シェルスクリプト言語xyzshのソースコード。
修订版 | abc5274fd18d50629cf56df61b532de0ddf619ec (tree) |
---|---|
时间 | 2013-01-31 20:42:40 |
作者 | ab25q <ab25cq@gmai...> |
Commiter | ab25q |
1.3.3
@@ -208,7 +208,7 @@ permission: | ||
208 | 208 | # clean |
209 | 209 | ######################################################## |
210 | 210 | clean: |
211 | - rm -fR xyzsh xyzsh.dSYM src/*.o libxyzsh* xyzsh.exe* config.log config.status *.stackdump autom4te.cache .DS_Store src/ext/*.so src/ext/*.o src/ext/migemo.dSYM | |
211 | + rm -fR xyzsh xyzsh.dSYM src/*.o libxyzsh* xyzsh.exe* config.log config.status *.stackdump autom4te.cache .DS_Store src/ext/*.so src/ext/*.o src/ext/migemo.so.dSYM | |
212 | 212 | |
213 | 213 | distclean: |
214 | - rm -fR xyzsh xyzsh.dSYM src/*.o libxyzsh* config.h Makefile xyzsh.exe* config.log config.status *.stackdump autom4te.cache .DS_Store src/ext/*.so src/ext/*.o src/ext/migemo.dSYM | |
214 | + rm -fR xyzsh xyzsh.dSYM src/*.o libxyzsh* config.h Makefile xyzsh.exe* config.log config.status *.stackdump autom4te.cache .DS_Store src/ext/*.so src/ext/*.o src/ext/migemo.so.dSYM |
@@ -1,20 +0,0 @@ | ||
1 | -<?xml version="1.0" encoding="UTF-8"?> | |
2 | -<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |
3 | -<plist version="1.0"> | |
4 | - <dict> | |
5 | - <key>CFBundleDevelopmentRegion</key> | |
6 | - <string>English</string> | |
7 | - <key>CFBundleIdentifier</key> | |
8 | - <string>com.apple.xcode.dsym.migemo.so</string> | |
9 | - <key>CFBundleInfoDictionaryVersion</key> | |
10 | - <string>6.0</string> | |
11 | - <key>CFBundlePackageType</key> | |
12 | - <string>dSYM</string> | |
13 | - <key>CFBundleSignature</key> | |
14 | - <string>????</string> | |
15 | - <key>CFBundleShortVersionString</key> | |
16 | - <string>1.0</string> | |
17 | - <key>CFBundleVersion</key> | |
18 | - <string>1</string> | |
19 | - </dict> | |
20 | -</plist> |
@@ -1,143 +0,0 @@ | ||
1 | - | |
2 | -print "welcome to migemo.so dynamic library. You can read help type with \"migemo::help 'command name'\""\n | |
3 | - | |
4 | -compl::run( root::object migemo ) | |
5 | - | |
6 | -completion migemo::help ( | |
7 | - migemo::self | egrep native\ function\$ | egrep -v 'run|show' | root::scan '(^.+?):' | each ( | chomp | quote | pomch ) | |
8 | -) | |
9 | - | |
10 | -migemo::run( | |
11 | - object help ( Help ) | |
12 | - | |
13 | - print <<<'EOS' | |
14 | -match (migemo クエリー) | |
15 | -- | |
16 | -パイプからの入力とmigemoクエリーを比較してマッチしたなら、そのマッチした文字範囲のバイト数を返す。 | |
17 | - | |
18 | --quiet リターンコードだけ返し、出力は返さない | |
19 | -EOS | help::set_helps_ja | |
20 | - | |
21 | - print <<<'EOS' | |
22 | -match (migemo querry) | |
23 | -- | |
24 | -Compare migemo querry with input from pipe data and output the string ranges. | |
25 | - | |
26 | --quiet no output. you can get only return code. | |
27 | -EOS | help::set_helps | |
28 | -) | |
29 | - | |
30 | -def common_head ( | |
31 | - | each ( | |
32 | - | chomp| length -utf8 | |
33 | - ) | max | var -local max_length | |
34 | - | |
35 | - print 0 | var -local point | |
36 | - | |
37 | - while(true) ( | |
38 | - | each ( | |
39 | - | chomp | rows -utf8 0..$point | pomch | |
40 | - ) | sys::sort | uniq | wc -l | strip | if(| != 1) ( | |
41 | - -- point; | |
42 | - break | |
43 | - ) | |
44 | - | |
45 | - ++ point; | |
46 | - | |
47 | - if(point | -ge $max_length) ( | |
48 | - -- point | |
49 | - break | |
50 | - ) | |
51 | - ) | |
52 | - | |
53 | - if(point | -ne -1) ( | |
54 | - | rows -utf8 0..$point | |
55 | - ) | |
56 | -) | |
57 | - | |
58 | -def is_all_ascii ( | |
59 | - | length -byte | var -local LEN | |
60 | - | |
61 | - LEN | -eq $(| length -utf8) | |
62 | -) | |
63 | - | |
64 | -def migemo_file_completion ( | |
65 | - print $ARGV[0] | var -local inputing | |
66 | - print $ARGV[1] | var -local editing_line | |
67 | - | |
68 | - if (inputing | =~ '.*\/[a-zA-Z]+') ( | |
69 | - inputing | sub '(.*\/)[a-zA-Z]+$' '\1' | var -local no_migemo_string | |
70 | - inputing | sub '.*\/([a-zA-Z]+)$' '\1' | var -local migemo_string | |
71 | - ) elif (inputing | =~ '.*\/[^a-zA-Z]+[a-zA-Z]+$') ( | |
72 | - inputing | sub '(.*\/[^a-zA-Z]+)[a-zA-Z]+$' '\1' | var -local no_migemo_string | |
73 | - inputing | sub '.*\/[^a-zA-Z]+([a-zA-Z]+)$' '\1' | var -local migemo_string | |
74 | - ) elif (inputing | =~ '[a-zA-Z]+$') ( | |
75 | - print "" | var -local no_migemo_string | |
76 | - inputing | var -local migemo_string | |
77 | - ) elif (inputing | =~ '[^a-zA-Z]+[a-zA-Z]+$') ( | |
78 | - inputing | sub '([^a-zA-Z]+)[a-zA-Z]+$' '\1' | var -local no_migemo_string | |
79 | - inputing | sub '[^a-zA-Z]+([a-zA-Z]+)$' '\1' | var -local migemo_string | |
80 | - ) else ( | |
81 | - print "" | var -local no_migemo_string | |
82 | - print "" | var -local migemo_string | |
83 | - ) | |
84 | - | |
85 | - | each ( | |
86 | - | if(|=~ '[a-zA-Z]+[^a-zA-z/]+$' && no_migemo_string |= \n) ( | |
87 | - (migemo_string; |print) | common_head | var -local same_head | |
88 | - | |
89 | - | if(| sub -no-regex $no_migemo_string '' | sub -no-regex $same_head '' | chomp | migemo::match $(migemo_string|sub -no-regex $same_head '' | chomp) | lines 0 | = 0\n) ( | |
90 | ||
91 | - ) | |
92 | - ) else ( | |
93 | - | if(| sub -no-regex $no_migemo_string '' | chomp | migemo::match $migemo_string | lines 0 | = 0\n) ( | |
94 | ||
95 | - ) | |
96 | - ) | |
97 | - ) | (| common_head | var -local COMMON_HEAD; | wc -l | var -local NUM) | |
98 | - | |
99 | - if(COMMON_HEAD | chomp | -n) ( | |
100 | - rl::delete_text $(editing_line | rindex $inputing) $(rl::point) | |
101 | - rl::insert_text $COMMON_HEAD | |
102 | - if(NUM | chomp | -eq 1 && COMMON_HEAD| chomp | rows -1 | != /) ( rl::insert_text " " ) | |
103 | - ) | |
104 | -) | |
105 | - | |
106 | -def file_completion ( | |
107 | - | split '(?<!\\) +' | lines -1 | var -local inputing | |
108 | - | |
109 | - if(inputing | index -quiet /) ( | |
110 | - sys::dirname $(inputing |chomp| if (|rows -1 | = /) ( |add aaa ) else ( | print ) ) | var -local DIR | |
111 | - | |
112 | - eval "ls $DIR" | each ( | |
113 | - | if (|chomp | add -number 0 $(DIR|xyzsh_dequote|chomp)/ | -d) ( | |
114 | - |chomp | add -number 0 $DIR/ | add / | pomch | |
115 | - ) else ( | |
116 | - |chomp | add -number 0 $DIR/ | pomch | |
117 | - ) | |
118 | - ) | migemo_file_completion $inputing $(|print) | each ( | |
119 | - | chomp | xyzsh_quote | pomch | |
120 | - ) | |
121 | - ) else ( | |
122 | - ls | each ( | |
123 | - | if (|chomp| -d) ( | |
124 | - | chomp | add / | pomch | |
125 | - ) else ( | |
126 | - |chomp| pomch | |
127 | - ) | |
128 | - ) | migemo_file_completion $inputing $(|print) | each ( | |
129 | - | chomp | xyzsh_quote | pomch | |
130 | - ) | |
131 | - ) | |
132 | -) | |
133 | - | |
134 | -completion __all__ ( | |
135 | - | file_completion | |
136 | -) | |
137 | - | |
138 | -root::compl::run( root::object sys ) | |
139 | - | |
140 | -completion sys::__all__ ( | |
141 | - | file_completion | |
142 | -) | |
143 | - |
@@ -1,1243 +0,0 @@ | ||
1 | -#include "config.h" | |
2 | -#include "xyzsh/xyzsh.h" | |
3 | - | |
4 | -#include <string.h> | |
5 | -#include <strings.h> | |
6 | -#include <stdlib.h> | |
7 | -#include <stdio.h> | |
8 | -#include <unistd.h> | |
9 | -#include <errno.h> | |
10 | -#include <fcntl.h> | |
11 | -#include <libgen.h> | |
12 | -#include <dirent.h> | |
13 | -#include <readline/readline.h> | |
14 | -#include <readline/history.h> | |
15 | -#include <oniguruma.h> | |
16 | -#include <sys/stat.h> | |
17 | -#include <sys/types.h> | |
18 | -#include <pwd.h> | |
19 | -#include <limits.h> | |
20 | - | |
21 | -static sObject* gReadlineBlock; | |
22 | -static sObject* gCompletionArray; | |
23 | - | |
24 | -static BOOL name_sort(void* left, void* right) | |
25 | -{ | |
26 | - char* lfname = left; | |
27 | - char* rfname = right; | |
28 | - | |
29 | - if(strcmp(lfname, ".") == 0) return TRUE; | |
30 | - if(strcmp(lfname, "..") == 0) { | |
31 | - if(strcmp(rfname, ".") == 0) return FALSE; | |
32 | - | |
33 | - return TRUE; | |
34 | - } | |
35 | - if(strcmp(rfname, ".") == 0) return FALSE; | |
36 | - if(strcmp(rfname, "..") == 0) return FALSE; | |
37 | - | |
38 | - return strcasecmp(lfname, rfname) < 0; | |
39 | -} | |
40 | - | |
41 | -static sObject* gUserCompletionNextout; | |
42 | -static sObject* gReadlineCurrentObject; | |
43 | - | |
44 | -static char* message_completion(const char* text, int stat) | |
45 | -{ | |
46 | - static int index, wordlen; | |
47 | - | |
48 | - if(stat == 0) { | |
49 | - sStatment* statment = SBLOCK(gReadlineBlock).mStatments + SBLOCK(gReadlineBlock).mStatmentsNum - 1; | |
50 | - | |
51 | - sCommand* command = statment->mCommands + statment->mCommandsNum-1; | |
52 | - | |
53 | - gCompletionArray = VECTOR_NEW_STACK(16); | |
54 | - | |
55 | - sObject* current = gReadlineCurrentObject; | |
56 | - sObject* object; | |
57 | - | |
58 | - sObject* messages = STRING_NEW_STACK(""); | |
59 | - | |
60 | - while(1) { | |
61 | - object = uobject_item(current, command->mMessages[0]); | |
62 | - if(object || current == gRootObject) break; | |
63 | - current = SUOBJECT((current)).mParent; | |
64 | - if(current == NULL) break; | |
65 | - } | |
66 | - | |
67 | - string_put(messages, command->mMessages[0]); | |
68 | - string_push_back(messages, "::"); | |
69 | - | |
70 | - if(object && TYPE(object) == T_UOBJECT) { | |
71 | - int i; | |
72 | - for(i=1; i<command->mMessagesNum; i++) { | |
73 | - object = uobject_item(object, command->mMessages[i]); | |
74 | - if(object == NULL || TYPE(object) != T_UOBJECT) break; | |
75 | - string_push_back(messages, command->mMessages[i]); | |
76 | - string_push_back(messages, "::"); | |
77 | - } | |
78 | - | |
79 | - if(object && TYPE(object) == T_UOBJECT) { | |
80 | - uobject_it* it = uobject_loop_begin(object); | |
81 | - while(it) { | |
82 | - char* key = uobject_loop_key(it); | |
83 | - sObject* item = uobject_loop_item(it); | |
84 | - | |
85 | - sObject* candidate = STRING_NEW_STACK(string_c_str(messages)); | |
86 | - string_push_back(candidate, key); | |
87 | - | |
88 | - if(TYPE(item) == T_UOBJECT) { | |
89 | - if(uobject_item(item, "main")) { | |
90 | - vector_add(gCompletionArray, string_c_str(candidate)); | |
91 | - } | |
92 | - else { | |
93 | - sObject* candidate2 = STRING_NEW_STACK(string_c_str(messages)); | |
94 | - string_push_back(candidate2, key); | |
95 | - string_push_back(candidate2, "::"); | |
96 | - | |
97 | - vector_add(gCompletionArray, string_c_str(candidate2)); | |
98 | - } | |
99 | - } | |
100 | - else { | |
101 | - vector_add(gCompletionArray, string_c_str(candidate)); | |
102 | - } | |
103 | - | |
104 | - it = uobject_loop_next(it); | |
105 | - } | |
106 | - | |
107 | - vector_sort(gCompletionArray, name_sort); | |
108 | - } | |
109 | - } | |
110 | - | |
111 | - wordlen = strlen(text); | |
112 | - index = 0; | |
113 | - } | |
114 | - | |
115 | - while(index < vector_count(gCompletionArray)) { | |
116 | - char* candidate = vector_item(gCompletionArray, index); | |
117 | - index++; | |
118 | - | |
119 | - if(!strncmp(text, candidate, wordlen)) { | |
120 | - int len = strlen(candidate); | |
121 | - if(len > 2 && candidate[len-2] == ':' && candidate[len-1] == ':') { | |
122 | - rl_completion_append_character = 0; | |
123 | - } | |
124 | - else { | |
125 | - rl_completion_append_character = ' '; | |
126 | - } | |
127 | - return strdup(candidate); | |
128 | - } | |
129 | - } | |
130 | - | |
131 | - return NULL; | |
132 | -} | |
133 | - | |
134 | -static char* all_program_completion(const char* text, int stat) | |
135 | -{ | |
136 | - static int index, wordlen; | |
137 | - | |
138 | - if(stat == 0) { | |
139 | - gCompletionArray = VECTOR_NEW_STACK(16); | |
140 | - sObject* hash = HASH_NEW_STACK(16); | |
141 | - | |
142 | - sObject* current = gReadlineCurrentObject; | |
143 | - while(1) { | |
144 | - uobject_it* it = uobject_loop_begin(current); | |
145 | - while(it) { | |
146 | - char* key = uobject_loop_key(it); | |
147 | - sObject* object = uobject_loop_item(it); | |
148 | - | |
149 | - if(hash_item(hash, key) == NULL) { | |
150 | - hash_put(hash, key, object); | |
151 | - | |
152 | - sObject* candidate = STRING_NEW_STACK(uobject_loop_key(it)); | |
153 | - if(TYPE(object) == T_UOBJECT) { | |
154 | - if(uobject_item(object, "main")) { | |
155 | - vector_add(gCompletionArray, string_c_str(candidate)); | |
156 | - } | |
157 | - else { | |
158 | - sObject* candidate2 = STRING_NEW_STACK(uobject_loop_key(it)); | |
159 | - string_push_back(candidate2, "::"); | |
160 | - vector_add(gCompletionArray, string_c_str(candidate2)); | |
161 | - } | |
162 | - } | |
163 | - else { | |
164 | - vector_add(gCompletionArray, string_c_str(candidate)); | |
165 | - } | |
166 | - } | |
167 | - | |
168 | - it = uobject_loop_next(it); | |
169 | - } | |
170 | - | |
171 | - if(current == gRootObject) break; | |
172 | - | |
173 | - current = SUOBJECT(current).mParent; | |
174 | - | |
175 | - if(current == NULL) break; | |
176 | - } | |
177 | - vector_sort(gCompletionArray, name_sort); | |
178 | - | |
179 | - wordlen = strlen(text); | |
180 | - index = 0; | |
181 | - } | |
182 | - | |
183 | - while(index < vector_count(gCompletionArray)) { | |
184 | - char* candidate = vector_item(gCompletionArray, index); | |
185 | - index++; | |
186 | - | |
187 | - return strdup(candidate); | |
188 | - } | |
189 | - | |
190 | - return NULL; | |
191 | -} | |
192 | - | |
193 | -static char* program_completion(const char* text, int stat) | |
194 | -{ | |
195 | - static int index, wordlen; | |
196 | - | |
197 | - if(stat == 0) { | |
198 | - gCompletionArray = VECTOR_NEW_STACK(16); | |
199 | - sObject* hash = HASH_NEW_STACK(16); | |
200 | - | |
201 | - sObject* current = gReadlineCurrentObject; | |
202 | - while(1) { | |
203 | - uobject_it* it = uobject_loop_begin(current); | |
204 | - while(it) { | |
205 | - char* key = uobject_loop_key(it); | |
206 | - sObject* object = uobject_loop_item(it); | |
207 | - | |
208 | - if(hash_item(hash, key) == NULL) { | |
209 | - hash_put(hash, key, object); | |
210 | - | |
211 | - sObject* candidate = STRING_NEW_STACK(uobject_loop_key(it)); | |
212 | - if(TYPE(object) == T_UOBJECT) { | |
213 | - if(uobject_item(object, "main")) { | |
214 | - vector_add(gCompletionArray, string_c_str(candidate)); | |
215 | - } | |
216 | - else { | |
217 | - sObject* candidate2 = STRING_NEW_STACK(uobject_loop_key(it)); | |
218 | - string_push_back(candidate2, "::"); | |
219 | - vector_add(gCompletionArray, string_c_str(candidate2)); | |
220 | - } | |
221 | - } | |
222 | - else { | |
223 | - vector_add(gCompletionArray, string_c_str(candidate)); | |
224 | - } | |
225 | - } | |
226 | - | |
227 | - it = uobject_loop_next(it); | |
228 | - } | |
229 | - | |
230 | - if(current == gRootObject) break; | |
231 | - | |
232 | - current = SUOBJECT(current).mParent; | |
233 | - | |
234 | - if(current == NULL) break; | |
235 | - } | |
236 | - vector_sort(gCompletionArray, name_sort); | |
237 | - | |
238 | - wordlen = strlen(text); | |
239 | - index = 0; | |
240 | - } | |
241 | - | |
242 | - while(index < vector_count(gCompletionArray)) { | |
243 | - char* candidate = vector_item(gCompletionArray, index); | |
244 | - index++; | |
245 | - | |
246 | - if(!strncmp(text, candidate, wordlen)) { | |
247 | - int len = strlen(candidate); | |
248 | - if(len > 2 && candidate[len-2] == ':' && candidate[len-1] == ':') { | |
249 | - rl_completion_append_character = 0; | |
250 | - } | |
251 | - else { | |
252 | - rl_completion_append_character = ' '; | |
253 | - } | |
254 | - return strdup(candidate); | |
255 | - } | |
256 | - } | |
257 | - | |
258 | - return NULL; | |
259 | -} | |
260 | - | |
261 | -static char* user_completion(const char* text, int stat) | |
262 | -{ | |
263 | - static int index, wordlen; | |
264 | - static char text2[1024]; | |
265 | - | |
266 | - if(stat == 0) { | |
267 | - gCompletionArray = VECTOR_NEW_STACK(16); | |
268 | - | |
269 | - int i; | |
270 | - for(i=0; i<vector_count(SFD(gUserCompletionNextout).mLines); i++) { | |
271 | - sObject* candidate = STRING_NEW_STACK(vector_item(SFD(gUserCompletionNextout).mLines, i)); | |
272 | - string_chomp(candidate); | |
273 | - vector_add(gCompletionArray, string_c_str(candidate)); | |
274 | - } | |
275 | - | |
276 | - vector_sort(gCompletionArray, name_sort); | |
277 | - | |
278 | - wordlen = strlen(text); | |
279 | - index = 0; | |
280 | - } | |
281 | - | |
282 | - while(index < vector_count(gCompletionArray)) { | |
283 | - char* candidate = vector_item(gCompletionArray, index); | |
284 | - index++; | |
285 | - | |
286 | - if(!strncmp(text, candidate, wordlen)) { | |
287 | - int l = strlen(candidate); | |
288 | - if((l > 2 && candidate[l-2] == ':' && candidate[l-1] == ':' ) | |
289 | - || (l > 1 && candidate[l-1] == '/') ) | |
290 | - { | |
291 | - rl_completion_append_character = 0; | |
292 | - } | |
293 | - else { | |
294 | - rl_completion_append_character = ' '; | |
295 | - } | |
296 | - return strdup(candidate); | |
297 | - } | |
298 | - } | |
299 | - | |
300 | - return NULL; | |
301 | -} | |
302 | - | |
303 | -static char* redirect_completion(const char* text, int stat) | |
304 | -{ | |
305 | - static int index, wordlen; | |
306 | - | |
307 | - if(stat == 0) { | |
308 | - gCompletionArray = VECTOR_NEW_STACK(16); | |
309 | - | |
310 | - vector_add(gCompletionArray, STRING_NEW_STACK("%>")); | |
311 | - vector_add(gCompletionArray, STRING_NEW_STACK("%>>")); | |
312 | - | |
313 | - vector_sort(gCompletionArray, name_sort); | |
314 | - | |
315 | - wordlen = strlen(text); | |
316 | - index = 0; | |
317 | - } | |
318 | - | |
319 | - while(index < vector_count(gCompletionArray)) { | |
320 | - char* candidate = string_c_str((sObject*)vector_item(gCompletionArray, index)); | |
321 | - index++; | |
322 | - | |
323 | - if(!strncmp(text, candidate, wordlen)) { | |
324 | - rl_completion_append_character = 0; | |
325 | - return strdup(candidate); | |
326 | - } | |
327 | - } | |
328 | - | |
329 | - return NULL; | |
330 | -} | |
331 | - | |
332 | -#if !HAVE_DECL_ENVIRON | |
333 | - extern char **environ; | |
334 | -#endif | |
335 | - | |
336 | -static char* env_completion(const char* text, int stat_) | |
337 | -{ | |
338 | - static int index, wordlen; | |
339 | - | |
340 | - if(stat_ == 0) { | |
341 | - gCompletionArray = VECTOR_NEW_STACK(16); | |
342 | - sObject* hash = HASH_NEW_STACK(16); | |
343 | - | |
344 | - char** p; | |
345 | - for(p = environ; *p; p++) { | |
346 | - char env_name[PATH_MAX]; | |
347 | - | |
348 | - char* p2 = env_name; | |
349 | - char* p3 = *p; | |
350 | - | |
351 | - while(*p3 != 0 && *p3 != '=') { | |
352 | - *p2++ = *p3++; | |
353 | - } | |
354 | - | |
355 | - char* env = getenv(*p); | |
356 | - struct stat estat; | |
357 | - if(stat(env, &estat) >= 0) { | |
358 | - if(S_ISDIR(estat.st_mode)) { | |
359 | - *p2++ = '/'; | |
360 | - } | |
361 | - } | |
362 | - *p2 = 0; | |
363 | - | |
364 | - sObject* string = STRING_NEW_STACK(env_name); | |
365 | - vector_add(gCompletionArray, string_c_str(string)); | |
366 | - } | |
367 | - | |
368 | - if(strstr((char*)text, "::")) { | |
369 | - sObject* current = gReadlineCurrentObject; | |
370 | - sObject* prefix = STRING_NEW_STACK(""); | |
371 | - sObject* name = STRING_NEW_STACK(""); | |
372 | - | |
373 | - split_prefix_of_object_and_name2(¤t, prefix, name, (char*)text, gReadlineCurrentObject); | |
374 | - | |
375 | - if(current && TYPE(current) == T_UOBJECT) { | |
376 | - uobject_it* it = uobject_loop_begin(current); | |
377 | - while(it) { | |
378 | - char* key = uobject_loop_key(it); | |
379 | - sObject* object = uobject_loop_item(it); | |
380 | - | |
381 | - if(TYPE(object) == T_UOBJECT) { | |
382 | - sObject* candidate = STRING_NEW_STACK(""); | |
383 | - string_push_back(candidate, string_c_str(prefix)); | |
384 | - string_push_back(candidate, key); | |
385 | - string_push_back(candidate, "::"); | |
386 | - | |
387 | - vector_add(gCompletionArray, string_c_str(candidate)); | |
388 | - } | |
389 | - else if(TYPE(object) == T_STRING || TYPE(object) == T_VECTOR || TYPE(object) == T_HASH) { | |
390 | - sObject* candidate = STRING_NEW_STACK(""); | |
391 | - string_push_back(candidate, string_c_str(prefix)); | |
392 | - string_push_back(candidate, key); | |
393 | - | |
394 | - vector_add(gCompletionArray, string_c_str(candidate)); | |
395 | - } | |
396 | - | |
397 | - it = uobject_loop_next(it); | |
398 | - } | |
399 | - } | |
400 | - } | |
401 | - else { | |
402 | - sObject* current = gReadlineCurrentObject; | |
403 | - | |
404 | - while(1) { | |
405 | - uobject_it* it = uobject_loop_begin(current); | |
406 | - while(it) { | |
407 | - char* key = uobject_loop_key(it); | |
408 | - sObject* object = uobject_loop_item(it); | |
409 | - | |
410 | - if(TYPE(object) == T_UOBJECT) { | |
411 | - sObject* candidate = STRING_NEW_STACK(""); | |
412 | - string_push_back(candidate, key); | |
413 | - string_push_back(candidate, "::"); | |
414 | - | |
415 | - vector_add(gCompletionArray, string_c_str(candidate)); | |
416 | - } | |
417 | - else if(TYPE(object) == T_STRING || TYPE(object) == T_VECTOR || TYPE(object) == T_HASH) { | |
418 | - sObject* candidate = STRING_NEW_STACK(""); | |
419 | - string_push_back(candidate, key); | |
420 | - | |
421 | - vector_add(gCompletionArray, string_c_str(candidate)); | |
422 | - } | |
423 | - | |
424 | - it = uobject_loop_next(it); | |
425 | - } | |
426 | - | |
427 | - if(current == gRootObject) break; | |
428 | - | |
429 | - current = SUOBJECT(current).mParent; | |
430 | - | |
431 | - if(current == NULL) break; | |
432 | - } | |
433 | - } | |
434 | - | |
435 | - vector_sort(gCompletionArray, name_sort); | |
436 | - | |
437 | - wordlen = strlen(text); | |
438 | - index = 0; | |
439 | - } | |
440 | - | |
441 | - while(index < vector_count(gCompletionArray)) { | |
442 | - char* candidate = vector_item(gCompletionArray, index); | |
443 | - index++; | |
444 | - | |
445 | - if(!strncmp(text, candidate, wordlen)) { | |
446 | - int len = strlen(candidate); | |
447 | - if(len > 2 && candidate[len-2] == ':' && candidate[len-1] == ':') { | |
448 | - rl_completion_append_character = 0; | |
449 | - } | |
450 | - else { | |
451 | - rl_completion_append_character = ' '; | |
452 | - } | |
453 | - return strdup(candidate); | |
454 | - } | |
455 | - } | |
456 | - | |
457 | - return NULL; | |
458 | -} | |
459 | - | |
460 | -static void get_current_completion_object(sObject** completion_object, sObject** current_object) | |
461 | -{ | |
462 | - if(*current_object && *current_object != gRootObject) { | |
463 | - sObject* parent_object = SUOBJECT(*current_object).mParent; | |
464 | - get_current_completion_object(completion_object, &parent_object); | |
465 | - if(*completion_object) *completion_object = uobject_item(*completion_object, SUOBJECT(*current_object).mName); | |
466 | - } | |
467 | -} | |
468 | - | |
469 | -static sObject* access_object_compl(char* name, sObject** current) | |
470 | -{ | |
471 | - sObject* object; | |
472 | - | |
473 | - while(1) { | |
474 | - object = uobject_item(*current, name); | |
475 | - | |
476 | - if(object || *current == gCompletionObject) { return object; } | |
477 | - | |
478 | - *current = SUOBJECT((*current)).mParent; | |
479 | - | |
480 | - if(*current == NULL) return NULL;; | |
481 | - } | |
482 | -} | |
483 | - | |
484 | -char** readline_on_complete(const char* text, int start, int end) | |
485 | -{ | |
486 | - stack_start_stack(); | |
487 | - | |
488 | - gReadlineBlock = BLOCK_NEW_STACK(); | |
489 | - | |
490 | - sObject* cmdline = STRING_NEW_STACK(""); | |
491 | - string_push_back3(cmdline, rl_line_buffer, end); | |
492 | - | |
493 | - int sline = 1; | |
494 | - gReadlineCurrentObject = gCurrentObject; | |
495 | - BOOL result = parse(string_c_str(cmdline), "readline", &sline, gReadlineBlock, &gReadlineCurrentObject); | |
496 | - | |
497 | - /// in the block? get the block | |
498 | - if(!result && (SBLOCK(gReadlineBlock).mCompletionFlags & (COMPLETION_FLAGS_BLOCK|COMPLETION_FLAGS_ENV_BLOCK))) { | |
499 | - while(1) { | |
500 | - if(SBLOCK(gReadlineBlock).mStatmentsNum > 0) { | |
501 | - sStatment* statment = SBLOCK(gReadlineBlock).mStatments + SBLOCK(gReadlineBlock).mStatmentsNum - 1; | |
502 | - | |
503 | - if(statment->mCommandsNum > 0) { | |
504 | - sCommand* command = statment->mCommands + statment->mCommandsNum-1; | |
505 | - | |
506 | - int num = SBLOCK(gReadlineBlock).mCompletionFlags & COMPLETION_FLAGS_BLOCK_OR_ENV_NUM; | |
507 | - | |
508 | - if(num > 0) { | |
509 | - if(SBLOCK(gReadlineBlock).mCompletionFlags & COMPLETION_FLAGS_ENV_BLOCK) { | |
510 | - sEnv* env = command->mEnvs + num -1; | |
511 | - gReadlineBlock = env->mBlock; | |
512 | - } | |
513 | - else { | |
514 | - gReadlineBlock = *(command->mBlocks + num -1); | |
515 | - } | |
516 | - } | |
517 | - else { | |
518 | - break; | |
519 | - } | |
520 | - } | |
521 | - else { | |
522 | - break; | |
523 | - } | |
524 | - } | |
525 | - else { | |
526 | - break; | |
527 | - } | |
528 | - } | |
529 | - } | |
530 | - | |
531 | - if(SBLOCK(gReadlineBlock).mCompletionFlags & COMPLETION_FLAGS_TILDA) { | |
532 | - char** result = rl_completion_matches(text, rl_username_completion_function); | |
533 | - stack_end_stack(); | |
534 | - return result; | |
535 | - } | |
536 | - else if(SBLOCK(gReadlineBlock).mStatmentsNum == 0) { | |
537 | - char** result = rl_completion_matches(text, all_program_completion); | |
538 | - stack_end_stack(); | |
539 | - return result; | |
540 | - } | |
541 | - else if(SBLOCK(gReadlineBlock).mCompletionFlags & COMPLETION_FLAGS_AFTER_REDIRECT) { | |
542 | - stack_end_stack(); | |
543 | - return NULL; | |
544 | - } | |
545 | - else { | |
546 | - sStatment* statment = SBLOCK(gReadlineBlock).mStatments + SBLOCK(gReadlineBlock).mStatmentsNum - 1; | |
547 | - | |
548 | - if(statment->mCommandsNum == 0 || SBLOCK(gReadlineBlock).mCompletionFlags & (COMPLETION_FLAGS_COMMAND_END|COMPLETION_FLAGS_STATMENT_END|COMPLETION_FLAGS_STATMENT_HEAD)) { | |
549 | - char** result = rl_completion_matches(text, all_program_completion); | |
550 | - stack_end_stack(); | |
551 | - return result; | |
552 | - } | |
553 | - else { | |
554 | - sCommand* command = statment->mCommands + statment->mCommandsNum-1; | |
555 | - | |
556 | - /// get user completion /// | |
557 | - sObject* ucompletion; | |
558 | - if(command->mArgsNum > 0) { | |
559 | - sObject* completion_object = gCompletionObject; | |
560 | - sObject* current_object = gCurrentObject; | |
561 | - | |
562 | - get_current_completion_object(&completion_object, ¤t_object); | |
563 | - | |
564 | - if(completion_object == NULL) completion_object = gCompletionObject; | |
565 | - | |
566 | - sObject* object; | |
567 | - if(command->mMessagesNum > 0) { | |
568 | - sObject* reciever = completion_object; | |
569 | - object = access_object_compl(command->mMessages[0], &reciever); | |
570 | - | |
571 | - int i; | |
572 | - for(i=1; i<command->mMessagesNum; i++) { | |
573 | - if(object && TYPE(object) == T_UOBJECT) { | |
574 | - object = uobject_item(object, command->mMessages[i]); | |
575 | - } | |
576 | - else { | |
577 | - break; | |
578 | - } | |
579 | - } | |
580 | - | |
581 | - if(object && TYPE(object) == T_UOBJECT) { | |
582 | - ucompletion = uobject_item(object, command->mArgs[0]); | |
583 | - | |
584 | - if(ucompletion == NULL) { | |
585 | - ucompletion = uobject_item(object, "__all__");; | |
586 | - } | |
587 | - } | |
588 | - else { | |
589 | - ucompletion = NULL; | |
590 | - } | |
591 | - } | |
592 | - else { | |
593 | - sObject* reciever = completion_object; | |
594 | - ucompletion = access_object_compl(command->mArgs[0], &reciever); | |
595 | - | |
596 | - if(ucompletion == NULL) { | |
597 | - reciever = completion_object; | |
598 | - ucompletion = access_object_compl("__all__", &reciever); | |
599 | - } | |
600 | - } | |
601 | - } | |
602 | - else { | |
603 | - ucompletion = NULL; | |
604 | - } | |
605 | - | |
606 | - /// go /// | |
607 | - if(SBLOCK(gReadlineBlock).mCompletionFlags & COMPLETION_FLAGS_ENV) { | |
608 | - char** result = rl_completion_matches(text, env_completion); | |
609 | - stack_end_stack(); | |
610 | - return result; | |
611 | - } | |
612 | - else if(command->mArgsNum == 0 | |
613 | - || command->mArgsNum == 1 && SBLOCK(gReadlineBlock).mCompletionFlags & COMPLETION_FLAGS_INPUTING_COMMAND_NAME) | |
614 | - { | |
615 | - if(command->mMessagesNum > 0) { | |
616 | - char** result = rl_completion_matches(text, message_completion); | |
617 | - stack_end_stack(); | |
618 | - return result; | |
619 | - } | |
620 | - else { | |
621 | - char** result = rl_completion_matches(text, program_completion); | |
622 | - stack_end_stack(); | |
623 | - return result; | |
624 | - } | |
625 | - } | |
626 | - else if(ucompletion && TYPE(ucompletion) == T_COMPLETION) { | |
627 | - sObject* nextin = FD_NEW_STACK(); | |
628 | - if(!fd_write(nextin, string_c_str(cmdline), string_length(cmdline))) { | |
629 | - stack_end_stack(); | |
630 | - return NULL; | |
631 | - } | |
632 | - sObject* nextout = FD_NEW_STACK(); | |
633 | - | |
634 | - sObject* fun = FUN_NEW_STACK(NULL); | |
635 | - sObject* stackframe = UOBJECT_NEW_GC(8, gXyzshObject, "_stackframe", FALSE); | |
636 | - vector_add(gStackFrames, stackframe); | |
637 | - //uobject_init(stackframe); | |
638 | - SFUN(fun).mLocalObjects = stackframe; | |
639 | - | |
640 | - sObject* argv = VECTOR_NEW_GC(16, FALSE); | |
641 | - if(command->mArgsNum == 1) { | |
642 | - vector_add(argv, STRING_NEW_GC(command->mArgs[0], FALSE)); | |
643 | - vector_add(argv, STRING_NEW_GC("", FALSE)); | |
644 | - } | |
645 | - else if(command->mArgsNum > 1) { | |
646 | - vector_add(argv, STRING_NEW_GC(command->mArgs[0], FALSE)); | |
647 | - | |
648 | - /// if parser uses PARSER_MAGIC_NUMBER_OPTION, convert it | |
649 | - char* str = command->mArgs[command->mArgsNum-1]; | |
650 | - char* new_str = MALLOC(strlen(str) + 1); | |
651 | - xstrncpy(new_str, str, strlen(str) + 1); | |
652 | - if(new_str[0] == PARSER_MAGIC_NUMBER_OPTION) { | |
653 | - new_str[0] = '-'; | |
654 | - } | |
655 | - vector_add(argv, STRING_NEW_GC(new_str, FALSE)); | |
656 | - FREE(new_str); | |
657 | - } | |
658 | - else { | |
659 | - vector_add(argv, STRING_NEW_GC("", FALSE)); | |
660 | - vector_add(argv, STRING_NEW_GC("", FALSE)); | |
661 | - } | |
662 | - uobject_put(SFUN(fun).mLocalObjects, "ARGV", argv); | |
663 | - | |
664 | - int rcode = 0; | |
665 | - xyzsh_set_signal(); | |
666 | - if(!run(SCOMPLETION(ucompletion).mBlock, nextin, nextout, &rcode, gReadlineCurrentObject, fun)) { | |
667 | - readline_signal(); | |
668 | - fprintf(stderr, "\nrun time error\n"); | |
669 | - fprintf(stderr, "%s", string_c_str(gErrMsg)); | |
670 | - (void)vector_pop_back(gStackFrames); | |
671 | - stack_end_stack(); | |
672 | - return NULL; | |
673 | - } | |
674 | - (void)vector_pop_back(gStackFrames); | |
675 | - readline_signal(); | |
676 | - | |
677 | - eLineField lf; | |
678 | - if(fd_guess_lf(nextout, &lf)) { | |
679 | - fd_split(nextout, lf); | |
680 | - } else { | |
681 | - fd_split(nextout, kLF); | |
682 | - } | |
683 | - | |
684 | - gUserCompletionNextout = nextout; | |
685 | - char** result = rl_completion_matches(text, user_completion); | |
686 | - stack_end_stack(); | |
687 | - return result; | |
688 | - } | |
689 | - } | |
690 | - } | |
691 | - | |
692 | - stack_end_stack(); | |
693 | - return NULL; | |
694 | -} | |
695 | - | |
696 | -BOOL cmd_completion(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | |
697 | -{ | |
698 | - if(runinfo->mArgsNumRuntime >= 2) { | |
699 | - /// input /// | |
700 | - if(runinfo->mBlocksNum == 1) { | |
701 | - sObject* block = runinfo->mBlocks[0]; | |
702 | - | |
703 | - int i; | |
704 | - for(i=1; i<runinfo->mArgsNumRuntime; i++) { | |
705 | - sObject* object = gCompletionObject; | |
706 | - sObject* prefix = STRING_NEW_STACK(""); | |
707 | - sObject* name = STRING_NEW_STACK(""); | |
708 | - | |
709 | - split_prefix_of_object_and_name(&object, prefix, name, runinfo->mArgsRuntime[i]); | |
710 | - | |
711 | - if(object && TYPE(object) == T_UOBJECT && string_c_str(name)[0] != 0) { | |
712 | - uobject_put(object, string_c_str(name), COMPLETION_NEW_GC(block, FALSE)); | |
713 | - } | |
714 | - else { | |
715 | - err_msg("invalid variable name", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
716 | - return FALSE; | |
717 | - } | |
718 | - } | |
719 | - | |
720 | - runinfo->mRCode = 0; | |
721 | - } | |
722 | - /// output /// | |
723 | - else if(runinfo->mBlocksNum == 0) { | |
724 | - int i; | |
725 | - for(i=1; i<runinfo->mArgsNumRuntime; i++) { | |
726 | - sObject* compl; | |
727 | - if(!get_object_from_str(&compl, runinfo->mArgsRuntime[i], runinfo->mCurrentObject, runinfo->mRunningObject, runinfo)) { | |
728 | - return FALSE; | |
729 | - } | |
730 | - | |
731 | - if(compl && TYPE(compl) == T_COMPLETION) { | |
732 | - if(!run_object(compl, nextin, nextout, runinfo)) { | |
733 | - return FALSE; | |
734 | - } | |
735 | - } | |
736 | - else { | |
737 | - err_msg("There is no object", runinfo->mSName, runinfo->mSLine, runinfo->mArgsRuntime[i]); | |
738 | - | |
739 | - return FALSE; | |
740 | - } | |
741 | - } | |
742 | - | |
743 | - runinfo->mRCode = 0; | |
744 | - } | |
745 | - } | |
746 | - | |
747 | - return TRUE; | |
748 | -} | |
749 | - | |
750 | -BOOL cmd_readline_clear_screen(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | |
751 | -{ | |
752 | - mclear_immediately(); | |
753 | - rl_forced_update_display(); | |
754 | - | |
755 | - runinfo->mRCode = 0; | |
756 | - | |
757 | - return TRUE; | |
758 | -} | |
759 | - | |
760 | -BOOL cmd_readline_point(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | |
761 | -{ | |
762 | - if(!runinfo->mFilter) { | |
763 | - char buf[BUFSIZ]; | |
764 | - int n = snprintf(buf, BUFSIZ, "%d\n", rl_point); | |
765 | - if(!fd_write(nextout, buf, n)) { | |
766 | - sCommand* command = runinfo->mCommand; | |
767 | - err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, command->mArgs[0]); | |
768 | - runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
769 | - return FALSE; | |
770 | - } | |
771 | - | |
772 | - runinfo->mRCode = 0; | |
773 | - } | |
774 | - | |
775 | - return TRUE; | |
776 | -} | |
777 | - | |
778 | -BOOL cmd_readline_point_move(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | |
779 | -{ | |
780 | - if(runinfo->mArgsNumRuntime == 2) { | |
781 | - int n = atoi(runinfo->mArgsRuntime[1]); | |
782 | - | |
783 | - if(n < 0) n += strlen(rl_line_buffer) + 1; | |
784 | - if(n < 0) n = 0; | |
785 | - if(n > strlen(rl_line_buffer)) n = strlen(rl_line_buffer); | |
786 | - | |
787 | - rl_point = n; | |
788 | - | |
789 | - runinfo->mRCode = 0; | |
790 | - } | |
791 | - | |
792 | - return TRUE; | |
793 | -} | |
794 | - | |
795 | -BOOL cmd_readline_insert_text(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | |
796 | -{ | |
797 | - if(runinfo->mArgsNumRuntime == 2) { | |
798 | - (void)rl_insert_text(runinfo->mArgsRuntime[1]); | |
799 | - puts(""); | |
800 | - rl_forced_update_display(); | |
801 | - | |
802 | - runinfo->mRCode = 0; | |
803 | - } | |
804 | - | |
805 | - return TRUE; | |
806 | -} | |
807 | - | |
808 | -BOOL cmd_readline_delete_text(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | |
809 | -{ | |
810 | - if(runinfo->mArgsNumRuntime == 3) { | |
811 | - int n = atoi(runinfo->mArgsRuntime[1]); | |
812 | - int m = atoi(runinfo->mArgsRuntime[2]); | |
813 | - if(n < 0) n += strlen(rl_line_buffer) + 1; | |
814 | - if(n < 0) n= 0; | |
815 | - if(m < 0) m += strlen(rl_line_buffer) + 1; | |
816 | - if(m < 0) m = 0; | |
817 | - rl_point -= rl_delete_text(n, m); | |
818 | - if(rl_point < 0) { | |
819 | - rl_point = 0; | |
820 | - } | |
821 | - puts(""); | |
822 | - rl_forced_update_display(); | |
823 | - | |
824 | - runinfo->mRCode = 0; | |
825 | - } | |
826 | - | |
827 | - return TRUE; | |
828 | -} | |
829 | - | |
830 | -BOOL cmd_readline_replace_line(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | |
831 | -{ | |
832 | - if(runinfo->mArgsNumRuntime == 3) { | |
833 | - (void)rl_replace_line(runinfo->mArgsRuntime[1], 0); | |
834 | - | |
835 | - int n = atoi(runinfo->mArgsRuntime[2]); | |
836 | - | |
837 | - if(n < 0) n += strlen(rl_line_buffer) + 1; | |
838 | - if(n < 0) n = 0; | |
839 | - if(n > strlen(rl_line_buffer)) n = strlen(rl_line_buffer); | |
840 | - | |
841 | - rl_point = n; | |
842 | - runinfo->mRCode = 0; | |
843 | - } | |
844 | - | |
845 | - return TRUE; | |
846 | -} | |
847 | - | |
848 | -BOOL cmd_readline_read_history(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | |
849 | -{ | |
850 | - if(runinfo->mArgsNumRuntime == 2) { | |
851 | - char* fname = runinfo->mArgsRuntime[1]; | |
852 | - read_history(fname); | |
853 | - runinfo->mRCode = 0; | |
854 | - } | |
855 | - | |
856 | - return TRUE; | |
857 | -} | |
858 | - | |
859 | -BOOL cmd_readline_write_history(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | |
860 | -{ | |
861 | - if(runinfo->mArgsNumRuntime == 2) { | |
862 | - char* fname = runinfo->mArgsRuntime[1]; | |
863 | - write_history(fname); | |
864 | - runinfo->mRCode = 0; | |
865 | - } | |
866 | - | |
867 | - return TRUE; | |
868 | -} | |
869 | - | |
870 | -char* readline_filename_completion_null_generator(const char* a, int b) | |
871 | -{ | |
872 | - return NULL; | |
873 | -} | |
874 | - | |
875 | -BOOL cmd_readline_file_name_completion_null_generator(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | |
876 | -{ | |
877 | - rl_completion_entry_function = readline_filename_completion_null_generator; | |
878 | - | |
879 | - return TRUE; | |
880 | -} | |
881 | - | |
882 | -static int readline_macro(int count, int key) | |
883 | -{ | |
884 | - stack_start_stack(); | |
885 | - | |
886 | - sObject* nextout2 = FD_NEW_STACK(); | |
887 | - | |
888 | - int rcode = 0; | |
889 | - sObject* block = BLOCK_NEW_STACK(); | |
890 | - int sline = 1; | |
891 | - if(parse("root::macro", "macro", &sline, block, NULL)) { | |
892 | - xyzsh_set_signal(); | |
893 | - | |
894 | - sObject* fun = FUN_NEW_STACK(NULL); | |
895 | - sObject* stackframe = UOBJECT_NEW_GC(8, gXyzshObject, "_stackframe", FALSE); | |
896 | - vector_add(gStackFrames, stackframe); | |
897 | - //uobject_init(stackframe); | |
898 | - SFUN(fun).mLocalObjects = stackframe; | |
899 | - | |
900 | - sObject* nextin2 = FD_NEW_STACK(); | |
901 | - | |
902 | - (void)fd_write(nextin2, rl_line_buffer, rl_point); | |
903 | - | |
904 | - if(!run(block, nextin2, nextout2, &rcode, gRootObject, fun)) { | |
905 | - if(rcode == RCODE_BREAK) { | |
906 | - fprintf(stderr, "invalid break. Not in a loop\n"); | |
907 | - } | |
908 | - else if(rcode == RCODE_RETURN) { | |
909 | - fprintf(stderr, "invalid return. Not in a function\n"); | |
910 | - } | |
911 | - else if(rcode == RCODE_EXIT) { | |
912 | - } | |
913 | - else { | |
914 | - fprintf(stderr, "run time error\n"); | |
915 | - fprintf(stderr, "%s", string_c_str(gErrMsg)); | |
916 | - } | |
917 | - } | |
918 | - (void)vector_pop_back(gStackFrames); | |
919 | - readline_signal(); | |
920 | - //xyzsh_restore_signal_default(); | |
921 | - } | |
922 | - else { | |
923 | - fprintf(stderr, "parser error\n"); | |
924 | - fprintf(stderr, "%s", string_c_str(gErrMsg)); | |
925 | - } | |
926 | - | |
927 | - rl_insert_text(SFD(nextout2).mBuf); | |
928 | - puts(""); | |
929 | - rl_forced_update_display(); | |
930 | - stack_end_stack(); | |
931 | - | |
932 | - return 0; | |
933 | -} | |
934 | - | |
935 | -enum { COMPLETE_DQUOTE,COMPLETE_SQUOTE,COMPLETE_BSQUOTE }; | |
936 | -#define completion_quoting_style COMPLETE_BSQUOTE | |
937 | - | |
938 | -static BOOL shell_cmd; | |
939 | - | |
940 | -static char * | |
941 | -double_quote (char *string) | |
942 | -{ | |
943 | - register int c; | |
944 | - char *result, *r, *s; | |
945 | - | |
946 | - result = (char *)malloc (3 + (2 * strlen (string))); | |
947 | - r = result; | |
948 | - *r++ = '"'; | |
949 | - | |
950 | - for (s = string; s && (c = *s); s++) | |
951 | - { | |
952 | - switch (c) | |
953 | - { | |
954 | - case '$': | |
955 | - case '`': | |
956 | - if(!shell_cmd) | |
957 | - goto def; | |
958 | - case '"': | |
959 | - case '\\': | |
960 | - *r++ = '\\'; | |
961 | - default: def: | |
962 | - *r++ = c; | |
963 | - break; | |
964 | - } | |
965 | - } | |
966 | - | |
967 | - *r++ = '"'; | |
968 | - *r = '\0'; | |
969 | - | |
970 | - return (result); | |
971 | -} | |
972 | - | |
973 | -static char * | |
974 | -single_quote (char *string) | |
975 | -{ | |
976 | - register int c; | |
977 | - char *result, *r, *s; | |
978 | - | |
979 | - result = (char *)malloc (3 + (4 * strlen (string))); | |
980 | - r = result; | |
981 | - *r++ = '\''; | |
982 | - | |
983 | - for (s = string; s && (c = *s); s++) | |
984 | - { | |
985 | - *r++ = c; | |
986 | - | |
987 | - if (c == '\'') | |
988 | - { | |
989 | - *r++ = '\\'; // insert escaped single quote | |
990 | - *r++ = '\''; | |
991 | - *r++ = '\''; // start new quoted string | |
992 | - } | |
993 | - } | |
994 | - | |
995 | - *r++ = '\''; | |
996 | - *r = '\0'; | |
997 | - | |
998 | - return (result); | |
999 | -} | |
1000 | - | |
1001 | -static BOOL quote_glob; | |
1002 | -static BOOL inhibit_tilde; | |
1003 | - | |
1004 | -static char * | |
1005 | -backslash_quote (char *string) | |
1006 | -{ | |
1007 | - int c; | |
1008 | - char *result, *r, *s; | |
1009 | - | |
1010 | - result = (char*)malloc (2 * strlen (string) + 1); | |
1011 | - | |
1012 | - for (r = result, s = string; s && (c = *s); s++) | |
1013 | - { | |
1014 | - switch (c) | |
1015 | - { | |
1016 | - case '(': case ')': | |
1017 | - case '{': case '}': // reserved words | |
1018 | - case '^': | |
1019 | - case '$': case '`': // expansion chars | |
1020 | - if(!shell_cmd) | |
1021 | - goto def; | |
1022 | - case '*': case '[': case '?': case ']': //globbing chars | |
1023 | - if(!shell_cmd && !quote_glob) | |
1024 | - goto def; | |
1025 | - case ' ': case '\t': case '\n': // IFS white space | |
1026 | - case '"': case '\'': case '\\': // quoting chars | |
1027 | - case '|': case '&': case ';': // shell metacharacters | |
1028 | - case '<': case '>': case '!': | |
1029 | - *r++ = '\\'; | |
1030 | - *r++ = c; | |
1031 | - break; | |
1032 | - case '~': // tilde expansion | |
1033 | - if (s == string && inhibit_tilde) | |
1034 | - *r++ = '.', *r++ = '/'; | |
1035 | - goto def; | |
1036 | - case '#': // comment char | |
1037 | - if(!shell_cmd) | |
1038 | - goto def; | |
1039 | - if (s == string) | |
1040 | - *r++ = '\\'; | |
1041 | - default: def: | |
1042 | - *r++ = c; | |
1043 | - break; | |
1044 | - } | |
1045 | - } | |
1046 | - | |
1047 | - *r = '\0'; | |
1048 | - return (result); | |
1049 | -} | |
1050 | - | |
1051 | -static char * | |
1052 | -quote_word_break_chars (char *text) | |
1053 | -{ | |
1054 | - char *ret, *r, *s; | |
1055 | - int l; | |
1056 | - | |
1057 | - l = strlen (text); | |
1058 | - ret = (char*)malloc ((2 * l) + 1); | |
1059 | - for (s = text, r = ret; *s; s++) | |
1060 | - { | |
1061 | - if (*s == '\\') | |
1062 | - { | |
1063 | - *r++ = '\\'; | |
1064 | - *r++ = *++s; | |
1065 | - if (*s == '\0') | |
1066 | - break; | |
1067 | - continue; | |
1068 | - } | |
1069 | - if (strchr (rl_completer_word_break_characters, *s)) | |
1070 | - *r++ = '\\'; | |
1071 | - *r++ = *s; | |
1072 | - } | |
1073 | - *r = '\0'; | |
1074 | - return ret; | |
1075 | -} | |
1076 | - | |
1077 | -static char * | |
1078 | -bash_quote_filename (char *s, int rtype, char *qcp) | |
1079 | -{ | |
1080 | - char *rtext, *mtext, *ret; | |
1081 | - int rlen, cs; | |
1082 | - | |
1083 | - rtext = (char *)NULL; | |
1084 | - | |
1085 | - mtext = s; | |
1086 | -#if 0 | |
1087 | - if (mtext[0] == '~' && rtype == SINGLE_MATCH) | |
1088 | - mtext = bash_tilde_expand (s); | |
1089 | -#endif | |
1090 | - | |
1091 | - cs = completion_quoting_style; | |
1092 | - if (*qcp == '"') | |
1093 | - cs = COMPLETE_DQUOTE; | |
1094 | - else if (*qcp == '\'') | |
1095 | - cs = COMPLETE_SQUOTE; | |
1096 | -#if defined (BANG_HISTORY) | |
1097 | - else if (*qcp == '\0' && history_expansion && cs == COMPLETE_DQUOTE && | |
1098 | - history_expansion_inhibited == 0 && strchr (mtext, '!')) | |
1099 | - cs = COMPLETE_BSQUOTE; | |
1100 | - | |
1101 | - if (*qcp == '"' && history_expansion && cs == COMPLETE_DQUOTE && | |
1102 | - history_expansion_inhibited == 0 && strchr (mtext, '!')) | |
1103 | - { | |
1104 | - cs = COMPLETE_BSQUOTE; | |
1105 | - *qcp = '\0'; | |
1106 | - } | |
1107 | -#endif | |
1108 | - | |
1109 | - switch (cs) | |
1110 | - { | |
1111 | - case COMPLETE_DQUOTE: | |
1112 | - rtext = double_quote (mtext); | |
1113 | - break; | |
1114 | - case COMPLETE_SQUOTE: | |
1115 | - rtext = single_quote (mtext); | |
1116 | - break; | |
1117 | - case COMPLETE_BSQUOTE: | |
1118 | - rtext = backslash_quote (mtext); | |
1119 | - break; | |
1120 | - } | |
1121 | - | |
1122 | - if (mtext != s) | |
1123 | - free (mtext); | |
1124 | - | |
1125 | - if (rtext && cs == COMPLETE_BSQUOTE) | |
1126 | - { | |
1127 | - mtext = quote_word_break_chars (rtext); | |
1128 | - free (rtext); | |
1129 | - rtext = mtext; | |
1130 | - } | |
1131 | - | |
1132 | - rlen = strlen (rtext); | |
1133 | - ret = (char*)malloc (rlen + 1); | |
1134 | - strcpy (ret, rtext); | |
1135 | - | |
1136 | - if (rtype == MULT_MATCH && cs != COMPLETE_BSQUOTE) | |
1137 | - ret[rlen - 1] = '\0'; | |
1138 | - free (rtext); | |
1139 | - return ret; | |
1140 | -} | |
1141 | - | |
1142 | -static char * | |
1143 | -bash_dequote_filename (const char *text, int quote_char) | |
1144 | -{ | |
1145 | - char *ret; | |
1146 | - const char *p; | |
1147 | - char *r; | |
1148 | - int l, quoted; | |
1149 | - | |
1150 | - l = strlen (text); | |
1151 | - ret = (char*)malloc (l + 1); | |
1152 | - for (quoted = quote_char, p = text, r = ret; p && *p; p++) | |
1153 | - { | |
1154 | - if (*p == '\\') | |
1155 | - { | |
1156 | - *r++ = *++p; | |
1157 | - if (*p == '\0') | |
1158 | - break; | |
1159 | - continue; | |
1160 | - } | |
1161 | - if (quoted && *p == quoted) | |
1162 | - { | |
1163 | - quoted = 0; | |
1164 | - continue; | |
1165 | - } | |
1166 | - if (quoted == 0 && (*p == '\'' || *p == '"')) | |
1167 | - { | |
1168 | - quoted = *p; | |
1169 | - continue; | |
1170 | - } | |
1171 | - *r++ = *p; | |
1172 | - } | |
1173 | - *r = '\0'; | |
1174 | - return ret; | |
1175 | -} | |
1176 | - | |
1177 | -static int skip_quoted(const char *s, int i, char q) | |
1178 | -{ | |
1179 | - while(s[i] && s[i]!=q) | |
1180 | - { | |
1181 | - if(s[i]=='\\' && s[i+1]) i++; | |
1182 | - i++; | |
1183 | - } | |
1184 | - if(s[i]) i++; | |
1185 | - return i; | |
1186 | -} | |
1187 | - | |
1188 | -static int lftp_char_is_quoted(const char *string, int eindex) | |
1189 | -{ | |
1190 | - int i, pass_next; | |
1191 | - | |
1192 | - for (i = pass_next = 0; i <= eindex; i++) | |
1193 | - { | |
1194 | - if (pass_next) | |
1195 | - { | |
1196 | - pass_next = 0; | |
1197 | - if (i >= eindex) | |
1198 | - return 1; | |
1199 | - continue; | |
1200 | - } | |
1201 | - else if (string[i] == '"' || string[i] == '\'') | |
1202 | - { | |
1203 | - char quote = string[i]; | |
1204 | - i = skip_quoted (string, ++i, quote); | |
1205 | - if (i > eindex) | |
1206 | - return 1; | |
1207 | - i--; | |
1208 | - } | |
1209 | - else if (string[i] == '\\') | |
1210 | - { | |
1211 | - pass_next = 1; | |
1212 | - continue; | |
1213 | - } | |
1214 | - } | |
1215 | - return (0); | |
1216 | -} | |
1217 | - | |
1218 | -void xyzsh_readline_init(BOOL runtime_script) | |
1219 | -{ | |
1220 | - rl_attempted_completion_function = readline_on_complete; | |
1221 | - //rl_completion_entry_function = readline_filename_completion_null_generator; | |
1222 | - rl_completer_quote_characters = "\"'"; | |
1223 | - rl_completer_word_break_characters = " \t\n\"'|!&;()$%<>="; | |
1224 | - rl_completion_append_character= ' '; | |
1225 | - rl_filename_quote_characters = " \t\n\"'|!&;()$%<>:[]"; | |
1226 | - rl_filename_quoting_function = bash_quote_filename; | |
1227 | - rl_filename_dequoting_function = (rl_dequote_func_t*)bash_dequote_filename; | |
1228 | -// rl_char_is_quoted_p = char_is_quoted; | |
1229 | - | |
1230 | - rl_char_is_quoted_p = (rl_linebuf_func_t*)lftp_char_is_quoted; | |
1231 | - | |
1232 | -/* | |
1233 | - rl_comrl_filename_quote_characters = " \t\n\\'\"()$&|>"; | |
1234 | - rl_completer_quote_characters = " \t\n\\'\"()$&|>"; | |
1235 | - rl_basic_quote_characters = " \t\n\"'|!&;()$"; | |
1236 | -*/ | |
1237 | - | |
1238 | - rl_bind_key('x'-'a'+1, readline_macro); | |
1239 | -} | |
1240 | - | |
1241 | -void xyzsh_readline_final() | |
1242 | -{ | |
1243 | -} |