mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-05-10 09:41:16 -03:00
Compare commits
532 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ff2d354ef8 | ||
|
|
3bef568955 | ||
|
|
9a7be6db08 | ||
|
|
40e2025327 | ||
|
|
a819c863eb | ||
|
|
827c88e4a1 | ||
|
|
e2b7a078f4 | ||
|
|
6de0c4103b | ||
|
|
b6e8171f01 | ||
|
|
b1439075c6 | ||
|
|
7df536023b | ||
|
|
f5f15f9de2 | ||
|
|
0e0a61119f | ||
|
|
6f058c687d | ||
|
|
53ea5d60b7 | ||
|
|
9525f429c6 | ||
|
|
548e379d6a | ||
|
|
202d29de88 | ||
|
|
23152ae8a6 | ||
|
|
7310596dab | ||
|
|
4afe49d7c6 | ||
|
|
d7c3d2acbf | ||
|
|
f771fce892 | ||
|
|
6522000bf0 | ||
|
|
285abcc9bc | ||
|
|
b15e8123ca | ||
|
|
1c86395ed8 | ||
|
|
3c8d2a1126 | ||
|
|
ed8cd08984 | ||
|
|
69537430ea | ||
|
|
0a603a56c6 | ||
|
|
046dd82995 | ||
|
|
97c3e231f4 | ||
|
|
76b782d576 | ||
|
|
ed5c1db392 | ||
|
|
37f5db2bf9 | ||
|
|
8a97bffd02 | ||
|
|
2fd48bce11 | ||
|
|
d1a3e6abf5 | ||
|
|
1a29979bbd | ||
|
|
69814e5066 | ||
|
|
4dbac8f941 | ||
|
|
303473f20c | ||
|
|
480a29594e | ||
|
|
dfe3dc1429 | ||
|
|
2ea00ce444 | ||
|
|
ac13bdeaa7 | ||
|
|
22cb7dd2d7 | ||
|
|
20698cc813 | ||
|
|
1ebf571da5 | ||
|
|
7c822cbf30 | ||
|
|
90302d9232 | ||
|
|
bee6805ff9 | ||
|
|
65035c4dc7 | ||
|
|
2b0d64184a | ||
|
|
51d7159ba7 | ||
|
|
0a4819be27 | ||
|
|
72ad4e0d3b | ||
|
|
21de293a44 | ||
|
|
8b395d05ef | ||
|
|
8392902cec | ||
|
|
a5abdd2792 | ||
|
|
e784683b8a | ||
|
|
7fadf6c083 | ||
|
|
7ff76476ed | ||
|
|
cd9102214b | ||
|
|
8da54a1955 | ||
|
|
6899e4e734 | ||
|
|
486e0dbe84 | ||
|
|
441c109afb | ||
|
|
4b0810d7e9 | ||
|
|
51d58a6a7c | ||
|
|
7a884e11a6 | ||
|
|
c4acfdd87c | ||
|
|
41f8007a03 | ||
|
|
8207030b21 | ||
|
|
a2c70f495e | ||
|
|
b11f366bb0 | ||
|
|
0e1a3c7c4a | ||
|
|
d3a75a354a | ||
|
|
afc49dded2 | ||
|
|
49b232df84 | ||
|
|
248d11c462 | ||
|
|
6b1570b745 | ||
|
|
dc3634dc94 | ||
|
|
696b4df1c6 | ||
|
|
65f4d6e866 | ||
|
|
8833e8f4ea | ||
|
|
f29026b767 | ||
|
|
7ecf7c1fac | ||
|
|
4a2fa5ea34 | ||
|
|
03f6656af6 | ||
|
|
8e6dbe245c | ||
|
|
daf171aa86 | ||
|
|
d1bbb89389 | ||
|
|
bd0c1573df | ||
|
|
2700a9b697 | ||
|
|
474f6e90ff | ||
|
|
7cbc11f1c3 | ||
|
|
09f9d43be3 | ||
|
|
109e7455a8 | ||
|
|
9b95332aa9 | ||
|
|
cccd13db92 | ||
|
|
2c8a2c9f61 | ||
|
|
f05e1f6e48 | ||
|
|
f439c4a484 | ||
|
|
2fba53b113 | ||
|
|
8a2846ed44 | ||
|
|
91b63e4989 | ||
|
|
89d876d0f7 | ||
|
|
e79fdcb194 | ||
|
|
60f0533821 | ||
|
|
0768cf7e53 | ||
|
|
bdd83d338c | ||
|
|
db369a9ad7 | ||
|
|
aa895c6740 | ||
|
|
8e06805f2d | ||
|
|
00360d8fbc | ||
|
|
3b365d9f8d | ||
|
|
3835000e9d | ||
|
|
9bbe19bfb8 | ||
|
|
787e99d901 | ||
|
|
713748c782 | ||
|
|
c9eb74fa4b | ||
|
|
b2d940c25a | ||
|
|
2a7bc8c04b | ||
|
|
013d3dbb89 | ||
|
|
0aff94dd4c | ||
|
|
431850b4ec | ||
|
|
e280d10033 | ||
|
|
8c4708b51e | ||
|
|
4ba9ac28bb | ||
|
|
4664d65af7 | ||
|
|
1b7157a03f | ||
|
|
e1dd17a7dd | ||
|
|
5c8d9bd13c | ||
|
|
1c9a173b3d | ||
|
|
a0c40fcf8d | ||
|
|
f36811b7be | ||
|
|
40ed01f6f2 | ||
|
|
b2e2743195 | ||
|
|
1dc033f71c | ||
|
|
ba4166d17d | ||
|
|
46c6f7880b | ||
|
|
bef7fff383 | ||
|
|
0811613fe9 | ||
|
|
a09abea737 | ||
|
|
fd4e5e6777 | ||
|
|
57b3965518 | ||
|
|
3e843f8219 | ||
|
|
2343ce5a0c | ||
|
|
0122e35cb6 | ||
|
|
c96382152c | ||
|
|
af0bd61fb5 | ||
|
|
4a87c9895d | ||
|
|
036cc4e0fa | ||
|
|
9e304fa734 | ||
|
|
6d9631d0d0 | ||
|
|
bb04df2ac9 | ||
|
|
746a602515 | ||
|
|
a41fd8f759 | ||
|
|
ba9fbc67da | ||
|
|
ac40a3bcd0 | ||
|
|
942dcd7d54 | ||
|
|
9830bf985a | ||
|
|
7bb070d817 | ||
|
|
d56ab1d365 | ||
|
|
38175cdd30 | ||
|
|
436b1e10c6 | ||
|
|
e59cb1da5d | ||
|
|
e42198b7c8 | ||
|
|
2076944268 | ||
|
|
407c96e943 | ||
|
|
bf333f2a84 | ||
|
|
3ddd5e5981 | ||
|
|
b016438c08 | ||
|
|
7268a4a4e0 | ||
|
|
51c6c5ea49 | ||
|
|
5688035680 | ||
|
|
43b6b703ff | ||
|
|
e007a5c203 | ||
|
|
f836bd41c0 | ||
|
|
c9e98c2eef | ||
|
|
e94803152c | ||
|
|
07ff8a6c03 | ||
|
|
9f10dd377e | ||
|
|
6e0e7e0996 | ||
|
|
907b2f8462 | ||
|
|
d2869d5140 | ||
|
|
587e91d0c1 | ||
|
|
aad3249b79 | ||
|
|
081ab955af | ||
|
|
9a9d84c58a | ||
|
|
94d1322fc1 | ||
|
|
eed8b61a9e | ||
|
|
40558c2eb9 | ||
|
|
d677b468db | ||
|
|
4e38d3bc8c | ||
|
|
36ae253a29 | ||
|
|
f673b06dd2 | ||
|
|
e9e0643817 | ||
|
|
358f412abb | ||
|
|
a983798295 | ||
|
|
52a0149e4f | ||
|
|
8fdc46a105 | ||
|
|
63b02e308d | ||
|
|
7c97095bca | ||
|
|
b62beaf47d | ||
|
|
b2b1ec27d8 | ||
|
|
6aa682755d | ||
|
|
2bc49b3291 | ||
|
|
cea3dfd0cb | ||
|
|
d7d2c82a82 | ||
|
|
58aa1e75c1 | ||
|
|
0361423469 | ||
|
|
9aee2b7c9c | ||
|
|
2c95e087b2 | ||
|
|
5d5ee87a59 | ||
|
|
c60b62de73 | ||
|
|
2e5821c17d | ||
|
|
f46145a6b3 | ||
|
|
c61f6ceea6 | ||
|
|
d32751df13 | ||
|
|
038dcca143 | ||
|
|
d79e8c7f62 | ||
|
|
af8cb6fe87 | ||
|
|
5855f78010 | ||
|
|
f7118e769f | ||
|
|
93ae00e8e5 | ||
|
|
d7eb084b9d | ||
|
|
6e1548b821 | ||
|
|
5381c6cf93 | ||
|
|
20e5d298a0 | ||
|
|
39e9974e71 | ||
|
|
d2bd3e4919 | ||
|
|
04b142208d | ||
|
|
cf35a8e3a5 | ||
|
|
e7e3e8ee74 | ||
|
|
6fd69bdda8 | ||
|
|
a85f4cc1c4 | ||
|
|
07af5f4832 | ||
|
|
446272eee6 | ||
|
|
48ca253097 | ||
|
|
da2a757dff | ||
|
|
6fada015b6 | ||
|
|
a1a2773cbf | ||
|
|
67f216fa55 | ||
|
|
8986e05b94 | ||
|
|
7c016c56e3 | ||
|
|
0602044723 | ||
|
|
4ffd2afccd | ||
|
|
ec58ffa641 | ||
|
|
2c44ecb4a3 | ||
|
|
2eebb6e7ed | ||
|
|
1a3ab8a189 | ||
|
|
4722ddc373 | ||
|
|
25365dbc54 | ||
|
|
6a5f11879b | ||
|
|
b028e41f7f | ||
|
|
86593cd6a2 | ||
|
|
6cae5c8b0a | ||
|
|
29cd62ab6e | ||
|
|
4c7e06e752 | ||
|
|
433169dca4 | ||
|
|
d46dade284 | ||
|
|
79b466441b | ||
|
|
9f14d50974 | ||
|
|
990803009e | ||
|
|
6dfd629fc5 | ||
|
|
d97f8f3fde | ||
|
|
95ca3d1c69 | ||
|
|
c8b04f70cf | ||
|
|
bffff77d17 | ||
|
|
6bdb0cde8b | ||
|
|
42a260f1e6 | ||
|
|
148cb68700 | ||
|
|
18c185c256 | ||
|
|
b5b49e7a4d | ||
|
|
28ea5ce732 | ||
|
|
eccba7626d | ||
|
|
79d3207d51 | ||
|
|
d6bf879675 | ||
|
|
051f557e8f | ||
|
|
17171c3277 | ||
|
|
18a59291ed | ||
|
|
29e86254d0 | ||
|
|
b746a803a9 | ||
|
|
07e14ed7a8 | ||
|
|
df5cc6f858 | ||
|
|
409a407ca0 | ||
|
|
1c2cbb00bc | ||
|
|
bbf2a3836f | ||
|
|
1aa1ab540e | ||
|
|
27c9eb8758 | ||
|
|
e6b1035ddc | ||
|
|
9f6aba38d6 | ||
|
|
b52fe0feb6 | ||
|
|
db459f869a | ||
|
|
763a6b8351 | ||
|
|
4a06821d99 | ||
|
|
22f3dcfd35 | ||
|
|
dbb66e1895 | ||
|
|
5a7a264b96 | ||
|
|
3d601bd751 | ||
|
|
c9deea2237 | ||
|
|
32e54fd719 | ||
|
|
9ebdc16be6 | ||
|
|
92ecc01baa | ||
|
|
ff1c5e058f | ||
|
|
3d192a8e93 | ||
|
|
f5c6306bde | ||
|
|
524e0aa174 | ||
|
|
94abb30f94 | ||
|
|
af8e053896 | ||
|
|
633e2f498f | ||
|
|
4932538c74 | ||
|
|
786144ba86 | ||
|
|
e3dd94f272 | ||
|
|
b110a0ae21 | ||
|
|
48d9c38d1e | ||
|
|
51f8272ebd | ||
|
|
77f35c1b41 | ||
|
|
06668bfacb | ||
|
|
df59b8498f | ||
|
|
92fde30c0c | ||
|
|
d690a15b29 | ||
|
|
445f6539cf | ||
|
|
13a7269378 | ||
|
|
fd2644ce49 | ||
|
|
508de57459 | ||
|
|
de2405b35a | ||
|
|
a7f977836a | ||
|
|
f59e4a88c6 | ||
|
|
c755bd0358 | ||
|
|
536523ffd7 | ||
|
|
ca82fc2f03 | ||
|
|
d1411c42d6 | ||
|
|
9d770af5f4 | ||
|
|
d1ff6a323a | ||
|
|
112ea1759a | ||
|
|
76bafbef2a | ||
|
|
1947ec88f1 | ||
|
|
d0956f1e43 | ||
|
|
6996c7718e | ||
|
|
45d56d8e05 | ||
|
|
53295d38b7 | ||
|
|
bd9c843fd1 | ||
|
|
f812b9b26c | ||
|
|
52851a3ba4 | ||
|
|
b1bf115fa2 | ||
|
|
0f25ef365d | ||
|
|
55ea4b6fc0 | ||
|
|
5ef8cccf21 | ||
|
|
5613d96001 | ||
|
|
5d9ba8c1a2 | ||
|
|
0de232bf54 | ||
|
|
db5b887824 | ||
|
|
634bdb8b3b | ||
|
|
9c579a37bb | ||
|
|
1502acd83e | ||
|
|
ef3430f669 | ||
|
|
01af64cf1f | ||
|
|
349f52a1a5 | ||
|
|
850aa1963f | ||
|
|
185d0c3c1c | ||
|
|
3656443b1f | ||
|
|
6748b9699f | ||
|
|
dc91d7aec4 | ||
|
|
13a51ba4c2 | ||
|
|
749dad1309 | ||
|
|
7a07d7c188 | ||
|
|
53c95abfb2 | ||
|
|
7fd2ae4ffd | ||
|
|
717ac3f7fe | ||
|
|
50fa7234ea | ||
|
|
80b4055eab | ||
|
|
94b7c8d5e6 | ||
|
|
580ec26885 | ||
|
|
6ba5d80a20 | ||
|
|
d58b9de63b | ||
|
|
99a93b5add | ||
|
|
de50539c02 | ||
|
|
04cf08b93b | ||
|
|
2c5b52eb6c | ||
|
|
dd8150d98d | ||
|
|
99662d7711 | ||
|
|
5f3ad87a98 | ||
|
|
83d05f9170 | ||
|
|
0d56818664 | ||
|
|
5b0cd5a911 | ||
|
|
102b99a17b | ||
|
|
6222d00ffc | ||
|
|
73370f5f39 | ||
|
|
883ce6e440 | ||
|
|
f320f5f710 | ||
|
|
32b531667a | ||
|
|
c47dae77a4 | ||
|
|
53160d134e | ||
|
|
619defd748 | ||
|
|
40db2b3c2a | ||
|
|
b05ccee0f0 | ||
|
|
d722fa59ca | ||
|
|
60065614bd | ||
|
|
05b39a9bdb | ||
|
|
91ab644173 | ||
|
|
083fcd6491 | ||
|
|
7e9e7d77d1 | ||
|
|
66ee644130 | ||
|
|
c20b8982bc | ||
|
|
15bb8f712d | ||
|
|
d48e9ef8b1 | ||
|
|
acd28b5dc4 | ||
|
|
1fe4863039 | ||
|
|
d347da963b | ||
|
|
930bb9c6d1 | ||
|
|
676c3ed505 | ||
|
|
2d3588fa51 | ||
|
|
4835945c09 | ||
|
|
82bff9f407 | ||
|
|
3b6d8756ea | ||
|
|
d1bb30afae | ||
|
|
7a1d64637d | ||
|
|
5f85d27671 | ||
|
|
5d828b5fcf | ||
|
|
c2f6c6c1d2 | ||
|
|
7726cffdab | ||
|
|
3570013496 | ||
|
|
2401a163fe | ||
|
|
e8d802c5e1 | ||
|
|
dca4167de6 | ||
|
|
6d0b6e5de5 | ||
|
|
fd6bf06f15 | ||
|
|
d2e11ea61d | ||
|
|
dad2b93d1e | ||
|
|
1075ca69b0 | ||
|
|
e29f5c5474 | ||
|
|
22bfa6638a | ||
|
|
1a48941f6b | ||
|
|
68e0c94dbb | ||
|
|
ca04fc745d | ||
|
|
3afead1827 | ||
|
|
0ea69dab7b | ||
|
|
a4a025b786 | ||
|
|
328c3a39a1 | ||
|
|
5aa019a0b5 | ||
|
|
92aa99104a | ||
|
|
6b544bc3c2 | ||
|
|
ea0005e16d | ||
|
|
6901ad361d | ||
|
|
b21cccf5f0 | ||
|
|
7740035d14 | ||
|
|
7dc3934997 | ||
|
|
845e15876c | ||
|
|
c4e7a7992f | ||
|
|
43ab84397b | ||
|
|
0840c9248f | ||
|
|
dd79d75504 | ||
|
|
7073f0b58b | ||
|
|
15916bfbdc | ||
|
|
228fdbef5a | ||
|
|
7f7f8fb156 | ||
|
|
2ae9735858 | ||
|
|
8ac1688c89 | ||
|
|
9cd2dbc9e7 | ||
|
|
a74055bc33 | ||
|
|
e1d0b9370e | ||
|
|
5dfa28059e | ||
|
|
7ead45d899 | ||
|
|
5c9ac72c19 | ||
|
|
343cafef34 | ||
|
|
95a01f3c8f | ||
|
|
cfa367f14c | ||
|
|
94cae410f3 | ||
|
|
cc69afc4fe | ||
|
|
777a559e12 | ||
|
|
0427ccbb55 | ||
|
|
f9a4699147 | ||
|
|
e6e287ae1f | ||
|
|
143602e5f6 | ||
|
|
1c2d3583e7 | ||
|
|
e58110da2c | ||
|
|
0d1683edc8 | ||
|
|
c94b9e504d | ||
|
|
8be3bf3e5d | ||
|
|
3e165297ce | ||
|
|
7ac922def6 | ||
|
|
f12127c775 | ||
|
|
73d84fe136 | ||
|
|
c595448f9c | ||
|
|
5a2aeb1511 | ||
|
|
5fb9d9aa38 | ||
|
|
8258961c29 | ||
|
|
0dab94a54c | ||
|
|
3097f71abd | ||
|
|
ea5e1b70db | ||
|
|
6b393d35a9 | ||
|
|
a5dde6021c | ||
|
|
a015472739 | ||
|
|
6affa4452b | ||
|
|
7ebfa380dd | ||
|
|
370336e7c7 | ||
|
|
bad4269dc9 | ||
|
|
effe6f47a3 | ||
|
|
7eb3a5a17d | ||
|
|
b6cd723eb7 | ||
|
|
a2cd8c8a8d | ||
|
|
3b03bd6a10 | ||
|
|
6caff2d85d | ||
|
|
eeaa241be8 | ||
|
|
8fdb4d2a17 | ||
|
|
7c7f744b4c | ||
|
|
5718ea41df | ||
|
|
20c83ba605 | ||
|
|
e9e32f980b | ||
|
|
4b2cc49aaa | ||
|
|
28f65c07b0 | ||
|
|
18279c3867 | ||
|
|
d1c9bca2e9 | ||
|
|
49973b85da | ||
|
|
47373c4f68 | ||
|
|
cbf1dbaa2e | ||
|
|
fdaa79416a | ||
|
|
7c3700c190 | ||
|
|
a0e1f9113e | ||
|
|
133b682793 | ||
|
|
824f4ee566 | ||
|
|
1cb9b65744 | ||
|
|
35dde5de15 | ||
|
|
4d9bb19467 | ||
|
|
2555353161 | ||
|
|
73a9c8bcb8 | ||
|
|
47b652c76e |
@@ -93,7 +93,7 @@ DISABLE_INDEX = YES
|
||||
ENUM_VALUES_PER_LINE = 4
|
||||
GENERATE_TREEVIEW = NO
|
||||
TREEVIEW_WIDTH = 250
|
||||
GENERATE_LATEX = YES
|
||||
GENERATE_LATEX = NO
|
||||
LATEX_OUTPUT = latex
|
||||
LATEX_CMD_NAME = latex
|
||||
MAKEINDEX_CMD_NAME = makeindex
|
||||
|
||||
13
INSTALL
13
INSTALL
@@ -2,11 +2,12 @@
|
||||
Known issues
|
||||
============
|
||||
|
||||
Fish currently requires a semi-modern GCC version to
|
||||
compile. Specifically, GCC 2.95.* won't compile fish, but GCC 3.23
|
||||
should work. Fish has not been coded with an C99- or GNU-specific
|
||||
features in mind, so it is hoped that it should be possible to make
|
||||
fish work with other compilers. Patches are welcome.
|
||||
Fish is developed using GCC, with the goal of using only C89 language
|
||||
features. Fish does, however use the *wprintf family of functions,
|
||||
which are new to the C99 standrard. It is not unlikely that any given
|
||||
release contains a few GCC:isms, but ICC 9.0.030 has been found to
|
||||
produce working binaries. GCC 2.95.* won't compile fish, but GCC 3.2.3
|
||||
is known to work. Patches to fix any remaining GNU:isms are welcome.
|
||||
|
||||
Older versions of Doxygen has bugs in the man-page generation which
|
||||
cause the builtin help to render incorrectly. Doxygen 1.2.14 is known
|
||||
@@ -52,7 +53,7 @@ Local install procedure
|
||||
=======================
|
||||
|
||||
If you have downloaded the darcs repository of fish, you need to run
|
||||
autoconf first.
|
||||
autoconf to generate the configure script.
|
||||
|
||||
To install fish in your own home directory (typically as non-root),
|
||||
type:
|
||||
|
||||
519
Makefile.in
519
Makefile.in
@@ -23,7 +23,7 @@
|
||||
#
|
||||
# Makefile for the fish shell. Can build fish and associated
|
||||
# applications, install them, recalculate dependencies and also create
|
||||
# binary distributions in tar.bz2 tar.gz and rpm formats.
|
||||
# binary distributions in tar.bz2, tar.gz and rpm formats.
|
||||
#
|
||||
|
||||
#
|
||||
@@ -36,11 +36,6 @@
|
||||
CC := @CC@
|
||||
INSTALL:=@INSTALL@
|
||||
|
||||
# Compiler flags
|
||||
CFLAGS:=@CFLAGS@ -Wall -std=gnu99 -fno-strict-aliasing
|
||||
CPPFLAGS=@CPPFLAGS@
|
||||
LDFLAGS:= @LIBS@ @LDFLAGS@
|
||||
|
||||
# Installation directories
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
@@ -48,58 +43,57 @@ datadir = @datadir@
|
||||
bindir = @bindir@
|
||||
mandir = @mandir@
|
||||
sysconfdir = @sysconfdir@
|
||||
fishdir = @fishdir@
|
||||
fishfile = @fishfile@
|
||||
fishinputfile = @fishinputfile@
|
||||
docdir = @docdir@
|
||||
localedir = @localedir@
|
||||
prefix = @prefix@
|
||||
optbindirs = @optbindirs@
|
||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||
|
||||
#Init files to install
|
||||
INIT_DIR_INSTALL = init/fish_interactive.fish init/fish_function.fish init/fish_complete.fish
|
||||
MACROS=-DLOCALEDIR=\"$(localedir)\" -DPREFIX=L\"$(prefix)\" -DDATADIR=L\"$(datadir)\" -DSYSCONFDIR=L\"$(sysconfdir)\"
|
||||
CFLAGS=@CFLAGS@ $(MACROS)
|
||||
CPPFLAGS=@CPPFLAGS@
|
||||
LDFLAGS= @LIBS@ @LDFLAGS@
|
||||
|
||||
|
||||
#etc files to install
|
||||
ETC_DIR_INSTALL = etc/fish_interactive.fish
|
||||
|
||||
# Set to 1 if we have gettext
|
||||
HAVE_GETTEXT=@HAVE_GETTEXT@
|
||||
|
||||
# All objects used by fish, that are compiled from an ordinary .c file
|
||||
# using an ordinary .h file.
|
||||
COMMON_OBJS := function.o builtin.o common.o complete.o env.o exec.o \
|
||||
#Additional .c files used by common.o. These also have a corresponding
|
||||
#.h file.
|
||||
COMMON_FILES := util.c halloc.c halloc_util.c fallback.c
|
||||
|
||||
# All objects that the system needs to build fish, except main.o
|
||||
FISH_OBJS := function.o builtin.o complete.o env.o exec.o \
|
||||
expand.o highlight.o history.o kill.o parser.o proc.o reader.o \
|
||||
sanity.o tokenizer.o util.o wildcard.o wgetopt.o wutil.o input.o \
|
||||
sanity.o tokenizer.o wildcard.o wgetopt.o wutil.o input.o \
|
||||
output.o intern.o env_universal.o env_universal_common.o \
|
||||
input_common.o event.o signal.o io.o translate.o parse_util.o \
|
||||
halloc.o
|
||||
input_common.o event.o signal.o io.o parse_util.o common.o \
|
||||
|
||||
# builtin_help.h exists, but builtin_help.c is autogenerated
|
||||
COMMON_OBJS_WITH_HEADER := builtin_help.o
|
||||
|
||||
# main.c exists, but main.h does not, etc.
|
||||
COMMON_OBJS_WITH_CODE := builtin_set.o builtin_commandline.o \
|
||||
builtin_ulimit.c builtin_complete.o
|
||||
|
||||
# All objects that the system needs to build fish
|
||||
FISH_OBJS := $(COMMON_OBJS) $(COMMON_OBJS_WITH_CODE) \
|
||||
$(COMMON_OBJS_WITH_HEADER) main.o
|
||||
# Additional files used by builtin.o
|
||||
BUILTIN_FILES := builtin_help.c builtin_set.c builtin_commandline.c \
|
||||
builtin_ulimit.c builtin_complete.c builtin_jobs.c
|
||||
|
||||
# All objects that the system needs to build fish_pager
|
||||
FISH_PAGER_OBJS := fish_pager.o common.o output.o util.o wutil.o \
|
||||
FISH_PAGER_OBJS := fish_pager.o output.o wutil.o \
|
||||
tokenizer.o input_common.o env_universal.o env_universal_common.o \
|
||||
translate.o halloc.o
|
||||
common.o
|
||||
|
||||
# All objects that the system needs to build fish_tests
|
||||
FISH_TESTS_OBJS := $(COMMON_OBJS) $(COMMON_OBJS_WITH_CODE) \
|
||||
$(COMMON_OBJS_WITH_HEADER) fish_tests.o
|
||||
FISH_TESTS_OBJS := $(FISH_OBJS) fish_tests.o
|
||||
|
||||
# All objects that the system needs to build fishd
|
||||
FISHD_OBJS := fishd.o env_universal_common.o common.o util.o wutil.o \
|
||||
doc_src/fishd.o halloc.o
|
||||
FISHD_OBJS := fishd.o env_universal_common.o wutil.o \
|
||||
doc_src/fishd.o common.o
|
||||
|
||||
# All objects needed to build mimedb
|
||||
MIME_OBJS := mimedb.o xdgmimealias.o xdgmime.o xdgmimeglob.o \
|
||||
xdgmimeint.o xdgmimemagic.o xdgmimeparent.o wutil.o halloc.o
|
||||
MIME_OBJS := mimedb.o xdgmimealias.o xdgmime.o xdgmimeglob.o \
|
||||
xdgmimeint.o xdgmimemagic.o xdgmimeparent.o wutil.o common.o
|
||||
|
||||
#
|
||||
# Files containing documentation for builtins. Should be listed
|
||||
# alphabetically, since this is the order in which they will be written
|
||||
# in the help file.
|
||||
# Files containing documentation for builtins.
|
||||
#
|
||||
BUILTIN_DOC_SRC := doc_src/source.txt doc_src/and.txt \
|
||||
doc_src/begin.txt doc_src/bg.txt doc_src/bind.txt \
|
||||
@@ -120,9 +114,7 @@ BUILTIN_DOC_SRC := doc_src/source.txt doc_src/and.txt \
|
||||
BUILTIN_DOC_HDR := $(BUILTIN_DOC_SRC:.txt=.doxygen)
|
||||
|
||||
#
|
||||
# Files containing documentation for external commands. Should be listed
|
||||
# alphabetically, since this is the order in which they will be written
|
||||
# in the help file.
|
||||
# Files containing documentation for external commands.
|
||||
#
|
||||
CMD_DOC_SRC := doc_src/contains.txt doc_src/count.txt doc_src/dirh.txt \
|
||||
doc_src/dirs.txt doc_src/fish_pager.txt doc_src/fishd.txt \
|
||||
@@ -151,25 +143,31 @@ DOC_SRC_DIR_FILES := doc_src/Doxyfile.in doc_src/doc.hdr \
|
||||
$(BUILTIN_DOC_SRC) $(CMD_DOC_SRC) doc_src/fish.1.in
|
||||
|
||||
# Files in ./
|
||||
MAIN_DIR_FILES := Doxyfile Doxyfile.user Makefile.in configure \
|
||||
configure.ac config.h.in install-sh set_color.c count.c \
|
||||
key_reader.c gen_hdr.sh gen_hdr2.c $(MIME_OBJS:.o=.h) \
|
||||
$(MIME_OBJS:.o=.c) $(COMMON_OBJS_WITH_HEADER:.o=.h) \
|
||||
$(COMMON_OBJS:.o=.h) $(COMMON_OBJS_WITH_CODE:.o=.c) \
|
||||
$(COMMON_OBJS:.o=.c) builtin_help.hdr fish.spec.in INSTALL README \
|
||||
user_doc.head.html xsel-0.9.6.tar ChangeLog config.sub \
|
||||
config.guess fish_tests.c main.c fish_pager.c fishd.c seq.in
|
||||
MAIN_DIR_FILES := Doxyfile Doxyfile.user Makefile.in configure \
|
||||
configure.ac config.h.in install-sh set_color.c count.c \
|
||||
key_reader.c gen_hdr.sh gen_hdr2.c $(MIME_OBJS:.o=.h) \
|
||||
$(MIME_OBJS:.o=.c) $(FISH_OBJS:.o=.h) $(BUILTIN_FILES) \
|
||||
$(COMMON_FILES) $(COMMON_FILES:.c=.h) $(FISH_OBJS:.o=.c) \
|
||||
builtin_help.hdr fish.spec.in INSTALL README user_doc.head.html \
|
||||
xsel-0.9.6.tar ChangeLog config.sub config.guess fish_tests.c \
|
||||
main.c fish_pager.c fishd.c seq.in
|
||||
|
||||
# Files in ./init/
|
||||
INIT_DIR_FILES :=init/fish.in init/fish_complete.fish.in \
|
||||
init/fish_function.fish init/fish_inputrc \
|
||||
init/fish_interactive.fish.in
|
||||
# Files in ./etc/
|
||||
ETC_DIR_FILES :=etc/fish.in etc/fish_inputrc \
|
||||
etc/fish_interactive.fish.in
|
||||
|
||||
# Files in ./share/
|
||||
SHARE_DIR_FILES :=share/fish.in
|
||||
|
||||
# Files in ./tests/
|
||||
TESTS_DIR_FILES := $(TEST_IN) $(TEST_IN:.in=.out) $(TEST_IN:.in=.err) \
|
||||
$(TEST_IN:.in=.status) tests/test.fish tests/gen_output.fish
|
||||
|
||||
COMPLETIONS_DIR_FILES := $(wildcard init/completions/*.fish)
|
||||
# Files in ./share/completions/
|
||||
COMPLETIONS_DIR_FILES := $(wildcard share/completions/*.fish)
|
||||
|
||||
# Files in ./share/functions/
|
||||
FUNCTIONS_DIR_FILES := $(wildcard share/functions/*.fish)
|
||||
|
||||
# Programs to build
|
||||
PROGRAMS:=fish set_color @XSEL@ @SEQ_FALLBACK@ mimedb count fish_pager fishd
|
||||
@@ -187,18 +185,29 @@ TRANSLATIONS_SRC := $(wildcard po/*.po)
|
||||
TRANSLATIONS := $(TRANSLATIONS_SRC:.po=.gmo)
|
||||
|
||||
#Make everything needed for installing fish
|
||||
all: $(PROGRAMS) user_doc
|
||||
all: $(PROGRAMS) user_doc etc/fish share/fish etc/fish_interactive.fish $(TRANSLATIONS)
|
||||
@echo fish has now been built.
|
||||
@echo Use \'make install\' to install fish.
|
||||
.PHONY: all
|
||||
|
||||
configure: configure.ac
|
||||
./config.status --recheck
|
||||
|
||||
Makefile: Makefile.in configure
|
||||
./config.status
|
||||
|
||||
fish.spec: fish.spec.in
|
||||
./config.status
|
||||
|
||||
debug:
|
||||
make fish CFLAGS="-O0 -Wno-unused -Werror -g -Wall -std=gnu99 -fno-strict-aliasing"
|
||||
make fish CFLAGS="@CFLAGS@ $(MACROS) -O0 -Wno-unused -Werror -g"
|
||||
.PHONY: debug
|
||||
|
||||
# User documentation, describing the features of the fish shell.
|
||||
user_doc: doc.h Doxyfile.user user_doc.head.html
|
||||
user_doc: doc_src/doc.hdr Doxyfile.user user_doc.head.html
|
||||
$(MAKE) doc.h # Depend on the source (doc.hdr) and manually make the intermediate as needed
|
||||
doxygen Doxyfile.user
|
||||
touch user_doc
|
||||
|
||||
# Source code documentation. Also includes user documentation.
|
||||
doc: *.h *.c doc.h Doxyfile builtin_help.c
|
||||
@@ -229,11 +238,17 @@ xsel-0.9.6/xsel: xsel-0.9.6
|
||||
doc.h:$(BUILTIN_DOC_SRC) $(CMD_DOC_SRC) doc_src/doc.hdr
|
||||
cat doc_src/doc.hdr >doc.h;
|
||||
echo "/** \page builtins Builtin commands" >>doc.h;
|
||||
cat $(BUILTIN_DOC_SRC) >>doc.h;
|
||||
for i in `printf "%s\n" $(BUILTIN_DOC_SRC)|sort`; do \
|
||||
echo "<hr>" >>doc.h; \
|
||||
cat $$i >>doc.h; \
|
||||
done
|
||||
echo "*/" >>doc.h
|
||||
echo "/** \page commands External commands" >>doc.h;
|
||||
echo "\c fish is shipped with commands which do not use any internal parts of the shell, and are therefore not written as builtins, but separate commands." >>doc.h
|
||||
cat $(CMD_DOC_SRC) >>doc.h;
|
||||
for i in `printf "%s\n" $(CMD_DOC_SRC)|sort`; do \
|
||||
echo "<hr>" >>doc.h; \
|
||||
cat $$i >>doc.h; \
|
||||
done
|
||||
echo "*/" >>doc.h
|
||||
|
||||
# This rule creates complete doxygen headers from each of the various
|
||||
@@ -245,10 +260,14 @@ doc.h:$(BUILTIN_DOC_SRC) $(CMD_DOC_SRC) doc_src/doc.hdr
|
||||
cat $*.txt >>$@;
|
||||
echo "*/" >>$@
|
||||
|
||||
%: %.in Makefile
|
||||
sed <$@.in >$@ -e "s,@sysconfdir\@,$(sysconfdir)," -e "s,@datadir\@,$(datadir)," -e "s,@docdir\@,$(docdir)," -e "s|@configure_input\@|$@, generated from $@.in by the Makefile. DO NOT MANUALLY EDIT THIS FILE!|" -e "s,@prefix\@,$(prefix)," -e "s,@optbindirs\@,$(optbindirs),"
|
||||
#-e "s,@\@,$(),"
|
||||
|
||||
# Compile translation file
|
||||
%.gmo:
|
||||
if test $(HAVE_GETTEXT) = 1; then \
|
||||
msgfmt $*.po -o $*.gmo; \
|
||||
msgfmt -o $*.gmo $*.po; \
|
||||
fi
|
||||
|
||||
# Update existing po file or copy messages.pot
|
||||
@@ -262,16 +281,20 @@ doc.h:$(BUILTIN_DOC_SRC) $(CMD_DOC_SRC) doc_src/doc.hdr
|
||||
fi
|
||||
|
||||
# Create a template translation object
|
||||
messages.pot: *.c *.h init/*.in init/*.fish init/completions/*.fish seq
|
||||
messages.pot: *.c *.h etc/*.in share/fish share/completions/*.fish share/functions/*.fish seq
|
||||
if test $(HAVE_GETTEXT) = 1;then \
|
||||
xgettext -k_ -kN_ -kcomplete_desc *.c *.h -o messages.pot; \
|
||||
if ! xgettext -j -k_ -LShell init/*.in init/*.fish init/completions/*.fish seq -o messages.pot; then \
|
||||
xgettext -k_ -kN_ *.c *.h -o messages.pot; \
|
||||
if xgettext -j -k_ -kN_ -LShell etc/*.in share/fish share/completions/*.fish share/functions/*.fish seq -o messages.pot; then true; else \
|
||||
echo "Your xgettext version is too old to build the messages.pot file"\
|
||||
rm messages.pot\
|
||||
false;\
|
||||
fi; \
|
||||
fi
|
||||
|
||||
builtin.o: $(BUILTIN_FILES)
|
||||
|
||||
common.o: $(COMMON_FILES)
|
||||
|
||||
# Generate the internal help functions by making doxygen create
|
||||
# man-pages which are then converted into C code. The convertion path
|
||||
# looks like this:
|
||||
@@ -304,15 +327,28 @@ messages.pot: *.c *.h init/*.in init/*.fish init/completions/*.fish seq
|
||||
# Which is an awful, clunky and ugly way of producing
|
||||
# documentation. There ought to be something simpler.
|
||||
|
||||
builtin_help.c: $(BUILTIN_DOC_HDR) doc_src/count.doxygen gen_hdr2 gen_hdr.sh builtin_help.hdr $(CMD_DOC_HDR)
|
||||
cd doc_src; doxygen; cd ..;
|
||||
doc_src/builtin_doc: $(BUILTIN_DOC_SRC) doc_src/count.txt builtin_help.hdr $(CMD_DOC_SRC)
|
||||
for i in $(BUILTIN_DOC_SRC) $(CMD_DOC_SRC); do \
|
||||
FILE=doc_src/`basename $$i .txt`.doxygen; \
|
||||
echo "/** \page" `basename $$i .txt` >$$FILE; \
|
||||
cat $$i >>$$FILE; \
|
||||
echo "*/" >>$$FILE; \
|
||||
done
|
||||
cd doc_src; doxygen; cd ..;
|
||||
for i in doc_src/builtin_doc/man/man1/*.1; do \
|
||||
sed -e "s/\(.\)\\.SH/\1/" <$$i >$$i.tmp; \
|
||||
mv $$i.tmp $$i; \
|
||||
done
|
||||
touch doc_src/builtin_doc
|
||||
|
||||
builtin_help.c: doc_src/builtin_doc gen_hdr.sh
|
||||
$(MAKE) gen_hdr2 # Don't depend on gen_hdr2, because then we would need to rebuild the docs whenever we use a fresh tarball
|
||||
cp builtin_help.hdr builtin_help.c;
|
||||
chmod 755 gen_hdr.sh
|
||||
if test -x gen_hdr.sh; then true; else chmod 755 gen_hdr.sh; fi
|
||||
for i in $(BUILTIN_DOC_HDR) doc_src/count.doxygen ; do \
|
||||
echo ' hash_put( &tbl, L"'`basename $$i .doxygen`'",' >>$@; \
|
||||
echo ' hash_put( &tbl, L"'`basename $$i .doxygen`'",' >>$@; \
|
||||
./gen_hdr.sh $$i >>$@; \
|
||||
echo " );" >>$@; \
|
||||
echo >>$@; \
|
||||
printf " );\n\n" >>$@; \
|
||||
done;
|
||||
echo "}" >>builtin_help.c
|
||||
|
||||
@@ -321,7 +357,8 @@ builtin_help.c: $(BUILTIN_DOC_HDR) doc_src/count.doxygen gen_hdr2 gen_hdr.sh bui
|
||||
# mimedb. Depends on builtin_help.c to make sure doxygen gets run to
|
||||
# generate the man files.
|
||||
#
|
||||
%.c : %.doxygen gen_hdr2 builtin_help.c
|
||||
%.c : %.doxygen
|
||||
$(MAKE) gen_hdr2 builtin_help.c # These should really be filed as dependencis for %.c above instead, but that seems to confuse make
|
||||
echo "// This file was automatically generated, do not edit" >$@
|
||||
echo "#include <stdlib.h>" >>$@
|
||||
echo "#include <stdio.h>" >>$@
|
||||
@@ -333,27 +370,60 @@ builtin_help.c: $(BUILTIN_DOC_HDR) doc_src/count.doxygen gen_hdr2 gen_hdr.sh bui
|
||||
./gen_hdr.sh $*.doxygen >>$@
|
||||
echo ");" >>$@
|
||||
echo "}" >>$@
|
||||
#man -- doc_src/builtin_doc/man/man1/`basename $@ .c`.1 | cat -s | ./gen_hdr2 >>$@
|
||||
|
||||
#
|
||||
# The build rules for installing/uninstalling
|
||||
# The build rules for installing/uninstalling fish
|
||||
#
|
||||
|
||||
install: all install-translations
|
||||
# Check for an incompatible installed fish version, and fail with an
|
||||
# error if found
|
||||
|
||||
check-uninstall:
|
||||
if test -f $(DESTDIR)$(sysconfdir)/fish.d/fish_function.fish -o -f $(DESTDIR)$(sysconfdir)/fish.d/fish_complete.fish; then \
|
||||
echo;\
|
||||
echo ERROR;\
|
||||
echo;\
|
||||
echo An older fish installation using an incompatible filesystem hierarchy was detected;\
|
||||
echo You must uninstall this fish version before installing proceeding;\
|
||||
echo type \'make uninstall-legacy\' to uninstall these files,;\
|
||||
echo or type \'make force-install\' to force installation.;\
|
||||
echo The latter may result in a broken installation.;\
|
||||
echo;\
|
||||
false;\
|
||||
fi;
|
||||
.PHONY: check-uninstall
|
||||
|
||||
install-sh:
|
||||
if test -x install-sh; then true; else chmod 755 install-sh; fi
|
||||
.PHONY: install-sh
|
||||
|
||||
# Try to install after checking for incompatible installed versions
|
||||
install: all install-sh check-uninstall install-force
|
||||
.PHONY: install
|
||||
|
||||
# Force installation, even in presense of incompatible previous
|
||||
# version
|
||||
install-force: all install-translations
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(bindir)
|
||||
for i in $(PROGRAMS); do\
|
||||
$(INSTALL) -m 755 $$i $(DESTDIR)$(bindir) ; \
|
||||
done;
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(sysconfdir)$(fishdir)
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(sysconfdir)$(fishdir)/completions
|
||||
$(INSTALL) -m 644 init/fish $(DESTDIR)$(sysconfdir)$(fishfile)
|
||||
for i in $(INIT_DIR_INSTALL); do \
|
||||
$(INSTALL) -m 644 $$i $(DESTDIR)$(sysconfdir)$(fishdir); \
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(sysconfdir)/fish.d
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(datadir)/fish
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(datadir)/fish/completions
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(datadir)/fish/functions
|
||||
$(INSTALL) -m 644 etc/fish $(DESTDIR)$(sysconfdir)/fish
|
||||
$(INSTALL) -m 644 share/fish $(DESTDIR)$(datadir)/fish
|
||||
for i in $(ETC_DIR_INSTALL); do \
|
||||
$(INSTALL) -m 644 $$i $(DESTDIR)$(sysconfdir)/fish.d; \
|
||||
done;
|
||||
for i in $(COMPLETIONS_DIR_FILES); do \
|
||||
$(INSTALL) -m 644 $$i $(DESTDIR)$(sysconfdir)$(fishdir)/completions/; \
|
||||
$(INSTALL) -m 644 $$i $(DESTDIR)$(datadir)/fish/completions/; \
|
||||
done;
|
||||
$(INSTALL) -m 644 init/fish_inputrc $(DESTDIR)$(sysconfdir)$(fishinputfile);
|
||||
for i in $(FUNCTIONS_DIR_FILES); do \
|
||||
$(INSTALL) -m 644 $$i $(DESTDIR)$(datadir)/fish/functions/; \
|
||||
done;
|
||||
$(INSTALL) -m 644 etc/fish_inputrc $(DESTDIR)$(sysconfdir)/fish_inputrc;
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(docdir)
|
||||
for i in user_doc/html/* ChangeLog; do \
|
||||
if test -f $$i; then \
|
||||
@@ -372,22 +442,53 @@ install: all install-translations
|
||||
@echo \* use the command \'chsh -s $(DESTDIR)$(bindir)/fish\'.
|
||||
@echo
|
||||
@echo Have fun!
|
||||
.PHONY: install
|
||||
.PHONY: install-force
|
||||
|
||||
|
||||
# Uninstall this fish version
|
||||
|
||||
uninstall: uninstall-translations
|
||||
for i in $(PROGRAMS); do \
|
||||
rm -f $(DESTDIR)$(bindir)/$$i; \
|
||||
done;
|
||||
rm -f $(DESTDIR)$(bindir)/xsel
|
||||
rm -f $(DESTDIR)$(sysconfdir)$(fishfile)
|
||||
rm -f $(DESTDIR)$(sysconfdir)$(fishinputfile)
|
||||
rm -r $(DESTDIR)$(sysconfdir)$(fishdir)
|
||||
rm -r $(DESTDIR)$(docdir)
|
||||
for i in fish.1* @XSEL_MAN@ mimedb.1* fishd.1* set_color.1* count.1*; do \
|
||||
rm $(DESTDIR)$(mandir)/man1/$$i; \
|
||||
rm -f $(DESTDIR)$(sysconfdir)/fish
|
||||
rm -f $(DESTDIR)$(sysconfdir)/fish_inputrc
|
||||
if test -f $(DESTDIR)$(sysconfdir)/fish.d/fish_interactive.fish; then \
|
||||
rm -f $(DESTDIR)$(sysconfdir)/fish.d/fish_interactive.fish; \
|
||||
fi
|
||||
if test -d $(DESTDIR)$(datadir)/fish; then \
|
||||
rm -r $(DESTDIR)$(datadir)/fish; \
|
||||
fi
|
||||
if test -d $(DESTDIR)$(docdir); then \
|
||||
rm -r $(DESTDIR)$(docdir);\
|
||||
fi
|
||||
for i in $(MANUALS); do \
|
||||
rm -f $(DESTDIR)$(mandir)/man1/`basename $$i`*; \
|
||||
done;
|
||||
.PHONY: uninstall
|
||||
|
||||
# Uninstall older fish release. This is not the default uninstall
|
||||
# since there is a slight chance that it removes a file put in place by
|
||||
# the sysadmin.
|
||||
|
||||
uninstall-legacy: uninstall
|
||||
rm -f $(DESTDIR)$(sysconfdir)/fish.d/fish_interactive.fish
|
||||
rm -f $(DESTDIR)$(sysconfdir)/fish.d/fish_complete.fish
|
||||
rm -f $(DESTDIR)$(sysconfdir)/fish.d/fish_function.fish
|
||||
if test -d $(DESTDIR)$(sysconfdir)/fish.d/completions; then \
|
||||
for i in $(COMPLETIONS_DIR_FILES); do \
|
||||
basename=`basename $$i`; \
|
||||
if test -f $(DESTDIR)$(sysconfdir)/fish.d/completions/$$basename; then \
|
||||
rm $(DESTDIR)$(sysconfdir)/fish.d/completions/$$basename; \
|
||||
fi; \
|
||||
done; \
|
||||
fi;
|
||||
rmdir $(DESTDIR)$(sysconfdir)/fish.d/completions; true
|
||||
rmdir $(DESTDIR)$(sysconfdir)/fish.d; true
|
||||
@echo The previous fish installation has been removed.
|
||||
.PHONY: uninstall-legacy
|
||||
|
||||
install-translations: $(TRANSLATIONS)
|
||||
if test $(HAVE_GETTEXT) = 1; then \
|
||||
for i in $(TRANSLATIONS); do \
|
||||
@@ -395,13 +496,13 @@ install-translations: $(TRANSLATIONS)
|
||||
$(INSTALL) -m 644 $$i $(DESTDIR)$(datadir)/locale/`basename $$i .gmo`/LC_MESSAGES/fish.mo; \
|
||||
echo $(DESTDIR)$(datadir)/locale/`basename $$i .gmo`/LC_MESSAGES/fish.mo;\
|
||||
done; \
|
||||
fi
|
||||
fi;
|
||||
.PHONY: install-translations
|
||||
|
||||
uninstall-translations:
|
||||
if test $(HAVE_GETTEXT) = 1; then \
|
||||
for i in $(TRANSLATIONS_SRC); do \
|
||||
rm -f $(DESTDIR)$(datadir)/locale/`basename $$i .po`/LC_MESSAGES/fish.mo; \
|
||||
rm -f $(DESTDIR)$(datadir)/locale/*/LC_MESSAGES/fish.mo; \
|
||||
done; \
|
||||
fi
|
||||
.PHONY: uninstall-translations
|
||||
@@ -410,8 +511,8 @@ uninstall-translations:
|
||||
# The build rules for all the commands
|
||||
#
|
||||
|
||||
fish: $(FISH_OBJS)
|
||||
$(CC) $(FISH_OBJS) $(LDFLAGS) -o $@
|
||||
fish: $(FISH_OBJS) main.o
|
||||
$(CC) $(FISH_OBJS) main.o $(LDFLAGS) -o $@
|
||||
|
||||
fish_pager: $(FISH_PAGER_OBJS)
|
||||
$(CC) $(FISH_PAGER_OBJS) $(LDFLAGS) -o $@
|
||||
@@ -422,26 +523,31 @@ fishd: $(FISHD_OBJS)
|
||||
fish_tests: $(FISH_TESTS_OBJS)
|
||||
$(CC) $(FISH_TESTS_OBJS) $(LDFLAGS) -o $@
|
||||
|
||||
# mimedb does not need any libraries, so we don't use LDFLAGS here
|
||||
mimedb: $(MIME_OBJS) doc_src/mimedb.o
|
||||
$(CC) $(MIME_OBJS) doc_src/mimedb.o $(LDFLAGS) -o $@
|
||||
|
||||
mimedb: $(MIME_OBJS) util.o common.o doc_src/mimedb.c
|
||||
$(CC) ${MIME_OBJS} util.o common.o doc_src/mimedb.c $(LDFLAGS) -o $@
|
||||
# count does not need any libraries, so we don't use LDFLAGS here
|
||||
count: count.o
|
||||
$(CC) count.o -o $@
|
||||
|
||||
set_color: set_color.o doc_src/set_color.c
|
||||
$(CC) set_color.o doc_src/set_color.c $(LDFLAGS) -o $@
|
||||
set_color: set_color.o doc_src/set_color.o common.o
|
||||
$(CC) set_color.o doc_src/set_color.o common.o $(LDFLAGS) -o $@
|
||||
|
||||
# Test program for the tokenizer library
|
||||
tokenizer_test: tokenizer.c tokenizer.h util.o wutil.o common.o
|
||||
$(CC) ${CFLAGS} tokenizer.c util.o wutil.o common.o -D TOKENIZER_TEST $(LDFLAGS) -o $@
|
||||
tokenizer_test: tokenizer.c tokenizer.h wutil.o common.o
|
||||
$(CC) $(CFLAGS) tokenizer.c wutil.o common.o -D TOKENIZER_TEST $(LDFLAGS) -o $@
|
||||
|
||||
# Neat little program to show output from terminal
|
||||
key_reader: key_reader.o input_common.o common.o env_universal.o env_universal_common.o util.o wutil.o
|
||||
$(CC) key_reader.o input_common.o common.o env_universal.o env_universal_common.o util.o wutil.o $(LDFLAGS) -o $@
|
||||
key_reader: key_reader.o input_common.o common.o env_universal.o env_universal_common.o wutil.o
|
||||
$(CC) key_reader.o input_common.o common.o env_universal.o env_universal_common.o wutil.o $(LDFLAGS) -o $@
|
||||
|
||||
#
|
||||
# Update dependencies
|
||||
#
|
||||
depend:
|
||||
makedepend -fMakefile.in -Y *.c
|
||||
./config.status
|
||||
.PHONY: depend
|
||||
|
||||
# Copy all the source files into a new directory and use tar to create
|
||||
@@ -450,32 +556,51 @@ depend:
|
||||
#
|
||||
# Uses install instead of mkdir so build won't fail if the directory
|
||||
# exists
|
||||
fish-@PACKAGE_VERSION@.tar: $(DOC_SRC_DIR_FILES) $(MAIN_DIR_FILES) $(INIT_DIR_FILES) $(TEST_DIR_FILES) $(COMPLETIONS_DIR_FILES) ChangeLog
|
||||
fish-@PACKAGE_VERSION@.tar: $(DOC_SRC_DIR_FILES) $(MAIN_DIR_FILES) $(ETC_DIR_FILES) $(TEST_DIR_FILES) $(SHARE_DIR_FILES) $(FUNCTIONS_DIR_FILES) $(COMPLETIONS_DIR_FILES) ChangeLog user_doc doc_src/builtin_doc
|
||||
rm -rf fish-@PACKAGE_VERSION@
|
||||
$(INSTALL) -d fish-@PACKAGE_VERSION@
|
||||
$(INSTALL) -d fish-@PACKAGE_VERSION@/doc_src
|
||||
$(INSTALL) -d fish-@PACKAGE_VERSION@/init
|
||||
$(INSTALL) -d fish-@PACKAGE_VERSION@/init/completions
|
||||
$(INSTALL) -d fish-@PACKAGE_VERSION@/user_doc
|
||||
$(INSTALL) -d fish-@PACKAGE_VERSION@/etc
|
||||
$(INSTALL) -d fish-@PACKAGE_VERSION@/share
|
||||
$(INSTALL) -d fish-@PACKAGE_VERSION@/share/completions
|
||||
$(INSTALL) -d fish-@PACKAGE_VERSION@/share/functions
|
||||
$(INSTALL) -d fish-@PACKAGE_VERSION@/tests
|
||||
$(INSTALL) -d fish-@PACKAGE_VERSION@/po
|
||||
cp -f $(DOC_SRC_DIR_FILES) fish-@PACKAGE_VERSION@/doc_src
|
||||
cp -f $(MAIN_DIR_FILES) fish-@PACKAGE_VERSION@/
|
||||
cp -f $(INIT_DIR_FILES) fish-@PACKAGE_VERSION@/init/
|
||||
cp -f $(COMPLETIONS_DIR_FILES) fish-@PACKAGE_VERSION@/init/completions/
|
||||
cp -f $(ETC_DIR_FILES) fish-@PACKAGE_VERSION@/etc/
|
||||
cp -f $(SHARE_DIR_FILES) fish-@PACKAGE_VERSION@/share/
|
||||
cp -f $(COMPLETIONS_DIR_FILES) fish-@PACKAGE_VERSION@/share/completions/
|
||||
cp -f $(FUNCTIONS_DIR_FILES) fish-@PACKAGE_VERSION@/share/functions/
|
||||
cp -f $(TESTS_DIR_FILES) fish-@PACKAGE_VERSION@/tests/
|
||||
cp -f $(TRANSLATIONS_SRC) fish-@PACKAGE_VERSION@/po/
|
||||
cp -rf user_doc fish-@PACKAGE_VERSION@/
|
||||
cp -rf doc_src/builtin_doc fish-@PACKAGE_VERSION@/doc_src/
|
||||
tar -c fish-@PACKAGE_VERSION@ >fish-@PACKAGE_VERSION@.tar
|
||||
rm -rf fish-@PACKAGE_VERSION@
|
||||
|
||||
tar: fish-@PACKAGE_VERSION@.tar
|
||||
.PHONY: tar
|
||||
|
||||
fish-@PACKAGE_VERSION@.tar.gz: fish-@PACKAGE_VERSION@.tar
|
||||
gzip -f --best -c fish-@PACKAGE_VERSION@.tar >fish-@PACKAGE_VERSION@.tar.gz
|
||||
|
||||
fish-@PACKAGE_VERSION@.tar.bz2: fish-@PACKAGE_VERSION@.tar
|
||||
bzip2 -f --best -k fish-@PACKAGE_VERSION@.tar
|
||||
|
||||
dist: fish-@PACKAGE_VERSION@.tar.bz2
|
||||
.PHONY: dist
|
||||
|
||||
# Create .rpm file for the current systems architecture and an
|
||||
# .src.rpm file.
|
||||
rpm: fish-@PACKAGE_VERSION@.tar.bz2
|
||||
rpm: fish-@PACKAGE_VERSION@.tar.bz2 fish.spec
|
||||
@if which rpmbuild; then true; else \
|
||||
echo Could not find the rpmbuild command, needed to build an rpm; \
|
||||
echo You may be able to install it using the following command:; \
|
||||
echo \'yum install rpm-build\'; \
|
||||
false; \
|
||||
fi
|
||||
cp fish.spec /usr/src/redhat/SPECS/
|
||||
cp fish-@PACKAGE_VERSION@.tar.bz2 /usr/src/redhat/SOURCES/
|
||||
rpmbuild -ba --clean /usr/src/redhat/SPECS/fish.spec
|
||||
@@ -489,15 +614,15 @@ rpm: fish-@PACKAGE_VERSION@.tar.bz2
|
||||
|
||||
distclean: clean
|
||||
rm -f fish.spec doc_src/fish.1 doc_src/Doxyfile
|
||||
rm -f init/fish init/fish_interactive.fish init/fish_complete.fish
|
||||
rm -f etc/fish etc/fish_interactive.fish seq
|
||||
rm -f config.status config.log config.h Makefile
|
||||
.PHONY: distclean
|
||||
|
||||
clean:
|
||||
rm -f *.o doc.h doc_src/*.doxygen doc_src/*.c builtin_help.c
|
||||
rm -f *.o doc.h doc_src/*.doxygen doc_src/*.c builtin_help.c doc_src/*.o
|
||||
rm -f tests/tmp.err tests/tmp.out tests/tmp.status tests/foo.txt
|
||||
rm -f tokenizer_test fish key_reader set_color gen_hdr2 mimedb
|
||||
rm -f fishd fish_pager count
|
||||
rm -f fishd fish_pager count fish_tests
|
||||
rm -f fish-@PACKAGE_VERSION@.tar
|
||||
rm -f fish-@PACKAGE_VERSION@.tar.gz
|
||||
rm -f fish-@PACKAGE_VERSION@.tar.bz2
|
||||
@@ -511,87 +636,111 @@ clean:
|
||||
|
||||
# DO NOT DELETE THIS LINE -- make depend depends on it.
|
||||
|
||||
builtin.o: config.h util.h wutil.h builtin.h function.h complete.h proc.h
|
||||
builtin.o: io.h parser.h reader.h env.h expand.h common.h wgetopt.h sanity.h
|
||||
builtin.o: tokenizer.h builtin_help.h wildcard.h input_common.h input.h
|
||||
builtin.o: intern.h event.h signal.h translate.h
|
||||
builtin_commandline.o: signal.h config.h util.h builtin.h common.h wgetopt.h
|
||||
builtin_commandline.o: reader.h proc.h io.h parser.h tokenizer.h
|
||||
builtin_commandline.o: input_common.h input.h translate.h
|
||||
builtin_help.o: config.h util.h common.h builtin_help.h
|
||||
builtin_set.o: signal.h config.h util.h builtin.h env.h expand.h common.h
|
||||
builtin_set.o: wgetopt.h proc.h io.h parser.h translate.h
|
||||
builtin_ulimit.o: config.h util.h builtin.h common.h wgetopt.h translate.h
|
||||
common.o: config.h signal.h util.h wutil.h common.h expand.h proc.h io.h
|
||||
common.o: wildcard.h parser.h
|
||||
complete.o: signal.h config.h util.h tokenizer.h wildcard.h proc.h io.h
|
||||
complete.o: parser.h function.h complete.h builtin.h env.h exec.h expand.h
|
||||
complete.o: common.h reader.h history.h intern.h translate.h wutil.h
|
||||
env.o: config.h signal.h util.h wutil.h proc.h io.h common.h env.h sanity.h
|
||||
env.o: expand.h history.h reader.h parser.h env_universal.h
|
||||
env.o: env_universal_common.h input_common.h event.h translate.h
|
||||
env_universal.o: config.h signal.h util.h common.h wutil.h
|
||||
builtin.o: config.h fallback.h util.h wutil.h builtin.h function.h complete.h
|
||||
builtin.o: proc.h io.h parser.h event.h reader.h env.h common.h wgetopt.h
|
||||
builtin.o: sanity.h tokenizer.h wildcard.h input_common.h input.h intern.h
|
||||
builtin.o: signal.h halloc.h halloc_util.h parse_util.h expand.h
|
||||
builtin.o: builtin_help.c builtin_set.c builtin_commandline.c
|
||||
builtin.o: builtin_complete.c builtin_ulimit.c builtin_jobs.c
|
||||
builtin_commandline.o: signal.h config.h fallback.h util.h wutil.h builtin.h
|
||||
builtin_commandline.o: common.h wgetopt.h reader.h proc.h io.h parser.h
|
||||
builtin_commandline.o: event.h tokenizer.h input_common.h input.h
|
||||
builtin_commandline.o: parse_util.h
|
||||
builtin_complete.o: signal.h config.h fallback.h util.h wutil.h builtin.h
|
||||
builtin_complete.o: common.h complete.h wgetopt.h parser.h proc.h io.h
|
||||
builtin_complete.o: event.h reader.h
|
||||
builtin_help.o: config.h util.h common.h halloc_util.h
|
||||
builtin_jobs.o: config.h fallback.h util.h wutil.h builtin.h proc.h io.h
|
||||
builtin_jobs.o: parser.h event.h common.h wgetopt.h
|
||||
builtin_set.o: signal.h config.h fallback.h util.h wutil.h builtin.h env.h
|
||||
builtin_set.o: expand.h common.h wgetopt.h proc.h io.h parser.h event.h
|
||||
builtin_ulimit.o: config.h fallback.h util.h builtin.h common.h wgetopt.h
|
||||
common.o: config.h fallback.h util.h wutil.h common.h expand.h proc.h io.h
|
||||
common.o: wildcard.h parser.h event.h util.c halloc.c halloc.h halloc_util.c
|
||||
common.o: fallback.c
|
||||
complete.o: signal.h config.h fallback.h util.h tokenizer.h wildcard.h proc.h
|
||||
complete.o: io.h parser.h event.h function.h complete.h builtin.h env.h
|
||||
complete.o: exec.h expand.h common.h reader.h history.h intern.h parse_util.h
|
||||
complete.o: halloc.h halloc_util.h wutil.h
|
||||
env.o: config.h signal.h fallback.h util.h wutil.h proc.h io.h common.h env.h
|
||||
env.o: sanity.h expand.h history.h reader.h parser.h event.h env_universal.h
|
||||
env.o: env_universal_common.h input_common.h complete.h
|
||||
env_universal.o: config.h signal.h fallback.h util.h common.h wutil.h
|
||||
env_universal.o: env_universal_common.h env_universal.h
|
||||
env_universal_common.o: signal.h util.h common.h wutil.h
|
||||
env_universal_common.o: config.h signal.h fallback.h util.h common.h wutil.h
|
||||
env_universal_common.o: env_universal_common.h
|
||||
event.o: signal.h config.h util.h function.h proc.h io.h parser.h common.h
|
||||
event.o: event.h translate.h
|
||||
exec.o: signal.h config.h util.h common.h wutil.h proc.h io.h exec.h parser.h
|
||||
exec.o: builtin.h function.h env.h wildcard.h sanity.h expand.h
|
||||
exec.o: env_universal.h env_universal_common.h translate.h
|
||||
expand.o: signal.h config.h util.h common.h wutil.h env.h proc.h io.h
|
||||
expand.o: parser.h expand.h wildcard.h exec.h tokenizer.h complete.h
|
||||
fishd.o: signal.h util.h common.h wutil.h env_universal_common.h
|
||||
fish_pager.o: config.h signal.h util.h wutil.h common.h complete.h output.h
|
||||
fish_pager.o: input_common.h env_universal.h env_universal_common.h
|
||||
fish_tests.o: config.h signal.h util.h common.h proc.h io.h reader.h
|
||||
fish_tests.o: builtin.h function.h complete.h wutil.h env.h expand.h parser.h
|
||||
fish_tests.o: tokenizer.h output.h exec.h event.h
|
||||
function.o: signal.h config.h util.h function.h proc.h io.h parser.h common.h
|
||||
function.o: intern.h event.h
|
||||
highlight.o: signal.h config.h util.h wutil.h highlight.h tokenizer.h proc.h
|
||||
highlight.o: io.h parser.h builtin.h function.h env.h expand.h sanity.h
|
||||
highlight.o: common.h complete.h output.h
|
||||
history.o: config.h util.h wutil.h history.h common.h reader.h env.h sanity.h
|
||||
input.o: config.h signal.h util.h wutil.h reader.h proc.h io.h common.h
|
||||
input.o: sanity.h input_common.h input.h parser.h env.h expand.h event.h
|
||||
input.o: translate.h
|
||||
input_common.o: config.h util.h common.h wutil.h input_common.h
|
||||
event.o: signal.h config.h fallback.h util.h wutil.h function.h proc.h io.h
|
||||
event.o: parser.h event.h common.h halloc_util.h
|
||||
exec.o: signal.h config.h fallback.h util.h common.h wutil.h proc.h io.h
|
||||
exec.o: exec.h parser.h event.h builtin.h function.h env.h wildcard.h
|
||||
exec.o: sanity.h expand.h env_universal.h env_universal_common.h halloc.h
|
||||
exec.o: halloc_util.h parse_util.h
|
||||
expand.o: signal.h config.h fallback.h util.h common.h wutil.h env.h proc.h
|
||||
expand.o: io.h parser.h event.h expand.h wildcard.h exec.h tokenizer.h
|
||||
expand.o: complete.h parse_util.h halloc_util.h
|
||||
fallback.o: config.h fallback.h util.h
|
||||
fishd.o: config.h signal.h fallback.h util.h common.h wutil.h
|
||||
fishd.o: env_universal_common.h
|
||||
fish_pager.o: config.h signal.h fallback.h util.h wutil.h common.h complete.h
|
||||
fish_pager.o: output.h input_common.h env_universal.h env_universal_common.h
|
||||
fish_pager.o: halloc.h halloc_util.h
|
||||
fish_tests.o: config.h signal.h fallback.h util.h common.h proc.h io.h
|
||||
fish_tests.o: reader.h builtin.h function.h complete.h wutil.h env.h expand.h
|
||||
fish_tests.o: parser.h event.h tokenizer.h output.h exec.h halloc_util.h
|
||||
function.o: signal.h config.h wutil.h fallback.h util.h function.h proc.h
|
||||
function.o: io.h parser.h event.h common.h intern.h reader.h parse_util.h
|
||||
function.o: env.h expand.h
|
||||
halloc.o: config.h fallback.h util.h common.h halloc.h
|
||||
halloc_util.o: config.h fallback.h util.h common.h halloc.h
|
||||
highlight.o: signal.h config.h fallback.h util.h wutil.h highlight.h
|
||||
highlight.o: tokenizer.h proc.h io.h parser.h event.h parse_util.h builtin.h
|
||||
highlight.o: function.h env.h expand.h sanity.h common.h complete.h output.h
|
||||
highlight.o: halloc.h halloc_util.h
|
||||
history.o: config.h fallback.h util.h wutil.h history.h common.h reader.h
|
||||
history.o: env.h sanity.h signal.h
|
||||
input.o: config.h signal.h fallback.h util.h wutil.h reader.h proc.h io.h
|
||||
input.o: common.h sanity.h input_common.h input.h parser.h event.h env.h
|
||||
input.o: expand.h output.h intern.h
|
||||
input_common.o: config.h fallback.h util.h common.h wutil.h input_common.h
|
||||
input_common.o: env_universal.h env_universal_common.h
|
||||
intern.o: config.h util.h common.h intern.h
|
||||
io.o: config.h util.h wutil.h exec.h proc.h io.h common.h translate.h
|
||||
key_reader.o: input_common.h
|
||||
kill.o: signal.h config.h util.h wutil.h kill.h proc.h io.h sanity.h common.h
|
||||
kill.o: env.h expand.h exec.h parser.h
|
||||
main.o: config.h signal.h util.h common.h reader.h builtin.h function.h
|
||||
main.o: complete.h wutil.h env.h sanity.h proc.h io.h parser.h expand.h
|
||||
main.o: intern.h exec.h event.h output.h translate.h
|
||||
mimedb.o: config.h xdgmime.h util.h
|
||||
output.o: config.h signal.h util.h wutil.h expand.h common.h output.h
|
||||
output.o: highlight.h
|
||||
parser.o: signal.h config.h util.h common.h wutil.h proc.h io.h parser.h
|
||||
parser.o: tokenizer.h exec.h wildcard.h function.h builtin.h builtin_help.h
|
||||
intern.o: config.h fallback.h util.h wutil.h common.h intern.h
|
||||
io.o: config.h fallback.h util.h wutil.h exec.h proc.h io.h common.h halloc.h
|
||||
key_reader.o: config.h fallback.h input_common.h
|
||||
kill.o: signal.h config.h fallback.h util.h wutil.h kill.h proc.h io.h
|
||||
kill.o: sanity.h common.h env.h exec.h parser.h event.h halloc.h
|
||||
main.o: config.h signal.h fallback.h util.h common.h reader.h builtin.h
|
||||
main.o: function.h complete.h wutil.h env.h sanity.h proc.h io.h parser.h
|
||||
main.o: event.h expand.h intern.h exec.h output.h halloc_util.h history.h
|
||||
mimedb.o: config.h xdgmime.h fallback.h util.h
|
||||
output.o: config.h signal.h fallback.h util.h wutil.h expand.h common.h
|
||||
output.o: output.h halloc_util.h highlight.h
|
||||
parser.o: signal.h config.h fallback.h util.h common.h wutil.h proc.h io.h
|
||||
parser.o: parser.h event.h tokenizer.h exec.h wildcard.h function.h builtin.h
|
||||
parser.o: env.h expand.h reader.h sanity.h env_universal.h
|
||||
parser.o: env_universal_common.h event.h translate.h
|
||||
proc.o: config.h signal.h util.h wutil.h proc.h io.h common.h reader.h
|
||||
proc.o: sanity.h env.h parser.h event.h translate.h
|
||||
reader.o: config.h signal.h util.h wutil.h highlight.h reader.h proc.h io.h
|
||||
reader.o: parser.h complete.h history.h common.h sanity.h env.h exec.h
|
||||
reader.o: expand.h tokenizer.h kill.h input_common.h input.h function.h
|
||||
reader.o: output.h translate.h
|
||||
sanity.o: signal.h config.h util.h common.h sanity.h proc.h io.h history.h
|
||||
sanity.o: reader.h kill.h wutil.h
|
||||
set_color.o: config.h
|
||||
signal.o: config.h signal.h common.h util.h wutil.h event.h reader.h proc.h
|
||||
signal.o: io.h translate.h
|
||||
tokenizer.o: config.h util.h wutil.h tokenizer.h common.h wildcard.h
|
||||
tokenizer.o: translate.h
|
||||
translate.o: config.h common.h util.h
|
||||
util.o: config.h util.h common.h wutil.h
|
||||
wgetopt.o: config.h wgetopt.h wutil.h
|
||||
wildcard.o: config.h util.h wutil.h complete.h common.h wildcard.h reader.h
|
||||
wildcard.o: expand.h translate.h
|
||||
wutil.o: config.h util.h common.h wutil.h
|
||||
parser.o: env_universal_common.h intern.h parse_util.h halloc.h halloc_util.h
|
||||
parse_util.o: config.h fallback.h util.h wutil.h common.h tokenizer.h
|
||||
parse_util.o: parse_util.h expand.h intern.h exec.h proc.h io.h env.h
|
||||
parse_util.o: wildcard.h halloc_util.h
|
||||
proc.o: config.h signal.h fallback.h util.h wutil.h proc.h io.h common.h
|
||||
proc.o: reader.h sanity.h env.h parser.h event.h halloc.h halloc_util.h
|
||||
proc.o: output.h
|
||||
reader.o: config.h signal.h fallback.h util.h wutil.h highlight.h reader.h
|
||||
reader.o: proc.h io.h parser.h event.h complete.h history.h common.h sanity.h
|
||||
reader.o: env.h exec.h expand.h tokenizer.h kill.h input_common.h input.h
|
||||
reader.o: function.h output.h parse_util.h
|
||||
sanity.o: signal.h config.h fallback.h util.h common.h sanity.h proc.h io.h
|
||||
sanity.o: history.h reader.h kill.h wutil.h
|
||||
set_color.o: config.h fallback.h
|
||||
signal.o: config.h signal.h common.h util.h fallback.h wutil.h event.h
|
||||
signal.o: reader.h proc.h io.h
|
||||
test.o: stringtab.h
|
||||
tokenizer.o: config.h fallback.h util.h wutil.h tokenizer.h common.h
|
||||
tokenizer.o: wildcard.h
|
||||
util.o: config.h fallback.h util.h common.h wutil.h
|
||||
wgetopt.o: config.h wgetopt.h wutil.h fallback.h
|
||||
wildcard.o: config.h fallback.h util.h wutil.h complete.h common.h wildcard.h
|
||||
wildcard.o: reader.h expand.h
|
||||
wutil.o: config.h fallback.h util.h common.h wutil.h halloc.h halloc_util.h
|
||||
xdgmimealias.o: xdgmimealias.h xdgmime.h xdgmimeint.h
|
||||
xdgmime.o: xdgmime.h xdgmimeint.h xdgmimeglob.h xdgmimemagic.h xdgmimealias.h
|
||||
xdgmime.o: xdgmimeparent.h
|
||||
|
||||
56
builtin.h
56
builtin.h
@@ -57,6 +57,16 @@ enum
|
||||
*/
|
||||
#define BUILTIN_ERR_VARNAME_ZERO _( L"%ls: Variable name can not be the empty string\n" )
|
||||
|
||||
/**
|
||||
Error message when second argument to for isn't 'in'
|
||||
*/
|
||||
#define BUILTIN_FOR_ERR_IN _( L"%ls: Second argument must be 'in'\n" )
|
||||
|
||||
/**
|
||||
Error message when too many arguments are supplied to a builtin
|
||||
*/
|
||||
#define BUILTIN_ERR_TOO_MANY_ARGUMENTS _( L"%ls: Too many arguments\n" )
|
||||
|
||||
/**
|
||||
Stringbuffer used to represent standard output
|
||||
*/
|
||||
@@ -126,46 +136,22 @@ void builtin_pop_io();
|
||||
*/
|
||||
const wchar_t *builtin_get_desc( const wchar_t *b );
|
||||
|
||||
/**
|
||||
Counts the number of non null pointers in the specified array
|
||||
*/
|
||||
int builtin_count_args( wchar_t **argv );
|
||||
|
||||
/**
|
||||
Print help for the specified builtin. If \c b is sb_err, also print the line information
|
||||
Slightly kludgy function used with 'complete -C' in order to make
|
||||
the commandline builtin operate on the string to complete instead
|
||||
of operating on whatever is to be completed.
|
||||
*/
|
||||
void builtin_print_help( wchar_t *cmd, string_buffer_t *b );
|
||||
|
||||
|
||||
/**
|
||||
The set builtin, used for setting variables. Defined in builtin_set.c.
|
||||
*/
|
||||
int builtin_set(wchar_t **argv);
|
||||
|
||||
/**
|
||||
The commandline builtin, used for setting and getting the contents of the commandline. Defined in builtin_commandline.c.
|
||||
*/
|
||||
int builtin_commandline(wchar_t **argv);
|
||||
|
||||
/**
|
||||
The ulimit builtin, used for setting resource limits. Defined in builtin_ulimit.c.
|
||||
*/
|
||||
int builtin_ulimit(wchar_t **argv);
|
||||
|
||||
/**
|
||||
The complete builtin. Used for specifying programmable
|
||||
tab-completions. Calls the functions in complete.c for any heavy
|
||||
lifting.
|
||||
*/
|
||||
int builtin_complete(wchar_t **argv);
|
||||
|
||||
const wchar_t *builtin_complete_get_temporary_buffer();
|
||||
|
||||
/**
|
||||
This function works like wperror, but it prints its result into
|
||||
the sb_err string_buffer_t instead of to stderr. Used by the builtin
|
||||
commands.
|
||||
|
||||
/**
|
||||
Return the help text for the specified builtin command. Use
|
||||
non-wide characters since wide characters have some issues with
|
||||
string formating escape sequences sometimes.
|
||||
|
||||
\param cmd The command for which to obtain help text
|
||||
*/
|
||||
void builtin_wperror( const wchar_t *s);
|
||||
char *builtin_help_get( const wchar_t *cmd );
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
Functions used for implementing the commandline builtin.
|
||||
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <wchar.h>
|
||||
@@ -11,8 +13,9 @@ Functions used for implementing the commandline builtin.
|
||||
#include <termios.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "fallback.h"
|
||||
#include "util.h"
|
||||
|
||||
#include "wutil.h"
|
||||
#include "builtin.h"
|
||||
#include "common.h"
|
||||
@@ -23,7 +26,7 @@ Functions used for implementing the commandline builtin.
|
||||
#include "tokenizer.h"
|
||||
#include "input_common.h"
|
||||
#include "input.h"
|
||||
#include "translate.h"
|
||||
|
||||
#include "parse_util.h"
|
||||
|
||||
/**
|
||||
@@ -60,6 +63,9 @@ static const wchar_t *get_buffer()
|
||||
return buff;
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the position of the cursor
|
||||
*/
|
||||
static int get_cursor_pos()
|
||||
{
|
||||
const wchar_t *buff = builtin_complete_get_temporary_buffer();
|
||||
@@ -192,7 +198,7 @@ static void write_part( const wchar_t *begin,
|
||||
The commandline builtin. It is used for specifying a new value for
|
||||
the commandline.
|
||||
*/
|
||||
int builtin_commandline( wchar_t **argv )
|
||||
static int builtin_commandline( wchar_t **argv )
|
||||
{
|
||||
|
||||
int buffer_part=0;
|
||||
@@ -262,6 +268,10 @@ int builtin_commandline( wchar_t **argv )
|
||||
L"tokenize", no_argument, 0, 'o'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"help", no_argument, 0, 'h'
|
||||
}
|
||||
,
|
||||
{
|
||||
0, 0, 0, 0
|
||||
}
|
||||
@@ -272,7 +282,7 @@ int builtin_commandline( wchar_t **argv )
|
||||
|
||||
int opt = wgetopt_long( argc,
|
||||
argv,
|
||||
L"aijpctwfor",
|
||||
L"aijpctwforh",
|
||||
long_options,
|
||||
&opt_index );
|
||||
if( opt == -1 )
|
||||
@@ -327,6 +337,10 @@ int builtin_commandline( wchar_t **argv )
|
||||
tokenize=1;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
builtin_print_help( argv[0], sb_out );
|
||||
return 0;
|
||||
|
||||
case L'?':
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
return 1;
|
||||
@@ -450,13 +464,13 @@ int builtin_commandline( wchar_t **argv )
|
||||
buffer_part = STRING_MODE;
|
||||
}
|
||||
|
||||
const wchar_t *begin, *end;
|
||||
wchar_t *begin, *end;
|
||||
|
||||
switch( buffer_part )
|
||||
{
|
||||
case STRING_MODE:
|
||||
{
|
||||
begin = get_buffer();
|
||||
begin = (wchar_t *)get_buffer();
|
||||
end = begin+wcslen(begin);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
Functions used for implementing the complete builtin.
|
||||
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <wchar.h>
|
||||
@@ -11,8 +13,9 @@ Functions used for implementing the complete builtin.
|
||||
#include <termios.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "fallback.h"
|
||||
#include "util.h"
|
||||
|
||||
#include "wutil.h"
|
||||
#include "builtin.h"
|
||||
#include "common.h"
|
||||
@@ -20,16 +23,25 @@ Functions used for implementing the complete builtin.
|
||||
#include "wgetopt.h"
|
||||
#include "parser.h"
|
||||
#include "reader.h"
|
||||
#include "translate.h"
|
||||
|
||||
|
||||
/**
|
||||
Internal storage for the builtin_get_temporary_buffer() function.
|
||||
*/
|
||||
const static wchar_t *temporary_buffer;
|
||||
|
||||
/*
|
||||
builtin_complete_* are a set of rather silly looping functions that
|
||||
make sure that all the proper combinations of complete_add or
|
||||
complete_remove get called.
|
||||
complete_remove get called. This is needed since complete allows you
|
||||
to specify multiple switches on a single commandline, like 'complete
|
||||
-s a -s b -s c', but the complete_add function only accepts one
|
||||
short switch and one long switch.
|
||||
*/
|
||||
|
||||
/**
|
||||
Silly function
|
||||
*/
|
||||
static void builtin_complete_add2( const wchar_t *cmd,
|
||||
int cmd_type,
|
||||
const wchar_t *short_opt,
|
||||
@@ -101,6 +113,9 @@ static void builtin_complete_add2( const wchar_t *cmd,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Silly function
|
||||
*/
|
||||
static void builtin_complete_add( array_list_t *cmd,
|
||||
array_list_t *path,
|
||||
const wchar_t *short_opt,
|
||||
@@ -144,6 +159,9 @@ static void builtin_complete_add( array_list_t *cmd,
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
Silly function
|
||||
*/
|
||||
static void builtin_complete_remove3( wchar_t *cmd,
|
||||
int cmd_type,
|
||||
wchar_t short_opt,
|
||||
@@ -160,6 +178,9 @@ static void builtin_complete_remove3( wchar_t *cmd,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Silly function
|
||||
*/
|
||||
static void builtin_complete_remove2( wchar_t *cmd,
|
||||
int cmd_type,
|
||||
const wchar_t *short_opt,
|
||||
@@ -208,6 +229,9 @@ static void builtin_complete_remove2( wchar_t *cmd,
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
Silly function
|
||||
*/
|
||||
static void builtin_complete_remove( array_list_t *cmd,
|
||||
array_list_t *path,
|
||||
const wchar_t *short_opt,
|
||||
@@ -243,7 +267,12 @@ const wchar_t *builtin_complete_get_temporary_buffer()
|
||||
return temporary_buffer;
|
||||
}
|
||||
|
||||
int builtin_complete( wchar_t **argv )
|
||||
/**
|
||||
The complete builtin. Used for specifying programmable
|
||||
tab-completions. Calls the functions in complete.c for any heavy
|
||||
lifting. Defined in builtin_complete.c
|
||||
*/
|
||||
static int builtin_complete( wchar_t **argv )
|
||||
{
|
||||
int res=0;
|
||||
int argc=0;
|
||||
@@ -253,7 +282,7 @@ int builtin_complete( wchar_t **argv )
|
||||
|
||||
string_buffer_t short_opt;
|
||||
array_list_t gnu_opt, old_opt;
|
||||
wchar_t *comp=L"", *desc=L"", *condition=L"", *load=0;
|
||||
wchar_t *comp=L"", *desc=L"", *condition=L"";
|
||||
|
||||
wchar_t *do_complete = 0;
|
||||
|
||||
@@ -307,7 +336,8 @@ int builtin_complete( wchar_t **argv )
|
||||
}
|
||||
,
|
||||
{
|
||||
L"long-option", required_argument, 0, 'l' }
|
||||
L"long-option", required_argument, 0, 'l'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"old-option", required_argument, 0, 'o'
|
||||
@@ -334,11 +364,11 @@ int builtin_complete( wchar_t **argv )
|
||||
}
|
||||
,
|
||||
{
|
||||
L"load", required_argument, 0, 'y'
|
||||
L"do-complete", optional_argument, 0, 'C'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"do-complete", required_argument, 0, 'C'
|
||||
L"help", no_argument, 0, 'h'
|
||||
}
|
||||
,
|
||||
{
|
||||
@@ -351,7 +381,7 @@ int builtin_complete( wchar_t **argv )
|
||||
|
||||
int opt = wgetopt_long( argc,
|
||||
argv,
|
||||
L"a:c:p:s:l:o:d:frxeun:y:C:",
|
||||
L"a:c:p:s:l:o:d:frxeun:C::h",
|
||||
long_options,
|
||||
&opt_index );
|
||||
if( opt == -1 )
|
||||
@@ -368,7 +398,8 @@ int builtin_complete( wchar_t **argv )
|
||||
long_options[opt_index].name );
|
||||
sb_append( sb_err,
|
||||
parser_current_line() );
|
||||
// builtin_print_help( argv[0], sb_err );
|
||||
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
|
||||
|
||||
res = 1;
|
||||
@@ -387,12 +418,20 @@ int builtin_complete( wchar_t **argv )
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
al_push( &cmd, unescape( woptarg, 1));
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
al_push( &cmd, unescape( woptarg, 1) );
|
||||
{
|
||||
wchar_t *a = unescape( woptarg, 1);
|
||||
if( a )
|
||||
{
|
||||
al_push( (opt=='p'?&path:&cmd), a );
|
||||
}
|
||||
else
|
||||
{
|
||||
sb_printf( sb_err, L"%ls: Invalid token '%ls'\n", argv[0], woptarg );
|
||||
res = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'd':
|
||||
desc = woptarg;
|
||||
@@ -418,26 +457,26 @@ int builtin_complete( wchar_t **argv )
|
||||
comp = woptarg;
|
||||
break;
|
||||
|
||||
|
||||
case 'e':
|
||||
remove = 1;
|
||||
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
condition = woptarg;
|
||||
break;
|
||||
|
||||
case 'y':
|
||||
load = woptarg;
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
do_complete = woptarg?woptarg:reader_get_buffer();
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
builtin_print_help( argv[0], sb_out );
|
||||
return 0;
|
||||
|
||||
case '?':
|
||||
// builtin_print_help( argv[0], sb_err );
|
||||
sb_append( sb_err,
|
||||
parser_current_line() );
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
|
||||
res = 1;
|
||||
break;
|
||||
@@ -446,92 +485,123 @@ int builtin_complete( wchar_t **argv )
|
||||
|
||||
}
|
||||
|
||||
if( res != 0 )
|
||||
if( !res )
|
||||
{
|
||||
}
|
||||
else if( do_complete )
|
||||
{
|
||||
array_list_t comp;
|
||||
int i;
|
||||
|
||||
const wchar_t *prev_temporary_buffer = temporary_buffer;
|
||||
temporary_buffer = do_complete;
|
||||
|
||||
if( recursion_level < 1 )
|
||||
if( condition && wcslen( condition ) )
|
||||
{
|
||||
recursion_level++;
|
||||
if( parser_test( condition, 0, 0 ) )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
L"%ls: Condition '%ls' contained a syntax error\n",
|
||||
argv[0],
|
||||
condition );
|
||||
|
||||
parser_test( condition, sb_err, argv[0] );
|
||||
|
||||
res = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( !res )
|
||||
{
|
||||
if( comp && wcslen( comp ) )
|
||||
{
|
||||
if( parser_test_args( comp, 0, 0 ) )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
L"%ls: Completion '%ls' contained a syntax error\n",
|
||||
argv[0],
|
||||
comp );
|
||||
|
||||
parser_test_args( comp, sb_err, argv[0] );
|
||||
|
||||
res = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( !res )
|
||||
{
|
||||
if( do_complete )
|
||||
{
|
||||
array_list_t comp;
|
||||
int i;
|
||||
|
||||
const wchar_t *prev_temporary_buffer = temporary_buffer;
|
||||
temporary_buffer = do_complete;
|
||||
|
||||
if( recursion_level < 1 )
|
||||
{
|
||||
recursion_level++;
|
||||
|
||||
al_init( &comp );
|
||||
|
||||
complete( do_complete, &comp );
|
||||
|
||||
for( i=0; i<al_get_count( &comp ); i++ )
|
||||
{
|
||||
wchar_t *next = (wchar_t *)al_get( &comp, i );
|
||||
wchar_t *sep = wcschr( next, COMPLETE_SEP );
|
||||
if( sep )
|
||||
*sep = L'\t';
|
||||
sb_printf( sb_out, L"%ls\n", next );
|
||||
}
|
||||
|
||||
al_foreach( &comp, &free );
|
||||
al_destroy( &comp );
|
||||
recursion_level--;
|
||||
}
|
||||
|
||||
temporary_buffer = prev_temporary_buffer;
|
||||
|
||||
al_init( &comp );
|
||||
|
||||
complete( do_complete, &comp );
|
||||
|
||||
for( i=0; i<al_get_count( &comp ); i++ )
|
||||
{
|
||||
wchar_t *next = (wchar_t *)al_get( &comp, i );
|
||||
wchar_t *sep = wcschr( next, COMPLETE_SEP );
|
||||
if( sep )
|
||||
*sep = L'\t';
|
||||
sb_printf( sb_out, L"%ls\n", next );
|
||||
}
|
||||
|
||||
al_foreach( &comp, (void (*)(const void *))&free );
|
||||
al_destroy( &comp );
|
||||
recursion_level--;
|
||||
}
|
||||
|
||||
temporary_buffer = prev_temporary_buffer;
|
||||
|
||||
}
|
||||
else if( woptind != argc )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
_( L"%ls: Too many arguments\n" ),
|
||||
argv[0] );
|
||||
sb_append( sb_err,
|
||||
parser_current_line() );
|
||||
// builtin_print_help( argv[0], sb_err );
|
||||
|
||||
res = 1;
|
||||
}
|
||||
else if( load )
|
||||
{
|
||||
complete_load( load, 1 );
|
||||
}
|
||||
else if( (al_get_count( &cmd) == 0 ) && (al_get_count( &path) == 0 ) )
|
||||
{
|
||||
/* No arguments specified, meaning we print the definitions of
|
||||
* all specified completions to stdout.*/
|
||||
complete_print( sb_out );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( remove )
|
||||
else if( woptind != argc )
|
||||
{
|
||||
builtin_complete_remove( &cmd,
|
||||
&path,
|
||||
(wchar_t *)short_opt.buff,
|
||||
&gnu_opt,
|
||||
&old_opt );
|
||||
sb_printf( sb_err,
|
||||
_( L"%ls: Too many arguments\n" ),
|
||||
argv[0] );
|
||||
sb_append( sb_err,
|
||||
parser_current_line() );
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
|
||||
res = 1;
|
||||
}
|
||||
else if( (al_get_count( &cmd) == 0 ) && (al_get_count( &path) == 0 ) )
|
||||
{
|
||||
/* No arguments specified, meaning we print the definitions of
|
||||
* all specified completions to stdout.*/
|
||||
complete_print( sb_out );
|
||||
}
|
||||
else
|
||||
{
|
||||
builtin_complete_add( &cmd,
|
||||
&path,
|
||||
(wchar_t *)short_opt.buff,
|
||||
&gnu_opt,
|
||||
&old_opt,
|
||||
result_mode,
|
||||
authorative,
|
||||
condition,
|
||||
comp,
|
||||
desc );
|
||||
}
|
||||
if( remove )
|
||||
{
|
||||
builtin_complete_remove( &cmd,
|
||||
&path,
|
||||
(wchar_t *)short_opt.buff,
|
||||
&gnu_opt,
|
||||
&old_opt );
|
||||
}
|
||||
else
|
||||
{
|
||||
builtin_complete_add( &cmd,
|
||||
&path,
|
||||
(wchar_t *)short_opt.buff,
|
||||
&gnu_opt,
|
||||
&old_opt,
|
||||
result_mode,
|
||||
authorative,
|
||||
condition,
|
||||
comp,
|
||||
desc );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
al_foreach( &cmd, (void (*)(const void *))&free );
|
||||
al_foreach( &path, (void (*)(const void *))&free );
|
||||
}
|
||||
}
|
||||
|
||||
al_foreach( &cmd, &free );
|
||||
al_foreach( &path, &free );
|
||||
|
||||
al_destroy( &cmd );
|
||||
al_destroy( &path );
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
/** \file builtin_help.h
|
||||
|
||||
Prototypes for functions for printing usage information of builtin commands. The
|
||||
corresponding .c file is automatically generated by combining the
|
||||
builtin_help.hdr file with doxygen output.
|
||||
*/
|
||||
|
||||
#ifndef FISH_BUILTIN_HELP_H
|
||||
#define FISH_BUILTIN_HELP_H
|
||||
|
||||
#include <wchar.h>
|
||||
|
||||
/**
|
||||
Return the help text for the specified builtin command. Use
|
||||
non-wide characters since wide characters have some issues with
|
||||
string formating escape sequences sometimes.
|
||||
|
||||
\param cmd The command for which to obtain help text
|
||||
*/
|
||||
char *builtin_help_get( wchar_t *cmd );
|
||||
|
||||
/**
|
||||
Initialize builtin help data
|
||||
*/
|
||||
void builtin_help_init();
|
||||
|
||||
/**
|
||||
Destory builtin help data
|
||||
*/
|
||||
void builtin_help_destroy();
|
||||
|
||||
#endif
|
||||
@@ -5,33 +5,41 @@
|
||||
various help files in the doc_src directory.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <strings.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "util.h"
|
||||
#include "common.h"
|
||||
#include "builtin_help.h"
|
||||
#include "halloc_util.h"
|
||||
|
||||
/**
|
||||
Hashtable storing the help text
|
||||
*/
|
||||
static hash_table_t tbl;
|
||||
|
||||
char *builtin_help_get( wchar_t *cmd )
|
||||
static void builtin_help_init();
|
||||
|
||||
char *builtin_help_get( const wchar_t *cmd )
|
||||
{
|
||||
builtin_help_init();
|
||||
|
||||
return (char *)hash_get( &tbl, (void *)cmd );
|
||||
}
|
||||
|
||||
void builtin_help_destroy()
|
||||
{
|
||||
hash_destroy( &tbl );
|
||||
}
|
||||
|
||||
|
||||
void builtin_help_init()
|
||||
/**
|
||||
Initialize help hash table. Don't invoke it manually,
|
||||
it is called by builtin_help_get automatically.
|
||||
*/
|
||||
static void builtin_help_init()
|
||||
{
|
||||
static int is_help_init = 0;
|
||||
if( is_help_init )
|
||||
return;
|
||||
is_help_init=1;
|
||||
halloc_register_function( global_context, (void (*)(void *))&hash_destroy, &tbl );
|
||||
hash_init( &tbl, &hash_wcs_func, &hash_wcs_cmp );
|
||||
|
||||
351
builtin_jobs.c
Normal file
351
builtin_jobs.c
Normal file
@@ -0,0 +1,351 @@
|
||||
/** \file builtin_jobs.c
|
||||
Functions for executing the jobs builtin.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <wchar.h>
|
||||
#include <unistd.h>
|
||||
#include <termios.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
#include <wctype.h>
|
||||
|
||||
#include "fallback.h"
|
||||
#include "util.h"
|
||||
|
||||
#include "wutil.h"
|
||||
#include "builtin.h"
|
||||
#include "proc.h"
|
||||
#include "parser.h"
|
||||
#include "common.h"
|
||||
#include "wgetopt.h"
|
||||
|
||||
|
||||
/**
|
||||
Print modes for the jobs builtin
|
||||
*/
|
||||
enum
|
||||
{
|
||||
JOBS_DEFAULT, /**< Print lots of general info */
|
||||
JOBS_PRINT_PID, /**< Print pid of each process in job */
|
||||
JOBS_PRINT_COMMAND, /**< Print command name of each process in job */
|
||||
JOBS_PRINT_GROUP, /**< Print group id of job */
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
|
||||
#ifdef HAVE__PROC_SELF_STAT
|
||||
/**
|
||||
Calculates the cpu usage (in percent) of the specified job.
|
||||
*/
|
||||
static int cpu_use( job_t *j )
|
||||
{
|
||||
double u=0;
|
||||
process_t *p;
|
||||
|
||||
for( p=j->first_process; p; p=p->next )
|
||||
{
|
||||
struct timeval t;
|
||||
int jiffies;
|
||||
gettimeofday( &t, 0 );
|
||||
jiffies = proc_get_jiffies( p );
|
||||
|
||||
double t1 = 1000000.0*p->last_time.tv_sec+p->last_time.tv_usec;
|
||||
double t2 = 1000000.0*t.tv_sec+t.tv_usec;
|
||||
|
||||
/* fwprintf( stderr, L"t1 %f t2 %f p1 %d p2 %d\n",
|
||||
t1, t2, jiffies, p->last_jiffies );
|
||||
*/
|
||||
|
||||
u += ((double)(jiffies-p->last_jiffies))/(t2-t1);
|
||||
}
|
||||
return u*1000000;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
Print information about the specified job
|
||||
*/
|
||||
static void builtin_jobs_print( job_t *j, int mode, int header )
|
||||
{
|
||||
process_t *p;
|
||||
switch( mode )
|
||||
{
|
||||
case JOBS_DEFAULT:
|
||||
{
|
||||
|
||||
if( header )
|
||||
{
|
||||
/*
|
||||
Print table header before first job
|
||||
*/
|
||||
sb_append( sb_out, _( L"Job\tGroup\t" ));
|
||||
#ifdef HAVE__PROC_SELF_STAT
|
||||
sb_append( sb_out, _( L"CPU\t" ) );
|
||||
#endif
|
||||
sb_append( sb_out, _( L"State\tCommand\n" ) );
|
||||
}
|
||||
|
||||
sb_printf( sb_out, L"%d\t%d\t", j->job_id, j->pgid );
|
||||
|
||||
#ifdef HAVE__PROC_SELF_STAT
|
||||
sb_printf( sb_out, L"%d%%\t", cpu_use(j) );
|
||||
#endif
|
||||
sb_append2( sb_out,
|
||||
job_is_stopped(j)?_(L"stopped"):_(L"running"),
|
||||
L"\t",
|
||||
j->command,
|
||||
L"\n",
|
||||
(void *)0 );
|
||||
break;
|
||||
}
|
||||
|
||||
case JOBS_PRINT_GROUP:
|
||||
{
|
||||
if( header )
|
||||
{
|
||||
/*
|
||||
Print table header before first job
|
||||
*/
|
||||
sb_append( sb_out, _( L"Group\n" ));
|
||||
}
|
||||
sb_printf( sb_out, L"%d\n", j->pgid );
|
||||
break;
|
||||
}
|
||||
|
||||
case JOBS_PRINT_PID:
|
||||
{
|
||||
if( header )
|
||||
{
|
||||
/*
|
||||
Print table header before first job
|
||||
*/
|
||||
sb_append( sb_out, _( L"Procces\n" ));
|
||||
}
|
||||
|
||||
for( p=j->first_process; p; p=p->next )
|
||||
{
|
||||
sb_printf( sb_out, L"%d\n", p->pid );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case JOBS_PRINT_COMMAND:
|
||||
{
|
||||
if( header )
|
||||
{
|
||||
/*
|
||||
Print table header before first job
|
||||
*/
|
||||
sb_append( sb_out, _( L"Command\n" ));
|
||||
}
|
||||
|
||||
for( p=j->first_process; p; p=p->next )
|
||||
{
|
||||
sb_printf( sb_out, L"%ls\n", p->argv[0] );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
The jobs builtin. Used fopr printing running jobs. Defined in builtin_jobs.c.
|
||||
*/
|
||||
static int builtin_jobs( wchar_t **argv )
|
||||
{
|
||||
int argc=0;
|
||||
int found=0;
|
||||
int mode=JOBS_DEFAULT;
|
||||
int print_last = 0;
|
||||
job_t *j;
|
||||
|
||||
argc = builtin_count_args( argv );
|
||||
woptind=0;
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
const static struct woption
|
||||
long_options[] =
|
||||
{
|
||||
{
|
||||
L"pid", no_argument, 0, 'p'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"command", no_argument, 0, 'c'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"group", no_argument, 0, 'g'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"last", no_argument, 0, 'l'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"help", no_argument, 0, 'h'
|
||||
}
|
||||
,
|
||||
{
|
||||
0, 0, 0, 0
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
int opt_index = 0;
|
||||
|
||||
int opt = wgetopt_long( argc,
|
||||
argv,
|
||||
L"pclgh",
|
||||
long_options,
|
||||
&opt_index );
|
||||
if( opt == -1 )
|
||||
break;
|
||||
|
||||
switch( opt )
|
||||
{
|
||||
case 0:
|
||||
if(long_options[opt_index].flag != 0)
|
||||
break;
|
||||
sb_printf( sb_err,
|
||||
BUILTIN_ERR_UNKNOWN,
|
||||
argv[0],
|
||||
long_options[opt_index].name );
|
||||
|
||||
sb_append( sb_err,
|
||||
parser_current_line() );
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
|
||||
|
||||
return 1;
|
||||
|
||||
|
||||
case 'p':
|
||||
mode=JOBS_PRINT_PID;
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
mode=JOBS_PRINT_COMMAND;
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
mode=JOBS_PRINT_GROUP;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
{
|
||||
print_last = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
case 'h':
|
||||
builtin_print_help( argv[0], sb_out );
|
||||
return 0;
|
||||
|
||||
case '?':
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Do not babble if not interactive
|
||||
*/
|
||||
if( builtin_out_redirect )
|
||||
{
|
||||
found=1;
|
||||
}
|
||||
|
||||
if( print_last )
|
||||
{
|
||||
/*
|
||||
Ignore unconstructed jobs, i.e. ourself.
|
||||
*/
|
||||
for( j=first_job; j; j=j->next )
|
||||
{
|
||||
if( j->constructed && !job_is_completed(j) )
|
||||
{
|
||||
builtin_jobs_print( j, mode, !found );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if( woptind < argc )
|
||||
{
|
||||
int i;
|
||||
|
||||
found = 1;
|
||||
|
||||
for( i=woptind; i<argc; i++ )
|
||||
{
|
||||
long pid;
|
||||
wchar_t *end;
|
||||
errno=0;
|
||||
pid=wcstol( argv[i], &end, 10 );
|
||||
if( errno || *end )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
_( L"%ls: '%ls' is not a job\n" ),
|
||||
argv[0],
|
||||
argv[i] );
|
||||
return 1;
|
||||
}
|
||||
|
||||
j = job_get_from_pid( pid );
|
||||
|
||||
if( j && !job_is_completed( j ) )
|
||||
{
|
||||
builtin_jobs_print( j, mode, !found );
|
||||
}
|
||||
else
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
_( L"%ls: No suitable job: %d\n" ),
|
||||
argv[0],
|
||||
pid );
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( j= first_job; j; j=j->next )
|
||||
{
|
||||
/*
|
||||
Ignore unconstructed jobs, i.e. ourself.
|
||||
*/
|
||||
if( j->constructed && !job_is_completed(j) )
|
||||
{
|
||||
builtin_jobs_print( j, mode, !found );
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( !found )
|
||||
{
|
||||
sb_printf( sb_out,
|
||||
_( L"%ls: There are no jobs\n" ),
|
||||
argv[0] );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
753
builtin_set.c
753
builtin_set.c
@@ -3,6 +3,8 @@
|
||||
Functions used for implementing the set builtin.
|
||||
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <wchar.h>
|
||||
@@ -11,8 +13,9 @@ Functions used for implementing the set builtin.
|
||||
#include <termios.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "fallback.h"
|
||||
#include "util.h"
|
||||
|
||||
#include "wutil.h"
|
||||
#include "builtin.h"
|
||||
#include "env.h"
|
||||
@@ -21,48 +24,175 @@ Functions used for implementing the set builtin.
|
||||
#include "wgetopt.h"
|
||||
#include "proc.h"
|
||||
#include "parser.h"
|
||||
#include "translate.h"
|
||||
|
||||
/**
|
||||
Extract the name from a destination argument of the form name[index1 index2...]
|
||||
|
||||
/**
|
||||
Error message for invalid path operations
|
||||
*/
|
||||
static int parse_fill_name( string_buffer_t *name,
|
||||
const wchar_t *src)
|
||||
#define BUILTIN_SET_PATH_ERROR L"%ls: Could not add component %ls to %ls.\n"
|
||||
|
||||
/**
|
||||
Hint for invalid path operation with a colon
|
||||
*/
|
||||
#define BUILTIN_SET_PATH_HINT L"%ls: Did you mean 'set %ls $%ls %ls'?\n"
|
||||
|
||||
/**
|
||||
Error for mismatch between index count and elements
|
||||
*/
|
||||
#define BUILTIN_SET_ARG_COUNT L"%ls: The number of variable indexes does not match the number of values\n"
|
||||
|
||||
/**
|
||||
Test if the specified variable should be subject to path validation
|
||||
*/
|
||||
static int is_path_variable( const wchar_t *env )
|
||||
{
|
||||
|
||||
if (src == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (iswalnum(*src) || *src == L'_')
|
||||
{
|
||||
sb_append_char(name, *src++);
|
||||
}
|
||||
|
||||
if (*src != L'[' && *src != L'\0')
|
||||
{
|
||||
sb_printf( sb_err, BUILTIN_ERR_VARCHAR, L"set", *src );
|
||||
sb_append2(sb_err, parser_current_line(), L"\n", (void *)0 );
|
||||
// builtin_print_help( L"set", sb_err );
|
||||
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return contains_str( env,
|
||||
L"PATH",
|
||||
L"CDPATH",
|
||||
(void *)0 );
|
||||
}
|
||||
|
||||
/**
|
||||
Call env_set. If this is a path variable, e.g. PATH, validate the
|
||||
elements. On error, print a description of the problem to stderr.
|
||||
*/
|
||||
static int my_env_set( const wchar_t *key, array_list_t *val, int scope )
|
||||
{
|
||||
string_buffer_t sb;
|
||||
int i;
|
||||
int retcode = 0;
|
||||
wchar_t *val_str=0;
|
||||
|
||||
if( is_path_variable( key ) )
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
for( i=0; i<al_get_count( val ); i++ )
|
||||
{
|
||||
int show_perror = 0;
|
||||
int show_hint = 0;
|
||||
|
||||
struct stat buff;
|
||||
wchar_t *dir = (wchar_t *)al_get( val, i );
|
||||
|
||||
if( wstat( dir, &buff ) )
|
||||
{
|
||||
error = 1;
|
||||
show_perror = 1;
|
||||
}
|
||||
|
||||
if( !( S_ISDIR(buff.st_mode) ) )
|
||||
{
|
||||
error = 1;
|
||||
|
||||
}
|
||||
|
||||
if( error )
|
||||
{
|
||||
wchar_t *colon;
|
||||
|
||||
sb_printf( sb_err,
|
||||
_(BUILTIN_SET_PATH_ERROR),
|
||||
L"set",
|
||||
dir,
|
||||
key );
|
||||
|
||||
colon = wcschr( dir, L':' );
|
||||
|
||||
if( colon && *(colon+1) )
|
||||
{
|
||||
show_hint = 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if( show_perror )
|
||||
{
|
||||
builtin_wperror( L"set" );
|
||||
}
|
||||
|
||||
if( show_hint )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
_(BUILTIN_SET_PATH_HINT),
|
||||
L"set",
|
||||
key,
|
||||
key,
|
||||
wcschr( dir, L':' )+1);
|
||||
}
|
||||
|
||||
if( error )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if( error )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sb_init( &sb );
|
||||
|
||||
if( al_get_count( val ) )
|
||||
{
|
||||
for( i=0; i<al_get_count( val ); i++ )
|
||||
{
|
||||
sb_append( &sb, (wchar_t *)al_get( val, i ) );
|
||||
if( i<al_get_count( val )-1 )
|
||||
{
|
||||
sb_append( &sb, ARRAY_SEP_STR );
|
||||
}
|
||||
}
|
||||
val_str = (wchar_t *)sb.buff;
|
||||
|
||||
}
|
||||
|
||||
switch( env_set( key, val_str, scope | ENV_USER ) )
|
||||
{
|
||||
case ENV_PERM:
|
||||
{
|
||||
sb_printf( sb_err, _(L"%ls: Tried to change the read-only variable '%ls'\n"), L"set", key );
|
||||
retcode=1;
|
||||
break;
|
||||
}
|
||||
|
||||
case ENV_INVALID:
|
||||
{
|
||||
sb_printf( sb_err, _(L"%ls: Unknown error"), L"set" );
|
||||
retcode=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sb_destroy( &sb );
|
||||
|
||||
return retcode;
|
||||
}
|
||||
|
||||
/**
|
||||
Extract indexes from a destination argument of the form name[index1 index2...]
|
||||
*/
|
||||
static int parse_fill_indexes( array_list_t *indexes,
|
||||
const wchar_t *src)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
\param indexes the list to insert the new indexes into
|
||||
\param src the source string to parse
|
||||
\param name the name of the element. Return null if the name in \c src does not match this name
|
||||
\param var_count the number of elements in the array to parse.
|
||||
|
||||
\return the total number of indexes parsed, or -1 on error
|
||||
*/
|
||||
static int parse_index( array_list_t *indexes,
|
||||
const wchar_t *src,
|
||||
const wchar_t *name,
|
||||
int var_count )
|
||||
{
|
||||
int len;
|
||||
|
||||
int count = 0;
|
||||
const wchar_t *src_orig = src;
|
||||
|
||||
if (src == 0)
|
||||
{
|
||||
return 0;
|
||||
@@ -73,16 +203,27 @@ static int parse_fill_indexes( array_list_t *indexes,
|
||||
src++;
|
||||
}
|
||||
|
||||
if (*src == L'\0')
|
||||
if (*src != L'[')
|
||||
{
|
||||
sb_printf( sb_err, _(BUILTIN_SET_ARG_COUNT), L"set" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (*src++ != L'[')
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
len = src-src_orig;
|
||||
|
||||
if( (wcsncmp( src_orig, name, len )!=0) || (wcslen(name) != (len)) )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
_(L"%ls: Multiple variable names specified in single call (%ls and %.*ls)\n"),
|
||||
L"set",
|
||||
name,
|
||||
len,
|
||||
src_orig);
|
||||
return 0;
|
||||
}
|
||||
|
||||
src++;
|
||||
|
||||
while (iswspace(*src))
|
||||
{
|
||||
src++;
|
||||
@@ -92,15 +233,19 @@ static int parse_fill_indexes( array_list_t *indexes,
|
||||
{
|
||||
wchar_t *end;
|
||||
long l_ind = wcstol(src, &end, 10);
|
||||
|
||||
if (end == src)
|
||||
{
|
||||
sb_printf(sb_err, _(L"%ls: Invalid index starting at '%ls'\n"), L"set", src);
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int *ind = (int *) calloc(1, sizeof(int));
|
||||
*ind = (int) l_ind;
|
||||
al_push(indexes, ind);
|
||||
if( l_ind < 0 )
|
||||
{
|
||||
l_ind = var_count+l_ind+1;
|
||||
}
|
||||
|
||||
al_push_long(indexes, l_ind);
|
||||
src = end;
|
||||
count++;
|
||||
while (iswspace(*src)) src++;
|
||||
@@ -111,7 +256,12 @@ static int parse_fill_indexes( array_list_t *indexes,
|
||||
|
||||
|
||||
/**
|
||||
Update a list by writing the specified values at the specified indexes
|
||||
Update a list \c list by writing copies (using wcsdup) of the
|
||||
values specified by \c values to the indexes specified by \c
|
||||
indexes. The previous entries at the specidied position will be
|
||||
free'd.
|
||||
|
||||
\return 0 if the operation was successfull, non-zero otherwise
|
||||
*/
|
||||
static int update_values( array_list_t *list,
|
||||
array_list_t *indexes,
|
||||
@@ -119,36 +269,41 @@ static int update_values( array_list_t *list,
|
||||
{
|
||||
int i;
|
||||
|
||||
//fwprintf(stderr, L"Scan complete\n");
|
||||
/* Replace values where needed */
|
||||
for( i = 0; i < al_get_count(indexes); i++ )
|
||||
{
|
||||
int ind = *(int *) al_get(indexes, i) - 1;
|
||||
/*
|
||||
The '- 1' below is because the indices in fish are
|
||||
one-based, but the array_lsit_t uses zero-based indices
|
||||
*/
|
||||
long ind = al_get_long(indexes, i) - 1;
|
||||
void *new = (void *) al_get(values, i);
|
||||
if (al_get(list, ind) != 0)
|
||||
if( ind <= 0 )
|
||||
{
|
||||
free((void *) al_get(list, ind));
|
||||
return 1;
|
||||
}
|
||||
|
||||
free((void *) al_get(list, ind));
|
||||
al_set(list, ind, new != 0 ? wcsdup(new) : wcsdup(L""));
|
||||
}
|
||||
|
||||
return al_get_count(list);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Return 1 if an array list of int* pointers contains the specified
|
||||
Return 1 if an array list of longs contains the specified
|
||||
value, 0 otherwise
|
||||
*/
|
||||
static int al_contains_int( array_list_t *list,
|
||||
int val)
|
||||
static int al_contains_long( array_list_t *list,
|
||||
long val)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < al_get_count(list); i++)
|
||||
{
|
||||
int *current = (int *) al_get(list, i);
|
||||
if (current != 0 && *current == val)
|
||||
long current = al_get_long(list, i);
|
||||
if( current != 0 && current == val )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
@@ -161,18 +316,16 @@ static int al_contains_int( array_list_t *list,
|
||||
/**
|
||||
Erase from a list values at specified indexes
|
||||
*/
|
||||
static int erase_values(array_list_t *list, array_list_t *indexes)
|
||||
static void erase_values(array_list_t *list, array_list_t *indexes)
|
||||
{
|
||||
int i;
|
||||
array_list_t result;
|
||||
|
||||
//fwprintf(stderr, L"Starting with %d\n", al_get_count(list));
|
||||
|
||||
al_init(&result);
|
||||
|
||||
for (i = 0; i < al_get_count(list); i++)
|
||||
{
|
||||
if (!al_contains_int(indexes, i + 1))
|
||||
if (!al_contains_long(indexes, (long)i + 1))
|
||||
{
|
||||
al_push(&result, al_get(list, i));
|
||||
}
|
||||
@@ -185,33 +338,6 @@ static int erase_values(array_list_t *list, array_list_t *indexes)
|
||||
al_truncate(list,0);
|
||||
al_push_all( list, &result );
|
||||
al_destroy(&result);
|
||||
|
||||
//fwprintf(stderr, L"Remaining: %d\n", al_get_count(&result));
|
||||
|
||||
return al_get_count(list);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Fill a string buffer with values from a list, using ARRAY_SEP_STR to separate them
|
||||
*/
|
||||
static int fill_buffer_from_list(string_buffer_t *sb, array_list_t *list)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < al_get_count(list); i++)
|
||||
{
|
||||
wchar_t *v = (wchar_t *) al_get(list, i);
|
||||
if (v != 0)
|
||||
{
|
||||
// fwprintf(stderr, L".\n");
|
||||
// fwprintf(stderr, L"Collecting %ls from %d\n", v, i);
|
||||
sb_append(sb, v);
|
||||
}
|
||||
if (i < al_get_count(list) - 1)
|
||||
sb_append(sb, ARRAY_SEP_STR);
|
||||
}
|
||||
return al_get_count(list);
|
||||
}
|
||||
|
||||
|
||||
@@ -240,9 +366,12 @@ static void print_variables(int include_values, int esc, int scope)
|
||||
{
|
||||
wchar_t *value = env_get(key);
|
||||
wchar_t *e_value;
|
||||
e_value = esc ? expand_escape_variable(value) : wcsdup(value);
|
||||
sb_append2(sb_out, L" ", e_value, (void *)0);
|
||||
free(e_value);
|
||||
if( value )
|
||||
{
|
||||
e_value = esc ? expand_escape_variable(value) : wcsdup(value);
|
||||
sb_append2(sb_out, L" ", e_value, (void *)0);
|
||||
free(e_value);
|
||||
}
|
||||
}
|
||||
|
||||
sb_append(sb_out, L"\n");
|
||||
@@ -251,46 +380,64 @@ static void print_variables(int include_values, int esc, int scope)
|
||||
al_destroy(&names);
|
||||
}
|
||||
|
||||
/**
|
||||
The set builtin. Creates, updates and erases environment variables and environemnt variable arrays.
|
||||
*/
|
||||
|
||||
int builtin_set( wchar_t **argv )
|
||||
|
||||
/**
|
||||
The set builtin. Creates, updates and erases environment variables
|
||||
and environemnt variable arrays.
|
||||
*/
|
||||
static int builtin_set( wchar_t **argv )
|
||||
{
|
||||
|
||||
/**
|
||||
Variables used for parsing the argument list
|
||||
*/
|
||||
const static struct woption
|
||||
long_options[] =
|
||||
{
|
||||
{
|
||||
L"export", no_argument, 0, 'x'
|
||||
},
|
||||
}
|
||||
,
|
||||
{
|
||||
L"global", no_argument, 0, 'g'
|
||||
},
|
||||
}
|
||||
,
|
||||
{
|
||||
L"local", no_argument, 0, 'l'
|
||||
},
|
||||
}
|
||||
,
|
||||
{
|
||||
L"erase", no_argument, 0, 'e'
|
||||
},
|
||||
}
|
||||
,
|
||||
{
|
||||
L"names", no_argument, 0, 'n'
|
||||
} ,
|
||||
}
|
||||
,
|
||||
{
|
||||
L"unexport", no_argument, 0, 'u'
|
||||
} ,
|
||||
}
|
||||
,
|
||||
{
|
||||
L"universal", no_argument, 0, 'U'
|
||||
} ,
|
||||
}
|
||||
,
|
||||
{
|
||||
L"query", no_argument, 0, 'q'
|
||||
} ,
|
||||
}
|
||||
,
|
||||
{
|
||||
L"help", no_argument, 0, 'h'
|
||||
}
|
||||
,
|
||||
{
|
||||
0, 0, 0, 0
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
wchar_t short_options[] = L"+xglenuUq";
|
||||
const wchar_t *short_options = L"+xglenuUqh";
|
||||
|
||||
int argc = builtin_count_args(argv);
|
||||
|
||||
@@ -306,14 +453,14 @@ int builtin_set( wchar_t **argv )
|
||||
Variables used for performing the actual work
|
||||
*/
|
||||
wchar_t *dest = 0;
|
||||
array_list_t values;
|
||||
string_buffer_t name_sb;
|
||||
int retcode=0;
|
||||
wchar_t *name;
|
||||
array_list_t indexes;
|
||||
int retval;
|
||||
|
||||
|
||||
int scope;
|
||||
int slice=0;
|
||||
int i;
|
||||
|
||||
wchar_t *bad_char;
|
||||
|
||||
|
||||
/* Parse options to obtain the requested operation and the modifiers */
|
||||
woptind = 0;
|
||||
while (1)
|
||||
@@ -329,37 +476,61 @@ int builtin_set( wchar_t **argv )
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
erase = 1;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
list = 1;
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
export = 1;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
local = 1;
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
global = 1;
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
unexport = 1;
|
||||
break;
|
||||
|
||||
case 'U':
|
||||
universal = 1;
|
||||
break;
|
||||
|
||||
case 'q':
|
||||
query = 1;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
builtin_print_help( argv[0], sb_out );
|
||||
return 0;
|
||||
|
||||
case '?':
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
return 1;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Ok, all arguments have been parsed, let's validate them
|
||||
*/
|
||||
|
||||
/*
|
||||
If we are checking the existance of a variable (-q) we can not
|
||||
also specify scope
|
||||
*/
|
||||
|
||||
if( query && (erase || list || global || local || universal || export || unexport ) )
|
||||
{
|
||||
sb_printf(sb_err,
|
||||
@@ -372,7 +543,7 @@ int builtin_set( wchar_t **argv )
|
||||
}
|
||||
|
||||
|
||||
/* Check operation and modifiers sanity */
|
||||
/* We can't both list and erase varaibles */
|
||||
if( erase && list )
|
||||
{
|
||||
sb_printf(sb_err,
|
||||
@@ -384,6 +555,9 @@ int builtin_set( wchar_t **argv )
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
Variables can only have one scope
|
||||
*/
|
||||
if( local + global + universal > 1 )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
@@ -394,6 +568,9 @@ int builtin_set( wchar_t **argv )
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
Variables can only have one export status
|
||||
*/
|
||||
if( export && unexport )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
@@ -404,205 +581,235 @@ int builtin_set( wchar_t **argv )
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
Calculate the scope value for variable assignement
|
||||
*/
|
||||
scope = (local ? ENV_LOCAL : 0) | (global ? ENV_GLOBAL : 0) | (export ? ENV_EXPORT : 0) | (unexport ? ENV_UNEXPORT : 0) | (universal ? ENV_UNIVERSAL:0) | ENV_USER;
|
||||
|
||||
if( query )
|
||||
{
|
||||
/*
|
||||
Query mode. Return number of specified variables that do not exist.
|
||||
Query mode. Return the number of variables that do not exist
|
||||
out of the specified variables.
|
||||
*/
|
||||
int i;
|
||||
for( i=woptind; i<argc; i++ )
|
||||
{
|
||||
if( !env_exist( argv[i] ) )
|
||||
if( !env_exist( argv[i], scope ) )
|
||||
{
|
||||
retcode++;
|
||||
}
|
||||
|
||||
}
|
||||
return retcode;
|
||||
}
|
||||
|
||||
|
||||
/* Parse destination */
|
||||
if( woptind < argc )
|
||||
if( list )
|
||||
{
|
||||
dest = wcsdup(argv[woptind++]);
|
||||
//fwprintf(stderr, L"Dest: %ls\n", dest);
|
||||
|
||||
if( !wcslen( dest ) )
|
||||
{
|
||||
free( dest );
|
||||
sb_printf( sb_err, BUILTIN_ERR_VARNAME_ZERO, argv[0] );
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse values */
|
||||
// wchar_t **values = woptind < argc ? (wchar_t **) calloc(argc - woptind, sizeof(wchar_t *)) : 0;
|
||||
|
||||
al_init(&values);
|
||||
while( woptind < argc )
|
||||
{
|
||||
al_push(&values, argv[woptind++]);
|
||||
// fwprintf(stderr, L"Val: %ls\n", argv[woptind - 1]);
|
||||
}
|
||||
|
||||
/* Extract variable name and indexes */
|
||||
|
||||
sb_init(&name_sb);
|
||||
retval = parse_fill_name(&name_sb, dest);
|
||||
|
||||
/* Maybe we should issue an error if there are any other arguments? */
|
||||
print_variables(0, 0, scope);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( retval < 0 )
|
||||
retcode=1;
|
||||
|
||||
if( !retcode )
|
||||
if( woptind == argc )
|
||||
{
|
||||
name = (wchar_t *) name_sb.buff;
|
||||
//fwprintf(stderr, L"Name is %ls\n", name);
|
||||
/*
|
||||
Print values of variables
|
||||
*/
|
||||
|
||||
al_init(&indexes);
|
||||
retval = parse_fill_indexes(&indexes, dest);
|
||||
if (retval < 0)
|
||||
if( erase )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
_(L"%ls: Erase needs a variable name\n%ls\n"),
|
||||
argv[0],
|
||||
parser_current_line() );
|
||||
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
retcode = 1;
|
||||
}
|
||||
|
||||
if( !retcode )
|
||||
{
|
||||
|
||||
int i;
|
||||
int finished=0;
|
||||
|
||||
/* Do the actual work */
|
||||
int scope = (local ? ENV_LOCAL : 0) | (global ? ENV_GLOBAL : 0) | (export ? ENV_EXPORT : 0) | (unexport ? ENV_UNEXPORT : 0) | (universal ? ENV_UNIVERSAL:0) | ENV_USER;
|
||||
if( list )
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Maybe we should issue an error if there are any other arguments */
|
||||
print_variables(0, 0, scope);
|
||||
finished=1;
|
||||
}
|
||||
|
||||
if( (!finished ) &&
|
||||
(name == 0 || wcslen(name) == 0))
|
||||
{
|
||||
/* No arguments -- display name & value for all variables in scope */
|
||||
if( erase )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
_(L"%ls: Erase needs a variable name\n%ls\n"),
|
||||
argv[0],
|
||||
parser_current_line() );
|
||||
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
retcode = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
print_variables( 1, 1, scope );
|
||||
}
|
||||
|
||||
finished=1;
|
||||
}
|
||||
|
||||
|
||||
if( !finished )
|
||||
{
|
||||
if( al_get_count( &values ) == 0 &&
|
||||
al_get_count( &indexes ) == 0 &&
|
||||
!erase &&
|
||||
!list )
|
||||
{
|
||||
env_set( name, 0, scope );
|
||||
finished = 1;
|
||||
}
|
||||
print_variables( 1, 1, scope );
|
||||
}
|
||||
|
||||
if( !finished )
|
||||
return retcode;
|
||||
}
|
||||
|
||||
if( !(dest = wcsdup(argv[woptind])))
|
||||
{
|
||||
DIE_MEM();
|
||||
}
|
||||
|
||||
if( wcschr( dest, L'[' ) )
|
||||
{
|
||||
slice = 1;
|
||||
*wcschr( dest, L'[' )=0;
|
||||
}
|
||||
|
||||
if( !wcslen( dest ) )
|
||||
{
|
||||
free( dest );
|
||||
sb_printf( sb_err, BUILTIN_ERR_VARNAME_ZERO, argv[0] );
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
return 1;
|
||||
}
|
||||
|
||||
if( (bad_char = wcsvarname( dest ) ) )
|
||||
{
|
||||
sb_printf( sb_err, BUILTIN_ERR_VARCHAR, argv[0], *bad_char );
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
free( dest );
|
||||
return 1;
|
||||
}
|
||||
|
||||
if( slice && erase && (scope != ENV_USER) )
|
||||
{
|
||||
free( dest );
|
||||
sb_printf( sb_err, _(L"%ls: Can not specify scope when erasing array slice\n"), argv[0] );
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
set assignment can work in two modes, either using slices or
|
||||
using the whole array. We detect which mode is used here.
|
||||
*/
|
||||
|
||||
if( slice )
|
||||
{
|
||||
|
||||
/*
|
||||
Slice mode
|
||||
*/
|
||||
int idx_count, val_count;
|
||||
array_list_t values;
|
||||
array_list_t indexes;
|
||||
array_list_t result;
|
||||
|
||||
al_init(&values);
|
||||
al_init(&indexes);
|
||||
al_init(&result);
|
||||
|
||||
tokenize_variable_array( env_get(dest), &result );
|
||||
|
||||
for( ; woptind<argc; woptind++ )
|
||||
{
|
||||
if( !parse_index( &indexes, argv[woptind], dest, al_get_count( &result ) ) )
|
||||
{
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
retcode = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
val_count = argc-woptind-1;
|
||||
idx_count = al_get_count( &indexes );
|
||||
|
||||
if( !erase )
|
||||
{
|
||||
if( val_count < idx_count )
|
||||
{
|
||||
sb_printf( sb_err, _(BUILTIN_SET_ARG_COUNT), argv[0] );
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
retcode=1;
|
||||
break;
|
||||
}
|
||||
if( val_count == idx_count )
|
||||
{
|
||||
woptind++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( !retcode )
|
||||
{
|
||||
/* There are some arguments, we have at least a variable name */
|
||||
if( erase && al_get_count(&values) != 0 )
|
||||
/*
|
||||
Slice indexes have been calculated, do the actual work
|
||||
*/
|
||||
|
||||
if( erase )
|
||||
{
|
||||
erase_values(&result, &indexes);
|
||||
my_env_set( dest, &result, scope);
|
||||
}
|
||||
else
|
||||
{
|
||||
array_list_t value;
|
||||
al_init(&value);
|
||||
|
||||
while( woptind < argc )
|
||||
{
|
||||
al_push(&value, argv[woptind++]);
|
||||
}
|
||||
|
||||
if( update_values( &result,
|
||||
&indexes,
|
||||
&value ) )
|
||||
{
|
||||
sb_printf( sb_err, L"%ls: ", argv[0] );
|
||||
sb_printf( sb_err, ARRAY_BOUNDS_ERR );
|
||||
sb_append( sb_err, L"\n" );
|
||||
}
|
||||
|
||||
my_env_set(dest,
|
||||
&result,
|
||||
scope);
|
||||
|
||||
al_destroy( &value );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
al_foreach( &result, &free );
|
||||
al_destroy( &result );
|
||||
|
||||
al_destroy(&indexes);
|
||||
al_destroy(&values);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
woptind++;
|
||||
|
||||
/*
|
||||
No slicing
|
||||
*/
|
||||
if( erase )
|
||||
{
|
||||
if( woptind != argc )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
_(L"%ls: Values cannot be specfied with erase\n%ls\n"),
|
||||
argv[0],
|
||||
parser_current_line() );
|
||||
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
retcode = 1;
|
||||
}
|
||||
retcode=1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* All ok, we can alter the specified variable */
|
||||
array_list_t val_l;
|
||||
al_init(&val_l);
|
||||
|
||||
void *old=0;
|
||||
|
||||
if (al_get_count(&indexes) == 0)
|
||||
{
|
||||
/* We will act upon the entire variable */
|
||||
|
||||
al_push( &val_l, wcsdup(L"") );
|
||||
old = val_l.arr;
|
||||
|
||||
/* Build indexes for all variable or all new values */
|
||||
int end_index = erase ? al_get_count(&val_l) : al_get_count(&values);
|
||||
for (i = 0; i < end_index; i++)
|
||||
{
|
||||
int *ind = (int *) calloc(1, sizeof(int));
|
||||
*ind = i + 1;
|
||||
al_push(&indexes, ind);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We will act upon some specific indexes */
|
||||
expand_variable_array( env_get(name), &val_l );
|
||||
}
|
||||
|
||||
string_buffer_t result_sb;
|
||||
sb_init(&result_sb);
|
||||
if (erase)
|
||||
{
|
||||
int rem = erase_values(&val_l, &indexes);
|
||||
if (rem == 0)
|
||||
{
|
||||
env_remove(name, ENV_USER);
|
||||
}
|
||||
else
|
||||
{
|
||||
fill_buffer_from_list(&result_sb, &val_l);
|
||||
env_set(name, (wchar_t *) result_sb.buff, scope);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
update_values( &val_l,
|
||||
&indexes,
|
||||
&values );
|
||||
|
||||
fill_buffer_from_list( &result_sb,
|
||||
&val_l );
|
||||
|
||||
env_set(name,
|
||||
(wchar_t *) result_sb.buff,
|
||||
scope);
|
||||
}
|
||||
|
||||
al_foreach( &val_l, (void (*)(const void *))&free );
|
||||
al_destroy(&val_l);
|
||||
sb_destroy(&result_sb);
|
||||
{
|
||||
retcode = env_remove( dest, scope );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
array_list_t val;
|
||||
al_init( &val );
|
||||
|
||||
for( i=woptind; i<argc; i++ )
|
||||
{
|
||||
al_push( &val, argv[i] );
|
||||
}
|
||||
|
||||
al_foreach( &indexes, (void (*)(const void *))&free );
|
||||
al_destroy(&indexes);
|
||||
retcode = my_env_set( dest, &val, scope );
|
||||
|
||||
al_destroy( &val );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* Common cleanup */
|
||||
//fwprintf(stderr, L"Cleanup\n");
|
||||
free(dest);
|
||||
sb_destroy(&name_sb);
|
||||
al_destroy( &values );
|
||||
free( dest );
|
||||
|
||||
return retcode;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
Functions used for implementing the ulimit builtin.
|
||||
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <wchar.h>
|
||||
@@ -12,12 +14,13 @@ Functions used for implementing the ulimit builtin.
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "fallback.h"
|
||||
#include "util.h"
|
||||
|
||||
#include "builtin.h"
|
||||
#include "common.h"
|
||||
#include "wgetopt.h"
|
||||
#include "translate.h"
|
||||
|
||||
|
||||
/**
|
||||
Struct describing a resource limit
|
||||
@@ -60,13 +63,13 @@ const static struct resource_t resource_arr[] =
|
||||
RLIMIT_FSIZE, L"Maximum size of files created by the shell", L'f', 1024
|
||||
}
|
||||
,
|
||||
#if HAVE_RLIMIT_MEMLOCK
|
||||
#ifdef RLIMIT_MEMLOCK
|
||||
{
|
||||
RLIMIT_MEMLOCK, L"Maximum size that may be locked into memory", L'l', 1024
|
||||
}
|
||||
,
|
||||
#endif
|
||||
#if HAVE_RLIMIT_RSS
|
||||
#ifdef RLIMIT_RSS
|
||||
{
|
||||
RLIMIT_RSS, L"Maximum resident set size", L'm', 1024
|
||||
}
|
||||
@@ -84,13 +87,13 @@ const static struct resource_t resource_arr[] =
|
||||
RLIMIT_CPU, L"Maximum amount of cpu time in seconds", L't', 1
|
||||
}
|
||||
,
|
||||
#if HAVE_RLIMIT_NPROC
|
||||
#ifdef RLIMIT_NPROC
|
||||
{
|
||||
RLIMIT_NPROC, L"Maximum number of processes available to a single user", L'u', 1
|
||||
}
|
||||
,
|
||||
#endif
|
||||
#if HAVE_RLIMIT_AS
|
||||
#ifdef RLIMIT_AS
|
||||
{
|
||||
RLIMIT_AS, L"Maximum amount of virtual memory available to the shell", L'v', 1024
|
||||
}
|
||||
@@ -254,7 +257,11 @@ static int set_all( int hard, int soft, rlim_t value )
|
||||
return res;
|
||||
}
|
||||
|
||||
int builtin_ulimit( wchar_t ** argv )
|
||||
/**
|
||||
The ulimit builtin, used for setting resource limits. Defined in
|
||||
builtin_ulimit.c.
|
||||
*/
|
||||
static int builtin_ulimit( wchar_t ** argv )
|
||||
{
|
||||
int hard=0;
|
||||
int soft=0;
|
||||
@@ -323,6 +330,10 @@ int builtin_ulimit( wchar_t ** argv )
|
||||
L"virtual-memory-size", no_argument, 0, 'v'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"help", no_argument, 0, 'h'
|
||||
}
|
||||
,
|
||||
{
|
||||
0, 0, 0, 0
|
||||
}
|
||||
@@ -334,7 +345,7 @@ int builtin_ulimit( wchar_t ** argv )
|
||||
|
||||
int opt = wgetopt_long( argc,
|
||||
argv,
|
||||
L"aHScdflmnptuv",
|
||||
L"aHScdflmnptuvh",
|
||||
long_options,
|
||||
&opt_index );
|
||||
if( opt == -1 )
|
||||
@@ -376,13 +387,13 @@ int builtin_ulimit( wchar_t ** argv )
|
||||
case L'f':
|
||||
what=RLIMIT_FSIZE;
|
||||
break;
|
||||
#if HAVE_RLIMIT_MEMLOCK
|
||||
#ifdef RLIMIT_MEMLOCK
|
||||
case L'l':
|
||||
what=RLIMIT_MEMLOCK;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if HAVE_RLIMIT_RSS
|
||||
#ifdef RLIMIT_RSS
|
||||
case L'm':
|
||||
what=RLIMIT_RSS;
|
||||
break;
|
||||
@@ -400,18 +411,22 @@ int builtin_ulimit( wchar_t ** argv )
|
||||
what=RLIMIT_CPU;
|
||||
break;
|
||||
|
||||
#if HAVE_RLIMIT_NPROC
|
||||
#ifdef RLIMIT_NPROC
|
||||
case L'u':
|
||||
what=RLIMIT_NPROC;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if HAVE_RLIMIT_AS
|
||||
#ifdef RLIMIT_AS
|
||||
case L'v':
|
||||
what=RLIMIT_AS;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case L'h':
|
||||
builtin_print_help( argv[0], sb_out );
|
||||
return 0;
|
||||
|
||||
case L'?':
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
return 1;
|
||||
|
||||
207
common.h
207
common.h
@@ -15,39 +15,30 @@
|
||||
|
||||
#include "util.h"
|
||||
|
||||
/**
|
||||
Under curses, tputs expects an int (*func)(char) as its last
|
||||
parameter, but in ncurses, tputs expects a int (*func)(int) as its
|
||||
last parameter. tputs_arg_t is defined to always be what tputs
|
||||
expects. Hopefully.
|
||||
*/
|
||||
|
||||
#ifdef NCURSES_VERSION
|
||||
typedef int tputs_arg_t;
|
||||
#else
|
||||
typedef char tputs_arg_t;
|
||||
#endif
|
||||
|
||||
/**
|
||||
Maximum number of bytes used by a single utf-8 character
|
||||
*/
|
||||
#define MAX_UTF8_BYTES 6
|
||||
|
||||
/**
|
||||
Color code for set_color. Does not update the color.
|
||||
*/
|
||||
|
||||
#define FISH_COLOR_IGNORE -1
|
||||
|
||||
/**
|
||||
Color code for set_color. Sets the default color.
|
||||
*/
|
||||
#define FISH_COLOR_RESET -2
|
||||
|
||||
/**
|
||||
This is in the unicode private use area.
|
||||
*/
|
||||
#define ENCODE_DIRECT_BASE 0xf000
|
||||
#define ENCODE_DIRECT_BASE 0xf100
|
||||
|
||||
/**
|
||||
Highest legal ascii value
|
||||
*/
|
||||
#define ASCII_MAX 127u
|
||||
|
||||
/**
|
||||
Highest legal 16-bit unicode value
|
||||
*/
|
||||
#define UCS2_MAX 0xffffu
|
||||
|
||||
/**
|
||||
Highest legal byte value
|
||||
*/
|
||||
#define BYTE_MAX 0xffu
|
||||
|
||||
/**
|
||||
Save the shell mode on startup so we can restore them on exit
|
||||
@@ -60,11 +51,6 @@ extern struct termios shell_modes;
|
||||
*/
|
||||
extern wchar_t ellipsis_char;
|
||||
|
||||
/**
|
||||
The maximum number of charset convertion errors to report
|
||||
*/
|
||||
extern int error_max;
|
||||
|
||||
/**
|
||||
The verbosity of fish
|
||||
*/
|
||||
@@ -81,6 +67,45 @@ extern char *profile;
|
||||
*/
|
||||
extern wchar_t *program_name;
|
||||
|
||||
/**
|
||||
This macro is used to check that an input argument is not null. It
|
||||
is a bit lika a non-fatal form of assert. Instead of exit-ing on
|
||||
failiure, the current function is ended at once. The second
|
||||
parameter is the exit status of the current function on failiure.
|
||||
*/
|
||||
#define CHECK( arg, retval ) \
|
||||
if( !(arg) ) \
|
||||
{ \
|
||||
debug( 1, \
|
||||
L"function %s called with null value for argument %s. " \
|
||||
L"This is a bug. " \
|
||||
L"If you can reproduce it, please send a bug report to %s.", \
|
||||
__func__, \
|
||||
#arg, \
|
||||
PACKAGE_BUGREPORT ); \
|
||||
return retval; \
|
||||
} \
|
||||
|
||||
|
||||
/**
|
||||
Exit program at once, leaving an error message about running out of memory
|
||||
*/
|
||||
#define DIE_MEM() \
|
||||
{ \
|
||||
fwprintf( stderr, L"fish: Out of memory on line %d of file %s, shutting down fish\n", __LINE__, __FILE__ ); \
|
||||
exit(1); \
|
||||
} \
|
||||
|
||||
/**
|
||||
Shorthand for wgettext call
|
||||
*/
|
||||
#define _(wstr) wgettext(wstr)
|
||||
|
||||
/**
|
||||
Noop, used to tell xgettext that a string should be translated, even though it is not directly sent to wgettext.
|
||||
*/
|
||||
#define N_(wstr) wstr
|
||||
|
||||
/**
|
||||
Take an array_list_t containing wide strings and converts them to a
|
||||
single null-terminated wchar_t **. The array is allocated using
|
||||
@@ -88,7 +113,7 @@ extern wchar_t *program_name;
|
||||
is not noll, all elements of the \c array_list_t are also
|
||||
registered to \c context using \c halloc_register().
|
||||
*/
|
||||
wchar_t **list_to_char_arr( void *context, array_list_t *l );
|
||||
wchar_t **list_to_char_arr( array_list_t *l );
|
||||
|
||||
/**
|
||||
Read a line from the stream f into the buffer buff of length len. If
|
||||
@@ -104,23 +129,49 @@ wchar_t **list_to_char_arr( void *context, array_list_t *l );
|
||||
int fgetws2( wchar_t **buff, int *len, FILE *f );
|
||||
|
||||
/**
|
||||
Sorts a list of wide strings according to the wcsfilecmp-function
|
||||
from the util library
|
||||
Sorts an array_list of wide strings according to the
|
||||
wcsfilecmp-function from the util library
|
||||
*/
|
||||
void sort_list( array_list_t *comp );
|
||||
|
||||
/**
|
||||
Returns a newly allocated wide character string equivalent of the
|
||||
specified multibyte character string
|
||||
|
||||
This function encodes illegal character sequences in a reversible
|
||||
way using the private use area.
|
||||
*/
|
||||
wchar_t *str2wcs( const char *in );
|
||||
|
||||
/**
|
||||
Converts the narrow character string \c in into it's wide
|
||||
equivalent, stored in \c out. \c out must have enough space to fit
|
||||
the entire string.
|
||||
|
||||
This function encodes illegal character sequences in a reversible
|
||||
way using the private use area.
|
||||
*/
|
||||
wchar_t *str2wcs_internal( const char *in, wchar_t *out );
|
||||
|
||||
/**
|
||||
Returns a newly allocated multibyte character string equivalent of
|
||||
the specified wide character string
|
||||
|
||||
This function decodes illegal character sequences in a reversible
|
||||
way using the private use area.
|
||||
*/
|
||||
char *wcs2str( const wchar_t *in );
|
||||
|
||||
/**
|
||||
Converts the wide character string \c in into it's narrow
|
||||
equivalent, stored in \c out. \c out must have enough space to fit
|
||||
the entire string.
|
||||
|
||||
This function decodes illegal character sequences in a reversible
|
||||
way using the private use area.
|
||||
*/
|
||||
char *wcs2str_internal( const wchar_t *in, char *out );
|
||||
|
||||
/**
|
||||
Returns a newly allocated wide character string array equivalent of
|
||||
the specified multibyte character string array
|
||||
@@ -144,35 +195,26 @@ wchar_t *wcsdupcat( const wchar_t *a, const wchar_t *b );
|
||||
*/
|
||||
wchar_t *wcsdupcat2( const wchar_t *a, ... );
|
||||
|
||||
|
||||
/**
|
||||
Appends src to string dst of size siz (unlike wcsncat, siz is the
|
||||
full size of dst, not space left). At most siz-1 characters will be
|
||||
copied. Always NUL terminates (unless siz <= wcslen(dst)). Returns
|
||||
wcslen(src) + MIN(siz, wcslen(initial dst)). If retval >= siz,
|
||||
truncation occurred.
|
||||
|
||||
This is the OpenBSD strlcat function, modified for wide characters,
|
||||
and renamed to reflect this change.
|
||||
|
||||
*/
|
||||
size_t wcslcat( wchar_t *dst, const wchar_t *src, size_t siz );
|
||||
|
||||
/**
|
||||
Copy src to string dst of size siz. At most siz-1 characters will
|
||||
be copied. Always NUL terminates (unless siz == 0). Returns
|
||||
wcslen(src); if retval >= siz, truncation occurred.
|
||||
|
||||
This is the OpenBSD strlcpy function, modified for wide characters,
|
||||
and renamed to reflect this change.
|
||||
*/
|
||||
size_t wcslcpy( wchar_t *dst, const wchar_t *src, size_t siz );
|
||||
|
||||
/**
|
||||
Test if the given string is a valid variable name
|
||||
*/
|
||||
|
||||
int wcsvarname( wchar_t *str );
|
||||
|
||||
/**
|
||||
Test if the given string is a valid variable name.
|
||||
|
||||
\return null if this is a valid name, and a pointer to the first invalid character otherwise
|
||||
*/
|
||||
|
||||
wchar_t *wcsvarname( wchar_t *str );
|
||||
|
||||
/**
|
||||
Test if the given string is valid in a variable name
|
||||
|
||||
\return 1 if this is a valid name, 0 otherwise
|
||||
*/
|
||||
|
||||
int wcsvarchr( wchar_t chr );
|
||||
|
||||
|
||||
/**
|
||||
@@ -208,9 +250,11 @@ void error_reset();
|
||||
const wchar_t *wsetlocale( int category, const wchar_t *locale );
|
||||
|
||||
/**
|
||||
Checks if \c needle is included in the list of strings specified
|
||||
Checks if \c needle is included in the list of strings specified. A warning is printed if needle is zero.
|
||||
|
||||
\param needle the string to search for in the list
|
||||
|
||||
\return zero is needle is not found, of if needle is null, non-zero otherwise
|
||||
*/
|
||||
int contains_str( const wchar_t *needle, ... );
|
||||
|
||||
@@ -220,22 +264,6 @@ int contains_str( const wchar_t *needle, ... );
|
||||
*/
|
||||
int read_blocked(int fd, void *buf, size_t count);
|
||||
|
||||
/**
|
||||
This is for writing process notification messages. Has to write to
|
||||
stdout, so clr_eol and such functions will work correctly. Not an
|
||||
issue since this function is only used in interactive mode anyway.
|
||||
*/
|
||||
int writeb( tputs_arg_t b );
|
||||
|
||||
/**
|
||||
Exit program at once, leaving an error message about running out of memory
|
||||
*/
|
||||
void die_mem();
|
||||
|
||||
/**
|
||||
Clean up
|
||||
*/
|
||||
void common_destroy();
|
||||
|
||||
/**
|
||||
Issue a debug message with printf-style string formating and
|
||||
@@ -262,8 +290,7 @@ void debug( int level, const wchar_t *msg, ... );
|
||||
\return The escaped string, or 0 if there is not enough memory
|
||||
*/
|
||||
|
||||
wchar_t *escape( const wchar_t *in,
|
||||
int escape_all );
|
||||
wchar_t *escape( const wchar_t *in, int escape_all );
|
||||
|
||||
/**
|
||||
Expand backslashed escapes and substitute them with their unescaped
|
||||
@@ -279,16 +306,6 @@ wchar_t *escape( const wchar_t *in,
|
||||
wchar_t *unescape( const wchar_t * in,
|
||||
int escape_special );
|
||||
|
||||
/**
|
||||
Block SIGCHLD. Calls to block/unblock may be nested, and only once the nest count reaches zero wiull the block be removed.
|
||||
*/
|
||||
void block();
|
||||
|
||||
/**
|
||||
undo call to block().
|
||||
*/
|
||||
void unblock();
|
||||
|
||||
/**
|
||||
Attempt to acquire a lock based on a lockfile, waiting LOCKPOLLINTERVAL
|
||||
milliseconds between polls and timing out after timeout seconds,
|
||||
@@ -325,10 +342,20 @@ int common_get_height();
|
||||
void common_handle_winch( int signal );
|
||||
|
||||
/**
|
||||
Write paragraph of output to screen. Ignore newlines in message and
|
||||
perform internal line-breaking.
|
||||
Write paragraph of output to the specified stringbuffer, and redo
|
||||
the linebreaks to fit the current screen.
|
||||
*/
|
||||
void write_screen( const wchar_t *msg );
|
||||
void write_screen( const wchar_t *msg, string_buffer_t *buff );
|
||||
|
||||
/**
|
||||
Tokenize the specified string into the specified array_list_t.
|
||||
Each new element is allocated using malloc and must be freed by the
|
||||
caller.
|
||||
|
||||
\param val the input string. The contents of this string is not changed.
|
||||
\param out the list in which to place the elements.
|
||||
*/
|
||||
void tokenize_variable_array( const wchar_t *val, array_list_t *out );
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
777
complete.c
777
complete.c
File diff suppressed because it is too large
Load Diff
59
complete.h
59
complete.h
@@ -1,10 +1,12 @@
|
||||
/** \file complete.h
|
||||
Prototypes for functions related to tab-completion.
|
||||
|
||||
These functions are used for storing and retrieving tab-completion data, as well as for performing tab-completion.
|
||||
These functions are used for storing and retrieving tab-completion
|
||||
data, as well as for performing tab-completion.
|
||||
*/
|
||||
|
||||
#ifndef FISH_COMPLETE_H
|
||||
|
||||
/**
|
||||
Header guard
|
||||
*/
|
||||
@@ -14,39 +16,60 @@
|
||||
|
||||
#include "util.h"
|
||||
|
||||
/** Use all completions */
|
||||
/**
|
||||
Use all completions
|
||||
*/
|
||||
#define SHARED 0
|
||||
/** Do not use file completion */
|
||||
/**
|
||||
Do not use file completion
|
||||
*/
|
||||
#define NO_FILES 1
|
||||
/** Require a parameter after completion */
|
||||
/**
|
||||
Require a parameter after completion
|
||||
*/
|
||||
#define NO_COMMON 2
|
||||
/** Only use the argument list specifies with completion after option. This is the same as (NO_FILES & NO_COMMON) */
|
||||
/**
|
||||
Only use the argument list specifies with completion after
|
||||
option. This is the same as (NO_FILES & NO_COMMON)
|
||||
*/
|
||||
#define EXCLUSIVE 3
|
||||
|
||||
/** Command is a path */
|
||||
/**
|
||||
Command is a path
|
||||
*/
|
||||
#define PATH 1
|
||||
/** Command is not a path */
|
||||
/**
|
||||
Command is not a path
|
||||
*/
|
||||
#define COMMAND 0
|
||||
|
||||
/** Separateor between completion and description*/
|
||||
/**
|
||||
Separator between completion and description
|
||||
*/
|
||||
#define COMPLETE_SEP L'\004'
|
||||
/** Separateor between completion and description*/
|
||||
|
||||
/**
|
||||
Separator between completion and description
|
||||
*/
|
||||
#define COMPLETE_SEP_STR L"\004"
|
||||
|
||||
/**
|
||||
Character that separates the completion and description on programmable completions
|
||||
Separator between completion items in fish_pager. This is used for
|
||||
completion grouping, e.g. when putting completions with the same
|
||||
descriptions on the same line.
|
||||
*/
|
||||
#define COMPLETE_ITEM_SEP L'\uf500'
|
||||
|
||||
/**
|
||||
Character that separates the completion and description on
|
||||
programmable completions
|
||||
*/
|
||||
#define PROG_COMPLETE_SEP L'\t'
|
||||
|
||||
/**
|
||||
Initializes various structures used for tab-completion.
|
||||
Terminator for completions sent to the fish_pager
|
||||
*/
|
||||
void complete_init();
|
||||
|
||||
/**
|
||||
Destroys various structures used for tab-completion and free()s the memory used by them.
|
||||
*/
|
||||
void complete_destroy();
|
||||
#define COMPLETE_TERMINATOR L'\006'
|
||||
|
||||
/**
|
||||
|
||||
@@ -162,6 +185,6 @@ int complete_is_valid_argument( const wchar_t *str,
|
||||
\param cmd the command for which to load command-specific completions
|
||||
\param reload should the commands completions be reloaded, even if they where previously loaded. (This is set to true on actual completions, so that changed completion are updated in running shells)
|
||||
*/
|
||||
void complete_load( wchar_t *cmd, int reload );
|
||||
void complete_load( const wchar_t *cmd, int reload );
|
||||
|
||||
#endif
|
||||
|
||||
665
config.guess
vendored
665
config.guess
vendored
File diff suppressed because it is too large
Load Diff
219
config.sub
vendored
219
config.sub
vendored
@@ -1,9 +1,10 @@
|
||||
#! /bin/sh
|
||||
# Configuration validation subroutine script.
|
||||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||||
# 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||
# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
|
||||
# Inc.
|
||||
|
||||
timestamp='2003-06-18'
|
||||
timestamp='2006-02-27'
|
||||
|
||||
# This file is (in principle) common to ALL GNU software.
|
||||
# The presence of a machine in this file suggests that SOME GNU software
|
||||
@@ -21,14 +22,15 @@ timestamp='2003-06-18'
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
# Boston, MA 02111-1307, USA.
|
||||
|
||||
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
|
||||
# 02110-1301, USA.
|
||||
#
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
|
||||
# Please send patches to <config-patches@gnu.org>. Submit a context
|
||||
# diff and a properly formatted ChangeLog entry.
|
||||
#
|
||||
@@ -70,7 +72,7 @@ Report bugs and patches to <config-patches@gnu.org>."
|
||||
version="\
|
||||
GNU config.sub ($timestamp)
|
||||
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
@@ -83,11 +85,11 @@ Try \`$me --help' for more information."
|
||||
while test $# -gt 0 ; do
|
||||
case $1 in
|
||||
--time-stamp | --time* | -t )
|
||||
echo "$timestamp" ; exit 0 ;;
|
||||
echo "$timestamp" ; exit ;;
|
||||
--version | -v )
|
||||
echo "$version" ; exit 0 ;;
|
||||
echo "$version" ; exit ;;
|
||||
--help | --h* | -h )
|
||||
echo "$usage"; exit 0 ;;
|
||||
echo "$usage"; exit ;;
|
||||
-- ) # Stop option processing
|
||||
shift; break ;;
|
||||
- ) # Use stdin as input.
|
||||
@@ -99,7 +101,7 @@ while test $# -gt 0 ; do
|
||||
*local*)
|
||||
# First pass through any local machine types.
|
||||
echo $1
|
||||
exit 0;;
|
||||
exit ;;
|
||||
|
||||
* )
|
||||
break ;;
|
||||
@@ -118,7 +120,9 @@ esac
|
||||
# Here we must recognize all the valid KERNEL-OS combinations.
|
||||
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
|
||||
case $maybe_os in
|
||||
nto-qnx* | linux-gnu* | freebsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
|
||||
nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
|
||||
uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
|
||||
storm-chaos* | os2-emx* | rtmk-nova*)
|
||||
os=-$maybe_os
|
||||
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
|
||||
;;
|
||||
@@ -144,7 +148,7 @@ case $os in
|
||||
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
|
||||
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
|
||||
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
|
||||
-apple | -axis)
|
||||
-apple | -axis | -knuth | -cray)
|
||||
os=
|
||||
basic_machine=$1
|
||||
;;
|
||||
@@ -169,6 +173,10 @@ case $os in
|
||||
-hiux*)
|
||||
os=-hiuxwe2
|
||||
;;
|
||||
-sco6)
|
||||
os=-sco5v6
|
||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
||||
;;
|
||||
-sco5)
|
||||
os=-sco3.2v5
|
||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
||||
@@ -185,6 +193,10 @@ case $os in
|
||||
# Don't forget version if it is 3.2v4 or newer.
|
||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
||||
;;
|
||||
-sco5v6*)
|
||||
# Don't forget version if it is 3.2v4 or newer.
|
||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
||||
;;
|
||||
-sco*)
|
||||
os=-sco3.2v2
|
||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
||||
@@ -228,14 +240,16 @@ case $basic_machine in
|
||||
| a29k \
|
||||
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
|
||||
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
|
||||
| am33_2.0 \
|
||||
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
|
||||
| bfin \
|
||||
| c4x | clipper \
|
||||
| d10v | d30v | dlx | dsp16xx \
|
||||
| fr30 | frv \
|
||||
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
|
||||
| i370 | i860 | i960 | ia64 \
|
||||
| ip2k \
|
||||
| m32r | m68000 | m68k | m88k | mcore \
|
||||
| ip2k | iq2000 \
|
||||
| m32r | m32rle | m68000 | m68k | m88k | maxq | mb | microblaze | mcore \
|
||||
| mips | mipsbe | mipseb | mipsel | mipsle \
|
||||
| mips16 \
|
||||
| mips64 | mips64el \
|
||||
@@ -244,31 +258,38 @@ case $basic_machine in
|
||||
| mips64vr4100 | mips64vr4100el \
|
||||
| mips64vr4300 | mips64vr4300el \
|
||||
| mips64vr5000 | mips64vr5000el \
|
||||
| mips64vr5900 | mips64vr5900el \
|
||||
| mipsisa32 | mipsisa32el \
|
||||
| mipsisa32r2 | mipsisa32r2el \
|
||||
| mipsisa64 | mipsisa64el \
|
||||
| mipsisa64r2 | mipsisa64r2el \
|
||||
| mipsisa64sb1 | mipsisa64sb1el \
|
||||
| mipsisa64sr71k | mipsisa64sr71kel \
|
||||
| mipstx39 | mipstx39el \
|
||||
| mn10200 | mn10300 \
|
||||
| mt \
|
||||
| msp430 \
|
||||
| nios | nios2 \
|
||||
| ns16k | ns32k \
|
||||
| openrisc | or32 \
|
||||
| or32 \
|
||||
| pdp10 | pdp11 | pj | pjl \
|
||||
| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
|
||||
| pyramid \
|
||||
| s390 | s390x \
|
||||
| sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
|
||||
| sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
|
||||
| sh64 | sh64le \
|
||||
| sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \
|
||||
| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
|
||||
| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
|
||||
| strongarm \
|
||||
| tahoe | thumb | tic4x | tic80 | tron \
|
||||
| v850 | v850e \
|
||||
| we32k \
|
||||
| x86 | xscale | xstormy16 | xtensa \
|
||||
| x86 | xscale | xscalee[bl] | xstormy16 | xtensa \
|
||||
| z8k)
|
||||
basic_machine=$basic_machine-unknown
|
||||
;;
|
||||
m32c)
|
||||
basic_machine=$basic_machine-unknown
|
||||
;;
|
||||
m6811 | m68hc11 | m6812 | m68hc12)
|
||||
# Motorola 68HC11/12.
|
||||
basic_machine=$basic_machine-unknown
|
||||
@@ -276,6 +297,9 @@ case $basic_machine in
|
||||
;;
|
||||
m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
|
||||
;;
|
||||
ms1)
|
||||
basic_machine=mt-unknown
|
||||
;;
|
||||
|
||||
# We use `pc' rather than `unknown'
|
||||
# because (1) that's what they normally are, and
|
||||
@@ -296,19 +320,19 @@ case $basic_machine in
|
||||
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
|
||||
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
|
||||
| avr-* \
|
||||
| bs2000-* \
|
||||
| bfin-* | bs2000-* \
|
||||
| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
|
||||
| clipper-* | cydra-* \
|
||||
| clipper-* | craynv-* | cydra-* \
|
||||
| d10v-* | d30v-* | dlx-* \
|
||||
| elxsi-* \
|
||||
| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
|
||||
| h8300-* | h8500-* \
|
||||
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
|
||||
| i*86-* | i860-* | i960-* | ia64-* \
|
||||
| ip2k-* \
|
||||
| m32r-* \
|
||||
| ip2k-* | iq2000-* \
|
||||
| m32r-* | m32rle-* \
|
||||
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
|
||||
| m88110-* | m88k-* | mcore-* \
|
||||
| m88110-* | m88k-* | maxq-* | mcore-* \
|
||||
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
|
||||
| mips16-* \
|
||||
| mips64-* | mips64el-* \
|
||||
@@ -317,34 +341,41 @@ case $basic_machine in
|
||||
| mips64vr4100-* | mips64vr4100el-* \
|
||||
| mips64vr4300-* | mips64vr4300el-* \
|
||||
| mips64vr5000-* | mips64vr5000el-* \
|
||||
| mips64vr5900-* | mips64vr5900el-* \
|
||||
| mipsisa32-* | mipsisa32el-* \
|
||||
| mipsisa32r2-* | mipsisa32r2el-* \
|
||||
| mipsisa64-* | mipsisa64el-* \
|
||||
| mipsisa64r2-* | mipsisa64r2el-* \
|
||||
| mipsisa64sb1-* | mipsisa64sb1el-* \
|
||||
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
|
||||
| mipstx39-* | mipstx39el-* \
|
||||
| mmix-* \
|
||||
| mt-* \
|
||||
| msp430-* \
|
||||
| none-* | np1-* | nv1-* | ns16k-* | ns32k-* \
|
||||
| nios-* | nios2-* \
|
||||
| none-* | np1-* | ns16k-* | ns32k-* \
|
||||
| orion-* \
|
||||
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
|
||||
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
|
||||
| pyramid-* \
|
||||
| romp-* | rs6000-* \
|
||||
| s390-* | s390x-* \
|
||||
| sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \
|
||||
| sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | shbe-* \
|
||||
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
|
||||
| sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
|
||||
| sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
|
||||
| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
|
||||
| sparclite-* \
|
||||
| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
|
||||
| tahoe-* | thumb-* \
|
||||
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
|
||||
| tron-* \
|
||||
| v850-* | v850e-* | vax-* \
|
||||
| we32k-* \
|
||||
| x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
|
||||
| xtensa-* \
|
||||
| x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \
|
||||
| xstormy16-* | xtensa-* \
|
||||
| ymp-* \
|
||||
| z8k-*)
|
||||
;;
|
||||
m32c-*)
|
||||
;;
|
||||
# Recognize the various machine names and aliases which stand
|
||||
# for a CPU type and a company and sometimes even an OS.
|
||||
386bsd)
|
||||
@@ -361,6 +392,9 @@ case $basic_machine in
|
||||
basic_machine=a29k-amd
|
||||
os=-udi
|
||||
;;
|
||||
abacus)
|
||||
basic_machine=abacus-unknown
|
||||
;;
|
||||
adobe68k)
|
||||
basic_machine=m68010-adobe
|
||||
os=-scout
|
||||
@@ -378,6 +412,9 @@ case $basic_machine in
|
||||
amd64)
|
||||
basic_machine=x86_64-pc
|
||||
;;
|
||||
amd64-*)
|
||||
basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
amdahl)
|
||||
basic_machine=580-amdahl
|
||||
os=-sysv
|
||||
@@ -437,12 +474,27 @@ case $basic_machine in
|
||||
basic_machine=j90-cray
|
||||
os=-unicos
|
||||
;;
|
||||
craynv)
|
||||
basic_machine=craynv-cray
|
||||
os=-unicosmp
|
||||
;;
|
||||
cr16c)
|
||||
basic_machine=cr16c-unknown
|
||||
os=-elf
|
||||
;;
|
||||
crds | unos)
|
||||
basic_machine=m68k-crds
|
||||
;;
|
||||
crisv32 | crisv32-* | etraxfs*)
|
||||
basic_machine=crisv32-axis
|
||||
;;
|
||||
cris | cris-* | etrax*)
|
||||
basic_machine=cris-axis
|
||||
;;
|
||||
crx)
|
||||
basic_machine=crx-unknown
|
||||
os=-elf
|
||||
;;
|
||||
da30 | da30-*)
|
||||
basic_machine=m68k-da30
|
||||
;;
|
||||
@@ -465,6 +517,10 @@ case $basic_machine in
|
||||
basic_machine=m88k-motorola
|
||||
os=-sysv3
|
||||
;;
|
||||
djgpp)
|
||||
basic_machine=i586-pc
|
||||
os=-msdosdjgpp
|
||||
;;
|
||||
dpx20 | dpx20-*)
|
||||
basic_machine=rs6000-bull
|
||||
os=-bosx
|
||||
@@ -643,10 +699,6 @@ case $basic_machine in
|
||||
mips3*)
|
||||
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
|
||||
;;
|
||||
mmix*)
|
||||
basic_machine=mmix-knuth
|
||||
os=-mmixware
|
||||
;;
|
||||
monitor)
|
||||
basic_machine=m68k-rom68k
|
||||
os=-coff
|
||||
@@ -659,6 +711,9 @@ case $basic_machine in
|
||||
basic_machine=i386-pc
|
||||
os=-msdos
|
||||
;;
|
||||
ms1-*)
|
||||
basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
|
||||
;;
|
||||
mvs)
|
||||
basic_machine=i370-ibm
|
||||
os=-mvs
|
||||
@@ -727,10 +782,6 @@ case $basic_machine in
|
||||
np1)
|
||||
basic_machine=np1-gould
|
||||
;;
|
||||
nv1)
|
||||
basic_machine=nv1-cray
|
||||
os=-unicosmp
|
||||
;;
|
||||
nsr-tandem)
|
||||
basic_machine=nsr-tandem
|
||||
;;
|
||||
@@ -738,9 +789,12 @@ case $basic_machine in
|
||||
basic_machine=hppa1.1-oki
|
||||
os=-proelf
|
||||
;;
|
||||
or32 | or32-*)
|
||||
openrisc | openrisc-*)
|
||||
basic_machine=or32-unknown
|
||||
os=-coff
|
||||
;;
|
||||
os400)
|
||||
basic_machine=powerpc-ibm
|
||||
os=-os400
|
||||
;;
|
||||
OSE68000 | ose68000)
|
||||
basic_machine=m68000-ericsson
|
||||
@@ -767,6 +821,12 @@ case $basic_machine in
|
||||
pc532 | pc532-*)
|
||||
basic_machine=ns32k-pc532
|
||||
;;
|
||||
pc98)
|
||||
basic_machine=i386-pc
|
||||
;;
|
||||
pc98-*)
|
||||
basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
pentium | p5 | k5 | k6 | nexgen | viac3)
|
||||
basic_machine=i586-pc
|
||||
;;
|
||||
@@ -823,6 +883,10 @@ case $basic_machine in
|
||||
basic_machine=i586-unknown
|
||||
os=-pw32
|
||||
;;
|
||||
rdos)
|
||||
basic_machine=i386-pc
|
||||
os=-rdos
|
||||
;;
|
||||
rom68k)
|
||||
basic_machine=m68k-rom68k
|
||||
os=-coff
|
||||
@@ -833,6 +897,12 @@ case $basic_machine in
|
||||
rtpc | rtpc-*)
|
||||
basic_machine=romp-ibm
|
||||
;;
|
||||
s390 | s390-*)
|
||||
basic_machine=s390-ibm
|
||||
;;
|
||||
s390x | s390x-*)
|
||||
basic_machine=s390x-ibm
|
||||
;;
|
||||
sa29200)
|
||||
basic_machine=a29k-amd
|
||||
os=-udi
|
||||
@@ -956,6 +1026,10 @@ case $basic_machine in
|
||||
tower | tower-32)
|
||||
basic_machine=m68k-ncr
|
||||
;;
|
||||
tpf)
|
||||
basic_machine=s390x-ibm
|
||||
os=-tpf
|
||||
;;
|
||||
udi29k)
|
||||
basic_machine=a29k-amd
|
||||
os=-udi
|
||||
@@ -999,6 +1073,10 @@ case $basic_machine in
|
||||
basic_machine=hppa1.1-winbond
|
||||
os=-proelf
|
||||
;;
|
||||
xbox)
|
||||
basic_machine=i686-pc
|
||||
os=-mingw32
|
||||
;;
|
||||
xps | xps100)
|
||||
basic_machine=xps100-honeywell
|
||||
;;
|
||||
@@ -1029,6 +1107,9 @@ case $basic_machine in
|
||||
romp)
|
||||
basic_machine=romp-ibm
|
||||
;;
|
||||
mmix)
|
||||
basic_machine=mmix-knuth
|
||||
;;
|
||||
rs6000)
|
||||
basic_machine=rs6000-ibm
|
||||
;;
|
||||
@@ -1045,13 +1126,10 @@ case $basic_machine in
|
||||
we32k)
|
||||
basic_machine=we32k-att
|
||||
;;
|
||||
sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele)
|
||||
sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
|
||||
basic_machine=sh-unknown
|
||||
;;
|
||||
sh64)
|
||||
basic_machine=sh64-unknown
|
||||
;;
|
||||
sparc | sparcv9 | sparcv9b)
|
||||
sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
|
||||
basic_machine=sparc-sun
|
||||
;;
|
||||
cydra)
|
||||
@@ -1124,19 +1202,23 @@ case $os in
|
||||
| -aos* \
|
||||
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
|
||||
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
|
||||
| -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
|
||||
| -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
|
||||
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
|
||||
| -openbsd* | -solidbsd* \
|
||||
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
|
||||
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
|
||||
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
|
||||
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
|
||||
| -chorusos* | -chorusrdb* \
|
||||
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
|
||||
| -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
|
||||
| -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
|
||||
| -uxpv* | -beos* | -mpeix* | -udk* \
|
||||
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
|
||||
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
|
||||
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
|
||||
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
|
||||
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
|
||||
| -powermax* | -dnix* | -nx6 | -nx7 | -sei*)
|
||||
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
|
||||
| -skyos* | -haiku* | -rdos*)
|
||||
# Remember, each alternative MUST END IN *, to match a version number.
|
||||
;;
|
||||
-qnx*)
|
||||
@@ -1154,12 +1236,15 @@ case $os in
|
||||
os=`echo $os | sed -e 's|nto|nto-qnx|'`
|
||||
;;
|
||||
-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
|
||||
| -windows* | -osx | -abug | -netware* | -os9* | -beos* \
|
||||
| -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
|
||||
| -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
|
||||
;;
|
||||
-mac*)
|
||||
os=`echo $os | sed -e 's|mac|macos|'`
|
||||
;;
|
||||
-linux-dietlibc)
|
||||
os=-linux-dietlibc
|
||||
;;
|
||||
-linux*)
|
||||
os=`echo $os | sed -e 's|linux|linux-gnu|'`
|
||||
;;
|
||||
@@ -1172,6 +1257,9 @@ case $os in
|
||||
-opened*)
|
||||
os=-openedition
|
||||
;;
|
||||
-os400*)
|
||||
os=-os400
|
||||
;;
|
||||
-wince*)
|
||||
os=-wince
|
||||
;;
|
||||
@@ -1193,6 +1281,9 @@ case $os in
|
||||
-atheos*)
|
||||
os=-atheos
|
||||
;;
|
||||
-syllable*)
|
||||
os=-syllable
|
||||
;;
|
||||
-386bsd)
|
||||
os=-bsd
|
||||
;;
|
||||
@@ -1215,6 +1306,9 @@ case $os in
|
||||
-sinix*)
|
||||
os=-sysv4
|
||||
;;
|
||||
-tpf*)
|
||||
os=-tpf
|
||||
;;
|
||||
-triton*)
|
||||
os=-sysv3
|
||||
;;
|
||||
@@ -1251,6 +1345,9 @@ case $os in
|
||||
-kaos*)
|
||||
os=-kaos
|
||||
;;
|
||||
-zvmoe)
|
||||
os=-zvmoe
|
||||
;;
|
||||
-none)
|
||||
;;
|
||||
*)
|
||||
@@ -1282,9 +1379,9 @@ case $basic_machine in
|
||||
arm*-semi)
|
||||
os=-aout
|
||||
;;
|
||||
c4x-* | tic4x-*)
|
||||
os=-coff
|
||||
;;
|
||||
c4x-* | tic4x-*)
|
||||
os=-coff
|
||||
;;
|
||||
# This must come before the *-dec entry.
|
||||
pdp10-*)
|
||||
os=-tops20
|
||||
@@ -1328,9 +1425,15 @@ case $basic_machine in
|
||||
*-be)
|
||||
os=-beos
|
||||
;;
|
||||
*-haiku)
|
||||
os=-haiku
|
||||
;;
|
||||
*-ibm)
|
||||
os=-aix
|
||||
;;
|
||||
*-knuth)
|
||||
os=-mmixware
|
||||
;;
|
||||
*-wec)
|
||||
os=-proelf
|
||||
;;
|
||||
@@ -1463,9 +1566,15 @@ case $basic_machine in
|
||||
-mvs* | -opened*)
|
||||
vendor=ibm
|
||||
;;
|
||||
-os400*)
|
||||
vendor=ibm
|
||||
;;
|
||||
-ptx*)
|
||||
vendor=sequent
|
||||
;;
|
||||
-tpf*)
|
||||
vendor=ibm
|
||||
;;
|
||||
-vxsim* | -vxworks* | -windiss*)
|
||||
vendor=wrs
|
||||
;;
|
||||
@@ -1490,7 +1599,7 @@ case $basic_machine in
|
||||
esac
|
||||
|
||||
echo $basic_machine$os
|
||||
exit 0
|
||||
exit
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
|
||||
682
configure.ac
682
configure.ac
@@ -1,14 +1,72 @@
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
AC_INIT(fish,1.20.2,fish-users@lists.sf.net)
|
||||
|
||||
#
|
||||
# This file is the main build configuration file for fish. It is used
|
||||
# to determine your systems capabilities, and tried to adapt fish to
|
||||
# take maximum advantage of the services your system offers.
|
||||
#
|
||||
# Process this file using the 'autoconf' to produce a working
|
||||
# configure script, which should in turn be executed in order to
|
||||
# configure the build process.
|
||||
#
|
||||
|
||||
AC_INIT(fish,1.21.12,fish-users@lists.sf.net)
|
||||
|
||||
# If needed, run autoconf to regenerate the configure file
|
||||
AC_MSG_CHECKING([if autoconf needs to be run])
|
||||
if test configure -ot configure.ac; then
|
||||
AC_MSG_RESULT([yes])
|
||||
if which autoconf >/dev/null; then
|
||||
# No need to provide any error messages if autoconf fails, the
|
||||
# shell and autconf should take care of that themselves
|
||||
AC_MSG_NOTICE([running autoconf])
|
||||
if autoconf; then
|
||||
./configure "$@"
|
||||
exit
|
||||
fi
|
||||
exit 1
|
||||
else
|
||||
AC_MSG_ERROR(
|
||||
[cannot find the autoconf program in your path.
|
||||
This program needs to be run whenever the configure.ac file is modified.
|
||||
Please install it and try again.]
|
||||
)
|
||||
fi
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
|
||||
|
||||
# If needed, run autoheader to regenerate config.h.in
|
||||
AC_MSG_CHECKING([if autoheader needs to be run])
|
||||
if test ! -f ./config.h.in -o config.h.in -ot configure.ac; then
|
||||
AC_MSG_RESULT([yes])
|
||||
if which autoheader >/dev/null; then
|
||||
AC_MSG_NOTICE([running autoheader])
|
||||
autoheader || exit 1
|
||||
else
|
||||
AC_MSG_ERROR(
|
||||
[cannot find the autoheader program in your path.
|
||||
This program needs to be run whenever the configure.ac file is modified.
|
||||
Please install it and try again.]
|
||||
)
|
||||
fi
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
|
||||
|
||||
# Detect directories which may contain additional headers, libraries
|
||||
# and commands. This needs to be done early - before Autoconf starts
|
||||
# to mess with CFLAGS and all the other environemnt variables.
|
||||
for i in /usr/pkg /sw /opt /opt/local; do
|
||||
|
||||
AC_MSG_CHECKING([for $i/include include directory])
|
||||
if test -d $i/include; then
|
||||
AC_MSG_RESULT(yes)
|
||||
CPPFLAGS="$CPPFLAGS -I$i/include/"
|
||||
CFLAGS="$CFLAGS -I$i/include/"
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([for $i/lib library directory])
|
||||
@@ -31,22 +89,6 @@ done
|
||||
|
||||
AC_SUBST( optbindirs, $optbindirs )
|
||||
|
||||
# If needed, run autoheader automatically
|
||||
AC_MSG_CHECKING([if autoheader needs to be run])
|
||||
if test ! -f ./config.h.in -o config.h.in -ot configure.ac; then
|
||||
AC_MSG_RESULT([yes])
|
||||
if which autoheader >/dev/null; then
|
||||
AC_MSG_NOTICE([running autoheader])
|
||||
autoheader
|
||||
else
|
||||
AC_MSG_ERROR( [cannot find the autoheader program in your path.
|
||||
This program is needed because the configure.ac file has been modified.
|
||||
Please install it and try again.])
|
||||
fi
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
|
||||
# Tell autoconf to create config.h header
|
||||
AC_CONFIG_HEADERS(config.h)
|
||||
|
||||
@@ -55,24 +97,20 @@ AC_PROG_CC
|
||||
AC_PROG_CPP
|
||||
AC_PROG_INSTALL
|
||||
|
||||
# Check for doxygen, which is needed to build
|
||||
AC_CHECK_PROG( has_doxygen, [doxygen], "true")
|
||||
|
||||
if ! test $has_doxygen = "true"; then
|
||||
AC_MSG_ERROR( [cannot find the Doxygen program in your path.
|
||||
This program is needed to build fish.
|
||||
Please install it and try again.])
|
||||
fi
|
||||
|
||||
# Check for seq program. If missing, install fallback shellscript implementation
|
||||
# Check for seq command. If missing, make sure fallback shellscript
|
||||
# implementation is installed
|
||||
AC_CHECK_PROG( SEQ_FALLBACK, seq, [ ], [seq])
|
||||
|
||||
# Optionally drop xsel
|
||||
AC_ARG_WITH( xsel,
|
||||
AC_HELP_STRING([--without-xsel],
|
||||
[do not build the xsel program needed for X clipboard integration]),
|
||||
[xsel=$withval],
|
||||
[xsel=with_xsel] )
|
||||
# Optionally drop xsel command
|
||||
AC_ARG_WITH(
|
||||
xsel,
|
||||
AC_HELP_STRING(
|
||||
[--without-xsel],
|
||||
[do not build the xsel program needed for X clipboard integration]
|
||||
),
|
||||
[xsel=$withval],
|
||||
[xsel=with_xsel]
|
||||
)
|
||||
|
||||
if [[ "$xsel" = "with_xsel" ]]; then
|
||||
AC_SUBST( XSEL,[xsel-0.9.6/xsel])
|
||||
@@ -84,159 +122,533 @@ else
|
||||
AC_SUBST( XSEL_MAN_PATH,[ ])
|
||||
fi
|
||||
|
||||
# These help out with getting better prototypes on some platforms
|
||||
|
||||
#
|
||||
# Test if the compiler accepts the -std=c99 flag. If so, using it
|
||||
# increases the odds of correct compilation, since we want to use the
|
||||
# *wprintf functions, which where defined in C99.
|
||||
|
||||
XCFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS -std=c99"
|
||||
XCPPFLAGS="$CPPFLAGS"
|
||||
CPPFLAGS="$CPPFLAGS -std=c99"
|
||||
AC_MSG_CHECKING(if -std=c99 works)
|
||||
AC_CACHE_VAL(
|
||||
local_cv_has__std_c99,
|
||||
[
|
||||
AC_TRY_RUN(
|
||||
[
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
],
|
||||
local_cv_has__std_c99=yes,
|
||||
local_cv_has__std_c99=no,
|
||||
)
|
||||
]
|
||||
)
|
||||
AC_MSG_RESULT($local_cv_has__std_c99)
|
||||
case x$local_cv_has__std_c99 in
|
||||
xno)
|
||||
CFLAGS="$XCFLAGS"
|
||||
CPPFLAGS="$XCPPFLAGS" ;;
|
||||
esac
|
||||
|
||||
|
||||
#
|
||||
# If we are using gcc, set some flags that increase the odds of the
|
||||
# compiler producing a working binary...
|
||||
#
|
||||
|
||||
if test "$CC" = gcc; then
|
||||
|
||||
#
|
||||
# -fno-optimize-sibling-calls seems to work around a bug where
|
||||
# sending a SIGWINCH to fish on NetBSD 3.0 causes fish to exit when
|
||||
# compiled with GCC 3.3.3. This is probably either a compiler bug
|
||||
# or a libc bug, but adding this flag seems to fix things for
|
||||
# now. Long term, the real problem should be tracked down and
|
||||
# truly fixed, at which point we can remove this silly flag. This
|
||||
# bug has been verified to not exist on Linux using GCC 3.3.3.
|
||||
#
|
||||
|
||||
CFLAGS="$CFLAGS -fno-optimize-sibling-calls"
|
||||
|
||||
|
||||
#
|
||||
# -Wall is there to keep me on my toes
|
||||
#
|
||||
|
||||
CFLAGS="$CFLAGS -Wall"
|
||||
|
||||
fi
|
||||
|
||||
#
|
||||
# If we are compiling against glibc, set some flags to work around
|
||||
# some rather stupid attempts to hide prototypes for *wprintf
|
||||
# functions, as well as prototypes of various gnu extensions.
|
||||
#
|
||||
|
||||
AC_MSG_CHECKING([if we are compiling against glibc])
|
||||
AC_RUN_IFELSE(
|
||||
[
|
||||
AC_LANG_PROGRAM(
|
||||
[
|
||||
#include <stdlib.h>
|
||||
#ifdef __GLIBC__
|
||||
#define STATUS 0
|
||||
#else
|
||||
#define STATUS 1
|
||||
#endif
|
||||
],
|
||||
[
|
||||
return STATUS;
|
||||
]
|
||||
)
|
||||
],
|
||||
[glibc=yes],
|
||||
[glibc=no]
|
||||
)
|
||||
|
||||
if test "$glibc" = yes; then
|
||||
AC_MSG_RESULT(yes)
|
||||
|
||||
#
|
||||
# This gives us access to prototypes for gnu extensions and C99
|
||||
# functions if we are compiling agains glibc. All GNU extensions
|
||||
# that are used must have a fallback implementation available in
|
||||
# fallback.h, in order to keep fish working on non-gnu platforms.
|
||||
#
|
||||
|
||||
AC_DEFINE( _GNU_SOURCE, 1, [Macro to enable additional prototypes under Glibc])
|
||||
AC_DEFINE( _ISOC99_SOURCE, 1, [Macro to enable additional prototypes under Glibc])
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
# Test cpu for special handling of ppc
|
||||
#
|
||||
# This is used to skip use of tputs on ppc systems, since it seemed to
|
||||
# be broken, at least on older debin-based systems. This is obviously
|
||||
# not the right way to to detect whether this workaround should be
|
||||
# used, since it catches far to many systems, but I do not have the
|
||||
# hardware available to narrow this problem down, and in practice, it
|
||||
# seems that tputs is never really needed.
|
||||
#
|
||||
AC_CANONICAL_TARGET
|
||||
|
||||
if test $target_cpu = powerpc; then
|
||||
AC_DEFINE([TPUTS_KLUDGE],[1],[Evil kludge to get Power based machines to work])
|
||||
fi
|
||||
|
||||
AC_DEFINE_UNQUOTED([CPU],[L"$target_cpu"],[CPU type])
|
||||
# Solaris-specific flags go here
|
||||
AC_MSG_CHECKING([if we are under Solaris])
|
||||
case $target_os in
|
||||
solaris*)
|
||||
AC_DEFINE( __EXTENSIONS__, 1, [Macro to enable additional prototypes under Solaris])
|
||||
AC_MSG_RESULT(yes)
|
||||
;;
|
||||
*)
|
||||
AC_MSG_RESULT(no)
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
# Set up installation directories
|
||||
# BSD-specific flags go here
|
||||
AC_MSG_CHECKING([if we are under BSD])
|
||||
case $target_os in
|
||||
*bsd*)
|
||||
AC_DEFINE( __BSD_VISIBLE, 1, [Macro to enable additional prototypes under BSD])
|
||||
AC_DEFINE( _NETBSD_SOURCE, 1, [Macro to enable additional prototypes under BSD])
|
||||
AC_MSG_RESULT(yes)
|
||||
;;
|
||||
*)
|
||||
AC_MSG_RESULT(no)
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
|
||||
# Set up PREFIX and related preprocessor symbols. Fish needs to know
|
||||
# where it will be installed. One of the reasons for this is so that
|
||||
# it can make sure the fish installation directory is in the path
|
||||
# during startup.
|
||||
if [[ "$prefix" = NONE ]]; then
|
||||
AC_DEFINE_UNQUOTED( [PREFIX], L"/usr/local", [Installation directory])
|
||||
AC_SUBST( PREFIX, /usr/local)
|
||||
export prefix=/usr/local
|
||||
AC_SUBST( prefix, /usr/local)
|
||||
else
|
||||
AC_DEFINE_UNQUOTED( [PREFIX], L"$prefix", [Installation directory])
|
||||
AC_SUBST( PREFIX, [$prefix])
|
||||
AC_SUBST( prefix, [$prefix])
|
||||
fi
|
||||
|
||||
AC_SUBST(fishdir,[/fish.d])
|
||||
AC_SUBST(fishfile,[/fish])
|
||||
AC_SUBST(fishinputfile,[/fish_inputrc])
|
||||
|
||||
# Set up the directory where the documentation files should be
|
||||
# installed
|
||||
AC_ARG_VAR( [docdir], [Documentation direcotry] )
|
||||
|
||||
if test -z $docdir; then
|
||||
AC_SUBST(docdir,[$datadir/doc/fish])
|
||||
AC_SUBST(docdir, [$datadir/doc/fish] )
|
||||
else
|
||||
AC_SUBST(docdir, [$docdir])
|
||||
fi
|
||||
|
||||
AC_DEFINE_UNQUOTED( DOCDIR, [L"$(eval echo $docdir)"], [Documentation directory] )
|
||||
AC_DEFINE_UNQUOTED( SYSCONFDIR, [L"$(eval echo $sysconfdir)"], [System configuration directory] )
|
||||
AC_SUBST( SYSCONFDIR, ["$(eval echo $sysconfdir)"] )
|
||||
# Set up locale directory. This is where the .po files will be
|
||||
# installed.
|
||||
AC_SUBST( [localedir], [$datadir/locale])
|
||||
|
||||
# Set up locale directory
|
||||
AC_DEFINE_UNQUOTED( [LOCALEDIR], "$(eval echo $datadir)/locale", [Locale directory])
|
||||
AC_SUBST( [LOCALEDIR], [$datadir/locale])
|
||||
|
||||
# See if Linux procfs is present
|
||||
# See if Linux procfs is present. This is used to get extra
|
||||
# information about running processes.
|
||||
AC_CHECK_FILES([/proc/self/stat])
|
||||
|
||||
# Check for RLIMIT_AS in sys/resource.h.
|
||||
AC_MSG_CHECKING([for RLIMIT_AS in sys/resource.h])
|
||||
AC_TRY_COMPILE([#include <sys/resource.h>],
|
||||
[int tmp; tmp=RLIMIT_AS;], have_rlimit_as=yes, have_rlimit_as=no)
|
||||
if test "$have_rlimit_as" = yes; then
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE([HAVE_RLIMIT_AS], [1],
|
||||
[Define to 1 if HAVE_RLIMIT_AS is defined in <sys/resource.h>.])
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
# This is ued to tell the wgetopt library to translate strings. This
|
||||
# way wgetopt can be dropped into any project without requiring i18n.
|
||||
|
||||
AC_DEFINE(
|
||||
[HAVE_TRANSLATE_H],
|
||||
[1],
|
||||
[Define to 1 if the wgettext function should be used for translating strings.]
|
||||
)
|
||||
|
||||
# Check for presense of various libraries
|
||||
AC_SEARCH_LIBS( gettext, intl,,)
|
||||
AC_SEARCH_LIBS( connect, socket, , [AC_MSG_ERROR([Cannot find the socket library, needed to build this package.] )] )
|
||||
AC_SEARCH_LIBS( nanosleep, rt, , [AC_MSG_ERROR([Cannot find the rt library, needed to build this package.] )] )
|
||||
AC_SEARCH_LIBS( setupterm, [ncurses curses], , [AC_MSG_ERROR([Could not find a curses implementation, needed to build fish])] )
|
||||
|
||||
# Check for presense of various header files
|
||||
AC_CHECK_HEADERS([getopt.h termio.h sys/resource.h term.h ncurses/term.h libintl.h ncurses.h curses.h stropts.h siginfo.h sys/select.h sys/ioctl.h sys/termios.h])
|
||||
|
||||
AC_CHECK_HEADER(
|
||||
[regex.h],
|
||||
[
|
||||
AC_DEFINE(
|
||||
[HAVE_REGEX_H],
|
||||
[1],
|
||||
[Define to 1 if you have the <regex.h> header file.]
|
||||
)],
|
||||
[AC_MSG_ERROR([Could not find the header regex.h, needed to build fish])
|
||||
]
|
||||
)
|
||||
|
||||
#
|
||||
# On some platforms (Solaris 10) adding -std=c99 in turn requires that
|
||||
# _POSIX_C_SOURCE be defined to 200112L otherwise several
|
||||
# POSIX-specific, non-ISO-C99 types/prototypes are made unavailable
|
||||
# e.g. siginfo_t. Defining _XOPEN_SOURCE to 600 is compatible with
|
||||
# the _POSIX_C_SOURCE value and provides a little assurance that
|
||||
# extension functions' prototypes are available, e.g. killpg().
|
||||
#
|
||||
# Some other platforms (OS X), will remove types/prototypes/macros
|
||||
# e.g. SIGWINCH if either _POSIX_C_SOURCE or _XOPEN_SOURCE is defined.
|
||||
#
|
||||
# This test adds these macros only if they enable a program that uses
|
||||
# both Posix and non-standard features to compile, and that program
|
||||
# does not compile without these macros.
|
||||
#
|
||||
# We try to make everyone happy.
|
||||
#
|
||||
# The ordering of the various autoconf tests is very critical as well:
|
||||
#
|
||||
# * This test needs to be run _after_ header detection tests, so that
|
||||
# the proper headers are included.
|
||||
#
|
||||
# * This test needs to be run _before_ testing for the presense of any
|
||||
# prototypes or other language functinality.
|
||||
#
|
||||
# * This test should be (but does not need to be) run after the
|
||||
# conditional definition of __EXTENSIONS__, to avoid redundant tests.
|
||||
|
||||
XCFLAGS="$CFLAGS"
|
||||
|
||||
echo Checking how to use -D_XOPEN_SOURCE=600 and -D_POSIX_C_SOURCE=200112L...
|
||||
local_found_posix_switch=no
|
||||
|
||||
for i in "" "-D_POSIX_C_SOURCE=200112L" "-D_XOPEN_SOURCE=600 -D_POSIX_C_SOURCE=200112L"; do
|
||||
|
||||
AC_MSG_CHECKING( if switches \"$i\" works)
|
||||
CFLAGS="$XCFLAGS $i"
|
||||
|
||||
#
|
||||
# Try to run this program, which should test various extensions
|
||||
# and Posix functionality. If this program works, then everything
|
||||
# should work. Hopefully.
|
||||
#
|
||||
|
||||
AC_TRY_LINK(
|
||||
[
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
/* POSIX, C89 and C99: POSIX extends this header.
|
||||
* For: kill(), killpg(), siginfo_t, sigset_t,
|
||||
* struct sigaction, sigemptyset(), sigaction(),
|
||||
* SIGIO and SIGWINCH. */
|
||||
#include <signal.h>
|
||||
|
||||
#ifdef HAVE_SIGINFO_H
|
||||
/* Neither POSIX, C89 nor C99: Solaris-specific (others?).
|
||||
* For: siginfo_t (also defined by signal.h when in
|
||||
* POSIX/extensions mode). */
|
||||
#include <siginfo.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_TERMIOS_H
|
||||
/* Neither POSIX, C89 nor C99: a common extension.
|
||||
* For: TIOCGWINSZ and struct winsize (under at least
|
||||
* Solaris, NetBSD and (dual-listed) FreeBSD). */
|
||||
#include <sys/termios.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_IOCTL_H
|
||||
/* As above (under at least Linux and FreeBSD). */
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
],
|
||||
[
|
||||
/* Avert high-level optimisation, by making the program's
|
||||
* return value depend on all tested identifiers. */
|
||||
int ret = 0;
|
||||
/* POSIX only: might be unhidden by _POSIX_C_SOURCE. */
|
||||
struct sigaction sa;
|
||||
sigset_t ss;
|
||||
siginfo_t info;
|
||||
ret += (int)(void *)&info + kill( 0, 0 ) +
|
||||
sigaction( 0, &sa, 0 ) + sigemptyset( &ss );
|
||||
/* Extended-POSIX: might be unhidden by _XOPEN_SOURCE. */
|
||||
ret += killpg( 0, 0 );
|
||||
/* Non-standard: might be hidden by the macros. */
|
||||
{
|
||||
struct winsize termsize;
|
||||
ret += (int)(void *)&termsize;
|
||||
ret += SIGWINCH + TIOCGWINSZ + SIGIO;
|
||||
}
|
||||
return ret;
|
||||
|
||||
],
|
||||
local_cv_use__posix_c_source=yes,
|
||||
local_cv_use__posix_c_source=no,
|
||||
)
|
||||
|
||||
if test x$local_cv_use__posix_c_source = xyes; then
|
||||
AC_MSG_RESULT( yes )
|
||||
local_found_posix_switch=yes
|
||||
break;
|
||||
else
|
||||
AC_MSG_RESULT( no )
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
# We didn't find any combination of switches that worked - revert to
|
||||
# no switches and hope that the fallbacks work. A warning will be
|
||||
# printed at the end of the configure script.
|
||||
|
||||
if test ! x$local_found_posix_switch = xyes; then
|
||||
CFLAGS="$XCFLAGS"
|
||||
fi
|
||||
|
||||
# Check for RLIMIT_MEMLOCK in sys/resource.h.
|
||||
AC_MSG_CHECKING([for RLIMIT_MEMLOCK in sys/resource.h])
|
||||
AC_TRY_COMPILE([#include <sys/resource.h>],
|
||||
[int tmp; tmp=RLIMIT_MEMLOCK;], have_rlimit_as=yes, have_rlimit_as=no)
|
||||
if test "$have_rlimit_as" = yes; then
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE([HAVE_RLIMIT_MEMLOCK], [1],
|
||||
[Define to 1 if HAVE_RLIMIT_MEMLOCK is defined in <sys/resource.h>.])
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
# Check for presense of various functions
|
||||
AC_CHECK_FUNCS( gettext wcsdup wcsndup wcslen wcscasecmp wcsncasecmp fwprintf )
|
||||
AC_CHECK_FUNCS( futimes wcwidth wcswidth wcstok fputwc fgetwc )
|
||||
AC_CHECK_FUNCS( wcstol dcgettext wcslcat wcslcpy lrand48_r killpg)
|
||||
|
||||
# Check for RLIMIT_RSS in sys/resource.h.
|
||||
AC_MSG_CHECKING([for RLIMIT_RSS in sys/resource.h])
|
||||
AC_TRY_COMPILE([#include <sys/resource.h>],
|
||||
[int tmp; tmp=RLIMIT_RSS;], have_rlimit_as=yes, have_rlimit_as=no)
|
||||
if test "$have_rlimit_as" = yes; then
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE([HAVE_RLIMIT_RSS], [1],
|
||||
[Define to 1 if HAVE_RLIMIT_RSS is defined in <sys/resource.h>.])
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
# The Makefile also needs to know if we have gettext, so it knows if the translations should be installed.
|
||||
AC_CHECK_FUNC( gettext, AC_SUBST( HAVE_GETTEXT, 1 ), AC_SUBST( HAVE_GETTEXT, 0 ) )
|
||||
|
||||
|
||||
# Check for RLIMIT_NPROC in sys/resource.h.
|
||||
AC_MSG_CHECKING([for RLIMIT_NPROC in sys/resource.h])
|
||||
AC_TRY_COMPILE([#include <sys/resource.h>],
|
||||
[int tmp; tmp=RLIMIT_NPROC;], have_rlimit_as=yes, have_rlimit_as=no)
|
||||
if test "$have_rlimit_as" = yes; then
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE([HAVE_RLIMIT_NPROC], [1],
|
||||
[Define to 1 if HAVE_RLIMIT_NPROC is defined in <sys/resource.h>.])
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
# Here follows a list of small programs used to test for various
|
||||
# features that Autoconf doesn't tell us about
|
||||
|
||||
# Check if realpath accepts null for its second argument
|
||||
AC_MSG_CHECKING([if realpath accepts null for its second argument])
|
||||
AC_RUN_IFELSE(
|
||||
[AC_LANG_PROGRAM([#include <limits.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>],
|
||||
[int status; char *res; res = realpath( "somefile", 0 ); status = !(res != 0 || errno == ENOENT); exit( status );])],
|
||||
[
|
||||
AC_LANG_PROGRAM(
|
||||
[
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
],
|
||||
[
|
||||
int status;
|
||||
char *res;
|
||||
res = realpath( "somefile", 0 );
|
||||
status = !(res != 0 || errno == ENOENT);
|
||||
exit( status );
|
||||
]
|
||||
)
|
||||
],
|
||||
[have_realpath_null=yes],
|
||||
[have_realpath_null=no] )
|
||||
[have_realpath_null=no]
|
||||
)
|
||||
|
||||
if test "$have_realpath_null" = yes; then
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE([HAVE_REALPATH_NULL], [1],
|
||||
[Define to 1 if realpath accepts null for its second argument.])
|
||||
AC_DEFINE(
|
||||
[HAVE_REALPATH_NULL],
|
||||
[1],
|
||||
[Define to 1 if realpath accepts null for its second argument.]
|
||||
)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
|
||||
# Check for libraries
|
||||
AC_CHECK_LIB(socket, connect)
|
||||
AC_CHECK_LIB(rt, nanosleep)
|
||||
AC_CHECK_LIB(intl, gettext)
|
||||
# Check if struct winsize exists
|
||||
AC_MSG_CHECKING([if struct winsize and TIOCGWINSZ exist])
|
||||
AC_LINK_IFELSE(
|
||||
[
|
||||
AC_LANG_PROGRAM(
|
||||
[
|
||||
#ifdef HAVE_SYS_TERMIOS_H
|
||||
#include <sys/termios.h>
|
||||
#endif
|
||||
|
||||
# Check for various header files
|
||||
AC_CHECK_HEADERS([getopt.h termio.h sys/resource.h term.h ncurses/term.h libintl.h])
|
||||
#ifdef HAVE_SYS_IOCTL_H
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
],
|
||||
[
|
||||
struct winsize termsize = {0};
|
||||
TIOCGWINSZ;
|
||||
]
|
||||
)
|
||||
],
|
||||
[
|
||||
AC_MSG_RESULT(yes);
|
||||
AC_DEFINE([HAVE_WINSIZE], [1], [Define to 1 if the winsize struct and TIOCGWINSZ macro exist])
|
||||
],
|
||||
[
|
||||
AC_MSG_RESULT(no)
|
||||
]
|
||||
)
|
||||
|
||||
AC_CHECK_HEADER([regex.h],
|
||||
[AC_DEFINE([HAVE_REGEX_H], [1], [Define to 1 if you have the <regex.h> header file.])],
|
||||
[AC_MSG_ERROR([Could not find the header regex.h, needed to build fish])])
|
||||
# If we have a fwprintf in libc, test that it actually works. As of
|
||||
# March 2006, it is broken under Dragonfly BSD.
|
||||
if test "$ac_cv_func_fwprintf" = yes; then
|
||||
|
||||
AC_MSG_CHECKING([if fwprintf is broken])
|
||||
AC_RUN_IFELSE(
|
||||
[
|
||||
AC_LANG_PROGRAM(
|
||||
[
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <locale.h>
|
||||
#include <wchar.h>
|
||||
],
|
||||
[
|
||||
setlocale( LC_ALL, "" );
|
||||
fwprintf( stderr, L"%ls%ls", L"", L"fish:" );
|
||||
]
|
||||
)
|
||||
],
|
||||
[
|
||||
AC_MSG_RESULT(no)
|
||||
],
|
||||
[
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE([HAVE_BROKEN_FWPRINTF], [1], [Define to 1 one if the implemented fwprintf is broken])
|
||||
]
|
||||
)
|
||||
|
||||
# Check for various functions, and insert results into config.h
|
||||
AC_CHECK_FUNCS( wcsdup wcsndup wcslen wcscasecmp wcsncasecmp gettext fwprintf )
|
||||
AC_CHECK_FUNCS( futimes wcwidth wcswidth getopt_long wcstok fputwc fgetwc )
|
||||
AC_CHECK_FUNCS( wcstol dcgettext )
|
||||
fi
|
||||
|
||||
AC_DEFINE([HAVE_TRANSLATE_H], [1],
|
||||
[Define to 1 if the wgettext function should be used for translating strings.])
|
||||
|
||||
# Check again for gettext library, and insert results into the Makefile
|
||||
AC_CHECK_FUNC(gettext, AC_SUBST(HAVE_GETTEXT,1), AC_SUBST(HAVE_GETTEXT,0) )
|
||||
|
||||
# Check for _nl_msg_cat_cntr symbol
|
||||
AC_MSG_CHECKING([for _nl_msg_cat_cntr symbol])
|
||||
AC_TRY_LINK([#if HAVE_LIBINTL_H]
|
||||
[#include <libintl.h>]
|
||||
[#endif],
|
||||
[extern int _nl_msg_cat_cntr;]
|
||||
[int tmp = _nl_msg_cat_cntr; exit(tmp);], have__nl_msg_cat_cntr=yes, have__nl_msg_cat_cntr=no)
|
||||
AC_TRY_LINK(
|
||||
[
|
||||
#if HAVE_LIBINTL_H
|
||||
#include <libintl.h>
|
||||
#endif
|
||||
],
|
||||
[
|
||||
extern int _nl_msg_cat_cntr;
|
||||
int tmp = _nl_msg_cat_cntr;
|
||||
exit(tmp);
|
||||
],
|
||||
have__nl_msg_cat_cntr=yes,
|
||||
have__nl_msg_cat_cntr=no
|
||||
)
|
||||
if test "$have__nl_msg_cat_cntr" = yes; then
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE([HAVE__NL_MSG_CAT_CNTR], [1],
|
||||
[Define to 1 if the _nl_msg_cat_cntr symbol is exported.])
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(
|
||||
[HAVE__NL_MSG_CAT_CNTR],
|
||||
[1],
|
||||
[Define to 1 if the _nl_msg_cat_cntr symbol is exported.]
|
||||
)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
# Check if we have ncurses, and use it rather than curses if possible.
|
||||
AC_SEARCH_LIBS( setupterm, [ncurses curses], [ AC_MSG_NOTICE([Found curses implementation])], [AC_MSG_ERROR([Could not find a curses implementation, needed to build fish])] )
|
||||
# Check if getopt_long exists and works
|
||||
AC_MSG_CHECKING([if getopt_long exists and works])
|
||||
AC_TRY_LINK(
|
||||
[
|
||||
#if HAVE_GETOPT_H
|
||||
#include <getopt.h>
|
||||
#endif
|
||||
],
|
||||
[
|
||||
static struct option
|
||||
long_options[] =
|
||||
{
|
||||
0, 0, 0, 0
|
||||
}
|
||||
;
|
||||
int opt = getopt_long( 0,
|
||||
0,
|
||||
0,
|
||||
long_options,
|
||||
0 );
|
||||
|
||||
],
|
||||
have_working_getopt_long=yes,
|
||||
have_working_getopt_long=no
|
||||
)
|
||||
if test "$have_working_getopt_long" = yes; then
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(
|
||||
[HAVE_WORKING_GETOPT_LONG],
|
||||
[1],
|
||||
[Define to 1 if getopt_long exists and works.]
|
||||
)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
AC_CONFIG_FILES([Makefile fish.spec doc_src/fish.1 doc_src/Doxyfile init/fish init/fish_interactive.fish init/fish_complete.fish seq])
|
||||
# Check if del_curterm is broken - in that case we redefine
|
||||
# del_curterm as a no-op, to avoid a double-free
|
||||
|
||||
AC_MSG_CHECKING([If del_curterm is broken])
|
||||
case $target_os in
|
||||
*bsd*)
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(
|
||||
[HAVE_BROKEN_DEL_CURTERM],
|
||||
[1],
|
||||
[del_curterm is broken, redefine it to a no-op to avoid a double-free bug]
|
||||
)
|
||||
;;
|
||||
*)
|
||||
AC_MSG_RESULT(no)
|
||||
;;
|
||||
esac
|
||||
|
||||
# Tell the world what we know
|
||||
AC_CONFIG_FILES([Makefile fish.spec doc_src/fish.1 doc_src/Doxyfile seq])
|
||||
AC_OUTPUT
|
||||
|
||||
echo "Now run 'make' and 'make install' to built and install fish."
|
||||
echo "Good luck!"
|
||||
if test ! x$local_found_posix_switch = xyes; then
|
||||
echo "Can't find a combination of switches to enable common extensions like detecting window size."
|
||||
echo "Some fish features may be disabled."
|
||||
fi
|
||||
|
||||
echo "fish is now configured."
|
||||
echo "Use 'make' and 'make install' to build and install fish."
|
||||
|
||||
|
||||
2
count.c
2
count.c
@@ -2,6 +2,8 @@
|
||||
The length command, used for determining the number of items in an
|
||||
environment variable array.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
@@ -2,16 +2,23 @@
|
||||
\section and and - Conditionally execute a command
|
||||
|
||||
\subsection and-synopsis Synopsis
|
||||
<tt>COMMAND1; and COMMAND2</tt>
|
||||
<tt>COMMAND1; and COMMAND2</tt>
|
||||
|
||||
\subsection and-description Description
|
||||
|
||||
The \c and builtin is used to execute a command if the current exit status (as set by the last previous command) is zero
|
||||
The \c and builtin is used to execute a command if the current exit
|
||||
status (as set by the last previous command) is zero
|
||||
|
||||
The and command does not change the current exit status.
|
||||
|
||||
\subsection and-example Example
|
||||
|
||||
The following code runs the \c make command to build a program, and if it succeeds, it runs <tt>make install</tt>, which installs the program.
|
||||
The following code runs the \c make command to build a program, if the
|
||||
build succceds, the program is installed. If either step fails,
|
||||
<tt>make clean</tt> is run, which removes the files created by the
|
||||
build process
|
||||
|
||||
<pre>
|
||||
make; and make install
|
||||
make; and make install; or make clean
|
||||
</pre>
|
||||
|
||||
|
||||
@@ -7,11 +7,14 @@
|
||||
\subsection begin-description Description
|
||||
|
||||
The \c begin builtin is used to create a new block of code. The block
|
||||
is unconditionally executed. Begin is equivalent to <tt>if
|
||||
true</tt>. The begin command is used to group any number of commands
|
||||
into a block. The reason for this is usually either to introduce a new
|
||||
variable scope or to redirect the input to output of this set of
|
||||
commands as a group.
|
||||
is unconditionally executed. <code>begin; ...; end</tt> is equivalent
|
||||
to <tt>if true; ...; end</tt>. The begin command is used to group any
|
||||
number of commands into a block. The reason for doing so is usually
|
||||
either to introduce a new variable scope, to redirect the input or
|
||||
output of a set of commands as a group, or to specify precedence when
|
||||
using the conditional commands like \c and.
|
||||
|
||||
The \c begin command does not change the current exit status.
|
||||
|
||||
\subsection begin-example Example
|
||||
|
||||
@@ -28,3 +31,17 @@ end
|
||||
# the block and was killed
|
||||
echo $PIRATE
|
||||
</pre>
|
||||
|
||||
In the following code, all output is redirected to the file out.html.
|
||||
|
||||
<pre>
|
||||
begin
|
||||
echo $xml_header
|
||||
echo $html_header
|
||||
if test -e $file
|
||||
...
|
||||
end
|
||||
...
|
||||
|
||||
end > out.html
|
||||
</pre>
|
||||
|
||||
@@ -11,6 +11,22 @@ wildcarded values. The \c case statement is used together with the \c
|
||||
switch statement in order to determine which block should be
|
||||
performed.
|
||||
|
||||
Each \c case command is given one or more parameter. The first \c case
|
||||
command with a parameter that matches the string specified in the
|
||||
switch command will be evaluated. \c case parameters may contain
|
||||
wildcards. These need to be escaped or quoted in order to avoid
|
||||
regular wildcard expansion using filenames.
|
||||
|
||||
Note that fish does not fall through on case statements. Though the
|
||||
syntax may look a bit like C switch statements, it behaves more like
|
||||
the case stamantes of traditional shells.
|
||||
|
||||
Also note that command substitutions in a case statement will be
|
||||
evaluated even if it's body is not taken. This may seem
|
||||
counterintuitive at first, but it is unavoidable, since it would be
|
||||
impossible to know if a case command will evaluate to true before all
|
||||
forms of parameter expansion have been performed for the case command.
|
||||
|
||||
\subsection case-example Example
|
||||
|
||||
If the variable \$animal contains the name of an animal, the following
|
||||
@@ -27,9 +43,11 @@ switch $animal
|
||||
echo bird
|
||||
case shark trout stingray
|
||||
echo fish
|
||||
case '*'
|
||||
echo I have no idea what a $animal is
|
||||
end
|
||||
</pre>
|
||||
</p>
|
||||
<p>
|
||||
If the above code was run with \$animal set to \c whale, the output would be \c mammal.
|
||||
If the above code was run with \c \$animal set to \c whale, the output would be \c mammal.
|
||||
</p>
|
||||
|
||||
@@ -3,10 +3,9 @@
|
||||
\subsection cd-synopsis Synopsis
|
||||
<tt>cd [DIRECTORY]</tt>
|
||||
|
||||
\subsection cd-description Description
|
||||
Changes the current directory. If <tt>DIRECTORY</tt> is supplied it
|
||||
will become the new directory. If \c DIRECTORY is a relative path, the
|
||||
CDPATH environment variable will be separated using the : as
|
||||
separator, and the resulting list will be searched for a suitable new
|
||||
current directory. If CDPATH is not set, it is assumed to be '.'. If
|
||||
\c DIRECTORY is not specified, \$HOME will be the new directory.
|
||||
\subsection cd-description Description Changes the current
|
||||
directory. If <tt>DIRECTORY</tt> is supplied it will become the new
|
||||
directory. If \c DIRECTORY is a relative path, the paths found in the
|
||||
CDPATH environment variable array will be tried as prefixes for the
|
||||
specified path. If CDPATH is not set, it is assumed to be '.'. If \c
|
||||
DIRECTORY is not specified, \$HOME will be the new directory.
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
\subsection count-description Description
|
||||
|
||||
<tt>count</tt> returns the number of arguments that were passed to
|
||||
<tt>count</tt> prints the number of arguments that were passed to
|
||||
it. This is usually used to find out how many elements an environment
|
||||
variable array contains, but this is not the only potential usage for
|
||||
the count command.
|
||||
@@ -18,6 +18,9 @@ count program, and if the user uses a help option, this help page is
|
||||
displayed, but if a help option is contained inside of a variable or
|
||||
is the result of expansion, it will be passed on to the count program.
|
||||
|
||||
Count exits with a non-zero exit status if no arguments where passed
|
||||
to it, with zero otherwise.
|
||||
|
||||
\subsection count-example Example
|
||||
|
||||
<pre>
|
||||
|
||||
1324
doc_src/doc.hdr
1324
doc_src/doc.hdr
File diff suppressed because it is too large
Load Diff
@@ -5,9 +5,12 @@
|
||||
if CONDITION; COMMAND_TRUE [else; COMMAND_FALSE] end
|
||||
while CONDITION; COMMANDS; end
|
||||
switch VALUE; [case [WILDCARD...]; [COMMANDS...];...] end
|
||||
begin; [COMMANDS...] end
|
||||
</pre>
|
||||
|
||||
\subsection end-description Description
|
||||
<tt>end</tt> ends a block of commands. For more information, read the
|
||||
documentation for the block constructs, such as \c if, \c for and \
|
||||
documentation for the block constructs, such as \c if, \c for and \c
|
||||
while.
|
||||
|
||||
The \c end command does not change the current exit status.
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
|
||||
The <tt>exit</tt> builtin causes fish to exit. If <tt>STATUS</tt> is
|
||||
supplied, it will be converted to an integer and used as the exit
|
||||
code. Otherwise the exit code will be 0.
|
||||
code. Otherwise the exit code will be that of the last command executed.
|
||||
|
||||
If exit is called while sourcing a file (using the <a
|
||||
href="#source">.</a> builtin) the rest of the file will be skipped,
|
||||
but the shell will not exit.
|
||||
but the shell itself will not exit.
|
||||
|
||||
9
doc_src/fish_pager.txt
Normal file
9
doc_src/fish_pager.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
|
||||
\section fish_pager fish_pager - Internal command used by fish
|
||||
|
||||
\subsection fish_pager-description Description
|
||||
|
||||
This command is used internally by fish to display a list of
|
||||
completions. It should not be used by other commands, as it's
|
||||
interface is liable to change in the future.
|
||||
|
||||
@@ -20,6 +20,12 @@ When no clients are connected, fishd will automatically shut down.
|
||||
|
||||
~/.fishd.HOSTNAME permanent storage location for universal variable
|
||||
data. The data is stored as a set of \c set and \c set_export commands
|
||||
such as would be parsed by fishd. If an instance of fishd is running
|
||||
such as would be parsed by fishd. If an instance of fishd is running
|
||||
(which is generally the case), manual modifications to ~/.fishd.HOSTNAME
|
||||
will be lost.
|
||||
will be lost. Do NOT edit this file manually!
|
||||
|
||||
/tmp/fishd.socket.USERNAME the socket which fishd uses to communicate
|
||||
with all clients.
|
||||
|
||||
/tmp/fishd.log.USERNAME the fishd log file
|
||||
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
\section function function - create a function
|
||||
|
||||
\subsection function-synopsis Synopsis
|
||||
<tt>function [OPTIONS] NAME; BODY; end </tt>
|
||||
<code>function [OPTIONS] NAME; BODY; end </code>
|
||||
|
||||
\subsection function-description Description
|
||||
|
||||
- \c -b or \c --key-binding specifies that the function is a key biding. Key binding functions work exactly like regular functions except that they can not be tab-completed, and may contain the '-' character.
|
||||
- <tt>-d DESCRIPTION</tt> or \c --description=DESCRIPTION is a description of what the function does, suitable as a completion description
|
||||
- <tt>-j PID</tt> or <tt> --on-job-exit PID</tt> tells fish to run this function when the job with group id PID exits
|
||||
- <tt>-p PID</tt> or <tt> --on-process-exit PID</tt> tells fish to run this function when the fish child process with process id PID exits
|
||||
- <tt>-s</tt> or <tt>--on-signal SIGSPEC</tt> tells fish to run this function when the signal SIGSPEC is delivered. SIGSPEC can be a signal number, or the signal name, such as SIGHUP (or just HUP)
|
||||
- <tt>-v</tt> or <tt>--on-variable VARIABLE_NAME</tt> tells fish to run this function when the variable VARIABLE_NAME changes value
|
||||
- <code>-d DESCRIPTION</code> or \c --description=DESCRIPTION is a description of what the function does, suitable as a completion description
|
||||
- <code>-j PID</code> or <code> --on-job-exit PID</code> tells fish to run this function when the job with group id PID exits. Instead of PID, the string 'caller' can be specified. This is only legal when in a command substitution, and will result in the handler being triggered by the exit of the job which created this command substitution.
|
||||
- <code>-p PID</code> or <code> --on-process-exit PID</code> tells fish to run this function when the fish child process with process id PID exits
|
||||
- <code>-s</code> or <code>--on-signal SIGSPEC</code> tells fish to run this function when the signal SIGSPEC is delivered. SIGSPEC can be a signal number, or the signal name, such as SIGHUP (or just HUP)
|
||||
- <code>-v</code> or <code>--on-variable VARIABLE_NAME</code> tells fish to run this function when the variable VARIABLE_NAME changes value
|
||||
|
||||
This builtin command is used to create a new function. A Function is a
|
||||
This builtin command is used to create a new function. A function is a
|
||||
list of commands that will be executed when the name of the function
|
||||
is entered. The function
|
||||
|
||||
@@ -22,10 +22,10 @@ function hi
|
||||
end
|
||||
</pre>
|
||||
|
||||
will write <tt>hello</tt> whenever the user enters \c hi.
|
||||
will write <code>hello</code> whenever the user enters \c hi.
|
||||
|
||||
If the user enters any additional arguments after the function, they
|
||||
are inserted into the environment variable <a href="index.html#variables-arrays">array</a> argv.
|
||||
are inserted into the environment <a href="index.html#variables-arrays">variable array</a> argv.
|
||||
|
||||
\subsection function-example Example
|
||||
|
||||
|
||||
@@ -1,17 +1,27 @@
|
||||
\section functions functions - print or erase functions
|
||||
|
||||
\subsection function-synopsis Synopsis
|
||||
<tt>functions [-e] FUNCTIONS...</tt>
|
||||
<code>functions [-e] FUNCTIONS...</code>
|
||||
|
||||
\subsection functions-description Description
|
||||
|
||||
This builtin command is used to print or erase functions.
|
||||
|
||||
- <tt>-e</tt> or <tt>--erase</tt> causes the specified functions to be erased.
|
||||
- <tt>-n</tt> or <tt>--names</tt> List only the names of all defined functions
|
||||
- <code>-a</code> or <code>--all</code> list all functions, even those whose name start with an underscore.
|
||||
- <code>-d DESCRIPTION</code> or <code>--description=DESCRIPTION</code> change the description of this function
|
||||
- <code>-e</code> or <code>--erase</code> causes the specified functions to be erased.
|
||||
- <code>-h</code> or <code>--help</code> display a help message and exit
|
||||
- <code>-n</code> or <code>--names</code> list only the names of all defined functions, not their definition
|
||||
- <code>-q</code> or <code>--query</code> test if the specified functions exist. Does not output anything, but the builtins exit status is the number of functions specified that were not defined.
|
||||
|
||||
If \c functions is called with no arguments, the names and definition
|
||||
of all functions are printed, otherwise, the specified function
|
||||
definitions will be printed.
|
||||
The default behavior of \c functions when called with no arguments,
|
||||
is to print the names and definitions of all defined functions. If any
|
||||
non-switch parameters are given, only the definition of the specified
|
||||
functions are printed.
|
||||
|
||||
Automatically loaded functions can not be removed using functions
|
||||
-e. Either remove the definition file or change the
|
||||
$fish_function_path variable to remove autoloaded functions.
|
||||
|
||||
The exit status of the functions builtin is the number functions
|
||||
specified in the argument list that do not exist.
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
\section jobs jobs - print currently running jobs
|
||||
|
||||
\subsection jobs-synopsis
|
||||
<tt>jobs [OPTIONS] [PID]</tt>
|
||||
<code>jobs [OPTIONS] [PID]</code>
|
||||
|
||||
\subsection jobs-description Description
|
||||
The <tt>jobs</tt> builtin causes fish to print a list of the currently
|
||||
The <code>jobs</code> builtin causes fish to print a list of the currently
|
||||
running jobs and their status.
|
||||
|
||||
jobs accepts the following switches:
|
||||
|
||||
- <tt>-c</tt> or <tt>--command</tt> print the command name for each process in jobs
|
||||
- <tt>-g</tt> or <tt>--group</tt> only print the group id of each job
|
||||
- <tt>-l</tt> or <tt>--last</tt> only the last job to be started is printed
|
||||
- <tt>-p</tt> or <tt>--process</tt> print the process id for each process in all jobs
|
||||
- <code>-c</code> or <code>--command</code> print the command name for each process in jobs
|
||||
- <code>-g</code> or <code>--group</code> only print the group id of each job
|
||||
- <code>-h</code> or <code>--help</code> display a help message and exit
|
||||
- <code>-l</code> or <code>--last</code> only the last job to be started is printed
|
||||
- <code>-p</code> or <code>--pid</code> print the process id for each process in all jobs
|
||||
|
||||
On systems that supports this feature, jobs will print the CPU usage
|
||||
of each job since the last command was executed. The CPU usage is
|
||||
|
||||
@@ -14,6 +14,13 @@
|
||||
- \c -f, \c --output-description the output will be the description of each mimetype
|
||||
- \c -a, \c --output-action the output will be the default action of each mimetype
|
||||
- \c -l, \c --launch launch the default action for the specified file(s)
|
||||
- \c -h, \c --help Display a help message and exit
|
||||
- \c -v, \c --version Display version number and exit
|
||||
- \c -h, \c --help display a help message and exit
|
||||
- \c -v, \c --version display version number and exit
|
||||
|
||||
The mimedb command is used to query the mimetype database and the
|
||||
.desktop files installed on the system in order to find information on
|
||||
a file. The information that mimedb can retrive includes the mimetype
|
||||
for a file, a description of the type and what its default action
|
||||
is. mimedb can also be used to launch the default action for this
|
||||
file.
|
||||
|
||||
|
||||
@@ -8,10 +8,16 @@
|
||||
|
||||
The \c or builtin is used to execute a command if the current exit status (as set by the last previous command) is non-zero
|
||||
|
||||
The or command does not change the current exit status.
|
||||
|
||||
\subsection or-example Example
|
||||
|
||||
The following code runs the \c make command to build a program, or if it fails, it runs <tt>make clean</tt>, which removes the files created by the build process
|
||||
The following code runs the \c make command to build a program, if the
|
||||
build succceds, the program is installed. If either step fails,
|
||||
<tt>make clean</tt> is run, which removes the files created by the
|
||||
build process
|
||||
|
||||
<pre>
|
||||
make; or make clean
|
||||
make; and make install; or make clean
|
||||
</pre>
|
||||
|
||||
|
||||
@@ -8,10 +8,13 @@
|
||||
The <tt>read</tt> builtin causes fish to read one line from standard
|
||||
input and store the result in one or more environment variables.
|
||||
|
||||
- <tt>-c CMD</tt> or <tt>--command=CMD</tt> specifies that the initial string in the interactive mode command buffer should be CMD.
|
||||
- <tt>-e</tt> or <tt>--export</tt> specifies that the variables will be exported to subshells.
|
||||
- <tt>-g</tt> or <tt>--global</tt> specifies that the variables will be made global.
|
||||
- <tt>-pPROMPT_CMD</tt> or <tt>--prompt=PROMPT_CMD</tt> specifies that the output of the shell command PROMPT_CMD should be used as the prompt for the interactive mode prompt. The default prompt command is <tt>set_color green; echo read; set_color normal; echo "> "</tt>.
|
||||
- <tt>-cCMD</tt> or <tt>--command=CMD</tt> specifies that the initial string in the interactive mode command buffer should be CMD.
|
||||
- <tt>-p PROMPT_CMD</tt> or <tt>--prompt=PROMPT_CMD</tt> specifies that the output of the shell command PROMPT_CMD should be used as the prompt for the interactive mode prompt. The default prompt command is <tt>set_color green; echo read; set_color normal; echo "> "</tt>.
|
||||
- <code>-u</code> or <code>--unexport</code> causes the specified environment not to be exported to child processes
|
||||
- <code>-U</code> or <code>--universal</code> causes the specified environment variable to be made universal. If this option is supplied, the variable will be shared between all the current users fish instances on the current computer, and will be preserved across restarts of the shell.
|
||||
- <code>-x</code> or <code>--export</code> causes the specified environment variable to be exported to child processes
|
||||
|
||||
Read starts by reading a single line of input from stdin, the line is
|
||||
then tokenized using the <tt>IFS</tt> environment variable. Each variable
|
||||
|
||||
@@ -2,18 +2,21 @@
|
||||
\section return return - Stop the innermost currently evaluated function
|
||||
|
||||
\subsection return-synopsis Synopsis
|
||||
<tt>function NAME; [COMMANDS...] break [STATUS]; [COMMANDS...] end</tt>
|
||||
<tt>function NAME; [COMMANDS...] return [STATUS]; [COMMANDS...] end</tt>
|
||||
|
||||
\subsection return-description Description The \c return builtin is
|
||||
used to halt a currently running function. It is usually added inside
|
||||
of a conditional block such as an <a href="#if">if</a> statement or a
|
||||
<a href="#switch">switch</a> statement to conditionally stop the
|
||||
executing function and return to the caller.
|
||||
\subsection return-description Description
|
||||
|
||||
- \c STATUS is the return status of the function. If unspecified, the status is set to 0.
|
||||
The \c return builtin is used to halt a currently running function. It
|
||||
is usually added inside of a conditional block such as an <a
|
||||
href="#if">if</a> statement or a <a href="#switch">switch</a>
|
||||
statement to conditionally stop the executing function and return to
|
||||
the caller, but it can also be used to specify the exit status of a
|
||||
function.
|
||||
|
||||
- \c STATUS is the return status of the function. If unspecified, the status is unchanged.
|
||||
|
||||
\subsection return-example Example
|
||||
The following code is an implementation of the false program as a fish builtin
|
||||
The following code is an implementation of the false command as a fish function
|
||||
<p>
|
||||
<pre>function false
|
||||
return 1
|
||||
|
||||
@@ -1,18 +1,23 @@
|
||||
\section set set - Handle environment variables.
|
||||
|
||||
\subsection set-synopsis Synopsis
|
||||
<code>set [OPTIONS] [VARIABLE_NAME [VALUES...]]</code>
|
||||
<pre>set [SCOPE_OPTIONS]
|
||||
set [OPTIONS] VARIABLE_NAME VALUES...
|
||||
set [OPTIONS] VARIABLE_NAME[INDICES]... VALUES...
|
||||
set (-q | --query) [SCOPE_OPTIONS] VARIABLE_NAMES...
|
||||
set (-e | --erase) [SCOPE_OPTIONS] VARIABLE_NAME
|
||||
set (-e | --erase) [SCOPE_OPTIONS] VARIABLE_NAME[INDICES]... </pre>
|
||||
|
||||
The <code>set</code> builtin causes fish to assign the variable <code>VARIABLE_NAME</code> the values <code>VALUES...</code>.
|
||||
|
||||
\subsection set-description Description
|
||||
- <code>-e</code> or <code>--erase</code> causes the specified environment variable to be erased
|
||||
- <code>-g</code> or <code>--global</code> causes the specified environment variable to be made global. If this option is not supplied, the specified variable will disappear when the current block ends
|
||||
- <code>-l</code> or <code>--local</code> forces the specified environment variable to be made local to the current block, even if the variable already exists and is non-local
|
||||
- <code>-n</code> or <code>--names</code> List only the names of all defined variables
|
||||
- <code>-l</code> or <code>--local</code> forces the specified environment variable to be given a scope that is local to the current block, even if a variable with the given name exists and is non-local
|
||||
- <code>-g</code> or <code>--global</code> causes the specified environment variable to be given a global scope. Non-global variables disappear when the block they belong to ends
|
||||
- <code>-U</code> or <code>--universal</code> causes the specified environment variable to be given a universal scope. If this option is supplied, the variable will be shared between all the current users fish instances on the current computer, and will be preserved across restarts of the shell.
|
||||
- <code>-n</code> or <code>--names</code> List only the names of all defined variables, not their value
|
||||
- <code>-q</code> or <code>--query</code> test if the specified variable names are defined. Does not output anything, but the builtins exit status is the number of variables specified that were not defined.
|
||||
- <code>-u</code> or <code>--unexport</code> causes the specified environment not to be exported to child processes
|
||||
- <code>-U</code> or <code>--universal</code> causes the specified environment variable to be made universal. If this option is supplied, the variable will be shared between all the current users fish instances on the current computer, and will be preserved across restarts of the shell.
|
||||
- <code>-x</code> or <code>--export</code> causes the specified environment variable to be exported to child processes
|
||||
|
||||
If set is called with no arguments, the names and values of all
|
||||
@@ -20,22 +25,54 @@ environment variables are printed. If some of the scope or export
|
||||
flags have been given, only the variables matching the specified scope
|
||||
are printed.
|
||||
|
||||
If the \c -e or \c --erase option is specified, the variable
|
||||
specified by the following arguments will be erased
|
||||
|
||||
If a variable is set to more than one value, the variable will be an
|
||||
array with the specified elements. If a variable is set to zero
|
||||
elements, it will become an array with zero elements.
|
||||
|
||||
If the variable name is one or more array elements, such as
|
||||
<code>PATH[1 3 7]</code>, only those array elements specified will be
|
||||
changed.
|
||||
changed. When array indices are specified to set, multiple arguments
|
||||
may be used to specify additional indexes, e.g. <code>set PATH[1]
|
||||
PATH[4] /bin /sbin</code>. If you specify a negative index when
|
||||
expanding or assigning to an array variable, the index will be
|
||||
calculated from the end of the array. For example, the index -1 means
|
||||
the last index of an array.
|
||||
|
||||
The scoping rules when creating or updating a variable are:
|
||||
|
||||
-# If a variable is explicitly set to either universal, global or local, that setting will be honored. If a variable of the same name exists in a different scope, that variable will not be changed.
|
||||
-# If a variable is not explicitly set to be either universal, global or local, but has been previously defined, the previos variable scope is used.
|
||||
-# If a variable is not explicitly set to be either universal, global or local and has never before been defined, the variable will be local to the currently executing functions. If no function is executing, the variable will be global.
|
||||
|
||||
The exporting rules when creating or updating a variable are identical
|
||||
to the scoping rules for variables:
|
||||
|
||||
-# If a variable is explicitly set to either be exported or not exported, that setting will be honored.
|
||||
-# If a variable is not explicitly set to be exported or not exported, but has been previously defined, the previous exporting rule for the variable is kept.
|
||||
-# If a variable is not explicitly set to be either global or local and has never before been defined, the variable will not be exported.
|
||||
|
||||
In query mode, the scope to be examined can be specified.
|
||||
|
||||
In erase mode, if variable indices are specified, only the specified
|
||||
slices of the array variable will be erased. When erasing an entire
|
||||
variable (i.e. no slicing), the scope of the variable to be erased can
|
||||
be specified. That way, a global variable can be erased even if a
|
||||
local variable with the same name exists. Scope can not be specified
|
||||
when erasing a slice of an array. The innermost scope is always used.
|
||||
|
||||
The set command requires all switch arguments to come before any
|
||||
non-switch arguments. For example, <code>set flags -l</code> will have
|
||||
the effect of setting the value of the variable <code>flags</code> to
|
||||
'-l', not making the variable local.
|
||||
|
||||
In assignment mode, set exits with an exit status of zero it the
|
||||
variable assignments where sucessfully performed, with a non-zero exit
|
||||
status otherwise. In query mode, the exit status is the number of
|
||||
variables that where not found. In erase mode, set exits with a zero
|
||||
exit status in case of success, with a non-zero exit status if the
|
||||
commandline was invalid, if the variable was write-protected or if the
|
||||
variable did not exist.
|
||||
|
||||
\subsection set-example Example
|
||||
|
||||
<code>set -xg</code> will print all global, exported variables.
|
||||
|
||||
@@ -10,10 +10,11 @@ Change the foreground and/or background color of the terminal.
|
||||
COLOR is one of black, red, green, brown, yellow, blue, magenta,
|
||||
purple, cyan, white and normal.
|
||||
|
||||
- \c -c, \c --print-colors Prints a list of all valid color names
|
||||
- \c -b, \c --background Set the background color
|
||||
- \c -o, \c --bold Set bold or extra bright mode
|
||||
- \c -c, \c --print-colors Prints a list of all valid color names
|
||||
- \c -h, \c --help Display help message and exit
|
||||
- \c -o, \c --bold Set bold or extra bright mode
|
||||
- \c -u, \c --underline Set underlined mode
|
||||
- \c -v, \c --version Display version and exit
|
||||
|
||||
|
||||
@@ -25,3 +26,6 @@ color set. On such terminals, <code>set_color white</code> will result
|
||||
in a grey font color, while <code>set_color --bold white</code> will
|
||||
result in a white font color.
|
||||
|
||||
Not all terminal emulators support all these features. This is not a
|
||||
bug in set_color but a missing feature in the terminal emulator.
|
||||
|
||||
|
||||
@@ -8,7 +8,19 @@
|
||||
|
||||
The \c switch statement is used to perform one of several blocks of
|
||||
commands depending on whether a specified value equals one of several
|
||||
wildcarded values.
|
||||
wildcarded values. The \c case statement is used together with the \c
|
||||
switch statement in order to determine which block should be
|
||||
performed.
|
||||
|
||||
Each \c case command is given one or more parameter. The first \c case
|
||||
command with a parameter that matches the string specified in the
|
||||
switch command will be evaluated. \c case parameters may contain
|
||||
wildcards. These need to be escaped or quoted in order to avoid
|
||||
regular wildcard expansion using filenames.
|
||||
|
||||
Note that fish does not fall through on case statements. Though the
|
||||
syntax may look a bit like C switch statements, it behaves more like
|
||||
the case stamantes of traditional shells.
|
||||
|
||||
\subsection switch-example Example
|
||||
|
||||
@@ -26,12 +38,14 @@ switch $animal
|
||||
echo bird
|
||||
case shark trout stingray
|
||||
echo fish
|
||||
case '*'
|
||||
echo I have no idea what a $animal is
|
||||
end
|
||||
</pre>
|
||||
</p>
|
||||
<p>
|
||||
|
||||
If the above code was run with \$animal set to \c whale, the output
|
||||
If the above code was run with \c \$animal set to \c whale, the output
|
||||
would be \c mammal.
|
||||
|
||||
</p>
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
\subsection trap-description Description
|
||||
|
||||
Trap is a shellscript wrapper around the fish event delivery
|
||||
framework. IT is defined for backwards compatibility reasons. For
|
||||
other uses, it is recommended to define a <a
|
||||
framework. It exists for backwards compatibility with Posix
|
||||
shells. For other uses, it is recommended to define a <a
|
||||
href='index.html#event'>event handler</a>.
|
||||
|
||||
- ARG is the command to be executed on signal delivery
|
||||
|
||||
@@ -15,6 +15,9 @@ With no options, indicate how each name would be interpreted if used as a comman
|
||||
- \c -p or \c --path either return the name of the disk file that would be executed if name were specified as a command name, or nothing if 'type -t name' would not return 'file'
|
||||
- \c -P or \c --force-path either return the name of the disk file that would be executed if name were specified as a command name, or nothing no file with the specified name could be found in the PATH
|
||||
|
||||
\c type returns a zero exit status if the specified command was found,
|
||||
otherwise the exit status is one.
|
||||
|
||||
\subsection type-example Example
|
||||
|
||||
<tt>type fg</tt> outputs the string 'fg is a shell builtin'.
|
||||
|
||||
@@ -22,7 +22,7 @@ value. Other options are interpreted as follows:
|
||||
|
||||
- <code>-a</code> or <code>--all</code> Set or get all current limits
|
||||
- <code>-c</code> or <code>--core-size</code> The maximum size of core files created
|
||||
- <code>-d</code> or <code>--data-size</code> The maximum size of a process’s data segment
|
||||
- <code>-d</code> or <code>--data-size</code> The maximum size of a process's data segment
|
||||
- <code>-f</code> or <code>--file-size</code> The maximum size of files created by the shell
|
||||
- <code>-l</code> or <code>--lock-size</code> The maximum size that may be locked into memory
|
||||
- <code>-m</code> or <code>--resident-set-size</code> The maximum resident set size
|
||||
|
||||
248
env.c
248
env.c
@@ -31,9 +31,16 @@
|
||||
#include <ncurses/term.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_LIBINTL_H
|
||||
#include <libintl.h>
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
#include "fallback.h"
|
||||
#include "util.h"
|
||||
|
||||
#include "wutil.h"
|
||||
#include "proc.h"
|
||||
#include "common.h"
|
||||
@@ -46,13 +53,13 @@
|
||||
#include "env_universal.h"
|
||||
#include "input_common.h"
|
||||
#include "event.h"
|
||||
#include "translate.h"
|
||||
|
||||
#include "complete.h"
|
||||
|
||||
/**
|
||||
Command used to start fishd
|
||||
*/
|
||||
#define FISHD_CMD L"if which fishd >/dev/null; fishd ^/tmp/fishd.%s.log; end"
|
||||
#define FISHD_CMD L"if which fishd 2>/dev/null >/dev/null; fishd ^/tmp/fishd.log.%s; end"
|
||||
|
||||
/**
|
||||
Value denoting a null string
|
||||
@@ -101,7 +108,11 @@ typedef struct env_node
|
||||
typedef struct var_entry
|
||||
{
|
||||
int export; /**< Whether the variable should be exported */
|
||||
wchar_t val[0]; /**< The value of the variable */
|
||||
#if __STDC_VERSION__ < 199901L
|
||||
wchar_t val[1]; /**< The value of the variable */
|
||||
#else
|
||||
wchar_t val[]; /**< The value of the variable */
|
||||
#endif
|
||||
}
|
||||
var_entry_t;
|
||||
|
||||
@@ -185,7 +196,7 @@ static const wchar_t *locale_variable[] =
|
||||
/**
|
||||
Free hash key and hash value
|
||||
*/
|
||||
static void clear_hash_entry( const void *key, const void *data )
|
||||
static void clear_hash_entry( void *key, void *data )
|
||||
{
|
||||
var_entry_t *entry = (var_entry_t *)data;
|
||||
if( entry->export )
|
||||
@@ -298,21 +309,19 @@ static void handle_locale()
|
||||
if( wcscmp( wsetlocale( LC_MESSAGES, (void *)0 ), old ) != 0 )
|
||||
{
|
||||
|
||||
/* Try to make change known to gettext. */
|
||||
#ifdef HAVE__NL_MSG_CAT_CNTR
|
||||
{
|
||||
extern int _nl_msg_cat_cntr;
|
||||
++_nl_msg_cat_cntr;
|
||||
}
|
||||
#elif HAVE_DCGETTEXT
|
||||
dcgettext("fish","Changing language to English",LC_MESSAGES);
|
||||
#endif
|
||||
|
||||
/*
|
||||
Try to make change known to gettext. Both changing
|
||||
_nl_msg_cat_cntr and calling dcgettext might potentially
|
||||
tell some gettext implementation that the translation
|
||||
strings should be reloaded. We do both and hope for the
|
||||
best.
|
||||
*/
|
||||
extern int _nl_msg_cat_cntr;
|
||||
++_nl_msg_cat_cntr;
|
||||
dcgettext( "fish", "Changing language to English", LC_MESSAGES );
|
||||
|
||||
if( is_interactive )
|
||||
{
|
||||
complete_destroy();
|
||||
complete_init();
|
||||
|
||||
debug( 0, _(L"Changing language to English") );
|
||||
}
|
||||
}
|
||||
@@ -393,7 +402,7 @@ static void setup_path()
|
||||
al_init( &l );
|
||||
|
||||
if( path )
|
||||
expand_variable_array( path, &l );
|
||||
tokenize_variable_array( path, &l );
|
||||
|
||||
for( j=0; path_el[j]; j++ )
|
||||
{
|
||||
@@ -432,14 +441,14 @@ static void setup_path()
|
||||
|
||||
sb_destroy( &b );
|
||||
|
||||
al_foreach( &l, (void (*)(const void *))&free );
|
||||
al_foreach( &l, &free );
|
||||
path = env_get( L"PATH" );
|
||||
al_truncate( &l, 0 );
|
||||
expand_variable_array( path, &l );
|
||||
tokenize_variable_array( path, &l );
|
||||
}
|
||||
}
|
||||
|
||||
al_foreach( &l, (void (*)(const void *))&free );
|
||||
al_foreach( &l, &free );
|
||||
al_destroy( &l );
|
||||
}
|
||||
|
||||
@@ -448,6 +457,8 @@ void env_init()
|
||||
char **p;
|
||||
struct passwd *pw;
|
||||
wchar_t *uname;
|
||||
wchar_t *version;
|
||||
|
||||
|
||||
sb_init( &dyn_var );
|
||||
b_init( &export_buffer );
|
||||
@@ -459,6 +470,7 @@ void env_init()
|
||||
|
||||
hash_put( &env_read_only, L"status", L"" );
|
||||
hash_put( &env_read_only, L"history", L"" );
|
||||
hash_put( &env_read_only, L"version", L"" );
|
||||
hash_put( &env_read_only, L"_", L"" );
|
||||
hash_put( &env_read_only, L"LINES", L"" );
|
||||
hash_put( &env_read_only, L"COLUMNS", L"" );
|
||||
@@ -546,6 +558,13 @@ void env_init()
|
||||
env_set( L"USER", uname, ENV_GLOBAL | ENV_EXPORT );
|
||||
free( uname );
|
||||
}
|
||||
|
||||
/*
|
||||
Set up the version variable
|
||||
*/
|
||||
version = str2wcs( PACKAGE_VERSION );
|
||||
env_set( L"version", version, ENV_GLOBAL );
|
||||
free( version );
|
||||
|
||||
env_universal_init( env_get( L"FISHD_SOCKET_DIR"),
|
||||
env_get( L"USER" ),
|
||||
@@ -605,9 +624,9 @@ static env_node_t *env_get_node( const wchar_t *key )
|
||||
return 0;
|
||||
}
|
||||
|
||||
void env_set( const wchar_t *key,
|
||||
const wchar_t *val,
|
||||
int var_mode )
|
||||
int env_set( const wchar_t *key,
|
||||
const wchar_t *val,
|
||||
int var_mode )
|
||||
{
|
||||
int free_val = 0;
|
||||
var_entry_t *entry;
|
||||
@@ -620,10 +639,12 @@ void env_set( const wchar_t *key,
|
||||
event_t ev;
|
||||
int is_universal = 0;
|
||||
|
||||
CHECK( key, ENV_INVALID );
|
||||
|
||||
if( (var_mode & ENV_USER ) &&
|
||||
hash_get( &env_read_only, key ) )
|
||||
{
|
||||
return;
|
||||
return ENV_PERM;
|
||||
}
|
||||
|
||||
if( wcscmp( key, L"umask" ) == 0)
|
||||
@@ -647,7 +668,7 @@ void env_set( const wchar_t *key,
|
||||
/*
|
||||
Do not actually create a umask variable, on env_get, it will be calculated dynamically
|
||||
*/
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -746,7 +767,7 @@ void env_set( const wchar_t *key,
|
||||
node = top;
|
||||
while( node->next && !node->new_scope )
|
||||
node = node->next;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -754,7 +775,7 @@ void env_set( const wchar_t *key,
|
||||
if( !done )
|
||||
{
|
||||
void *k, *v;
|
||||
hash_remove( &node->env, key, (const void **)&k, (const void **)&v );
|
||||
hash_remove( &node->env, key, &k, &v );
|
||||
free( k );
|
||||
free( v );
|
||||
|
||||
@@ -794,6 +815,7 @@ void env_set( const wchar_t *key,
|
||||
|
||||
al_init( &ev.arguments );
|
||||
al_push( &ev.arguments, L"VARIABLE" );
|
||||
al_push( &ev.arguments, L"SET" );
|
||||
al_push( &ev.arguments, key );
|
||||
|
||||
// debug( 1, L"env_set: fire events on variable %ls", key );
|
||||
@@ -806,25 +828,35 @@ void env_set( const wchar_t *key,
|
||||
{
|
||||
handle_locale();
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Attempt to remove/free the specified key/value pair from the
|
||||
specified hash table.
|
||||
|
||||
\return zero if the variable was not found, non-zero otherwise
|
||||
*/
|
||||
static int try_remove( env_node_t *n,
|
||||
const wchar_t *key )
|
||||
const wchar_t *key,
|
||||
int var_mode )
|
||||
{
|
||||
void *old_key_void, *old_val_void;
|
||||
wchar_t *old_key, *old_val;
|
||||
|
||||
if( n == 0 )
|
||||
return 0;
|
||||
|
||||
hash_remove( &n->env,
|
||||
key,
|
||||
(const void **)&old_key,
|
||||
(const void **)&old_val );
|
||||
&old_key_void,
|
||||
&old_val_void );
|
||||
|
||||
old_key = (wchar_t *)old_key_void;
|
||||
old_val = (wchar_t *)old_val_void;
|
||||
|
||||
if( old_key != 0 )
|
||||
{
|
||||
var_entry_t * v = (var_entry_t *)old_val;
|
||||
@@ -838,29 +870,72 @@ static int try_remove( env_node_t *n,
|
||||
return 1;
|
||||
}
|
||||
|
||||
if( var_mode & ENV_LOCAL )
|
||||
return 0;
|
||||
|
||||
if( n->new_scope )
|
||||
return try_remove( global_env, key );
|
||||
return try_remove( global_env, key, var_mode );
|
||||
else
|
||||
return try_remove( n->next, key );
|
||||
return try_remove( n->next, key, var_mode );
|
||||
}
|
||||
|
||||
|
||||
void env_remove( const wchar_t *key, int var_mode )
|
||||
int env_remove( const wchar_t *key, int var_mode )
|
||||
{
|
||||
env_node_t *first_node;
|
||||
int erased = 0;
|
||||
|
||||
CHECK( key, 1 );
|
||||
|
||||
if( (var_mode & ENV_USER ) &&
|
||||
hash_get( &env_read_only, key ) )
|
||||
{
|
||||
return;
|
||||
return 2;
|
||||
}
|
||||
|
||||
if( !try_remove( top, key ) )
|
||||
first_node = top;
|
||||
|
||||
if( ! (var_mode & ENV_UNIVERSAL ) )
|
||||
{
|
||||
env_universal_remove( key );
|
||||
|
||||
if( var_mode & ENV_GLOBAL )
|
||||
{
|
||||
first_node = global_env;
|
||||
}
|
||||
|
||||
if( try_remove( first_node, key, var_mode ) )
|
||||
{
|
||||
event_t ev;
|
||||
|
||||
ev.type=EVENT_VARIABLE;
|
||||
ev.param1.variable=key;
|
||||
ev.function_name=0;
|
||||
|
||||
al_init( &ev.arguments );
|
||||
al_push( &ev.arguments, L"VARIABLE" );
|
||||
al_push( &ev.arguments, L"ERASE" );
|
||||
al_push( &ev.arguments, key );
|
||||
|
||||
event_fire( &ev );
|
||||
|
||||
al_destroy( &ev.arguments );
|
||||
erased = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if( !erased &&
|
||||
!(var_mode & ENV_GLOBAL) &&
|
||||
!(var_mode & ENV_LOCAL) )
|
||||
{
|
||||
erased = !env_universal_remove( key );
|
||||
}
|
||||
|
||||
if( is_locale( key ) )
|
||||
{
|
||||
handle_locale();
|
||||
|
||||
}
|
||||
|
||||
return !erased;
|
||||
}
|
||||
|
||||
|
||||
@@ -870,6 +945,8 @@ wchar_t *env_get( const wchar_t *key )
|
||||
env_node_t *env = top;
|
||||
wchar_t *item;
|
||||
|
||||
CHECK( key, 0 );
|
||||
|
||||
if( wcscmp( key, L"history" ) == 0 )
|
||||
{
|
||||
wchar_t *current;
|
||||
@@ -889,7 +966,10 @@ wchar_t *env_get( const wchar_t *key )
|
||||
wchar_t *next = history_get( i-add_current );
|
||||
if( !next )
|
||||
{
|
||||
debug( 1, _( L"No history item at index %d\n" ), i );
|
||||
/*
|
||||
This is not an error - it simply means the user has
|
||||
a short history
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -959,40 +1039,62 @@ wchar_t *env_get( const wchar_t *key )
|
||||
return item;
|
||||
}
|
||||
|
||||
int env_exist( const wchar_t *key )
|
||||
int env_exist( const wchar_t *key, int mode )
|
||||
{
|
||||
var_entry_t *res;
|
||||
env_node_t *env = top;
|
||||
wchar_t *item;
|
||||
|
||||
if( hash_get( &env_read_only, key ) || hash_get( &env_electric, key ) )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
while( env != 0 )
|
||||
env_node_t *env;
|
||||
wchar_t *item=0;
|
||||
|
||||
CHECK( key, 0 );
|
||||
|
||||
/*
|
||||
Read only variables all exist, and they are all global. A local
|
||||
version can not exist.
|
||||
*/
|
||||
if( ! (mode & ENV_LOCAL) && ! (mode & ENV_UNIVERSAL) )
|
||||
{
|
||||
res = (var_entry_t *) hash_get( &env->env,
|
||||
key );
|
||||
if( res != 0 )
|
||||
if( hash_get( &env_read_only, key ) || hash_get( &env_electric, key ) )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if( env->new_scope )
|
||||
env = global_env;
|
||||
else
|
||||
env = env->next;
|
||||
}
|
||||
if( !proc_had_barrier)
|
||||
}
|
||||
|
||||
if( ! (mode & ENV_UNIVERSAL) )
|
||||
{
|
||||
proc_had_barrier=1;
|
||||
env_universal_barrier();
|
||||
env = (mode & ENV_GLOBAL)?global_env:top;
|
||||
|
||||
while( env != 0 )
|
||||
{
|
||||
res = (var_entry_t *) hash_get( &env->env,
|
||||
key );
|
||||
if( res != 0 )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if( mode & ENV_LOCAL )
|
||||
break;
|
||||
|
||||
if( env->new_scope )
|
||||
env = global_env;
|
||||
else
|
||||
env = env->next;
|
||||
}
|
||||
}
|
||||
|
||||
item = env_universal_get( key );
|
||||
if( ! (mode & ENV_LOCAL) && ! (mode & ENV_GLOBAL) )
|
||||
{
|
||||
if( !proc_had_barrier)
|
||||
{
|
||||
proc_had_barrier=1;
|
||||
env_universal_barrier();
|
||||
}
|
||||
|
||||
item = env_universal_get( key );
|
||||
|
||||
}
|
||||
return item != 0;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1074,8 +1176,8 @@ void env_pop()
|
||||
Function used with hash_foreach to insert keys of one table into
|
||||
another
|
||||
*/
|
||||
static void add_key_to_hash( const void *key,
|
||||
const void *data,
|
||||
static void add_key_to_hash( void *key,
|
||||
void *data,
|
||||
void *aux )
|
||||
{
|
||||
var_entry_t *e = (var_entry_t *)data;
|
||||
@@ -1089,7 +1191,7 @@ static void add_key_to_hash( const void *key,
|
||||
/**
|
||||
Add key to hashtable
|
||||
*/
|
||||
static void add_to_hash( const void *k, void *aux )
|
||||
static void add_to_hash( void *k, void *aux )
|
||||
{
|
||||
hash_put( (hash_table_t *)aux,
|
||||
k,
|
||||
@@ -1099,8 +1201,8 @@ static void add_to_hash( const void *k, void *aux )
|
||||
/**
|
||||
Add key to list
|
||||
*/
|
||||
static void add_key_to_list( const void * key,
|
||||
const void * val,
|
||||
static void add_key_to_list( void * key,
|
||||
void * val,
|
||||
void *aux )
|
||||
{
|
||||
al_push( (array_list_t *)aux, key );
|
||||
@@ -1116,6 +1218,8 @@ void env_get_names( array_list_t *l, int flags )
|
||||
hash_table_t names;
|
||||
env_node_t *n=top;
|
||||
|
||||
CHECK( l, );
|
||||
|
||||
get_names_show_exported =
|
||||
flags & ENV_EXPORT|| (!(flags & ENV_UNEXPORT));
|
||||
get_names_show_unexported =
|
||||
@@ -1184,7 +1288,7 @@ void env_get_names( array_list_t *l, int flags )
|
||||
/**
|
||||
Function used by env_export_arr to iterate over hashtable of variables
|
||||
*/
|
||||
static void export_func1( const void *k, const void *v, void *aux )
|
||||
static void export_func1( void *k, void *v, void *aux )
|
||||
{
|
||||
var_entry_t *val_entry = (var_entry_t *)v;
|
||||
if( val_entry->export )
|
||||
@@ -1200,7 +1304,7 @@ static void export_func1( const void *k, const void *v, void *aux )
|
||||
/**
|
||||
Function used by env_export_arr to iterate over hashtable of variables
|
||||
*/
|
||||
static void export_func2( const void *k, const void *v, void *aux )
|
||||
static void export_func2( void *k, void *v, void *aux )
|
||||
{
|
||||
wchar_t *key = (wchar_t *)k;
|
||||
wchar_t *val = (wchar_t *)v;
|
||||
@@ -1214,7 +1318,7 @@ static void export_func2( const void *k, const void *v, void *aux )
|
||||
|
||||
if( !ks || !vs )
|
||||
{
|
||||
die_mem();
|
||||
DIE_MEM();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1237,7 +1341,7 @@ static void export_func2( const void *k, const void *v, void *aux )
|
||||
free( vs );
|
||||
}
|
||||
|
||||
char **env_export_arr( int recalc)
|
||||
char **env_export_arr( int recalc )
|
||||
{
|
||||
if( recalc && !proc_had_barrier)
|
||||
{
|
||||
|
||||
30
env.h
30
env.h
@@ -41,6 +41,16 @@
|
||||
*/
|
||||
#define ENV_UNIVERSAL 32
|
||||
|
||||
/**
|
||||
Error code for trying to alter read-only variable
|
||||
*/
|
||||
enum{
|
||||
ENV_PERM = 1,
|
||||
ENV_INVALID
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
/**
|
||||
Initialize environment variable data
|
||||
*/
|
||||
@@ -61,9 +71,15 @@ void env_destroy();
|
||||
\param val The value
|
||||
\param mode The type of the variable. Can be any combination of ENV_GLOBAL, ENV_LOCAL, ENV_EXPORT and ENV_USER. If mode is zero, the current variable space is searched and the current mode is used. If no current variable with the same name is found, ENV_LOCAL is assumed.
|
||||
|
||||
\returns 0 on suicess or an error code on failiure.
|
||||
|
||||
The current error codes are:
|
||||
|
||||
* ENV_PERM, can only be returned when setting as a user, e.g. ENV_USER is set. This means that the user tried to change a read-only variable.
|
||||
* ENV_INVALID, the variable name or mode was invalid
|
||||
*/
|
||||
|
||||
void env_set( const wchar_t *key,
|
||||
int env_set( const wchar_t *key,
|
||||
const wchar_t *val,
|
||||
int mode );
|
||||
|
||||
@@ -80,16 +96,21 @@ wchar_t *env_get( const wchar_t *key );
|
||||
/**
|
||||
Returns 1 if the specified key exists. This can't be reliable done
|
||||
using env_get, since env_get returns null for 0-element arrays
|
||||
|
||||
\param key The name of the variable to remove
|
||||
\param mode the scope to search in. All scopes are searched if unset
|
||||
*/
|
||||
int env_exist( const wchar_t *key );
|
||||
int env_exist( const wchar_t *key, int mode );
|
||||
|
||||
/**
|
||||
Remove environemnt variable
|
||||
|
||||
\param key The name of the variable to remove
|
||||
\param mode should be ENV_USER if this is a remove request from the user, 0 otherwise. If this is a user request, read-only variables can not be removed.
|
||||
\param mode should be ENV_USER if this is a remove request from the user, 0 otherwise. If this is a user request, read-only variables can not be removed. The mode may also specify the scope of the variable that should be erased.
|
||||
|
||||
\return zero if the variable existed, and non-zero if the variable did not exist
|
||||
*/
|
||||
void env_remove( const wchar_t *key, int mode );
|
||||
int env_remove( const wchar_t *key, int mode );
|
||||
|
||||
/**
|
||||
Push the variable stack. Used for implementing local variables for functions and for-loops.
|
||||
@@ -108,7 +129,6 @@ char **env_export_arr( int recalc );
|
||||
|
||||
/**
|
||||
Insert all variable names into l. These are not copies of the strings and should not be freed after use.
|
||||
|
||||
*/
|
||||
void env_get_names( array_list_t *l, int flags );
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
#include "config.h"
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <wchar.h>
|
||||
#include <strings.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
@@ -24,9 +25,15 @@
|
||||
#include <ncurses/term.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_SELECT_H
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
#include "fallback.h"
|
||||
#include "util.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "wutil.h"
|
||||
#include "env_universal_common.h"
|
||||
@@ -179,7 +186,12 @@ static void check_connection()
|
||||
if( env_universal_server.killme )
|
||||
{
|
||||
debug( 3, L"Lost connection to universal variable server." );
|
||||
close( env_universal_server.fd );
|
||||
|
||||
if( close( env_universal_server.fd ) )
|
||||
{
|
||||
wperror( L"close" );
|
||||
}
|
||||
|
||||
env_universal_server.fd = -1;
|
||||
env_universal_server.killme=0;
|
||||
sb_clear( &env_universal_server.input );
|
||||
@@ -214,7 +226,7 @@ void env_universal_init( wchar_t * p,
|
||||
void (*sf)(),
|
||||
void (*cb)( int type, const wchar_t *name, const wchar_t *val ))
|
||||
{
|
||||
debug( 2, L"env_universal_init()" );
|
||||
debug( 3, L"env_universal_init()" );
|
||||
path=p;
|
||||
user=u;
|
||||
start_fishd=sf;
|
||||
@@ -233,7 +245,7 @@ void env_universal_init( wchar_t * p,
|
||||
{
|
||||
env_universal_barrier();
|
||||
}
|
||||
debug( 2, L"end env_universal_init()" );
|
||||
debug( 3, L"end env_universal_init()" );
|
||||
}
|
||||
|
||||
void env_universal_destroy()
|
||||
@@ -248,8 +260,13 @@ void env_universal_destroy()
|
||||
wperror( L"fcntl" );
|
||||
}
|
||||
try_send_all( &env_universal_server );
|
||||
|
||||
if( close( env_universal_server.fd ) )
|
||||
{
|
||||
wperror( L"close" );
|
||||
}
|
||||
}
|
||||
close( env_universal_server.fd );
|
||||
|
||||
env_universal_server.fd =-1;
|
||||
q_destroy( &env_universal_server.unsent );
|
||||
sb_destroy( &env_universal_server.input );
|
||||
@@ -292,16 +309,20 @@ wchar_t *env_universal_get( const wchar_t *name )
|
||||
{
|
||||
if( !init)
|
||||
return 0;
|
||||
|
||||
if( !name )
|
||||
return 0;
|
||||
|
||||
CHECK( name, 0 );
|
||||
|
||||
debug( 3, L"env_universal_get( \"%ls\" )", name );
|
||||
return env_universal_common_get( name );
|
||||
}
|
||||
|
||||
int env_universal_get_export( const wchar_t *name )
|
||||
{
|
||||
if( !init)
|
||||
return 0;
|
||||
|
||||
CHECK( name, 0 );
|
||||
|
||||
debug( 3, L"env_universal_get_export()" );
|
||||
return env_universal_common_get_export( name );
|
||||
}
|
||||
@@ -374,7 +395,9 @@ void env_universal_set( const wchar_t *name, const wchar_t *value, int export )
|
||||
|
||||
if( !init )
|
||||
return;
|
||||
|
||||
|
||||
CHECK( name, );
|
||||
|
||||
debug( 3, L"env_universal_set( \"%ls\", \"%ls\" )", name, value );
|
||||
|
||||
msg = create_message( export?SET_EXPORT:SET,
|
||||
@@ -392,11 +415,17 @@ void env_universal_set( const wchar_t *name, const wchar_t *value, int export )
|
||||
env_universal_barrier();
|
||||
}
|
||||
|
||||
void env_universal_remove( const wchar_t *name )
|
||||
int env_universal_remove( const wchar_t *name )
|
||||
{
|
||||
int res;
|
||||
|
||||
message_t *msg;
|
||||
if( !init )
|
||||
return;
|
||||
return 1;
|
||||
|
||||
CHECK( name, 1 );
|
||||
|
||||
res = !env_universal_common_get( name );
|
||||
|
||||
debug( 3,
|
||||
L"env_universal_remove( \"%ls\" )",
|
||||
@@ -406,12 +435,17 @@ void env_universal_remove( const wchar_t *name )
|
||||
msg->count=1;
|
||||
q_put( &env_universal_server.unsent, msg );
|
||||
env_universal_barrier();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void env_universal_get_names( array_list_t *l,
|
||||
int show_exported,
|
||||
int show_unexported )
|
||||
{
|
||||
if( !init )
|
||||
return;
|
||||
|
||||
env_universal_common_get_names( l,
|
||||
show_exported,
|
||||
show_unexported );
|
||||
|
||||
@@ -40,8 +40,10 @@ int env_universal_get_export( const wchar_t *name );
|
||||
void env_universal_set( const wchar_t *name, const wchar_t *val, int export );
|
||||
/**
|
||||
Erase a universal variable
|
||||
|
||||
\return zero if the variable existed, and non-zero if the variable did not exist
|
||||
*/
|
||||
void env_universal_remove( const wchar_t *name );
|
||||
int env_universal_remove( const wchar_t *name );
|
||||
|
||||
/**
|
||||
Read all available messages from the server.
|
||||
|
||||
@@ -7,10 +7,11 @@
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <wchar.h>
|
||||
#include <strings.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
@@ -27,7 +28,13 @@
|
||||
#include <signal.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifdef HAVE_SYS_SELECT_H
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
|
||||
#include "fallback.h"
|
||||
#include "util.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "wutil.h"
|
||||
#include "env_universal_common.h"
|
||||
@@ -105,7 +112,7 @@ static int get_names_show_unexported;
|
||||
|
||||
void env_universal_common_init( void (*cb)(int type, const wchar_t *key, const wchar_t *val ) )
|
||||
{
|
||||
debug( 2, L"Init env_universal_common" );
|
||||
debug( 3, L"Init env_universal_common" );
|
||||
callback = cb;
|
||||
hash_init( &env_universal_var, &hash_wcs_func, &hash_wcs_cmp );
|
||||
}
|
||||
@@ -113,8 +120,8 @@ void env_universal_common_init( void (*cb)(int type, const wchar_t *key, const w
|
||||
/**
|
||||
Free both key and data
|
||||
*/
|
||||
static void erase( const void *key,
|
||||
const void *data )
|
||||
static void erase( void *key,
|
||||
void *data )
|
||||
{
|
||||
free( (void *)key );
|
||||
free( (void *)data );
|
||||
@@ -202,8 +209,8 @@ static void remove_entry( wchar_t *name )
|
||||
void *k, *v;
|
||||
hash_remove( &env_universal_var,
|
||||
name,
|
||||
(const void **)&k,
|
||||
(const void **)&v );
|
||||
&k,
|
||||
&v );
|
||||
free( k );
|
||||
free( v );
|
||||
}
|
||||
@@ -229,7 +236,7 @@ static int match( const wchar_t *msg, const wchar_t *cmd )
|
||||
static void parse_message( wchar_t *msg,
|
||||
connection_t *src )
|
||||
{
|
||||
debug( 2, L"parse_message( %ls );", msg );
|
||||
debug( 3, L"parse_message( %ls );", msg );
|
||||
|
||||
if( msg[0] == L'#' )
|
||||
return;
|
||||
@@ -258,7 +265,7 @@ static void parse_message( wchar_t *msg,
|
||||
var_uni_entry_t *entry =
|
||||
malloc( sizeof(var_uni_entry_t) + sizeof(wchar_t)*(wcslen(val)+1) );
|
||||
if( !entry )
|
||||
die_mem();
|
||||
DIE_MEM();
|
||||
entry->export=export;
|
||||
|
||||
wcscpy( entry->val, val );
|
||||
@@ -430,7 +437,7 @@ message_t *create_message( int type,
|
||||
msg = malloc( sizeof( message_t ) + sz );
|
||||
|
||||
if( !msg )
|
||||
die_mem();
|
||||
DIE_MEM();
|
||||
|
||||
strcpy( msg->body, (type==SET?SET_MBS:SET_EXPORT_MBS) );
|
||||
strcat( msg->body, " " );
|
||||
@@ -450,7 +457,7 @@ message_t *create_message( int type,
|
||||
msg = malloc( sizeof( message_t ) + sz );
|
||||
|
||||
if( !msg )
|
||||
die_mem();
|
||||
DIE_MEM();
|
||||
|
||||
strcpy( msg->body, ERASE_MBS " " );
|
||||
strcat( msg->body, key );
|
||||
@@ -463,7 +470,7 @@ message_t *create_message( int type,
|
||||
msg = malloc( sizeof( message_t ) +
|
||||
strlen( BARRIER_MBS ) +2);
|
||||
if( !msg )
|
||||
die_mem();
|
||||
DIE_MEM();
|
||||
strcpy( msg->body, BARRIER_MBS "\n" );
|
||||
break;
|
||||
}
|
||||
@@ -473,7 +480,7 @@ message_t *create_message( int type,
|
||||
msg = malloc( sizeof( message_t ) +
|
||||
strlen( BARRIER_REPLY_MBS ) +2);
|
||||
if( !msg )
|
||||
die_mem();
|
||||
DIE_MEM();
|
||||
strcpy( msg->body, BARRIER_REPLY_MBS "\n" );
|
||||
break;
|
||||
}
|
||||
@@ -495,8 +502,8 @@ message_t *create_message( int type,
|
||||
Function used with hash_foreach to insert keys of one table into
|
||||
another
|
||||
*/
|
||||
static void add_key_to_hash( const void *key,
|
||||
const void *data,
|
||||
static void add_key_to_hash( void *key,
|
||||
void *data,
|
||||
void *aux )
|
||||
{
|
||||
var_uni_entry_t *e = (var_uni_entry_t *)data;
|
||||
@@ -543,8 +550,8 @@ int env_universal_common_get_export( const wchar_t *name )
|
||||
\param v the variable value
|
||||
\param q the queue to add the message to
|
||||
*/
|
||||
static void enqueue( const void *k,
|
||||
const void *v,
|
||||
static void enqueue( void *k,
|
||||
void *v,
|
||||
void *q)
|
||||
{
|
||||
const wchar_t *key = (const wchar_t *)k;
|
||||
|
||||
71
etc/fish.in
Normal file
71
etc/fish.in
Normal file
@@ -0,0 +1,71 @@
|
||||
#
|
||||
# Init file for fish
|
||||
#
|
||||
# @configure_input@
|
||||
|
||||
#
|
||||
# Set default search paths for completions and shellscript functions
|
||||
#
|
||||
|
||||
set -g fish_function_path ~/.fish.d/functions @sysconfdir@/fish.d/functions @datadir@/fish/functions
|
||||
set -g fish_complete_path ~/.fish.d/completions @sysconfdir@/fish.d/completions @datadir@/fish/completions
|
||||
|
||||
#
|
||||
# Set default field separators
|
||||
#
|
||||
|
||||
set -g IFS \ \t\n
|
||||
|
||||
#
|
||||
# Some things should only be done for login terminals
|
||||
#
|
||||
|
||||
if status --is-login
|
||||
|
||||
#
|
||||
# Set some value for LANG if nothing was set before, and this is a
|
||||
# login shell.
|
||||
#
|
||||
|
||||
if not set -q LANG >/dev/null
|
||||
set -gx LANG en_US.UTF-8
|
||||
end
|
||||
|
||||
# Check for i18n information in
|
||||
# /etc/sysconfig/i18n
|
||||
|
||||
if test -f /etc/sysconfig/i18n
|
||||
eval (cat /etc/sysconfig/i18n |sed -ne 's/^\([a-zA-Z]*\)=\(.*\)$/set -gx \1 \2;/p')
|
||||
end
|
||||
|
||||
#
|
||||
# Put linux consoles in unicode mode.
|
||||
#
|
||||
|
||||
if expr "$LANG" : ".*\.[Uu][Tt][Ff].*" >/dev/null
|
||||
if test "$TERM" = linux
|
||||
if which unicode_start >/dev/null
|
||||
unicode_start
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# There are variables that contain colons that are not arrays. This
|
||||
# reverts them back to regular strings.
|
||||
#
|
||||
|
||||
for i in DISPLAY
|
||||
if set -q $i
|
||||
set -- $i (printf ":%s" $$i|cut -c 2-)
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Load additional initialization files
|
||||
#
|
||||
|
||||
for i in fish.d/*.fish
|
||||
. $i
|
||||
end
|
||||
110
etc/fish_interactive.fish.in
Normal file
110
etc/fish_interactive.fish.in
Normal file
@@ -0,0 +1,110 @@
|
||||
#
|
||||
# Initializations that should only be performed when in interactive mode
|
||||
#
|
||||
# @configure_input@
|
||||
|
||||
if not status --is-interactive
|
||||
exit
|
||||
end
|
||||
|
||||
#
|
||||
# Print a greeting
|
||||
#
|
||||
|
||||
printf (_ 'Welcome to fish, the friendly interactive shell\n')
|
||||
printf (_ 'Type %shelp%s for instructions on how to use fish\n') (set_color green) (set_color normal)
|
||||
|
||||
#
|
||||
# Set exit message
|
||||
#
|
||||
|
||||
function fish_on_exit -d (_ "Commands to execute when fish exits") --on-process %self
|
||||
printf (_ "Good bye\n")
|
||||
end
|
||||
|
||||
#
|
||||
# Set INPUTRC to something nice
|
||||
#
|
||||
# We override INPUTRC if already set, since it may be set by a shell
|
||||
# other than fish, which may use a different file. The new value should
|
||||
# be exported, since the fish inputrc file plays nice with other files
|
||||
# by including them when found.
|
||||
# Give priority to the default file installed with fish in
|
||||
# @sysconfdir@/fish_inputrc.
|
||||
#
|
||||
|
||||
for i in ~/.fish_inputrc @sysconfdir@/fish_inputrc ~/.inputrc /etc/inputrc
|
||||
if test -f $i
|
||||
set -xg INPUTRC $i
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Set various defaults using these throwaway functions
|
||||
#
|
||||
|
||||
function set_default -d "Set an universal variable, unless it has already been set"
|
||||
if not set -q $argv[1]
|
||||
set -U -- $argv
|
||||
end
|
||||
if not set -q $argv[1]
|
||||
set -g -- $argv
|
||||
end
|
||||
end
|
||||
|
||||
function set_exported_default -d "Set an exported universal variable, unless it has already been set"
|
||||
if not set -q $argv[1]
|
||||
set -Ux -- $argv
|
||||
end
|
||||
if not set -q $argv[1]
|
||||
set -gx -- $argv
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# Regular syntax highlighting colors
|
||||
set_default fish_color_normal normal
|
||||
set_default fish_color_command green
|
||||
set_default fish_color_redirection normal
|
||||
set_default fish_color_comment red
|
||||
set_default fish_color_error red --bold
|
||||
set_default fish_color_escape cyan
|
||||
set_default fish_color_operator cyan
|
||||
set_default fish_color_quote brown
|
||||
set_default fish_color_valid_path --underline
|
||||
|
||||
set_default fish_color_cwd green
|
||||
|
||||
# Background color for matching quotes and parenthesis
|
||||
set_default fish_color_match cyan
|
||||
|
||||
# Background color for search matches
|
||||
set_default fish_color_search_match purple
|
||||
|
||||
# Pager colors
|
||||
set_default fish_pager_color_prefix cyan
|
||||
set_default fish_pager_color_completion normal
|
||||
set_default fish_pager_color_description normal
|
||||
set_default fish_pager_color_progress cyan
|
||||
|
||||
#
|
||||
# Directory history colors
|
||||
#
|
||||
|
||||
set_default fish_color_history_current cyan
|
||||
|
||||
|
||||
#
|
||||
# Setup the CDPATH variable
|
||||
#
|
||||
|
||||
set_default CDPATH . ~
|
||||
|
||||
#
|
||||
# Remove temporary functions for setting default variable values
|
||||
#
|
||||
|
||||
functions -e set_exported_default
|
||||
functions -e set_default
|
||||
88
event.c
88
event.c
@@ -3,6 +3,8 @@
|
||||
Functions for handling event triggers
|
||||
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <wchar.h>
|
||||
@@ -11,8 +13,9 @@
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "fallback.h"
|
||||
#include "util.h"
|
||||
|
||||
#include "wutil.h"
|
||||
#include "function.h"
|
||||
#include "proc.h"
|
||||
@@ -20,7 +23,8 @@
|
||||
#include "common.h"
|
||||
#include "event.h"
|
||||
#include "signal.h"
|
||||
#include "translate.h"
|
||||
|
||||
#include "halloc_util.h"
|
||||
|
||||
/**
|
||||
Number of signals that can be queued before an overflow occurs
|
||||
@@ -53,7 +57,7 @@ typedef struct
|
||||
active, which is the one that new events is written to. The inactive
|
||||
one contains the events that are currently beeing performed.
|
||||
*/
|
||||
static signal_list_t sig_list[2];
|
||||
static signal_list_t sig_list[]={{0,0},{0,0}};
|
||||
|
||||
/**
|
||||
The index of sig_list that is the list of signals currently written to
|
||||
@@ -136,7 +140,7 @@ static event_t *event_copy( event_t *event, int copy_arguments )
|
||||
{
|
||||
event_t *e = malloc( sizeof( event_t ) );
|
||||
if( !e )
|
||||
die_mem();
|
||||
DIE_MEM();
|
||||
memcpy( e, event, sizeof(event_t));
|
||||
|
||||
if( e->function_name )
|
||||
@@ -192,12 +196,12 @@ static int event_is_blocked( event_t *e )
|
||||
|
||||
const wchar_t *event_get_desc( event_t *e )
|
||||
{
|
||||
|
||||
CHECK( e, 0 );
|
||||
|
||||
if( !get_desc_buff )
|
||||
{
|
||||
get_desc_buff=malloc(sizeof(string_buffer_t) );
|
||||
if( !get_desc_buff )
|
||||
die_mem();
|
||||
sb_init( get_desc_buff );
|
||||
get_desc_buff=sb_halloc( global_context );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -252,10 +256,12 @@ void event_add_handler( event_t *event )
|
||||
{
|
||||
event_t *e;
|
||||
|
||||
CHECK( event, );
|
||||
|
||||
e = event_copy( event, 0 );
|
||||
|
||||
if( !events )
|
||||
events = al_new();
|
||||
events = al_new();
|
||||
|
||||
if( e->type == EVENT_SIGNAL )
|
||||
{
|
||||
@@ -271,14 +277,19 @@ void event_remove( event_t *criterion )
|
||||
array_list_t *new_list=0;
|
||||
event_t e;
|
||||
|
||||
CHECK( criterion, );
|
||||
|
||||
/*
|
||||
Because of concurrency issues, env_remove does not actually free
|
||||
any events - instead it simply moves all events that should be
|
||||
removed from the event list to the killme list.
|
||||
Because of concurrency issues (env_remove could remove an event
|
||||
that is currently being executed), env_remove does not actually
|
||||
free any events - instead it simply moves all events that should
|
||||
be removed from the event list to the killme list, and the ones
|
||||
that shouldn't be killed to new_list, and then drops the empty
|
||||
events-list.
|
||||
*/
|
||||
|
||||
if( !events )
|
||||
return;
|
||||
return;
|
||||
|
||||
for( i=0; i<al_get_count( events); i++ )
|
||||
{
|
||||
@@ -326,6 +337,8 @@ int event_get( event_t *criterion, array_list_t *out )
|
||||
|
||||
if( !events )
|
||||
return 0;
|
||||
|
||||
CHECK( criterion, 0 );
|
||||
|
||||
for( i=0; i<al_get_count( events); i++ )
|
||||
{
|
||||
@@ -378,17 +391,15 @@ static int event_is_killed( event_t *e )
|
||||
|
||||
/**
|
||||
Perform the specified event. Since almost all event firings will
|
||||
not match a single event handler, we make sureto optimize the 'no
|
||||
matches' path. This means that nothing is allocated/initialized
|
||||
unless that is needed.
|
||||
not be matched by even a single event handler, we make sure to
|
||||
optimize the 'no matches' path. This means that nothing is
|
||||
allocated/initialized unless needed.
|
||||
*/
|
||||
static void event_fire_internal( event_t *event )
|
||||
{
|
||||
int i, j;
|
||||
string_buffer_t *b=0;
|
||||
array_list_t *fire=0;
|
||||
|
||||
int was_interactive = is_interactive;
|
||||
|
||||
/*
|
||||
First we free all events that have been removed
|
||||
@@ -452,7 +463,7 @@ static void event_fire_internal( event_t *event )
|
||||
|
||||
for( j=0; j<al_get_count(&event->arguments); j++ )
|
||||
{
|
||||
wchar_t *arg_esc = escape( (wchar_t *)al_get( &event->arguments, j), 0 );
|
||||
wchar_t *arg_esc = escape( (wchar_t *)al_get( &event->arguments, j), 1 );
|
||||
sb_append( b, L" " );
|
||||
sb_append( b, arg_esc );
|
||||
free( arg_esc );
|
||||
@@ -462,21 +473,16 @@ static void event_fire_internal( event_t *event )
|
||||
|
||||
/*
|
||||
Event handlers are not part of the main flow of code, so
|
||||
they are marked as non-interactive and as a subshell
|
||||
they are marked as non-interactive
|
||||
*/
|
||||
is_interactive=0;
|
||||
proc_push_interactive(0);
|
||||
parser_push_block( EVENT );
|
||||
current_block->param1.event = event;
|
||||
eval( (wchar_t *)b->buff, 0, TOP );
|
||||
parser_pop_block();
|
||||
|
||||
proc_pop_interactive();
|
||||
}
|
||||
|
||||
/*
|
||||
Restore interactivity flags
|
||||
*/
|
||||
is_interactive = was_interactive;
|
||||
|
||||
if( b )
|
||||
{
|
||||
sb_destroy( b );
|
||||
@@ -504,6 +510,13 @@ static void event_fire_delayed()
|
||||
|
||||
int i;
|
||||
|
||||
/*
|
||||
If is_event is one, we are running the event-handler non-recursively.
|
||||
|
||||
When the event handler has called a piece of code that triggers
|
||||
another event, we do not want to fire delayed events because of
|
||||
concurrency problems.
|
||||
*/
|
||||
if( blocked && is_event==1)
|
||||
{
|
||||
array_list_t *new_blocked = 0;
|
||||
@@ -527,7 +540,7 @@ static void event_fire_delayed()
|
||||
free( blocked );
|
||||
blocked = new_blocked;
|
||||
}
|
||||
|
||||
|
||||
while( sig_list[active_list].count > 0 )
|
||||
{
|
||||
signal_list_t *lst;
|
||||
@@ -588,7 +601,7 @@ void event_fire( event_t *event )
|
||||
/*
|
||||
This means we are in a signal handler. We must be very
|
||||
careful not do do anything that could cause a memory
|
||||
allocation or something else that might be illegal in a
|
||||
allocation or something else that might be bad when in a
|
||||
signal handler.
|
||||
*/
|
||||
if( sig_list[active_list].count < SIG_UNHANDLED_MAX )
|
||||
@@ -623,7 +636,6 @@ void event_fire( event_t *event )
|
||||
|
||||
void event_init()
|
||||
{
|
||||
sig_list[active_list].count=0;
|
||||
}
|
||||
|
||||
void event_destroy()
|
||||
@@ -631,7 +643,7 @@ void event_destroy()
|
||||
|
||||
if( events )
|
||||
{
|
||||
al_foreach( events, (void (*)(const void *))&event_free );
|
||||
al_foreach( events, (void (*)(void *))&event_free );
|
||||
al_destroy( events );
|
||||
free( events );
|
||||
events=0;
|
||||
@@ -639,26 +651,21 @@ void event_destroy()
|
||||
|
||||
if( killme )
|
||||
{
|
||||
al_foreach( killme, (void (*)(const void *))&event_free );
|
||||
al_foreach( killme, (void (*)(void *))&event_free );
|
||||
al_destroy( killme );
|
||||
free( killme );
|
||||
killme=0;
|
||||
}
|
||||
|
||||
if( get_desc_buff )
|
||||
{
|
||||
sb_destroy( get_desc_buff );
|
||||
free( get_desc_buff );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void event_free( event_t *e )
|
||||
{
|
||||
CHECK( e, );
|
||||
|
||||
/*
|
||||
When apropriate, we clear the argument vector
|
||||
*/
|
||||
al_foreach( &e->arguments, (void (*)(const void *))&free );
|
||||
al_foreach( &e->arguments, &free );
|
||||
al_destroy( &e->arguments );
|
||||
|
||||
free( (void *)e->function_name );
|
||||
@@ -666,3 +673,4 @@ void event_free( event_t *e )
|
||||
free( (void *)e->param1.variable );
|
||||
free( e );
|
||||
}
|
||||
|
||||
|
||||
409
exec.c
409
exec.c
@@ -5,6 +5,8 @@
|
||||
manual, though I the changes performed have been massive.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
@@ -21,8 +23,13 @@
|
||||
#include <assert.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#include "config.h"
|
||||
#ifdef HAVE_SIGINFO_H
|
||||
#include <siginfo.h>
|
||||
#endif
|
||||
|
||||
#include "fallback.h"
|
||||
#include "util.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "wutil.h"
|
||||
#include "proc.h"
|
||||
@@ -36,8 +43,10 @@
|
||||
#include "expand.h"
|
||||
#include "signal.h"
|
||||
#include "env_universal.h"
|
||||
#include "translate.h"
|
||||
|
||||
#include "halloc.h"
|
||||
#include "halloc_util.h"
|
||||
#include "parse_util.h"
|
||||
|
||||
/**
|
||||
Prototype for the getpgid library function. The prototype for this
|
||||
@@ -70,7 +79,6 @@ static array_list_t *open_fds=0;
|
||||
|
||||
static int set_child_group( job_t *j, process_t *p, int print_errors );
|
||||
|
||||
|
||||
void exec_close( int fd )
|
||||
{
|
||||
int i;
|
||||
@@ -81,20 +89,20 @@ void exec_close( int fd )
|
||||
{
|
||||
debug( 1, FD_ERROR, fd );
|
||||
wperror( L"close" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( open_fds )
|
||||
{
|
||||
for( i=0; i<al_get_count( open_fds ); i++ )
|
||||
{
|
||||
int n = (int)(long)al_get( open_fds, i );
|
||||
int n = (int)al_get_long( open_fds, i );
|
||||
if( n == fd )
|
||||
{
|
||||
al_set( open_fds,
|
||||
i,
|
||||
al_get( open_fds,
|
||||
al_get_count( open_fds ) -1 ) );
|
||||
al_set_long( open_fds,
|
||||
i,
|
||||
al_get_long( open_fds, al_get_count( open_fds ) -1 ) );
|
||||
al_truncate( open_fds,
|
||||
al_get_count( open_fds ) -1 );
|
||||
break;
|
||||
@@ -121,11 +129,11 @@ int exec_pipe( int fd[2])
|
||||
|
||||
if( open_fds == 0 )
|
||||
{
|
||||
open_fds = al_new();
|
||||
open_fds = al_halloc( global_context );
|
||||
}
|
||||
|
||||
al_push( open_fds, (void *)(long)fd[0] );
|
||||
al_push( open_fds, (void *)(long)fd[1] );
|
||||
al_push_long( open_fds, (long)fd[0] );
|
||||
al_push_long( open_fds, (long)fd[1] );
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -159,7 +167,8 @@ static int use_fd_in_pipe( int fd, io_data_t *io )
|
||||
the redirection list io. This should make sure that there are no
|
||||
stray opened file descriptors in the child.
|
||||
|
||||
\param io the list of io redirections for this job. Pipes mentioned here should not be closed.
|
||||
\param io the list of io redirections for this job. Pipes mentioned
|
||||
here should not be closed.
|
||||
*/
|
||||
static void close_unused_internal_pipes( io_data_t *io )
|
||||
{
|
||||
@@ -169,7 +178,7 @@ static void close_unused_internal_pipes( io_data_t *io )
|
||||
{
|
||||
for( ;i<al_get_count( open_fds ); i++ )
|
||||
{
|
||||
int n = (int)(long)al_get( open_fds, i );
|
||||
int n = (long)al_get_long( open_fds, i );
|
||||
if( !use_fd_in_pipe( n, io) )
|
||||
{
|
||||
debug( 4, L"Close fd %d, used in other context", n );
|
||||
@@ -180,20 +189,6 @@ static void close_unused_internal_pipes( io_data_t *io )
|
||||
}
|
||||
}
|
||||
|
||||
void exec_init()
|
||||
{
|
||||
}
|
||||
|
||||
void exec_destroy()
|
||||
{
|
||||
if( open_fds )
|
||||
{
|
||||
al_destroy( open_fds );
|
||||
free( open_fds );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Make sure the fd used by this redirection is not used by i.e. a pipe.
|
||||
*/
|
||||
@@ -260,7 +255,7 @@ static int handle_child_io( io_data_t *io, int exit_on_error )
|
||||
if( io->fd > 2 )
|
||||
{
|
||||
/*
|
||||
Make sure the fd used by this redirection is not used by i.e. a pipe.
|
||||
Make sure the fd used by this redirection is not used by e.g. a pipe.
|
||||
*/
|
||||
free_fd( io, io->fd );
|
||||
}
|
||||
@@ -268,7 +263,11 @@ static int handle_child_io( io_data_t *io, int exit_on_error )
|
||||
switch( io->io_mode )
|
||||
{
|
||||
case IO_CLOSE:
|
||||
close(io->fd);
|
||||
if( close(io->fd) )
|
||||
{
|
||||
debug( 0, _(L"Failed to close file descriptor %d"), io->fd );
|
||||
wperror( L"close" );
|
||||
}
|
||||
break;
|
||||
case IO_FILE:
|
||||
{
|
||||
@@ -291,8 +290,12 @@ static int handle_child_io( io_data_t *io, int exit_on_error )
|
||||
}
|
||||
else if( tmp != io->fd)
|
||||
{
|
||||
/*
|
||||
This call will sometimes fail, but that is ok,
|
||||
this is just a precausion.
|
||||
*/
|
||||
close(io->fd);
|
||||
|
||||
|
||||
if(dup2( tmp, io->fd ) == -1 )
|
||||
{
|
||||
debug( 1,
|
||||
@@ -315,6 +318,10 @@ static int handle_child_io( io_data_t *io, int exit_on_error )
|
||||
|
||||
case IO_FD:
|
||||
{
|
||||
/*
|
||||
This call will sometimes fail, but that is ok,
|
||||
this is just a precausion.
|
||||
*/
|
||||
close(io->fd);
|
||||
|
||||
if( dup2( io->param1.old_fd, io->fd ) == -1 )
|
||||
@@ -340,6 +347,10 @@ static int handle_child_io( io_data_t *io, int exit_on_error )
|
||||
{
|
||||
int fd_to_dup = io->fd;
|
||||
|
||||
/*
|
||||
This call will sometimes fail, but that is ok,
|
||||
this is just a precausion.
|
||||
*/
|
||||
close(io->fd);
|
||||
|
||||
if( dup2( io->param1.pipe_fd[fd_to_dup?1:0], io->fd ) == -1 )
|
||||
@@ -403,7 +414,7 @@ static int setup_child_process( job_t *j, process_t *p )
|
||||
|
||||
if( !res )
|
||||
{
|
||||
res = handle_child_io( j->io, (p==0) );
|
||||
res = handle_child_io( j->io, (p!=0) );
|
||||
}
|
||||
|
||||
/* Set the handling for job control signals back to the default. */
|
||||
@@ -430,7 +441,9 @@ static void launch_process( process_t *p )
|
||||
{
|
||||
// debug( 1, L"exec '%ls'", p->argv[0] );
|
||||
|
||||
execve (wcs2str(p->actual_cmd), wcsv2strv( (const wchar_t **) p->argv), env_export_arr( 0 ) );
|
||||
execve ( wcs2str(p->actual_cmd),
|
||||
wcsv2strv( (const wchar_t **) p->argv),
|
||||
env_export_arr( 0 ) );
|
||||
debug( 0,
|
||||
_( L"Failed to execute process '%ls'" ),
|
||||
p->actual_cmd );
|
||||
@@ -486,7 +499,7 @@ static io_data_t *io_transmogrify( io_data_t * in )
|
||||
|
||||
out = malloc( sizeof( io_data_t ) );
|
||||
if( !out )
|
||||
die_mem();
|
||||
DIE_MEM();
|
||||
|
||||
out->fd = in->fd;
|
||||
out->io_mode = IO_FD;
|
||||
@@ -559,7 +572,7 @@ static void internal_exec_helper( const wchar_t *def,
|
||||
io_data_t *io_internal = io_transmogrify( io );
|
||||
int is_block_old=is_block;
|
||||
is_block=1;
|
||||
|
||||
|
||||
/*
|
||||
Did the transmogrification fail - if so, set error status and return
|
||||
*/
|
||||
@@ -570,7 +583,7 @@ static void internal_exec_helper( const wchar_t *def,
|
||||
}
|
||||
|
||||
signal_unblock();
|
||||
|
||||
|
||||
eval( def, io_internal, block_type );
|
||||
|
||||
signal_block();
|
||||
@@ -598,21 +611,21 @@ static int set_child_group( job_t *j, process_t *p, int print_errors )
|
||||
|
||||
if( j->job_control )
|
||||
{
|
||||
int new_pgid=0;
|
||||
|
||||
if (!j->pgid)
|
||||
{
|
||||
new_pgid=1;
|
||||
j->pgid = p->pid;
|
||||
}
|
||||
|
||||
if( setpgid (p->pid, j->pgid) )
|
||||
{
|
||||
{
|
||||
if( getpgid( p->pid) != j->pgid && print_errors )
|
||||
{
|
||||
debug( 1,
|
||||
_( L"Could not send process %d from group %d to group %d" ),
|
||||
p->pid,
|
||||
_( L"Could not send process %d, '%ls' in job %d, '%ls' from group %d to group %d" ),
|
||||
p->pid,
|
||||
p->argv[0],
|
||||
j->job_id,
|
||||
j->command,
|
||||
getpgid( p->pid),
|
||||
j->pgid );
|
||||
wperror( L"setpgid" );
|
||||
@@ -648,8 +661,6 @@ void exec( job_t *j )
|
||||
pid_t pid;
|
||||
int mypipe[2];
|
||||
sigset_t chldset;
|
||||
sigemptyset( &chldset );
|
||||
sigaddset( &chldset, SIGCHLD );
|
||||
int skip_fork;
|
||||
|
||||
io_data_t pipe_read, pipe_write;
|
||||
@@ -662,9 +673,48 @@ void exec( job_t *j )
|
||||
*/
|
||||
int exec_error=0;
|
||||
|
||||
int needs_keepalive = 0;
|
||||
process_t keepalive;
|
||||
|
||||
|
||||
CHECK( j, );
|
||||
|
||||
if( no_exec )
|
||||
return;
|
||||
|
||||
|
||||
|
||||
sigemptyset( &chldset );
|
||||
sigaddset( &chldset, SIGCHLD );
|
||||
|
||||
debug( 4, L"Exec job '%ls' with id %d", j->command, j->job_id );
|
||||
|
||||
if( block_io )
|
||||
{
|
||||
if( j->io )
|
||||
j->io = io_add( io_duplicate( j, block_io), j->io );
|
||||
else
|
||||
j->io=io_duplicate( j, block_io);
|
||||
}
|
||||
|
||||
io_data_t *input_redirect = io_get( j->io, 0 );
|
||||
|
||||
if( input_redirect &&
|
||||
(input_redirect->io_mode == IO_BUFFER) &&
|
||||
input_redirect->param3.is_input )
|
||||
{
|
||||
/*
|
||||
Input redirection - create a new gobetween process to take
|
||||
care of buffering
|
||||
*/
|
||||
|
||||
process_t *fake = halloc( j, sizeof(process_t) );
|
||||
fake->type = INTERNAL_BUFFER;
|
||||
fake->pipe_fd = 1;
|
||||
fake->next = j->first_process;
|
||||
j->first_process = fake;
|
||||
}
|
||||
|
||||
if( j->first_process->type==INTERNAL_EXEC )
|
||||
{
|
||||
/*
|
||||
@@ -673,7 +723,7 @@ void exec( job_t *j )
|
||||
signal_block();
|
||||
|
||||
/*
|
||||
setup_child_process make sure signals are properly set
|
||||
setup_child_process makes sure signals are properly set
|
||||
up. It will also call signal_unblock
|
||||
*/
|
||||
if( !setup_child_process( j, 0 ) )
|
||||
@@ -689,7 +739,7 @@ void exec( job_t *j )
|
||||
j->first_process->completed=1;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
pipe_read.fd=0;
|
||||
@@ -702,20 +752,61 @@ void exec( job_t *j )
|
||||
pipe_write.next=0;
|
||||
pipe_write.param1.pipe_fd[0]=pipe_write.param1.pipe_fd[1]=-1;
|
||||
|
||||
//fwprintf( stderr, L"Run command %ls\n", j->command );
|
||||
|
||||
|
||||
if( block_io )
|
||||
{
|
||||
if( j->io )
|
||||
j->io = io_add( io_duplicate( j, block_io), j->io );
|
||||
else
|
||||
j->io=io_duplicate( j, block_io);
|
||||
}
|
||||
//fwprintf( stderr, L"Run command %ls\n", j->command );
|
||||
|
||||
j->io = io_add( j->io, &pipe_write );
|
||||
|
||||
signal_block();
|
||||
|
||||
/*
|
||||
See if we need to create a group keepalive process. This is a
|
||||
process that we create to make sure that the process group
|
||||
doesn't die accidentally, and is needed when a block/function is
|
||||
inside a pipeline.
|
||||
*/
|
||||
|
||||
if( j->job_control )
|
||||
{
|
||||
for( p=j->first_process; p; p = p->next )
|
||||
{
|
||||
if( (p->type == INTERNAL_BLOCK ) ||
|
||||
(p->type == INTERNAL_FUNCTION ) )
|
||||
{
|
||||
if( p->next )
|
||||
{
|
||||
needs_keepalive = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( needs_keepalive )
|
||||
{
|
||||
keepalive.pid = fork();
|
||||
|
||||
if( keepalive.pid == 0 )
|
||||
{
|
||||
keepalive.pid = getpid();
|
||||
set_child_group( j, &keepalive, 1 );
|
||||
pause();
|
||||
exit(0);
|
||||
}
|
||||
else if( keepalive.pid < 0 )
|
||||
{
|
||||
/* The fork failed. */
|
||||
debug( 0, FORK_ERROR );
|
||||
wperror (L"fork");
|
||||
exit (1);
|
||||
}
|
||||
else
|
||||
{
|
||||
set_child_group( j, &keepalive, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
This loop loops over every process_t in the job, starting it as
|
||||
appropriate. This turns out to be rather complex, since a
|
||||
@@ -728,7 +819,7 @@ void exec( job_t *j )
|
||||
{
|
||||
mypipe[1]=-1;
|
||||
skip_fork=0;
|
||||
|
||||
|
||||
pipe_write.fd = p->pipe_fd;
|
||||
|
||||
/*
|
||||
@@ -762,22 +853,12 @@ void exec( job_t *j )
|
||||
break;
|
||||
}
|
||||
|
||||
/* fwprintf( stderr,
|
||||
L"Make pipe from %ls to %ls using fds %d and %d\n",
|
||||
p->actual_cmd,
|
||||
p->next->actual_cmd,
|
||||
mypipe[0],
|
||||
mypipe[1] );
|
||||
*/
|
||||
memcpy( pipe_write.param1.pipe_fd, mypipe, sizeof(int)*2);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
This is the last element of the pipeline.
|
||||
*/
|
||||
|
||||
/*
|
||||
Remove the io redirection for pipe output.
|
||||
*/
|
||||
j->io = io_remove( j->io, &pipe_write );
|
||||
@@ -788,12 +869,8 @@ void exec( job_t *j )
|
||||
{
|
||||
case INTERNAL_FUNCTION:
|
||||
{
|
||||
wchar_t **arg;
|
||||
int i;
|
||||
string_buffer_t sb;
|
||||
|
||||
wchar_t * def = halloc_register( j, wcsdup( function_get_definition( p->argv[0] )));
|
||||
//fwprintf( stderr, L"run function %ls\n", argv[0] );
|
||||
if( def == 0 )
|
||||
{
|
||||
debug( 0, _( L"Unknown function '%ls'" ), p->argv[0] );
|
||||
@@ -804,32 +881,14 @@ void exec( job_t *j )
|
||||
|
||||
current_block->param2.function_call_process = p;
|
||||
current_block->param1.function_name = halloc_register( current_block, wcsdup( p->argv[0] ) );
|
||||
|
||||
if( builtin_count_args(p->argv)>1 )
|
||||
{
|
||||
sb_init( &sb );
|
||||
|
||||
for( i=1, arg=p->argv+1; *arg; i++, arg++ )
|
||||
{
|
||||
if( i != 1 )
|
||||
sb_append( &sb, ARRAY_SEP_STR );
|
||||
sb_append( &sb, *arg );
|
||||
}
|
||||
|
||||
env_set( L"argv", (wchar_t *)sb.buff, ENV_LOCAL );
|
||||
sb_destroy( &sb );
|
||||
}
|
||||
else
|
||||
{
|
||||
env_set( L"argv", 0, ENV_LOCAL );
|
||||
}
|
||||
|
||||
|
||||
parse_util_set_argv( p->argv+1 );
|
||||
|
||||
parser_forbid_function( p->argv[0] );
|
||||
|
||||
if( p->next )
|
||||
{
|
||||
// fwprintf( stderr, L"Function %ls\n", def );
|
||||
io_buffer = io_buffer_create();
|
||||
io_buffer = io_buffer_create( 0 );
|
||||
j->io = io_add( j->io, io_buffer );
|
||||
}
|
||||
|
||||
@@ -845,16 +904,15 @@ void exec( job_t *j )
|
||||
{
|
||||
if( p->next )
|
||||
{
|
||||
// fwprintf( stderr, L"Block %ls\n", p->argv[0] );
|
||||
io_buffer = io_buffer_create();
|
||||
io_buffer = io_buffer_create( 0 );
|
||||
j->io = io_add( j->io, io_buffer );
|
||||
}
|
||||
|
||||
|
||||
internal_exec_helper( p->argv[0], TOP, j->io );
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
|
||||
case INTERNAL_BUILTIN:
|
||||
{
|
||||
int builtin_stdin=0;
|
||||
@@ -864,6 +922,7 @@ void exec( job_t *j )
|
||||
if( p == j->first_process )
|
||||
{
|
||||
io_data_t *in = io_get( j->io, 0 );
|
||||
|
||||
if( in )
|
||||
{
|
||||
switch( in->io_mode )
|
||||
@@ -872,11 +931,6 @@ void exec( job_t *j )
|
||||
case IO_FD:
|
||||
{
|
||||
builtin_stdin = in->param1.old_fd;
|
||||
/* fwprintf( stderr,
|
||||
L"Input redirection for builtin '%ls' from fd %d\n",
|
||||
p->argv[0],
|
||||
in->old_fd );
|
||||
*/
|
||||
break;
|
||||
}
|
||||
case IO_PIPE:
|
||||
@@ -887,11 +941,6 @@ void exec( job_t *j )
|
||||
|
||||
case IO_FILE:
|
||||
{
|
||||
/*
|
||||
fwprintf( stderr,
|
||||
L"Input redirection for builtin from file %ls\n",
|
||||
in->filename);
|
||||
*/
|
||||
builtin_stdin=wopen( in->param1.filename,
|
||||
in->param2.flags, 0777 );
|
||||
if( builtin_stdin == -1 )
|
||||
@@ -931,40 +980,37 @@ void exec( job_t *j )
|
||||
exec_error=1;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
builtin_push_io( builtin_stdin );
|
||||
|
||||
/*
|
||||
Since this may be the foreground job, and since a
|
||||
builtin may execute another foreground job, we need to
|
||||
pretend to suspend this job while running the builtin.
|
||||
*/
|
||||
|
||||
builtin_out_redirect = has_fd( j->io, 1 );
|
||||
builtin_err_redirect = has_fd( j->io, 2 );
|
||||
fg = j->fg;
|
||||
j->fg = 0;
|
||||
|
||||
signal_unblock();
|
||||
|
||||
p->status = builtin_run( p->argv );
|
||||
|
||||
signal_block();
|
||||
|
||||
/*
|
||||
Restore the fg flag, which is temporarily set to
|
||||
false during builtin execution so as not to confuse
|
||||
some job-handling builtins.
|
||||
*/
|
||||
j->fg = fg;
|
||||
}
|
||||
|
||||
builtin_push_io( builtin_stdin );
|
||||
|
||||
/*
|
||||
Since this may be the foreground job, and since a
|
||||
builtin may execute another foreground job, we need to
|
||||
pretend to suspend this job while running the builtin.
|
||||
*/
|
||||
|
||||
builtin_out_redirect = has_fd( j->io, 1 );
|
||||
builtin_err_redirect = has_fd( j->io, 2 );
|
||||
fg = j->fg;
|
||||
j->fg = 0;
|
||||
|
||||
signal_unblock();
|
||||
|
||||
p->status = builtin_run( p->argv );
|
||||
|
||||
signal_block();
|
||||
|
||||
/*
|
||||
Restore the fg flag, which is temporarily set to
|
||||
false during builtin execution so as not to confuse
|
||||
some job-handling builtins.
|
||||
*/
|
||||
j->fg = fg;
|
||||
|
||||
|
||||
/* if( is_interactive )
|
||||
fwprintf( stderr, L"Builtin '%ls' finished\n", j->command );
|
||||
*/
|
||||
if( close_stdin )
|
||||
{
|
||||
// fwprintf( stderr, L"Close builtin_stdin\n" );
|
||||
exec_close( builtin_stdin );
|
||||
}
|
||||
break;
|
||||
@@ -976,6 +1022,7 @@ void exec( job_t *j )
|
||||
|
||||
switch( p->type )
|
||||
{
|
||||
|
||||
case INTERNAL_BLOCK:
|
||||
case INTERNAL_FUNCTION:
|
||||
{
|
||||
@@ -1056,6 +1103,46 @@ void exec( job_t *j )
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
|
||||
case INTERNAL_BUFFER:
|
||||
{
|
||||
|
||||
pid = fork();
|
||||
|
||||
if( pid == 0 )
|
||||
{
|
||||
/*
|
||||
This is the child process. Write out the contents of the pipeline.
|
||||
*/
|
||||
p->pid = getpid();
|
||||
setup_child_process( j, p );
|
||||
|
||||
write( 1,
|
||||
input_redirect->param2.out_buffer->buff,
|
||||
input_redirect->param2.out_buffer->used );
|
||||
exit( 0 );
|
||||
}
|
||||
else if( pid < 0 )
|
||||
{
|
||||
/* The fork failed. */
|
||||
debug( 0, FORK_ERROR );
|
||||
wperror (L"fork");
|
||||
exit (1);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
This is the parent process. Store away
|
||||
information on the child, and possibly give
|
||||
it control over the terminal.
|
||||
*/
|
||||
p->pid = pid;
|
||||
set_child_group( j, p, 0 );
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case INTERNAL_BUILTIN:
|
||||
{
|
||||
@@ -1083,7 +1170,6 @@ void exec( job_t *j )
|
||||
( sb_out->used ) &&
|
||||
( buffer_stdout ) )
|
||||
{
|
||||
// fwprintf( stderr, L"Skip fork of %ls\n", j->command );
|
||||
char *res = wcs2str( (wchar_t *)sb_out->buff );
|
||||
b_append( io->param2.out_buffer, res, strlen( res ) );
|
||||
skip_fork = 1;
|
||||
@@ -1106,9 +1192,13 @@ void exec( job_t *j )
|
||||
pid = fork();
|
||||
if( pid == 0 )
|
||||
{
|
||||
|
||||
/*
|
||||
This is the child process.
|
||||
This is the child process. Setup redirections,
|
||||
print correct output to stdout and stderr, and
|
||||
then exit.
|
||||
*/
|
||||
|
||||
p->pid = getpid();
|
||||
setup_child_process( j, p );
|
||||
if( sb_out->used )
|
||||
@@ -1130,7 +1220,7 @@ void exec( job_t *j )
|
||||
{
|
||||
/*
|
||||
This is the parent process. Store away
|
||||
information on the child, and possibly fice
|
||||
information on the child, and possibly give
|
||||
it control over the terminal.
|
||||
*/
|
||||
p->pid = pid;
|
||||
@@ -1153,7 +1243,7 @@ void exec( job_t *j )
|
||||
p->pid = getpid();
|
||||
setup_child_process( j, p );
|
||||
launch_process( p );
|
||||
|
||||
|
||||
/*
|
||||
launch_process _never_ returns...
|
||||
*/
|
||||
@@ -1197,8 +1287,11 @@ void exec( job_t *j )
|
||||
pipe_read.param1.pipe_fd[0] = mypipe[0];
|
||||
|
||||
/*
|
||||
If there is a next process, close the output end of the
|
||||
pipe (the child subprocess already has a copy of the pipe).
|
||||
If there is a next process in the pipeline, close the
|
||||
output end of the current pipe (the surrent child
|
||||
subprocess already has a copy of the pipe - this makes sure
|
||||
we don't leak file descriptors either in the shell or in
|
||||
the children).
|
||||
*/
|
||||
if( p->next )
|
||||
{
|
||||
@@ -1206,6 +1299,15 @@ void exec( job_t *j )
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
The keepalive process is no longer needed, so we terminate it
|
||||
with extreme prejudice
|
||||
*/
|
||||
if( needs_keepalive )
|
||||
{
|
||||
kill( keepalive.pid, SIGKILL );
|
||||
}
|
||||
|
||||
signal_unblock();
|
||||
|
||||
debug( 3, L"Job is constructed" );
|
||||
@@ -1221,14 +1323,12 @@ void exec( job_t *j )
|
||||
{
|
||||
proc_last_bg_pid = j->pgid;
|
||||
}
|
||||
|
||||
|
||||
if( !exec_error )
|
||||
{
|
||||
job_continue (j, 0);
|
||||
}
|
||||
|
||||
debug( 3, L"End of exec()" );
|
||||
|
||||
}
|
||||
|
||||
int exec_subshell( const wchar_t *cmd,
|
||||
@@ -1249,7 +1349,7 @@ int exec_subshell( const wchar_t *cmd,
|
||||
}
|
||||
|
||||
is_subshell=1;
|
||||
io_buffer= io_buffer_create();
|
||||
io_buffer= io_buffer_create( 0 );
|
||||
|
||||
prev_status = proc_get_last_status();
|
||||
|
||||
@@ -1278,10 +1378,16 @@ int exec_subshell( const wchar_t *cmd,
|
||||
{
|
||||
wchar_t *el = str2wcs( begin );
|
||||
if( el )
|
||||
{
|
||||
al_push( l, el );
|
||||
}
|
||||
else
|
||||
{
|
||||
debug( 2, L"Got null string on line %d of file %s", __LINE__, __FILE__ );
|
||||
}
|
||||
}
|
||||
io_buffer_destroy( io_buffer );
|
||||
|
||||
|
||||
return status;
|
||||
|
||||
case '\n':
|
||||
@@ -1289,7 +1395,14 @@ int exec_subshell( const wchar_t *cmd,
|
||||
wchar_t *el;
|
||||
*end=0;
|
||||
el = str2wcs( begin );
|
||||
al_push( l, el );
|
||||
if( el )
|
||||
{
|
||||
al_push( l, el );
|
||||
}
|
||||
else
|
||||
{
|
||||
debug( 2, L"Got null string on line %d of file %s", __LINE__, __FILE__ );
|
||||
}
|
||||
begin = end+1;
|
||||
break;
|
||||
}
|
||||
|
||||
11
exec.h
11
exec.h
@@ -18,17 +18,6 @@
|
||||
*/
|
||||
#define PIPE_ERROR _(L"An error occurred while setting up pipe")
|
||||
|
||||
/**
|
||||
Initialize the exec library
|
||||
*/
|
||||
void exec_init();
|
||||
|
||||
/**
|
||||
Destroy dynamically allocated data and other resources used by the
|
||||
exec library
|
||||
*/
|
||||
void exec_destroy();
|
||||
|
||||
/**
|
||||
Execute the processes specified by j.
|
||||
|
||||
|
||||
70
expand.h
70
expand.h
@@ -20,9 +20,9 @@
|
||||
#include "util.h"
|
||||
|
||||
/**
|
||||
Flag specifying that subshell expansion should be skipped
|
||||
Flag specifying that cmdsubst expansion should be skipped
|
||||
*/
|
||||
#define EXPAND_SKIP_SUBSHELL 1
|
||||
#define EXPAND_SKIP_CMDSUBST 1
|
||||
|
||||
/**
|
||||
Flag specifying that variable expansion should be skipped
|
||||
@@ -112,60 +112,92 @@ enum
|
||||
/** String containing the character for separating two array elements */
|
||||
#define ARRAY_SEP_STR L"\x1e"
|
||||
|
||||
/**
|
||||
Error issued on array out of bounds
|
||||
*/
|
||||
#define ARRAY_BOUNDS_ERR _(L"Array index out of bounds")
|
||||
|
||||
|
||||
/**
|
||||
Perform various forms of expansion on in, such as tilde expansion
|
||||
(~USER becomes the users home directory), variable expansion
|
||||
($VAR_NAME becomes the value of the environment variable VAR_NAME),
|
||||
subshell expansion and wildcard expansion. The results are inserted
|
||||
(\~USER becomes the users home directory), variable expansion
|
||||
(\$VAR_NAME becomes the value of the environment variable VAR_NAME),
|
||||
cmdsubst expansion and wildcard expansion. The results are inserted
|
||||
into the list out.
|
||||
|
||||
If the parameter does not need expansion, it is copied into the list
|
||||
out. If expansion is performed, the original parameter is freed and
|
||||
newly allocated strings are inserted into the list out.
|
||||
|
||||
|
||||
If \c context is non-null, all the strings contained in the
|
||||
array_list_t \c out will be registered to be free'd when context is
|
||||
free'd.
|
||||
|
||||
\param context the halloc context to use for automatic deallocation
|
||||
\param in The parameter to expand
|
||||
\param flag Specifies if any expansion pass should be skipped. Legal values are any combination of EXPAND_SKIP_SUBSHELL EXPAND_SKIP_VARIABLES and EXPAND_SKIP_WILDCARDS
|
||||
\param flag Specifies if any expansion pass should be skipped. Legal values are any combination of EXPAND_SKIP_CMDSUBST EXPAND_SKIP_VARIABLES and EXPAND_SKIP_WILDCARDS
|
||||
\param out The list to which the result will be appended.
|
||||
\return One of EXPAND_OK, EXPAND_ERROR, EXPAND_WILDCARD_MATCH and EXPAND_WILDCARD_NO_MATCH
|
||||
\return One of EXPAND_OK, EXPAND_ERROR, EXPAND_WILDCARD_MATCH and EXPAND_WILDCARD_NO_MATCH. EXPAND_WILDCARD_NO_MATCH and EXPAND_WILDCARD_MATCH are normal exit conditions used only on strings containing wildcards to tell if the wildcard produced any matches.
|
||||
*/
|
||||
int expand_string( wchar_t *in, array_list_t *out, int flag );
|
||||
int expand_string( void *context, wchar_t *in, array_list_t *out, int flag );
|
||||
|
||||
/**
|
||||
expand_one is identical to expand_string, except it will fail if in
|
||||
expands to more than one string. This is used for expanding command
|
||||
names.
|
||||
|
||||
If \c context is non-null, the returning string ill be registered
|
||||
to be free'd when context is free'd.
|
||||
|
||||
\param context the halloc context to use for automatic deallocation
|
||||
\param in The parameter to expand
|
||||
\param flag Specifies if any expansion pass should be skipped. Legal values are any combination of EXPAND_SKIP_SUBSHELL EXPAND_SKIP_VARIABLES and EXPAND_SKIP_WILDCARDS
|
||||
\param flag Specifies if any expansion pass should be skipped. Legal values are any combination of EXPAND_SKIP_CMDSUBST EXPAND_SKIP_VARIABLES and EXPAND_SKIP_WILDCARDS
|
||||
\return The expanded parameter, or 0 on failiure
|
||||
*/
|
||||
wchar_t *expand_one( wchar_t *in, int flag );
|
||||
wchar_t *expand_one( void *context, wchar_t *in, int flag );
|
||||
|
||||
/**
|
||||
Convert the variable value to a human readable form, i.e. escape things, handle arrays, etc. Suitable for pretty-printing.
|
||||
|
||||
\param in the value to escape
|
||||
*/
|
||||
wchar_t *expand_escape_variable( const wchar_t *in );
|
||||
|
||||
|
||||
/**
|
||||
Perform tilde expansion and nothing else on the specified string.
|
||||
|
||||
If tilde expansion is needed, the original string is freed and a
|
||||
new string, allocated using malloc, is returned.
|
||||
|
||||
\param in the string to tilde expand
|
||||
*/
|
||||
wchar_t *expand_tilde(wchar_t *in);
|
||||
|
||||
|
||||
/**
|
||||
Tokenize the specified string into the specified array_list_t.
|
||||
Each new element is allocated using malloc and must be freed by the
|
||||
caller.
|
||||
|
||||
\param val the input string. The contents of this string is not changed.
|
||||
\param out the list in which to place the elements.
|
||||
Test if the specified argument is clean, i.e. it does not contain
|
||||
any tokens which need to be expanded or otherwise altered. Clean
|
||||
strings can be passed through expand_string and expand_one without
|
||||
changing them. About two thirds of all strings are clean, so
|
||||
skipping expansion on them actually does save a small amount of
|
||||
time, since it avoids multiple memory allocations during the
|
||||
expansion process.
|
||||
|
||||
\param in the string to test
|
||||
*/
|
||||
void expand_variable_array( const wchar_t *val, array_list_t *out );
|
||||
int expand_is_clean( const wchar_t *in );
|
||||
|
||||
/**
|
||||
Perform error reporting for a syntax error related to the variable
|
||||
expansion beginning at the specified character of the specified
|
||||
token. This function will call the error function with an
|
||||
explanatory string about what is wrong with the specified token.
|
||||
|
||||
\param token The token containing the error
|
||||
\param token_pos The position where the expansion begins
|
||||
\param error_pos The position on the line to report to the error function.
|
||||
*/
|
||||
void expand_variable_error( const wchar_t *token, int token_pos, int error_pos );
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
1093
fallback.c
Normal file
1093
fallback.c
Normal file
File diff suppressed because it is too large
Load Diff
427
fallback.h
Normal file
427
fallback.h
Normal file
@@ -0,0 +1,427 @@
|
||||
|
||||
#ifndef FISH_FALLBACK_H
|
||||
#define FISH_FALLBACK_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include <wctype.h>
|
||||
#include <wchar.h>
|
||||
#include <limits.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
|
||||
#ifndef WCHAR_MAX
|
||||
/**
|
||||
This _should_ be defined by wchar.h, but e.g. OpenBSD doesn't.
|
||||
*/
|
||||
#define WCHAR_MAX INT_MAX
|
||||
#endif
|
||||
|
||||
/**
|
||||
Make sure __func__ is defined to some string. In C99, this should
|
||||
be the currently compiled function. If we aren't using C99 or
|
||||
later, older versions of GCC had __FUNCTION__.
|
||||
*/
|
||||
#if __STDC_VERSION__ < 199901L
|
||||
# if __GNUC__ >= 2
|
||||
# define __func__ __FUNCTION__
|
||||
# else
|
||||
# define __func__ "<unknown>"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
Under curses, tputs expects an int (*func)(char) as its last
|
||||
parameter, but in ncurses, tputs expects a int (*func)(int) as its
|
||||
last parameter. tputs_arg_t is defined to always be what tputs
|
||||
expects. Hopefully.
|
||||
*/
|
||||
|
||||
#ifdef NCURSES_VERSION
|
||||
typedef int tputs_arg_t;
|
||||
#else
|
||||
typedef char tputs_arg_t;
|
||||
#endif
|
||||
|
||||
#ifndef SIGIO
|
||||
#define SIGIO SIGUSR1
|
||||
#endif
|
||||
|
||||
#ifndef SIGWINCH
|
||||
#define SIGIO SIGUSR2
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_WINSIZE
|
||||
struct winsize
|
||||
{
|
||||
unsigned short ws_row;
|
||||
unsigned short ws_col;
|
||||
}
|
||||
;
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TPUTS_KLUDGE
|
||||
|
||||
/**
|
||||
Linux on PPC seems to have a tputs implementation that sometimes
|
||||
behaves strangely. This fallback seems to fix things.
|
||||
*/
|
||||
int tputs(const char *str, int affcnt, int (*fish_putc)(tputs_arg_t));
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_FWPRINTF
|
||||
|
||||
/**
|
||||
Print formated string. Some operating systems (Like NetBSD) do not
|
||||
have wide string formating functions. Therefore we implement our
|
||||
own. Not at all complete. Supports wide and narrow characters,
|
||||
strings and decimal numbers, position (%n), field width and
|
||||
precision.
|
||||
*/
|
||||
int fwprintf( FILE *f, const wchar_t *format, ... );
|
||||
|
||||
|
||||
/**
|
||||
Print formated string. Some operating systems (Like NetBSD) do not
|
||||
have wide string formating functions. Therefore we define our
|
||||
own. Not at all complete. Supports wide and narrow characters,
|
||||
strings and decimal numbers, position (%n), field width and
|
||||
precision.
|
||||
*/
|
||||
int swprintf( wchar_t *str, size_t l, const wchar_t *format, ... );
|
||||
|
||||
/**
|
||||
Print formated string. Some operating systems (Like NetBSD) do not
|
||||
have wide string formating functions. Therefore we define our
|
||||
own. Not at all complete. Supports wide and narrow characters,
|
||||
strings and decimal numbers, position (%n), field width and
|
||||
precision.
|
||||
*/
|
||||
int wprintf( const wchar_t *format, ... );
|
||||
|
||||
/**
|
||||
Print formated string. Some operating systems (Like NetBSD) do not
|
||||
have wide string formating functions. Therefore we define our
|
||||
own. Not at all complete. Supports wide and narrow characters,
|
||||
strings and decimal numbers, position (%n), field width and
|
||||
precision.
|
||||
*/
|
||||
int vwprintf( const wchar_t *filter, va_list va );
|
||||
|
||||
/**
|
||||
Print formated string. Some operating systems (Like NetBSD) do not
|
||||
have wide string formating functions. Therefore we define our
|
||||
own. Not at all complete. Supports wide and narrow characters,
|
||||
strings and decimal numbers, position (%n), field width and
|
||||
precision.
|
||||
*/
|
||||
int vfwprintf( FILE *f, const wchar_t *filter, va_list va );
|
||||
|
||||
/**
|
||||
Print formated string. Some operating systems (Like NetBSD) do not
|
||||
have wide string formating functions. Therefore we define our
|
||||
own. Not at all complete. Supports wide and narrow characters,
|
||||
strings and decimal numbers, position (%n), field width and
|
||||
precision.
|
||||
*/
|
||||
int vswprintf( wchar_t *out, size_t n, const wchar_t *filter, va_list va );
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_FGETWC
|
||||
/**
|
||||
Fallback implementation of fgetwc
|
||||
*/
|
||||
wint_t fgetwc(FILE *stream);
|
||||
|
||||
/**
|
||||
Fallback implementation of getwc
|
||||
*/
|
||||
wint_t getwc(FILE *stream);
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_FPUTWC
|
||||
|
||||
/**
|
||||
Fallback implementation of fputwc
|
||||
*/
|
||||
wint_t fputwc(wchar_t wc, FILE *stream);
|
||||
/**
|
||||
Fallback implementation of putwc
|
||||
*/
|
||||
wint_t putwc(wchar_t wc, FILE *stream);
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_WCSTOK
|
||||
|
||||
/**
|
||||
Fallback implementation of wcstok. Uses code borrowed from glibc.
|
||||
*/
|
||||
wchar_t *wcstok(wchar_t *wcs, const wchar_t *delim, wchar_t **ptr);
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_WCWIDTH
|
||||
|
||||
/**
|
||||
Return the number of columns used by a character. This is a libc
|
||||
function, but the prototype for this function is missing in some libc
|
||||
implementations.
|
||||
|
||||
Fish has a fallback implementation in case the implementation is
|
||||
missing altogether. In locales without a native wcwidth, Unicode
|
||||
is probably so broken that it isn't worth trying to implement a
|
||||
real wcwidth. Therefore, the fallback wcwidth assumes any printing
|
||||
character takes up one column and anything else uses 0 columns.
|
||||
*/
|
||||
int wcwidth( wchar_t c );
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_WCSDUP
|
||||
|
||||
/**
|
||||
Create a duplicate string. Wide string version of strdup. Will
|
||||
automatically exit if out of memory.
|
||||
*/
|
||||
wchar_t *wcsdup(const wchar_t *in);
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_WCSLEN
|
||||
|
||||
/**
|
||||
Fallback for wcsen. Returns the length of the specified string.
|
||||
*/
|
||||
size_t wcslen(const wchar_t *in);
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_WCSCASECMP
|
||||
/**
|
||||
Case insensitive string compare function. Wide string version of
|
||||
strcasecmp.
|
||||
|
||||
This implementation of wcscasecmp does not take into account
|
||||
esoteric locales where uppercase and lowercase do not cleanly
|
||||
transform between each other. Hopefully this should be fine since
|
||||
fish only uses this function with one of the strings supplied by
|
||||
fish and guaranteed to be a sane, english word. Using wcscasecmp on
|
||||
a user-supplied string should be considered a bug.
|
||||
*/
|
||||
int wcscasecmp( const wchar_t *a, const wchar_t *b );
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_WCSNCASECMP
|
||||
|
||||
/**
|
||||
Case insensitive string compare function. Wide string version of
|
||||
strncasecmp.
|
||||
|
||||
This implementation of wcsncasecmp does not take into account
|
||||
esoteric locales where uppercase and lowercase do not cleanly
|
||||
transform between each other. Hopefully this should be fine since
|
||||
fish only uses this function with one of the strings supplied by
|
||||
fish and guaranteed to be a sane, english word. Using wcsncasecmp on
|
||||
a user-supplied string should be considered a bug.
|
||||
*/
|
||||
int wcsncasecmp( const wchar_t *a, const wchar_t *b, int count );
|
||||
|
||||
/**
|
||||
Returns a newly allocated wide character string wich is a copy of
|
||||
the string in, but of length c or shorter. The returned string is
|
||||
always null terminated, and the null is not included in the string
|
||||
length.
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_WCSNDUP
|
||||
|
||||
/**
|
||||
Fallback for wcsndup function. Returns a copy of \c in, truncated
|
||||
to a maximum length of \c c.
|
||||
*/
|
||||
wchar_t *wcsndup( const wchar_t *in, int c );
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
Converts from wide char to digit in the specified base. If d is not
|
||||
a valid digit in the specified base, return -1. This is a helper
|
||||
function for wcstol, but it is useful itself, so it is exported.
|
||||
*/
|
||||
long convert_digit( wchar_t d, int base );
|
||||
|
||||
#ifndef HAVE_WCSTOL
|
||||
|
||||
/**
|
||||
Fallback implementation. Convert a wide character string to a
|
||||
number in the specified base. This functions is the wide character
|
||||
string equivalent of strtol. For bases of 10 or lower, 0..9 are
|
||||
used to represent numbers. For bases below 36, a-z and A-Z are used
|
||||
to represent numbers higher than 9. Higher bases than 36 are not
|
||||
supported.
|
||||
*/
|
||||
long wcstol(const wchar_t *nptr,
|
||||
wchar_t **endptr,
|
||||
int base);
|
||||
|
||||
#endif
|
||||
#ifndef HAVE_WCSLCAT
|
||||
|
||||
/**
|
||||
Appends src to string dst of size siz (unlike wcsncat, siz is the
|
||||
full size of dst, not space left). At most siz-1 characters will be
|
||||
copied. Always NUL terminates (unless siz <= wcslen(dst)). Returns
|
||||
wcslen(src) + MIN(siz, wcslen(initial dst)). If retval >= siz,
|
||||
truncation occurred.
|
||||
|
||||
This is the OpenBSD strlcat function, modified for wide characters,
|
||||
and renamed to reflect this change.
|
||||
|
||||
*/
|
||||
size_t wcslcat( wchar_t *dst, const wchar_t *src, size_t siz );
|
||||
|
||||
#endif
|
||||
#ifndef HAVE_WCSLCPY
|
||||
|
||||
/**
|
||||
Copy src to string dst of size siz. At most siz-1 characters will
|
||||
be copied. Always NUL terminates (unless siz == 0). Returns
|
||||
wcslen(src); if retval >= siz, truncation occurred.
|
||||
|
||||
This is the OpenBSD strlcpy function, modified for wide characters,
|
||||
and renamed to reflect this change.
|
||||
*/
|
||||
size_t wcslcpy( wchar_t *dst, const wchar_t *src, size_t siz );
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_BROKEN_DEL_CURTERM
|
||||
|
||||
/**
|
||||
BSD del_curterm seems to do a double-free. We redefine it as a no-op
|
||||
*/
|
||||
#define del_curterm(oterm) OK
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_LRAND48_R
|
||||
|
||||
/**
|
||||
Datastructure for the lrand48_r fallback implementation.
|
||||
*/
|
||||
struct drand48_data
|
||||
{
|
||||
/**
|
||||
Seed value
|
||||
*/
|
||||
unsigned int seed;
|
||||
}
|
||||
;
|
||||
|
||||
/**
|
||||
Fallback implementation of lrand48_r. Internally uses rand_r, so it is pretty weak.
|
||||
*/
|
||||
int lrand48_r( struct drand48_data *buffer, long int *result );
|
||||
|
||||
/**
|
||||
Fallback implementation of srand48_r, the seed function for lrand48_r.
|
||||
*/
|
||||
int srand48_r( long int seedval, struct drand48_data *buffer );
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_FUTIMES
|
||||
|
||||
int futimes( int fd, const struct timeval *times );
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_GETTEXT
|
||||
|
||||
/**
|
||||
Fallback implementation of gettext. Just returns the original string.
|
||||
*/
|
||||
char * gettext( const char * msgid );
|
||||
|
||||
/**
|
||||
Fallback implementation of bindtextdomain. Does nothing.
|
||||
*/
|
||||
char * bindtextdomain( const char * domainname, const char * dirname );
|
||||
|
||||
/**
|
||||
Fallback implementation of textdomain. Does nothing.
|
||||
*/
|
||||
char * textdomain( const char * domainname );
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_DCGETTEXT
|
||||
|
||||
/**
|
||||
Fallback implementation of dcgettext. Just returns the original string.
|
||||
*/
|
||||
char * dcgettext ( const char * domainname,
|
||||
const char * msgid,
|
||||
int category );
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef HAVE__NL_MSG_CAT_CNTR
|
||||
|
||||
/**
|
||||
Some gettext implementation use have this variable, and by
|
||||
increasing it, one can tell the system that the translations need
|
||||
to be reloaded.
|
||||
*/
|
||||
extern int _nl_msg_cat_cntr;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef HAVE_KILLPG
|
||||
int killpg( int pgr, int sig );
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef HAVE_WORKING_GETOPT_LONG
|
||||
|
||||
struct option
|
||||
{
|
||||
const char *name;
|
||||
int has_arg;
|
||||
int *flag;
|
||||
int val;
|
||||
}
|
||||
;
|
||||
|
||||
#ifndef no_argument
|
||||
#define no_argument 0
|
||||
#endif
|
||||
|
||||
#ifndef required_argument
|
||||
#define required_argument 1
|
||||
#endif
|
||||
|
||||
#ifndef optional_argument
|
||||
#define optional_argument 2
|
||||
#endif
|
||||
|
||||
int getopt_long(int argc,
|
||||
char * const argv[],
|
||||
const char *optstring,
|
||||
const struct option *longopts,
|
||||
int *longindex);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
113
fish.spec.in
113
fish.spec.in
@@ -11,42 +11,110 @@ URL: http://roo.no-ip.org/fish/
|
||||
Source0: http://roo.no-ip.org/%{name}/files/%{version}/%{name}-%{version}.tar.bz2
|
||||
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
||||
BuildRequires: doxygen ncurses-devel xorg-x11-devel
|
||||
BuildRequires: ncurses-devel gettext groff
|
||||
|
||||
|
||||
# Locate correct build time-dependencies for providing X headers
|
||||
%if "%fedora" >= "5"
|
||||
|
||||
# Modern Fedora version, has modular X.org
|
||||
BuildRequires: xorg-x11-proto-devel libX11-devel libXt-devel libXext-devel
|
||||
|
||||
%endif
|
||||
|
||||
%if "%fedora" < "5"
|
||||
%if "%fedora" >= "3"
|
||||
|
||||
# Semi-old Fedora version, has non-modular X.org
|
||||
BuildRequires: xorg-x11-devel
|
||||
|
||||
%endif
|
||||
%endif
|
||||
|
||||
%if 0%{?fedora}
|
||||
%if "%fedora" < "3"
|
||||
|
||||
# Ancient Fedora version, has XFree86
|
||||
BuildRequires: XFree86-devel
|
||||
|
||||
%endif
|
||||
%else
|
||||
|
||||
# The %fedora variable has not been correctly defined, or this is is
|
||||
# not a Fedora system, try guessing BuildRequires by looking at the
|
||||
# directory structure
|
||||
%define xinclude /usr%(if [ -d /usr/X11R6/include ]; then echo /X11R6; fi)/include
|
||||
BuildRequires: %{xinclude}/X11/StringDefs.h, %{xinclude}/X11/Xlib.h
|
||||
BuildRequires: %{xinclude}/X11/Intrinsic.h, %{xinclude}/X11/Xatom.h
|
||||
|
||||
%endif
|
||||
|
||||
|
||||
%description
|
||||
fish is a shell geared towards interactive use. It's features are
|
||||
focused on user friendlieness and discoverability. The language syntax
|
||||
|
||||
fish is a shell geared towards interactive use. Its features are
|
||||
focused on user friendliness and discoverability. The language syntax
|
||||
is simple but incompatible with other shell languages.
|
||||
|
||||
|
||||
%prep
|
||||
%setup -q
|
||||
|
||||
%build
|
||||
|
||||
|
||||
|
||||
%build
|
||||
# The docdir argument is to make the name of the cosumantation
|
||||
# directory 'fish-VERSION', instead of the default, which is simply
|
||||
# 'fish'.
|
||||
%configure docdir=%_datadir/doc/%{name}-%{version}
|
||||
make %{?_smp_mflags}
|
||||
|
||||
|
||||
|
||||
|
||||
%install
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
make install DESTDIR="$RPM_BUILD_ROOT"
|
||||
|
||||
# Find translation files
|
||||
%find_lang %{name}.\*
|
||||
|
||||
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
|
||||
|
||||
|
||||
%post
|
||||
# Add fish to the list of allowed shells in /etc/shells
|
||||
if ! grep %_bindir/fish %_sysconfdir/shells >/dev/null; then
|
||||
echo %_bindir/fish >>%_sysconfdir/shells
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
%postun
|
||||
# Remove fish from the list of allowed shells in /etc/shells
|
||||
if [ "$1" = 0 ]; then
|
||||
grep -v %_bindir/fish %_sysconfdir/shells >%_sysconfdir/fish.tmp
|
||||
mv %_sysconfdir/fish.tmp %_sysconfdir/shells
|
||||
fi
|
||||
|
||||
%files
|
||||
|
||||
|
||||
|
||||
%files -f %{name}.\*.lang
|
||||
|
||||
%defattr(-,root,root,-)
|
||||
|
||||
# The documentation directory
|
||||
%doc %_datadir/doc/%{name}-%{version}
|
||||
|
||||
# man files
|
||||
%_mandir/man1/fish.1*
|
||||
%_mandir/man1/xsel.1x*
|
||||
%_mandir/man1/mimedb.1*
|
||||
@@ -54,6 +122,8 @@ fi
|
||||
%_mandir/man1/count.1*
|
||||
%_mandir/man1/fishd.1*
|
||||
%_mandir/man1/fish_pager.1*
|
||||
|
||||
# The program binaries
|
||||
%attr(0755,root,root) %_bindir/fish
|
||||
%attr(0755,root,root) %_bindir/fishd
|
||||
%attr(0755,root,root) %_bindir/fish_pager
|
||||
@@ -61,15 +131,42 @@ fi
|
||||
%attr(0755,root,root) %_bindir/set_color
|
||||
%attr(0755,root,root) %_bindir/mimedb
|
||||
%attr(0755,root,root) %_bindir/count
|
||||
|
||||
# Configuration files
|
||||
%config %_sysconfdir/fish
|
||||
%config %_sysconfdir/fish_inputrc
|
||||
%dir %_sysconfdir/fish.d
|
||||
%config %_sysconfdir/fish.d/fish_*.fish
|
||||
%dir %_sysconfdir/fish.d/completions
|
||||
%config %_sysconfdir/fish.d/completions/*.fish
|
||||
%_datadir/locale/*/LC_MESSAGES/fish.mo
|
||||
|
||||
# Non-configuration initialization files
|
||||
%dir %_datadir/fish
|
||||
%_datadir/fish/fish
|
||||
|
||||
# Program specific tab-completions
|
||||
%dir %_datadir/fish/completions
|
||||
%_datadir/fish/completions/*.fish
|
||||
|
||||
# Dynamically loaded shellscript functions
|
||||
%dir %_datadir/fish/functions
|
||||
%_datadir/fish/functions/*.fish
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
%changelog
|
||||
* Fri Aug 4 2006 Axel Liljencrantz<axel@liljencrantz.se> 1.21.10-4
|
||||
- Add better translation finding code from fedora spec to main spec. Thank you to Michael Schwendt.
|
||||
- Add missing dependency libXext-devel.
|
||||
- Remove one nesting level from dependency checking code.
|
||||
|
||||
* Tue Aug 1 2006 Axel Liljencrantz<axel@liljencrantz.se> 1.21.10-1
|
||||
- Improved the dependency check for X headers. Thank you to Michael Schwendt for pointers on how to do this
|
||||
|
||||
* Mon Jul 31 2006 Axel Liljencrantz<axel@liljencrantz.se> 1.21.10-1
|
||||
- Fixed spelling and punctuation as a per patch from Paul Howarth
|
||||
- Fixed dependencies as per patch from Paul Howarth
|
||||
|
||||
* Tue Nov 29 2005 Axel Liljencrantz <axel@liljencrantz.se> 1.17.0-0
|
||||
- 1.17.0
|
||||
|
||||
|
||||
741
fish_pager.c
741
fish_pager.c
@@ -9,7 +9,14 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#ifdef HAVE_SYS_TERMIOS_H
|
||||
#include <sys/termios.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_IOCTL_H
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <sys/wait.h>
|
||||
#include <dirent.h>
|
||||
@@ -35,13 +42,18 @@
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
|
||||
#include "fallback.h"
|
||||
#include "util.h"
|
||||
|
||||
#include "wutil.h"
|
||||
#include "common.h"
|
||||
#include "complete.h"
|
||||
#include "output.h"
|
||||
#include "input_common.h"
|
||||
#include "env_universal.h"
|
||||
#include "halloc.h"
|
||||
#include "halloc_util.h"
|
||||
|
||||
enum
|
||||
{
|
||||
@@ -74,6 +86,7 @@ static struct termios pager_modes;
|
||||
|
||||
static int is_ca_mode = 0;
|
||||
|
||||
static buffer_t *pager_buffer;
|
||||
|
||||
/**
|
||||
The environment variables used to specify the color of different
|
||||
@@ -91,20 +104,55 @@ static wchar_t *hightlight_var[] =
|
||||
static string_buffer_t out_buff;
|
||||
static FILE *out_file;
|
||||
|
||||
|
||||
int get_color( int highlight )
|
||||
/**
|
||||
Data structure describing one or a group of related completions
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/**
|
||||
The list of all completin strings this entry applies to
|
||||
*/
|
||||
array_list_t *comp;
|
||||
/**
|
||||
The description
|
||||
*/
|
||||
wchar_t *desc;
|
||||
/**
|
||||
On-screen width of the completion string
|
||||
*/
|
||||
int comp_width;
|
||||
/**
|
||||
On-screen width of the description information
|
||||
*/
|
||||
int desc_width;
|
||||
/**
|
||||
Preffered total width
|
||||
*/
|
||||
int pref_width;
|
||||
/**
|
||||
Minimum acceptable width
|
||||
*/
|
||||
int min_width;
|
||||
}
|
||||
comp_t;
|
||||
|
||||
static int get_color( int highlight )
|
||||
{
|
||||
wchar_t *val;
|
||||
|
||||
if( highlight < 0 )
|
||||
return FISH_COLOR_NORMAL;
|
||||
if( highlight >= (4) )
|
||||
return FISH_COLOR_NORMAL;
|
||||
|
||||
wchar_t *val = env_universal_get( hightlight_var[highlight]);
|
||||
val = wgetenv( hightlight_var[highlight]);
|
||||
|
||||
if( !val )
|
||||
{
|
||||
val = env_universal_get( hightlight_var[highlight]);
|
||||
}
|
||||
|
||||
if( val == 0 )
|
||||
return FISH_COLOR_NORMAL;
|
||||
|
||||
if( val == 0 )
|
||||
if( !val )
|
||||
{
|
||||
return FISH_COLOR_NORMAL;
|
||||
}
|
||||
@@ -112,7 +160,20 @@ int get_color( int highlight )
|
||||
return output_color_code( val );
|
||||
}
|
||||
|
||||
int try_sequence( char *seq )
|
||||
static void recalc_width( array_list_t *l, const wchar_t *prefix )
|
||||
{
|
||||
int i;
|
||||
for( i=0; i<al_get_count( l ); i++ )
|
||||
{
|
||||
comp_t *c = (comp_t *)al_get( l, i );
|
||||
|
||||
c->min_width = mini( c->desc_width, maxi(0,termsize.ws_col/3 - 2)) +
|
||||
mini( c->desc_width, maxi(0,termsize.ws_col/5 - 4)) +4;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static int try_sequence( char *seq )
|
||||
{
|
||||
int j, k;
|
||||
wint_t c=0;
|
||||
@@ -195,6 +256,110 @@ static wint_t readch()
|
||||
}
|
||||
|
||||
|
||||
static int pager_buffered_writer( char c)
|
||||
{
|
||||
b_append( pager_buffer, &c, 1 );
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pager_flush()
|
||||
{
|
||||
write( 1, pager_buffer->buff, pager_buffer->used );
|
||||
pager_buffer->used = 0;
|
||||
}
|
||||
|
||||
|
||||
static int print_max( const wchar_t *str, int max, int has_more )
|
||||
{
|
||||
int i;
|
||||
int written = 0;
|
||||
for( i=0; str[i]; i++ )
|
||||
{
|
||||
if( written + wcwidth(str[i]) > max )
|
||||
break;
|
||||
if( ( written + wcwidth(str[i]) == max) && (has_more || str[i+1]) )
|
||||
{
|
||||
writech( ellipsis_char );
|
||||
written += wcwidth(ellipsis_char );
|
||||
break;
|
||||
}
|
||||
|
||||
writech( str[i] );
|
||||
written+= wcwidth( str[i] );
|
||||
}
|
||||
return written;
|
||||
}
|
||||
|
||||
static void completion_print_item( const wchar_t *prefix, comp_t *c, int width )
|
||||
{
|
||||
int comp_width=0, desc_width=0;
|
||||
int i;
|
||||
int written=0;
|
||||
|
||||
if( c->pref_width <= width )
|
||||
{
|
||||
/*
|
||||
The entry fits, we give it as much space as it wants
|
||||
*/
|
||||
comp_width = c->comp_width;
|
||||
desc_width = c->desc_width;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
The completion and description won't fit on the
|
||||
allocated space. Give a maximum of 2/3 of the
|
||||
space to the completion, and whatever is left to
|
||||
the description.
|
||||
*/
|
||||
int desc_all = c->desc_width?c->desc_width+4:0;
|
||||
|
||||
comp_width = maxi( mini( c->comp_width,
|
||||
2*(width-4)/3 ),
|
||||
width - desc_all );
|
||||
if( c->desc_width )
|
||||
desc_width = width-comp_width-4;
|
||||
else
|
||||
c->desc_width=0;
|
||||
|
||||
}
|
||||
|
||||
for( i=0; i<al_get_count( c->comp ); i++ )
|
||||
{
|
||||
const wchar_t *comp = (const wchar_t *)al_get( c->comp, i );
|
||||
if( i != 0 )
|
||||
written += print_max( L" ", comp_width - written, 2 );
|
||||
set_color( get_color(HIGHLIGHT_PAGER_PREFIX),FISH_COLOR_NORMAL );
|
||||
written += print_max( prefix, comp_width - written, comp[0]?1:0 );
|
||||
set_color( get_color(HIGHLIGHT_PAGER_COMPLETION),FISH_COLOR_IGNORE );
|
||||
written += print_max( comp, comp_width - written, i!=(al_get_count(c->comp)-1) );
|
||||
}
|
||||
|
||||
|
||||
if( desc_width )
|
||||
{
|
||||
while( written < (width-desc_width-2))
|
||||
{
|
||||
written++;
|
||||
writech( L' ');
|
||||
}
|
||||
written += print_max( L"(", 1, 0 );
|
||||
set_color( get_color( HIGHLIGHT_PAGER_DESCRIPTION ),
|
||||
FISH_COLOR_IGNORE );
|
||||
written += print_max( c->desc, desc_width, 0 );
|
||||
written += print_max( L")", 1, 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
while( written < width )
|
||||
{
|
||||
written++;
|
||||
writech( L' ');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
Print the specified part of the completion list, using the
|
||||
specified column offsets and quoting style.
|
||||
@@ -219,291 +384,29 @@ static void completion_print( int cols,
|
||||
|
||||
int rows = (al_get_count( l )-1)/cols+1;
|
||||
int i, j;
|
||||
int prefix_width= my_wcswidth(prefix);
|
||||
|
||||
for( i = row_start; i<row_stop; i++ )
|
||||
{
|
||||
for( j = 0; j < cols; j++ )
|
||||
{
|
||||
wchar_t *el, *el_end;
|
||||
comp_t *el;
|
||||
|
||||
int is_last = (j==(cols-1));
|
||||
|
||||
if( al_get_count( l ) <= j*rows + i )
|
||||
continue;
|
||||
|
||||
el = (wchar_t *)al_get( l, j*rows + i );
|
||||
el_end= wcschr( el, COMPLETE_SEP );
|
||||
|
||||
set_color( get_color(HIGHLIGHT_PAGER_PREFIX),FISH_COLOR_NORMAL );
|
||||
|
||||
writestr( prefix );
|
||||
|
||||
set_color( get_color(HIGHLIGHT_PAGER_COMPLETION),FISH_COLOR_IGNORE );
|
||||
|
||||
if( el_end == 0 )
|
||||
{
|
||||
/* We do not have a description for this completion */
|
||||
int written = 0;
|
||||
int max_written = width[j] - prefix_width - (j==cols-1?0:2);
|
||||
|
||||
if( is_quoted )
|
||||
{
|
||||
for( i=0; i<max_written; i++ )
|
||||
{
|
||||
if( !el[i] )
|
||||
break;
|
||||
writech( el[i] );
|
||||
written+= wcwidth( el[i] );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
written = write_escaped_str( el, max_written );
|
||||
}
|
||||
|
||||
set_color( get_color( HIGHLIGHT_PAGER_DESCRIPTION ),
|
||||
FISH_COLOR_IGNORE );
|
||||
|
||||
writespace( width[j]-
|
||||
written-
|
||||
prefix_width );
|
||||
}
|
||||
else
|
||||
{
|
||||
int whole_desc_width = my_wcswidth(el_end+1);
|
||||
int whole_comp_width;
|
||||
|
||||
/*
|
||||
Temporarily drop the description so that wcswidth et
|
||||
al only calculate the width of the completion.
|
||||
*/
|
||||
*el_end = L'\0';
|
||||
|
||||
/*
|
||||
Calculate preferred completion width
|
||||
*/
|
||||
if( is_quoted )
|
||||
{
|
||||
whole_comp_width = my_wcswidth(el);
|
||||
}
|
||||
else
|
||||
{
|
||||
wchar_t *tmp = escape( el, 1 );
|
||||
whole_comp_width = my_wcswidth( tmp );
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
/*
|
||||
Calculate how wide this entry 'wants' to be
|
||||
*/
|
||||
int pref_width = whole_desc_width + 4 + prefix_width + 2 -
|
||||
(j==cols-1?2:0) + whole_comp_width;
|
||||
|
||||
int comp_width, desc_width;
|
||||
|
||||
if( pref_width <= width[j] )
|
||||
{
|
||||
/*
|
||||
The entry fits, we give it as much space as it wants
|
||||
*/
|
||||
comp_width = whole_comp_width;
|
||||
desc_width = whole_desc_width;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
The completion and description won't fit on the
|
||||
allocated space. Give a maximum of 2/3 of the
|
||||
space to the completion, and whatever is left to
|
||||
the description.
|
||||
*/
|
||||
int sum = width[j] - prefix_width - 4 - 2 + (j==cols-1?2:0);
|
||||
|
||||
comp_width = maxi( mini( whole_comp_width,
|
||||
2*sum/3 ),
|
||||
sum - whole_desc_width );
|
||||
desc_width = sum-comp_width;
|
||||
}
|
||||
|
||||
/* First we must print the completion. */
|
||||
if( is_quoted )
|
||||
{
|
||||
writestr_ellipsis( el, comp_width);
|
||||
}
|
||||
else
|
||||
{
|
||||
write_escaped_str( el, comp_width );
|
||||
}
|
||||
|
||||
/* Put the description back */
|
||||
*el_end = COMPLETE_SEP;
|
||||
|
||||
/* And print it */
|
||||
set_color( get_color(HIGHLIGHT_PAGER_DESCRIPTION),
|
||||
FISH_COLOR_IGNORE );
|
||||
writespace( maxi( 2,
|
||||
width[j]
|
||||
- comp_width
|
||||
- desc_width
|
||||
- 4
|
||||
- prefix_width
|
||||
+ (j==cols-1?2:0) ) );
|
||||
/* Print description */
|
||||
writestr(L"(");
|
||||
writestr_ellipsis( el_end+1, desc_width);
|
||||
writestr(L")");
|
||||
|
||||
if( j != cols-1)
|
||||
writestr( L" " );
|
||||
|
||||
}
|
||||
el = (comp_t *)al_get( l, j*rows + i );
|
||||
|
||||
completion_print_item( prefix, el, width[j] - (is_last?0:2) );
|
||||
|
||||
if( !is_last)
|
||||
writestr( L" " );
|
||||
}
|
||||
writech( L'\n' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Calculates how long the specified string would be when printed on the command line.
|
||||
|
||||
\param str The string to be printed.
|
||||
\param is_quoted Whether the string would be printed quoted or unquoted
|
||||
\param pref_width the preferred width for this item
|
||||
\param min_width the minimum width for this item
|
||||
*/
|
||||
static void printed_length( wchar_t *str,
|
||||
int is_quoted,
|
||||
int *pref_width,
|
||||
int *min_width )
|
||||
{
|
||||
if( is_quoted )
|
||||
{
|
||||
wchar_t *sep = wcschr(str,COMPLETE_SEP);
|
||||
if( sep )
|
||||
{
|
||||
*sep=0;
|
||||
int cw = my_wcswidth( str );
|
||||
int dw = my_wcswidth(sep+1);
|
||||
|
||||
if( termsize.ws_col > 80 )
|
||||
dw = mini( dw, termsize.ws_col/3 );
|
||||
|
||||
|
||||
*pref_width = cw+dw+4;
|
||||
|
||||
if( dw > termsize.ws_col/3 )
|
||||
{
|
||||
dw = termsize.ws_col/3;
|
||||
}
|
||||
|
||||
*min_width=cw+dw+4;
|
||||
|
||||
*sep= COMPLETE_SEP;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pref_width=*min_width= my_wcswidth( str );
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
int comp_len=0, desc_len=0;
|
||||
int has_description = 0;
|
||||
while( *str != 0 )
|
||||
{
|
||||
if( ( *str >= ENCODE_DIRECT_BASE) &&
|
||||
( *str < ENCODE_DIRECT_BASE+256) )
|
||||
{
|
||||
if( has_description )
|
||||
desc_len+=4;
|
||||
else
|
||||
comp_len+=4;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
switch( *str )
|
||||
{
|
||||
case L'\n':
|
||||
case L'\b':
|
||||
case L'\r':
|
||||
case L'\e':
|
||||
case L'\t':
|
||||
case L'\\':
|
||||
case L'&':
|
||||
case L'$':
|
||||
case L' ':
|
||||
case L'#':
|
||||
case L'^':
|
||||
case L'<':
|
||||
case L'>':
|
||||
case L'(':
|
||||
case L')':
|
||||
case L'[':
|
||||
case L']':
|
||||
case L'{':
|
||||
case L'}':
|
||||
case L'?':
|
||||
case L'*':
|
||||
case L'|':
|
||||
case L';':
|
||||
case L':':
|
||||
case L'\'':
|
||||
case L'"':
|
||||
case L'%':
|
||||
case L'~':
|
||||
|
||||
if( has_description )
|
||||
desc_len++;
|
||||
else
|
||||
comp_len+=2;
|
||||
break;
|
||||
|
||||
case COMPLETE_SEP:
|
||||
has_description = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
if( has_description )
|
||||
desc_len+= wcwidth(*str);
|
||||
else
|
||||
comp_len+= wcwidth(*str);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
str++;
|
||||
}
|
||||
if( has_description )
|
||||
{
|
||||
/*
|
||||
Mangle long descriptions to make formating look nicer
|
||||
*/
|
||||
debug( 3, L"Desc, width = %d %d\n", comp_len, desc_len );
|
||||
// if( termsize.ws_col > 80 )
|
||||
// desc_len = mini( desc_len, termsize.ws_col/3 );
|
||||
|
||||
*pref_width = comp_len+ desc_len+4;;
|
||||
|
||||
comp_len = mini( comp_len, maxi(0,termsize.ws_col/3 - 2));
|
||||
desc_len = mini( desc_len, maxi(0,termsize.ws_col/5 - 4));
|
||||
|
||||
*min_width = comp_len+ desc_len+4;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
debug( 3, L"No desc, width = %d\n", comp_len );
|
||||
|
||||
*pref_width=*min_width= comp_len;
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Try to print the list of completions l with the prefix prefix using
|
||||
@@ -551,8 +454,6 @@ static int completion_try_print( int cols,
|
||||
|
||||
int pref_tot_width=0;
|
||||
int min_tot_width = 0;
|
||||
int prefix_width = my_wcswidth( prefix );
|
||||
|
||||
int res=0;
|
||||
/*
|
||||
Skip completions on tiny terminals
|
||||
@@ -560,25 +461,24 @@ static int completion_try_print( int cols,
|
||||
|
||||
if( termsize.ws_col < 16 )
|
||||
return 1;
|
||||
|
||||
|
||||
memset( pref_width, 0, sizeof(pref_width) );
|
||||
memset( min_width, 0, sizeof(min_width) );
|
||||
|
||||
|
||||
/* Calculate how wide the list would be */
|
||||
for( j = 0; j < cols; j++ )
|
||||
{
|
||||
for( i = 0; i<rows; i++ )
|
||||
{
|
||||
int pref,min;
|
||||
wchar_t *el;
|
||||
comp_t *c;
|
||||
if( al_get_count( l ) <= j*rows + i )
|
||||
continue;
|
||||
|
||||
el = (wchar_t *)al_get( l, j*rows + i );
|
||||
printed_length( el, is_quoted, &pref, &min );
|
||||
|
||||
pref += prefix_width;
|
||||
min += prefix_width;
|
||||
c = (comp_t *)al_get( l, j*rows + i );
|
||||
pref = c->pref_width;
|
||||
min = c->min_width;
|
||||
|
||||
if( j != cols-1 )
|
||||
{
|
||||
pref += 2;
|
||||
@@ -660,6 +560,7 @@ static int completion_try_print( int cols,
|
||||
}
|
||||
|
||||
completion_print( cols, width, 0, rows, prefix, is_quoted, l);
|
||||
pager_flush();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -682,16 +583,16 @@ static int completion_try_print( int cols,
|
||||
*/
|
||||
while(do_loop)
|
||||
{
|
||||
wchar_t msg[10];
|
||||
int percent = 100*pos/(rows-termsize.ws_row+1);
|
||||
wchar_t msg[30];
|
||||
int percent = 100*(pos+rows)/(2*rows-termsize.ws_row+1);
|
||||
set_color( FISH_COLOR_BLACK,
|
||||
get_color(HIGHLIGHT_PAGER_PROGRESS) );
|
||||
swprintf( msg, 12,
|
||||
L" %ls(%d%%) \r",
|
||||
percent==100?L"":(percent >=10?L" ": L" "),
|
||||
percent );
|
||||
swprintf( msg, 30,
|
||||
L" %d to %d of %d \r",
|
||||
pos, pos+termsize.ws_row-1, rows );
|
||||
writestr(msg);
|
||||
set_color( FISH_COLOR_NORMAL, FISH_COLOR_NORMAL );
|
||||
pager_flush();
|
||||
int c = readch();
|
||||
|
||||
switch( c )
|
||||
@@ -753,7 +654,8 @@ static int completion_try_print( int cols,
|
||||
}
|
||||
else
|
||||
{
|
||||
writembs( flash_screen );
|
||||
if( flash_screen )
|
||||
writembs( flash_screen );
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -777,7 +679,8 @@ static int completion_try_print( int cols,
|
||||
}
|
||||
else
|
||||
{
|
||||
writembs( flash_screen );
|
||||
if( flash_screen )
|
||||
writembs( flash_screen );
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -805,7 +708,9 @@ static int completion_try_print( int cols,
|
||||
}
|
||||
|
||||
/**
|
||||
Substitute any series of tabs, newlines, etc. with a single space character in completion description
|
||||
Substitute any series of whitespace with a single space character
|
||||
inside completion descriptions. Remove all whitespace from
|
||||
beginning/end of completion descriptions.
|
||||
*/
|
||||
static void mangle_descriptions( array_list_t *l )
|
||||
{
|
||||
@@ -843,6 +748,124 @@ static void mangle_descriptions( array_list_t *l )
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Merge multiple completions with the same description to the same line
|
||||
*/
|
||||
static void join_completions( array_list_t *l )
|
||||
{
|
||||
long i;
|
||||
int in, out;
|
||||
hash_table_t desc_table;
|
||||
|
||||
hash_init( &desc_table, &hash_wcs_func, &hash_wcs_cmp );
|
||||
|
||||
for( i=0; i<al_get_count(l); i++ )
|
||||
{
|
||||
wchar_t *item = (wchar_t *)al_get( l, i );
|
||||
wchar_t *desc = wcschr( item, COMPLETE_SEP );
|
||||
long prev_idx;
|
||||
|
||||
if( !desc )
|
||||
continue;
|
||||
desc++;
|
||||
prev_idx = ((long)hash_get( &desc_table, desc) )-1;
|
||||
if( prev_idx == -1 )
|
||||
{
|
||||
hash_put( &desc_table, halloc_wcsdup( global_context, desc), (void *)(i+1));
|
||||
}
|
||||
else
|
||||
{
|
||||
string_buffer_t foo;
|
||||
wchar_t *old = (wchar_t *)al_get( l, prev_idx );
|
||||
wchar_t *old_end = wcschr( old, COMPLETE_SEP );
|
||||
|
||||
if( old_end )
|
||||
{
|
||||
*old_end = 0;
|
||||
|
||||
sb_init( &foo );
|
||||
sb_append( &foo, old );
|
||||
sb_append_char( &foo, COMPLETE_ITEM_SEP );
|
||||
sb_append( &foo, item );
|
||||
|
||||
free( (void *)al_get( l, prev_idx ) );
|
||||
al_set( l, prev_idx, foo.buff );
|
||||
|
||||
free( (void *)al_get( l, i ) );
|
||||
al_set( l, i, 0 );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
hash_destroy( &desc_table );
|
||||
|
||||
out=0;
|
||||
for( in=0; in < al_get_count(l); in++ )
|
||||
{
|
||||
const void * d = al_get( l, in );
|
||||
|
||||
if( d )
|
||||
{
|
||||
al_set( l, out++, d );
|
||||
}
|
||||
}
|
||||
al_truncate( l, out );
|
||||
}
|
||||
|
||||
/**
|
||||
Replace completion strings with a comp_t structure
|
||||
*/
|
||||
static void mangle_completions( array_list_t *l, const wchar_t *prefix )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i=0; i<al_get_count( l ); i++ )
|
||||
{
|
||||
wchar_t *next = (wchar_t *)al_get( l, i );
|
||||
wchar_t *start, *end;
|
||||
comp_t *comp = halloc( global_context, sizeof( comp_t ) );
|
||||
comp->comp = al_halloc( global_context );
|
||||
|
||||
for( start=end=next; 1; end++ )
|
||||
{
|
||||
wchar_t c = *end;
|
||||
|
||||
if( (c == COMPLETE_ITEM_SEP) || (c==COMPLETE_SEP) || !c)
|
||||
{
|
||||
*end = 0;
|
||||
wchar_t * str = escape( start, 1 );
|
||||
comp->comp_width += my_wcswidth( str );
|
||||
halloc_register( global_context, str );
|
||||
al_push( comp->comp, str );
|
||||
start = end+1;
|
||||
}
|
||||
|
||||
if( c == COMPLETE_SEP )
|
||||
{
|
||||
comp->desc = halloc_wcsdup( global_context, start );
|
||||
break;
|
||||
}
|
||||
|
||||
if( !c )
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
comp->comp_width += my_wcswidth(prefix)*al_get_count(comp->comp) + 2*(al_get_count(comp->comp)-1);
|
||||
comp->desc_width = comp->desc?my_wcswidth( comp->desc ):0;
|
||||
|
||||
comp->pref_width = comp->comp_width + comp->desc_width + (comp->desc_width?4:0);
|
||||
|
||||
free( next );
|
||||
al_set( l, i, comp );
|
||||
}
|
||||
|
||||
recalc_width( l, prefix );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Respond to a winch signal by checking the terminal size
|
||||
*/
|
||||
@@ -871,15 +894,29 @@ static void init()
|
||||
the resulting output back to the caller
|
||||
*/
|
||||
int out = dup( 1 );
|
||||
int in = dup( 0 );
|
||||
close(1);
|
||||
if( open( ttyname(0), O_WRONLY ) != 1 )
|
||||
close(0);
|
||||
|
||||
if( (in = open( ttyname(2), O_RDWR )) != -1 )
|
||||
{
|
||||
if( dup2( 2, 1 ) == -1 )
|
||||
{
|
||||
debug( 0, L"Could not set up file descriptors for pager" );
|
||||
debug( 0, L"Could not set up output file descriptors for pager" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
if( dup2( in, 0 ) == -1 )
|
||||
{
|
||||
debug( 0, L"Could not set up input file descriptors for pager %d", in );
|
||||
exit( 1 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
debug( 0, L"Could not open tty for pager" );
|
||||
exit( 1 );
|
||||
}
|
||||
out_file = fdopen( out, "w" );
|
||||
|
||||
/**
|
||||
@@ -887,10 +924,13 @@ static void init()
|
||||
*/
|
||||
sb_init( &out_buff );
|
||||
|
||||
output_init();
|
||||
halloc_util_init();
|
||||
env_universal_init( 0, 0, 0, 0);
|
||||
input_common_init( &interrupt_handler );
|
||||
|
||||
output_set_writer( &pager_buffered_writer );
|
||||
pager_buffer = halloc( global_context, sizeof( buffer_t ) );
|
||||
halloc_register_function( global_context, (void (*)(void *))&b_destroy, pager_buffer );
|
||||
|
||||
sigemptyset( & act.sa_mask );
|
||||
act.sa_flags=0;
|
||||
act.sa_handler=SIG_DFL;
|
||||
@@ -903,7 +943,7 @@ static void init()
|
||||
}
|
||||
|
||||
handle_winch( 0 ); /* Set handler for window change events */
|
||||
|
||||
|
||||
tcgetattr(0,&pager_modes); /* get the current terminal modes */
|
||||
memcpy( &saved_modes,
|
||||
&pager_modes,
|
||||
@@ -914,6 +954,9 @@ static void init()
|
||||
pager_modes.c_cc[VMIN]=1;
|
||||
pager_modes.c_cc[VTIME]=0;
|
||||
|
||||
/*
|
||||
|
||||
*/
|
||||
if( tcsetattr(0,TCSANOW,&pager_modes)) /* set the new modes */
|
||||
{
|
||||
wperror(L"tcsetattr");
|
||||
@@ -932,49 +975,102 @@ void destroy()
|
||||
{
|
||||
env_universal_destroy();
|
||||
input_common_destroy();
|
||||
output_destroy();
|
||||
del_curterm( cur_term );
|
||||
halloc_util_destroy();
|
||||
if( del_curterm( cur_term ) == ERR )
|
||||
{
|
||||
debug( 0, _(L"Error while closing terminfo") );
|
||||
}
|
||||
|
||||
sb_destroy( &out_buff );
|
||||
fclose( out_file );
|
||||
}
|
||||
|
||||
#define BUFSIZE 1024
|
||||
void read_array( FILE* file, array_list_t *comp )
|
||||
{
|
||||
char buffer[BUFSIZE];
|
||||
int c;
|
||||
int i;
|
||||
wchar_t *wcs, *unescaped;
|
||||
|
||||
while( !feof( file ) )
|
||||
{
|
||||
i = 0;
|
||||
while( i < BUFSIZE-1 )
|
||||
{
|
||||
c = getc( file );
|
||||
if( c == EOF )
|
||||
{
|
||||
return;
|
||||
|
||||
}
|
||||
if( c == '\n' )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
buffer[ i++ ] = c;
|
||||
}
|
||||
|
||||
buffer[ i ] = '\0';
|
||||
|
||||
wcs = str2wcs( buffer );
|
||||
if( wcs )
|
||||
{
|
||||
unescaped = unescape( wcs, 0 );
|
||||
al_push( comp, unescaped );
|
||||
free( wcs );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
int i;
|
||||
int is_quoted=0;
|
||||
array_list_t comp;
|
||||
array_list_t *comp;
|
||||
wchar_t *prefix;
|
||||
|
||||
|
||||
init();
|
||||
if( argc < 3 )
|
||||
{
|
||||
debug( 0, L"Insufficient arguments" );
|
||||
}
|
||||
else
|
||||
{
|
||||
comp = al_halloc( global_context );
|
||||
prefix = str2wcs( argv[2] );
|
||||
is_quoted = strcmp( "1", argv[1] )==0;
|
||||
|
||||
is_quoted = 0;
|
||||
|
||||
debug( 3, L"prefix is '%ls'", prefix );
|
||||
|
||||
al_init( &comp );
|
||||
|
||||
for( i=3; i<argc; i++ )
|
||||
|
||||
if( argc > 3 )
|
||||
{
|
||||
wchar_t *wcs = str2wcs( argv[i] );
|
||||
if( wcs )
|
||||
for( i=3; i<argc; i++ )
|
||||
{
|
||||
al_push( &comp, wcs );
|
||||
wchar_t *wcs = str2wcs( argv[i] );
|
||||
if( wcs )
|
||||
{
|
||||
al_push( comp, wcs );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mangle_descriptions( &comp );
|
||||
else
|
||||
{
|
||||
read_array( stdin, comp );
|
||||
}
|
||||
|
||||
|
||||
init();
|
||||
|
||||
mangle_descriptions( comp );
|
||||
if( wcscmp( prefix, L"-" ) == 0 )
|
||||
join_completions( comp );
|
||||
mangle_completions( comp, prefix );
|
||||
|
||||
for( i = 6; i>0; i-- )
|
||||
{
|
||||
switch( completion_try_print( i, prefix, is_quoted, &comp ) )
|
||||
switch( completion_try_print( i, prefix, is_quoted, comp ) )
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
@@ -988,15 +1084,16 @@ int main( int argc, char **argv )
|
||||
|
||||
}
|
||||
|
||||
al_foreach( &comp, (void(*)(const void *))&free );
|
||||
al_destroy( &comp );
|
||||
free(prefix );
|
||||
|
||||
fwprintf( out_file, L"%ls", (wchar_t *)out_buff.buff );
|
||||
if( is_ca_mode )
|
||||
{
|
||||
writembs(exit_ca_mode);
|
||||
pager_flush();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
destroy();
|
||||
}
|
||||
|
||||
|
||||
94
fish_tests.c
94
fish_tests.c
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <wchar.h>
|
||||
@@ -26,7 +27,9 @@
|
||||
#include <locale.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#include "fallback.h"
|
||||
#include "util.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "proc.h"
|
||||
#include "reader.h"
|
||||
@@ -41,12 +44,18 @@
|
||||
#include "output.h"
|
||||
#include "exec.h"
|
||||
#include "event.h"
|
||||
#include "halloc_util.h"
|
||||
|
||||
/**
|
||||
Number of laps to run performance testing loop
|
||||
*/
|
||||
#define LAPS 50
|
||||
|
||||
/**
|
||||
The result of one of the test passes
|
||||
*/
|
||||
#define NUM_ANS L"-7 99999999 1234567 deadbeef DEADBEEFDEADBEEF"
|
||||
|
||||
/**
|
||||
Number of encountered errors
|
||||
*/
|
||||
@@ -98,7 +107,7 @@ static int pq_compare( void *e1, void *e2 )
|
||||
/**
|
||||
Test priority queue functionality
|
||||
*/
|
||||
static int pq_test( int elements )
|
||||
static void pq_test( int elements )
|
||||
{
|
||||
int i;
|
||||
int prev;
|
||||
@@ -143,7 +152,7 @@ static int pq_test( int elements )
|
||||
*/
|
||||
static int stack_test( int elements )
|
||||
{
|
||||
int i;
|
||||
long i;
|
||||
|
||||
int res=1;
|
||||
|
||||
@@ -153,12 +162,12 @@ static int stack_test( int elements )
|
||||
|
||||
for( i=0; i<elements; i++ )
|
||||
{
|
||||
int foo;
|
||||
long foo;
|
||||
|
||||
al_push( &s, (void*)i);
|
||||
al_push( &s, (void*)i);
|
||||
al_push_long( &s, i);
|
||||
al_push_long( &s, i);
|
||||
|
||||
if( (foo=(int)al_pop( &s )) != i )
|
||||
if( (foo=al_pop_long( &s )) != i )
|
||||
{
|
||||
err( L"Unexpected data" );
|
||||
res = 0;
|
||||
@@ -168,16 +177,14 @@ static int stack_test( int elements )
|
||||
|
||||
for( i=0; i<elements; i++ )
|
||||
{
|
||||
int foo;
|
||||
long foo;
|
||||
|
||||
if( (foo=(int)al_pop( &s )) != (elements-i-1) )
|
||||
if( (foo=al_pop_long( &s )) != (elements-i-1) )
|
||||
{
|
||||
err( L"Unexpected data" );
|
||||
res = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -189,7 +196,7 @@ static int stack_test( int elements )
|
||||
/**
|
||||
Hash function for pointers
|
||||
*/
|
||||
static int hash_func( const void *data )
|
||||
static int hash_func( void *data )
|
||||
{
|
||||
/* srand( (int)data );
|
||||
return rand();
|
||||
@@ -201,7 +208,7 @@ static int hash_func( const void *data )
|
||||
/**
|
||||
Pointer hash comparison function
|
||||
*/
|
||||
static int compare_func( const void *key1, const void *key2 )
|
||||
static int compare_func( void *key1, void *key2 )
|
||||
{
|
||||
return key1==key2;
|
||||
}
|
||||
@@ -286,24 +293,24 @@ static int hash_test( int elements )
|
||||
/**
|
||||
Arraylist test
|
||||
*/
|
||||
static int al_test( int sz)
|
||||
static void al_test( int sz)
|
||||
{
|
||||
int i;
|
||||
long i;
|
||||
array_list_t l;
|
||||
|
||||
|
||||
|
||||
al_init( &l );
|
||||
|
||||
al_set( &l, 1, (void *)7 );
|
||||
al_set( &l, sz, (void *)7 );
|
||||
al_set_long( &l, 1, 7L );
|
||||
al_set_long( &l, sz, 7L );
|
||||
|
||||
if( al_get_count( &l ) != maxf( sz+1, 2 ) )
|
||||
if( al_get_count( &l ) != maxi( sz+1, 2 ) )
|
||||
err( L"Wrong number of elements in array list" );
|
||||
|
||||
for( i=0; i<al_get_count( &l ); i++ )
|
||||
{
|
||||
int val = (int)((long) al_get( &l, i ));
|
||||
long val = al_get_long( &l, i );
|
||||
if( (i == 1) || (i==sz))
|
||||
{
|
||||
if( val != 7 )
|
||||
@@ -327,7 +334,7 @@ static void sb_test()
|
||||
|
||||
sb_init( &b );
|
||||
|
||||
if( res=sb_printf( &b, L"%ls%s", L"Testing ", "string_buffer_t " ) == -1 )
|
||||
if( (res=sb_printf( &b, L"%ls%s", L"Testing ", "string_buffer_t " )) == -1 )
|
||||
{
|
||||
err( L"Error %d while testing stringbuffers", res );
|
||||
}
|
||||
@@ -336,7 +343,20 @@ static void sb_test()
|
||||
{
|
||||
err( L"Error %d while testing stringbuffers", res );
|
||||
}
|
||||
|
||||
say( (wchar_t *)b.buff );
|
||||
|
||||
sb_clear( &b );
|
||||
|
||||
sb_printf( &b, L"%d %u %o %x %llX", -7, 99999999, 01234567, 0xdeadbeef, 0xdeadbeefdeadbeefll );
|
||||
if( wcscmp( (wchar_t *)b.buff, NUM_ANS) != 0 )
|
||||
{
|
||||
err( L"numerical formating is broken, '%ls' != '%ls'", (wchar_t *)b.buff, NUM_ANS );
|
||||
}
|
||||
else
|
||||
say( L"numerical formating works" );
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -464,43 +484,43 @@ static void test_parser()
|
||||
|
||||
|
||||
say( L"Testing null input to parser" );
|
||||
if( !parser_test( 0, 0 ) )
|
||||
if( !parser_test( 0, 0, 0 ) )
|
||||
{
|
||||
err( L"Null input to parser_test undetected" );
|
||||
}
|
||||
|
||||
say( L"Testing block nesting" );
|
||||
if( !parser_test( L"if; end", 0 ) )
|
||||
if( !parser_test( L"if; end", 0, 0 ) )
|
||||
{
|
||||
err( L"Incomplete if statement undetected" );
|
||||
}
|
||||
if( !parser_test( L"if test; echo", 0 ) )
|
||||
if( !parser_test( L"if test; echo", 0, 0 ) )
|
||||
{
|
||||
err( L"Missing end undetected" );
|
||||
}
|
||||
if( !parser_test( L"if test; end; end", 0 ) )
|
||||
if( !parser_test( L"if test; end; end", 0, 0 ) )
|
||||
{
|
||||
err( L"Unbalanced end undetected" );
|
||||
}
|
||||
|
||||
say( L"Testing detection of invalid use of builtin commands" );
|
||||
if( !parser_test( L"case foo", 0 ) )
|
||||
if( !parser_test( L"case foo", 0, 0 ) )
|
||||
{
|
||||
err( L"'case' command outside of block context undetected" );
|
||||
}
|
||||
if( !parser_test( L"switch ggg; if true; case foo;end;end", 0 ) )
|
||||
if( !parser_test( L"switch ggg; if true; case foo;end;end", 0, 0 ) )
|
||||
{
|
||||
err( L"'case' command outside of switch block context undetected" );
|
||||
}
|
||||
if( !parser_test( L"else", 0 ) )
|
||||
if( !parser_test( L"else", 0, 0 ) )
|
||||
{
|
||||
err( L"'else' command outside of conditional block context undetected" );
|
||||
}
|
||||
if( !parser_test( L"break", 0 ) )
|
||||
if( !parser_test( L"break", 0, 0 ) )
|
||||
{
|
||||
err( L"'break' command outside of loop block context undetected" );
|
||||
}
|
||||
if( !parser_test( L"exec ls|less", 0 ) || !parser_test( L"echo|return", 0 ))
|
||||
if( !parser_test( L"exec ls|less", 0, 0 ) || !parser_test( L"echo|return", 0, 0 ))
|
||||
{
|
||||
err( L"Invalid pipe command undetected" );
|
||||
}
|
||||
@@ -533,7 +553,7 @@ static int expand_test( const wchar_t *in, int flags, ... )
|
||||
wchar_t *arg;
|
||||
|
||||
al_init( &out );
|
||||
expand_string( wcsdup(in), &out, flags);
|
||||
expand_string( 0, wcsdup(in), &out, flags);
|
||||
|
||||
va_start( va, flags );
|
||||
|
||||
@@ -555,7 +575,7 @@ static int expand_test( const wchar_t *in, int flags, ... )
|
||||
}
|
||||
va_end( va );
|
||||
|
||||
al_foreach( &out, (void (*)(const void *))&free );
|
||||
al_foreach( &out, &free );
|
||||
return res;
|
||||
|
||||
}
|
||||
@@ -620,7 +640,7 @@ void perf_complete()
|
||||
|
||||
matches += al_get_count( &out );
|
||||
|
||||
al_foreach( &out, (void (*)(const void *))&free );
|
||||
al_foreach( &out, &free );
|
||||
al_truncate( &out, 0 );
|
||||
}
|
||||
t2=get_time();
|
||||
@@ -642,7 +662,7 @@ void perf_complete()
|
||||
|
||||
matches += al_get_count( &out );
|
||||
|
||||
al_foreach( &out, (void (*)(const void *))&free );
|
||||
al_foreach( &out, &free );
|
||||
al_truncate( &out, 0 );
|
||||
}
|
||||
t2=get_time();
|
||||
@@ -669,13 +689,11 @@ int main( int argc, char **argv )
|
||||
say( L"Lines beginning with '(ignore):' are not errors, they are warning messages\ngenerated by the fish parser library when given broken input, and can be\nignored. All actual errors begin with 'Error:'." );
|
||||
|
||||
proc_init();
|
||||
output_init();
|
||||
halloc_util_init();
|
||||
event_init();
|
||||
exec_init();
|
||||
parser_init();
|
||||
function_init();
|
||||
builtin_init();
|
||||
complete_init();
|
||||
reader_init();
|
||||
env_init();
|
||||
|
||||
@@ -697,11 +715,9 @@ int main( int argc, char **argv )
|
||||
parser_destroy();
|
||||
function_destroy();
|
||||
builtin_destroy();
|
||||
complete_destroy();
|
||||
wutil_destroy();
|
||||
exec_destroy();
|
||||
event_destroy();
|
||||
output_destroy();
|
||||
proc_destroy();
|
||||
halloc_util_destroy();
|
||||
|
||||
}
|
||||
|
||||
41
fishd.c
41
fishd.c
@@ -6,7 +6,7 @@ variables from ~/.fishd, and takes care of communication between fish
|
||||
instances. When no clients are running, fishd will automatically shut
|
||||
down and save.
|
||||
|
||||
\subsection fishd-commands Commands
|
||||
\section fishd-commands Commands
|
||||
|
||||
Fishd works by sending and receiving commands. Each command is ended
|
||||
with a newline. These are the commands supported by fishd:
|
||||
@@ -41,6 +41,7 @@ time the original barrier request was sent have been received.
|
||||
|
||||
#include "config.h"
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
@@ -61,7 +62,9 @@ time the original barrier request was sent have been received.
|
||||
#include <locale.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "fallback.h"
|
||||
#include "util.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "wutil.h"
|
||||
#include "env_universal_common.h"
|
||||
@@ -85,7 +88,12 @@ time the original barrier request was sent have been received.
|
||||
/**
|
||||
Small greeting to show that fishd is running
|
||||
*/
|
||||
#define GREETING "#Fish universal variable daemon\n"
|
||||
#define GREETING "# Fish universal variable daemon\n"
|
||||
|
||||
/**
|
||||
Small not about not editing ~/.fishd manually. Inserted at the top of all .fishd files.
|
||||
*/
|
||||
#define SAVE_MSG "# This file is automatically generated by the fishd universal variable daemon.\n# Do NOT edit it directly, your changes will be overwritten.\n"
|
||||
|
||||
/**
|
||||
The name of the save file. The hostname is appended to this.
|
||||
@@ -107,6 +115,11 @@ time the original barrier request was sent have been received.
|
||||
*/
|
||||
#define LOCKTIMEOUT 1
|
||||
|
||||
/**
|
||||
Getopt short switches for fishd
|
||||
*/
|
||||
#define GETOPT_STRING "hv"
|
||||
|
||||
/**
|
||||
The list of connections to clients
|
||||
*/
|
||||
@@ -222,7 +235,7 @@ static int get_socket()
|
||||
debug( 0, L"Unable to obtain lock on socket, exiting" );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
debug( 1, L"Acquired lockfile: %s", lockfile );
|
||||
debug( 4, L"Acquired lockfile: %s", lockfile );
|
||||
|
||||
local.sun_family = AF_UNIX;
|
||||
strcpy( local.sun_path, sock_name );
|
||||
@@ -270,7 +283,7 @@ static int get_socket()
|
||||
|
||||
unlock:
|
||||
(void)unlink( lockfile );
|
||||
debug( 1, L"Released lockfile: %s", lockfile );
|
||||
debug( 4, L"Released lockfile: %s", lockfile );
|
||||
/*
|
||||
End critical section protected by lock
|
||||
*/
|
||||
@@ -398,7 +411,7 @@ void load_or_save( int save)
|
||||
strcat( name, FILE );
|
||||
strcat( name, hostname );
|
||||
|
||||
debug( 1, L"Open file for %s: '%s'",
|
||||
debug( 4, L"Open file for %s: '%s'",
|
||||
save?"saving":"loading",
|
||||
name );
|
||||
|
||||
@@ -411,14 +424,18 @@ void load_or_save( int save)
|
||||
wperror( L"open" );
|
||||
return;
|
||||
}
|
||||
debug( 1, L"File open on fd %d", c.fd );
|
||||
debug( 4, L"File open on fd %d", c.fd );
|
||||
|
||||
sb_init( &c.input );
|
||||
memset (&c.wstate, '\0', sizeof (mbstate_t));
|
||||
q_init( &c.unsent );
|
||||
|
||||
if( save )
|
||||
{
|
||||
|
||||
write( c.fd, SAVE_MSG, strlen(SAVE_MSG) );
|
||||
enqueue_all( &c );
|
||||
}
|
||||
else
|
||||
read_message( &c );
|
||||
|
||||
@@ -477,7 +494,6 @@ int main( int argc, char ** argv )
|
||||
*/
|
||||
while( 1 )
|
||||
{
|
||||
#ifdef HAVE_GETOPT_LONG
|
||||
static struct option
|
||||
long_options[] =
|
||||
{
|
||||
@@ -499,15 +515,10 @@ int main( int argc, char ** argv )
|
||||
|
||||
int opt = getopt_long( argc,
|
||||
argv,
|
||||
"hv",
|
||||
GETOPT_STRING,
|
||||
long_options,
|
||||
&opt_index );
|
||||
|
||||
#else
|
||||
int opt = getopt( argc,
|
||||
argv,
|
||||
"hv" );
|
||||
#endif
|
||||
if( opt == -1 )
|
||||
break;
|
||||
|
||||
@@ -584,7 +595,7 @@ int main( int argc, char ** argv )
|
||||
}
|
||||
else
|
||||
{
|
||||
debug( 1, L"Connected with new child on fd %d", child_socket );
|
||||
debug( 4, L"Connected with new child on fd %d", child_socket );
|
||||
|
||||
if( fcntl( child_socket, F_SETFL, O_NONBLOCK ) != 0 )
|
||||
{
|
||||
@@ -641,7 +652,7 @@ int main( int argc, char ** argv )
|
||||
{
|
||||
if( c->killme )
|
||||
{
|
||||
debug( 1, L"Close connection %d", c->fd );
|
||||
debug( 4, L"Close connection %d", c->fd );
|
||||
|
||||
close(c->fd );
|
||||
sb_destroy( &c->input );
|
||||
|
||||
233
function.c
233
function.c
@@ -1,6 +1,9 @@
|
||||
/** \file function.c
|
||||
Functions for storing and retrieving function information.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <wchar.h>
|
||||
@@ -8,9 +11,10 @@
|
||||
#include <termios.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "wutil.h"
|
||||
#include "fallback.h"
|
||||
#include "util.h"
|
||||
|
||||
#include "function.h"
|
||||
#include "proc.h"
|
||||
#include "parser.h"
|
||||
@@ -19,6 +23,8 @@
|
||||
#include "event.h"
|
||||
#include "reader.h"
|
||||
#include "parse_util.h"
|
||||
#include "env.h"
|
||||
#include "expand.h"
|
||||
|
||||
|
||||
/**
|
||||
@@ -30,9 +36,23 @@ typedef struct
|
||||
wchar_t *cmd;
|
||||
/** Function description */
|
||||
wchar_t *desc;
|
||||
/**
|
||||
File where this function was defined
|
||||
*/
|
||||
const wchar_t *definition_file;
|
||||
/**
|
||||
Line where definition started
|
||||
*/
|
||||
int definition_offset;
|
||||
/**
|
||||
Flag for specifying functions which are actually key bindings
|
||||
*/
|
||||
int is_binding;
|
||||
|
||||
/**
|
||||
Flag for specifying that this function was automatically loaded
|
||||
*/
|
||||
int is_autoload;
|
||||
}
|
||||
function_data_t;
|
||||
|
||||
@@ -41,11 +61,90 @@ typedef struct
|
||||
*/
|
||||
static hash_table_t function;
|
||||
|
||||
/**
|
||||
Kludgy flag set by the load function in order to tell function_add
|
||||
that the function being defined is autoloaded. There should be a
|
||||
better way to do this...
|
||||
*/
|
||||
static int is_autoload = 0;
|
||||
|
||||
/**
|
||||
Make sure that if the specified function is a dynamically loaded
|
||||
function, it has been fully loaded.
|
||||
*/
|
||||
static int load( const wchar_t *name )
|
||||
{
|
||||
int was_autoload = is_autoload;
|
||||
int res;
|
||||
function_data_t *data;
|
||||
data = (function_data_t *)hash_get( &function, name );
|
||||
if( data && !data->is_autoload )
|
||||
return 0;
|
||||
|
||||
is_autoload = 1;
|
||||
res = parse_util_load( name,
|
||||
L"fish_function_path",
|
||||
&function_remove,
|
||||
1 );
|
||||
is_autoload = was_autoload;
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
Insert a list of all dynamically loaded functions into the
|
||||
specified list.
|
||||
*/
|
||||
static void autoload_names( array_list_t *out, int get_hidden )
|
||||
{
|
||||
int i;
|
||||
|
||||
array_list_t path_list;
|
||||
const wchar_t *path_var = env_get( L"fish_function_path" );
|
||||
|
||||
if( ! path_var )
|
||||
return;
|
||||
|
||||
al_init( &path_list );
|
||||
|
||||
tokenize_variable_array( path_var, &path_list );
|
||||
for( i=0; i<al_get_count( &path_list ); i++ )
|
||||
{
|
||||
wchar_t *ndir = (wchar_t *)al_get( &path_list, i );
|
||||
DIR *dir = wopendir( ndir );
|
||||
if( !dir )
|
||||
continue;
|
||||
|
||||
struct wdirent *next;
|
||||
while( (next=wreaddir(dir))!=0 )
|
||||
{
|
||||
wchar_t *fn = next->d_name;
|
||||
wchar_t *suffix;
|
||||
if( !get_hidden && fn[0] == L'_' )
|
||||
continue;
|
||||
|
||||
suffix = wcsrchr( fn, L'.' );
|
||||
if( suffix && (wcscmp( suffix, L".fish" ) == 0 ) )
|
||||
{
|
||||
const wchar_t *dup;
|
||||
*suffix = 0;
|
||||
dup = intern( fn );
|
||||
if( !dup )
|
||||
DIE_MEM();
|
||||
al_push( out, dup );
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
}
|
||||
al_foreach( &path_list, &free );
|
||||
al_destroy( &path_list );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Free all contents of an entry to the function hash table
|
||||
*/
|
||||
static void clear_function_entry( const void *key,
|
||||
const void *data )
|
||||
static void clear_function_entry( void *key,
|
||||
void *data )
|
||||
{
|
||||
function_data_t *d = (function_data_t *)data;
|
||||
free( (void *)d->cmd );
|
||||
@@ -77,10 +176,13 @@ void function_add( const wchar_t *name,
|
||||
wchar_t *cmd_end;
|
||||
function_data_t *d;
|
||||
|
||||
CHECK( name, );
|
||||
CHECK( val, );
|
||||
|
||||
function_remove( name );
|
||||
|
||||
d = malloc( sizeof( function_data_t ) );
|
||||
d->definition_offset = parse_util_lineno( parser_get_buffer(), current_block->tok_pos );
|
||||
d->definition_offset = parse_util_lineno( parser_get_buffer(), current_block->tok_pos )-1;
|
||||
d->cmd = wcsdup( val );
|
||||
|
||||
cmd_end = d->cmd + wcslen(d->cmd)-1;
|
||||
@@ -92,7 +194,8 @@ void function_add( const wchar_t *name,
|
||||
d->desc = desc?wcsdup( desc ):0;
|
||||
d->is_binding = is_binding;
|
||||
d->definition_file = intern(reader_current_filename());
|
||||
|
||||
d->is_autoload = is_autoload;
|
||||
|
||||
hash_put( &function, intern(name), d );
|
||||
|
||||
for( i=0; i<al_get_count( events ); i++ )
|
||||
@@ -104,20 +207,32 @@ void function_add( const wchar_t *name,
|
||||
|
||||
int function_exists( const wchar_t *cmd )
|
||||
{
|
||||
|
||||
CHECK( cmd, 0 );
|
||||
|
||||
if( parser_is_reserved(cmd) )
|
||||
return 0;
|
||||
|
||||
load( cmd );
|
||||
return (hash_get(&function, cmd) != 0 );
|
||||
}
|
||||
|
||||
void function_remove( const wchar_t *name )
|
||||
{
|
||||
void *key;
|
||||
void *dv;
|
||||
function_data_t *d;
|
||||
event_t ev;
|
||||
|
||||
CHECK( name, );
|
||||
|
||||
hash_remove( &function,
|
||||
name,
|
||||
(const void **) &key,
|
||||
(const void **)&d );
|
||||
&key,
|
||||
&dv );
|
||||
|
||||
d=(function_data_t *)dv;
|
||||
|
||||
if( !key )
|
||||
return;
|
||||
|
||||
@@ -126,12 +241,26 @@ void function_remove( const wchar_t *name )
|
||||
event_remove( &ev );
|
||||
|
||||
clear_function_entry( key, d );
|
||||
|
||||
/*
|
||||
Notify the autoloader that the specified function is erased, but
|
||||
only if this call to fish_remove is not made by the autoloader
|
||||
itself.
|
||||
*/
|
||||
if( !is_autoload )
|
||||
{
|
||||
parse_util_unload( name, L"fish_function_path", 0 );
|
||||
}
|
||||
}
|
||||
|
||||
const wchar_t *function_get_definition( const wchar_t *argv )
|
||||
{
|
||||
function_data_t *data =
|
||||
(function_data_t *)hash_get( &function, argv );
|
||||
function_data_t *data;
|
||||
|
||||
CHECK( argv, 0 );
|
||||
|
||||
load( argv );
|
||||
data = (function_data_t *)hash_get( &function, argv );
|
||||
if( data == 0 )
|
||||
return 0;
|
||||
return data->cmd;
|
||||
@@ -139,51 +268,105 @@ const wchar_t *function_get_definition( const wchar_t *argv )
|
||||
|
||||
const wchar_t *function_get_desc( const wchar_t *argv )
|
||||
{
|
||||
function_data_t *data =
|
||||
(function_data_t *)hash_get( &function, argv );
|
||||
function_data_t *data;
|
||||
|
||||
CHECK( argv, 0 );
|
||||
|
||||
load( argv );
|
||||
data = (function_data_t *)hash_get( &function, argv );
|
||||
if( data == 0 )
|
||||
return 0;
|
||||
|
||||
return data->desc;
|
||||
return _(data->desc);
|
||||
}
|
||||
|
||||
void function_set_desc( const wchar_t *name, const wchar_t *desc )
|
||||
{
|
||||
function_data_t *data =
|
||||
(function_data_t *)hash_get( &function, name );
|
||||
function_data_t *data;
|
||||
|
||||
CHECK( name, );
|
||||
CHECK( desc, );
|
||||
|
||||
load( name );
|
||||
data = (function_data_t *)hash_get( &function, name );
|
||||
if( data == 0 )
|
||||
return;
|
||||
|
||||
data->desc =wcsdup(desc);
|
||||
}
|
||||
|
||||
/**
|
||||
Search arraylist of strings for specified string
|
||||
*/
|
||||
static int al_contains_str( array_list_t *list, const wchar_t * str )
|
||||
{
|
||||
int i;
|
||||
for( i=0; i<al_get_count( list ); i++ )
|
||||
{
|
||||
if( wcscmp( al_get( list, i ), str) == 0 )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
Helper function for removing hidden functions
|
||||
*/
|
||||
static void get_names_internal( const void *key,
|
||||
const void *val,
|
||||
static void get_names_internal( void *key,
|
||||
void *val,
|
||||
void *aux )
|
||||
{
|
||||
wchar_t *name = (wchar_t *)key;
|
||||
function_data_t *f = (function_data_t *)val;
|
||||
|
||||
if( name[0] != L'_' && !f->is_binding)
|
||||
if( name[0] != L'_' && !f->is_binding && !al_contains_str( (array_list_t *)aux, name ) )
|
||||
{
|
||||
al_push( (array_list_t *)aux, name );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Helper function for removing hidden functions
|
||||
*/
|
||||
static void get_names_internal_all( void *key,
|
||||
void *val,
|
||||
void *aux )
|
||||
{
|
||||
wchar_t *name = (wchar_t *)key;
|
||||
|
||||
if( !al_contains_str( (array_list_t *)aux, name ) )
|
||||
{
|
||||
al_push( (array_list_t *)aux, name );
|
||||
}
|
||||
}
|
||||
|
||||
void function_get_names( array_list_t *list, int get_hidden )
|
||||
{
|
||||
CHECK( list, );
|
||||
|
||||
autoload_names( list, get_hidden );
|
||||
|
||||
if( get_hidden )
|
||||
hash_get_keys( &function, list );
|
||||
{
|
||||
hash_foreach2( &function, &get_names_internal_all, list );
|
||||
}
|
||||
else
|
||||
{
|
||||
hash_foreach2( &function, &get_names_internal, list );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const wchar_t *function_get_definition_file( const wchar_t *argv )
|
||||
{
|
||||
function_data_t *data =
|
||||
(function_data_t *)hash_get( &function, argv );
|
||||
function_data_t *data;
|
||||
|
||||
CHECK( argv, 0 );
|
||||
|
||||
load( argv );
|
||||
data = (function_data_t *)hash_get( &function, argv );
|
||||
if( data == 0 )
|
||||
return 0;
|
||||
|
||||
@@ -193,13 +376,15 @@ const wchar_t *function_get_definition_file( const wchar_t *argv )
|
||||
|
||||
int function_get_definition_offset( const wchar_t *argv )
|
||||
{
|
||||
function_data_t *data =
|
||||
(function_data_t *)hash_get( &function, argv );
|
||||
function_data_t *data;
|
||||
|
||||
CHECK( argv, -1 );
|
||||
|
||||
load( argv );
|
||||
data = (function_data_t *)hash_get( &function, argv );
|
||||
if( data == 0 )
|
||||
return -1;
|
||||
|
||||
return data->definition_offset;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -69,8 +69,15 @@ int function_exists( const wchar_t *name );
|
||||
void function_get_names( array_list_t *list,
|
||||
int get_hidden );
|
||||
|
||||
/**
|
||||
Returns tha absolute path of the file where the specified function
|
||||
was defined. Returns 0 if the file was defined on the commandline.
|
||||
*/
|
||||
const wchar_t *function_get_definition_file( const wchar_t *name );
|
||||
|
||||
/**
|
||||
Returns the linenumber where the definition of the specified function started
|
||||
*/
|
||||
int function_get_definition_offset( const wchar_t *name );
|
||||
|
||||
#endif
|
||||
|
||||
220
halloc.c
220
halloc.c
@@ -8,71 +8,221 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "fallback.h"
|
||||
#include "util.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "halloc.h"
|
||||
|
||||
/**
|
||||
Extra size to allocate whenever doing a halloc, in order to fill uyp smaller halloc calls
|
||||
*/
|
||||
#define HALLOC_BLOCK_SIZE 128
|
||||
|
||||
/**
|
||||
Maximum size of trailing halloc space to refuse to discard
|
||||
*/
|
||||
#define HALLOC_SCRAP_SIZE 16
|
||||
|
||||
#ifdef HALLOC_DEBUG
|
||||
/**
|
||||
Debug statistic parameter
|
||||
*/
|
||||
static int child_count=0;
|
||||
/**
|
||||
Debug statistic parameter
|
||||
*/
|
||||
static int child_size=0;
|
||||
/**
|
||||
Debug statistic parameter
|
||||
*/
|
||||
static int alloc_count =0;
|
||||
/**
|
||||
Debug statistic parameter
|
||||
*/
|
||||
static int alloc_spill = 0;
|
||||
/**
|
||||
Debug statistic parameter
|
||||
*/
|
||||
static pid_t pid=0;
|
||||
/**
|
||||
Debug statistic parameter
|
||||
*/
|
||||
static int parent_count=0;
|
||||
#endif
|
||||
|
||||
/**
|
||||
The main datastructure for a main halloc context
|
||||
*/
|
||||
typedef struct halloc
|
||||
{
|
||||
/**
|
||||
List of all addresses and functions to call on them
|
||||
*/
|
||||
array_list_t children;
|
||||
array_list_t hchildren;
|
||||
long long data[0];
|
||||
/**
|
||||
Memory scratch area used to fullfil smaller memory allocations
|
||||
*/
|
||||
void *scratch;
|
||||
/**
|
||||
Amount of free space in the scratch area
|
||||
*/
|
||||
size_t scratch_free;
|
||||
#if __STDC_VERSION__ < 199901L
|
||||
/**
|
||||
The actual data. Made to be of type long long to make sure memory alignment is in order.
|
||||
*/
|
||||
long long data[1]; // Waste one byte on non-C99 compilers... :-(
|
||||
#else
|
||||
long long data[];
|
||||
#endif
|
||||
}
|
||||
halloc_t;
|
||||
|
||||
/**
|
||||
Get the offset of the halloc structure before a data block
|
||||
*/
|
||||
static halloc_t *halloc_from_data( void *data )
|
||||
{
|
||||
return (halloc_t *)(data - sizeof( halloc_t ) );
|
||||
return (halloc_t *)(((char *)data) - sizeof( halloc_t ) );
|
||||
}
|
||||
|
||||
/**
|
||||
A function that does nothing
|
||||
*/
|
||||
static void late_free( void *data)
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef HALLOC_DEBUG
|
||||
/**
|
||||
Debug function, called at exit when in debug mode. Prints usage
|
||||
statistics, like number of allocations and number of internal calls
|
||||
to malloc.
|
||||
*/
|
||||
static void woot()
|
||||
{
|
||||
if( getpid() == pid )
|
||||
{
|
||||
debug( 1, L"%d parents, %d children with average child size of %.2f bytes caused %d allocs, average spill of %.2f bytes",
|
||||
parent_count, child_count, (double)child_size/child_count,
|
||||
parent_count+alloc_count, (double)alloc_spill/(parent_count+alloc_count) );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void *halloc( void *context, size_t size )
|
||||
{
|
||||
|
||||
{
|
||||
halloc_t *me, *parent;
|
||||
|
||||
me = (halloc_t *)calloc( 1, sizeof(halloc_t) + size );
|
||||
|
||||
if( !me )
|
||||
return 0;
|
||||
|
||||
al_init( &me->children );
|
||||
|
||||
if( context )
|
||||
{
|
||||
parent = halloc_from_data( context );
|
||||
al_push( &parent->hchildren, &me->data );
|
||||
}
|
||||
{
|
||||
void *res;
|
||||
|
||||
return &me->data;
|
||||
}
|
||||
#ifdef HALLOC_DEBUG
|
||||
|
||||
if( !child_count )
|
||||
{
|
||||
pid = getpid();
|
||||
atexit( woot );
|
||||
}
|
||||
|
||||
child_count++;
|
||||
child_size += size;
|
||||
#endif
|
||||
parent = halloc_from_data( context );
|
||||
if( size <= parent->scratch_free )
|
||||
{
|
||||
res = parent->scratch;
|
||||
parent->scratch_free -= size;
|
||||
parent->scratch = ((char *)parent->scratch)+size;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
void *halloc_register( void *context, void *data )
|
||||
{
|
||||
halloc_t *me;
|
||||
if( !context )
|
||||
return data;
|
||||
#ifdef HALLOC_DEBUG
|
||||
alloc_count++;
|
||||
#endif
|
||||
|
||||
if( parent->scratch_free < HALLOC_SCRAP_SIZE )
|
||||
{
|
||||
#ifdef HALLOC_DEBUG
|
||||
alloc_spill += parent->scratch_free;
|
||||
#endif
|
||||
res = calloc( 1, size + HALLOC_BLOCK_SIZE );
|
||||
parent->scratch = (char *)res + size;
|
||||
parent->scratch_free = HALLOC_BLOCK_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
res = calloc( 1, size );
|
||||
}
|
||||
al_push( &parent->children, &late_free );
|
||||
al_push( &parent->children, res );
|
||||
|
||||
}
|
||||
return res;
|
||||
|
||||
me = halloc_from_data( context );
|
||||
al_push( &me->children, data );
|
||||
return data;
|
||||
}
|
||||
else
|
||||
{
|
||||
me = (halloc_t *)calloc( 1, sizeof(halloc_t) + size + HALLOC_BLOCK_SIZE );
|
||||
|
||||
if( !me )
|
||||
return 0;
|
||||
#ifdef HALLOC_DEBUG
|
||||
parent_count++;
|
||||
#endif
|
||||
me->scratch = ((char *)me) + sizeof(halloc_t) + size;
|
||||
me->scratch_free = HALLOC_BLOCK_SIZE;
|
||||
|
||||
al_init( &me->children );
|
||||
return &me->data;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void halloc_free( void *context )
|
||||
void halloc_register_function( void *context, void (*func)(void *), void *data )
|
||||
{
|
||||
halloc_t *me;
|
||||
if( !context )
|
||||
return;
|
||||
|
||||
|
||||
me = halloc_from_data( context );
|
||||
al_foreach( &me->hchildren, (void (*)(const void *))&halloc_free );
|
||||
al_foreach( &me->children, (void (*)(const void *))&free );
|
||||
al_destroy( &me->children );
|
||||
al_destroy( &me->hchildren );
|
||||
free(me);
|
||||
al_push( &me->children, func );
|
||||
al_push( &me->children, data );
|
||||
}
|
||||
|
||||
void halloc_free( void *context )
|
||||
{
|
||||
halloc_t *me;
|
||||
int i;
|
||||
|
||||
if( !context )
|
||||
return;
|
||||
|
||||
|
||||
me = halloc_from_data( context );
|
||||
|
||||
#ifdef HALLOC_DEBUG
|
||||
alloc_spill += me->scratch_free;
|
||||
#endif
|
||||
for( i=0; i<al_get_count(&me->children); i+=2 )
|
||||
{
|
||||
void (*func)(void *) = (void (*)(void *))al_get( &me->children, i );
|
||||
void * data = (void *)al_get( &me->children, i+1 );
|
||||
if( func != &late_free )
|
||||
func( data );
|
||||
}
|
||||
for( i=0; i<al_get_count(&me->children); i+=2 )
|
||||
{
|
||||
void (*func)(void *) = (void (*)(void *))al_get( &me->children, i );
|
||||
void * data = (void *)al_get( &me->children, i+1 );
|
||||
if( func == &late_free )
|
||||
free( data );
|
||||
}
|
||||
al_destroy( &me->children );
|
||||
free(me);
|
||||
}
|
||||
|
||||
43
halloc.h
43
halloc.h
@@ -1,35 +1,48 @@
|
||||
/** \file halloc.h
|
||||
|
||||
A hierarchical memory allocation system. Works just like talloc
|
||||
A hierarchical memory allocation system. Works mostly like talloc
|
||||
used in Samba, except that an arbitrary block allocated with
|
||||
malloc() can be registered to be freed by halloc_free.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef FISH_HALLOC_H
|
||||
#define FISH_HALLOC_H
|
||||
|
||||
/**
|
||||
Allocate new memory using specified parent memory context. If \c
|
||||
context is null, a new root context is created. Context _must_ be
|
||||
either 0 or the result of a previous call to halloc.
|
||||
Allocate new memory using specified parent memory context. Context
|
||||
_must_ be either 0 or the result of a previous call to halloc.
|
||||
|
||||
If \c context is null, the resulting block must be freed with a
|
||||
call to halloc_free().
|
||||
If \c context is null, the resulting block is a root block, and
|
||||
must be freed with a call to halloc_free().
|
||||
|
||||
If \c context is not null, the resulting memory block must never be
|
||||
If \c context is not null, context must be a halloc root block. the
|
||||
resulting memory block is a child context, and must never be
|
||||
explicitly freed, it will be automatically freed whenever the
|
||||
parent context is freed.
|
||||
parent context is freed. Child blocks can also never be used as the
|
||||
context in calls to halloc_register_function, halloc_free, etc.
|
||||
*/
|
||||
void *halloc( void *context, size_t size );
|
||||
|
||||
/**
|
||||
Make the specified function run whenever context is free'd, using data as argument.
|
||||
|
||||
\c context a halloc root block
|
||||
*/
|
||||
void halloc_register_function( void *context, void (*func)(void *), void *data );
|
||||
|
||||
/**
|
||||
Free memory context and all children contexts. Only root contexts
|
||||
may be freed explicitly.
|
||||
|
||||
All functions registered with halloc_register_function are run in
|
||||
the order they where added. Afterwards, all memory allocated using
|
||||
halloc itself is free'd.
|
||||
|
||||
\c context a halloc root block
|
||||
*/
|
||||
void halloc_free( void *context );
|
||||
|
||||
/**
|
||||
Free the memory pointed to by \c data when the memory pointed to by
|
||||
\c context is free:d. Note that this will _not_ turn the specified
|
||||
memory area into a valid halloc context. Only memory areas created
|
||||
using a call to halloc() can be used as a context.
|
||||
*/
|
||||
void *halloc_register( void *context, void *data );
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
100
halloc_util.c
Normal file
100
halloc_util.c
Normal file
@@ -0,0 +1,100 @@
|
||||
/** \file halloc_util.c
|
||||
|
||||
A hierarchical memory allocation system. Works just like talloc
|
||||
used in Samba, except that an arbitrary block allocated with
|
||||
malloc() can be registered to be freed by halloc_free.
|
||||
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "fallback.h"
|
||||
#include "util.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "halloc.h"
|
||||
|
||||
void *global_context=0;
|
||||
|
||||
void halloc_util_init()
|
||||
{
|
||||
global_context = halloc( 0, 0 );
|
||||
}
|
||||
|
||||
void halloc_util_destroy()
|
||||
{
|
||||
halloc_free( global_context );
|
||||
}
|
||||
|
||||
array_list_t *al_halloc( void *context )
|
||||
{
|
||||
array_list_t *res = halloc( context, sizeof( array_list_t ) );
|
||||
if( !res )
|
||||
DIE_MEM();
|
||||
al_init( res );
|
||||
halloc_register_function( context, (void (*)(void *)) &al_destroy, res );
|
||||
return res;
|
||||
}
|
||||
|
||||
string_buffer_t *sb_halloc( void *context )
|
||||
{
|
||||
string_buffer_t *res = halloc( context, sizeof( string_buffer_t ) );
|
||||
if( !res )
|
||||
DIE_MEM();
|
||||
sb_init( res );
|
||||
halloc_register_function( context, (void (*)(void *)) &sb_destroy, res );
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
A function that takes a single parameter, which is a function pointer, and calls it.
|
||||
*/
|
||||
static void halloc_passthrough( void *f )
|
||||
{
|
||||
void (*func)() = (void (*)() )f;
|
||||
func();
|
||||
}
|
||||
|
||||
void halloc_register_function_void( void *context, void (*func)() )
|
||||
{
|
||||
halloc_register_function( context, &halloc_passthrough, (void *)func );
|
||||
}
|
||||
|
||||
void *halloc_register( void *context, void *data )
|
||||
{
|
||||
if( !data )
|
||||
return 0;
|
||||
|
||||
halloc_register_function( context, &free, data );
|
||||
return data;
|
||||
}
|
||||
|
||||
wchar_t *halloc_wcsdup( void *context, const wchar_t *in )
|
||||
{
|
||||
size_t len=wcslen(in);
|
||||
wchar_t *out = halloc( context, sizeof( wchar_t)*(len+1));
|
||||
|
||||
if( out == 0 )
|
||||
{
|
||||
DIE_MEM();
|
||||
}
|
||||
memcpy( out, in, sizeof( wchar_t)*(len+1));
|
||||
return out;
|
||||
}
|
||||
|
||||
wchar_t *halloc_wcsndup( void * context, const wchar_t *in, int c )
|
||||
{
|
||||
wchar_t *res = halloc( context, sizeof(wchar_t)*(c+1) );
|
||||
if( res == 0 )
|
||||
{
|
||||
DIE_MEM();
|
||||
}
|
||||
wcslcpy( res, in, c+1 );
|
||||
res[c] = L'\0';
|
||||
return res;
|
||||
}
|
||||
66
halloc_util.h
Normal file
66
halloc_util.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
\file halloc_util.h
|
||||
|
||||
Various halloc-related utility functions.
|
||||
*/
|
||||
|
||||
#ifndef FISH_HALLOC_UTIL_H
|
||||
#define FISH_HALLOC_UTIL_H
|
||||
|
||||
/**
|
||||
This pointer is a valid halloc context that will be freed right
|
||||
before program shutdown. It may be used to allocate memory that
|
||||
should be freed when the program shuts down.
|
||||
*/
|
||||
extern void *global_context;
|
||||
|
||||
/**
|
||||
Create the global_context halloc object
|
||||
*/
|
||||
void halloc_util_init();
|
||||
|
||||
/**
|
||||
Free the global_context halloc object
|
||||
*/
|
||||
void halloc_util_destroy();
|
||||
|
||||
/**
|
||||
Allocate a array_list_t that will be automatically disposed of when
|
||||
the specified context is free'd
|
||||
*/
|
||||
array_list_t *al_halloc( void *context );
|
||||
|
||||
/**
|
||||
Allocate a string_buffer_t that will be automatically disposed of
|
||||
when the specified context is free'd
|
||||
*/
|
||||
string_buffer_t *sb_halloc( void *context );
|
||||
|
||||
/**
|
||||
Register the specified function to run when the specified context
|
||||
is free'd. This function is related to halloc_register_function,
|
||||
but the specified function dowes not take an argument.
|
||||
*/
|
||||
void halloc_register_function_void( void *context, void (*func)() );
|
||||
|
||||
/**
|
||||
Free the memory pointed to by \c data when the memory pointed to by
|
||||
\c context is free:d. Note that this will _not_ turn the specified
|
||||
memory area into a valid halloc context. Only memory areas created
|
||||
using a call to halloc( 0, size ) can be used as a context.
|
||||
*/
|
||||
void *halloc_register( void *context, void *data );
|
||||
|
||||
/**
|
||||
Make a copy of the specified string using memory allocated using
|
||||
halloc and the specified context
|
||||
*/
|
||||
wchar_t *halloc_wcsdup( void *context, const wchar_t *str );
|
||||
|
||||
/**
|
||||
Make a copy of the specified substring using memory allocated using
|
||||
halloc and the specified context
|
||||
*/
|
||||
wchar_t *halloc_wcsndup( void * context, const wchar_t *in, int c );
|
||||
|
||||
#endif
|
||||
660
highlight.c
660
highlight.c
@@ -1,6 +1,8 @@
|
||||
/** \file highlight.c
|
||||
Functions for syntax highlighting
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -11,8 +13,9 @@
|
||||
#include <termios.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "fallback.h"
|
||||
#include "util.h"
|
||||
|
||||
#include "wutil.h"
|
||||
#include "highlight.h"
|
||||
#include "tokenizer.h"
|
||||
@@ -27,6 +30,14 @@
|
||||
#include "common.h"
|
||||
#include "complete.h"
|
||||
#include "output.h"
|
||||
#include "halloc.h"
|
||||
#include "halloc_util.h"
|
||||
#include "wildcard.h"
|
||||
|
||||
/**
|
||||
Number of elements in the highlight_var array
|
||||
*/
|
||||
#define VAR_COUNT ( sizeof(highlight_var)/sizeof(wchar_t *) )
|
||||
|
||||
static void highlight_universal_internal( wchar_t * buff,
|
||||
int *color,
|
||||
@@ -37,43 +48,480 @@ static void highlight_universal_internal( wchar_t * buff,
|
||||
/**
|
||||
The environment variables used to specify the color of different tokens.
|
||||
*/
|
||||
static wchar_t *hightlight_var[] =
|
||||
static wchar_t *highlight_var[] =
|
||||
{
|
||||
L"fish_color_normal",
|
||||
L"fish_color_command",
|
||||
L"fish_color_subshell",
|
||||
L"fish_color_redirection",
|
||||
L"fish_color_end",
|
||||
L"fish_color_error",
|
||||
L"fish_color_command",
|
||||
L"fish_color_end",
|
||||
L"fish_color_param",
|
||||
L"fish_color_comment",
|
||||
L"fish_color_match",
|
||||
L"fish_color_search_match",
|
||||
L"fish_color_pager_prefix",
|
||||
L"fish_color_pager_completion",
|
||||
L"fish_color_pager_description",
|
||||
L"fish_color_pager_progress"
|
||||
L"fish_color_operator",
|
||||
L"fish_color_escape",
|
||||
L"fish_color_quote",
|
||||
L"fish_color_redirection",
|
||||
L"fish_color_valid_path"
|
||||
}
|
||||
;
|
||||
|
||||
/**
|
||||
Tests if the specified string is the prefix of any valid path in the system.
|
||||
|
||||
\return zero it this is not a valid prefix, non-zero otherwise
|
||||
*/
|
||||
static int is_potential_path( const wchar_t *path )
|
||||
{
|
||||
wchar_t *tilde, *unescaped;
|
||||
wchar_t *in, *out;
|
||||
int has_magic = 0;
|
||||
int res = 0;
|
||||
|
||||
void *context = halloc( 0, 0 );
|
||||
|
||||
tilde = expand_tilde( wcsdup(path) );
|
||||
if( tilde )
|
||||
{
|
||||
halloc_register( context, tilde );
|
||||
|
||||
unescaped = unescape( tilde, 1 );
|
||||
if( unescaped )
|
||||
{
|
||||
|
||||
// debug( 1, L"%ls -> %ls ->%ls", path, tilde, unescaped );
|
||||
|
||||
halloc_register( context, unescaped );
|
||||
|
||||
for( in = out = unescaped; *in; in++ )
|
||||
{
|
||||
switch( *in )
|
||||
{
|
||||
case PROCESS_EXPAND:
|
||||
case VARIABLE_EXPAND:
|
||||
case VARIABLE_EXPAND_SINGLE:
|
||||
case BRACKET_BEGIN:
|
||||
case BRACKET_END:
|
||||
case BRACKET_SEP:
|
||||
case ANY_CHAR:
|
||||
case ANY_STRING:
|
||||
case ANY_STRING_RECURSIVE:
|
||||
{
|
||||
has_magic = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
case INTERNAL_SEPARATOR:
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
*(out++) = *in;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
*out = 0;
|
||||
|
||||
if( !has_magic && wcslen( unescaped ) )
|
||||
{
|
||||
int must_be_dir = 0;
|
||||
DIR *dir;
|
||||
must_be_dir = unescaped[wcslen(unescaped)-1] == L'/';
|
||||
if( must_be_dir )
|
||||
{
|
||||
dir = wopendir( unescaped );
|
||||
res = !!dir;
|
||||
if( dir )
|
||||
{
|
||||
closedir( dir );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
wchar_t *dir_name, *base;
|
||||
struct wdirent *ent;
|
||||
|
||||
dir_name = wdirname( halloc_wcsdup(context, unescaped) );
|
||||
base = wbasename( halloc_wcsdup(context, unescaped) );
|
||||
|
||||
if( (wcscmp( dir_name, L"/" ) == 0 ) &&
|
||||
(wcscmp( base, L"/" ) == 0 ) )
|
||||
{
|
||||
res = 1;
|
||||
}
|
||||
else if( (dir = wopendir( dir_name )) )
|
||||
{
|
||||
|
||||
while( (ent = wreaddir( dir )) )
|
||||
{
|
||||
if( wcsncmp( ent->d_name, base, wcslen(base) ) == 0 )
|
||||
{
|
||||
res = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
closedir( dir );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
halloc_free( context );
|
||||
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
int highlight_get_color( int highlight )
|
||||
{
|
||||
int i;
|
||||
int idx=0;
|
||||
int result = 0;
|
||||
|
||||
if( highlight < 0 )
|
||||
return FISH_COLOR_NORMAL;
|
||||
if( highlight >= (12) )
|
||||
if( highlight >= (1<<VAR_COUNT) )
|
||||
return FISH_COLOR_NORMAL;
|
||||
|
||||
wchar_t *val = env_get( hightlight_var[highlight]);
|
||||
if( val == 0 )
|
||||
val = env_get( hightlight_var[HIGHLIGHT_NORMAL]);
|
||||
|
||||
if( val == 0 )
|
||||
|
||||
for( i=0; i<(VAR_COUNT-1); i++ )
|
||||
{
|
||||
return FISH_COLOR_NORMAL;
|
||||
if( highlight & (1<<i ))
|
||||
{
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
wchar_t *val = env_get( highlight_var[idx]);
|
||||
|
||||
// debug( 1, L"%d -> %d -> %ls", highlight, idx, val );
|
||||
|
||||
return output_color_code( val );
|
||||
if( val == 0 )
|
||||
val = env_get( highlight_var[0]);
|
||||
|
||||
if( val )
|
||||
result = output_color_code( val );
|
||||
|
||||
if( highlight & HIGHLIGHT_VALID_PATH )
|
||||
{
|
||||
wchar_t *val2 = env_get( L"fish_color_valid_path" );
|
||||
int result2 = output_color_code( val2 );
|
||||
if( result == FISH_COLOR_NORMAL )
|
||||
result = result2;
|
||||
else
|
||||
{
|
||||
if( result2 & FISH_COLOR_BOLD )
|
||||
result |= FISH_COLOR_BOLD;
|
||||
if( result2 & FISH_COLOR_UNDERLINE )
|
||||
result |= FISH_COLOR_UNDERLINE;
|
||||
}
|
||||
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
Highligt operators (such as $, ~, %, as well as escaped characters.
|
||||
*/
|
||||
static void highlight_param( const wchar_t * buff,
|
||||
int *color,
|
||||
int pos,
|
||||
array_list_t *error )
|
||||
{
|
||||
|
||||
|
||||
int mode = 0;
|
||||
int in_pos, len = wcslen( buff );
|
||||
int bracket_count=0;
|
||||
wchar_t c;
|
||||
int normal_status = *color;
|
||||
|
||||
for( in_pos=0;
|
||||
in_pos<len;
|
||||
in_pos++ )
|
||||
{
|
||||
c = buff[in_pos];
|
||||
switch( mode )
|
||||
{
|
||||
|
||||
/*
|
||||
Mode 0 means unquoted string
|
||||
*/
|
||||
case 0:
|
||||
{
|
||||
if( c == L'\\' )
|
||||
{
|
||||
int start_pos = in_pos;
|
||||
in_pos++;
|
||||
|
||||
if( wcschr( L"~%", buff[in_pos] ) )
|
||||
{
|
||||
if( in_pos == 1 )
|
||||
{
|
||||
color[start_pos] = HIGHLIGHT_ESCAPE;
|
||||
color[in_pos+1] = normal_status;
|
||||
}
|
||||
}
|
||||
else if( buff[in_pos]==L',' )
|
||||
{
|
||||
if( bracket_count )
|
||||
{
|
||||
color[start_pos] = HIGHLIGHT_ESCAPE;
|
||||
color[in_pos+1] = normal_status;
|
||||
}
|
||||
}
|
||||
else if( wcschr( L"nrtbe*?$(){}'\"<>^ \\#;|&", buff[in_pos] ) )
|
||||
{
|
||||
color[start_pos]=HIGHLIGHT_ESCAPE;
|
||||
color[in_pos+1]=normal_status;
|
||||
}
|
||||
else if( wcschr( L"uUxX01234567", buff[in_pos] ) )
|
||||
{
|
||||
int i;
|
||||
long long res=0;
|
||||
int chars=2;
|
||||
int base=16;
|
||||
|
||||
int byte = 0;
|
||||
wchar_t max_val = ASCII_MAX;
|
||||
|
||||
switch( buff[in_pos] )
|
||||
{
|
||||
case L'u':
|
||||
{
|
||||
chars=4;
|
||||
max_val = UCS2_MAX;
|
||||
break;
|
||||
}
|
||||
|
||||
case L'U':
|
||||
{
|
||||
chars=8;
|
||||
max_val = WCHAR_MAX;
|
||||
break;
|
||||
}
|
||||
|
||||
case L'x':
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
case L'X':
|
||||
{
|
||||
byte=1;
|
||||
max_val = BYTE_MAX;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
base=8;
|
||||
chars=3;
|
||||
in_pos--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for( i=0; i<chars; i++ )
|
||||
{
|
||||
int d = convert_digit( buff[++in_pos],base);
|
||||
|
||||
if( d < 0 )
|
||||
{
|
||||
in_pos--;
|
||||
break;
|
||||
}
|
||||
|
||||
res=(res*base)|d;
|
||||
}
|
||||
|
||||
if( (res <= max_val) )
|
||||
{
|
||||
color[start_pos] = HIGHLIGHT_ESCAPE;
|
||||
color[in_pos+1] = normal_status;
|
||||
}
|
||||
else
|
||||
{
|
||||
color[start_pos] = HIGHLIGHT_ERROR;
|
||||
color[in_pos+1] = normal_status;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
switch( buff[in_pos]){
|
||||
case L'~':
|
||||
case L'%':
|
||||
{
|
||||
if( in_pos == 0 )
|
||||
{
|
||||
color[in_pos] = HIGHLIGHT_OPERATOR;
|
||||
color[in_pos+1] = normal_status;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case L'$':
|
||||
{
|
||||
wchar_t n = buff[in_pos+1];
|
||||
color[in_pos] = (n==L'$'||wcsvarchr(n))? HIGHLIGHT_OPERATOR:HIGHLIGHT_ERROR;
|
||||
color[in_pos+1] = normal_status;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case L'*':
|
||||
case L'?':
|
||||
case L'(':
|
||||
case L')':
|
||||
{
|
||||
color[in_pos] = HIGHLIGHT_OPERATOR;
|
||||
color[in_pos+1] = normal_status;
|
||||
break;
|
||||
}
|
||||
|
||||
case L'{':
|
||||
{
|
||||
color[in_pos] = HIGHLIGHT_OPERATOR;
|
||||
color[in_pos+1] = normal_status;
|
||||
bracket_count++;
|
||||
break;
|
||||
}
|
||||
|
||||
case L'}':
|
||||
{
|
||||
color[in_pos] = HIGHLIGHT_OPERATOR;
|
||||
color[in_pos+1] = normal_status;
|
||||
bracket_count--;
|
||||
break;
|
||||
}
|
||||
|
||||
case L',':
|
||||
{
|
||||
if( bracket_count )
|
||||
{
|
||||
color[in_pos] = HIGHLIGHT_OPERATOR;
|
||||
color[in_pos+1] = normal_status;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case L'\'':
|
||||
{
|
||||
color[in_pos] = HIGHLIGHT_QUOTE;
|
||||
mode = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
case L'\"':
|
||||
{
|
||||
color[in_pos] = HIGHLIGHT_QUOTE;
|
||||
mode = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
Mode 1 means single quoted string, i.e 'foo'
|
||||
*/
|
||||
case 1:
|
||||
{
|
||||
if( c == L'\\' )
|
||||
{
|
||||
int start_pos = in_pos;
|
||||
switch( buff[++in_pos] )
|
||||
{
|
||||
case '\\':
|
||||
case L'\'':
|
||||
{
|
||||
color[start_pos] = HIGHLIGHT_ESCAPE;
|
||||
color[in_pos+1] = HIGHLIGHT_QUOTE;
|
||||
break;
|
||||
}
|
||||
|
||||
case 0:
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
if( c == L'\'' )
|
||||
{
|
||||
mode = 0;
|
||||
color[in_pos+1] = normal_status;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
Mode 2 means double quoted string, i.e. "foo"
|
||||
*/
|
||||
case 2:
|
||||
{
|
||||
switch( c )
|
||||
{
|
||||
case '"':
|
||||
{
|
||||
mode = 0;
|
||||
color[in_pos+1] = normal_status;
|
||||
break;
|
||||
}
|
||||
|
||||
case '\\':
|
||||
{
|
||||
int start_pos = in_pos;
|
||||
switch( buff[++in_pos] )
|
||||
{
|
||||
case L'\0':
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
case '\\':
|
||||
case L'$':
|
||||
case '"':
|
||||
{
|
||||
color[start_pos] = HIGHLIGHT_ESCAPE;
|
||||
color[in_pos+1] = HIGHLIGHT_QUOTE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case '$':
|
||||
{
|
||||
wchar_t n = buff[in_pos+1];
|
||||
color[in_pos] = (n==L'$'||wcsvarchr(n))? HIGHLIGHT_OPERATOR:HIGHLIGHT_ERROR;
|
||||
color[in_pos+1] = HIGHLIGHT_QUOTE;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -87,11 +535,21 @@ void highlight_shell( wchar_t * buff,
|
||||
int i;
|
||||
int last_val;
|
||||
wchar_t *last_cmd=0;
|
||||
int len = wcslen(buff);
|
||||
int len;
|
||||
|
||||
void *context;
|
||||
wchar_t *cmd=0;
|
||||
|
||||
CHECK( buff, );
|
||||
CHECK( color, );
|
||||
|
||||
len = wcslen(buff);
|
||||
|
||||
if( !len )
|
||||
return;
|
||||
|
||||
context = halloc( 0, 0 );
|
||||
|
||||
for( i=0; buff[i] != 0; i++ )
|
||||
color[i] = -1;
|
||||
|
||||
@@ -102,6 +560,7 @@ void highlight_shell( wchar_t * buff,
|
||||
int last_type = tok_last_type( &tok );
|
||||
int prev_argc=0;
|
||||
|
||||
|
||||
switch( last_type )
|
||||
{
|
||||
case TOK_STRING:
|
||||
@@ -122,6 +581,27 @@ void highlight_shell( wchar_t * buff,
|
||||
{
|
||||
color[ tok_get_pos( &tok ) ] = HIGHLIGHT_PARAM;
|
||||
}
|
||||
|
||||
if( cmd && (wcscmp( cmd, L"cd" ) == 0) )
|
||||
{
|
||||
wchar_t *dir = expand_one( context,
|
||||
wcsdup(tok_last( &tok )),
|
||||
EXPAND_SKIP_CMDSUBST );
|
||||
if( dir )
|
||||
{
|
||||
if( !parser_cdpath_get( context, dir ) )
|
||||
{
|
||||
color[ tok_get_pos( &tok ) ] = HIGHLIGHT_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
highlight_param( param,
|
||||
&color[tok_get_pos( &tok )],
|
||||
pos-tok_get_pos( &tok ),
|
||||
error );
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -130,28 +610,27 @@ void highlight_shell( wchar_t * buff,
|
||||
/*
|
||||
Command. First check that the command actually exists.
|
||||
*/
|
||||
wchar_t *cmd =
|
||||
(last_type == TOK_STRING) ?
|
||||
expand_one(wcsdup(tok_last( &tok )),EXPAND_SKIP_SUBSHELL | EXPAND_SKIP_VARIABLES) :
|
||||
wcsdup(tok_last( &tok ));
|
||||
cmd = expand_one( context,
|
||||
wcsdup(tok_last( &tok )),
|
||||
EXPAND_SKIP_CMDSUBST | EXPAND_SKIP_VARIABLES);
|
||||
|
||||
if( cmd == 0 )
|
||||
{
|
||||
color[ tok_get_pos( &tok ) ] = HIGHLIGHT_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
wchar_t *tmp;
|
||||
int is_cmd = 0;
|
||||
int is_subcommand = 0;
|
||||
int mark = tok_get_pos( &tok );
|
||||
color[ tok_get_pos( &tok ) ] = HIGHLIGHT_COMMAND;
|
||||
|
||||
|
||||
if( parser_is_subcommand( cmd ) )
|
||||
{
|
||||
tok_next( &tok );
|
||||
if(( wcscmp( L"-h", tok_last( &tok ) ) == 0 ) ||
|
||||
( wcscmp( L"--help", tok_last( &tok ) ) == 0 ) )
|
||||
if( ( ! parser_is_block( cmd ) ) &&
|
||||
( ( wcscmp( L"-h", tok_last( &tok ) ) == 0 ) ||
|
||||
( wcsncmp( L"--help", tok_last( &tok ), wcslen( tok_last( &tok ) ) ) == 0 && wcslen( tok_last( &tok ) ) >= 3 ) ) )
|
||||
{
|
||||
/*
|
||||
The builtin and command builtins
|
||||
@@ -170,31 +649,37 @@ void highlight_shell( wchar_t * buff,
|
||||
|
||||
if( !is_subcommand )
|
||||
{
|
||||
wchar_t *tmp;
|
||||
/*
|
||||
OK, this is a command, it has been
|
||||
successfully expanded and everything
|
||||
looks ok. Lets check if the command
|
||||
exists.
|
||||
*/
|
||||
|
||||
/*
|
||||
First check if it is a builtin or
|
||||
function, since we don't have to stat
|
||||
any files for that
|
||||
*/
|
||||
is_cmd |= builtin_exists( cmd );
|
||||
is_cmd |= function_exists( cmd );
|
||||
is_cmd |= (tmp=get_filename( cmd )) != 0;
|
||||
|
||||
/*
|
||||
Moving on to expensive tests
|
||||
*/
|
||||
|
||||
/*
|
||||
Check if this is a regular command
|
||||
*/
|
||||
is_cmd |= !!(tmp=parser_get_filename( context, cmd ));
|
||||
|
||||
/*
|
||||
Could not find the command. Maybe it is a path for a implicit cd command.
|
||||
Lets check!
|
||||
Could not find the command. Maybe it is
|
||||
a path for a implicit cd command.
|
||||
*/
|
||||
if( !is_cmd )
|
||||
{
|
||||
wchar_t *pp = parser_cdpath_get( cmd );
|
||||
if( pp )
|
||||
{
|
||||
free( pp );
|
||||
is_cmd = 1;
|
||||
}
|
||||
}
|
||||
|
||||
free(tmp);
|
||||
is_cmd |= !!(tmp=parser_cdpath_get( context, cmd ));
|
||||
|
||||
if( is_cmd )
|
||||
{
|
||||
color[ tok_get_pos( &tok ) ] = HIGHLIGHT_COMMAND;
|
||||
@@ -207,15 +692,11 @@ void highlight_shell( wchar_t * buff,
|
||||
}
|
||||
had_cmd = 1;
|
||||
}
|
||||
free(cmd);
|
||||
|
||||
if( had_cmd )
|
||||
{
|
||||
if( last_cmd )
|
||||
free( last_cmd );
|
||||
last_cmd = wcsdup( tok_last( &tok ) );
|
||||
}
|
||||
|
||||
last_cmd = halloc_wcsdup( context, tok_last( &tok ) );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -248,9 +729,9 @@ void highlight_shell( wchar_t * buff,
|
||||
{
|
||||
case TOK_STRING:
|
||||
{
|
||||
target = expand_one( wcsdup( tok_last( &tok ) ), EXPAND_SKIP_SUBSHELL);
|
||||
target = expand_one( context, wcsdup( tok_last( &tok ) ), EXPAND_SKIP_CMDSUBST);
|
||||
/*
|
||||
Redirect filename may contain a subshell.
|
||||
Redirect filename may contain a cmdsubst.
|
||||
If so, it will be ignored/not flagged.
|
||||
*/
|
||||
}
|
||||
@@ -266,7 +747,7 @@ void highlight_shell( wchar_t * buff,
|
||||
|
||||
if( target != 0 )
|
||||
{
|
||||
wchar_t *dir = wcsdup( target );
|
||||
wchar_t *dir = halloc_wcsdup( context, target );
|
||||
wchar_t *dir_end = wcsrchr( dir, L'/' );
|
||||
struct stat buff;
|
||||
/*
|
||||
@@ -282,9 +763,8 @@ void highlight_shell( wchar_t * buff,
|
||||
if( error )
|
||||
al_push( error, wcsdupcat2( L"Directory \'", dir, L"\' does not exist", 0 ) );
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
free( dir );
|
||||
|
||||
/*
|
||||
If the file is read from or appended to, check
|
||||
@@ -300,7 +780,6 @@ void highlight_shell( wchar_t * buff,
|
||||
al_push( error, wcsdupcat2( L"File \'", target, L"\' does not exist", 0 ) );
|
||||
}
|
||||
}
|
||||
free( target );
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -350,16 +829,13 @@ void highlight_shell( wchar_t * buff,
|
||||
}
|
||||
}
|
||||
|
||||
if( last_cmd )
|
||||
free( last_cmd );
|
||||
|
||||
tok_destroy( &tok );
|
||||
|
||||
/*
|
||||
Locate and syntax highlight subshells recursively
|
||||
Locate and syntax highlight cmdsubsts recursively
|
||||
*/
|
||||
|
||||
wchar_t *buffcpy = wcsdup( buff );
|
||||
wchar_t *buffcpy = halloc_wcsdup( context, buff );
|
||||
wchar_t *subpos=buffcpy;
|
||||
int done=0;
|
||||
|
||||
@@ -368,8 +844,8 @@ void highlight_shell( wchar_t * buff,
|
||||
wchar_t *begin, *end;
|
||||
|
||||
if( parse_util_locate_cmdsubst( subpos,
|
||||
(const wchar_t **)&begin,
|
||||
(const wchar_t **)&end,
|
||||
&begin,
|
||||
&end,
|
||||
1) <= 0)
|
||||
{
|
||||
break;
|
||||
@@ -381,7 +857,7 @@ void highlight_shell( wchar_t * buff,
|
||||
*end=0;
|
||||
|
||||
highlight_shell( begin+1, color +(begin-buffcpy)+1, -1, error );
|
||||
color[end-buffcpy]=HIGHLIGHT_PARAM;
|
||||
color[end-buffcpy]=HIGHLIGHT_OPERATOR;
|
||||
|
||||
if( done )
|
||||
break;
|
||||
@@ -389,9 +865,11 @@ void highlight_shell( wchar_t * buff,
|
||||
subpos = end+1;
|
||||
|
||||
}
|
||||
free( buffcpy);
|
||||
|
||||
|
||||
/*
|
||||
The highlighting code only changes the first element when the
|
||||
color changes. This fills in the rest.
|
||||
*/
|
||||
last_val=0;
|
||||
for( i=0; buff[i] != 0; i++ )
|
||||
{
|
||||
@@ -401,6 +879,32 @@ void highlight_shell( wchar_t * buff,
|
||||
color[i] = last_val;
|
||||
}
|
||||
|
||||
/*
|
||||
Color potentially valid paths in a special path color if they
|
||||
are the current token.
|
||||
*/
|
||||
|
||||
if( pos >= 0 && pos <= len )
|
||||
{
|
||||
|
||||
wchar_t *tok_begin, *tok_end;
|
||||
wchar_t *token;
|
||||
|
||||
parse_util_token_extent( buff, pos, &tok_begin, &tok_end, 0, 0 );
|
||||
if( tok_begin && tok_end )
|
||||
{
|
||||
token = halloc_wcsndup( context, tok_begin, tok_end-tok_begin );
|
||||
|
||||
if( is_potential_path( token ) )
|
||||
{
|
||||
for( i=tok_begin-buff; i < (tok_end-buff); i++ )
|
||||
{
|
||||
color[i] |= HIGHLIGHT_VALID_PATH;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
highlight_universal_internal( buff, color, pos, error );
|
||||
|
||||
@@ -414,6 +918,9 @@ void highlight_shell( wchar_t * buff,
|
||||
color[i]=0;
|
||||
}
|
||||
}
|
||||
|
||||
halloc_free( context );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -456,22 +963,22 @@ static void highlight_universal_internal( wchar_t * buff,
|
||||
if( level == 0 )
|
||||
{
|
||||
level++;
|
||||
al_push( &l, (void *)(str-buff) );
|
||||
al_push_long( &l, (long)(str-buff) );
|
||||
prev_q = *str;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( prev_q == *str )
|
||||
{
|
||||
int pos1, pos2;
|
||||
long pos1, pos2;
|
||||
|
||||
level--;
|
||||
pos1 = (int)al_pop( &l );
|
||||
pos1 = al_pop_long( &l );
|
||||
pos2 = str-buff;
|
||||
if( pos1==pos || pos2==pos )
|
||||
{
|
||||
color[pos1]|=HIGHLIGHT_MATCH<<8;
|
||||
color[pos2]|=HIGHLIGHT_MATCH<<8;
|
||||
color[pos1]|=HIGHLIGHT_MATCH<<16;
|
||||
color[pos2]|=HIGHLIGHT_MATCH<<16;
|
||||
match_found = 1;
|
||||
|
||||
}
|
||||
@@ -480,7 +987,7 @@ static void highlight_universal_internal( wchar_t * buff,
|
||||
else
|
||||
{
|
||||
level++;
|
||||
al_push( &l, (void *)(str-buff) );
|
||||
al_push_long( &l, (long)(str-buff) );
|
||||
prev_q = *str;
|
||||
}
|
||||
}
|
||||
@@ -496,7 +1003,7 @@ static void highlight_universal_internal( wchar_t * buff,
|
||||
al_destroy( &l );
|
||||
|
||||
if( !match_found )
|
||||
color[pos] = HIGHLIGHT_ERROR<<8;
|
||||
color[pos] = HIGHLIGHT_ERROR<<16;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -509,8 +1016,7 @@ static void highlight_universal_internal( wchar_t * buff,
|
||||
wchar_t inc_char = buff[pos];
|
||||
int level = 0;
|
||||
wchar_t *str = &buff[pos];
|
||||
int match_found=0;
|
||||
|
||||
int match_found=0;
|
||||
|
||||
while( (str >= buff) && *str)
|
||||
{
|
||||
@@ -521,8 +1027,8 @@ static void highlight_universal_internal( wchar_t * buff,
|
||||
if( level == 0 )
|
||||
{
|
||||
int pos2 = str-buff;
|
||||
color[pos]|=HIGHLIGHT_MATCH<<8;
|
||||
color[pos2]|=HIGHLIGHT_MATCH<<8;
|
||||
color[pos]|=HIGHLIGHT_MATCH<<16;
|
||||
color[pos2]|=HIGHLIGHT_MATCH<<16;
|
||||
match_found=1;
|
||||
break;
|
||||
}
|
||||
@@ -530,7 +1036,7 @@ static void highlight_universal_internal( wchar_t * buff,
|
||||
}
|
||||
|
||||
if( !match_found )
|
||||
color[pos] = HIGHLIGHT_ERROR<<8;
|
||||
color[pos] = HIGHLIGHT_ERROR<<16;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -542,7 +1048,7 @@ void highlight_universal( wchar_t * buff,
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i=0; buff[i] != 0; i++ )
|
||||
for( i=0; buff[i]; i++ )
|
||||
color[i] = 0;
|
||||
|
||||
highlight_universal_internal( buff, color, pos, error );
|
||||
|
||||
53
highlight.h
53
highlight.h
@@ -9,6 +9,59 @@
|
||||
|
||||
#include "util.h"
|
||||
|
||||
/**
|
||||
Internal value representing highlighting of normal text
|
||||
*/
|
||||
#define HIGHLIGHT_NORMAL 0x1
|
||||
/**
|
||||
Internal value representing highlighting of an error
|
||||
*/
|
||||
#define HIGHLIGHT_ERROR 0x2
|
||||
/**
|
||||
Internal value representing highlighting of a command
|
||||
*/
|
||||
#define HIGHLIGHT_COMMAND 0x4
|
||||
/**
|
||||
Internal value representing highlighting of a process separator
|
||||
*/
|
||||
#define HIGHLIGHT_END 0x8
|
||||
/**
|
||||
Internal value representing highlighting of a regular command parameter
|
||||
*/
|
||||
#define HIGHLIGHT_PARAM 0x10
|
||||
/**
|
||||
Internal value representing highlighting of a comment
|
||||
*/
|
||||
#define HIGHLIGHT_COMMENT 0x20
|
||||
/**
|
||||
Internal value representing highlighting of a matching parenteses, etc.
|
||||
*/
|
||||
#define HIGHLIGHT_MATCH 0x40
|
||||
/**
|
||||
Internal value representing highlighting of a search match
|
||||
*/
|
||||
#define HIGHLIGHT_SEARCH_MATCH 0x80
|
||||
/**
|
||||
Internal value representing highlighting of an operator
|
||||
*/
|
||||
#define HIGHLIGHT_OPERATOR 0x100
|
||||
/**
|
||||
Internal value representing highlighting of an escape sequence
|
||||
*/
|
||||
#define HIGHLIGHT_ESCAPE 0x200
|
||||
/**
|
||||
Internal value representing highlighting of a quoted string
|
||||
*/
|
||||
#define HIGHLIGHT_QUOTE 0x400
|
||||
/**
|
||||
Internal value representing highlighting of an IO redirection
|
||||
*/
|
||||
#define HIGHLIGHT_REDIRECTION 0x800
|
||||
/**
|
||||
Internal value representing highlighting a potentially valid path
|
||||
*/
|
||||
#define HIGHLIGHT_VALID_PATH 0x1000
|
||||
|
||||
/**
|
||||
Perform syntax highlighting for the shell commands in buff. The result is
|
||||
stored in the color array as a color_code from the HIGHLIGHT_ enum
|
||||
|
||||
113
history.c
113
history.c
@@ -1,6 +1,8 @@
|
||||
/** \file history.c
|
||||
History functions, part of the user interface.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <wchar.h>
|
||||
@@ -11,14 +13,16 @@
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
#include "config.h"
|
||||
#include "fallback.h"
|
||||
#include "util.h"
|
||||
|
||||
#include "wutil.h"
|
||||
#include "history.h"
|
||||
#include "common.h"
|
||||
#include "reader.h"
|
||||
#include "env.h"
|
||||
#include "sanity.h"
|
||||
#include "signal.h"
|
||||
|
||||
/*
|
||||
The history is implemented using a linked list. Searches are done
|
||||
@@ -37,15 +41,20 @@ typedef struct
|
||||
Number of entries
|
||||
*/
|
||||
int count;
|
||||
|
||||
/**
|
||||
Last history item
|
||||
*/
|
||||
ll_node_t *last;
|
||||
|
||||
/**
|
||||
The last item loaded from file
|
||||
*/
|
||||
ll_node_t *last_loaded;
|
||||
|
||||
/**
|
||||
Set to one if the file containing the saved history has been loaded
|
||||
*/
|
||||
int is_loaded;
|
||||
}
|
||||
history_data;
|
||||
@@ -75,7 +84,9 @@ static int past_end =1;
|
||||
static int history_count=0;
|
||||
|
||||
/**
|
||||
The name of the current history list. The name is used to switch between history lists for different commands as sell as for deciding the name of the file to save the history in.
|
||||
The name of the current history list. The name is used to switch
|
||||
between history lists for different commands as sell as for
|
||||
deciding the name of the file to save the history in.
|
||||
*/
|
||||
static wchar_t *mode_name;
|
||||
|
||||
@@ -87,22 +98,28 @@ static hash_table_t history_table;
|
||||
/**
|
||||
Flag, set to 1 once the history file has been loaded
|
||||
*/
|
||||
static int is_loaded;
|
||||
static int is_loaded=0;
|
||||
|
||||
/**
|
||||
Load history from file
|
||||
*/
|
||||
static void history_load()
|
||||
static int history_load()
|
||||
{
|
||||
wchar_t *fn;
|
||||
wchar_t *buff=0;
|
||||
int buff_len=0;
|
||||
FILE *in_stream;
|
||||
hash_table_t used;
|
||||
int res = 0;
|
||||
|
||||
if( !mode_name )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
is_loaded = 1;
|
||||
|
||||
block();
|
||||
signal_block();
|
||||
hash_init2( &used,
|
||||
&hash_wcs_func,
|
||||
&hash_wcs_cmp,
|
||||
@@ -124,8 +141,8 @@ static void history_load()
|
||||
fclose( in_stream );
|
||||
free( fn );
|
||||
free( buff );
|
||||
unblock();
|
||||
return;
|
||||
signal_unblock();
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -143,7 +160,7 @@ static void history_load()
|
||||
history_current = malloc( sizeof( ll_node_t ) );
|
||||
if( !history_current )
|
||||
{
|
||||
die_mem();
|
||||
DIE_MEM();
|
||||
|
||||
}
|
||||
|
||||
@@ -171,6 +188,8 @@ static void history_load()
|
||||
{
|
||||
debug( 1, L"The following non-fatal error occurred while reading command history from \'%ls\':", mode_name );
|
||||
wperror( L"fopen" );
|
||||
res = -1;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -181,7 +200,9 @@ static void history_load()
|
||||
free( buff );
|
||||
free( fn );
|
||||
last_loaded = history_last;
|
||||
unblock();
|
||||
signal_unblock();
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
void history_init()
|
||||
@@ -198,6 +219,10 @@ static void history_to_hash()
|
||||
{
|
||||
history_data *d;
|
||||
|
||||
if( !mode_name )
|
||||
return;
|
||||
|
||||
|
||||
d = (history_data *)hash_get( &history_table,
|
||||
mode_name );
|
||||
|
||||
@@ -221,12 +246,22 @@ void history_set_mode( wchar_t *name )
|
||||
|
||||
if( mode_name )
|
||||
{
|
||||
/*
|
||||
Move the current history to the hashtable
|
||||
*/
|
||||
history_to_hash();
|
||||
}
|
||||
|
||||
/*
|
||||
See if the new history already exists
|
||||
*/
|
||||
curr = (history_data *)hash_get( &history_table,
|
||||
name );
|
||||
if( curr )
|
||||
{
|
||||
/*
|
||||
Yes. Restore it.
|
||||
*/
|
||||
mode_name = (wchar_t *)hash_get_key( &history_table,
|
||||
name );
|
||||
history_current = history_last = curr->last;
|
||||
@@ -236,6 +271,9 @@ void history_set_mode( wchar_t *name )
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
Nope. Create a new history list.
|
||||
*/
|
||||
history_count=0;
|
||||
history_last = history_current = last_loaded=0;
|
||||
mode_name = wcsdup( name );
|
||||
@@ -287,7 +325,9 @@ static void history_save()
|
||||
history_count=0;
|
||||
past_end=1;
|
||||
|
||||
history_load( mode_name );
|
||||
if( !history_load() )
|
||||
{
|
||||
|
||||
if( real_pos != 0 )
|
||||
{
|
||||
/*
|
||||
@@ -345,6 +385,8 @@ static void history_save()
|
||||
}
|
||||
free( fn );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -352,7 +394,7 @@ static void history_save()
|
||||
Save the specified mode to file
|
||||
*/
|
||||
|
||||
static void history_destroy_mode( const void *name, const void *link )
|
||||
static void history_destroy_mode( void *name, void *link )
|
||||
{
|
||||
mode_name = (wchar_t *)name;
|
||||
history_data *d = (history_data *)link;
|
||||
@@ -362,7 +404,7 @@ static void history_destroy_mode( const void *name, const void *link )
|
||||
past_end=1;
|
||||
|
||||
// fwprintf( stderr, L"Destroy history mode \'%ls\'\n", mode_name );
|
||||
|
||||
|
||||
if( history_last )
|
||||
{
|
||||
history_save();
|
||||
@@ -381,11 +423,12 @@ static void history_destroy_mode( const void *name, const void *link )
|
||||
|
||||
void history_destroy()
|
||||
{
|
||||
|
||||
/**
|
||||
Make sure current mode is in table
|
||||
*/
|
||||
history_to_hash();
|
||||
|
||||
|
||||
/**
|
||||
Save all modes in table
|
||||
*/
|
||||
@@ -404,7 +447,13 @@ void history_destroy()
|
||||
static ll_node_t *history_find( ll_node_t *n, const wchar_t *s )
|
||||
{
|
||||
if( !is_loaded )
|
||||
history_load();
|
||||
{
|
||||
if( history_load() )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( n == 0 )
|
||||
return 0;
|
||||
@@ -423,7 +472,13 @@ void history_add( const wchar_t *str )
|
||||
ll_node_t *old_node;
|
||||
|
||||
if( !is_loaded )
|
||||
history_load();
|
||||
{
|
||||
if( history_load() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( wcslen( str ) == 0 )
|
||||
return;
|
||||
@@ -474,13 +529,19 @@ static int history_test( const wchar_t *needle, const wchar_t *haystack )
|
||||
/*
|
||||
return wcsncmp( haystack, needle, wcslen(needle) )==0;
|
||||
*/
|
||||
return (int)wcsstr( haystack, needle );
|
||||
return !!wcsstr( haystack, needle );
|
||||
}
|
||||
|
||||
const wchar_t *history_prev_match( const wchar_t *str )
|
||||
{
|
||||
if( !is_loaded )
|
||||
history_load();
|
||||
{
|
||||
if( history_load() )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( history_current == 0 )
|
||||
return str;
|
||||
@@ -504,7 +565,13 @@ const wchar_t *history_prev_match( const wchar_t *str )
|
||||
const wchar_t *history_next_match( const wchar_t *str)
|
||||
{
|
||||
if( !is_loaded )
|
||||
history_load();
|
||||
{
|
||||
if( history_load() )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( history_current == 0 )
|
||||
return str;
|
||||
@@ -542,9 +609,15 @@ wchar_t *history_get( int idx )
|
||||
{
|
||||
ll_node_t *n;
|
||||
int i;
|
||||
|
||||
if( !is_loaded )
|
||||
history_load();
|
||||
|
||||
{
|
||||
if( history_load() )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
n = history_last;
|
||||
|
||||
if( idx<0)
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
#apm
|
||||
complete -f -c apm -s V -l version -d (_ "Display version and exit")
|
||||
complete -f -c apm -s v -l verbose -d (_ "Print APM info")
|
||||
complete -f -c apm -s m -l minutes -d (_ "Print time remaining")
|
||||
complete -f -c apm -s M -l monitor -d (_ "Monitor status info")
|
||||
complete -f -c apm -s S -l standby -d (_ "Request APM standby mode")
|
||||
complete -f -c apm -s s -l suspend -d (_ "Request APM suspend mode")
|
||||
complete -f -c apm -s d -l debug -d (_ "APM status debugging info")
|
||||
@@ -1,21 +0,0 @@
|
||||
|
||||
function __fish_complete_apropos
|
||||
if test (commandline -ct)
|
||||
set str (commandline -ct)
|
||||
apropos $str|sed -e "s/^\(.*$str\([^ ]*\).*\)$/$str\2\t\1/"
|
||||
end
|
||||
end
|
||||
|
||||
complete -xc apropos -a '(__fish_complete_apropos)' -d (_ "whatis entry")
|
||||
|
||||
complete -c apropos -s h -l help -d (_ "Display help and exit")
|
||||
complete -f -c apropos -s d -l debug -d (_ "Print debugging info")
|
||||
complete -f -c apropos -s v -l verbose -d (_ "Verbose mode")
|
||||
complete -f -c apropos -s r -l regex -d (_ "Keyword as regex")
|
||||
complete -f -c apropos -s w -l wildcard -d (_ "Keyword as wildwards")
|
||||
complete -f -c apropos -s e -l exact -d (_ "Keyword as exactly match")
|
||||
complete -x -c apropos -s m -l system -d (_ "Search for other system")
|
||||
complete -x -c apropos -s M -l manpath -a '(echo $MANPATH)' -d (_ "Specify man path")
|
||||
complete -x -c apropos -s C -l config-file -d (_ "Specify a configuration file")
|
||||
complete -f -c apropos -s V -l version -d (_ "Display version and exit")
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
|
||||
#apt-build
|
||||
complete -c apt-build -l help -d (_ "Display help and exit")
|
||||
complete -f -c apt-build -a update -d (_ "Update list of packages")
|
||||
complete -f -c apt-build -a upgrade -d (_ "Upgrade packages")
|
||||
complete -f -c apt-bulid -a world -d (_ "Rebuild your system")
|
||||
complete -x -c apt-build -a install -d (_ "Build and install a new package")
|
||||
complete -x -c apt-build -a source -d (_ "Download and extract a source")
|
||||
complete -x -c apt-build -a info -d (_ "Info on a package")
|
||||
complete -x -c apt-build -a remove -d (_ "Remove packages")
|
||||
complete -x -c apt-build -a clean-build -d (_ "Erase built packages")
|
||||
complete -x -c apt-build -a build-source -d (_ "Build source without install")
|
||||
complete -x -c apt-build -a clean-sources -d (_ "Clean source directories")
|
||||
complete -x -c apt-build -a update-source -d (_ "Update source and rebuild")
|
||||
complete -x -c apt-build -a update-repository -d (_ "Update the repository")
|
||||
complete -f -c apt-build -l nowrapper -d (_ "Do not use gcc wrapper")
|
||||
complete -f -c apt-build -l remove-builddep -d (_ "Remove build-dep")
|
||||
complete -f -c apt-build -l no-source -d (_ "Do not download source")
|
||||
complete -f -c apt-build -l build-dir -d (_ "Specify build-dir")
|
||||
complete -f -c apt-build -l rebuild -d (_ "Rebuild a package")
|
||||
complete -f -c apt-build -l reinstall -d (_ "Rebuild and install an installed package")
|
||||
complete -r -f -c apt-build -l build-command -d (_ "Use <command> to build")
|
||||
complete -r -c apt-build -l patch -d (_ "Apply <file> patch")
|
||||
complete -c apt-build -s p -l patch-strip -d (_ "Prefix to strip on patch")
|
||||
complete -c apt-build -s y -l yes -d (_ "Assume yes to all questions")
|
||||
complete -c apt-build -l purge -d (_ "Use purge instead of remove")
|
||||
complete -c apt-build -l noupdate -d (_ "Do not run update")
|
||||
complete -r -c apt-build -l source-list -d (_ "Specify sources.list file")
|
||||
complete -f -c apt-build -s v -l version -d (_ "Display version and exit")
|
||||
@@ -1,31 +0,0 @@
|
||||
#apt-cache
|
||||
complete -c apt-cache -s h -l help -d (_ "Display help and exit")
|
||||
complete -f -c apt-cache -a gencaches -d (_ "Build apt cache")
|
||||
complete -x -c apt-cache -a showpkg -d (_ "Show package info")
|
||||
complete -f -c apt-cache -a stats -d (_ "Show cache statistics")
|
||||
complete -x -c apt-cache -a showsrc -d (_ "Show source package")
|
||||
complete -f -c apt-cache -a dump -d (_ "Show packages in cache")
|
||||
complete -f -c apt-cache -a dumpavail -d (_ "Print available list")
|
||||
complete -f -c apt-cache -a unmet -d (_ "List unmet dependencies in cache")
|
||||
complete -x -c apt-cache -a show -d (_ "Display package record")
|
||||
complete -x -c apt-cache -a search -d (_ "Search packagename by REGEX")
|
||||
complete -c apt-cache -l full -a search -d (_ "Search full package name")
|
||||
complete -x -c apt-cache -l names-only -a search -d (_ "Search packagename only")
|
||||
complete -x -c apt-cache -a depends -d (_ "List dependencies for the package")
|
||||
complete -x -c apt-cache -a rdepends -d (_ "List reverse dependencies for the package")
|
||||
complete -x -c apt-cache -a pkgnames -d (_ "Print package name by prefix")
|
||||
complete -x -c apt-cache -a dotty -d (_ "Generate dotty output for packages")
|
||||
complete -x -c apt-cache -a policy -d (_ "Debug preferences file")
|
||||
complete -r -c apt-cache -s p -l pkg-cache -d (_ "Select file to store package cache")
|
||||
complete -r -c apt-cache -s s -l src-cache -d (_ "Select file to store source cache")
|
||||
complete -f -c apt-cache -s q -l quiet -d (_ "Quiet mode")
|
||||
complete -f -c apt-cache -s i -l important -d (_ "Print important dependencies")
|
||||
complete -f -c apt-cache -s a -l all-versions -d (_ "Print full records")
|
||||
complete -f -c apt-cache -s g -l generate -d (_ "Auto-gen package cache")
|
||||
complete -f -c apt-cache -l all-names -d (_ "Print all names")
|
||||
complete -f -c apt-cache -l recurse -d (_ "Dep and rdep recursive")
|
||||
complete -f -c apt-cache -l installed -d (_ "Limit to installed")
|
||||
complete -f -c apt-cache -s v -l version -d (_ "Display version and exit")
|
||||
complete -r -c apt-cache -s c -l config-file -d (_ "Specify config file")
|
||||
complete -x -c apt-cache -s o -l option -d (_ "Specify options")
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
#apt-cdrom
|
||||
complete -c apt-cdrom -s h -l help -d (_ "Display help and exit")
|
||||
complete -r -c apt-cdrom -a add -d (_ "Add new disc to source list")
|
||||
complete -x -c apt-cdrom -a ident -d (_ "Report identity of disc")
|
||||
complete -r -c apt-cdrom -s d -l cdrom -d (_ "Mount point")
|
||||
complete -f -c apt-cdrom -s r -l rename -d (_ "Rename a disc")
|
||||
complete -f -c apt-cdrom -s m -l no-mount -d (_ "No mounting")
|
||||
complete -f -c apt-cdrom -s f -l fast -d (_ "Fast copy")
|
||||
complete -f -c apt-cdrom -s a -l thorough -d (_ "Thorough package scan")
|
||||
complete -f -c apt-cdrom -s n -l no-act -d (_ "No changes")
|
||||
complete -f -c apt-cdrom -s v -l version -d (_ "Display version and exit")
|
||||
complete -r -c apt-cdrom -s c -l config-file -d (_ "Specify config file")
|
||||
complete -x -c apt-cdrom -s o -l option -d (_ "Specify options")
|
||||
@@ -1,7 +0,0 @@
|
||||
#apt-config
|
||||
complete -c apt-config -s h -l help -d (_ "Display help and exit")
|
||||
complete -c apt-config -a shell -d (_ "Access config file from shell")
|
||||
complete -f -c apt-config -a dump -d (_ "Dump contents of config file")
|
||||
complete -f -c apt-config -s v -l version -d (_ "Display version and exit")
|
||||
complete -r -c apt-config -s c -l config-file -d (_ "Specify config file")
|
||||
complete -x -c apt-config -s o -l option -d (_ "Specify options")
|
||||
@@ -1,7 +0,0 @@
|
||||
|
||||
#apt-extracttemplates
|
||||
complete -c apt-extracttemplates -s h -l help -d (_ "Display help and exit")
|
||||
complete -r -c apt-extracttemplates -s t -d (_ "Set temp dir")
|
||||
complete -r -c apt-extracttemplates -s c -d (_ "Specifiy config file")
|
||||
complete -r -c apt-extracttemplates -s o -d (_ "Specify options")
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
#apt-file
|
||||
complete -c apt-file -s h -l help -d (_ "Display help and exit")
|
||||
complete -x -c apt-file -a update -d (_ "Resync package contents from source")
|
||||
complete -r -c apt-file -a search -d (_ "Search package containing pattern")
|
||||
complete -r -c apt-file -a list -d (_ "List contents of a package matching pattern")
|
||||
complete -x -c apt-file -a purge -d (_ "Remove all gz files from cache")
|
||||
complete -r -c apt-file -s c -l cache -d (_ "Set cache dir")
|
||||
complete -f -c apt-file -s v -l verbose -d (_ "Verbose mode")
|
||||
complete -c apt-file -s d -l cdrom-mount -d (_ "Use cdrom-mount-point")
|
||||
complete -f -c apt-file -s i -l ignore-case -d (_ "Do not expand pattern")
|
||||
complete -f -c apt-file -s x -l regexp -d (_ "Pattern is regexp")
|
||||
complete -f -c apt-file -s V -l version -d (_ "Display version and exit")
|
||||
complete -f -c apt-file -s a -l architecture -d (_ "Set arch")
|
||||
complete -r -c apt-file -s s -l sources-list -a "(ls /etc/apt)" -d (_ "Set sources.list file")
|
||||
complete -f -c apt-file -s l -l package-only -d (_ "Only display package name")
|
||||
complete -f -c apt-file -s F -l fixed-string -d (_ "Do not expand pattern")
|
||||
complete -f -c apt-file -s y -l dummy -d (_ "Run in dummy mode")
|
||||
@@ -1,17 +0,0 @@
|
||||
#apt-ftparchive
|
||||
complete -c apt-ftparchive -s h -l help -d (_ "Display help and exit")
|
||||
complete -f -c apt-ftparchive -a packages -d (_ "Generate package from source")
|
||||
complete -f -c apt-ftparchive -a sources -d (_ "Generate source index file")
|
||||
complete -f -c apt-ftparchive -a contents -d (_ "Generate contents file")
|
||||
complete -f -c apt-ftparchive -a release -d (_ "Generate release file")
|
||||
complete -f -c apt-ftparchive -a clean -d (_ "Remove records")
|
||||
complete -f -c apt-ftparchive -l md5 -d (_ "Generate MD5 sums")
|
||||
complete -f -c apt-ftparchive -s d -l db -d (_ "Use a binary db")
|
||||
complete -f -c apt-ftparchive -s q -l quiet -d (_ "Quiet mode")
|
||||
complete -f -c apt-ftparchive -l delink -d (_ "Perform delinking")
|
||||
complete -f -c apt-ftparchive -l contents -d (_ "Perform contents generation")
|
||||
complete -c apt-ftparchive -s s -l source-override -d (_ "Use source override")
|
||||
complete -f -c apt-ftparchive -l readonly -d (_ "Make caching db readonly")
|
||||
complete -f -c apt-ftparchive -s v -l version -d (_ "Display version and exit")
|
||||
complete -r -c apt-ftparchive -s c -l config-file -d (_ "Use config file")
|
||||
complete -r -c apt-ftparchive -s o -l option -d (_ "Set config options")
|
||||
@@ -1,64 +0,0 @@
|
||||
#completion for apt-get
|
||||
|
||||
function __fish_apt_no_subcommand -d (_ 'Test if apt has yet to be given the subcommand')
|
||||
for i in (commandline -opc)
|
||||
if contains -- $i update upgrade dselect-upgrade dist-upgrade install remove source build-dep check clean autoclean
|
||||
return 1
|
||||
end
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
function __fish_apt_use_package -d (_ 'Test if apt command should have packages as potential completion')
|
||||
for i in (commandline -opc)
|
||||
if contains -- $i contains install remove build-dep
|
||||
return 0
|
||||
end
|
||||
end
|
||||
return 1
|
||||
end
|
||||
|
||||
complete -c apt-get -n '__fish_apt_use_package' -a '(__fish_print_packages)' -d (_ 'Package')
|
||||
|
||||
complete -c apt-get -s h -l help -d (_ 'Display help and exit')
|
||||
complete -f -n '__fish_apt_no_subcommand' -c apt-get -a 'update' -d (_ 'Update sources')
|
||||
complete -f -n '__fish_apt_no_subcommand' -c apt-get -a 'upgrade' -d (_ 'Upgrade or install newest packages')
|
||||
complete -f -n '__fish_apt_no_subcommand' -c apt-get -a 'dselect-upgrade' -d (_ 'Use with dselect front-end')
|
||||
complete -f -n '__fish_apt_no_subcommand' -c apt-get -a 'dist-upgrade' -d (_ 'Distro upgrade')
|
||||
complete -f -n '__fish_apt_no_subcommand' -c apt-get -a 'install' -d (_ 'Install one or more packages')
|
||||
complete -f -n '__fish_apt_no_subcommand' -c apt-get -a 'remove' -d (_ 'Remove one or more packages')
|
||||
complete -f -n '__fish_apt_no_subcommand' -c apt-get -a 'source' -d (_ 'Fetch source packages')
|
||||
complete -f -n '__fish_apt_no_subcommand' -c apt-get -a 'build-dep' -d (_ 'Install/remove packages for dependencies')
|
||||
complete -f -n '__fish_apt_no_subcommand' -c apt-get -a 'check' -d (_ 'Update cache and check dependencies')
|
||||
complete -f -n '__fish_apt_no_subcommand' -c apt-get -a 'clean' -d (_ 'Clean local caches and packages')
|
||||
complete -f -n '__fish_apt_no_subcommand' -c apt-get -a 'autoclean' -d (_ 'Clean packages no longer be downloaded')
|
||||
complete -c apt-get -s d -l download-only -d (_ 'Download Only')
|
||||
complete -c apt-get -s f -l fix-broken -d (_ 'Correct broken dependencies')
|
||||
complete -c apt-get -s m -l fix-missing -d (_ 'Ignore missing packages')
|
||||
complete -c apt-get -l no-download -d (_ 'Disable downloading packages')
|
||||
complete -c apt-get -s q -l quiet -d (_ 'Quiet mode')
|
||||
complete -c apt-get -s s -l simulate -d (_ 'Perform a simulation')
|
||||
complete -c apt-get -s y -l assume-yes -d (_ 'Automatic yes to prompts')
|
||||
complete -c apt-get -s u -l show-upgraded -d (_ 'Show upgraded packages')
|
||||
complete -c apt-get -s V -l verbose-versions -d (_ 'Show full versions for packages')
|
||||
complete -c apt-get -s b -l compile -d (_ 'Compile source packages')
|
||||
complete -c apt-get -s b -l build -d (_ 'Compile source packages')
|
||||
complete -c apt-get -l ignore-hold -d (_ 'Ignore package Holds')
|
||||
complete -c apt-get -l no-upgrade -d (_ "Do not upgrade packages")
|
||||
complete -c apt-get -l force-yes -d (_ 'Force yes')
|
||||
complete -c apt-get -l print-uris -d (_ 'Print the URIs')
|
||||
complete -c apt-get -l purge -d (_ 'Use purge instead of remove')
|
||||
complete -c apt-get -l reinstall -d (_ 'Reinstall packages')
|
||||
complete -c apt-get -l list-cleanup -d (_ 'Erase obsolete files')
|
||||
complete -c apt-get -s t -l target-release -d (_ 'Control default input to the policy engine')
|
||||
complete -c apt-get -l trivial-only -d (_ 'Only perform operations that are trivial')
|
||||
complete -c apt-get -l no-remove -d (_ 'Abort if any packages are to be removed')
|
||||
complete -c apt-get -l only-source -d (_ 'Only accept source packages')
|
||||
complete -c apt-get -l diff-only -d (_ 'Download only diff file')
|
||||
complete -c apt-get -l tar-only -d (_ 'Download only tar file')
|
||||
complete -c apt-get -l arch-only -d (_ 'Only process arch-dependant build-dependencies')
|
||||
complete -c apt-get -l allow-unauthenticated -d (_ 'Ignore non-authenticated packages')
|
||||
complete -c apt-get -s v -l version -d (_ 'Display version and exit')
|
||||
complete -r -c apt-get -s c -l config-file -d (_ 'Specify a config file')
|
||||
complete -r -c apt-get -s o -l option -d (_ 'Set a config option')
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
#apt-key
|
||||
complete -r -c apt-key -a add -d (_ "Add a new key")
|
||||
complete -f -c apt-key -a del -d (_ "Remove a key")
|
||||
complete -f -c apt-key -a list -d (_ "List trusted keys")
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
#apt-listbugs
|
||||
complete -c apt-listbugs -s h -l help -d (_ "Display help and exit")
|
||||
complete -f -c apt-listbugs -s s -l severity -a "critical grave" -d (_ "Set severity")
|
||||
complete -f -c apt-listbugs -s T -l tag -d (_ "Tags you want to see")
|
||||
complete -f -c apt-listbugs -s S -l stats -a "outstanding 'pending upload' resolved done open" -d (_ "Bug-status you want to see")
|
||||
complete -f -c apt-listbugs -s l -l showless -d (_ "Ignore bugs in your system")
|
||||
complete -f -c apt-listbugs -s g -l showgreater -d (_ "Ignore newer bugs than upgrade packages")
|
||||
complete -f -c apt-listbugs -s D -l show-downgrade -d (_ "Bugs for downgrade packages")
|
||||
complete -f -c apt-listbugs -s H -l hostname -a "osdn.debian.or.jp" -d (_ "Bug Tracking system")
|
||||
complete -f -c apt-listbugs -s p -l port -d (_ "Specify port for web interface")
|
||||
complete -f -c apt-listbugs -s R -l release-critical -d (_ "Use daily bug report")
|
||||
complete -f -c apt-listbugs -s I -l index -d (_ "Use the raw index.db")
|
||||
complete -f -c apt-listbugs -s X -l indexdir -d (_ "Specify index dir")
|
||||
complete -f -c apt-listbugs -s P -l pin-priority -d (_ "Specify Pin-Priority value")
|
||||
complete -f -c apt-listbugs -l title -d (_ "Specify the title of rss")
|
||||
complete -f -c apt-listbugs -s f -l force-download -d (_ "Retrieve fresh bugs")
|
||||
complete -f -c apt-listbugs -s q -l quiet -d (_ "Do not display progress bar")
|
||||
complete -f -c apt-listbugs -s c -l cache-dir -a "/var/cache/apt-listbugs/" -d (_ "Specify local cache dir")
|
||||
complete -f -c apt-listbugs -s t -l timer -d (_ "Specify the expire cache timer")
|
||||
complete -c apt-listbugs -s C -l aptconf -d (_ "Specify apt config file")
|
||||
complete -f -c apt-listbugs -s y -l force-yes -d (_ "Assume yes to all questions")
|
||||
complete -f -c apt-listbugs -s n -l force-no -d (_ "Assume no to all questions")
|
||||
complete -c apt-listbugs -a list -d (_ "List bugs from packages")
|
||||
complete -c apt-listbugs -a rss -d (_ "List bugs in rss format")
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
#apt-listchanges
|
||||
complete -c apt-listchanges -l help -d (_ "Display help and exit")
|
||||
complete -c apt-listchanges -l apt -d (_ "Read filenames from pipe")
|
||||
complete -f -c apt-listchanges -s v -l verbose -d (_ "Verbose mode")
|
||||
complete -f -c apt-listchanges -s f -l frontend -a "pager browser xterm-pager xterm-browser text mail none" -d (_ "Select frontend interface")
|
||||
complete -r -f -c apt-listchanges -l email-address -d (_ "Specify email address")
|
||||
complete -f -c apt-listchanges -s c -l confirm -d (_ "Ask confirmation")
|
||||
complete -f -c apt-listchanges -s a -l all -d (_ "Display all changelogs")
|
||||
complete -r -c apt-listchanges -l save_seen -d (_ "Avoid changelogs from db in named file")
|
||||
complete -r -f -c apt-listchanges -l which -a "news changelogs both" -d (_ "Select display")
|
||||
complete -f -c apt-listchanges -s h -l headers -d (_ "Insert header")
|
||||
complete -f -c apt-listchanges -l debug -d (_ "Display debug info")
|
||||
complete -r -c apt-listchanges -l profile -d (_ "Select an option profile")
|
||||
@@ -1,22 +0,0 @@
|
||||
#apt-move
|
||||
complete -c apt-move -a get -d (_ "Generate master file")
|
||||
complete -c apt-move -a getlocal -d (_ "Alias for 'get'")
|
||||
complete -f -c apt-move -a move -d (_ "Move packages to local tree")
|
||||
complete -f -c apt-move -a delete -d (_ "Delete obsolete package files")
|
||||
complete -f -c apt-move -a packages -d (_ "Build new local files")
|
||||
complete -f -c apt-move -a fsck -d (_ "Rebuild index files")
|
||||
complete -f -c apt-move -a update -d (_ "Move packages from cache to local mirror")
|
||||
complete -f -c apt-move -a local -d (_ "Alias for 'move delete packages'")
|
||||
complete -f -c apt-move -a localupdate -d (_ "Alias for 'update'")
|
||||
complete -f -c apt-move -a mirror -d (_ "Download package missing from mirror")
|
||||
complete -f -c apt-move -a sync -d (_ "Sync packages installed")
|
||||
complete -f -c apt-move -a exclude -d 'test $LOCALDIR/.exclude file'
|
||||
complete -c apt-move -a movefile -d (_ "Move file specified on commandline")
|
||||
complete -f -c apt-move -a listbin -d (_ "List packages that may serve as input to mirrorbin or mirrorsource" )
|
||||
complete -f -c apt-move -a mirrorbin -d (_ "Fetch package from STDIN")
|
||||
complete -f -c apt-move -a mirrorsrc -d (_ "Fetch source package from STDIN")
|
||||
complete -f -c apt-move -s a -d (_ "Process all packages")
|
||||
complete -c apt-move -s c -d (_ "Use specific conffile")
|
||||
complete -f -c apt-move -s f -d (_ "Force deletion")
|
||||
complete -f -c apt-move -s q -d (_ "Suppresses normal output")
|
||||
complete -f -c apt-move -s t -d (_ "Test run")
|
||||
@@ -1,10 +0,0 @@
|
||||
#apt-proxy-import
|
||||
complete -c apt-proxy-import -s h -l help -d (_ 'Display help and exit')
|
||||
complete -f -c apt-proxy-import -s V -l version -d (_ 'Display version and exit')
|
||||
complete -f -c apt-proxy-import -s v -l verbose -d (_ 'Verbose mode')
|
||||
complete -f -c apt-proxy-import -s q -l quiet -d (_ 'No message to STDOUT')
|
||||
complete -f -c apt-proxy-import -s r -l recursive -d (_ 'Recurse into subdir')
|
||||
complete -r -c apt-proxy-import -s i -l import-dir -a '(ls -Fp|grep /$)' -d (_ 'Dir to import')
|
||||
complete -r -c apt-proxy-import -s u -l user -a '(__fish_complete_users)' -d (_ 'Change to user')
|
||||
complete -r -c apt-proxy-import -s d -l debug -d (_ 'Debug level[default 0]')
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
#apt-rdepends
|
||||
complete -c apt-rdepends -l help -d (_ "Display help and exit")
|
||||
complete -f -c apt-rdepends -s b -l build-depends -d (_ "Show build dependencies")
|
||||
complete -f -c apt-rdepends -s d -l dotty -d (_ "Generate a dotty graph")
|
||||
complete -f -c apt-rdepends -s p -l print-state -d (_ "Show state of dependencies")
|
||||
complete -f -c apt-rdepends -s r -l reverse -d (_ "List packages depending on")
|
||||
complete -r -f -c apt-rdepends -s f -l follow -d (_ "Comma-separated list of dependancy types to follow recursively")
|
||||
complete -r -f -c apt-rdepends -s s -l show -d (_ "Comma-separated list of dependancy types to show")
|
||||
complete -r -f -c apt-rdepends -l state-follow -d (_ "Comma-separated list of package installation states to follow recursively")
|
||||
complete -r -f -c apt-rdepends -l state-show -d (_ "Comma-separated list of package installation states to show")
|
||||
complete -f -c apt-rdepends -l man -d (_ "Display man page")
|
||||
complete -f -c apt-rdepends -l version -d (_ "Display version and exit")
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
#apt-setup
|
||||
complete -c apt-setup -a probe -d (_ "Probe a CD")
|
||||
complete -c apt-setup -s N -d (_ "Run in noninteractive mode")
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
#apt-show-source
|
||||
complete -c apt-show-source -s h -l help -d (_ 'Display help and exit')
|
||||
complete -r -c apt-show-source -l status-file -d (_ 'Read package from file') -f
|
||||
complete -r -c apt-show-source -o stf -d (_ 'Read package from file') -f
|
||||
complete -r -c apt-show-source -l list-dir -a '(ls -Fp .|grep /$) /var/lib/apt/lists' -d (_ 'Specify APT list dir')
|
||||
complete -r -c apt-show-source -o ld -a '(ls -Fp .|grep /$) /var/lib/apt/lists' -d (_ 'Specify APT list dir')
|
||||
complete -r -c apt-show-source -s p -l package -a '(apt-cache pkgnames)' -d (_ 'List PKG info')
|
||||
complete -f -c apt-show-source -l version-only -d (_ 'Display version and exit')
|
||||
complete -f -c apt-show-source -s a -l all -d (_ 'Print all source packages with version')
|
||||
complete -f -c apt-show-source -s v -l verbose -d (_ 'Verbose mode')
|
||||
@@ -1,14 +0,0 @@
|
||||
#apt-show-versions
|
||||
complete -c apt-show-source -s h -l help -d (_ 'Display help and exit')
|
||||
complete -r -c apt-show-versions -s p -l packages -a '(apt-cache pkgnames)' -d (_ 'Print PKG versions')
|
||||
complete -f -c apt-show-versions -s r -l regex -d (_ 'Using regex')
|
||||
complete -f -c apt-show-versions -s u -l upgradeable -d (_ 'Print only upgradeable packages')
|
||||
complete -f -c apt-show-versions -s a -l allversions -d (_ 'Print all versions')
|
||||
complete -f -c apt-show-versions -s b -l brief -d (_ 'Print package name/distro')
|
||||
complete -f -c apt-show-versions -s v -l verbose -d (_ 'Print verbose info')
|
||||
complete -f -c apt-show-versions -s i -l initialize -d (_ 'Init or update cache only')
|
||||
complete -r -c apt-show-versions -l status-file -d (_ 'Read package from file')
|
||||
complete -r -c apt-show-versions -o stf -d (_ 'Read package from file')
|
||||
complete -r -c apt-show-versions -l list-dir -a '(ls -Fp .|grep /$) /var/lib/apt/lists /var/state/apt/lists' -d (_ 'Specify APT list dir')
|
||||
complete -r -c apt-show-versions -o ld -a '(ls -Fp .|grep /$) /var/lib/apt/lists /var/state/apt/lists' -d (_ 'Specify APT list dir')
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
#apt-sortpkgs
|
||||
complete -c apt-sortpkgs -s h -l help -d (_ "Display help and exit")
|
||||
complete -f -c apt-sortpkgs -s s -l source -d (_ "Use source index field")
|
||||
complete -f -c apt-sortpkgs -s v -l version -d (_ "Display version and exit")
|
||||
complete -r -c apt-sortpkgs -s c -l conf-file -d (_ "Specify conffile")
|
||||
complete -r -f -c apt-sortpkgs -s o -l option -d (_ "Set config options")
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
#apt-spy
|
||||
complete -c apt-spy -s h -d (_ "Display help and exit")
|
||||
complete -f -c apt-spy -s d -a "stable testing unstable" -d (_ "Debian distribution")
|
||||
complete -f -c apt-spy -s a -a "Africa Asia Europe North-America Oceania South-America" -d (_ "Servers in the areas")
|
||||
complete -c apt-spy -s c -d (_ "Conf file")
|
||||
complete -f -c apt-spy -s e -d (_ "Finish after number of servers")
|
||||
complete -c apt-spy -s f -d (_ "File to grab servers")
|
||||
complete -c apt-spy -s i -d (_ "File as input")
|
||||
complete -c apt-spy -s m -d (_ "Mirror-list file")
|
||||
complete -c apt-spy -s o -d (_ "Output sources.list file")
|
||||
complete -f -c apt-spy -s p -d (_ "Use proxy server")
|
||||
complete -f -c apt-spy -s s -d (_ "Comma separated country list")
|
||||
complete -f -c apt-spy -s t -d (_ "How long in sec to download")
|
||||
complete -f -c apt-spy -s u -d (_ "Custom URL to get mirror list")
|
||||
complete -c apt-spy -s w -d (_ "Write top servers to file")
|
||||
complete -f -c apt-spy -s n -d (_ "Number of top servers")
|
||||
complete -f -c apt-spy -a "update" -d (_ "Update mirror list")
|
||||
complete -f -c apt-spy -s v -d (_ "Version number")
|
||||
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
#apt-src
|
||||
complete -c apt-src -s h -l help -d (_ "Display help and exit")
|
||||
complete -f -c apt-src -a "update" -d (_ "Update list of source packages")
|
||||
complete -f -c apt-src -a "install" -d (_ "Install source packages")
|
||||
complete -f -c apt-src -a "upgrade" -d (_ "Upgrade source packages")
|
||||
complete -f -c apt-src -a "remove" -d (_ "Remove source packages")
|
||||
complete -f -c apt-src -a "build" -d (_ "Build source packages")
|
||||
complete -f -c apt-src -a "clean" -d (_ "Clean source packages")
|
||||
complete -f -c apt-src -a "import" -d (_ "Detect known source tree")
|
||||
complete -f -c apt-src -a "list" -d (_ "List installed source package\(s\)")
|
||||
complete -f -c apt-src -a "location" -d (_ "Root source tree")
|
||||
complete -f -c apt-src -a "version" -d (_ "Version of source package")
|
||||
complete -f -c apt-src -a "name" -d (_ "Name of the source package")
|
||||
complete -f -c apt-src -s b -l build -d (_ "Build source packages")
|
||||
complete -f -c apt-src -s i -l installdebs -d (_ "Install after build")
|
||||
complete -f -c apt-src -s p -l patch -d (_ "Patch local changes")
|
||||
complete -r -c apt-src -s l -l location -d (_ "Specify a dir")
|
||||
complete -c apt-src -s c -l here -d (_ "Run on current dir")
|
||||
complete -f -c apt-src -l upstream-version -d (_ "Omit debian version")
|
||||
complete -f -c apt-src -s k -l keep-built -d (_ "Do not del built files")
|
||||
complete -f -c apt-src -s n -l no-delete-source -d (_ "Do not del source files")
|
||||
complete -f -c apt-src -l version -d (_ "Source tree version")
|
||||
complete -f -c apt-src -s q -l quiet -d (_ "Output to /dev/null")
|
||||
complete -f -c apt-src -s t -l trace -d (_ "Output trace")
|
||||
@@ -1,10 +0,0 @@
|
||||
#apt-zip-inst
|
||||
complete -c apt-zip-inst -s h -l help -d (_ "Display help and exit")
|
||||
complete -f -c apt-zip-inst -s V -l version -d (_ "Display version and exit")
|
||||
complete -c apt-zip-inst -s m -l medium -d (_ "Removable medium")
|
||||
complete -f -c apt-zip-inst -s a -l aptgetaction -a "dselect-upgrade upgrade dist-upgrade" -d (_ "Select an action")
|
||||
complete -c apt-zip-inst -s p -l packages -d (_ "List of packages to install")
|
||||
complete -f -c apt-zip-inst -s f -l fix-broken -d (_ "Fix broken option")
|
||||
complete -c apt-zip-inst -l skip-mount -d (_ "Specify a non-mountpoint dir")
|
||||
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
#apt-zip-list
|
||||
complete -c apt-zip-list -s h -l help -d (_ "Display help and exit")
|
||||
complete -f -c apt-zip-list -s V -l version -d (_ "Display version and exit")
|
||||
complete -c apt-zip-list -s m -l medium -d (_ "Removable medium")
|
||||
complete -f -c apt-zip-list -s a -l aptgetaction -a "dselect-upgrade upgrade dist-upgrade" -d (_ "Select an action")
|
||||
complete -c apt-zip-list -s p -l packages -d (_ "List of packages to install")
|
||||
complete -f -c apt-zip-list -s f -l fix-broken -d (_ "Fix broken option")
|
||||
complete -c apt-zip-list -l skip-mount -d (_ "Specify a non-mountpoint dir")
|
||||
complete -c apt-zip-list -s M -l method -d (_ "Select a method")
|
||||
complete -c apt-zip-list -s o -l options -a "tar restart" -d (_ "Specify options")
|
||||
complete -c apt-zip-list -s A -l accept -a "http ftp" -d (_ "Accept protocols")
|
||||
complete -c apt-zip-list -s R -l reject -a "http ftp" -d (_ "Reject protocols")
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
#completion for arp
|
||||
complete -c arp -s v -l verbose -d (_ "Verbose mode")
|
||||
complete -c arp -s n -l numeric -d (_ "Numerical address")
|
||||
complete -x -c arp -s H -l tw-type -a "ether arcnet pronet ax25 netrom" -d (_ "Class of hw type")
|
||||
complete -c arp -s a -l display -x -a "(__fish_print_hostnames)" -d (_ "Show arp entries")
|
||||
complete -x -c arp -s d -l delete -a "(__fish_print_hostnames)" -d (_ "Remove an entry for hostname")
|
||||
complete -c arp -s D -l use-device -d (_ "Use hardware address")
|
||||
complete -x -c arp -s i -l device -a "(__fish_print_interfaces)" -d (_ "Select interface")
|
||||
complete -x -c arp -s s -l set -d (_ "Manually create ARP address") -a "(__fish_print_hostnames)"
|
||||
complete -f -c arp -s f -l file -d (_ "Take addr from filename, default /etc/ethers")
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
#at
|
||||
complete -f -c at -s V -d (_ "Display version and exit")
|
||||
complete -f -c at -s q -d (_ "Use specified queue")
|
||||
complete -f -c at -s m -d (_ "Send mail to user")
|
||||
complete -c at -s f -x -a "(__fish_complete_suffix (commandline -ct) '' 'At job')" -d (_ "Read job from file")
|
||||
complete -f -c at -s l -d (_ "Alias for atq")
|
||||
complete -f -c at -s d -d (_ "Alias for atrm")
|
||||
complete -f -c at -s v -d (_ "Show the time")
|
||||
complete -f -c at -s c -d (_ "Print the jobs listed")
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
#atd
|
||||
complete -f -c atd -s l -d (_ "Limiting load factor")
|
||||
complete -f -c atd -s b -d (_ "Minimum interval in seconds")
|
||||
complete -f -c atd -s d -d (_ "Debug mode")
|
||||
complete -f -c atd -s s -d (_ "Process at queue only once")
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
#atq
|
||||
complete -f -c atq -s V -d (_ "Display version and exit")
|
||||
complete -f -c atq -s q -d (_ "Use specified queue")
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
#atrm
|
||||
complete -f -c atrm -s V -d (_ "Display version and exit")
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user