シェルスクリプト言語xyzshのソースコード。
リビジョン | 12a1d8fd6621a6637a81cd8d639722458767c8b9 (tree) |
---|---|
日時 | 2013-01-31 20:40:07 |
作者 | ab25q <ab25cq@gmai...> |
コミッター | ab25q |
1.3.3
@@ -1,13 +1,27 @@ | ||
1 | 1 | |
2 | -2013 January version 1.3.3 | |
2 | +2013 31th January version 1.3.3 | |
3 | 3 | |
4 | - 1. Modified configure.in and Makfile.in especially for related docdir and sysconfdir | |
4 | + 1. Modified configure.in and Makfile.in especially for related with docdir and sysconfdir | |
5 | 5 | |
6 | 6 | 2. Added XYZSH_DOCDIR for help.xyzsh. Remained XYZSH_DATAROOTDIR. |
7 | 7 | |
8 | - 3. After runned on command line, changed "HIT ANY KEY" working. | |
8 | + 3. Fixed job title problem. | |
9 | 9 | |
10 | - 4. Fixed job title problem. | |
10 | + 4. Added C extension mechanism which loads dynamic library from searched path. See USAGE or USAGE.ja. Cutted off migemo and made it as C extension. | |
11 | + | |
12 | + 5. Added migemo completion for Japanese. | |
13 | + | |
14 | + 6. Added "-regex" option to "index" and "rindex" command. Added "-no-regex" option to "sub" and "split" command. | |
15 | + | |
16 | + 7. Checked on Ubuntu 64 bit. | |
17 | + | |
18 | + 8. You can set return code of "return" command. | |
19 | + | |
20 | + > def fun ( return 1 ) | |
21 | + > fun | |
22 | + return code is 1 | |
23 | + | |
24 | + 9. Modified completion working especially tilde completion.. | |
11 | 25 | |
12 | 26 | 2013 20th January version 1.3.2 |
13 | 27 |
@@ -21,6 +21,7 @@ INSTALL=@INSTALL@ | ||
21 | 21 | CFLAGS=@CFLAGS@ |
22 | 22 | LIBS=@LIBS@ |
23 | 23 | OBJ=@OBJ@ |
24 | +EXTOBJ=@EXTOBJ@ | |
24 | 25 | LIBXYZSHSO=@LIBXYZSHSO@ |
25 | 26 | LIBXYZSHSO1=@LIBXYZSHSO1@ |
26 | 27 | LIBXYZSHA=@LIBXYZSHA@ |
@@ -28,11 +29,17 @@ LIBXYZSHASTRIP=@LIBXYZSHASTRIP@ | ||
28 | 29 | DESTDIR= |
29 | 30 | SYSTEM_MIGEMODIR=@SYSTEM_MIGEMODIR@ |
30 | 31 | SO_VERSION=@SO_VERSION@ |
32 | +EXTDIR=@EXTDIR@ | |
31 | 33 | |
32 | 34 | ########################################################## |
33 | -all: lib xyzsh | |
35 | +# main | |
36 | +########################################################## | |
37 | +all: lib xyzsh extension | |
34 | 38 | rm -f install |
35 | 39 | |
40 | +xyzsh: config.h src/main.c $(LIBXYZSHSO) $(LIBXYZSHA) | |
41 | + $(CC) -o xyzsh src/main.c $(CFLAGS:-static=) -lxyzsh $(LIBS) | |
42 | + | |
36 | 43 | lib: $(LIBXYZSHSO1) $(LIBXYZSHA) |
37 | 44 | rm -f install |
38 | 45 |
@@ -53,15 +60,6 @@ lib-dest-install: | ||
53 | 60 | if [ "$(LIBXYZSHSO)" = libxyzsh.so ]; then ln -s -f libxyzsh.so.$(SO_VERSION) "$(DESTDIR)/$(libdir)"/libxyzsh.so.1; elif [ "$(LIBXYZSHSO)" = libxyzsh.dylib ]; then ln -s -f libxyzsh.$(SO_VERSION).dylib "$(DESTDIR)/$(libdir)"/libxyzsh.1.dylib; fi |
54 | 61 | if [ "$(LIBXYZSHSO)" = libxyzsh.so ]; then ln -s -f libxyzsh.so.$(SO_VERSION) "$(DESTDIR)/$(libdir)"/libxyzsh.so; elif [ "$(LIBXYZSHSO)" = libxyzsh.dylib ]; then ln -s -f libxyzsh.$(SO_VERSION).dylib "$(DESTDIR)/$(libdir)"/libxyzsh.dylib; fi |
55 | 62 | |
56 | -clean: | |
57 | - rm -fR xyzsh xyzsh.dSYM src/*.o libxyzsh* xyzsh.exe* config.log config.status *.stackdump autom4te.cache | |
58 | - | |
59 | -distclean: | |
60 | - rm -fR xyzsh xyzsh.dSYM src/*.o libxyzsh* config.h Makefile xyzsh.exe* config.log config.status *.stackdump autom4te.cache | |
61 | - | |
62 | -xyzsh: config.h src/main.c $(LIBXYZSHSO) $(LIBXYZSHA) | |
63 | - $(CC) -o xyzsh src/main.c $(CFLAGS:-static=) -lxyzsh $(LIBS) | |
64 | - | |
65 | 63 | ######################################################## |
66 | 64 | # xyzsh libraries |
67 | 65 | ######################################################## |
@@ -87,18 +85,20 @@ libxyzsh.dylib: libxyzsh.$(SO_VERSION).dylib | ||
87 | 85 | cp libxyzsh.$(SO_VERSION).dylib libxyzsh.1.dylib |
88 | 86 | cp libxyzsh.$(SO_VERSION).dylib libxyzsh.dylib |
89 | 87 | |
90 | -permission: | |
91 | - chmod 644 * | |
92 | - chmod 755 .git man src configure | |
93 | - chmod 644 src/*.c | |
94 | - chmod 644 src/xyzsh/*.h | |
95 | - | |
96 | 88 | ######################################################### |
97 | -# install | |
89 | +# Object files | |
98 | 90 | ######################################################### |
99 | 91 | $(OBJ): src/xyzsh/xyzsh.h src/xyzsh/block.h src/xyzsh/curses.h src/xyzsh/debug.h src/xyzsh/hash.h src/xyzsh/kanji.h src/xyzsh/list.h src/xyzsh/string.h src/xyzsh/vector.h Makefile configure |
100 | 92 | |
101 | 93 | ######################################################### |
94 | +# Extension | |
95 | +######################################################### | |
96 | +extension: $(EXTOBJ) | |
97 | + | |
98 | +src/ext/migemo.so: src/ext/migemo.c | |
99 | + gcc -shared src/ext/migemo.c -o src/ext/migemo.so -lmigemo -lxyzsh $(LIBS) $(CFLAGS) | |
100 | + | |
101 | +######################################################### | |
102 | 102 | # install |
103 | 103 | ######################################################### |
104 | 104 | install: lib-install |
@@ -132,6 +132,9 @@ normal-install: | ||
132 | 132 | $(INSTALL) -m 644 completion.xyzsh "$(sysconfdir)" |
133 | 133 | $(INSTALL) -m 644 help.xyzsh "$(sysconfdir)" |
134 | 134 | $(INSTALL) -m 644 read_history.xyzsh "$(sysconfdir)" |
135 | + mkdir -p "$(DESTDIR)/$(EXTDIR)" | |
136 | + $(INSTALL) -m 755 src/ext/migemo.so "$(EXTDIR)" | |
137 | + $(INSTALL) -m 644 src/ext/migemo.so.xyzsh "$(EXTDIR)" | |
135 | 138 | |
136 | 139 | dest-install: |
137 | 140 | mkdir -p "$(DESTDIR)/$(bindir)"; |
@@ -160,4 +163,52 @@ dest-install: | ||
160 | 163 | $(INSTALL) -m 644 completion.xyzsh "$(DESTDIR)/$(sysconfdir)" |
161 | 164 | $(INSTALL) -m 644 help.xyzsh "$(DESTDIR)/$(sysconfdir)" |
162 | 165 | $(INSTALL) -m 644 read_history.xyzsh "$(DESTDIR)/$(sysconfdir)" |
166 | + mkdir -p "$(DESTDIR)/$(EXTDIR)" | |
167 | + $(INSTALL) -m 755 src/ext/migemo.so "$(DESTDIR)/$(EXTDIR)" | |
168 | + $(INSTALL) -m 644 src/ext/migemo.so.xyzsh "$(DESTDIR)/$(EXTDIR)" | |
169 | + | |
170 | +######################################################### | |
171 | +# uninstall | |
172 | +######################################################### | |
173 | +uninstall: | |
174 | + rm -f $(includedir)/block.h | |
175 | + rm -f $(includedir)/curses.h | |
176 | + rm -f $(includedir)/debug.h | |
177 | + rm -f $(includedir)/hash.h | |
178 | + rm -f $(includedir)/kanji.h | |
179 | + rm -f $(includedir)/list.h | |
180 | + rm -f $(includedir)/string.h | |
181 | + rm -f $(includedir)/vector.h | |
182 | + rm -f $(includedir)/xyzsh.h | |
183 | + rmdir $(includedir) | |
184 | + rm -f $(docdir)/USAGE | |
185 | + rm -f $(docdir)/USAGE.ja | |
186 | + rm -f $(docdir)/README | |
187 | + rm -f $(docdir)/README.ja | |
188 | + rm -f $(docdir)/CHANGELOG | |
189 | + rmdir $(docdir) | |
190 | + rm -f $(bindir)/xyzsh | |
191 | + rm -f $(mandir)/man1/xyzsh.1 | |
192 | + rm -f $(sysconfdir)/xyzsh.xyzsh | |
193 | + rm -f $(sysconfdir)/completion.xyzsh | |
194 | + rm -f $(sysconfdir)/help.xyzsh | |
195 | + rm -f $(sysconfdir)/read_history.xyzsh | |
196 | + rmdir $(sysconfdir) | |
163 | 197 | |
198 | +######################################################### | |
199 | +# permission | |
200 | +######################################################### | |
201 | +permission: | |
202 | + chmod 644 * | |
203 | + chmod 755 .git man src configure | |
204 | + chmod 644 src/*.c | |
205 | + chmod 644 src/xyzsh/*.h | |
206 | + | |
207 | +######################################################## | |
208 | +# clean | |
209 | +######################################################## | |
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 | |
212 | + | |
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 |
@@ -161,12 +161,14 @@ Used files | ||
161 | 161 | /usr/local/etc/xyzsh/completion.xyzsh --> a source completion setting file |
162 | 162 | /usr/local/etc/xyzsh/help.xyzsh --> a source help setting file |
163 | 163 | /usr/local/etc/xyzsh/read_history.xyzsh --> a source which reads command line history |
164 | + /usr/local/lib/xyzsh/*.so --> xyzsh C extension library | |
164 | 165 | ~/.xyzsh/xyzsh.xyzsh --> a source user setting file. xyzsh read this after /usr/local/etc/xyzsh.xyzsh |
165 | 166 | ~/.xyzsh/history --> a command line history file |
166 | 167 | ~/.xyzsh/macro --> macro which is runned by typing C-x on command line uses this file |
167 | 168 | ~/.xyzsh/jump --> jump inner command uses this file |
168 | 169 | ~/.xyzsh/menu --> menu inner command uses this file |
169 | 170 | ~/.xyzsh/program --> program list which is entried to root object |
171 | + ~/.xyzsh/lib/*.so --> xyzsh C extension library for user | |
170 | 172 | |
171 | 173 | Encoding and Line field |
172 | 174 | xyzsh script source file must be written with UTF-8 encode and LF Linefield. But, xyzsh can treat UTF8, EUCJP, and SJIS encodings and can treat LF, CR, LFCR line fields. (EUCJP and SJIS are for Japanese) |
@@ -149,7 +149,7 @@ xyzsh シェルスクリプト言語 | ||
149 | 149 | 日本人向けのオプション |
150 | 150 | |
151 | 151 | --with-migemo |
152 | - migemo_match内部コマンドを作成します。 | |
152 | + migemo::match内部コマンドをC拡張ライブラリとして作成します。 | |
153 | 153 | --with-migemo-dir |
154 | 154 | デフォルトでは/usr, /usr/localで検索されるmigemoのインストール先を指定します。 |
155 | 155 | これも管理者権限がない場合で自分のホームディレクトリにmigemoをインストールした場合には必要になるでしょう。 |
@@ -198,6 +198,7 @@ xyzshが使用するファイル | ||
198 | 198 | /usr/local/etc/xyzsh/completion.xyzsh --> 補完関係の設定ファイル |
199 | 199 | /usr/local/etc/xyzsh/help.xyzsh --> ヘルプ関連の設定ファイル |
200 | 200 | /usr/local/etc/xyzsh/read_history.xyzsh --> コマンドラインのヒストリを読み込む設定ファイル |
201 | + /usr/local/lib/xyzsh/*.so --> xyzshのC拡張ライブラリ | |
201 | 202 | ~/.xyzsh/xyzsh.xyzsh --> /usr/local/etc/xyzsh.xyzshの後に呼ばれるユーザーの設定ファイル |
202 | 203 | ~/.xyzsh/history --> コマンドライン履歴が保存されたファイル |
203 | 204 | ~/.xyzsh/macro --> コマンドラインでControl-xを押した場合に表示されるワンライナーの一覧。 |
@@ -208,6 +209,7 @@ xyzshが使用するファイル | ||
208 | 209 | ~/.xyzsh/menu --> menu内部コマンドを実行したときに表示されるワンライナーの一覧。 |
209 | 210 | ~/.xyzsh/program --> sys::を省略したい外部プログラムの一覧。このファイルに外部プログラム名を追加して |
210 | 211 | rehashコマンドを実行すれば、sys::を省略することができるようになる。 |
212 | + ~/.xyzsh/lib/*.so --> ユーザーがインストールしたxyzshのC拡張ライブラリ | |
211 | 213 | |
212 | 214 | エンコードと改行コードについて |
213 | 215 |
@@ -8,7 +8,7 @@ | ||
8 | 8 | |
9 | 9 | Ofcourse, on interactive shell, it helps you to type with completion. |
10 | 10 | |
11 | - Taget users are who has mastered bash, sed/awk, perl, python, ruby and want to seek somemore. If you don't master these tools, you should learn these tools before using xyzsh. | |
11 | + Taget users are who has mastered bash, sed/awk, perl, python, ruby and want to seek somemore. If you don't master these tools, you should learn these tools before using xyzsh because these tools are installed on many systems. | |
12 | 12 | |
13 | 13 | I can't take resposbility on your works with xyzsh. I recommend that you use this on your personal systems. |
14 | 14 |
@@ -16,8 +16,6 @@ | ||
16 | 16 | |
17 | 17 | You can get this on the internet belows |
18 | 18 | |
19 | - Develop version http://code.google.com/p/xyzsh/ | |
20 | - | |
21 | 19 | Stable version http://sourceforge.jp/projects/xyzsh |
22 | 20 | Develop version http://sourceforge.jp/projects/xyzsh/scm/git/xyzsh/ |
23 | 21 |
@@ -688,3 +686,12 @@ | ||
688 | 686 | |
689 | 687 | help (command name) |
690 | 688 | |
689 | +3.6 C extension library | |
690 | + | |
691 | + About how to load C language extension library. Searched path is 3 step. First searched it from /usr/local/xyzsh/(pathname) or (installed prefix path)/(pathname), next searched it from ~/lib/(pathname), and finaly searched it from (absolute pathname or relative pathname). You can't ommit the file name extesion. | |
692 | + About how to make C language extension library. I made migemo C extension. See src/ext/migemo.c. You need to define dl_init and dl_final. dl_init is called on "load -dynamic-library" command called. dl_final is called on xyzsh exited. You can compile the C extension source like below | |
693 | + | |
694 | + gcc -shared src/ext/migemo.c -o src/ext/migemo.so -lmigemo -lxyzsh $(LIBS) $(CFLAGS) | |
695 | + | |
696 | + Xyzsh reads a xyzsh source which is (dynamic library file).xyzsh on running "load -dynamic-library". You can write help, completion settings, and son initialize function on it. | |
697 | + |
@@ -12,7 +12,7 @@ | ||
12 | 12 | |
13 | 13 | 対象とするユーザーとしては、bashやperl, python, ruby, sed, awkなど一通りマスターしたけれども |
14 | 14 | 「もっと何か無いかな?」 と思っておられる方です。 |
15 | - 初心者は最初にbashやperlなどを学んだほうがいいと思います。 | |
15 | + 初心者の方は最初にbashやperlなどを学んだほうがいいと思います。 | |
16 | 16 | (大抵のシステムではそちらがインストールされているので) |
17 | 17 | |
18 | 18 | 使用に当たっては、このプログラムによって被る結果には自分で責任を持つことをお願いします。 |
@@ -739,13 +739,13 @@ | ||
739 | 739 | error-data |
740 | 740 | data |
741 | 741 | |
742 | -3.2 複数行のテキストの取り扱い | |
742 | +3.3 複数行のテキストの取り扱い | |
743 | 743 | |
744 | 744 | xyzshで複数行のテキストを一つの変数に入力したい場合は-Laオプションを使ってください。 |
745 | 745 | \aが行の区切りとして扱われ、結果\n,\r\n,\rなどを単なるテキストとして処理でき、複数行のテキストを扱えます。 |
746 | 746 | 少し複雑なコードとなりますがpコマンドでデバッグすれば、理解できるかと思います。 |
747 | 747 | |
748 | -3.3 コマンドライン補完 | |
748 | +3.4 コマンドライン補完 | |
749 | 749 | |
750 | 750 | コマンドライン補完にはreadlineを使っているので、ほぼbashと同じように使うことができます。 |
751 | 751 |
@@ -758,13 +758,24 @@ | ||
758 | 758 | |
759 | 759 | rlオブジェクトを使って補完のプログラム中にreadlineを操作できます。rl::helpを見てください。 |
760 | 760 | |
761 | -3.4 ヘルプ | |
761 | +3.5 ヘルプ | |
762 | 762 | |
763 | 763 | help コマンド名 |
764 | 764 | |
765 | 765 | でコマンドの使い方を見ることができます。各コマンドのオプションなどはそちらで調べてください。 |
766 | 766 | |
767 | -3.5 xyzshの組み込みについて | |
767 | +3.6 C拡張ライブラリ | |
768 | + | |
769 | + C拡張ライブラリはload -dynamic-libraryを使って呼び出せます。サーチパスは/usr/local/lib/xyzsh/"ファイル名"(xyzshをインストールしたディレクトリ/lib/xyzsh/"ファイル名")を探して無いなら、~/lib/"ファイル名"を探し、それでもないなら、"ファイル名(絶対パス、または相対パス)"を探します。拡張子は省略してはいけません。 | |
770 | + 作り方について。migemoがC拡張ライブラリとなってます。詳しくはsrc/ext/migemo.cを見てください。dl_initとdl_finalを定義する必要があります。dl_initはload -dynamic-libraryをするときに呼ばれます。dl_finalはxyzshが終了するときに呼ばれます。拡張ライブラリのコンパイルは | |
771 | + | |
772 | + gcc -shared src/ext/migemo.c -o src/ext/migemo.so -lmigemo -lxyzsh $(LIBS) $(CFLAGS) | |
773 | + | |
774 | + などとすれば良いです。$(LIBS)と$(CFLAGS)は自分で定義する必要があります。 | |
775 | + | |
776 | + 拡張ライブラリと同じ名前 + .xyzshのソースファイルはload時に自動的に読み込まれます。ヘルプや補完などをそこに書くことができます。 | |
777 | + | |
778 | +3.7 xyzshの組み込みについて | |
768 | 779 | |
769 | 780 | xyzshのメモリ管理について。xyzshはGCとスタックとmalloc&freeの3つのオブジェクトのメモリ管理を行なってます。しかし、以下の制限があります。 |
770 | 781 | GCで作り出されるオブジェクトはマークをさせるためにgRootObjectかgXyzshObjectから辿れるようにしなければなりません。(GCで管理されてgRootObjectかgXyzshObjectから辿れるコンテナオブジェクトに格納される必要がある)。でなければ、sweepで消されてしまいます。sweepは一定回数コードを実行すると自動的に実行されます。 |
@@ -1,6 +1,6 @@ | ||
1 | 1 | |
2 | 2 | def xyzsh_quote ( |
3 | - | sub -global ' |\\|"|\$|\*|\?|\[|\]|\{|\}|\&|\;|\(|\)|-' ( | add -number 0 \\ ) | |
3 | + | sub -global ' |\\|"|\$|\*|\?|\[|\]|\{|\}|\&|\;|\(|\)' ( | add -number 0 \\ ) | |
4 | 4 | ) |
5 | 5 | |
6 | 6 | def xyzsh_dequote ( |
@@ -23,22 +23,28 @@ def program_completion ( | ||
23 | 23 | ) |
24 | 24 | ) |
25 | 25 | |
26 | -compl::run( object rl ) | |
27 | - | |
28 | -completion rl::help ( | |
29 | - rl::self | egrep native\ function\$ | root::scan '(^.+?):' | each ( | chomp | quote | pomch ) | |
30 | -) | |
31 | - | |
32 | -root | egrep ': native function$' | egrep -v '^run: native function$|^show: native function$' | scan '(^.+):' | add sub\nsplit\nscan\n | each ( | |
33 | - | var -local command | |
26 | +def file_completion ( | |
27 | + | split '(?<!\\) +' | lines -1 | var -local inputing | |
34 | 28 | |
35 | - help $command | lines 1..-1 | scan '^-[a-zA-Z0-9-]+' |chomp| add -number 0 $command\a | hash -append -La COMPLETION_OPTIONS | |
29 | + if(inputing | index -quiet /) ( | |
30 | + sys::dirname $(inputing |chomp| if (|rows -1 | = /) ( |add aaa ) else ( | print ) ) | var -local DIR | |
36 | 31 | |
37 | - print <<<EOS | |
38 | - completion "$command" ( | |
39 | - hash COMPLETION_OPTIONS -key "$command" | |
32 | + eval "ls $DIR" | each ( | |
33 | + | if (|chomp | add -number 0 $DIR/ | -d) ( | |
34 | + |chomp | add -number 0 $DIR/ | xyzsh_quote | add / | pomch | |
35 | + ) else ( | |
36 | + |chomp | add -number 0 $DIR/ | xyzsh_quote | pomch | |
37 | + ) | |
38 | + ) | |
39 | + ) else ( | |
40 | + ls | each ( | |
41 | + | if (|chomp| -d) ( | |
42 | + | chomp | xyzsh_quote | add / | pomch | |
43 | + ) else ( | |
44 | + |chomp| xyzsh_quote | pomch | |
45 | + ) | |
46 | + ) | |
40 | 47 | ) |
41 | -EOS | eval | |
42 | 48 | ) |
43 | 49 | |
44 | 50 | class object_completion ( |
@@ -68,6 +74,18 @@ class object_completion ( | ||
68 | 74 | ) |
69 | 75 | ) |
70 | 76 | |
77 | +root | egrep ': native function$' | egrep -v '^run: native function$|^show: native function$' | scan '(^.+):' | add sub\nsplit\nscan\n | each ( | |
78 | + | var -local command | |
79 | + | |
80 | + help $command | lines 1..-1 | scan '^-[a-zA-Z0-9-]+' |chomp| add -number 0 $command\a | hash -append -La COMPLETION_OPTIONS | |
81 | + | |
82 | + print <<<EOS | |
83 | + completion "$command" ( | |
84 | + hash COMPLETION_OPTIONS -key "$command" | |
85 | + ) | |
86 | +EOS | eval | |
87 | +) | |
88 | + | |
71 | 89 | completion var ( |
72 | 90 | | object_completion var |
73 | 91 | hash COMPLETION_OPTIONS -key var |
@@ -175,3 +193,19 @@ completion kill ( | ||
175 | 193 | rl::clear_screen |
176 | 194 | ) |
177 | 195 | |
196 | +completion load ( | |
197 | + | if(| index -quiet "-dynamic-library" ) ( | |
198 | + ls $XYZSH_EXT_PATH | (| print -read-from-error; | print) | egrep '.so$' | |
199 | + ls ~/.xyzsh/lib | ( | print -read-from-error; | print ) | grep '.so$' | |
200 | + ) else ( | |
201 | + | file_completion | |
202 | + hash COMPLETION_OPTIONS -key load | |
203 | + ) | |
204 | +) | |
205 | + | |
206 | +root::compl::run( root::object rl ) | |
207 | + | |
208 | +completion rl::help ( | |
209 | + rl::self | egrep native\ function\$ | egrep -v 'run|show' | root::scan '(^.+?):' | each ( | chomp | quote | pomch ) | |
210 | +) | |
211 | + |
@@ -621,6 +621,8 @@ ac_includes_default="\ | ||
621 | 621 | |
622 | 622 | ac_subst_vars='LTLIBOBJS |
623 | 623 | LIBOBJS |
624 | +EXTDIR | |
625 | +EXTOBJ | |
624 | 626 | EGREP |
625 | 627 | GREP |
626 | 628 | CPP |
@@ -3041,6 +3043,7 @@ fi | ||
3041 | 3043 | ##################################################################### |
3042 | 3044 | # check operating systems |
3043 | 3045 | ##################################################################### |
3046 | +EXTDIR='$(libdir)/xyzsh/' | |
3044 | 3047 | SO_VERSION=1.7.0 |
3045 | 3048 | |
3046 | 3049 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking Operating System" >&5 |
@@ -3049,7 +3052,7 @@ $as_echo_n "checking Operating System... " >&6; } | ||
3049 | 3052 | OBJ="src/gc.o src/stack.o src/string.o src/list.o src/kanji.o src/debug.o src/hash.o src/vector.o src/block.o src/fun.o src/class.o src/completion.o src/xyzsh.o src/parser.o src/run.o src/readline.o src/curses.o src/cmd_base.o src/cmd_obj.o src/cmd_file.o src/cmd_str.o src/cmd_ary.o src/cmd_condition.o src/interface.o src/object.o src/uobject.o src/cmd_num.o src/cmd_curses.o src/fd.o src/nfun.o src/extprog.o" |
3050 | 3053 | |
3051 | 3054 | |
3052 | -CFLAGS='-DSYSCONFDIR="\"${sysconfdir}/\"" -DDOCDIR="\"${docdir}/\"" -DSYSTEM_MIGEMODIR="\"${SYSTEM_MIGEMODIR}\""' | |
3055 | +CFLAGS='-DSYSCONFDIR="\"${sysconfdir}/\"" -DDOCDIR="\"${docdir}/\"" -DSYSTEM_MIGEMODIR="\"${SYSTEM_MIGEMODIR}\"" -DEXTDIR="\"${EXTDIR}\""' | |
3053 | 3056 | |
3054 | 3057 | if test `uname -s` = "Darwin"; then |
3055 | 3058 | echo "Darwin" |
@@ -3847,6 +3850,8 @@ then | ||
3847 | 3850 | exit |
3848 | 3851 | fi |
3849 | 3852 | |
3853 | +EXTOBJ= | |
3854 | + | |
3850 | 3855 | ##################################################################### |
3851 | 3856 | # math settings |
3852 | 3857 | ##################################################################### |
@@ -3972,7 +3977,7 @@ if test $ENABLE_MIGEMO = 1 | ||
3972 | 3977 | then |
3973 | 3978 | ac_fn_c_check_header_mongrel "$LINENO" "migemo.h" "ac_cv_header_migemo_h" "$ac_includes_default" |
3974 | 3979 | if test "x$ac_cv_header_migemo_h" = xyes; then : |
3975 | - LIBS="$LIBS -lmigemo"; $as_echo "#define HAVE_MIGEMO_H 1" >>confdefs.h | |
3980 | + EXTOBJ="$EXTOBJ src/ext/migemo.so"; $as_echo "#define HAVE_MIGEMO_H 1" >>confdefs.h | |
3976 | 3981 | |
3977 | 3982 | else |
3978 | 3983 | exit |
@@ -3983,6 +3988,8 @@ fi | ||
3983 | 3988 | |
3984 | 3989 | |
3985 | 3990 | |
3991 | + | |
3992 | + | |
3986 | 3993 | ########################################################################## |
3987 | 3994 | # type checking |
3988 | 3995 | ########################################################################### |
@@ -32,6 +32,7 @@ AC_SUBST(SYSTEM_MIGEMODIR) | ||
32 | 32 | ##################################################################### |
33 | 33 | # check operating systems |
34 | 34 | ##################################################################### |
35 | +EXTDIR='$(libdir)/xyzsh/' | |
35 | 36 | SO_VERSION=1.7.0 |
36 | 37 | AC_SUBST(SO_VERSION) |
37 | 38 | AC_MSG_CHECKING(Operating System) |
@@ -39,7 +40,7 @@ AC_MSG_CHECKING(Operating System) | ||
39 | 40 | OBJ="src/gc.o src/stack.o src/string.o src/list.o src/kanji.o src/debug.o src/hash.o src/vector.o src/block.o src/fun.o src/class.o src/completion.o src/xyzsh.o src/parser.o src/run.o src/readline.o src/curses.o src/cmd_base.o src/cmd_obj.o src/cmd_file.o src/cmd_str.o src/cmd_ary.o src/cmd_condition.o src/interface.o src/object.o src/uobject.o src/cmd_num.o src/cmd_curses.o src/fd.o src/nfun.o src/extprog.o" |
40 | 41 | AC_SUBST(OBJ) |
41 | 42 | |
42 | -CFLAGS='-DSYSCONFDIR="\"${sysconfdir}/\"" -DDOCDIR="\"${docdir}/\"" -DSYSTEM_MIGEMODIR="\"${SYSTEM_MIGEMODIR}\""' | |
43 | +CFLAGS='-DSYSCONFDIR="\"${sysconfdir}/\"" -DDOCDIR="\"${docdir}/\"" -DSYSTEM_MIGEMODIR="\"${SYSTEM_MIGEMODIR}\"" -DEXTDIR="\"${EXTDIR}\""' | |
43 | 44 | |
44 | 45 | if test `uname -s` = "Darwin"; then |
45 | 46 | echo "Darwin" |
@@ -234,6 +235,8 @@ then | ||
234 | 235 | exit |
235 | 236 | fi |
236 | 237 | |
238 | +EXTOBJ= | |
239 | + | |
237 | 240 | ##################################################################### |
238 | 241 | # math settings |
239 | 242 | ##################################################################### |
@@ -261,10 +264,12 @@ AC_HAVE_LIBRARY(onig, [ LIBS="$LIBS -lonig"; ], [ exit ]) | ||
261 | 264 | ########################################################################### |
262 | 265 | if test $ENABLE_MIGEMO = 1 |
263 | 266 | then |
264 | - AC_CHECK_HEADER(migemo.h, [LIBS="$LIBS -lmigemo"; AC_DEFINE(HAVE_MIGEMO_H, 1)], [ exit ]) | |
267 | + AC_CHECK_HEADER(migemo.h, [EXTOBJ="$EXTOBJ src/ext/migemo.so"; AC_DEFINE(HAVE_MIGEMO_H, 1)], [ exit ]) | |
265 | 268 | fi |
266 | 269 | |
270 | +AC_SUBST(EXTOBJ) | |
267 | 271 | AC_SUBST(LIBS) |
272 | +AC_SUBST(EXTDIR) | |
268 | 273 | |
269 | 274 | ########################################################################## |
270 | 275 | # type checking |
@@ -137,7 +137,7 @@ if (条件式1) (ブロック1) (条件式2) (ブロック2) ... (条件式x) ( | ||
137 | 137 | - |
138 | 138 | 条件式が真ならば対応するブロックを実行する。もし全部の条件式が偽なら最後のブロックを実行する |
139 | 139 | - |
140 | -return | |
140 | +return (リターンコード) | |
141 | 141 | - |
142 | 142 | 関数かクラスを実行中なら、途中で抜ける |
143 | 143 | - |
@@ -175,6 +175,8 @@ print 文字列1 文字列2, ..., 文字列x | ||
175 | 175 | load ファイル名 引数1 引数2 ... 引数X |
176 | 176 | - |
177 | 177 | スクリプトファイルを実行する。ローカル変数は初期化される。ARGVに引数が入っている。 |
178 | + | |
179 | +-dynamic-library C言語による拡張ライブラリをロードする。サーチパスは/usr/local/lib/xyzsh/"ファイル名"(xyzshをインストールしたディレクトリ/lib/xyzsh/"ファイル名")を探して無いなら、~/lib/"ファイル名"を探す、それでもないなら、"ファイル名(絶対パス、または相対パス)"を探す。拡張子は省略してはならない。 | |
178 | 180 | - |
179 | 181 | eval (ブロック|文字列) |
180 | 182 | - |
@@ -436,6 +438,8 @@ sort (ブロック) | ||
436 | 438 | |
437 | 439 | -offsets マッチした位置(インデックス)の始点と終点を出力する(グループ化された文字列も含む) |
438 | 440 | -verbose マッチした位置(インデックス)を出力する |
441 | +-ignore-case 大文字と小文字を無視する | |
442 | +-multi-line 複数行にまたがる、正規表現を許す。(パフォーマンスは落ちる) | |
439 | 443 | -byte バイトコードとして処理する |
440 | 444 | -utf8 UTF8コードとして処理する |
441 | 445 | -sjis SJISコードとして処理する |
@@ -741,8 +745,10 @@ index 文字列 | ||
741 | 745 | - |
742 | 746 | パイプから文字列を検索して見つかったインデックスを返すフィルター。 |
743 | 747 | |
748 | +-regex 正規表現で検索する | |
744 | 749 | -quiet 見つかった位置を出力しない。戻り値のみ設定する |
745 | 750 | -ignore-case 大文字と小文字を無視する |
751 | +-multi-line 複数行にまたがる、正規表現を許す。(パフォーマンスは落ちる) | |
746 | 752 | -number 数値 文字列の検索を開始する位置を設定する |
747 | 753 | -count 数値 検索する回数を設定する |
748 | 754 | -byte バイトコードとして処理する |
@@ -755,8 +761,10 @@ rindex 文字列 | ||
755 | 761 | パイプから文字列を検索して見つかったインデックスを返すフィルター。 |
756 | 762 | 末尾から検索する。 |
757 | 763 | |
764 | +-regex 正規表現で検索する | |
758 | 765 | -quiet 見つかった位置を出力しない。戻り値のみ設定する |
759 | 766 | -ignore-case 大文字と小文字を無視する |
767 | +-multi-line 複数行にまたがる、正規表現を許す。(パフォーマンスは落ちる) | |
760 | 768 | -number 数値 文字列の検索を開始する位置を設定する |
761 | 769 | -count 数値 検索する回数を設定する |
762 | 770 | -byte バイトコードとして処理する |
@@ -851,9 +859,15 @@ b | ||
851 | 859 | |
852 | 860 | 変換回数はグローバル変数SUB_COUNTに代入される。 |
853 | 861 | |
862 | +-no-regex 正規表現じゃなくて普通の文字列としてパターンを使う | |
863 | +-ignore-case 大文字と小文字を無視する | |
854 | 864 | -multi-line 複数行にまたがる、正規表現を許す。(パフォーマンスは落ちる) |
855 | 865 | -global 普通なら各行に一回のみ変換を行うが、これを付けると各行何回も変換を行う |
856 | 866 | -quiet 変換結果を出力しない。戻り値と変換結果を格納した変数のみ設定する。 |
867 | +-byte バイトコードとして処理する | |
868 | +-utf8 UTF8コードとして処理する | |
869 | +-sjis SJISコードとして処理する | |
870 | +-eucjp EUCJPコードとして処理する | |
857 | 871 | -Lw 改行コードをCRLFとして処理する |
858 | 872 | -Lm 改行コードをCRとして処理する |
859 | 873 | -Lu 改行コードをLFとして処理する |
@@ -875,7 +889,12 @@ scan 正規表現 (変換文字列|ブロック) | ||
875 | 889 | 最後にマッチした文字列 LAST_MATCH |
876 | 890 | マッチした文字列の数 MATCH_NUMBER |
877 | 891 | |
892 | +-ignore-case 大文字と小文字を無視する | |
878 | 893 | -multi-line 複数行にまたがる、正規表現を許す。(パフォーマンスは落ちる) |
894 | +-byte バイトコードとして処理する | |
895 | +-utf8 UTF8コードとして処理する | |
896 | +-sjis SJISコードとして処理する | |
897 | +-eucjp EUCJPコードとして処理する | |
879 | 898 | -Lw 改行コードをCRLFとして処理する |
880 | 899 | -Lm 改行コードをCRとして処理する |
881 | 900 | -Lu 改行コードをLFとして処理する |
@@ -890,6 +909,8 @@ split 正規表現 | ||
890 | 909 | パイプから得たテキストを正規表現にマッチする部分を区切りとして分解する。分解結果は複数行の文字列として出力される。 |
891 | 910 | 正規表現が省略されたら、"\s+"が設定される。 |
892 | 911 | |
912 | +-no-regex 正規表現じゃなくて普通の文字列としてパターンを使う | |
913 | +-ignore-case 大文字と小文字を無視する | |
893 | 914 | -multi-line 複数行にまたがる、正規表現を許す。(パフォーマンスは落ちる) |
894 | 915 | -byte バイトコードとして処理する |
895 | 916 | -utf8 UTF8コードとして処理する |
@@ -1053,7 +1074,7 @@ if (condition1) (block1) (condition2) (block2)...(conditioni X) (block X) (the l | ||
1053 | 1074 | - |
1054 | 1075 | If the result of condition is true, run conresponding block. If the all result of conditions, runthe last of blocks. |
1055 | 1076 | - |
1056 | -return | |
1077 | +return (return code) | |
1057 | 1078 | - |
1058 | 1079 | If running function or class, exited from it. |
1059 | 1080 | - |
@@ -1089,6 +1110,8 @@ If you use this for filter, outputs the inout then. | ||
1089 | 1110 | load (script file name) (argument1) (argument2) ... (argument X) |
1090 | 1111 | - |
1091 | 1112 | Run the script file. Local variable stackframe is initialized, and local variable array "ARGV" has the arguments. |
1113 | + | |
1114 | +-dynamic-library load C language extension library. Searched path is 3 step. First searched it from /usr/local/xyzsh/(pathname) or (installed prefix path)/(pathname), next searched it from ~/lib/(pathname), and finaly searched it from (absolute pathname or relative pathname). You can't ommit the file name extesion. | |
1092 | 1115 | - |
1093 | 1116 | eval (block|string) |
1094 | 1117 | - |
@@ -1347,6 +1370,8 @@ Matched number --> MATCH_NUMBER | ||
1347 | 1370 | |
1348 | 1371 | -offsets Output all maching points. |
1349 | 1372 | -verbose Output maching point(index). |
1373 | +-ignore-case Ignore case. | |
1374 | +-multi-line Allow to write multiline matching regex, but the performance is less than normal. | |
1350 | 1375 | -byte assume text encode as byte code. |
1351 | 1376 | -utf8 assume text encode as utf-8 code. |
1352 | 1377 | -sjis assume text encode as SJIS code. |
@@ -1616,8 +1641,10 @@ index (string) | ||
1616 | 1641 | - |
1617 | 1642 | It is a filter for outputing the index with searching the string position. |
1618 | 1643 | |
1644 | +-regex search with regex | |
1619 | 1645 | -quiet No output, but set return code. |
1620 | 1646 | -ignore-case Ignore case. |
1647 | +-multi-line Allow to write multiline matching regex, but the performance is less than normal. | |
1621 | 1648 | -number (number) Set the first position on searching string. |
1622 | 1649 | -count 数値 Set the searching count. |
1623 | 1650 | -byte assume text encode as byte code. |
@@ -1630,8 +1657,10 @@ rindex (string) | ||
1630 | 1657 | It is a filter for outputing the index with searching the string position. |
1631 | 1658 | Searching from the tail. |
1632 | 1659 | |
1660 | +-regex search with regex | |
1633 | 1661 | -quiet No output, but set return code. |
1634 | 1662 | -ignore-case Ignore case. |
1663 | +-multi-line Allow to write multiline matching regex, but the performance is less than normal. | |
1635 | 1664 | -number (number) Set the first position on searching string. |
1636 | 1665 | -count 数値 Set the searching count. |
1637 | 1666 | -byte assume text encode as byte code. |
@@ -1729,6 +1758,8 @@ b | ||
1729 | 1758 | |
1730 | 1759 | You can get the count of searching to use the local variable "SUB_COUNT" |
1731 | 1760 | |
1761 | +-no-regex Don't use regex for pattern. Use it as text. | |
1762 | +-ignore-case ignore case | |
1732 | 1763 | -multi-line Allow to write multiline matching regex, but the performance is less than normal. |
1733 | 1764 | -global Allow to match at several times in a line. |
1734 | 1765 | -quiet No output, but set return code and the local variables. |
@@ -1736,6 +1767,10 @@ You can get the count of searching to use the local variable "SUB_COUNT" | ||
1736 | 1767 | -Lm Processing with CR line field |
1737 | 1768 | -Lu Processing with LF line field |
1738 | 1769 | -La Processing with BEL line field |
1770 | +-byte assume text encode as byte code. | |
1771 | +-utf8 assume text encode as utf-8 code. | |
1772 | +-sjis assume text encode as SJIS code. | |
1773 | +-eucjp assume text encode as EUCJP code. | |
1739 | 1774 | - |
1740 | 1775 | scan (regex|block) |
1741 | 1776 | - |
@@ -1753,7 +1788,12 @@ Postmatched string --> POSTMATCH | ||
1753 | 1788 | Lastmatched string --> LAST_MATCH |
1754 | 1789 | Matched number --> MATCH_NUMBER |
1755 | 1790 | |
1791 | +-ignore-case ignore case | |
1756 | 1792 | -multi-line Allow to write multiline matching regex, but the performance is less than normal. |
1793 | +-byte assume text encode as byte code. | |
1794 | +-utf8 assume text encode as utf-8 code. | |
1795 | +-sjis assume text encode as SJIS code. | |
1796 | +-eucjp assume text encode as EUCJP code. | |
1757 | 1797 | -Lw Processing with CRLF line field |
1758 | 1798 | -Lm Processing with CR line field |
1759 | 1799 | -Lu Processing with LF line field |
@@ -1769,6 +1809,8 @@ split (regex) | ||
1769 | 1809 | It is a filter for spliting pipe data with regex. |
1770 | 1810 | If you omit the argument, xyzsh set "\s+" for it. |
1771 | 1811 | |
1812 | +-no-regex Don't use regex for pattern. Use it as text. | |
1813 | +-ignore-case ignore case | |
1772 | 1814 | -multi-line Allow to write multiline matching regex, but the performance is less than normal. |
1773 | 1815 | -byte assume text encode as byte code. |
1774 | 1816 | -utf8 assume text encode as utf-8 code. |
@@ -1865,6 +1907,10 @@ rl::run( | ||
1865 | 1907 | object help ( Help ) |
1866 | 1908 | |
1867 | 1909 | print <<<'EOS' |
1910 | +point | |
1911 | +- | |
1912 | +カーソル位置を出力する | |
1913 | +- | |
1868 | 1914 | point_move (number) |
1869 | 1915 | - |
1870 | 1916 | コンプレッション時のカーソル移動 |
@@ -1873,13 +1919,17 @@ clear_screen | ||
1873 | 1919 | - |
1874 | 1920 | コンプレッション時のスクリーンクリア |
1875 | 1921 | - |
1922 | +replace_line (text) (cursor point) | |
1923 | +- | |
1924 | +コンプレッション時のテキストの置き換え | |
1925 | +- | |
1876 | 1926 | delete_text (start index) (end index) |
1877 | 1927 | - |
1878 | 1928 | コンプレッション時のテキスト削除 |
1879 | 1929 | - |
1880 | -insert_text | |
1930 | +insert_text (text) | |
1881 | 1931 | - |
1882 | -コンプレッション時のテキスト挿入。テキストはパイプから得られる | |
1932 | +コンプレッション時のテキスト挿入。 | |
1883 | 1933 | - |
1884 | 1934 | write_history (file name) |
1885 | 1935 | - |
@@ -1891,6 +1941,10 @@ read_history (file name) | ||
1891 | 1941 | EOS | help::set_helps_ja |
1892 | 1942 | |
1893 | 1943 | print <<<'EOS' |
1944 | +point | |
1945 | +- | |
1946 | +output cursor position. | |
1947 | +- | |
1894 | 1948 | point_move (number) |
1895 | 1949 | - |
1896 | 1950 | cursor move on completion. |
@@ -1903,9 +1957,13 @@ delete_text (start index) (end index) | ||
1903 | 1957 | - |
1904 | 1958 | delete editing line on completion. |
1905 | 1959 | - |
1906 | -insert_text | |
1960 | +replace_line (text) (cursor point) | |
1961 | +- | |
1962 | +replace editing line on completion. | |
1963 | +- | |
1964 | +insert_text (text) | |
1907 | 1965 | - |
1908 | -add string which is getting pipe data to editing line on completion. | |
1966 | +add string to editing line on completion. | |
1909 | 1967 | - |
1910 | 1968 | write_history (file name) |
1911 | 1969 | - |
@@ -208,8 +208,17 @@ BOOL cmd_if(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | ||
208 | 208 | |
209 | 209 | BOOL cmd_return(sObject* nextin, sObject* nextout, sRunInfo* runinfo) |
210 | 210 | { |
211 | - runinfo->mRCode = RCODE_RETURN; | |
212 | - return FALSE; | |
211 | + if(runinfo->mArgsNumRuntime >= 2) { | |
212 | + uchar code = atoi(runinfo->mArgsRuntime[1]); | |
213 | + runinfo->mRCode = RCODE_RETURN | code; | |
214 | + | |
215 | + return FALSE; | |
216 | + } | |
217 | + else { | |
218 | + runinfo->mRCode = RCODE_RETURN; | |
219 | + | |
220 | + return FALSE; | |
221 | + } | |
213 | 222 | } |
214 | 223 | |
215 | 224 | BOOL cmd_subshell(sObject* nextin, sObject* nextout, sRunInfo* runinfo) |
@@ -290,7 +299,7 @@ BOOL cmd_try(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | ||
290 | 299 | if(runinfo->mBlocksNum == 2) { |
291 | 300 | int rcode = 0; |
292 | 301 | if(!run(runinfo->mBlocks[0], nextin, nextout, &rcode, runinfo->mCurrentObject, runinfo->mRunningObject)) { |
293 | - if(rcode == RCODE_NFUN_FALSE || rcode == RCODE_BREAK || rcode == RCODE_RETURN || rcode == RCODE_EXIT) { | |
302 | + if(rcode == RCODE_NFUN_FALSE || rcode == RCODE_BREAK || rcode & RCODE_RETURN || rcode == RCODE_EXIT) { | |
294 | 303 | runinfo->mRCode = rcode; |
295 | 304 | return FALSE; |
296 | 305 | } |
@@ -379,7 +388,15 @@ BOOL cmd_sweep(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | ||
379 | 388 | |
380 | 389 | BOOL cmd_load(sObject* nextin, sObject* nextout, sRunInfo* runinfo) |
381 | 390 | { |
382 | - if(runinfo->mArgsNumRuntime >= 2) { | |
391 | + if(sRunInfo_option(runinfo, "-dynamic-library")) { | |
392 | + if(!load_so_file(runinfo->mArgsRuntime[1], nextin, nextout, runinfo)) | |
393 | + { | |
394 | + return FALSE; | |
395 | + } | |
396 | + | |
397 | + runinfo->mRCode = 0; | |
398 | + } | |
399 | + else if(runinfo->mArgsNumRuntime >= 2) { | |
383 | 400 | runinfo->mRCode = 0; |
384 | 401 | if(!load_file(runinfo->mArgsRuntime[1], nextin, nextout, runinfo, runinfo->mArgsRuntime + 2, runinfo->mArgsNumRuntime -2)) |
385 | 402 | { |
@@ -713,148 +713,3 @@ BOOL cmd_condition_re(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | ||
713 | 713 | return TRUE; |
714 | 714 | } |
715 | 715 | |
716 | -#if defined(HAVE_MIGEMO_H) | |
717 | -#include <migemo.h> | |
718 | - | |
719 | -static migemo* gMigemo; | |
720 | -static regex_t* gReg; | |
721 | - | |
722 | -void migemo_init() | |
723 | -{ | |
724 | - char buf[PATH_MAX]; | |
725 | - char migemodir[PATH_MAX]; | |
726 | - gMigemo = migemo_open(NULL); | |
727 | - | |
728 | - snprintf(migemodir, PATH_MAX, "%s", SYSTEM_MIGEMODIR); | |
729 | - | |
730 | - snprintf(buf, PATH_MAX, "%s/utf-8/migemo-dict", migemodir); | |
731 | - if(migemo_load(gMigemo, MIGEMO_DICTID_MIGEMO, buf) == MIGEMO_DICTID_INVALID) { | |
732 | - fprintf(stderr, "%s is not found\n", buf); | |
733 | - exit(1); | |
734 | - } | |
735 | - snprintf(buf, PATH_MAX, "%s/utf-8/roma2hira.dat", migemodir); | |
736 | - if(migemo_load(gMigemo, MIGEMO_DICTID_ROMA2HIRA, buf) == MIGEMO_DICTID_INVALID) { | |
737 | - fprintf(stderr, "%s is not found\n", buf); | |
738 | - exit(1); | |
739 | - } | |
740 | - snprintf(buf, PATH_MAX, "%s/utf-8/hira2kata.dat", migemodir); | |
741 | - if(migemo_load(gMigemo, MIGEMO_DICTID_HIRA2KATA, buf) == MIGEMO_DICTID_INVALID) { | |
742 | - fprintf(stderr, "%s is not found\n", buf); | |
743 | - exit(1); | |
744 | - } | |
745 | - snprintf(buf, PATH_MAX, "%s/utf-8/han2zen.dat", migemodir); | |
746 | - if(migemo_load(gMigemo, MIGEMO_DICTID_HAN2ZEN, buf) == MIGEMO_DICTID_INVALID) { | |
747 | - fprintf(stderr, "%s is not found\n", buf); | |
748 | - exit(1); | |
749 | - } | |
750 | -} | |
751 | - | |
752 | -void migemo_final() | |
753 | -{ | |
754 | - onig_end(); | |
755 | - migemo_close(gMigemo); | |
756 | - if(gReg) onig_free(gReg); | |
757 | - gReg = NULL; | |
758 | -} | |
759 | - | |
760 | -BOOL cmd_migemo_match(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | |
761 | -{ | |
762 | - BOOL quiet = sRunInfo_option(runinfo, "-quiet"); | |
763 | - | |
764 | - if(runinfo->mFilter && runinfo->mArgsNumRuntime == 2) { | |
765 | - runinfo->mRCode = RCODE_NFUN_FALSE; | |
766 | - char* target = SFD(nextin).mBuf; | |
767 | - char* regex = runinfo->mArgsRuntime[1]; | |
768 | - | |
769 | - if(regex[0] == 0) { | |
770 | - runinfo->mRCode = 0; | |
771 | - if(!quiet) { | |
772 | - char buf[1024]; | |
773 | - int n = snprintf(buf, 1024, "0%d\n", (int)strlen(target)); | |
774 | - if(!fd_write(nextout, buf, n)) { | |
775 | - err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
776 | - runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
777 | - return FALSE; | |
778 | - } | |
779 | - } | |
780 | - } | |
781 | - else { | |
782 | - OnigUChar * p = migemo_query(gMigemo, regex); | |
783 | - if(p == NULL) { | |
784 | - err_msg("migemo query failed", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
785 | - migemo_release(gMigemo, (unsigned char*) p); | |
786 | - return FALSE; | |
787 | - } | |
788 | - | |
789 | - /// modify query /// | |
790 | - char* p2 = MALLOC(strlen(p)*2 + 1); | |
791 | - | |
792 | - char* _p = p; | |
793 | - char* _p2 = p2; | |
794 | - | |
795 | - while(*_p) { | |
796 | - if(*_p == '+') { | |
797 | - *_p2++ = '\\'; | |
798 | - *_p2++ = *_p++; | |
799 | - } | |
800 | - else { | |
801 | - *_p2++ = *_p++; | |
802 | - } | |
803 | - } | |
804 | - *_p2 = 0; | |
805 | - | |
806 | - /// make regex /// | |
807 | - regex_t* reg; | |
808 | - OnigErrorInfo err_info; | |
809 | - | |
810 | - int r = onig_new(®, p2, p2 + strlen(p2), ONIG_OPTION_DEFAULT, ONIG_ENCODING_UTF8, ONIG_SYNTAX_DEFAULT, &err_info); | |
811 | - | |
812 | - FREE(p2); | |
813 | - migemo_release(gMigemo, (unsigned char*) p); | |
814 | - | |
815 | - if(r != ONIG_NORMAL && r != 0) { | |
816 | - err_msg("regex of migemo query failed", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
817 | - onig_free(reg); | |
818 | - return FALSE; | |
819 | - } | |
820 | - | |
821 | - OnigRegion* region = onig_region_new(); | |
822 | - int r2 = onig_search(reg, target, target + strlen(target), target, target + strlen(target), region, ONIG_OPTION_NONE); | |
823 | - | |
824 | - if(r2 == 0) { | |
825 | - runinfo->mRCode = 0; | |
826 | - if(!quiet) { | |
827 | - char buf[1024]; | |
828 | - int n = snprintf(buf, 1024, "%d\n%d\n", region->beg[0], region->end[0]); | |
829 | - if(!fd_write(nextout, buf, n)) { | |
830 | - err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
831 | - runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
832 | - onig_region_free(region, 1); | |
833 | - onig_free(reg); | |
834 | - return FALSE; | |
835 | - } | |
836 | - } | |
837 | - } | |
838 | - else { | |
839 | - if(!quiet) { | |
840 | - char buf[1024]; | |
841 | - int n = snprintf(buf, 1024, "-1\n-1\n"); | |
842 | - if(!fd_write(nextout, buf, n)) { | |
843 | - err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
844 | - runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
845 | - onig_region_free(region, 1); | |
846 | - onig_free(reg); | |
847 | - return FALSE; | |
848 | - } | |
849 | - } | |
850 | - } | |
851 | - | |
852 | - onig_region_free(region, 1); | |
853 | - onig_free(reg); | |
854 | - } | |
855 | - } | |
856 | - | |
857 | - return TRUE; | |
858 | -} | |
859 | - | |
860 | -#endif |
@@ -767,7 +767,7 @@ BOOL cmd_var(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | ||
767 | 767 | sObject* tmp = access_object3(runinfo->mArgsRuntime[i], ¤t); |
768 | 768 | |
769 | 769 | if(tmp && sRunInfo_option(runinfo, "-local") && !sRunInfo_option(runinfo, "-force")) { |
770 | - err_msg("can't overwrite other the same name variable. Use -force option", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
770 | + err_msg("this name of local variable hides global variable name. Use -force option", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
771 | 771 | return FALSE; |
772 | 772 | } |
773 | 773 |
@@ -1115,7 +1115,7 @@ BOOL cmd_ary(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | ||
1115 | 1115 | sObject* tmp = access_object3(runinfo->mArgsRuntime[1], ¤t); |
1116 | 1116 | |
1117 | 1117 | if(tmp && sRunInfo_option(runinfo, "-local") && !sRunInfo_option(runinfo, "-force")) { |
1118 | - err_msg("can't overwrite other the same name variable. Use -force option", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1118 | + err_msg("this name of local variable hides global variable name. Use -force option", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1119 | 1119 | return FALSE; |
1120 | 1120 | } |
1121 | 1121 |
@@ -1374,7 +1374,7 @@ BOOL cmd_hash(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | ||
1374 | 1374 | sObject* tmp = access_object3(runinfo->mArgsRuntime[1], ¤t); |
1375 | 1375 | |
1376 | 1376 | if(tmp && sRunInfo_option(runinfo, "-local") && !sRunInfo_option(runinfo, "-force")) { |
1377 | - err_msg("can't overwrite other the same name variable. Use -force option", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1377 | + err_msg("this name of local variable hides global variable name. Use -force option", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1378 | 1378 | return FALSE; |
1379 | 1379 | } |
1380 | 1380 |
@@ -338,7 +338,8 @@ BOOL cmd_x(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | ||
338 | 338 | return TRUE; |
339 | 339 | } |
340 | 340 | |
341 | -BOOL cmd_index(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | |
341 | + | |
342 | +BOOL cmd_lc(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | |
342 | 343 | { |
343 | 344 | enum eKanjiCode code = gKanjiCode; |
344 | 345 | if(sRunInfo_option(runinfo, "-byte")) { |
@@ -354,205 +355,96 @@ BOOL cmd_index(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | ||
354 | 355 | code = kEucjp; |
355 | 356 | } |
356 | 357 | |
357 | - /// output | |
358 | 358 | if(runinfo->mFilter) { |
359 | - if(runinfo->mArgsNumRuntime == 2) { | |
360 | - char* target = SFD(nextin).mBuf; | |
361 | - | |
362 | - char* word = runinfo->mArgsRuntime[1]; | |
363 | - | |
364 | - /// get starting point /// | |
365 | - int start; | |
366 | - char* number; | |
367 | - if(number = sRunInfo_option_with_argument(runinfo, "-number")) { | |
368 | - start = atoi(number); | |
369 | - | |
370 | - int len = str_kanjilen(code, target); | |
371 | - if(len < 0) { | |
372 | - err_msg("invalid target string", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
373 | - return FALSE; | |
374 | - } | |
375 | - | |
376 | - if(start < 0) { | |
377 | - start += len; | |
378 | - if(start < 0) start = 0; | |
379 | - } | |
380 | - if(start >= len) { | |
381 | - start = len -1; | |
382 | - if(start < 0) start = 0; | |
383 | - } | |
384 | - } | |
385 | - else { | |
386 | - start = 0; | |
387 | - } | |
388 | - | |
389 | - /// get search count /// | |
390 | - int match_count; | |
391 | - char* count; | |
392 | - if(count = sRunInfo_option_with_argument(runinfo, "-count")) { | |
393 | - match_count = atoi(count); | |
394 | - if(match_count <= 0) { match_count = 1; } | |
395 | - } | |
396 | - else { | |
397 | - match_count = 1; | |
398 | - } | |
399 | - | |
400 | - char* start_byte = str_kanjipos2pointer(code, target, start); | |
401 | - char* p = start_byte; | |
402 | - char* result = NULL; | |
403 | - if(sRunInfo_option(runinfo, "-ignore-case")) { | |
404 | - while(p < start_byte + strlen(start_byte)) { | |
405 | - if(gXyzshSigInt) { | |
406 | - gXyzshSigInt = FALSE; | |
407 | - err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
408 | - runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
409 | - return FALSE; | |
410 | - } | |
411 | - | |
412 | - result = strcasestr(p, word); | |
413 | - if(result) { | |
414 | - match_count--; | |
415 | - if(match_count == 0) { | |
416 | - break; | |
417 | - } | |
418 | - p = result+strlen(word); | |
419 | - } | |
420 | - else { | |
421 | - break; | |
422 | - } | |
423 | - } | |
424 | - } | |
425 | - else { | |
426 | - while(p < start_byte + strlen(start_byte)) { | |
427 | - if(gXyzshSigInt) { | |
428 | - gXyzshSigInt = FALSE; | |
429 | - err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
430 | - runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
431 | - return FALSE; | |
432 | - } | |
433 | - | |
434 | - result = strstr(p, word); | |
435 | - if(result) { | |
436 | - match_count--; | |
437 | - if(match_count == 0) { | |
438 | - break; | |
439 | - } | |
440 | - p = result+strlen(word); | |
441 | - } | |
442 | - else { | |
443 | - break; | |
444 | - } | |
445 | - } | |
446 | - } | |
447 | - | |
448 | - char msg[64]; | |
449 | - int size; | |
450 | - if(result == NULL || match_count !=0) { | |
451 | - size = snprintf(msg, 64, "-1"); | |
452 | - runinfo->mRCode = RCODE_NFUN_FALSE; | |
453 | - } | |
454 | - else { | |
455 | - int c = str_pointer2kanjipos(code, target, result); | |
456 | - size = snprintf(msg, 64, "%d", c); | |
359 | + sObject* str = STRING_NEW_STACK(SFD(nextin).mBuf); | |
360 | + string_tolower(str, code); | |
457 | 361 | |
458 | - if(SFD(nextin).mBufLen == 0) { | |
459 | - runinfo->mRCode = RCODE_NFUN_NULL_INPUT; | |
460 | - } | |
461 | - else { | |
462 | - runinfo->mRCode = 0; | |
463 | - } | |
464 | - } | |
362 | + if(!fd_write(nextout, string_c_str(str), string_length(str))) { | |
363 | + err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
364 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
365 | + return FALSE; | |
366 | + } | |
465 | 367 | |
466 | - /// Ω–Œœ /// | |
467 | - if(!sRunInfo_option(runinfo, "-quiet")) { | |
468 | - if(!fd_write(nextout, msg, size)) { | |
469 | - err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
470 | - runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
471 | - return FALSE; | |
472 | - } | |
473 | - if(!fd_write(nextout, "\n", 1)) { | |
474 | - err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
475 | - runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
476 | - return FALSE; | |
477 | - } | |
478 | - } | |
368 | + if(SFD(nextin).mBufLen == 0) { | |
369 | + runinfo->mRCode = RCODE_NFUN_NULL_INPUT; | |
370 | + } | |
371 | + else { | |
372 | + runinfo->mRCode = 0; | |
479 | 373 | } |
480 | 374 | } |
481 | 375 | |
482 | 376 | return TRUE; |
483 | 377 | } |
484 | 378 | |
485 | -static char* strstr_back(char* p, char* start, char* word, char* sname, int sline, char* command) | |
379 | +BOOL cmd_uc(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | |
486 | 380 | { |
487 | - int n = strlen(word); | |
381 | + enum eKanjiCode code = gKanjiCode; | |
382 | + if(sRunInfo_option(runinfo, "-byte")) { | |
383 | + code = kByte; | |
384 | + } | |
385 | + else if(sRunInfo_option(runinfo, "-utf8")) { | |
386 | + code = kUtf8; | |
387 | + } | |
388 | + else if(sRunInfo_option(runinfo, "-sjis")) { | |
389 | + code = kSjis; | |
390 | + } | |
391 | + else if(sRunInfo_option(runinfo, "-eucjp")) { | |
392 | + code = kEucjp; | |
393 | + } | |
488 | 394 | |
489 | - while(p >= start) { | |
490 | - BOOL flg = TRUE; | |
491 | - int i; | |
492 | - for(i=-1; i>=-n; i--) { | |
493 | - if(p[i] != word[n+i]) { | |
494 | - flg = FALSE; | |
495 | - break; | |
496 | - } | |
395 | + if(runinfo->mFilter) { | |
396 | + sObject* str = STRING_NEW_STACK(SFD(nextin).mBuf); | |
397 | + string_toupper(str, code); | |
497 | 398 | |
498 | - if(gXyzshSigInt) { | |
499 | - err_msg("interrupt", sname, sline, command); | |
500 | - gXyzshSigInt = FALSE; | |
501 | - return NULL; | |
502 | - } | |
399 | + if(!fd_write(nextout, string_c_str(str), string_length(str))) { | |
400 | + err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
401 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
402 | + return FALSE; | |
503 | 403 | } |
504 | 404 | |
505 | - if(flg) { | |
506 | - return p -n; | |
405 | + if(SFD(nextin).mBufLen == 0) { | |
406 | + runinfo->mRCode = RCODE_NFUN_NULL_INPUT; | |
507 | 407 | } |
508 | 408 | else { |
509 | - p--; | |
409 | + runinfo->mRCode = 0; | |
510 | 410 | } |
511 | 411 | } |
512 | 412 | |
513 | - return NULL; | |
413 | + return TRUE; | |
514 | 414 | } |
515 | 415 | |
516 | -static char* strcasestr_back(char* p, char* start, char* word, char* sname, int sline, char* command) | |
416 | +BOOL cmd_chomp(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | |
517 | 417 | { |
518 | - int n = strlen(word); | |
519 | - | |
520 | - while(p >= start) { | |
521 | - BOOL flg = TRUE; | |
522 | - int i; | |
523 | - for(i=-1; i>=-n; i--) { | |
524 | - if(isascii(p[i]) && isascii(word[n+i])) { | |
525 | - if(tolower(p[i]) != tolower(word[n+i])) { | |
526 | - flg = FALSE; | |
527 | - break; | |
528 | - } | |
418 | + if(runinfo->mFilter) { | |
419 | + sObject* str = STRING_NEW_STACK(SFD(nextin).mBuf); | |
420 | + if(string_chomp(str)) { | |
421 | + if(SFD(nextin).mBufLen == 0) { | |
422 | + runinfo->mRCode = RCODE_NFUN_NULL_INPUT; | |
529 | 423 | } |
530 | 424 | else { |
531 | - if(p[i] != word[n+i]) { | |
532 | - flg = FALSE; | |
533 | - break; | |
534 | - } | |
425 | + runinfo->mRCode = 0; | |
535 | 426 | } |
536 | - | |
537 | - if(gXyzshSigInt) { | |
538 | - gXyzshSigInt = FALSE; | |
539 | - err_msg("interrupt", sname, sline, command); | |
540 | - return NULL; | |
427 | + } | |
428 | + else { | |
429 | + if(SFD(nextin).mBufLen == 0) { | |
430 | + runinfo->mRCode = RCODE_NFUN_NULL_INPUT; | |
431 | + } | |
432 | + else { | |
433 | + runinfo->mRCode = 1; | |
541 | 434 | } |
542 | 435 | } |
543 | 436 | |
544 | - if(flg) { | |
545 | - return p -n; | |
546 | - } | |
547 | - else { | |
548 | - p--; | |
437 | + if(!fd_write(nextout, string_c_str(str), string_length(str))) { | |
438 | + err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
439 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
440 | + return FALSE; | |
549 | 441 | } |
550 | 442 | } |
551 | 443 | |
552 | - return NULL; | |
444 | + return TRUE; | |
553 | 445 | } |
554 | 446 | |
555 | -BOOL cmd_rindex(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | |
447 | +BOOL cmd_chop(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | |
556 | 448 | { |
557 | 449 | enum eKanjiCode code = gKanjiCode; |
558 | 450 | if(sRunInfo_option(runinfo, "-byte")) { |
@@ -568,303 +460,51 @@ BOOL cmd_rindex(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | ||
568 | 460 | code = kEucjp; |
569 | 461 | } |
570 | 462 | |
571 | - /// output | |
572 | 463 | if(runinfo->mFilter) { |
573 | - if(runinfo->mArgsNumRuntime == 2) { | |
574 | - char* target = SFD(nextin).mBuf; | |
575 | - char* word = runinfo->mArgsRuntime[1]; | |
576 | - | |
577 | - /// get starting point /// | |
578 | - int len = str_kanjilen(code, target); | |
579 | - if(len < 0) { | |
580 | - err_msg("invalid target string", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
581 | - return FALSE; | |
582 | - } | |
464 | + sObject* str = STRING_NEW_STACK(SFD(nextin).mBuf); | |
583 | 465 | |
584 | - int start; | |
585 | - char* number; | |
586 | - if(number = sRunInfo_option_with_argument(runinfo, "-number")) { | |
587 | - start = atoi(number); | |
466 | + if(code == kByte) { | |
467 | + char* s = string_c_str(str); | |
468 | + const int len = strlen(s); | |
469 | + | |
470 | + if(len >= 2 && s[len-2] == '\r' && s[len-1] == '\n') | |
471 | + { | |
472 | + string_trunc(str, len-2); | |
588 | 473 | |
589 | - if(start < 0) { | |
590 | - start += len; | |
591 | - if(start < 0) start = 0; | |
474 | + if(SFD(nextin).mBufLen == 0) { | |
475 | + runinfo->mRCode = RCODE_NFUN_NULL_INPUT; | |
592 | 476 | } |
593 | - if(start >= len) { | |
594 | - start = len -1 ; | |
595 | - if(start < 0) start = 0; | |
477 | + else { | |
478 | + runinfo->mRCode = 0; | |
596 | 479 | } |
597 | 480 | } |
598 | - else { | |
599 | - start = len -1; | |
600 | - if(start < 0) start = 0; | |
601 | - } | |
602 | - | |
603 | - /// get search count /// | |
604 | - int match_count; | |
605 | - char* count; | |
606 | - if(count = sRunInfo_option_with_argument(runinfo, "-count")) { | |
607 | - match_count = atoi(count); | |
608 | - if(match_count <= 0) { match_count = 1; } | |
609 | - } | |
610 | - else { | |
611 | - match_count = 1; | |
612 | - } | |
613 | - | |
614 | - | |
615 | - char* start_byte = str_kanjipos2pointer(code, target, start+1); | |
616 | - char* p = start_byte; | |
617 | - char* result = NULL; | |
618 | - if(sRunInfo_option(runinfo, "-ignore-case")) { | |
619 | - while(p>=target) { | |
620 | - result = strcasestr_back(p, target, word, runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
621 | - | |
622 | - if(gXyzshSigInt) { | |
623 | - gXyzshSigInt = FALSE; | |
624 | - err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
625 | - runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
626 | - return FALSE; | |
627 | - } | |
481 | + else if(len >= 1) { | |
482 | + string_trunc(str, len-1); | |
628 | 483 | |
629 | - if(result != NULL) { | |
630 | - match_count--; | |
631 | - if(match_count == 0) { | |
632 | - break; | |
633 | - } | |
634 | - p = result - 1; | |
635 | - } | |
636 | - else { | |
637 | - break; | |
638 | - } | |
484 | + if(SFD(nextin).mBufLen == 0) { | |
485 | + runinfo->mRCode = RCODE_NFUN_NULL_INPUT; | |
486 | + } | |
487 | + else { | |
488 | + runinfo->mRCode = 0; | |
639 | 489 | } |
640 | 490 | } |
641 | 491 | else { |
642 | - while(p>=target) { | |
643 | - result = strstr_back(p, target, word, runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
644 | - | |
645 | - if(gXyzshSigInt) { | |
646 | - gXyzshSigInt = FALSE; | |
647 | - err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
648 | - runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
649 | - return FALSE; | |
650 | - } | |
651 | - | |
652 | - if(result != NULL) { | |
653 | - match_count--; | |
654 | - if(match_count == 0) { | |
655 | - break; | |
656 | - } | |
657 | - p = result - 1; | |
658 | - } | |
659 | - else { | |
660 | - break; | |
661 | - } | |
492 | + if(SFD(nextin).mBufLen == 0) { | |
493 | + runinfo->mRCode = RCODE_NFUN_NULL_INPUT; | |
494 | + } | |
495 | + else { | |
496 | + runinfo->mRCode = 1; | |
662 | 497 | } |
663 | 498 | } |
499 | + } | |
500 | + else { | |
501 | + char* s = string_c_str(str); | |
502 | + const int len = str_kanjilen(code, s); | |
664 | 503 | |
665 | - char msg[64]; | |
666 | - int size; | |
667 | - if(result == NULL || match_count !=0) { | |
668 | - size = snprintf(msg, 64, "-1"); | |
669 | - runinfo->mRCode = RCODE_NFUN_FALSE; | |
670 | - } | |
671 | - else { | |
672 | - int c = str_pointer2kanjipos(code, target, result); | |
673 | - size = snprintf(msg, 64, "%d", c); | |
504 | + char* last_char_head = str_kanjipos2pointer(code, s, len-1); | |
505 | + string_erase(str, last_char_head-s, s + strlen(s) - last_char_head); | |
674 | 506 | |
675 | - if(SFD(nextin).mBufLen == 0) { | |
676 | - runinfo->mRCode = RCODE_NFUN_NULL_INPUT; | |
677 | - } | |
678 | - else { | |
679 | - runinfo->mRCode = 0; | |
680 | - } | |
681 | - } | |
682 | - | |
683 | - /// Ω–Œœ /// | |
684 | - if(!sRunInfo_option(runinfo, "-quiet")) { | |
685 | - if(!fd_write(nextout, msg, size)) { | |
686 | - err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
687 | - runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
688 | - return FALSE; | |
689 | - } | |
690 | - if(!fd_write(nextout, "\n", 1)) { | |
691 | - err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
692 | - runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
693 | - return FALSE; | |
694 | - } | |
695 | - } | |
696 | - } | |
697 | - } | |
698 | - | |
699 | - return TRUE; | |
700 | -} | |
701 | - | |
702 | -BOOL cmd_lc(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | |
703 | -{ | |
704 | - enum eKanjiCode code = gKanjiCode; | |
705 | - if(sRunInfo_option(runinfo, "-byte")) { | |
706 | - code = kByte; | |
707 | - } | |
708 | - else if(sRunInfo_option(runinfo, "-utf8")) { | |
709 | - code = kUtf8; | |
710 | - } | |
711 | - else if(sRunInfo_option(runinfo, "-sjis")) { | |
712 | - code = kSjis; | |
713 | - } | |
714 | - else if(sRunInfo_option(runinfo, "-eucjp")) { | |
715 | - code = kEucjp; | |
716 | - } | |
717 | - | |
718 | - if(runinfo->mFilter) { | |
719 | - sObject* str = STRING_NEW_STACK(SFD(nextin).mBuf); | |
720 | - string_tolower(str, code); | |
721 | - | |
722 | - if(!fd_write(nextout, string_c_str(str), string_length(str))) { | |
723 | - err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
724 | - runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
725 | - return FALSE; | |
726 | - } | |
727 | - | |
728 | - if(SFD(nextin).mBufLen == 0) { | |
729 | - runinfo->mRCode = RCODE_NFUN_NULL_INPUT; | |
730 | - } | |
731 | - else { | |
732 | - runinfo->mRCode = 0; | |
733 | - } | |
734 | - } | |
735 | - | |
736 | - return TRUE; | |
737 | -} | |
738 | - | |
739 | -BOOL cmd_uc(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | |
740 | -{ | |
741 | - enum eKanjiCode code = gKanjiCode; | |
742 | - if(sRunInfo_option(runinfo, "-byte")) { | |
743 | - code = kByte; | |
744 | - } | |
745 | - else if(sRunInfo_option(runinfo, "-utf8")) { | |
746 | - code = kUtf8; | |
747 | - } | |
748 | - else if(sRunInfo_option(runinfo, "-sjis")) { | |
749 | - code = kSjis; | |
750 | - } | |
751 | - else if(sRunInfo_option(runinfo, "-eucjp")) { | |
752 | - code = kEucjp; | |
753 | - } | |
754 | - | |
755 | - if(runinfo->mFilter) { | |
756 | - sObject* str = STRING_NEW_STACK(SFD(nextin).mBuf); | |
757 | - string_toupper(str, code); | |
758 | - | |
759 | - if(!fd_write(nextout, string_c_str(str), string_length(str))) { | |
760 | - err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
761 | - runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
762 | - return FALSE; | |
763 | - } | |
764 | - | |
765 | - if(SFD(nextin).mBufLen == 0) { | |
766 | - runinfo->mRCode = RCODE_NFUN_NULL_INPUT; | |
767 | - } | |
768 | - else { | |
769 | - runinfo->mRCode = 0; | |
770 | - } | |
771 | - } | |
772 | - | |
773 | - return TRUE; | |
774 | -} | |
775 | - | |
776 | -BOOL cmd_chomp(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | |
777 | -{ | |
778 | - if(runinfo->mFilter) { | |
779 | - sObject* str = STRING_NEW_STACK(SFD(nextin).mBuf); | |
780 | - if(string_chomp(str)) { | |
781 | - if(SFD(nextin).mBufLen == 0) { | |
782 | - runinfo->mRCode = RCODE_NFUN_NULL_INPUT; | |
783 | - } | |
784 | - else { | |
785 | - runinfo->mRCode = 0; | |
786 | - } | |
787 | - } | |
788 | - else { | |
789 | - if(SFD(nextin).mBufLen == 0) { | |
790 | - runinfo->mRCode = RCODE_NFUN_NULL_INPUT; | |
791 | - } | |
792 | - else { | |
793 | - runinfo->mRCode = 1; | |
794 | - } | |
795 | - } | |
796 | - | |
797 | - if(!fd_write(nextout, string_c_str(str), string_length(str))) { | |
798 | - err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
799 | - runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
800 | - return FALSE; | |
801 | - } | |
802 | - } | |
803 | - | |
804 | - return TRUE; | |
805 | -} | |
806 | - | |
807 | -BOOL cmd_chop(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | |
808 | -{ | |
809 | - enum eKanjiCode code = gKanjiCode; | |
810 | - if(sRunInfo_option(runinfo, "-byte")) { | |
811 | - code = kByte; | |
812 | - } | |
813 | - else if(sRunInfo_option(runinfo, "-utf8")) { | |
814 | - code = kUtf8; | |
815 | - } | |
816 | - else if(sRunInfo_option(runinfo, "-sjis")) { | |
817 | - code = kSjis; | |
818 | - } | |
819 | - else if(sRunInfo_option(runinfo, "-eucjp")) { | |
820 | - code = kEucjp; | |
821 | - } | |
822 | - | |
823 | - if(runinfo->mFilter) { | |
824 | - sObject* str = STRING_NEW_STACK(SFD(nextin).mBuf); | |
825 | - | |
826 | - if(code == kByte) { | |
827 | - char* s = string_c_str(str); | |
828 | - const int len = strlen(s); | |
829 | - | |
830 | - if(len >= 2 && s[len-2] == '\r' && s[len-1] == '\n') | |
831 | - { | |
832 | - string_trunc(str, len-2); | |
833 | - | |
834 | - if(SFD(nextin).mBufLen == 0) { | |
835 | - runinfo->mRCode = RCODE_NFUN_NULL_INPUT; | |
836 | - } | |
837 | - else { | |
838 | - runinfo->mRCode = 0; | |
839 | - } | |
840 | - } | |
841 | - else if(len >= 1) { | |
842 | - string_trunc(str, len-1); | |
843 | - | |
844 | - if(SFD(nextin).mBufLen == 0) { | |
845 | - runinfo->mRCode = RCODE_NFUN_NULL_INPUT; | |
846 | - } | |
847 | - else { | |
848 | - runinfo->mRCode = 0; | |
849 | - } | |
850 | - } | |
851 | - else { | |
852 | - if(SFD(nextin).mBufLen == 0) { | |
853 | - runinfo->mRCode = RCODE_NFUN_NULL_INPUT; | |
854 | - } | |
855 | - else { | |
856 | - runinfo->mRCode = 1; | |
857 | - } | |
858 | - } | |
859 | - } | |
860 | - else { | |
861 | - char* s = string_c_str(str); | |
862 | - const int len = str_kanjilen(code, s); | |
863 | - | |
864 | - char* last_char_head = str_kanjipos2pointer(code, s, len-1); | |
865 | - string_erase(str, last_char_head-s, s + strlen(s) - last_char_head); | |
866 | - | |
867 | - if(len > 0) { | |
507 | + if(len > 0) { | |
868 | 508 | if(SFD(nextin).mBufLen == 0) { |
869 | 509 | runinfo->mRCode = RCODE_NFUN_NULL_INPUT; |
870 | 510 | } |
@@ -1132,498 +772,1315 @@ BOOL cmd_printf(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | ||
1132 | 772 | return TRUE; |
1133 | 773 | } |
1134 | 774 | |
1135 | -BOOL cmd_sub(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | |
775 | +BOOL cmd_add(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | |
1136 | 776 | { |
1137 | - BOOL quiet = sRunInfo_option(runinfo, "-quiet"); | |
1138 | - | |
1139 | - if(runinfo->mFilter && (runinfo->mArgsNumRuntime == 3 || runinfo->mArgsNumRuntime == 2 && runinfo->mBlocksNum >= 1)) { | |
1140 | - sObject* block; | |
1141 | - sObject* nextin2; | |
1142 | - sObject* nextout2; | |
777 | + enum eKanjiCode code = gKanjiCode; | |
778 | + if(sRunInfo_option(runinfo, "-byte")) { | |
779 | + code = kByte; | |
780 | + } | |
781 | + else if(sRunInfo_option(runinfo, "-utf8")) { | |
782 | + code = kUtf8; | |
783 | + } | |
784 | + else if(sRunInfo_option(runinfo, "-sjis")) { | |
785 | + code = kSjis; | |
786 | + } | |
787 | + else if(sRunInfo_option(runinfo, "-eucjp")) { | |
788 | + code = kEucjp; | |
789 | + } | |
1143 | 790 | |
1144 | - if(runinfo->mBlocksNum >= 1) { | |
1145 | - block = runinfo->mBlocks[0]; | |
1146 | - nextin2 = FD_NEW_STACK(); | |
1147 | - nextout2 = FD_NEW_STACK(); | |
791 | + if(runinfo->mFilter && runinfo->mArgsNumRuntime == 2) { | |
792 | + char* arg = runinfo->mArgsRuntime[1]; | |
793 | + int number; | |
794 | + char* argument; | |
795 | + if(argument = sRunInfo_option_with_argument(runinfo, "-number")) { | |
796 | + number = atoi(argument); | |
797 | + } | |
798 | + else if(argument = sRunInfo_option_with_argument(runinfo, "-index")) { | |
799 | + number = atoi(argument); | |
1148 | 800 | } |
1149 | 801 | else { |
1150 | - block = NULL; | |
802 | + number = -1; | |
1151 | 803 | } |
1152 | 804 | |
1153 | - BOOL global = sRunInfo_option(runinfo, "-global"); | |
805 | + const int len = str_kanjilen(code, SFD(nextin).mBuf); | |
1154 | 806 | |
1155 | - char* regex = runinfo->mArgsRuntime[1]; | |
1156 | - char* destination = runinfo->mArgsRuntime[2]; | |
807 | + if(number < 0) { | |
808 | + number += len + 1; | |
809 | + if(number < 0) number = 0; | |
810 | + } | |
1157 | 811 | |
1158 | - int sub_count = 0; | |
812 | + if(number < len) { | |
813 | + int point = str_kanjipos2pointer(code, SFD(nextin).mBuf, number) - SFD(nextin).mBuf; | |
814 | + if(!fd_write(nextout, SFD(nextin).mBuf, point)) { | |
815 | + err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
816 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
817 | + return FALSE; | |
818 | + } | |
819 | + if(!fd_write(nextout, arg, strlen(arg))) { | |
820 | + err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
821 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
822 | + return FALSE; | |
823 | + } | |
824 | + if(!fd_write(nextout, SFD(nextin).mBuf + point, SFD(nextin).mBufLen - point)) { | |
825 | + err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
826 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
827 | + return FALSE; | |
828 | + } | |
829 | + } | |
830 | + else { | |
831 | + if(!fd_write(nextout, SFD(nextin).mBuf, SFD(nextin).mBufLen)) { | |
832 | + err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
833 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
834 | + return FALSE; | |
835 | + } | |
836 | + if(!fd_write(nextout, arg, strlen(arg))) { | |
837 | + err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
838 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
839 | + return FALSE; | |
840 | + } | |
841 | + } | |
1159 | 842 | |
1160 | - regex_t* reg; | |
843 | + if(SFD(nextin).mBufLen == 0) { | |
844 | + runinfo->mRCode = RCODE_NFUN_NULL_INPUT; | |
845 | + } | |
846 | + else { | |
847 | + runinfo->mRCode = 0; | |
848 | + } | |
849 | + } | |
850 | + | |
851 | + return TRUE; | |
852 | +} | |
853 | + | |
854 | +BOOL cmd_del(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | |
855 | +{ | |
856 | + enum eKanjiCode code = gKanjiCode; | |
857 | + if(sRunInfo_option(runinfo, "-byte")) { | |
858 | + code = kByte; | |
859 | + } | |
860 | + else if(sRunInfo_option(runinfo, "-utf8")) { | |
861 | + code = kUtf8; | |
862 | + } | |
863 | + else if(sRunInfo_option(runinfo, "-sjis")) { | |
864 | + code = kSjis; | |
865 | + } | |
866 | + else if(sRunInfo_option(runinfo, "-eucjp")) { | |
867 | + code = kEucjp; | |
868 | + } | |
869 | + | |
870 | + | |
871 | + if(runinfo->mFilter && runinfo->mArgsNumRuntime == 2) { | |
872 | + char* arg = runinfo->mArgsRuntime[1]; | |
873 | + int index = atoi(arg); | |
874 | + | |
875 | + int number; | |
876 | + char* argument; | |
877 | + if(argument = sRunInfo_option_with_argument(runinfo, "-number")) { | |
878 | + number = atoi(argument); | |
879 | + } | |
880 | + else if(argument = sRunInfo_option_with_argument(runinfo, "-index")) { | |
881 | + number = atoi(argument); | |
882 | + } | |
883 | + else { | |
884 | + number = 1; | |
885 | + } | |
886 | + | |
887 | + const int len = str_kanjilen(code, SFD(nextin).mBuf); | |
888 | + | |
889 | + if(index < 0) { | |
890 | + index += len; | |
891 | + if(index < 0) index = 0; | |
892 | + } | |
893 | + if(index >= len) { | |
894 | + index = len -1; | |
895 | + if(index < 0) index = 0; | |
896 | + } | |
897 | + | |
898 | + int point = str_kanjipos2pointer(code, SFD(nextin).mBuf, index) - SFD(nextin).mBuf; | |
899 | + | |
900 | + if(!fd_write(nextout, SFD(nextin).mBuf, point)) { | |
901 | + err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
902 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
903 | + return FALSE; | |
904 | + } | |
905 | + if(index + number < len) { | |
906 | + char* point = str_kanjipos2pointer(code, SFD(nextin).mBuf, index + number); | |
907 | + if(!fd_write(nextout, point, strlen(point))) { | |
908 | + err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
909 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
910 | + return FALSE; | |
911 | + } | |
912 | + } | |
913 | + | |
914 | + if(SFD(nextin).mBufLen == 0) { | |
915 | + runinfo->mRCode = RCODE_NFUN_NULL_INPUT; | |
916 | + } | |
917 | + else { | |
918 | + runinfo->mRCode = 0; | |
919 | + } | |
920 | + } | |
921 | + | |
922 | + return TRUE; | |
923 | +} | |
924 | + | |
925 | +BOOL cmd_rows(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | |
926 | +{ | |
927 | + enum eKanjiCode code = gKanjiCode; | |
928 | + if(sRunInfo_option(runinfo, "-byte")) { | |
929 | + code = kByte; | |
930 | + } | |
931 | + else if(sRunInfo_option(runinfo, "-utf8")) { | |
932 | + code = kUtf8; | |
933 | + } | |
934 | + else if(sRunInfo_option(runinfo, "-sjis")) { | |
935 | + code = kSjis; | |
936 | + } | |
937 | + else if(sRunInfo_option(runinfo, "-eucjp")) { | |
938 | + code = kEucjp; | |
939 | + } | |
940 | + | |
941 | + if(runinfo->mFilter && runinfo->mArgsNumRuntime > 1 && runinfo->mBlocksNum <= runinfo->mArgsNumRuntime-1) { | |
942 | + if(SFD(nextin).mBufLen == 0) { | |
943 | + runinfo->mRCode = RCODE_NFUN_NULL_INPUT; | |
944 | + } | |
945 | + else { | |
946 | + runinfo->mRCode = 0; | |
947 | + } | |
948 | + | |
949 | + int i; | |
950 | + for(i=1; i<runinfo->mArgsNumRuntime; i++) { | |
951 | + char* arg = runinfo->mArgsRuntime[i]; | |
952 | + char* p; | |
953 | + if(p = strstr(arg, "..")) { | |
954 | + char buf[128+1]; | |
955 | + char buf2[128+1]; | |
956 | + const int len = p - arg; | |
957 | + const int len2 = arg + strlen(arg) - (p + 2); | |
958 | + if(len < 128 || len2 < 128) { | |
959 | + memcpy(buf, arg, len); | |
960 | + buf[len] = 0; | |
961 | + | |
962 | + memcpy(buf2, p + 2, len2); | |
963 | + buf2[len2] = 0; | |
964 | + } | |
965 | + else { | |
966 | + err_msg("invalid range", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
967 | + return FALSE; | |
968 | + } | |
969 | + | |
970 | + const int kanjilen = str_kanjilen(code, SFD(nextin).mBuf); | |
971 | + if(kanjilen > 0) { | |
972 | + int first = atoi(buf); | |
973 | + int second = atoi(buf2); | |
974 | + | |
975 | + if(first < 0) { | |
976 | + first += kanjilen; | |
977 | + if(first < 0) first = 0; | |
978 | + } | |
979 | + if(second < 0) { | |
980 | + second += kanjilen; | |
981 | + if(second < 0) second = 0; | |
982 | + } | |
983 | + if(first >= kanjilen) { | |
984 | + first = kanjilen -1; | |
985 | + if(first < 0) first = 0; | |
986 | + } | |
987 | + if(second >= kanjilen) { | |
988 | + second = kanjilen -1; | |
989 | + if(second < 0) second = 0; | |
990 | + } | |
991 | + | |
992 | + /// make table to indexing access /// | |
993 | + char** array = MALLOC(sizeof(char*)*(kanjilen+1)); | |
994 | + if(code == kByte) { | |
995 | + int k; | |
996 | + for(k=0; k<kanjilen; k++) { | |
997 | + array[k] = SFD(nextin).mBuf + k; | |
998 | + } | |
999 | + array[k] = SFD(nextin).mBuf + k; | |
1000 | + } | |
1001 | + else if(code == kUtf8) { | |
1002 | + char* p = SFD(nextin).mBuf; | |
1003 | + | |
1004 | + int k; | |
1005 | + for(k=0; k<kanjilen; k++) { | |
1006 | + array[k] = p; | |
1007 | + if(((unsigned char)*p) > 127) { | |
1008 | + const int size = ((*p & 0x80) >> 7) + ((*p & 0x40) >> 6) + ((*p & 0x20) >> 5) + ((*p & 0x10) >> 4); | |
1009 | + p+=size; | |
1010 | + } | |
1011 | + else { | |
1012 | + p++; | |
1013 | + } | |
1014 | + } | |
1015 | + array[k] = p; | |
1016 | + } | |
1017 | + else { | |
1018 | + char* p = SFD(nextin).mBuf; | |
1019 | + | |
1020 | + int k; | |
1021 | + for(k=0; k<kanjilen; k++) { | |
1022 | + const int size = is_kanji(code, *p) ? 2 : 1; | |
1023 | + array[k] = p; | |
1024 | + p+=size; | |
1025 | + } | |
1026 | + array[k] = p; | |
1027 | + } | |
1028 | + | |
1029 | + if(first < second) { | |
1030 | + sObject* nextin2 = FD_NEW_STACK(); | |
1031 | + | |
1032 | + int j; | |
1033 | + for(j=first; j<=second; j++) { | |
1034 | + fd_clear(nextin2); | |
1035 | + | |
1036 | + if(!fd_write(nextin2, array[j], array[j+1] -array[j])) { | |
1037 | + err_msg("interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1038 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1039 | + FREE(array); | |
1040 | + return FALSE; | |
1041 | + } | |
1042 | + | |
1043 | + if(i-1 < runinfo->mBlocksNum) { | |
1044 | + int rcode = 0; | |
1045 | + if(!run(runinfo->mBlocks[i-1], nextin2, nextout, &rcode, runinfo->mCurrentObject, runinfo->mRunningObject)) { | |
1046 | + runinfo->mRCode = rcode; | |
1047 | + FREE(array); | |
1048 | + return FALSE; | |
1049 | + } | |
1050 | + runinfo->mRCode = rcode; | |
1051 | + } | |
1052 | + else { | |
1053 | + if(!fd_write(nextout, SFD(nextin2).mBuf, SFD(nextin2).mBufLen)) | |
1054 | + { | |
1055 | + err_msg("interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1056 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1057 | + FREE(array); | |
1058 | + return FALSE; | |
1059 | + } | |
1060 | + runinfo->mRCode = 0; | |
1061 | + } | |
1062 | + } | |
1063 | + } | |
1064 | + else { | |
1065 | + sObject* nextin2 = FD_NEW_STACK(); | |
1066 | + | |
1067 | + int j; | |
1068 | + for(j=first; j>=second; j--) { | |
1069 | + fd_clear(nextin2); | |
1070 | + | |
1071 | + if(!fd_write(nextin2, array[j], array[j+1]-array[j])) { | |
1072 | + err_msg("interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1073 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1074 | + FREE(array); | |
1075 | + return FALSE; | |
1076 | + } | |
1077 | + | |
1078 | + if(i-1 < runinfo->mBlocksNum) { | |
1079 | + int rcode = 0; | |
1080 | + if(!run(runinfo->mBlocks[i-1], nextin2, nextout, &rcode, runinfo->mCurrentObject, runinfo->mRunningObject)) { | |
1081 | + runinfo->mRCode = rcode; | |
1082 | + FREE(array); | |
1083 | + return FALSE; | |
1084 | + } | |
1085 | + runinfo->mRCode = rcode; | |
1086 | + } | |
1087 | + else { | |
1088 | + if(!fd_write(nextout, SFD(nextin2).mBuf, SFD(nextin2).mBufLen)) | |
1089 | + { | |
1090 | + err_msg("interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1091 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1092 | + FREE(array); | |
1093 | + return FALSE; | |
1094 | + } | |
1095 | + runinfo->mRCode = 0; | |
1096 | + } | |
1097 | + } | |
1098 | + } | |
1099 | + | |
1100 | + FREE(array); | |
1101 | + } | |
1102 | + } | |
1103 | + else { | |
1104 | + const int len = str_kanjilen(code, SFD(nextin).mBuf); | |
1105 | + int num = atoi(arg); | |
1106 | + | |
1107 | + if(num < 0) { | |
1108 | + num += len; | |
1109 | + if(num < 0) num = 0; | |
1110 | + } | |
1111 | + if(num >= len) { | |
1112 | + num = len -1; | |
1113 | + if(num < 0) num = 0; | |
1114 | + } | |
1115 | + | |
1116 | + sObject* nextin2 = FD_NEW_STACK(); | |
1117 | + | |
1118 | + char* str = str_kanjipos2pointer(code, SFD(nextin).mBuf, num); | |
1119 | + char* str2 = str_kanjipos2pointer(code, str, 1); | |
1120 | + if(!fd_write(nextin2, str, str2 -str)) { | |
1121 | + err_msg("interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1122 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1123 | + return FALSE; | |
1124 | + } | |
1125 | + | |
1126 | + if(i-1 < runinfo->mBlocksNum) { | |
1127 | + int rcode = 0; | |
1128 | + if(!run(runinfo->mBlocks[i-1], nextin2, nextout, &rcode, runinfo->mCurrentObject, runinfo->mRunningObject)) { | |
1129 | + runinfo->mRCode = rcode; | |
1130 | + return FALSE; | |
1131 | + } | |
1132 | + runinfo->mRCode = rcode; | |
1133 | + } | |
1134 | + else { | |
1135 | + if(!fd_write(nextout, SFD(nextin2).mBuf, SFD(nextin2).mBufLen)) | |
1136 | + { | |
1137 | + err_msg("interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1138 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1139 | + return FALSE; | |
1140 | + } | |
1141 | + runinfo->mRCode = 0; | |
1142 | + } | |
1143 | + } | |
1144 | + } | |
1145 | + } | |
1146 | + | |
1147 | + return TRUE; | |
1148 | +} | |
1149 | + | |
1150 | +BOOL cmd_scan(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | |
1151 | +{ | |
1152 | + char* field = "\n"; | |
1153 | + if(sRunInfo_option(runinfo, "-Lw")) { | |
1154 | + field = "\r\n"; | |
1155 | + } | |
1156 | + else if(sRunInfo_option(runinfo, "-Lm")) { | |
1157 | + field = "\r"; | |
1158 | + } | |
1159 | + else if(sRunInfo_option(runinfo, "-Lu")) { | |
1160 | + field = "\n"; | |
1161 | + } | |
1162 | + else if(sRunInfo_option(runinfo, "-La")) { | |
1163 | + field = "\a"; | |
1164 | + } | |
1165 | + | |
1166 | + if(runinfo->mFilter && runinfo->mArgsNumRuntime == 2) { | |
1167 | + sObject* block; | |
1168 | + sObject* nextin2; | |
1169 | + | |
1170 | + if(runinfo->mBlocksNum >= 1) { | |
1171 | + block = runinfo->mBlocks[0]; | |
1172 | + nextin2 = FD_NEW_STACK(); | |
1173 | + } | |
1174 | + else { | |
1175 | + block = NULL; | |
1176 | + } | |
1177 | + | |
1178 | + int match_count = 0; | |
1179 | + char* regex = runinfo->mArgsRuntime[1]; | |
1180 | + | |
1181 | + regex_t* reg; | |
1161 | 1182 | int r = get_onig_regex(®, runinfo, regex); |
1162 | 1183 | |
1163 | 1184 | if(r == ONIG_NORMAL) { |
1164 | - char* p = SFD(nextin).mBuf; | |
1185 | + char* target = SFD(nextin).mBuf; | |
1186 | + char* p = SFD(nextin).mBuf; | |
1187 | + char* end = SFD(nextin).mBuf + strlen(SFD(nextin).mBuf); | |
1188 | + while(p < end) { | |
1189 | + OnigRegion* region = onig_region_new(); | |
1190 | + int r2 = onig_search(reg, target | |
1191 | + , target + strlen(target) | |
1192 | + , p | |
1193 | + , p + strlen(p) | |
1194 | + , region, ONIG_OPTION_NONE); | |
1195 | + | |
1196 | + if(r2 >= 0) { | |
1197 | + match_count++; | |
1198 | + | |
1199 | + if(block) { | |
1200 | + fd_clear(nextin2); | |
1201 | + | |
1202 | + /// no group /// | |
1203 | + if(region->num_regs == 1) { | |
1204 | + const int n = region->end[0] - region->beg[0]; | |
1205 | + | |
1206 | + if(!fd_write(nextin2, target + region->beg[0], n)) { | |
1207 | + err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1208 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1209 | + onig_free(reg); | |
1210 | + onig_region_free(region, 1); | |
1211 | + return FALSE; | |
1212 | + } | |
1213 | + if(!fd_write(nextin2, field, strlen(field))) { | |
1214 | + err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1215 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1216 | + onig_free(reg); | |
1217 | + onig_region_free(region, 1); | |
1218 | + return FALSE; | |
1219 | + } | |
1220 | + } | |
1221 | + /// group /// | |
1222 | + else { | |
1223 | + int i; | |
1224 | + for (i=1; i<region->num_regs; i++) { | |
1225 | + const int size = region->end[i] - region->beg[i]; | |
1226 | + | |
1227 | + if(!fd_write(nextin2, target + region->beg[i], size)) { | |
1228 | + err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1229 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1230 | + onig_free(reg); | |
1231 | + onig_region_free(region, 1); | |
1232 | + return FALSE; | |
1233 | + } | |
1234 | + | |
1235 | + if(i==region->num_regs-1) { | |
1236 | + if(!fd_write(nextin2, field, strlen(field))) { | |
1237 | + err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1238 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1239 | + onig_free(reg); | |
1240 | + onig_region_free(region, 1); | |
1241 | + return FALSE; | |
1242 | + } | |
1243 | + } | |
1244 | + else { | |
1245 | + if(!fd_write(nextin2, "\t", 1)) { | |
1246 | + err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1247 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1248 | + onig_free(reg); | |
1249 | + onig_region_free(region, 1); | |
1250 | + return FALSE; | |
1251 | + } | |
1252 | + } | |
1253 | + } | |
1254 | + } | |
1255 | + | |
1256 | + clear_matching_info_variable(); | |
1257 | + | |
1258 | + const int size = region->beg[0] - (p - target); | |
1259 | + if(size > 0) { | |
1260 | + uobject_put(gRootObject, "PREMATCH", STRING_NEW_GC3(p, size, FALSE)); | |
1261 | + } | |
1262 | + | |
1263 | + const int size2 = region->end[0] - region->beg[0]; | |
1264 | + | |
1265 | + uobject_put(gRootObject, "MATCH", STRING_NEW_GC3(target + region->beg[0], size2, FALSE)); | |
1266 | + uobject_put(gRootObject, "0", STRING_NEW_GC3(target + region->beg[0], size2, FALSE)); | |
1267 | + | |
1268 | + const int n = strlen(target)-region->end[0]; | |
1269 | + if(n > 0) { | |
1270 | + uobject_put(gRootObject, "POSTMATCH", STRING_NEW_GC3(target + region->end[0], n, FALSE)); | |
1271 | + } | |
1272 | + | |
1273 | + int i; | |
1274 | + for (i=1; i<region->num_regs; i++) { | |
1275 | + const int size = region->end[i] - region->beg[i]; | |
1276 | + | |
1277 | + char name[16]; | |
1278 | + snprintf(name, 16, "%d", i); | |
1279 | + | |
1280 | + uobject_put(gRootObject, name, STRING_NEW_GC3(target + region->beg[i], size, FALSE)); | |
1281 | + } | |
1282 | + | |
1283 | + if(region->num_regs > 0) { | |
1284 | + const int n = region->num_regs -1; | |
1285 | + | |
1286 | + const int size = region->end[n] - region->beg[n]; | |
1287 | + | |
1288 | + uobject_put(gRootObject, "LAST_MATCH", STRING_NEW_GC3(target + region->beg[n], size, FALSE)); | |
1289 | + } | |
1290 | + | |
1291 | + char buf[128]; | |
1292 | + snprintf(buf, 128, "%d", region->num_regs); | |
1293 | + uobject_put(gRootObject, "MATCH_NUMBER", STRING_NEW_GC(buf, FALSE)); | |
1294 | + | |
1295 | + int rcode = 0; | |
1296 | + if(!run(block, nextin2, nextout, &rcode, runinfo->mCurrentObject, runinfo->mRunningObject)) { | |
1297 | + runinfo->mRCode = rcode; | |
1298 | + onig_region_free(region, 1); | |
1299 | + onig_free(reg); | |
1300 | + return FALSE; | |
1301 | + } | |
1302 | + } | |
1303 | + else { | |
1304 | + /// no group /// | |
1305 | + if(region->num_regs == 1) { | |
1306 | + const int n = region->end[0] - region->beg[0]; | |
1307 | + | |
1308 | + if(!fd_write(nextout, target + region->beg[0], n)) { | |
1309 | + err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1310 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1311 | + onig_free(reg); | |
1312 | + onig_region_free(region, 1); | |
1313 | + return FALSE; | |
1314 | + } | |
1315 | + if(!fd_write(nextout, field, strlen(field))) { | |
1316 | + err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1317 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1318 | + onig_free(reg); | |
1319 | + onig_region_free(region, 1); | |
1320 | + return FALSE; | |
1321 | + } | |
1322 | + } | |
1323 | + /// group /// | |
1324 | + else { | |
1325 | + int i; | |
1326 | + for (i=1; i<region->num_regs; i++) { | |
1327 | + const int size = region->end[i] - region->beg[i]; | |
1328 | + | |
1329 | + if(!fd_write(nextout, target + region->beg[i], size)) { | |
1330 | + err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1331 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1332 | + onig_free(reg); | |
1333 | + onig_region_free(region, 1); | |
1334 | + return FALSE; | |
1335 | + } | |
1336 | + | |
1337 | + if(i==region->num_regs-1) { | |
1338 | + if(!fd_write(nextout, field, strlen(field))) { | |
1339 | + err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1340 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1341 | + onig_free(reg); | |
1342 | + onig_region_free(region, 1); | |
1343 | + return FALSE; | |
1344 | + } | |
1345 | + } | |
1346 | + else { | |
1347 | + if(!fd_write(nextout, "\t", 1)) { | |
1348 | + err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1349 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1350 | + onig_free(reg); | |
1351 | + onig_region_free(region, 1); | |
1352 | + return FALSE; | |
1353 | + } | |
1354 | + } | |
1355 | + } | |
1356 | + } | |
1357 | + } | |
1358 | + | |
1359 | + p = SFD(nextin).mBuf + region->end[0]; | |
1360 | + } | |
1361 | + else { | |
1362 | + p++; | |
1363 | + } | |
1364 | + | |
1365 | + onig_region_free(region, 1); | |
1366 | + } | |
1367 | + | |
1368 | + onig_free(reg); | |
1369 | + | |
1370 | + char buf[128]; | |
1371 | + snprintf(buf, 128, "%d", match_count); | |
1372 | + uobject_put(gRootObject, "MATCH_COUNT", STRING_NEW_GC(buf, FALSE)); | |
1373 | + | |
1374 | + if(match_count > 0) { | |
1375 | + if(SFD(nextin).mBufLen == 0) { | |
1376 | + runinfo->mRCode = RCODE_NFUN_NULL_INPUT; | |
1377 | + } | |
1378 | + else { | |
1379 | + runinfo->mRCode = 0; | |
1380 | + } | |
1381 | + } | |
1382 | + else { | |
1383 | + runinfo->mRCode = RCODE_NFUN_FALSE; | |
1384 | + } | |
1385 | + } | |
1386 | + else { | |
1387 | + err_msg("invalid regex", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1388 | + return FALSE; | |
1389 | + } | |
1390 | + } | |
1165 | 1391 | |
1166 | - sObject* sub_str = STRING_NEW_STACK(""); | |
1392 | + return TRUE; | |
1393 | +} | |
1167 | 1394 | |
1168 | - while(1) { | |
1169 | - OnigRegion* region = onig_region_new(); | |
1170 | - OnigErrorInfo err_info; | |
1395 | +BOOL cmd_index(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | |
1396 | +{ | |
1397 | + enum eKanjiCode code = gKanjiCode; | |
1398 | + if(sRunInfo_option(runinfo, "-byte")) { | |
1399 | + code = kByte; | |
1400 | + } | |
1401 | + else if(sRunInfo_option(runinfo, "-utf8")) { | |
1402 | + code = kUtf8; | |
1403 | + } | |
1404 | + else if(sRunInfo_option(runinfo, "-sjis")) { | |
1405 | + code = kSjis; | |
1406 | + } | |
1407 | + else if(sRunInfo_option(runinfo, "-eucjp")) { | |
1408 | + code = kEucjp; | |
1409 | + } | |
1171 | 1410 | |
1411 | + if(sRunInfo_option(runinfo, "-regex")) { | |
1412 | + if(runinfo->mFilter) { | |
1413 | + if(runinfo->mArgsNumRuntime == 2) { | |
1172 | 1414 | char* target = SFD(nextin).mBuf; |
1415 | + char* regex = runinfo->mArgsRuntime[1]; | |
1173 | 1416 | |
1174 | - const int point = p - target; | |
1175 | - int r2 = onig_search(reg, target | |
1176 | - , target + strlen(target) | |
1177 | - , p | |
1178 | - , p + strlen(p) | |
1179 | - , region, ONIG_OPTION_NONE); | |
1417 | + regex_t* reg; | |
1418 | + int r = get_onig_regex(®, runinfo, regex); | |
1180 | 1419 | |
1181 | - if(r2 == ONIG_MISMATCH) { | |
1182 | - onig_region_free(region, 1); | |
1420 | + if(r == ONIG_NORMAL) { | |
1421 | + /// get starting point /// | |
1422 | + int start; | |
1423 | + char* number; | |
1424 | + if(number = sRunInfo_option_with_argument(runinfo, "-number")) { | |
1425 | + start = atoi(number); | |
1183 | 1426 | |
1184 | - if(!quiet) { | |
1185 | - if(!fd_write(nextout, p, strlen(p))) { | |
1186 | - err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1187 | - runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1188 | - onig_free(reg); | |
1427 | + int len = str_kanjilen(code, target); | |
1428 | + if(len < 0) { | |
1429 | + err_msg("invalid target string", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1189 | 1430 | return FALSE; |
1190 | 1431 | } |
1191 | - } | |
1192 | - break; | |
1193 | - } | |
1194 | - else { | |
1195 | - /// make distination /// | |
1196 | - string_put(sub_str, ""); | |
1197 | - | |
1198 | - if(block) { | |
1199 | - clear_matching_info_variable(); | |
1200 | 1432 | |
1201 | - const int size = region->beg[0] - (p - target); | |
1202 | - if(size > 0) { | |
1203 | - uobject_put(gRootObject, "PREMATCH", STRING_NEW_GC3(p, size, FALSE)); | |
1433 | + if(start < 0) { | |
1434 | + start += len; | |
1435 | + if(start < 0) start = 0; | |
1436 | + } | |
1437 | + if(start >= len) { | |
1438 | + start = len -1; | |
1439 | + if(start < 0) start = 0; | |
1204 | 1440 | } |
1441 | + } | |
1442 | + else { | |
1443 | + start = 0; | |
1444 | + } | |
1205 | 1445 | |
1206 | - const int size2 = region->end[0] - region->beg[0]; | |
1207 | - | |
1208 | - uobject_put(gRootObject, "MATCH", STRING_NEW_GC3(target + region->beg[0], size2, FALSE)); | |
1209 | - uobject_put(gRootObject, "0", STRING_NEW_GC3(target + region->beg[0], size2, FALSE)); | |
1446 | + /// get search count /// | |
1447 | + int match_count; | |
1448 | + char* count; | |
1449 | + if(count = sRunInfo_option_with_argument(runinfo, "-count")) { | |
1450 | + match_count = atoi(count); | |
1451 | + if(match_count <= 0) { match_count = 1; } | |
1452 | + } | |
1453 | + else { | |
1454 | + match_count = 1; | |
1455 | + } | |
1210 | 1456 | |
1211 | - const int n = strlen(target)-region->end[0]; | |
1212 | - if(n > 0) { | |
1213 | - uobject_put(gRootObject, "POSTMATCH", STRING_NEW_GC3(target + region->end[0], n, FALSE)); | |
1457 | + char* start_byte = str_kanjipos2pointer(code, target, start); | |
1458 | + char* p = start_byte; | |
1459 | + char* result = NULL; | |
1460 | + while(p < start_byte + strlen(start_byte)) { | |
1461 | + if(gXyzshSigInt) { | |
1462 | + gXyzshSigInt = FALSE; | |
1463 | + err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1464 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1465 | + return FALSE; | |
1214 | 1466 | } |
1215 | 1467 | |
1216 | - int i; | |
1217 | - for (i=1; i<region->num_regs; i++) { | |
1218 | - const int size = region->end[i] - region->beg[i]; | |
1468 | + OnigRegion* region = onig_region_new(); | |
1469 | + OnigErrorInfo err_info; | |
1219 | 1470 | |
1220 | - char name[16]; | |
1221 | - snprintf(name, 16, "%d", i); | |
1471 | + const int point = p - target; | |
1472 | + int r2 = onig_search(reg, target | |
1473 | + , target + strlen(target) | |
1474 | + , p | |
1475 | + , p + strlen(p) | |
1476 | + , region, ONIG_OPTION_NONE); | |
1222 | 1477 | |
1223 | - uobject_put(gRootObject, name, STRING_NEW_GC3(target + region->beg[i], size, FALSE)); | |
1478 | + if(r2 == ONIG_MISMATCH) { | |
1479 | + onig_region_free(region, 1); | |
1480 | + break; | |
1224 | 1481 | } |
1225 | 1482 | |
1226 | - if(region->num_regs > 0) { | |
1227 | - const int n = region->num_regs -1; | |
1483 | + if(r2 >= 0) { | |
1484 | + result = target + region->beg[0]; | |
1228 | 1485 | |
1229 | - const int size = region->end[n] - region->beg[n]; | |
1486 | + match_count--; | |
1487 | + if(match_count == 0) { | |
1488 | + break; | |
1489 | + } | |
1490 | + p = target + region->beg[0] + 1; | |
1230 | 1491 | |
1231 | - uobject_put(gRootObject, "LAST_MATCH", STRING_NEW_GC3(target + region->beg[n], size, FALSE)); | |
1492 | + onig_region_free(region, 1); | |
1493 | + } | |
1494 | + else { | |
1495 | + onig_region_free(region, 1); | |
1496 | + break; | |
1232 | 1497 | } |
1498 | + } | |
1233 | 1499 | |
1234 | - char buf[128]; | |
1235 | - snprintf(buf, 128, "%d", region->num_regs); | |
1236 | - uobject_put(gRootObject, "MATCH_NUMBER", STRING_NEW_GC(buf, FALSE)); | |
1500 | + char msg[64]; | |
1501 | + int size; | |
1502 | + if(result == NULL || match_count !=0) { | |
1503 | + size = snprintf(msg, 64, "-1"); | |
1504 | + runinfo->mRCode = RCODE_NFUN_FALSE; | |
1505 | + } | |
1506 | + else { | |
1507 | + int c = str_pointer2kanjipos(code, target, result); | |
1508 | + size = snprintf(msg, 64, "%d", c); | |
1237 | 1509 | |
1238 | - fd_clear(nextin2); | |
1239 | - fd_clear(nextout2); | |
1510 | + if(SFD(nextin).mBufLen == 0) { | |
1511 | + runinfo->mRCode = RCODE_NFUN_NULL_INPUT; | |
1512 | + } | |
1513 | + else { | |
1514 | + runinfo->mRCode = 0; | |
1515 | + } | |
1516 | + } | |
1240 | 1517 | |
1241 | - if(!fd_write(nextin2, target + region->beg[0], region->end[0]-region->beg[0])) { | |
1242 | - err_msg("interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1518 | + if(!sRunInfo_option(runinfo, "-quiet")) { | |
1519 | + if(!fd_write(nextout, msg, size)) { | |
1520 | + err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1243 | 1521 | runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; |
1244 | - onig_region_free(region, 1); | |
1245 | - onig_free(reg); | |
1246 | 1522 | return FALSE; |
1247 | 1523 | } |
1248 | - | |
1249 | - int rcode = 0; | |
1250 | - if(!run(block, nextin2, nextout2, &rcode, runinfo->mCurrentObject, runinfo->mRunningObject)) { | |
1251 | - runinfo->mRCode = rcode; | |
1252 | - onig_region_free(region, 1); | |
1253 | - onig_free(reg); | |
1524 | + if(!fd_write(nextout, "\n", 1)) { | |
1525 | + err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1526 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1254 | 1527 | return FALSE; |
1255 | 1528 | } |
1256 | - | |
1257 | - string_put(sub_str, SFD(nextout2).mBuf); | |
1258 | 1529 | } |
1259 | - else { | |
1260 | - char* p2 = destination; | |
1261 | - | |
1262 | - while(*p2) { | |
1263 | - if(*p2 == '\\') { | |
1264 | - if(*(p2+1) == '\\') { | |
1265 | - p2+=2; | |
1266 | - string_push_back2(sub_str , '\\'); | |
1267 | - } | |
1268 | - else if(*(p2+1) >= '0' && *(p2+1) <= '9') { | |
1269 | - int n = *(p2+1) - '0'; | |
1270 | - | |
1271 | - if(n < region->num_regs) { | |
1272 | - p2+=2; | |
1273 | - | |
1274 | - const int size = region->end[n] - region->beg[n]; | |
1275 | - | |
1276 | - string_push_back3(sub_str, target + region->beg[n], size); | |
1277 | - } | |
1278 | - else { | |
1279 | - string_push_back2(sub_str, *p2++); | |
1280 | - string_push_back2(sub_str , *p2++); | |
1281 | - } | |
1282 | - } | |
1283 | - else if(*(p2+1) == '&') { | |
1284 | - p2 += 2; | |
1285 | - | |
1286 | - const int size = region->end[0] - region->beg[0]; | |
1287 | - | |
1288 | - string_push_back3(sub_str, target + region->beg[0], size); | |
1289 | - } | |
1290 | - else if(*(p2+1) == '`') { | |
1291 | - p2+=2; | |
1530 | + } | |
1531 | + else { | |
1532 | + err_msg("invalid regex", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1533 | + return FALSE; | |
1534 | + } | |
1292 | 1535 | |
1293 | - string_push_back3(sub_str, target, region->beg[0]); | |
1294 | - } | |
1295 | - else if(*(p2+1) == '\'') { | |
1296 | - p2+=2; | |
1536 | + onig_free(reg); | |
1537 | + } | |
1538 | + } | |
1539 | + } | |
1540 | + else { | |
1541 | + if(runinfo->mFilter) { | |
1542 | + if(runinfo->mArgsNumRuntime == 2) { | |
1543 | + char* target = SFD(nextin).mBuf; | |
1297 | 1544 | |
1298 | - string_push_back(sub_str, target + region->end[0]); | |
1299 | - } | |
1300 | - else if(*(p2+1) == '+') { | |
1301 | - p2+=2; | |
1545 | + char* word = runinfo->mArgsRuntime[1]; | |
1302 | 1546 | |
1303 | - if(region->num_regs > 0) { | |
1304 | - const int n = region->num_regs - 1; | |
1547 | + /// get starting point /// | |
1548 | + int start; | |
1549 | + char* number; | |
1550 | + if(number = sRunInfo_option_with_argument(runinfo, "-number")) { | |
1551 | + start = atoi(number); | |
1305 | 1552 | |
1306 | - const int size = region->end[n] - region->beg[n]; | |
1553 | + int len = str_kanjilen(code, target); | |
1554 | + if(len < 0) { | |
1555 | + err_msg("invalid target string", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1556 | + return FALSE; | |
1557 | + } | |
1307 | 1558 | |
1308 | - string_push_back3(sub_str, target + region->beg[n], size); | |
1309 | - } | |
1310 | - } | |
1311 | - else { | |
1312 | - string_push_back2(sub_str, *p2++); | |
1313 | - } | |
1314 | - } | |
1315 | - else { | |
1316 | - string_push_back2(sub_str, *p2++); | |
1317 | - } | |
1318 | - } | |
1559 | + if(start < 0) { | |
1560 | + start += len; | |
1561 | + if(start < 0) start = 0; | |
1562 | + } | |
1563 | + if(start >= len) { | |
1564 | + start = len -1; | |
1565 | + if(start < 0) start = 0; | |
1319 | 1566 | } |
1567 | + } | |
1568 | + else { | |
1569 | + start = 0; | |
1570 | + } | |
1320 | 1571 | |
1321 | - if(!quiet) { | |
1322 | - if(!fd_write(nextout, p, region->beg[0]-point)) { | |
1572 | + /// get search count /// | |
1573 | + int match_count; | |
1574 | + char* count; | |
1575 | + if(count = sRunInfo_option_with_argument(runinfo, "-count")) { | |
1576 | + match_count = atoi(count); | |
1577 | + if(match_count <= 0) { match_count = 1; } | |
1578 | + } | |
1579 | + else { | |
1580 | + match_count = 1; | |
1581 | + } | |
1582 | + | |
1583 | + char* start_byte = str_kanjipos2pointer(code, target, start); | |
1584 | + char* p = start_byte; | |
1585 | + char* result = NULL; | |
1586 | + if(sRunInfo_option(runinfo, "-ignore-case")) { | |
1587 | + while(p < start_byte + strlen(start_byte)) { | |
1588 | + if(gXyzshSigInt) { | |
1589 | + gXyzshSigInt = FALSE; | |
1323 | 1590 | err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); |
1324 | 1591 | runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; |
1325 | - onig_region_free(region, 1); | |
1326 | - onig_free(reg); | |
1327 | 1592 | return FALSE; |
1328 | 1593 | } |
1329 | - if(!fd_write(nextout, string_c_str(sub_str), string_length(sub_str))) { | |
1594 | + | |
1595 | + result = strcasestr(p, word); | |
1596 | + if(result) { | |
1597 | + match_count--; | |
1598 | + if(match_count == 0) { | |
1599 | + break; | |
1600 | + } | |
1601 | + p = result+strlen(word); | |
1602 | + } | |
1603 | + else { | |
1604 | + break; | |
1605 | + } | |
1606 | + } | |
1607 | + } | |
1608 | + else { | |
1609 | + while(p < start_byte + strlen(start_byte)) { | |
1610 | + if(gXyzshSigInt) { | |
1611 | + gXyzshSigInt = FALSE; | |
1330 | 1612 | err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); |
1331 | 1613 | runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; |
1332 | - onig_region_free(region, 1); | |
1333 | - onig_free(reg); | |
1334 | 1614 | return FALSE; |
1335 | 1615 | } |
1336 | - } | |
1337 | - | |
1338 | - sub_count++; | |
1339 | 1616 | |
1340 | - if(region->beg[0] == region->end[0]) { | |
1341 | - char buf[2]; | |
1342 | - buf[0] = target[region->beg[0]]; | |
1343 | - buf[1] = 0; | |
1344 | - | |
1345 | - if(!quiet) { | |
1346 | - if(!fd_write(nextout, buf, 1)) { | |
1347 | - err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1348 | - runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1349 | - onig_region_free(region, 1); | |
1350 | - onig_free(reg); | |
1351 | - return FALSE; | |
1617 | + result = strstr(p, word); | |
1618 | + if(result) { | |
1619 | + match_count--; | |
1620 | + if(match_count == 0) { | |
1621 | + break; | |
1352 | 1622 | } |
1623 | + p = result+strlen(word); | |
1353 | 1624 | } |
1354 | - | |
1355 | - p = target + region->end[0] + 1; | |
1356 | - | |
1357 | - if(p > target + strlen(target)) { | |
1625 | + else { | |
1358 | 1626 | break; |
1359 | 1627 | } |
1360 | 1628 | } |
1629 | + } | |
1630 | + | |
1631 | + char msg[64]; | |
1632 | + int size; | |
1633 | + if(result == NULL || match_count !=0) { | |
1634 | + size = snprintf(msg, 64, "-1"); | |
1635 | + runinfo->mRCode = RCODE_NFUN_FALSE; | |
1636 | + } | |
1637 | + else { | |
1638 | + int c = str_pointer2kanjipos(code, target, result); | |
1639 | + size = snprintf(msg, 64, "%d", c); | |
1640 | + | |
1641 | + if(SFD(nextin).mBufLen == 0) { | |
1642 | + runinfo->mRCode = RCODE_NFUN_NULL_INPUT; | |
1643 | + } | |
1361 | 1644 | else { |
1362 | - p= target + region->end[0]; | |
1645 | + runinfo->mRCode = 0; | |
1363 | 1646 | } |
1647 | + } | |
1364 | 1648 | |
1365 | - onig_region_free(region, 1); | |
1366 | - | |
1367 | - if(!global && !quiet) { | |
1368 | - if(!fd_write(nextout, p, strlen(p))) { | |
1369 | - err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1370 | - runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1371 | - onig_free(reg); | |
1372 | - return FALSE; | |
1373 | - } | |
1374 | - break; | |
1649 | + if(!sRunInfo_option(runinfo, "-quiet")) { | |
1650 | + if(!fd_write(nextout, msg, size)) { | |
1651 | + err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1652 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1653 | + return FALSE; | |
1654 | + } | |
1655 | + if(!fd_write(nextout, "\n", 1)) { | |
1656 | + err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1657 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1658 | + return FALSE; | |
1375 | 1659 | } |
1376 | 1660 | } |
1377 | 1661 | } |
1378 | 1662 | } |
1663 | + } | |
1379 | 1664 | |
1380 | - onig_free(reg); | |
1665 | + return TRUE; | |
1666 | +} | |
1381 | 1667 | |
1382 | - char buf[128]; | |
1383 | - snprintf(buf, 128, "%d", sub_count); | |
1384 | - uobject_put(gRootObject, "SUB_COUNT", STRING_NEW_GC(buf, FALSE)); | |
1668 | +static char* strstr_back(char* p, char* start, char* word, char* sname, int sline, char* command) | |
1669 | +{ | |
1670 | + int n = strlen(word); | |
1385 | 1671 | |
1386 | - if(sub_count > 0) { | |
1387 | - if(SFD(nextin).mBufLen == 0) { | |
1388 | - runinfo->mRCode = RCODE_NFUN_NULL_INPUT; | |
1672 | + while(p >= start) { | |
1673 | + BOOL flg = TRUE; | |
1674 | + int i; | |
1675 | + for(i=-1; i>=-n; i--) { | |
1676 | + if(p[i] != word[n+i]) { | |
1677 | + flg = FALSE; | |
1678 | + break; | |
1679 | + } | |
1680 | + | |
1681 | + if(gXyzshSigInt) { | |
1682 | + err_msg("interrupt", sname, sline, command); | |
1683 | + gXyzshSigInt = FALSE; | |
1684 | + return NULL; | |
1685 | + } | |
1686 | + } | |
1687 | + | |
1688 | + if(flg) { | |
1689 | + return p -n; | |
1690 | + } | |
1691 | + else { | |
1692 | + p--; | |
1693 | + } | |
1694 | + } | |
1695 | + | |
1696 | + return NULL; | |
1697 | +} | |
1698 | + | |
1699 | +static char* strcasestr_back(char* p, char* start, char* word, char* sname, int sline, char* command) | |
1700 | +{ | |
1701 | + int n = strlen(word); | |
1702 | + | |
1703 | + while(p >= start) { | |
1704 | + BOOL flg = TRUE; | |
1705 | + int i; | |
1706 | + for(i=-1; i>=-n; i--) { | |
1707 | + if(isascii(p[i]) && isascii(word[n+i])) { | |
1708 | + if(tolower(p[i]) != tolower(word[n+i])) { | |
1709 | + flg = FALSE; | |
1710 | + break; | |
1711 | + } | |
1389 | 1712 | } |
1390 | 1713 | else { |
1391 | - runinfo->mRCode = 0; | |
1714 | + if(p[i] != word[n+i]) { | |
1715 | + flg = FALSE; | |
1716 | + break; | |
1717 | + } | |
1718 | + } | |
1719 | + | |
1720 | + if(gXyzshSigInt) { | |
1721 | + gXyzshSigInt = FALSE; | |
1722 | + err_msg("interrupt", sname, sline, command); | |
1723 | + return NULL; | |
1392 | 1724 | } |
1393 | 1725 | } |
1726 | + | |
1727 | + if(flg) { | |
1728 | + return p -n; | |
1729 | + } | |
1394 | 1730 | else { |
1395 | - runinfo->mRCode = RCODE_NFUN_FALSE; | |
1731 | + p--; | |
1396 | 1732 | } |
1397 | 1733 | } |
1398 | 1734 | |
1399 | - return TRUE; | |
1735 | + return NULL; | |
1400 | 1736 | } |
1401 | 1737 | |
1402 | -BOOL cmd_scan(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | |
1738 | +BOOL cmd_rindex(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | |
1403 | 1739 | { |
1404 | - char* field = "\n"; | |
1405 | - if(sRunInfo_option(runinfo, "-Lw")) { | |
1406 | - field = "\r\n"; | |
1740 | + enum eKanjiCode code = gKanjiCode; | |
1741 | + if(sRunInfo_option(runinfo, "-byte")) { | |
1742 | + code = kByte; | |
1407 | 1743 | } |
1408 | - else if(sRunInfo_option(runinfo, "-Lm")) { | |
1409 | - field = "\r"; | |
1744 | + else if(sRunInfo_option(runinfo, "-utf8")) { | |
1745 | + code = kUtf8; | |
1410 | 1746 | } |
1411 | - else if(sRunInfo_option(runinfo, "-Lu")) { | |
1412 | - field = "\n"; | |
1747 | + else if(sRunInfo_option(runinfo, "-sjis")) { | |
1748 | + code = kSjis; | |
1413 | 1749 | } |
1414 | - else if(sRunInfo_option(runinfo, "-La")) { | |
1415 | - field = "\a"; | |
1750 | + else if(sRunInfo_option(runinfo, "-eucjp")) { | |
1751 | + code = kEucjp; | |
1416 | 1752 | } |
1417 | - | |
1418 | - if(runinfo->mFilter && runinfo->mArgsNumRuntime == 2) { | |
1419 | - sObject* block; | |
1420 | - sObject* nextin2; | |
1421 | - | |
1422 | - if(runinfo->mBlocksNum >= 1) { | |
1423 | - block = runinfo->mBlocks[0]; | |
1424 | - nextin2 = FD_NEW_STACK(); | |
1425 | - } | |
1426 | - else { | |
1427 | - block = NULL; | |
1428 | - } | |
1429 | - | |
1430 | - int match_count = 0; | |
1431 | - char* regex = runinfo->mArgsRuntime[1]; | |
1432 | - | |
1433 | - regex_t* reg; | |
1434 | - int r = get_onig_regex(®, runinfo, regex); | |
1435 | 1753 | |
1436 | - if(r == ONIG_NORMAL) { | |
1437 | - char* target = SFD(nextin).mBuf; | |
1438 | - char* p = SFD(nextin).mBuf; | |
1439 | - char* end = SFD(nextin).mBuf + strlen(SFD(nextin).mBuf); | |
1440 | - while(p < end) { | |
1441 | - OnigRegion* region = onig_region_new(); | |
1442 | - int r2 = onig_search(reg, target | |
1443 | - , target + strlen(target) | |
1444 | - , p | |
1445 | - , p + strlen(p) | |
1446 | - , region, ONIG_OPTION_NONE); | |
1754 | + if(sRunInfo_option(runinfo, "-regex")) { | |
1755 | + if(runinfo->mFilter) { | |
1756 | + if(runinfo->mArgsNumRuntime == 2) { | |
1757 | + char* target = SFD(nextin).mBuf; | |
1758 | + char* regex = runinfo->mArgsRuntime[1]; | |
1447 | 1759 | |
1448 | - if(r2 >= 0) { | |
1449 | - match_count++; | |
1760 | + regex_t* reg; | |
1761 | + int r = get_onig_regex(®, runinfo, regex); | |
1450 | 1762 | |
1451 | - if(block) { | |
1452 | - fd_clear(nextin2); | |
1763 | + if(r == ONIG_NORMAL) { | |
1764 | + /// get starting point /// | |
1765 | + int len = str_kanjilen(code, target); | |
1766 | + if(len < 0) { | |
1767 | + err_msg("invalid target string", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1768 | + return FALSE; | |
1769 | + } | |
1453 | 1770 | |
1454 | - /// no group /// | |
1455 | - if(region->num_regs == 1) { | |
1456 | - const int n = region->end[0] - region->beg[0]; | |
1771 | + int start; | |
1772 | + char* number; | |
1773 | + if(number = sRunInfo_option_with_argument(runinfo, "-number")) { | |
1774 | + start = atoi(number); | |
1457 | 1775 | |
1458 | - if(!fd_write(nextin2, target + region->beg[0], n)) { | |
1459 | - err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1460 | - runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1461 | - onig_free(reg); | |
1462 | - onig_region_free(region, 1); | |
1463 | - return FALSE; | |
1464 | - } | |
1465 | - if(!fd_write(nextin2, field, strlen(field))) { | |
1466 | - err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1467 | - runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1468 | - onig_free(reg); | |
1469 | - onig_region_free(region, 1); | |
1470 | - return FALSE; | |
1471 | - } | |
1776 | + if(start < 0) { | |
1777 | + start += len; | |
1778 | + if(start < 0) start = 0; | |
1472 | 1779 | } |
1473 | - /// group /// | |
1474 | - else { | |
1475 | - int i; | |
1476 | - for (i=1; i<region->num_regs; i++) { | |
1477 | - const int size = region->end[i] - region->beg[i]; | |
1478 | - | |
1479 | - if(!fd_write(nextin2, target + region->beg[i], size)) { | |
1480 | - err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1481 | - runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1482 | - onig_free(reg); | |
1483 | - onig_region_free(region, 1); | |
1484 | - return FALSE; | |
1485 | - } | |
1780 | + if(start >= len) { | |
1781 | + start = len -1 ; | |
1782 | + if(start < 0) start = 0; | |
1783 | + } | |
1784 | + } | |
1785 | + else { | |
1786 | + start = len -1; | |
1787 | + if(start < 0) start = 0; | |
1788 | + } | |
1486 | 1789 | |
1487 | - if(i==region->num_regs-1) { | |
1488 | - if(!fd_write(nextin2, field, strlen(field))) { | |
1489 | - err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1490 | - runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1491 | - onig_free(reg); | |
1492 | - onig_region_free(region, 1); | |
1493 | - return FALSE; | |
1494 | - } | |
1495 | - } | |
1496 | - else { | |
1497 | - if(!fd_write(nextin2, "\t", 1)) { | |
1498 | - err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1499 | - runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1500 | - onig_free(reg); | |
1501 | - onig_region_free(region, 1); | |
1502 | - return FALSE; | |
1503 | - } | |
1504 | - } | |
1505 | - } | |
1790 | + /// get search count /// | |
1791 | + int match_count; | |
1792 | + char* count; | |
1793 | + if(count = sRunInfo_option_with_argument(runinfo, "-count")) { | |
1794 | + match_count = atoi(count); | |
1795 | + if(match_count <= 0) { match_count = 1; } | |
1796 | + } | |
1797 | + else { | |
1798 | + match_count = 1; | |
1799 | + } | |
1800 | + | |
1801 | + char* start_byte = str_kanjipos2pointer(code, target, start); | |
1802 | + char* p = start_byte; | |
1803 | + char* result = NULL; | |
1804 | + while(p>=target) { | |
1805 | + if(gXyzshSigInt) { | |
1806 | + gXyzshSigInt = FALSE; | |
1807 | + err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1808 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1809 | + return FALSE; | |
1506 | 1810 | } |
1507 | 1811 | |
1508 | - clear_matching_info_variable(); | |
1812 | + OnigRegion* region = onig_region_new(); | |
1813 | + OnigErrorInfo err_info; | |
1509 | 1814 | |
1510 | - const int size = region->beg[0] - (p - target); | |
1511 | - if(size > 0) { | |
1512 | - uobject_put(gRootObject, "PREMATCH", STRING_NEW_GC3(p, size, FALSE)); | |
1815 | + int r2 = onig_search(reg, target | |
1816 | + , target + strlen(target) | |
1817 | + , p | |
1818 | + , target | |
1819 | + , region, ONIG_OPTION_NONE); | |
1820 | + | |
1821 | + if(r2 == ONIG_MISMATCH) { | |
1822 | + onig_region_free(region, 1); | |
1823 | + break; | |
1513 | 1824 | } |
1514 | 1825 | |
1515 | - const int size2 = region->end[0] - region->beg[0]; | |
1826 | + if(r2 >= 0) { | |
1827 | + result = target + region->beg[0]; | |
1516 | 1828 | |
1517 | - uobject_put(gRootObject, "MATCH", STRING_NEW_GC3(target + region->beg[0], size2, FALSE)); | |
1518 | - uobject_put(gRootObject, "0", STRING_NEW_GC3(target + region->beg[0], size2, FALSE)); | |
1829 | + match_count--; | |
1830 | + if(match_count == 0) { | |
1831 | + break; | |
1832 | + } | |
1833 | + p = target + region->beg[0] - 1; | |
1519 | 1834 | |
1520 | - const int n = strlen(target)-region->end[0]; | |
1521 | - if(n > 0) { | |
1522 | - uobject_put(gRootObject, "POSTMATCH", STRING_NEW_GC3(target + region->end[0], n, FALSE)); | |
1835 | + onig_region_free(region, 1); | |
1836 | + } | |
1837 | + else { | |
1838 | + onig_region_free(region, 1); | |
1839 | + break; | |
1523 | 1840 | } |
1841 | + } | |
1524 | 1842 | |
1525 | - int i; | |
1526 | - for (i=1; i<region->num_regs; i++) { | |
1527 | - const int size = region->end[i] - region->beg[i]; | |
1843 | + char msg[64]; | |
1844 | + int size; | |
1845 | + if(result == NULL || match_count !=0) { | |
1846 | + size = snprintf(msg, 64, "-1"); | |
1847 | + runinfo->mRCode = RCODE_NFUN_FALSE; | |
1848 | + } | |
1849 | + else { | |
1850 | + int c = str_pointer2kanjipos(code, target, result); | |
1851 | + size = snprintf(msg, 64, "%d", c); | |
1528 | 1852 | |
1529 | - char name[16]; | |
1530 | - snprintf(name, 16, "%d", i); | |
1853 | + if(SFD(nextin).mBufLen == 0) { | |
1854 | + runinfo->mRCode = RCODE_NFUN_NULL_INPUT; | |
1855 | + } | |
1856 | + else { | |
1857 | + runinfo->mRCode = 0; | |
1858 | + } | |
1859 | + } | |
1531 | 1860 | |
1532 | - uobject_put(gRootObject, name, STRING_NEW_GC3(target + region->beg[i], size, FALSE)); | |
1861 | + if(!sRunInfo_option(runinfo, "-quiet")) { | |
1862 | + if(!fd_write(nextout, msg, size)) { | |
1863 | + err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1864 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1865 | + return FALSE; | |
1866 | + } | |
1867 | + if(!fd_write(nextout, "\n", 1)) { | |
1868 | + err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1869 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1870 | + return FALSE; | |
1533 | 1871 | } |
1872 | + } | |
1873 | + } | |
1874 | + else { | |
1875 | + err_msg("invalid regex", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1876 | + return FALSE; | |
1877 | + } | |
1878 | + } | |
1879 | + } | |
1880 | + } | |
1881 | + else { | |
1882 | + if(runinfo->mFilter) { | |
1883 | + if(runinfo->mArgsNumRuntime == 2) { | |
1884 | + char* target = SFD(nextin).mBuf; | |
1885 | + char* word = runinfo->mArgsRuntime[1]; | |
1534 | 1886 | |
1535 | - if(region->num_regs > 0) { | |
1536 | - const int n = region->num_regs -1; | |
1887 | + /// get starting point /// | |
1888 | + int len = str_kanjilen(code, target); | |
1889 | + if(len < 0) { | |
1890 | + err_msg("invalid target string", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1891 | + return FALSE; | |
1892 | + } | |
1537 | 1893 | |
1538 | - const int size = region->end[n] - region->beg[n]; | |
1894 | + int start; | |
1895 | + char* number; | |
1896 | + if(number = sRunInfo_option_with_argument(runinfo, "-number")) { | |
1897 | + start = atoi(number); | |
1539 | 1898 | |
1540 | - uobject_put(gRootObject, "LAST_MATCH", STRING_NEW_GC3(target + region->beg[n], size, FALSE)); | |
1541 | - } | |
1899 | + if(start < 0) { | |
1900 | + start += len; | |
1901 | + if(start < 0) start = 0; | |
1902 | + } | |
1903 | + if(start >= len) { | |
1904 | + start = len -1 ; | |
1905 | + if(start < 0) start = 0; | |
1906 | + } | |
1907 | + } | |
1908 | + else { | |
1909 | + start = len -1; | |
1910 | + if(start < 0) start = 0; | |
1911 | + } | |
1542 | 1912 | |
1543 | - char buf[128]; | |
1544 | - snprintf(buf, 128, "%d", region->num_regs); | |
1545 | - uobject_put(gRootObject, "MATCH_NUMBER", STRING_NEW_GC(buf, FALSE)); | |
1913 | + /// get search count /// | |
1914 | + int match_count; | |
1915 | + char* count; | |
1916 | + if(count = sRunInfo_option_with_argument(runinfo, "-count")) { | |
1917 | + match_count = atoi(count); | |
1918 | + if(match_count <= 0) { match_count = 1; } | |
1919 | + } | |
1920 | + else { | |
1921 | + match_count = 1; | |
1922 | + } | |
1546 | 1923 | |
1547 | - int rcode = 0; | |
1548 | - if(!run(block, nextin2, nextout, &rcode, runinfo->mCurrentObject, runinfo->mRunningObject)) { | |
1549 | - runinfo->mRCode = rcode; | |
1550 | - onig_region_free(region, 1); | |
1551 | - onig_free(reg); | |
1924 | + | |
1925 | + char* start_byte = str_kanjipos2pointer(code, target, start+1); | |
1926 | + char* p = start_byte; | |
1927 | + char* result = NULL; | |
1928 | + if(sRunInfo_option(runinfo, "-ignore-case")) { | |
1929 | + while(p>=target) { | |
1930 | + result = strcasestr_back(p, target, word, runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1931 | + | |
1932 | + if(gXyzshSigInt) { | |
1933 | + gXyzshSigInt = FALSE; | |
1934 | + err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1935 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1552 | 1936 | return FALSE; |
1553 | 1937 | } |
1554 | - } | |
1555 | - else { | |
1556 | - /// no group /// | |
1557 | - if(region->num_regs == 1) { | |
1558 | - const int n = region->end[0] - region->beg[0]; | |
1559 | 1938 | |
1560 | - if(!fd_write(nextout, target + region->beg[0], n)) { | |
1561 | - err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1562 | - runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1563 | - onig_free(reg); | |
1564 | - onig_region_free(region, 1); | |
1565 | - return FALSE; | |
1566 | - } | |
1567 | - if(!fd_write(nextout, field, strlen(field))) { | |
1568 | - err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1569 | - runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1570 | - onig_free(reg); | |
1571 | - onig_region_free(region, 1); | |
1572 | - return FALSE; | |
1939 | + if(result != NULL) { | |
1940 | + match_count--; | |
1941 | + if(match_count == 0) { | |
1942 | + break; | |
1573 | 1943 | } |
1944 | + p = result - 1; | |
1574 | 1945 | } |
1575 | - /// group /// | |
1576 | 1946 | else { |
1577 | - int i; | |
1578 | - for (i=1; i<region->num_regs; i++) { | |
1579 | - const int size = region->end[i] - region->beg[i]; | |
1580 | - | |
1581 | - if(!fd_write(nextout, target + region->beg[i], size)) { | |
1582 | - err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1583 | - runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1584 | - onig_free(reg); | |
1585 | - onig_region_free(region, 1); | |
1586 | - return FALSE; | |
1587 | - } | |
1947 | + break; | |
1948 | + } | |
1949 | + } | |
1950 | + } | |
1951 | + else { | |
1952 | + while(p>=target) { | |
1953 | + result = strstr_back(p, target, word, runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1588 | 1954 | |
1589 | - if(i==region->num_regs-1) { | |
1590 | - if(!fd_write(nextout, field, strlen(field))) { | |
1591 | - err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1592 | - runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1593 | - onig_free(reg); | |
1594 | - onig_region_free(region, 1); | |
1595 | - return FALSE; | |
1596 | - } | |
1597 | - } | |
1598 | - else { | |
1599 | - if(!fd_write(nextout, "\t", 1)) { | |
1600 | - err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1601 | - runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1602 | - onig_free(reg); | |
1603 | - onig_region_free(region, 1); | |
1604 | - return FALSE; | |
1605 | - } | |
1606 | - } | |
1955 | + if(gXyzshSigInt) { | |
1956 | + gXyzshSigInt = FALSE; | |
1957 | + err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1958 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1959 | + return FALSE; | |
1960 | + } | |
1961 | + | |
1962 | + if(result != NULL) { | |
1963 | + match_count--; | |
1964 | + if(match_count == 0) { | |
1965 | + break; | |
1607 | 1966 | } |
1967 | + p = result - 1; | |
1968 | + } | |
1969 | + else { | |
1970 | + break; | |
1608 | 1971 | } |
1609 | 1972 | } |
1973 | + } | |
1610 | 1974 | |
1611 | - p = SFD(nextin).mBuf + region->end[0]; | |
1975 | + char msg[64]; | |
1976 | + int size; | |
1977 | + if(result == NULL || match_count !=0) { | |
1978 | + size = snprintf(msg, 64, "-1"); | |
1979 | + runinfo->mRCode = RCODE_NFUN_FALSE; | |
1612 | 1980 | } |
1613 | 1981 | else { |
1614 | - p++; | |
1982 | + int c = str_pointer2kanjipos(code, target, result); | |
1983 | + size = snprintf(msg, 64, "%d", c); | |
1984 | + | |
1985 | + if(SFD(nextin).mBufLen == 0) { | |
1986 | + runinfo->mRCode = RCODE_NFUN_NULL_INPUT; | |
1987 | + } | |
1988 | + else { | |
1989 | + runinfo->mRCode = 0; | |
1990 | + } | |
1615 | 1991 | } |
1616 | 1992 | |
1617 | - onig_region_free(region, 1); | |
1993 | + /// Ω–Œœ /// | |
1994 | + if(!sRunInfo_option(runinfo, "-quiet")) { | |
1995 | + if(!fd_write(nextout, msg, size)) { | |
1996 | + err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1997 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1998 | + return FALSE; | |
1999 | + } | |
2000 | + if(!fd_write(nextout, "\n", 1)) { | |
2001 | + err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
2002 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
2003 | + return FALSE; | |
2004 | + } | |
2005 | + } | |
1618 | 2006 | } |
2007 | + } | |
2008 | + } | |
1619 | 2009 | |
1620 | - onig_free(reg); | |
2010 | + return TRUE; | |
2011 | +} | |
2012 | + | |
2013 | +BOOL cmd_sub(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | |
2014 | +{ | |
2015 | + BOOL quiet = sRunInfo_option(runinfo, "-quiet"); | |
2016 | + BOOL ignore = sRunInfo_option(runinfo, "-ignore-case"); | |
2017 | + | |
2018 | + if(sRunInfo_option(runinfo, "-no-regex")) { | |
2019 | + if(runinfo->mFilter && runinfo->mArgsNumRuntime == 3) { | |
2020 | + BOOL global = sRunInfo_option(runinfo, "-global"); | |
2021 | + | |
2022 | + char* word = runinfo->mArgsRuntime[1]; | |
2023 | + char* destination = runinfo->mArgsRuntime[2]; | |
2024 | + const int destination_len = strlen(destination); | |
2025 | + | |
2026 | + int sub_count = 0; | |
2027 | + | |
2028 | + char* target = SFD(nextin).mBuf; | |
2029 | + char* p = target; | |
2030 | + | |
2031 | + while(1) { | |
2032 | + char* result = strstr(p, word); | |
2033 | + if(ignore) { | |
2034 | + result = strcasestr(p, word); | |
2035 | + } | |
2036 | + else { | |
2037 | + result = strstr(p, word); | |
2038 | + } | |
2039 | + | |
2040 | + if(result == NULL) { | |
2041 | + if(!quiet) { | |
2042 | + if(!fd_write(nextout, p, strlen(p))) { | |
2043 | + err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
2044 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
2045 | + return FALSE; | |
2046 | + } | |
2047 | + } | |
2048 | + break; | |
2049 | + } | |
2050 | + | |
2051 | + if(!quiet) { | |
2052 | + if(!fd_write(nextout, p, result - p)) { | |
2053 | + err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
2054 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
2055 | + return FALSE; | |
2056 | + } | |
2057 | + if(!fd_write(nextout, destination, destination_len)) { | |
2058 | + err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
2059 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
2060 | + return FALSE; | |
2061 | + } | |
2062 | + } | |
2063 | + | |
2064 | + p = result + strlen(word); | |
2065 | + sub_count++; | |
2066 | + | |
2067 | + if(!global) { | |
2068 | + if(!quiet) { | |
2069 | + if(!fd_write(nextout, p, strlen(p))) { | |
2070 | + err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
2071 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
2072 | + return FALSE; | |
2073 | + } | |
2074 | + } | |
2075 | + break; | |
2076 | + } | |
2077 | + } | |
1621 | 2078 | |
1622 | 2079 | char buf[128]; |
1623 | - snprintf(buf, 128, "%d", match_count); | |
1624 | - uobject_put(gRootObject, "MATCH_COUNT", STRING_NEW_GC(buf, FALSE)); | |
2080 | + snprintf(buf, 128, "%d", sub_count); | |
2081 | + uobject_put(gRootObject, "SUB_COUNT", STRING_NEW_GC(buf, FALSE)); | |
1625 | 2082 | |
1626 | - if(match_count > 0) { | |
2083 | + if(sub_count > 0) { | |
1627 | 2084 | if(SFD(nextin).mBufLen == 0) { |
1628 | 2085 | runinfo->mRCode = RCODE_NFUN_NULL_INPUT; |
1629 | 2086 | } |
@@ -1636,181 +2093,199 @@ BOOL cmd_scan(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | ||
1636 | 2093 | } |
1637 | 2094 | } |
1638 | 2095 | } |
2096 | + else { | |
2097 | + if(runinfo->mFilter && (runinfo->mArgsNumRuntime == 3 || runinfo->mArgsNumRuntime == 2 && runinfo->mBlocksNum >= 1)) { | |
2098 | + sObject* block; | |
2099 | + sObject* nextin2; | |
2100 | + sObject* nextout2; | |
1639 | 2101 | |
1640 | - return TRUE; | |
1641 | -} | |
2102 | + if(runinfo->mBlocksNum >= 1) { | |
2103 | + block = runinfo->mBlocks[0]; | |
2104 | + nextin2 = FD_NEW_STACK(); | |
2105 | + nextout2 = FD_NEW_STACK(); | |
2106 | + } | |
2107 | + else { | |
2108 | + block = NULL; | |
2109 | + } | |
1642 | 2110 | |
1643 | -BOOL cmd_split(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | |
1644 | -{ | |
1645 | - char* field = "\n"; | |
1646 | - eLineField lf = gLineField; | |
1647 | - if(sRunInfo_option(runinfo, "-Lw")) { | |
1648 | - lf = kCRLF; | |
1649 | - field = "\r\n"; | |
1650 | - } | |
1651 | - else if(sRunInfo_option(runinfo, "-Lm")) { | |
1652 | - lf = kCR; | |
1653 | - field = "\r"; | |
1654 | - } | |
1655 | - else if(sRunInfo_option(runinfo, "-Lu")) { | |
1656 | - lf = kLF; | |
1657 | - field = "\n"; | |
1658 | - } | |
1659 | - else if(sRunInfo_option(runinfo, "-La")) { | |
1660 | - lf = kBel; | |
1661 | - field = "\a"; | |
1662 | - } | |
2111 | + BOOL global = sRunInfo_option(runinfo, "-global"); | |
1663 | 2112 | |
1664 | - enum eKanjiCode code = gKanjiCode; | |
1665 | - if(sRunInfo_option(runinfo, "-byte")) { | |
1666 | - code = kByte; | |
1667 | - } | |
1668 | - else if(sRunInfo_option(runinfo, "-utf8")) { | |
1669 | - code = kUtf8; | |
1670 | - } | |
1671 | - else if(sRunInfo_option(runinfo, "-sjis")) { | |
1672 | - code = kSjis; | |
1673 | - } | |
1674 | - else if(sRunInfo_option(runinfo, "-eucjp")) { | |
1675 | - code = kEucjp; | |
1676 | - } | |
2113 | + char* regex = runinfo->mArgsRuntime[1]; | |
2114 | + char* destination = runinfo->mArgsRuntime[2]; | |
1677 | 2115 | |
1678 | - if(runinfo->mFilter) { | |
1679 | - char* regex; | |
2116 | + int sub_count = 0; | |
1680 | 2117 | |
1681 | - if(runinfo->mArgsNumRuntime == 1) { | |
1682 | - regex = "\\s+"; | |
1683 | - } | |
1684 | - else if(runinfo->mArgsNumRuntime >= 2) { | |
1685 | - regex = runinfo->mArgsRuntime[1]; | |
1686 | - } | |
2118 | + regex_t* reg; | |
2119 | + int r = get_onig_regex(®, runinfo, regex); | |
1687 | 2120 | |
1688 | - regex_t* reg; | |
1689 | - int r = get_onig_regex(®, runinfo, regex); | |
2121 | + if(r == ONIG_NORMAL) { | |
2122 | + char* p = SFD(nextin).mBuf; | |
1690 | 2123 | |
1691 | - if(r == ONIG_NORMAL) { | |
1692 | - char* target; | |
1693 | - char* p = target = SFD(nextin).mBuf; | |
2124 | + sObject* sub_str = STRING_NEW_STACK(""); | |
1694 | 2125 | |
1695 | - int split_count = 0; | |
2126 | + while(1) { | |
2127 | + OnigRegion* region = onig_region_new(); | |
2128 | + OnigErrorInfo err_info; | |
1696 | 2129 | |
1697 | - while(1) { | |
1698 | - OnigRegion* region = onig_region_new(); | |
2130 | + char* target = SFD(nextin).mBuf; | |
1699 | 2131 | |
1700 | - int r2 = onig_search(reg, target | |
1701 | - , target + strlen(target) | |
1702 | - , p, p + strlen(p) | |
1703 | - , region, ONIG_OPTION_NONE); | |
1704 | - | |
1705 | - if(r2 == ONIG_MISMATCH) { | |
1706 | - onig_region_free(region, 1); | |
2132 | + const int point = p - target; | |
2133 | + int r2 = onig_search(reg, target | |
2134 | + , target + strlen(target) | |
2135 | + , p | |
2136 | + , p + strlen(p) | |
2137 | + , region, ONIG_OPTION_NONE); | |
1707 | 2138 | |
1708 | - if(*p) { | |
1709 | - if(!fd_write(nextout, p, strlen(p))) { | |
1710 | - err_msg("singal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1711 | - runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1712 | - onig_free(reg); | |
1713 | - return FALSE; | |
1714 | - } | |
1715 | - } | |
2139 | + if(r2 == ONIG_MISMATCH) { | |
2140 | + onig_region_free(region, 1); | |
1716 | 2141 | |
1717 | - if(!fd_write(nextout, field, strlen(field))) { | |
1718 | - err_msg("singal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1719 | - runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1720 | - onig_free(reg); | |
1721 | - return FALSE; | |
2142 | + if(!quiet) { | |
2143 | + if(!fd_write(nextout, p, strlen(p))) { | |
2144 | + err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
2145 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
2146 | + onig_free(reg); | |
2147 | + return FALSE; | |
2148 | + } | |
2149 | + } | |
2150 | + break; | |
1722 | 2151 | } |
1723 | - break; | |
1724 | - } | |
1725 | - else { | |
1726 | - split_count++; | |
2152 | + else { | |
2153 | + /// make distination /// | |
2154 | + string_put(sub_str, ""); | |
1727 | 2155 | |
1728 | - if(region->beg[0] == region->end[0]) { | |
1729 | - if(target + region->beg[0] == p) { | |
1730 | - char* end_byte = str_kanjipos2pointer(code, p, 1); | |
1731 | - int size = end_byte - p; | |
2156 | + if(block) { | |
2157 | + clear_matching_info_variable(); | |
1732 | 2158 | |
2159 | + const int size = region->beg[0] - (p - target); | |
1733 | 2160 | if(size > 0) { |
1734 | - if(!fd_write(nextout, p, size)) { | |
1735 | - err_msg("singal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1736 | - runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1737 | - onig_region_free(region, 1); | |
1738 | - onig_free(reg); | |
1739 | - return FALSE; | |
1740 | - } | |
2161 | + uobject_put(gRootObject, "PREMATCH", STRING_NEW_GC3(p, size, FALSE)); | |
2162 | + } | |
1741 | 2163 | |
1742 | - if(!fd_write(nextout, field, strlen(field))) { | |
1743 | - err_msg("singal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1744 | - runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1745 | - onig_region_free(region, 1); | |
1746 | - onig_free(reg); | |
1747 | - return FALSE; | |
1748 | - } | |
2164 | + const int size2 = region->end[0] - region->beg[0]; | |
1749 | 2165 | |
1750 | - p += size; | |
1751 | - } | |
1752 | - else { | |
1753 | - onig_region_free(region, 1); | |
2166 | + uobject_put(gRootObject, "MATCH", STRING_NEW_GC3(target + region->beg[0], size2, FALSE)); | |
2167 | + uobject_put(gRootObject, "0", STRING_NEW_GC3(target + region->beg[0], size2, FALSE)); | |
1754 | 2168 | |
1755 | - break; | |
2169 | + const int n = strlen(target)-region->end[0]; | |
2170 | + if(n > 0) { | |
2171 | + uobject_put(gRootObject, "POSTMATCH", STRING_NEW_GC3(target + region->end[0], n, FALSE)); | |
1756 | 2172 | } |
1757 | - } | |
1758 | - else { | |
1759 | - int size = region->beg[0] - (p-target); | |
1760 | 2173 | |
1761 | - if(size > 0) { | |
1762 | - if(!fd_write(nextout, p, size)) { | |
1763 | - err_msg("singal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1764 | - runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1765 | - onig_region_free(region, 1); | |
1766 | - onig_free(reg); | |
1767 | - return FALSE; | |
1768 | - } | |
2174 | + int i; | |
2175 | + for (i=1; i<region->num_regs; i++) { | |
2176 | + const int size = region->end[i] - region->beg[i]; | |
1769 | 2177 | |
1770 | - if(!fd_write(nextout, field, strlen(field))) { | |
1771 | - err_msg("singal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1772 | - runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1773 | - onig_region_free(region, 1); | |
1774 | - onig_free(reg); | |
1775 | - return FALSE; | |
1776 | - } | |
2178 | + char name[16]; | |
2179 | + snprintf(name, 16, "%d", i); | |
2180 | + | |
2181 | + uobject_put(gRootObject, name, STRING_NEW_GC3(target + region->beg[i], size, FALSE)); | |
1777 | 2182 | } |
1778 | - else if(size == 0) { | |
1779 | - if(!fd_write(nextout, field, strlen(field))) { | |
1780 | - err_msg("singal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1781 | - runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1782 | - onig_region_free(region, 1); | |
1783 | - onig_free(reg); | |
1784 | - return FALSE; | |
1785 | - } | |
2183 | + | |
2184 | + if(region->num_regs > 0) { | |
2185 | + const int n = region->num_regs -1; | |
2186 | + | |
2187 | + const int size = region->end[n] - region->beg[n]; | |
2188 | + | |
2189 | + uobject_put(gRootObject, "LAST_MATCH", STRING_NEW_GC3(target + region->beg[n], size, FALSE)); | |
1786 | 2190 | } |
1787 | 2191 | |
1788 | - p = target + region->end[0]; | |
1789 | - } | |
1790 | - } | |
1791 | - else { | |
1792 | - int size = region->beg[0] - (p-target); | |
2192 | + char buf[128]; | |
2193 | + snprintf(buf, 128, "%d", region->num_regs); | |
2194 | + uobject_put(gRootObject, "MATCH_NUMBER", STRING_NEW_GC(buf, FALSE)); | |
1793 | 2195 | |
1794 | - if(size > 0) { | |
1795 | - if(!fd_write(nextout, p, size)) { | |
1796 | - err_msg("singal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
2196 | + fd_clear(nextin2); | |
2197 | + fd_clear(nextout2); | |
2198 | + | |
2199 | + if(!fd_write(nextin2, target + region->beg[0], region->end[0]-region->beg[0])) { | |
2200 | + err_msg("interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1797 | 2201 | runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; |
1798 | 2202 | onig_region_free(region, 1); |
1799 | 2203 | onig_free(reg); |
1800 | 2204 | return FALSE; |
1801 | 2205 | } |
1802 | 2206 | |
1803 | - if(!fd_write(nextout, field, strlen(field))) { | |
1804 | - err_msg("singal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
2207 | + int rcode = 0; | |
2208 | + if(!run(block, nextin2, nextout2, &rcode, runinfo->mCurrentObject, runinfo->mRunningObject)) { | |
2209 | + runinfo->mRCode = rcode; | |
2210 | + onig_region_free(region, 1); | |
2211 | + onig_free(reg); | |
2212 | + return FALSE; | |
2213 | + } | |
2214 | + | |
2215 | + string_put(sub_str, SFD(nextout2).mBuf); | |
2216 | + } | |
2217 | + else { | |
2218 | + char* p2 = destination; | |
2219 | + | |
2220 | + while(*p2) { | |
2221 | + if(*p2 == '\\') { | |
2222 | + if(*(p2+1) == '\\') { | |
2223 | + p2+=2; | |
2224 | + string_push_back2(sub_str , '\\'); | |
2225 | + } | |
2226 | + else if(*(p2+1) >= '0' && *(p2+1) <= '9') { | |
2227 | + int n = *(p2+1) - '0'; | |
2228 | + | |
2229 | + if(n < region->num_regs) { | |
2230 | + p2+=2; | |
2231 | + | |
2232 | + const int size = region->end[n] - region->beg[n]; | |
2233 | + | |
2234 | + string_push_back3(sub_str, target + region->beg[n], size); | |
2235 | + } | |
2236 | + else { | |
2237 | + string_push_back2(sub_str, *p2++); | |
2238 | + string_push_back2(sub_str , *p2++); | |
2239 | + } | |
2240 | + } | |
2241 | + else if(*(p2+1) == '&') { | |
2242 | + p2 += 2; | |
2243 | + | |
2244 | + const int size = region->end[0] - region->beg[0]; | |
2245 | + | |
2246 | + string_push_back3(sub_str, target + region->beg[0], size); | |
2247 | + } | |
2248 | + else if(*(p2+1) == '`') { | |
2249 | + p2+=2; | |
2250 | + | |
2251 | + string_push_back3(sub_str, target, region->beg[0]); | |
2252 | + } | |
2253 | + else if(*(p2+1) == '\'') { | |
2254 | + p2+=2; | |
2255 | + | |
2256 | + string_push_back(sub_str, target + region->end[0]); | |
2257 | + } | |
2258 | + else if(*(p2+1) == '+') { | |
2259 | + p2+=2; | |
2260 | + | |
2261 | + if(region->num_regs > 0) { | |
2262 | + const int n = region->num_regs - 1; | |
2263 | + | |
2264 | + const int size = region->end[n] - region->beg[n]; | |
2265 | + | |
2266 | + string_push_back3(sub_str, target + region->beg[n], size); | |
2267 | + } | |
2268 | + } | |
2269 | + else { | |
2270 | + string_push_back2(sub_str, *p2++); | |
2271 | + } | |
2272 | + } | |
2273 | + else { | |
2274 | + string_push_back2(sub_str, *p2++); | |
2275 | + } | |
2276 | + } | |
2277 | + } | |
2278 | + | |
2279 | + if(!quiet) { | |
2280 | + if(!fd_write(nextout, p, region->beg[0]-point)) { | |
2281 | + err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1805 | 2282 | runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; |
1806 | 2283 | onig_region_free(region, 1); |
1807 | 2284 | onig_free(reg); |
1808 | 2285 | return FALSE; |
1809 | 2286 | } |
1810 | - } | |
1811 | - else if(size == 0) { | |
1812 | - if(!fd_write(nextout, field, strlen(field))) { | |
1813 | - err_msg("singal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
2287 | + if(!fd_write(nextout, string_c_str(sub_str), string_length(sub_str))) { | |
2288 | + err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1814 | 2289 | runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; |
1815 | 2290 | onig_region_free(region, 1); |
1816 | 2291 | onig_free(reg); |
@@ -1818,39 +2293,59 @@ BOOL cmd_split(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | ||
1818 | 2293 | } |
1819 | 2294 | } |
1820 | 2295 | |
1821 | - p = target + region->end[0]; | |
1822 | - } | |
2296 | + sub_count++; | |
1823 | 2297 | |
1824 | - if(region->num_regs > 1) { | |
1825 | - /// group strings /// | |
1826 | - int i; | |
1827 | - for(i=1; i<region->num_regs; i++) { | |
1828 | - const int size = region->end[i]-region->beg[i]; | |
1829 | - if(size > 0) { | |
1830 | - if(!fd_write(nextout, target + region->beg[i], size)) { | |
1831 | - err_msg("singal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1832 | - runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1833 | - onig_region_free(region, 1); | |
1834 | - onig_free(reg); | |
1835 | - return FALSE; | |
1836 | - } | |
2298 | + if(region->beg[0] == region->end[0]) { | |
2299 | + char buf[2]; | |
2300 | + buf[0] = target[region->beg[0]]; | |
2301 | + buf[1] = 0; | |
1837 | 2302 | |
1838 | - if(!fd_write(nextout, field, strlen(field))) { | |
1839 | - err_msg("singal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
2303 | + if(!quiet) { | |
2304 | + if(!fd_write(nextout, buf, 1)) { | |
2305 | + err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1840 | 2306 | runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; |
1841 | 2307 | onig_region_free(region, 1); |
1842 | 2308 | onig_free(reg); |
1843 | 2309 | return FALSE; |
1844 | 2310 | } |
1845 | 2311 | } |
2312 | + | |
2313 | + p = target + region->end[0] + 1; | |
2314 | + | |
2315 | + if(p > target + strlen(target)) { | |
2316 | + break; | |
2317 | + } | |
2318 | + } | |
2319 | + else { | |
2320 | + p= target + region->end[0]; | |
2321 | + } | |
2322 | + | |
2323 | + onig_region_free(region, 1); | |
2324 | + | |
2325 | + if(!global && !quiet) { | |
2326 | + if(!fd_write(nextout, p, strlen(p))) { | |
2327 | + err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
2328 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
2329 | + onig_free(reg); | |
2330 | + return FALSE; | |
2331 | + } | |
2332 | + break; | |
1846 | 2333 | } |
1847 | 2334 | } |
1848 | 2335 | } |
1849 | - | |
1850 | - onig_region_free(region, 1); | |
2336 | + } | |
2337 | + else { | |
2338 | + err_msg("invalid regex", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
2339 | + return FALSE; | |
1851 | 2340 | } |
1852 | 2341 | |
1853 | - if(split_count > 0) { | |
2342 | + onig_free(reg); | |
2343 | + | |
2344 | + char buf[128]; | |
2345 | + snprintf(buf, 128, "%d", sub_count); | |
2346 | + uobject_put(gRootObject, "SUB_COUNT", STRING_NEW_GC(buf, FALSE)); | |
2347 | + | |
2348 | + if(sub_count > 0) { | |
1854 | 2349 | if(SFD(nextin).mBufLen == 0) { |
1855 | 2350 | runinfo->mRCode = RCODE_NFUN_NULL_INPUT; |
1856 | 2351 | } |
@@ -1859,97 +2354,35 @@ BOOL cmd_split(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | ||
1859 | 2354 | } |
1860 | 2355 | } |
1861 | 2356 | else { |
1862 | - runinfo->mRCode = 1; | |
2357 | + runinfo->mRCode = RCODE_NFUN_FALSE; | |
1863 | 2358 | } |
1864 | 2359 | } |
1865 | - | |
1866 | - onig_free(reg); | |
1867 | 2360 | } |
1868 | 2361 | |
1869 | 2362 | return TRUE; |
1870 | 2363 | } |
1871 | 2364 | |
1872 | -BOOL cmd_add(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | |
2365 | +BOOL cmd_split(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | |
1873 | 2366 | { |
1874 | - enum eKanjiCode code = gKanjiCode; | |
1875 | - if(sRunInfo_option(runinfo, "-byte")) { | |
1876 | - code = kByte; | |
1877 | - } | |
1878 | - else if(sRunInfo_option(runinfo, "-utf8")) { | |
1879 | - code = kUtf8; | |
2367 | + char* field = "\n"; | |
2368 | + eLineField lf = gLineField; | |
2369 | + if(sRunInfo_option(runinfo, "-Lw")) { | |
2370 | + lf = kCRLF; | |
2371 | + field = "\r\n"; | |
1880 | 2372 | } |
1881 | - else if(sRunInfo_option(runinfo, "-sjis")) { | |
1882 | - code = kSjis; | |
2373 | + else if(sRunInfo_option(runinfo, "-Lm")) { | |
2374 | + lf = kCR; | |
2375 | + field = "\r"; | |
1883 | 2376 | } |
1884 | - else if(sRunInfo_option(runinfo, "-eucjp")) { | |
1885 | - code = kEucjp; | |
2377 | + else if(sRunInfo_option(runinfo, "-Lu")) { | |
2378 | + lf = kLF; | |
2379 | + field = "\n"; | |
1886 | 2380 | } |
1887 | - | |
1888 | - if(runinfo->mFilter && runinfo->mArgsNumRuntime == 2) { | |
1889 | - char* arg = runinfo->mArgsRuntime[1]; | |
1890 | - int number; | |
1891 | - char* argument; | |
1892 | - if(argument = sRunInfo_option_with_argument(runinfo, "-number")) { | |
1893 | - number = atoi(argument); | |
1894 | - } | |
1895 | - else if(argument = sRunInfo_option_with_argument(runinfo, "-index")) { | |
1896 | - number = atoi(argument); | |
1897 | - } | |
1898 | - else { | |
1899 | - number = -1; | |
1900 | - } | |
1901 | - | |
1902 | - const int len = str_kanjilen(code, SFD(nextin).mBuf); | |
1903 | - | |
1904 | - if(number < 0) { | |
1905 | - number += len + 1; | |
1906 | - if(number < 0) number = 0; | |
1907 | - } | |
1908 | - | |
1909 | - if(number < len) { | |
1910 | - int point = str_kanjipos2pointer(code, SFD(nextin).mBuf, number) - SFD(nextin).mBuf; | |
1911 | - if(!fd_write(nextout, SFD(nextin).mBuf, point)) { | |
1912 | - err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1913 | - runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1914 | - return FALSE; | |
1915 | - } | |
1916 | - if(!fd_write(nextout, arg, strlen(arg))) { | |
1917 | - err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1918 | - runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1919 | - return FALSE; | |
1920 | - } | |
1921 | - if(!fd_write(nextout, SFD(nextin).mBuf + point, SFD(nextin).mBufLen - point)) { | |
1922 | - err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1923 | - runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1924 | - return FALSE; | |
1925 | - } | |
1926 | - } | |
1927 | - else { | |
1928 | - if(!fd_write(nextout, SFD(nextin).mBuf, SFD(nextin).mBufLen)) { | |
1929 | - err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1930 | - runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1931 | - return FALSE; | |
1932 | - } | |
1933 | - if(!fd_write(nextout, arg, strlen(arg))) { | |
1934 | - err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1935 | - runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
1936 | - return FALSE; | |
1937 | - } | |
1938 | - } | |
1939 | - | |
1940 | - if(SFD(nextin).mBufLen == 0) { | |
1941 | - runinfo->mRCode = RCODE_NFUN_NULL_INPUT; | |
1942 | - } | |
1943 | - else { | |
1944 | - runinfo->mRCode = 0; | |
1945 | - } | |
2381 | + else if(sRunInfo_option(runinfo, "-La")) { | |
2382 | + lf = kBel; | |
2383 | + field = "\a"; | |
1946 | 2384 | } |
1947 | 2385 | |
1948 | - return TRUE; | |
1949 | -} | |
1950 | - | |
1951 | -BOOL cmd_del(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | |
1952 | -{ | |
1953 | 2386 | enum eKanjiCode code = gKanjiCode; |
1954 | 2387 | if(sRunInfo_option(runinfo, "-byte")) { |
1955 | 2388 | code = kByte; |
@@ -1964,283 +2397,274 @@ BOOL cmd_del(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | ||
1964 | 2397 | code = kEucjp; |
1965 | 2398 | } |
1966 | 2399 | |
1967 | - | |
1968 | - if(runinfo->mFilter && runinfo->mArgsNumRuntime == 2) { | |
1969 | - char* arg = runinfo->mArgsRuntime[1]; | |
1970 | - int index = atoi(arg); | |
1971 | - | |
1972 | - int number; | |
1973 | - char* argument; | |
1974 | - if(argument = sRunInfo_option_with_argument(runinfo, "-number")) { | |
1975 | - number = atoi(argument); | |
1976 | - } | |
1977 | - else if(argument = sRunInfo_option_with_argument(runinfo, "-index")) { | |
1978 | - number = atoi(argument); | |
1979 | - } | |
1980 | - else { | |
1981 | - number = 1; | |
1982 | - } | |
1983 | - | |
1984 | - const int len = str_kanjilen(code, SFD(nextin).mBuf); | |
1985 | - | |
1986 | - if(index < 0) { | |
1987 | - index += len; | |
1988 | - if(index < 0) index = 0; | |
1989 | - } | |
1990 | - if(index >= len) { | |
1991 | - index = len -1; | |
1992 | - if(index < 0) index = 0; | |
1993 | - } | |
2400 | + if(runinfo->mFilter) { | |
2401 | + if(sRunInfo_option(runinfo, "-no-regex")) { | |
2402 | + char* word; | |
1994 | 2403 | |
1995 | - int point = str_kanjipos2pointer(code, SFD(nextin).mBuf, index) - SFD(nextin).mBuf; | |
1996 | - | |
1997 | - if(!fd_write(nextout, SFD(nextin).mBuf, point)) { | |
1998 | - err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
1999 | - runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
2000 | - return FALSE; | |
2001 | - } | |
2002 | - if(index + number < len) { | |
2003 | - char* point = str_kanjipos2pointer(code, SFD(nextin).mBuf, index + number); | |
2004 | - if(!fd_write(nextout, point, strlen(point))) { | |
2005 | - err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
2006 | - runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
2007 | - return FALSE; | |
2404 | + if(runinfo->mArgsNumRuntime == 1) { | |
2405 | + word = " "; | |
2406 | + } | |
2407 | + else if(runinfo->mArgsNumRuntime >= 2) { | |
2408 | + word = runinfo->mArgsRuntime[1]; | |
2008 | 2409 | } |
2009 | - } | |
2010 | 2410 | |
2011 | - if(SFD(nextin).mBufLen == 0) { | |
2012 | - runinfo->mRCode = RCODE_NFUN_NULL_INPUT; | |
2013 | - } | |
2014 | - else { | |
2015 | - runinfo->mRCode = 0; | |
2016 | - } | |
2017 | - } | |
2411 | + char* target; | |
2412 | + char* p = target = SFD(nextin).mBuf; | |
2018 | 2413 | |
2019 | - return TRUE; | |
2020 | -} | |
2414 | + int split_count = 0; | |
2021 | 2415 | |
2022 | -BOOL cmd_rows(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | |
2023 | -{ | |
2024 | - enum eKanjiCode code = gKanjiCode; | |
2025 | - if(sRunInfo_option(runinfo, "-byte")) { | |
2026 | - code = kByte; | |
2027 | - } | |
2028 | - else if(sRunInfo_option(runinfo, "-utf8")) { | |
2029 | - code = kUtf8; | |
2030 | - } | |
2031 | - else if(sRunInfo_option(runinfo, "-sjis")) { | |
2032 | - code = kSjis; | |
2033 | - } | |
2034 | - else if(sRunInfo_option(runinfo, "-eucjp")) { | |
2035 | - code = kEucjp; | |
2036 | - } | |
2416 | + while(1) { | |
2417 | + char* result; | |
2418 | + if(sRunInfo_option(runinfo, "-ignore-case")) { | |
2419 | + result = strcasestr(p, word); | |
2420 | + } | |
2421 | + else { | |
2422 | + result = strstr(p, word); | |
2423 | + } | |
2424 | + | |
2425 | + if(result == NULL) { | |
2426 | + if(*p) { | |
2427 | + if(!fd_write(nextout, p, strlen(p))) { | |
2428 | + err_msg("singal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
2429 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
2430 | + return FALSE; | |
2431 | + } | |
2432 | + } | |
2037 | 2433 | |
2038 | - if(runinfo->mFilter && runinfo->mArgsNumRuntime > 1 && runinfo->mBlocksNum <= runinfo->mArgsNumRuntime-1) { | |
2039 | - if(SFD(nextin).mBufLen == 0) { | |
2040 | - runinfo->mRCode = RCODE_NFUN_NULL_INPUT; | |
2041 | - } | |
2042 | - else { | |
2043 | - runinfo->mRCode = 0; | |
2044 | - } | |
2434 | + if(!fd_write(nextout, field, strlen(field))) { | |
2435 | + err_msg("singal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
2436 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
2437 | + return FALSE; | |
2438 | + } | |
2439 | + break; | |
2440 | + } | |
2441 | + else { | |
2442 | + split_count++; | |
2045 | 2443 | |
2046 | - int i; | |
2047 | - for(i=1; i<runinfo->mArgsNumRuntime; i++) { | |
2048 | - char* arg = runinfo->mArgsRuntime[i]; | |
2049 | - char* p; | |
2050 | - if(p = strstr(arg, "..")) { | |
2051 | - char buf[128+1]; | |
2052 | - char buf2[128+1]; | |
2053 | - const int len = p - arg; | |
2054 | - const int len2 = arg + strlen(arg) - (p + 2); | |
2055 | - if(len < 128 || len2 < 128) { | |
2056 | - memcpy(buf, arg, len); | |
2057 | - buf[len] = 0; | |
2444 | + if(!fd_write(nextout, p, result - p)) { | |
2445 | + err_msg("singal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
2446 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
2447 | + return FALSE; | |
2448 | + } | |
2058 | 2449 | |
2059 | - memcpy(buf2, p + 2, len2); | |
2060 | - buf2[len2] = 0; | |
2450 | + if(!fd_write(nextout, field, strlen(field))) { | |
2451 | + err_msg("singal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
2452 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
2453 | + return FALSE; | |
2454 | + } | |
2455 | + | |
2456 | + p = result + strlen(word); | |
2457 | + } | |
2458 | + } | |
2459 | + | |
2460 | + if(split_count > 0) { | |
2461 | + if(SFD(nextin).mBufLen == 0) { | |
2462 | + runinfo->mRCode = RCODE_NFUN_NULL_INPUT; | |
2061 | 2463 | } |
2062 | 2464 | else { |
2063 | - err_msg("invalid range", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
2064 | - return FALSE; | |
2465 | + runinfo->mRCode = 0; | |
2065 | 2466 | } |
2467 | + } | |
2468 | + else { | |
2469 | + runinfo->mRCode = 1; | |
2470 | + } | |
2471 | + } else { | |
2472 | + char* regex; | |
2066 | 2473 | |
2067 | - const int kanjilen = str_kanjilen(code, SFD(nextin).mBuf); | |
2068 | - if(kanjilen > 0) { | |
2069 | - int first = atoi(buf); | |
2070 | - int second = atoi(buf2); | |
2474 | + if(runinfo->mArgsNumRuntime == 1) { | |
2475 | + regex = "\\s+"; | |
2476 | + } | |
2477 | + else if(runinfo->mArgsNumRuntime >= 2) { | |
2478 | + regex = runinfo->mArgsRuntime[1]; | |
2479 | + } | |
2071 | 2480 | |
2072 | - if(first < 0) { | |
2073 | - first += kanjilen; | |
2074 | - if(first < 0) first = 0; | |
2075 | - } | |
2076 | - if(second < 0) { | |
2077 | - second += kanjilen; | |
2078 | - if(second < 0) second = 0; | |
2079 | - } | |
2080 | - if(first >= kanjilen) { | |
2081 | - first = kanjilen -1; | |
2082 | - if(first < 0) first = 0; | |
2083 | - } | |
2084 | - if(second >= kanjilen) { | |
2085 | - second = kanjilen -1; | |
2086 | - if(second < 0) second = 0; | |
2087 | - } | |
2481 | + regex_t* reg; | |
2482 | + int r = get_onig_regex(®, runinfo, regex); | |
2088 | 2483 | |
2089 | - /// make table to indexing access /// | |
2090 | - char** array = MALLOC(sizeof(char*)*(kanjilen+1)); | |
2091 | - if(code == kByte) { | |
2092 | - int k; | |
2093 | - for(k=0; k<kanjilen; k++) { | |
2094 | - array[k] = SFD(nextin).mBuf + k; | |
2095 | - } | |
2096 | - array[k] = SFD(nextin).mBuf + k; | |
2097 | - } | |
2098 | - else if(code == kUtf8) { | |
2099 | - char* p = SFD(nextin).mBuf; | |
2484 | + if(r == ONIG_NORMAL) { | |
2485 | + char* target; | |
2486 | + char* p = target = SFD(nextin).mBuf; | |
2100 | 2487 | |
2101 | - int k; | |
2102 | - for(k=0; k<kanjilen; k++) { | |
2103 | - array[k] = p; | |
2104 | - if(((unsigned char)*p) > 127) { | |
2105 | - const int size = ((*p & 0x80) >> 7) + ((*p & 0x40) >> 6) + ((*p & 0x20) >> 5) + ((*p & 0x10) >> 4); | |
2106 | - p+=size; | |
2107 | - } | |
2108 | - else { | |
2109 | - p++; | |
2488 | + int split_count = 0; | |
2489 | + | |
2490 | + while(1) { | |
2491 | + OnigRegion* region = onig_region_new(); | |
2492 | + | |
2493 | + int r2 = onig_search(reg, target | |
2494 | + , target + strlen(target) | |
2495 | + , p, p + strlen(p) | |
2496 | + , region, ONIG_OPTION_NONE); | |
2497 | + | |
2498 | + if(r2 == ONIG_MISMATCH) { | |
2499 | + onig_region_free(region, 1); | |
2500 | + | |
2501 | + if(*p) { | |
2502 | + if(!fd_write(nextout, p, strlen(p))) { | |
2503 | + err_msg("singal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
2504 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
2505 | + onig_free(reg); | |
2506 | + return FALSE; | |
2110 | 2507 | } |
2111 | 2508 | } |
2112 | - array[k] = p; | |
2113 | - } | |
2114 | - else { | |
2115 | - char* p = SFD(nextin).mBuf; | |
2116 | 2509 | |
2117 | - int k; | |
2118 | - for(k=0; k<kanjilen; k++) { | |
2119 | - const int size = is_kanji(code, *p) ? 2 : 1; | |
2120 | - array[k] = p; | |
2121 | - p+=size; | |
2510 | + if(!fd_write(nextout, field, strlen(field))) { | |
2511 | + err_msg("singal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
2512 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
2513 | + onig_free(reg); | |
2514 | + return FALSE; | |
2122 | 2515 | } |
2123 | - array[k] = p; | |
2516 | + break; | |
2124 | 2517 | } |
2518 | + else { | |
2519 | + split_count++; | |
2125 | 2520 | |
2126 | - if(first < second) { | |
2127 | - sObject* nextin2 = FD_NEW_STACK(); | |
2521 | + if(region->beg[0] == region->end[0]) { | |
2522 | + if(target + region->beg[0] == p) { | |
2523 | + char* end_byte = str_kanjipos2pointer(code, p, 1); | |
2524 | + int size = end_byte - p; | |
2128 | 2525 | |
2129 | - int j; | |
2130 | - for(j=first; j<=second; j++) { | |
2131 | - fd_clear(nextin2); | |
2526 | + if(size > 0) { | |
2527 | + if(!fd_write(nextout, p, size)) { | |
2528 | + err_msg("singal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
2529 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
2530 | + onig_region_free(region, 1); | |
2531 | + onig_free(reg); | |
2532 | + return FALSE; | |
2533 | + } | |
2132 | 2534 | |
2133 | - if(!fd_write(nextin2, array[j], array[j+1] -array[j])) { | |
2134 | - err_msg("interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
2135 | - runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
2136 | - FREE(array); | |
2137 | - return FALSE; | |
2138 | - } | |
2535 | + if(!fd_write(nextout, field, strlen(field))) { | |
2536 | + err_msg("singal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
2537 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
2538 | + onig_region_free(region, 1); | |
2539 | + onig_free(reg); | |
2540 | + return FALSE; | |
2541 | + } | |
2139 | 2542 | |
2140 | - if(i-1 < runinfo->mBlocksNum) { | |
2141 | - int rcode = 0; | |
2142 | - if(!run(runinfo->mBlocks[i-1], nextin2, nextout, &rcode, runinfo->mCurrentObject, runinfo->mRunningObject)) { | |
2143 | - runinfo->mRCode = rcode; | |
2144 | - FREE(array); | |
2145 | - return FALSE; | |
2543 | + p += size; | |
2544 | + } | |
2545 | + else { | |
2546 | + onig_region_free(region, 1); | |
2547 | + | |
2548 | + break; | |
2146 | 2549 | } |
2147 | - runinfo->mRCode = rcode; | |
2148 | 2550 | } |
2149 | 2551 | else { |
2150 | - if(!fd_write(nextout, SFD(nextin2).mBuf, SFD(nextin2).mBufLen)) | |
2151 | - { | |
2152 | - err_msg("interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
2153 | - runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
2154 | - FREE(array); | |
2155 | - return FALSE; | |
2552 | + int size = region->beg[0] - (p-target); | |
2553 | + | |
2554 | + if(size > 0) { | |
2555 | + if(!fd_write(nextout, p, size)) { | |
2556 | + err_msg("singal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
2557 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
2558 | + onig_region_free(region, 1); | |
2559 | + onig_free(reg); | |
2560 | + return FALSE; | |
2561 | + } | |
2562 | + | |
2563 | + if(!fd_write(nextout, field, strlen(field))) { | |
2564 | + err_msg("singal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
2565 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
2566 | + onig_region_free(region, 1); | |
2567 | + onig_free(reg); | |
2568 | + return FALSE; | |
2569 | + } | |
2156 | 2570 | } |
2157 | - runinfo->mRCode = 0; | |
2571 | + else if(size == 0) { | |
2572 | + if(!fd_write(nextout, field, strlen(field))) { | |
2573 | + err_msg("singal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
2574 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
2575 | + onig_region_free(region, 1); | |
2576 | + onig_free(reg); | |
2577 | + return FALSE; | |
2578 | + } | |
2579 | + } | |
2580 | + | |
2581 | + p = target + region->end[0]; | |
2158 | 2582 | } |
2159 | 2583 | } |
2160 | - } | |
2161 | - else { | |
2162 | - sObject* nextin2 = FD_NEW_STACK(); | |
2163 | - | |
2164 | - int j; | |
2165 | - for(j=first; j>=second; j--) { | |
2166 | - fd_clear(nextin2); | |
2584 | + else { | |
2585 | + int size = region->beg[0] - (p-target); | |
2167 | 2586 | |
2168 | - if(!fd_write(nextin2, array[j], array[j+1]-array[j])) { | |
2169 | - err_msg("interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
2170 | - runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
2171 | - FREE(array); | |
2172 | - return FALSE; | |
2173 | - } | |
2587 | + if(size > 0) { | |
2588 | + if(!fd_write(nextout, p, size)) { | |
2589 | + err_msg("singal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
2590 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
2591 | + onig_region_free(region, 1); | |
2592 | + onig_free(reg); | |
2593 | + return FALSE; | |
2594 | + } | |
2174 | 2595 | |
2175 | - if(i-1 < runinfo->mBlocksNum) { | |
2176 | - int rcode = 0; | |
2177 | - if(!run(runinfo->mBlocks[i-1], nextin2, nextout, &rcode, runinfo->mCurrentObject, runinfo->mRunningObject)) { | |
2178 | - runinfo->mRCode = rcode; | |
2179 | - FREE(array); | |
2596 | + if(!fd_write(nextout, field, strlen(field))) { | |
2597 | + err_msg("singal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
2598 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
2599 | + onig_region_free(region, 1); | |
2600 | + onig_free(reg); | |
2180 | 2601 | return FALSE; |
2181 | 2602 | } |
2182 | - runinfo->mRCode = rcode; | |
2183 | 2603 | } |
2184 | - else { | |
2185 | - if(!fd_write(nextout, SFD(nextin2).mBuf, SFD(nextin2).mBufLen)) | |
2186 | - { | |
2187 | - err_msg("interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
2604 | + else if(size == 0) { | |
2605 | + if(!fd_write(nextout, field, strlen(field))) { | |
2606 | + err_msg("singal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
2188 | 2607 | runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; |
2189 | - FREE(array); | |
2608 | + onig_region_free(region, 1); | |
2609 | + onig_free(reg); | |
2190 | 2610 | return FALSE; |
2191 | 2611 | } |
2192 | - runinfo->mRCode = 0; | |
2193 | 2612 | } |
2194 | - } | |
2195 | - } | |
2196 | 2613 | |
2197 | - FREE(array); | |
2198 | - } | |
2199 | - } | |
2200 | - else { | |
2201 | - const int len = str_kanjilen(code, SFD(nextin).mBuf); | |
2202 | - int num = atoi(arg); | |
2614 | + p = target + region->end[0]; | |
2615 | + } | |
2203 | 2616 | |
2204 | - if(num < 0) { | |
2205 | - num += len; | |
2206 | - if(num < 0) num = 0; | |
2207 | - } | |
2208 | - if(num >= len) { | |
2209 | - num = len -1; | |
2210 | - if(num < 0) num = 0; | |
2211 | - } | |
2617 | + if(region->num_regs > 1) { | |
2618 | + /// group strings /// | |
2619 | + int i; | |
2620 | + for(i=1; i<region->num_regs; i++) { | |
2621 | + const int size = region->end[i]-region->beg[i]; | |
2622 | + if(size > 0) { | |
2623 | + if(!fd_write(nextout, target + region->beg[i], size)) { | |
2624 | + err_msg("singal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
2625 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
2626 | + onig_region_free(region, 1); | |
2627 | + onig_free(reg); | |
2628 | + return FALSE; | |
2629 | + } | |
2212 | 2630 | |
2213 | - sObject* nextin2 = FD_NEW_STACK(); | |
2631 | + if(!fd_write(nextout, field, strlen(field))) { | |
2632 | + err_msg("singal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
2633 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
2634 | + onig_region_free(region, 1); | |
2635 | + onig_free(reg); | |
2636 | + return FALSE; | |
2637 | + } | |
2638 | + } | |
2639 | + } | |
2640 | + } | |
2641 | + } | |
2214 | 2642 | |
2215 | - char* str = str_kanjipos2pointer(code, SFD(nextin).mBuf, num); | |
2216 | - char* str2 = str_kanjipos2pointer(code, str, 1); | |
2217 | - if(!fd_write(nextin2, str, str2 -str)) { | |
2218 | - err_msg("interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
2219 | - runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
2220 | - return FALSE; | |
2643 | + onig_region_free(region, 1); | |
2221 | 2644 | } |
2222 | 2645 | |
2223 | - if(i-1 < runinfo->mBlocksNum) { | |
2224 | - int rcode = 0; | |
2225 | - if(!run(runinfo->mBlocks[i-1], nextin2, nextout, &rcode, runinfo->mCurrentObject, runinfo->mRunningObject)) { | |
2226 | - runinfo->mRCode = rcode; | |
2227 | - return FALSE; | |
2646 | + if(split_count > 0) { | |
2647 | + if(SFD(nextin).mBufLen == 0) { | |
2648 | + runinfo->mRCode = RCODE_NFUN_NULL_INPUT; | |
2649 | + } | |
2650 | + else { | |
2651 | + runinfo->mRCode = 0; | |
2228 | 2652 | } |
2229 | - runinfo->mRCode = rcode; | |
2230 | 2653 | } |
2231 | 2654 | else { |
2232 | - if(!fd_write(nextout, SFD(nextin2).mBuf, SFD(nextin2).mBufLen)) | |
2233 | - { | |
2234 | - err_msg("interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
2235 | - runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
2236 | - return FALSE; | |
2237 | - } | |
2238 | - runinfo->mRCode = 0; | |
2655 | + runinfo->mRCode = 1; | |
2239 | 2656 | } |
2240 | 2657 | } |
2658 | + else { | |
2659 | + err_msg("invalid regex", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
2660 | + return FALSE; | |
2661 | + } | |
2662 | + | |
2663 | + onig_free(reg); | |
2241 | 2664 | } |
2242 | 2665 | } |
2243 | 2666 | |
2244 | 2667 | return TRUE; |
2245 | 2668 | } |
2246 | 2669 | |
2670 | + |
@@ -0,0 +1,198 @@ | ||
1 | +#include "config.h" | |
2 | +#include <errno.h> | |
3 | +#include <time.h> | |
4 | +#include <stdlib.h> | |
5 | +#include <fcntl.h> | |
6 | +#include <libgen.h> | |
7 | +#include <stdio.h> | |
8 | +#include <string.h> | |
9 | +#include <unistd.h> | |
10 | +#include <math.h> | |
11 | +#include <oniguruma.h> | |
12 | +#include <sys/stat.h> | |
13 | +#include <signal.h> | |
14 | +#include <limits.h> | |
15 | +#include <dirent.h> | |
16 | +#include <migemo.h> | |
17 | + | |
18 | +#include "xyzsh/xyzsh.h" | |
19 | + | |
20 | +static migemo* gMigemo; | |
21 | +static sObject* gMigemoCache; | |
22 | + | |
23 | +static void migemo_init() | |
24 | +{ | |
25 | + char buf[PATH_MAX]; | |
26 | + char migemodir[PATH_MAX]; | |
27 | + gMigemo = migemo_open(NULL); | |
28 | + | |
29 | + snprintf(migemodir, PATH_MAX, "%s", SYSTEM_MIGEMODIR); | |
30 | + | |
31 | + snprintf(buf, PATH_MAX, "%s/utf-8/migemo-dict", migemodir); | |
32 | + if(migemo_load(gMigemo, MIGEMO_DICTID_MIGEMO, buf) == MIGEMO_DICTID_INVALID) { | |
33 | + fprintf(stderr, "%s is not found\n", buf); | |
34 | + exit(1); | |
35 | + } | |
36 | + snprintf(buf, PATH_MAX, "%s/utf-8/roma2hira.dat", migemodir); | |
37 | + if(migemo_load(gMigemo, MIGEMO_DICTID_ROMA2HIRA, buf) == MIGEMO_DICTID_INVALID) { | |
38 | + fprintf(stderr, "%s is not found\n", buf); | |
39 | + exit(1); | |
40 | + } | |
41 | + snprintf(buf, PATH_MAX, "%s/utf-8/hira2kata.dat", migemodir); | |
42 | + if(migemo_load(gMigemo, MIGEMO_DICTID_HIRA2KATA, buf) == MIGEMO_DICTID_INVALID) { | |
43 | + fprintf(stderr, "%s is not found\n", buf); | |
44 | + exit(1); | |
45 | + } | |
46 | + snprintf(buf, PATH_MAX, "%s/utf-8/han2zen.dat", migemodir); | |
47 | + if(migemo_load(gMigemo, MIGEMO_DICTID_HAN2ZEN, buf) == MIGEMO_DICTID_INVALID) { | |
48 | + fprintf(stderr, "%s is not found\n", buf); | |
49 | + exit(1); | |
50 | + } | |
51 | +} | |
52 | + | |
53 | +static void migemo_final() | |
54 | +{ | |
55 | + onig_end(); | |
56 | + migemo_close(gMigemo); | |
57 | + | |
58 | + hash_it* it = hash_loop_begin(gMigemoCache); | |
59 | + while(it) { | |
60 | + regex_t* reg = hash_loop_item(it); | |
61 | + onig_free(reg); | |
62 | + | |
63 | + it = hash_loop_next(it); | |
64 | + } | |
65 | + hash_delete_on_malloc(gMigemoCache); | |
66 | +} | |
67 | + | |
68 | +BOOL cmd_migemo_match(sObject* nextin, sObject* nextout, sRunInfo* runinfo) | |
69 | +{ | |
70 | + BOOL quiet = sRunInfo_option(runinfo, "-quiet"); | |
71 | + | |
72 | + if(runinfo->mFilter && runinfo->mArgsNumRuntime == 2) { | |
73 | + runinfo->mRCode = RCODE_NFUN_FALSE; | |
74 | + char* target = SFD(nextin).mBuf; | |
75 | + char* regex = runinfo->mArgsRuntime[1]; | |
76 | + | |
77 | + if(regex[0] == 0) { | |
78 | + runinfo->mRCode = 0; | |
79 | + if(!quiet) { | |
80 | + char buf[1024]; | |
81 | + int n = snprintf(buf, 1024, "0%d\n", (int)strlen(target)); | |
82 | + if(!fd_write(nextout, buf, n)) { | |
83 | + err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
84 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
85 | + return FALSE; | |
86 | + } | |
87 | + } | |
88 | + } | |
89 | + else { | |
90 | + regex_t* reg = hash_item(gMigemoCache, regex); | |
91 | + | |
92 | + if(reg == NULL) { | |
93 | + OnigUChar * p = migemo_query(gMigemo, regex); | |
94 | + if(p == NULL) { | |
95 | + err_msg("migemo query failed", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
96 | + migemo_release(gMigemo, (unsigned char*) p); | |
97 | + return FALSE; | |
98 | + } | |
99 | + | |
100 | + /// modify query /// | |
101 | + char* p2 = MALLOC(strlen(p)*2 + 1); | |
102 | + | |
103 | + char* _p = p; | |
104 | + char* _p2 = p2; | |
105 | + | |
106 | + while(*_p) { | |
107 | + if(*_p == '+') { | |
108 | + *_p2++ = '\\'; | |
109 | + *_p2++ = *_p++; | |
110 | + } | |
111 | + else { | |
112 | + *_p2++ = *_p++; | |
113 | + } | |
114 | + } | |
115 | + *_p2 = 0; | |
116 | + | |
117 | + /// make regex /// | |
118 | + OnigErrorInfo err_info; | |
119 | + | |
120 | + int r = onig_new(®, p2, p2 + strlen(p2), ONIG_OPTION_DEFAULT, ONIG_ENCODING_UTF8, ONIG_SYNTAX_DEFAULT, &err_info); | |
121 | + | |
122 | + if(r != ONIG_NORMAL && r != 0) { | |
123 | + err_msg("regex of migemo query failed", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
124 | + onig_free(reg); | |
125 | + FREE(p2); | |
126 | + migemo_release(gMigemo, (unsigned char*) p); | |
127 | + return FALSE; | |
128 | + } | |
129 | + | |
130 | + FREE(p2); | |
131 | + migemo_release(gMigemo, (unsigned char*) p); | |
132 | + } | |
133 | + | |
134 | + OnigRegion* region = onig_region_new(); | |
135 | + int r2 = onig_search(reg, target, target + strlen(target), target, target + strlen(target), region, ONIG_OPTION_NONE); | |
136 | + | |
137 | + if(r2 >= 0) { | |
138 | + runinfo->mRCode = 0; | |
139 | + if(!quiet) { | |
140 | + char buf[1024]; | |
141 | + int n = snprintf(buf, 1024, "%d\n%d\n", region->beg[0], region->end[0]); | |
142 | + if(!fd_write(nextout, buf, n)) { | |
143 | + err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
144 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
145 | + onig_region_free(region, 1); | |
146 | + onig_free(reg); | |
147 | + return FALSE; | |
148 | + } | |
149 | + } | |
150 | + } | |
151 | + else { | |
152 | + if(!quiet) { | |
153 | + char buf[1024]; | |
154 | + int n = snprintf(buf, 1024, "-1\n-1\n"); | |
155 | + if(!fd_write(nextout, buf, n)) { | |
156 | + err_msg("signal interrupt", runinfo->mSName, runinfo->mSLine, runinfo->mArgs[0]); | |
157 | + runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; | |
158 | + onig_region_free(region, 1); | |
159 | + onig_free(reg); | |
160 | + return FALSE; | |
161 | + } | |
162 | + } | |
163 | + } | |
164 | + | |
165 | + onig_region_free(region, 1); | |
166 | + | |
167 | + /// Migemo querry which is only one character is very heavy, so get cache. | |
168 | + if(strlen(regex) <= 2) { | |
169 | + hash_put(gMigemoCache, regex, reg); | |
170 | + } | |
171 | + else { | |
172 | + onig_free(reg); | |
173 | + } | |
174 | + } | |
175 | + } | |
176 | + | |
177 | + return TRUE; | |
178 | +} | |
179 | + | |
180 | +int dl_init() | |
181 | +{ | |
182 | + migemo_init(); | |
183 | + sObject* migemo_object = UOBJECT_NEW_GC(8, gRootObject, "migemo", TRUE); | |
184 | + uobject_init(migemo_object); | |
185 | + uobject_put(gRootObject, "migemo", migemo_object); | |
186 | + uobject_put(migemo_object, "match", NFUN_NEW_GC(cmd_migemo_match, NULL, TRUE)); | |
187 | + gMigemoCache = HASH_NEW_MALLOC(100); | |
188 | + | |
189 | + return 0; | |
190 | +} | |
191 | + | |
192 | +int dl_final() | |
193 | +{ | |
194 | + migemo_final(); | |
195 | + | |
196 | + return 0; | |
197 | +} | |
198 | + |
@@ -0,0 +1,20 @@ | ||
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> |
@@ -0,0 +1,151 @@ | ||
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 | +class MigemoCompletion ( | |
31 | + def common_head ( | |
32 | + | each ( | |
33 | + | chomp| length -utf8 | |
34 | + ) | max | var -local max_length | |
35 | + | |
36 | + print 0 | var -local point | |
37 | + | |
38 | + while(true) ( | |
39 | + | each ( | |
40 | + | chomp | rows -utf8 0..$point | pomch | |
41 | + ) | sys::sort | uniq | length -line-num | strip | if(| != 1) ( | |
42 | + -- point; | |
43 | + break | |
44 | + ) | |
45 | + | |
46 | + ++ point; | |
47 | + | |
48 | + if(point | -ge $max_length) ( | |
49 | + -- point | |
50 | + break | |
51 | + ) | |
52 | + ) | |
53 | + | |
54 | + if(point | -ne -1) ( | |
55 | + | rows -utf8 0..$point | |
56 | + ) | |
57 | + ) | |
58 | + | |
59 | + def is_all_ascii ( | |
60 | + | length -byte | var -local LEN | |
61 | + | |
62 | + LEN | -eq $(| length -utf8) | |
63 | + ) | |
64 | + | |
65 | + def migemo_file_completion ( | |
66 | + print $ARGV[0] | var -local inputing | |
67 | + print $ARGV[1] | var -local editing_line | |
68 | + | |
69 | + | each ( | |
70 | + if (inputing | =~ '.*\/[a-zA-Z]+$') ( | |
71 | + | if(|=~ '.*\/[a-zA-Z]+[^a-zA-z/]+$') ( | |
72 | + (inputing; |print) | common_head | var -local same_head | |
73 | + | |
74 | + same_head | var -local no_migemo_string | |
75 | + inputing | sub -no-regex $same_head '' | var -local migemo_string | |
76 | + ) else ( | |
77 | + inputing | sub '(.*\/)[a-zA-Z]+$' '\1' | var -local no_migemo_string | |
78 | + inputing | sub '.*\/([a-zA-Z]+)$' '\1' | var -local migemo_string | |
79 | + ) | |
80 | + ) elif (inputing | =~ '.*\/[^a-zA-Z]+[a-zA-Z]+$') ( | |
81 | + inputing | sub '(.*\/[^a-zA-Z]+)[a-zA-Z]+$' '\1' | var -local no_migemo_string | |
82 | + inputing | sub '.*\/[^a-zA-Z]+([a-zA-Z]+)$' '\1' | var -local migemo_string | |
83 | + ) elif (inputing | =~ '[a-zA-Z]+$') ( | |
84 | + | if(|=~ '[a-zA-Z]+[^a-zA-z/]+$') ( | |
85 | + (inputing; |print) | common_head | var -local same_head | |
86 | + | |
87 | + same_head | var -local no_migemo_string | |
88 | + inputing | sub -no-regex $same_head '' | var -local migemo_string | |
89 | + ) else ( | |
90 | + print "" | var -local no_migemo_string | |
91 | + inputing | var -local migemo_string | |
92 | + ) | |
93 | + ) elif (inputing | =~ '[^a-zA-Z]+[a-zA-Z]+$') ( | |
94 | + inputing | sub '([^a-zA-Z]+)[a-zA-Z]+$' '\1' | var -local no_migemo_string | |
95 | + inputing | sub '[^a-zA-Z]+([a-zA-Z]+)$' '\1' | var -local migemo_string | |
96 | + ) else ( | |
97 | + print "" | var -local no_migemo_string | |
98 | + print "" | var -local migemo_string | |
99 | + ) | |
100 | + | |
101 | + | if(| sub -no-regex $no_migemo_string '' | chomp | migemo::match $migemo_string | lines 0 | = 0\n) ( | |
102 | ||
103 | + ) | |
104 | + ) | (| common_head | var -local COMMON_HEAD; | length -line-num | var -local NUM) | |
105 | + | |
106 | + if(COMMON_HEAD | chomp | -n && COMMON_HEAD | length | -gt $(inputing | length)) ( | |
107 | + rl::delete_text $(editing_line | rindex $inputing) $(rl::point) | |
108 | + rl::insert_text $COMMON_HEAD | |
109 | + if(NUM | chomp | -eq 1 && COMMON_HEAD| chomp | rows -1 | != /) ( rl::insert_text " " ) | |
110 | + ) | |
111 | + ) | |
112 | + | |
113 | + def file_completion ( | |
114 | + | split '(?<!\\) +' | lines -1 | var -local inputing | |
115 | + | |
116 | + if(inputing | index -quiet /) ( | |
117 | + sys::dirname $(inputing|chomp| if (|rows -1 | = /) ( |add aaa ) else ( | print ) ) | var -local DIR | |
118 | + | |
119 | + ls $(DIR|xyzsh_dequote|chomp) | each ( | |
120 | + | if (|chomp | add -number 0 $(DIR|xyzsh_dequote|chomp)/ | -d) ( | |
121 | + |chomp | xyzsh_quote | add -number 0 $DIR/ | add / | pomch | |
122 | + ) else ( | |
123 | + |chomp | xyzsh_quote | add -number 0 $DIR/ | pomch | |
124 | + ) | |
125 | + ) | migemo_file_completion $inputing $(|print) | |
126 | + ) else ( | |
127 | + ls | each ( | |
128 | + | if (|chomp| -d) ( | |
129 | + | chomp | xyzsh_quote | add / | pomch | |
130 | + ) else ( | |
131 | + |chomp | xyzsh_quote| pomch | |
132 | + ) | |
133 | + ) | migemo_file_completion $inputing $(|print) | |
134 | + ) | |
135 | + ) | |
136 | + | |
137 | + completion __all__ ( | |
138 | + | file_completion | |
139 | + ) | |
140 | + | |
141 | + root::compl::run( root::object sys ) | |
142 | + | |
143 | + completion sys::__all__ ( | |
144 | + | file_completion | |
145 | + ) | |
146 | +) | |
147 | + | |
148 | +readline "Do you want to use migemo completion which is Japanese ROMAJI completion?(y/n)" | chomp | if(|=~ -ignore-case ^y) ( | |
149 | + MigemoCompletion | |
150 | +) | |
151 | + |
@@ -0,0 +1,143 @@ | ||
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 | + |
@@ -75,7 +75,7 @@ static char* prompt() | ||
75 | 75 | if(rcode == RCODE_BREAK) { |
76 | 76 | fprintf(stderr, "invalid break. Not in a loop\n"); |
77 | 77 | } |
78 | - else if(rcode == RCODE_RETURN) { | |
78 | + else if(rcode & RCODE_RETURN) { | |
79 | 79 | fprintf(stderr, "invalid return. Not in a function\n"); |
80 | 80 | } |
81 | 81 | else if(rcode == RCODE_EXIT) { |
@@ -143,6 +143,63 @@ BOOL xyzsh_run(int* rcode, sObject* block, char* source_name, fXyzshJobDone xyzs | ||
143 | 143 | return TRUE; |
144 | 144 | } |
145 | 145 | |
146 | +BOOL xyzsh_eval(int* rcode, char* cmd, char* source_name, fXyzshJobDone xyzsh_job_done_, sObject* nextin, sObject* nextout, int argc, char** argv, sObject* current_object) | |
147 | +{ | |
148 | + string_put(gErrMsg, ""); | |
149 | + | |
150 | + xyzsh_job_done = xyzsh_job_done_; | |
151 | + | |
152 | + stack_start_stack(); | |
153 | + | |
154 | + sObject* block = BLOCK_NEW_STACK(); | |
155 | + int sline = 1; | |
156 | + if(parse(cmd, source_name, &sline, block, NULL)) { | |
157 | + xyzsh_set_signal(); | |
158 | + | |
159 | + sObject* fun = FUN_NEW_STACK(NULL); | |
160 | + sObject* stackframe = UOBJECT_NEW_GC(8, gXyzshObject, "_stackframe", FALSE); | |
161 | + vector_add(gStackFrames, stackframe); | |
162 | + //uobject_init(stackframe); | |
163 | + SFUN(fun).mLocalObjects = stackframe; | |
164 | + | |
165 | + sObject* argv2 = VECTOR_NEW_GC(16, FALSE); | |
166 | + int i; | |
167 | + for(i=0; i<argc; i++) { | |
168 | + vector_add(argv2, STRING_NEW_GC(argv[i], FALSE)); | |
169 | + } | |
170 | + uobject_put(SFUN(fun).mLocalObjects, "ARGV", argv2); | |
171 | + | |
172 | + if(!run(block, nextin, nextout, rcode, current_object, fun)) { | |
173 | + xyzsh_restore_signal_default(); | |
174 | + (void)vector_pop_back(gStackFrames); | |
175 | + | |
176 | + stack_end_stack(); | |
177 | + | |
178 | + /// wait background job | |
179 | + xyzsh_wait_background_job(); | |
180 | + | |
181 | + return FALSE; | |
182 | + } | |
183 | + xyzsh_restore_signal_default(); | |
184 | + | |
185 | + (void)vector_pop_back(gStackFrames); | |
186 | + stack_end_stack(); | |
187 | + } | |
188 | + else { | |
189 | + stack_end_stack(); | |
190 | + | |
191 | + /// wait background job | |
192 | + xyzsh_wait_background_job(); | |
193 | + | |
194 | + return FALSE; | |
195 | + } | |
196 | + | |
197 | + /// wait background job | |
198 | + xyzsh_wait_background_job(); | |
199 | + | |
200 | + return TRUE; | |
201 | +} | |
202 | + | |
146 | 203 | static void readline_insert_text(char* cmdline, int cursor_point) |
147 | 204 | { |
148 | 205 | (void)rl_replace_line(cmdline, 0); |
@@ -288,7 +345,7 @@ BOOL xyzsh_readline_interface_onetime(int* rcode, char* cmdline, int cursor_poin | ||
288 | 345 | if(*rcode == RCODE_BREAK) { |
289 | 346 | fprintf(stderr, "invalid break. Not in a loop\n"); |
290 | 347 | } |
291 | - else if(*rcode == RCODE_RETURN) { | |
348 | + else if(*rcode & RCODE_RETURN) { | |
292 | 349 | fprintf(stderr, "invalid return. Not in a function\n"); |
293 | 350 | } |
294 | 351 | else if(*rcode == RCODE_EXIT) { |
@@ -445,7 +502,7 @@ void xyzsh_readline_interface(char* cmdline, int cursor_point, char** argv, int | ||
445 | 502 | if(rcode == RCODE_BREAK) { |
446 | 503 | fprintf(stderr, "invalid break. Not in a loop\n"); |
447 | 504 | } |
448 | - else if(rcode == RCODE_RETURN) { | |
505 | + else if(rcode & RCODE_RETURN) { | |
449 | 506 | fprintf(stderr, "invalid return. Not in a function\n"); |
450 | 507 | } |
451 | 508 | else if(rcode == RCODE_EXIT) { |
@@ -500,7 +557,7 @@ BOOL xyzsh_load_file(char* fname, char** argv, int argc, sObject* current_object | ||
500 | 557 | xyzsh_restore_signal_default(); |
501 | 558 | return FALSE; |
502 | 559 | } |
503 | - else if(runinfo.mRCode == RCODE_RETURN) { | |
560 | + else if(runinfo.mRCode & RCODE_RETURN) { | |
504 | 561 | fprintf(stderr, "invalid return. Not in a function\n"); |
505 | 562 | xyzsh_restore_signal_default(); |
506 | 563 | return FALSE; |
@@ -552,7 +609,7 @@ void xyzsh_opt_c(char* cmd, char** argv, int argc) | ||
552 | 609 | if(rcode == RCODE_BREAK) { |
553 | 610 | fprintf(stderr, "invalid break. Not in a loop\n"); |
554 | 611 | } |
555 | - else if(rcode == RCODE_RETURN) { | |
612 | + else if(rcode & RCODE_RETURN) { | |
556 | 613 | fprintf(stderr, "invalid return. Not in a function\n"); |
557 | 614 | } |
558 | 615 | else if(rcode == RCODE_EXIT) { |
@@ -86,13 +86,16 @@ static char* message_completion(const char* text, int stat) | ||
86 | 86 | string_push_back(candidate, key); |
87 | 87 | |
88 | 88 | if(TYPE(item) == T_UOBJECT) { |
89 | - vector_add(gCompletionArray, string_c_str(candidate)); | |
90 | - | |
91 | - sObject* candidate2 = STRING_NEW_STACK(string_c_str(messages)); | |
92 | - string_push_back(candidate2, key); | |
93 | - string_push_back(candidate2, "::"); | |
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, "::"); | |
94 | 96 | |
95 | - vector_add(gCompletionArray, string_c_str(candidate2)); | |
97 | + vector_add(gCompletionArray, string_c_str(candidate2)); | |
98 | + } | |
96 | 99 | } |
97 | 100 | else { |
98 | 101 | vector_add(gCompletionArray, string_c_str(candidate)); |
@@ -282,7 +285,9 @@ static char* user_completion(const char* text, int stat) | ||
282 | 285 | |
283 | 286 | if(!strncmp(text, candidate, wordlen)) { |
284 | 287 | int l = strlen(candidate); |
285 | - if(l > 2 && candidate[l-2] == ':' && candidate[l-1] == ':') { | |
288 | + if((l > 2 && candidate[l-2] == ':' && candidate[l-1] == ':' ) | |
289 | + || (l > 1 && candidate[l-1] == '/') ) | |
290 | + { | |
286 | 291 | rl_completion_append_character = 0; |
287 | 292 | } |
288 | 293 | else { |
@@ -476,7 +481,6 @@ static sObject* access_object_compl(char* name, sObject** current) | ||
476 | 481 | } |
477 | 482 | } |
478 | 483 | |
479 | - | |
480 | 484 | char** readline_on_complete(const char* text, int start, int end) |
481 | 485 | { |
482 | 486 | stack_start_stack(); |
@@ -753,6 +757,24 @@ BOOL cmd_readline_clear_screen(sObject* nextin, sObject* nextout, sRunInfo* runi | ||
753 | 757 | return TRUE; |
754 | 758 | } |
755 | 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 | + | |
756 | 778 | BOOL cmd_readline_point_move(sObject* nextin, sObject* nextout, sRunInfo* runinfo) |
757 | 779 | { |
758 | 780 | if(runinfo->mArgsNumRuntime == 2) { |
@@ -772,8 +794,8 @@ BOOL cmd_readline_point_move(sObject* nextin, sObject* nextout, sRunInfo* runinf | ||
772 | 794 | |
773 | 795 | BOOL cmd_readline_insert_text(sObject* nextin, sObject* nextout, sRunInfo* runinfo) |
774 | 796 | { |
775 | - if(runinfo->mFilter) { | |
776 | - (void)rl_insert_text(SFD(nextin).mBuf); | |
797 | + if(runinfo->mArgsNumRuntime == 2) { | |
798 | + (void)rl_insert_text(runinfo->mArgsRuntime[1]); | |
777 | 799 | puts(""); |
778 | 800 | rl_forced_update_display(); |
779 | 801 |
@@ -805,6 +827,24 @@ BOOL cmd_readline_delete_text(sObject* nextin, sObject* nextout, sRunInfo* runin | ||
805 | 827 | return TRUE; |
806 | 828 | } |
807 | 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 | + | |
808 | 848 | BOOL cmd_readline_read_history(sObject* nextin, sObject* nextout, sRunInfo* runinfo) |
809 | 849 | { |
810 | 850 | if(runinfo->mArgsNumRuntime == 2) { |
@@ -827,6 +867,18 @@ BOOL cmd_readline_write_history(sObject* nextin, sObject* nextout, sRunInfo* run | ||
827 | 867 | return TRUE; |
828 | 868 | } |
829 | 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 | + | |
830 | 882 | static int readline_macro(int count, int key) |
831 | 883 | { |
832 | 884 | stack_start_stack(); |
@@ -853,7 +905,7 @@ static int readline_macro(int count, int key) | ||
853 | 905 | if(rcode == RCODE_BREAK) { |
854 | 906 | fprintf(stderr, "invalid break. Not in a loop\n"); |
855 | 907 | } |
856 | - else if(rcode == RCODE_RETURN) { | |
908 | + else if(rcode & RCODE_RETURN) { | |
857 | 909 | fprintf(stderr, "invalid return. Not in a function\n"); |
858 | 910 | } |
859 | 911 | else if(rcode == RCODE_EXIT) { |
@@ -880,53 +932,6 @@ static int readline_macro(int count, int key) | ||
880 | 932 | return 0; |
881 | 933 | } |
882 | 934 | |
883 | -static int skip_quoted(const char *s, int i, char q) | |
884 | -{ | |
885 | - while(s[i] && s[i]!=q) | |
886 | - { | |
887 | - if(s[i]=='\\' && s[i+1]) i++; | |
888 | - i++; | |
889 | - } | |
890 | - if(s[i]) i++; | |
891 | - return i; | |
892 | -} | |
893 | - | |
894 | -static int lftp_char_is_quoted(const char *string, int eindex) | |
895 | -{ | |
896 | - int i, pass_next; | |
897 | - | |
898 | - for (i = pass_next = 0; i <= eindex; i++) | |
899 | - { | |
900 | - if (pass_next) | |
901 | - { | |
902 | - pass_next = 0; | |
903 | - if (i >= eindex) | |
904 | - return 1; | |
905 | - continue; | |
906 | - } | |
907 | - else if (string[i] == '"' || string[i] == '\'') | |
908 | - { | |
909 | - char quote = string[i]; | |
910 | - i = skip_quoted (string, ++i, quote); | |
911 | - if (i > eindex) | |
912 | - return 1; | |
913 | - i--; | |
914 | - } | |
915 | - else if (string[i] == '\\') | |
916 | - { | |
917 | - pass_next = 1; | |
918 | - continue; | |
919 | - } | |
920 | - } | |
921 | - return (0); | |
922 | -} | |
923 | - | |
924 | -char* readline_filename_completion_null_generator(const char* a, int b) | |
925 | -{ | |
926 | - return NULL; | |
927 | -} | |
928 | - | |
929 | - | |
930 | 935 | enum { COMPLETE_DQUOTE,COMPLETE_SQUOTE,COMPLETE_BSQUOTE }; |
931 | 936 | #define completion_quoting_style COMPLETE_BSQUOTE |
932 | 937 |
@@ -946,16 +951,16 @@ double_quote (char *string) | ||
946 | 951 | { |
947 | 952 | switch (c) |
948 | 953 | { |
949 | - case '$': | |
950 | - case '`': | |
951 | - if(!shell_cmd) | |
952 | - goto def; | |
953 | - case '"': | |
954 | - case '\\': | |
955 | - *r++ = '\\'; | |
956 | - default: def: | |
957 | - *r++ = c; | |
958 | - break; | |
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; | |
959 | 964 | } |
960 | 965 | } |
961 | 966 |
@@ -980,11 +985,11 @@ single_quote (char *string) | ||
980 | 985 | *r++ = c; |
981 | 986 | |
982 | 987 | if (c == '\'') |
983 | - { | |
984 | - *r++ = '\\'; // insert escaped single quote | |
985 | - *r++ = '\''; | |
986 | - *r++ = '\''; // start new quoted string | |
987 | - } | |
988 | + { | |
989 | + *r++ = '\\'; // insert escaped single quote | |
990 | + *r++ = '\''; | |
991 | + *r++ = '\''; // start new quoted string | |
992 | + } | |
988 | 993 | } |
989 | 994 | |
990 | 995 | *r++ = '\''; |
@@ -994,7 +999,7 @@ single_quote (char *string) | ||
994 | 999 | } |
995 | 1000 | |
996 | 1001 | static BOOL quote_glob; |
997 | -static BOOL inhibit_tilde; | |
1002 | +//static BOOL inhibit_tilde = 0; | |
998 | 1003 | |
999 | 1004 | static char * |
1000 | 1005 | backslash_quote (char *string) |
@@ -1007,36 +1012,43 @@ backslash_quote (char *string) | ||
1007 | 1012 | for (r = result, s = string; s && (c = *s); s++) |
1008 | 1013 | { |
1009 | 1014 | switch (c) |
1010 | - { | |
1011 | - case '(': case ')': | |
1012 | - case '{': case '}': // reserved words | |
1013 | - case '^': | |
1014 | - case '$': case '`': // expansion chars | |
1015 | - if(!shell_cmd) | |
1016 | - goto def; | |
1017 | - case '*': case '[': case '?': case ']': //globbing chars | |
1018 | - if(!shell_cmd && !quote_glob) | |
1019 | - goto def; | |
1020 | - case ' ': case '\t': case '\n': // IFS white space | |
1021 | - case '"': case '\'': case '\\': // quoting chars | |
1022 | - case '|': case '&': case ';': // shell metacharacters | |
1023 | - case '<': case '>': case '!': | |
1024 | - *r++ = '\\'; | |
1025 | - *r++ = c; | |
1026 | - break; | |
1027 | - case '~': // tilde expansion | |
1028 | - if (s == string && inhibit_tilde) | |
1029 | - *r++ = '.', *r++ = '/'; | |
1030 | - goto def; | |
1031 | - case '#': // comment char | |
1032 | - if(!shell_cmd) | |
1033 | - goto def; | |
1034 | - if (s == string) | |
1035 | - *r++ = '\\'; | |
1036 | - default: def: | |
1037 | - *r++ = c; | |
1038 | - break; | |
1039 | - } | |
1015 | + { | |
1016 | + case '(': case ')': | |
1017 | + case '{': case '}': // reserved words | |
1018 | + case '^': | |
1019 | + case '$': case '`': // expansion chars | |
1020 | + case '*': case '[': case '?': case ']': //globbing chars | |
1021 | + case ' ': case '\t': case '\n': // IFS white space | |
1022 | + case '"': case '\'': case '\\': // quoting chars | |
1023 | + case '|': case '&': case ';': // shell metacharacters | |
1024 | + case '<': case '>': case '!': | |
1025 | + case '%': | |
1026 | + case '#': | |
1027 | + *r++ = '\\'; | |
1028 | + *r++ = c; | |
1029 | + break; | |
1030 | + case '~': // tilde expansion | |
1031 | + //*r++ = '\\'; | |
1032 | + *r++ = c; | |
1033 | + break; | |
1034 | +/* | |
1035 | + if (s == string) { | |
1036 | + goto def; | |
1037 | + | |
1038 | + } | |
1039 | +*/ | |
1040 | + break; | |
1041 | +/* | |
1042 | + case '#': // comment char | |
1043 | + if(!shell_cmd) | |
1044 | + goto def; | |
1045 | + if (s == string) | |
1046 | + *r++ = '\\'; | |
1047 | +*/ | |
1048 | + default: def: | |
1049 | + *r++ = c; | |
1050 | + break; | |
1051 | + } | |
1040 | 1052 | } |
1041 | 1053 | |
1042 | 1054 | *r = '\0'; |
@@ -1054,13 +1066,13 @@ quote_word_break_chars (char *text) | ||
1054 | 1066 | for (s = text, r = ret; *s; s++) |
1055 | 1067 | { |
1056 | 1068 | if (*s == '\\') |
1057 | - { | |
1058 | - *r++ = '\\'; | |
1059 | - *r++ = *++s; | |
1060 | - if (*s == '\0') | |
1061 | - break; | |
1062 | - continue; | |
1063 | - } | |
1069 | + { | |
1070 | + *r++ = '\\'; | |
1071 | + *r++ = *++s; | |
1072 | + if (*s == '\0') | |
1073 | + break; | |
1074 | + continue; | |
1075 | + } | |
1064 | 1076 | if (strchr (rl_completer_word_break_characters, *s)) |
1065 | 1077 | *r++ = '\\'; |
1066 | 1078 | *r++ = *s; |
@@ -1069,37 +1081,90 @@ quote_word_break_chars (char *text) | ||
1069 | 1081 | return ret; |
1070 | 1082 | } |
1071 | 1083 | |
1084 | +static char* | |
1085 | +bash_tilde_expand(char *s) | |
1086 | +{ | |
1087 | +//puts("bash_tilde_expand"); | |
1088 | +//sleep(1); | |
1089 | + char* mtext = malloc(1024); | |
1090 | + char* p = mtext; | |
1091 | + | |
1092 | + s++; // ~ | |
1093 | + | |
1094 | + if(*s == '/') { // ~/ | |
1095 | + s++; | |
1096 | + | |
1097 | + char* home = getenv("HOME"); | |
1098 | + while(*home) { | |
1099 | + *p++ = *home++; | |
1100 | + } | |
1101 | + *p++ = '/'; | |
1102 | + | |
1103 | + while(*s) { | |
1104 | + *p++ = *s++; | |
1105 | + } | |
1106 | + *p = 0; | |
1107 | + } | |
1108 | + else if(*s == 0) { // this may be never runned, paranoia | |
1109 | + *p++ = '~'; | |
1110 | + *p = 0; | |
1111 | + } | |
1112 | + /// ~user/ | |
1113 | + else { | |
1114 | + char* point = strstr(s, "/"); | |
1115 | + if(point) { | |
1116 | + char* user_name = malloc(point -s + 1); | |
1117 | + memcpy(user_name, s, point -s); | |
1118 | + user_name[point -s] = 0; | |
1119 | + | |
1120 | + struct passwd* pwd = getpwnam(user_name); | |
1121 | + | |
1122 | + char* p2 = pwd->pw_dir; | |
1123 | + | |
1124 | + while(*p2) { | |
1125 | + *p++ = *p2++; | |
1126 | + } | |
1127 | + *p++ = '/'; | |
1128 | + | |
1129 | + s = point; | |
1130 | + s++; | |
1131 | + while(*s) { | |
1132 | + *p++ = *s++; | |
1133 | + } | |
1134 | + *p = 0; | |
1135 | + | |
1136 | + free(user_name); | |
1137 | + } | |
1138 | + else { | |
1139 | + *p++ = '~'; | |
1140 | + while(*s) { | |
1141 | + *p++ = *s++; | |
1142 | + } | |
1143 | + *p = 0; | |
1144 | + } | |
1145 | + } | |
1146 | + | |
1147 | + return mtext; | |
1148 | +} | |
1149 | + | |
1072 | 1150 | static char * |
1073 | 1151 | bash_quote_filename (char *s, int rtype, char *qcp) |
1074 | 1152 | { |
1153 | +//puts("bash_quote_filename"); | |
1075 | 1154 | char *rtext, *mtext, *ret; |
1076 | 1155 | int rlen, cs; |
1077 | 1156 | |
1078 | 1157 | rtext = (char *)NULL; |
1079 | 1158 | |
1080 | 1159 | mtext = s; |
1081 | -#if 0 | |
1082 | - if (mtext[0] == '~' && rtype == SINGLE_MATCH) | |
1160 | + if (mtext[0] == '~') // && rtype == SINGLE_MATCH) | |
1083 | 1161 | mtext = bash_tilde_expand (s); |
1084 | -#endif | |
1085 | 1162 | |
1086 | 1163 | cs = completion_quoting_style; |
1087 | 1164 | if (*qcp == '"') |
1088 | 1165 | cs = COMPLETE_DQUOTE; |
1089 | 1166 | else if (*qcp == '\'') |
1090 | 1167 | cs = COMPLETE_SQUOTE; |
1091 | -#if defined (BANG_HISTORY) | |
1092 | - else if (*qcp == '\0' && history_expansion && cs == COMPLETE_DQUOTE && | |
1093 | - history_expansion_inhibited == 0 && strchr (mtext, '!')) | |
1094 | - cs = COMPLETE_BSQUOTE; | |
1095 | - | |
1096 | - if (*qcp == '"' && history_expansion && cs == COMPLETE_DQUOTE && | |
1097 | - history_expansion_inhibited == 0 && strchr (mtext, '!')) | |
1098 | - { | |
1099 | - cs = COMPLETE_BSQUOTE; | |
1100 | - *qcp = '\0'; | |
1101 | - } | |
1102 | -#endif | |
1103 | 1168 | |
1104 | 1169 | switch (cs) |
1105 | 1170 | { |
@@ -1147,12 +1212,12 @@ bash_dequote_filename (const char *text, int quote_char) | ||
1147 | 1212 | for (quoted = quote_char, p = text, r = ret; p && *p; p++) |
1148 | 1213 | { |
1149 | 1214 | if (*p == '\\') |
1150 | - { | |
1151 | - *r++ = *++p; | |
1152 | - if (*p == '\0') | |
1153 | - break; | |
1154 | - continue; | |
1155 | - } | |
1215 | + { | |
1216 | + *r++ = *++p; | |
1217 | + if (*p == '\0') | |
1218 | + break; | |
1219 | + continue; | |
1220 | + } | |
1156 | 1221 | if (quoted && *p == quoted) |
1157 | 1222 | { |
1158 | 1223 | quoted = 0; |
@@ -1169,25 +1234,61 @@ bash_dequote_filename (const char *text, int quote_char) | ||
1169 | 1234 | return ret; |
1170 | 1235 | } |
1171 | 1236 | |
1237 | +static int skip_quoted(const char *s, int i, char q) | |
1238 | +{ | |
1239 | + while(s[i] && s[i]!=q) | |
1240 | + { | |
1241 | + if(s[i]=='\\' && s[i+1]) i++; | |
1242 | + i++; | |
1243 | + } | |
1244 | + if(s[i]) i++; | |
1245 | + return i; | |
1246 | +} | |
1247 | + | |
1248 | +static int lftp_char_is_quoted(const char *string, int eindex) | |
1249 | +{ | |
1250 | + int i, pass_next; | |
1251 | + | |
1252 | + for (i = pass_next = 0; i <= eindex; i++) | |
1253 | + { | |
1254 | + if (pass_next) | |
1255 | + { | |
1256 | + pass_next = 0; | |
1257 | + if (i >= eindex) { | |
1258 | + return 1; | |
1259 | + } | |
1260 | + continue; | |
1261 | + } | |
1262 | + else if (string[i] == '"' || string[i] == '\'') | |
1263 | + { | |
1264 | + char quote = string[i]; | |
1265 | + i = skip_quoted (string, ++i, quote); | |
1266 | + if (i > eindex) { | |
1267 | + return 1; | |
1268 | + } | |
1269 | + i--; | |
1270 | + } | |
1271 | + else if (string[i] == '\\') | |
1272 | + { | |
1273 | + pass_next = 1; | |
1274 | + continue; | |
1275 | + } | |
1276 | + } | |
1277 | + return (0); | |
1278 | +} | |
1279 | + | |
1172 | 1280 | void xyzsh_readline_init(BOOL runtime_script) |
1173 | 1281 | { |
1174 | 1282 | rl_attempted_completion_function = readline_on_complete; |
1175 | -// rl_completion_entry_function = readline_filename_completion_null_generator; | |
1283 | + //rl_completion_entry_function = readline_filename_completion_null_generator; | |
1176 | 1284 | rl_completer_quote_characters = "\"'"; |
1177 | - rl_completer_word_break_characters = " \t\n\"'|!&;()$%<>="; | |
1285 | + rl_completer_word_break_characters = " \t\n\"'|!&;()$<>="; | |
1178 | 1286 | rl_completion_append_character= ' '; |
1179 | - rl_filename_quote_characters = " \t\n\"'|!&;()$%<>:"; | |
1287 | + rl_filename_quote_characters = " \t\n\"'|!&;()$%<>[]~"; | |
1180 | 1288 | rl_filename_quoting_function = bash_quote_filename; |
1181 | 1289 | rl_filename_dequoting_function = (rl_dequote_func_t*)bash_dequote_filename; |
1182 | - | |
1183 | 1290 | rl_char_is_quoted_p = (rl_linebuf_func_t*)lftp_char_is_quoted; |
1184 | 1291 | |
1185 | -/* | |
1186 | - rl_comrl_filename_quote_characters = " \t\n\\'\"()$&|>"; | |
1187 | - rl_completer_quote_characters = " \t\n\\'\"()$&|>"; | |
1188 | - rl_basic_quote_characters = " \t\n\"'|!&;()$"; | |
1189 | -*/ | |
1190 | - | |
1191 | 1292 | rl_bind_key('x'-'a'+1, readline_macro); |
1192 | 1293 | } |
1193 | 1294 |
@@ -0,0 +1,1243 @@ | ||
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 | +} |
@@ -1,5 +1,6 @@ | ||
1 | 1 | #include "config.h" |
2 | 2 | |
3 | +#include <dlfcn.h> | |
3 | 4 | #include <errno.h> |
4 | 5 | #include <stdlib.h> |
5 | 6 | #include <assert.h> |
@@ -31,6 +32,8 @@ static sObject* gRunningObjects; | ||
31 | 32 | |
32 | 33 | sRunInfo* gRunInfoOfRunningObject; |
33 | 34 | |
35 | +sObject* gDynamicLibraryFinals; | |
36 | + | |
34 | 37 | BOOL contained_in_pipe(sObject* object) |
35 | 38 | { |
36 | 39 | BOOL found = FALSE; |
@@ -86,10 +89,22 @@ void run_init(enum eAppType app_type) | ||
86 | 89 | |
87 | 90 | gRunningObjects = VECTOR_NEW_GC(10, FALSE); |
88 | 91 | uobject_put(gXyzshObject, "_running_block", gRunningObjects); |
92 | + | |
93 | + gDynamicLibraryFinals = HASH_NEW_MALLOC(10); | |
89 | 94 | } |
90 | 95 | |
91 | 96 | void run_final() |
92 | 97 | { |
98 | + hash_it* it = hash_loop_begin(gDynamicLibraryFinals); | |
99 | + while(it) { | |
100 | + int (*func)() = hash_loop_item(it); | |
101 | + if(func() != 0) { | |
102 | + fprintf(stderr, "false in finalize"); | |
103 | + } | |
104 | + | |
105 | + it = hash_loop_next(it); | |
106 | + } | |
107 | + hash_delete_on_malloc(gDynamicLibraryFinals); | |
93 | 108 | } |
94 | 109 | |
95 | 110 | sObject* job_new_on_gc(char* name, pid_t pgroup, struct termios tty) |
@@ -678,7 +693,10 @@ BOOL run_function(sObject* fun, sObject* nextin, sObject* nextout, sRunInfo* run | ||
678 | 693 | int rcode = 0; |
679 | 694 | |
680 | 695 | if(!run(SFUN(fun).mBlock, nextin, nextout, &rcode, runinfo->mCurrentObject, fun)) { |
681 | - if(rcode != RCODE_RETURN) { | |
696 | + if(rcode & RCODE_RETURN) { | |
697 | + rcode = rcode & 0xff; | |
698 | + } | |
699 | + else { | |
682 | 700 | char buf[BUFSIZ]; |
683 | 701 | err_msg_adding("run time error", runinfo->mSName, runinfo->mSLine, command->mArgs[0]); |
684 | 702 | runinfo->mRCode = rcode; |
@@ -728,7 +746,7 @@ static BOOL run_completion(sObject* compl, sObject* nextin, sObject* nextout, sR | ||
728 | 746 | if(!run(SCOMPLETION(compl).mBlock, nextin, nextout, &rcode, gRootObject, fun)) { |
729 | 747 | if(rcode == RCODE_BREAK) { |
730 | 748 | } |
731 | - else if(rcode == RCODE_RETURN) { | |
749 | + else if(rcode & RCODE_RETURN) { | |
732 | 750 | } |
733 | 751 | else if(rcode == RCODE_EXIT) { |
734 | 752 | } |
@@ -1682,7 +1700,6 @@ BOOL load_file(char* fname, sObject* nextin, sObject* nextout, sRunInfo* runinfo | ||
1682 | 1700 | sCommand* command = runinfo->mCommand; |
1683 | 1701 | err_msg("signal interrupt16", runinfo->mSName, runinfo->mSLine, command->mArgs[0]); |
1684 | 1702 | runinfo->mRCode = RCODE_SIGNAL_INTERRUPT; |
1685 | - FREE(buf); | |
1686 | 1703 | close(fd); |
1687 | 1704 | return FALSE; |
1688 | 1705 | } |
@@ -1734,3 +1751,61 @@ BOOL load_file(char* fname, sObject* nextin, sObject* nextout, sRunInfo* runinfo | ||
1734 | 1751 | |
1735 | 1752 | return TRUE; |
1736 | 1753 | } |
1754 | + | |
1755 | +BOOL load_so_file(char* fname, sObject* nextin, sObject* nextout, sRunInfo* runinfo) | |
1756 | +{ | |
1757 | + sCommand* command = runinfo->mCommand; | |
1758 | + | |
1759 | + char path[PATH_MAX]; | |
1760 | + snprintf(path, PATH_MAX, "%s%s", EXTDIR, fname); | |
1761 | + | |
1762 | + if(access(path, X_OK) != 0) { | |
1763 | + char* home = getenv("HOME"); | |
1764 | + if(home) { | |
1765 | + snprintf(path, PATH_MAX, "%s/.xyzsh/lib/%s", home, fname); | |
1766 | + if(access(path, X_OK) != 0) { | |
1767 | + xstrncpy(path, fname, PATH_MAX); | |
1768 | + } | |
1769 | + } | |
1770 | + else { | |
1771 | + xstrncpy(path, fname, PATH_MAX); | |
1772 | + } | |
1773 | + } | |
1774 | + | |
1775 | + if(hash_item(gDynamicLibraryFinals, path) == NULL) { | |
1776 | + void* handle = dlopen(path, RTLD_LAZY); | |
1777 | + | |
1778 | + if(handle == NULL) { | |
1779 | + err_msg(dlerror(), runinfo->mSName, runinfo->mSLine, command->mArgs[0]); | |
1780 | + return FALSE; | |
1781 | + } | |
1782 | + | |
1783 | + int (*init_func)() = dlsym(handle, "dl_init"); | |
1784 | + int (*final_func)() = dlsym(handle, "dl_final"); | |
1785 | + if(init_func == NULL || final_func == NULL) { | |
1786 | + err_msg("not found dl_init or dl_final", runinfo->mSName, runinfo->mSLine, command->mArgs[0]); | |
1787 | + dlclose(handle); | |
1788 | + return FALSE; | |
1789 | + } | |
1790 | + | |
1791 | + if(init_func(NULL) != 0) { | |
1792 | + err_msg("false in initialize the dynamic library", runinfo->mSName, runinfo->mSLine, command->mArgs[0]); | |
1793 | + dlclose(handle); | |
1794 | + return FALSE; | |
1795 | + } | |
1796 | + | |
1797 | + hash_put(gDynamicLibraryFinals, path, final_func); | |
1798 | + | |
1799 | + //dlclose(handle); | |
1800 | + | |
1801 | + snprintf(path, PATH_MAX, "%s.xyzsh", path); | |
1802 | + if(access(path, F_OK) == 0) { | |
1803 | + if(!load_file(path, nextin, nextout, runinfo, NULL, 0)) { | |
1804 | + return FALSE; | |
1805 | + } | |
1806 | + } | |
1807 | + } | |
1808 | + | |
1809 | + return TRUE; | |
1810 | +} | |
1811 | + |
@@ -115,12 +115,15 @@ void uobject_root_init(sObject* self) | ||
115 | 115 | uobject_init(readline); |
116 | 116 | uobject_put(self, "rl", readline); |
117 | 117 | |
118 | + uobject_put(readline, "file_name_completion_null_generator", NFUN_NEW_GC(cmd_readline_file_name_completion_null_generator, NULL, TRUE)); | |
118 | 119 | uobject_put(readline, "insert_text", NFUN_NEW_GC(cmd_readline_insert_text, NULL, TRUE)); |
119 | 120 | uobject_put(readline, "delete_text", NFUN_NEW_GC(cmd_readline_delete_text, NULL, TRUE)); |
120 | 121 | uobject_put(readline, "clear_screen", NFUN_NEW_GC(cmd_readline_clear_screen, NULL, TRUE)); |
121 | 122 | uobject_put(readline, "point_move", NFUN_NEW_GC(cmd_readline_point_move, NULL, TRUE)); |
122 | 123 | uobject_put(readline, "read_history", NFUN_NEW_GC(cmd_readline_read_history, NULL, TRUE)); |
123 | 124 | uobject_put(readline, "write_history", NFUN_NEW_GC(cmd_readline_write_history, NULL, TRUE)); |
125 | + uobject_put(readline, "replace_line", NFUN_NEW_GC(cmd_readline_replace_line, NULL, TRUE)); | |
126 | + uobject_put(readline, "point", NFUN_NEW_GC(cmd_readline_point, NULL, TRUE)); | |
124 | 127 | uobject_put(self, "completion", NFUN_NEW_GC(cmd_completion, NULL, TRUE)); |
125 | 128 | uobject_put(self, "p", NFUN_NEW_GC(cmd_p, NULL, TRUE)); |
126 | 129 | uobject_put(self, "jobs", NFUN_NEW_GC(cmd_jobs, NULL, TRUE)); |
@@ -229,9 +232,6 @@ void uobject_root_init(sObject* self) | ||
229 | 232 | uobject_put(self, "sort", NFUN_NEW_GC(cmd_sort, NULL, TRUE)); |
230 | 233 | uobject_put(self, "readline", NFUN_NEW_GC(cmd_readline, NULL, TRUE)); |
231 | 234 | uobject_put(self, "kanjicode", NFUN_NEW_GC(cmd_kanjicode, NULL, TRUE)); |
232 | -#if defined(HAVE_MIGEMO_H) | |
233 | - uobject_put(self, "migemo_match", NFUN_NEW_GC(cmd_migemo_match, NULL, TRUE)); | |
234 | -#endif | |
235 | 235 | |
236 | 236 | uobject_put(self, "sub", NFUN_NEW_GC(cmd_sub, NULL, TRUE)); |
237 | 237 | uobject_put(self, "time", NFUN_NEW_GC(cmd_time, NULL, TRUE)); |
@@ -35,7 +35,7 @@ void xyzsh_read_rc_core(char* path) | ||
35 | 35 | fprintf(stderr, "invalid break. Not in a loop\n"); |
36 | 36 | exit(1); |
37 | 37 | } |
38 | - else if(runinfo.mRCode == RCODE_RETURN) { | |
38 | + else if(runinfo.mRCode & RCODE_RETURN) { | |
39 | 39 | fprintf(stderr, "invalid return. Not in a function\n"); |
40 | 40 | exit(1); |
41 | 41 | } |
@@ -88,6 +88,8 @@ void xyzsh_init(enum eAppType app_type, BOOL no_runtime_script) | ||
88 | 88 | setenv("XYZSH_VERSION", "1.3.3", 1); |
89 | 89 | setenv("XYZSH_DOCDIR", DOCDIR, 1); |
90 | 90 | setenv("XYZSH_DATAROOTDIR", DOCDIR, 1); |
91 | + setenv("XYZSH_EXT_PATH", EXTDIR, 1); | |
92 | + setenv("XYZSH_SYSCONFDIR", SYSCONFDIR, 1); | |
91 | 93 | |
92 | 94 | setlocale(LC_ALL, ""); |
93 | 95 |
@@ -121,10 +123,6 @@ void xyzsh_init(enum eAppType app_type, BOOL no_runtime_script) | ||
121 | 123 | exit(1); |
122 | 124 | } |
123 | 125 | |
124 | -#if defined(HAVE_MIGEMO_H) | |
125 | - migemo_init(); | |
126 | -#endif | |
127 | - | |
128 | 126 | if(!no_runtime_script) { |
129 | 127 | xyzsh_read_rc(); |
130 | 128 | readline_read_history(); |
@@ -134,9 +132,6 @@ void xyzsh_init(enum eAppType app_type, BOOL no_runtime_script) | ||
134 | 132 | void xyzsh_final() |
135 | 133 | { |
136 | 134 | readline_write_history(); |
137 | -#if defined(HAVE_MIGEMO_H) | |
138 | - migemo_final(); | |
139 | -#endif | |
140 | 135 | |
141 | 136 | mcurses_final(); |
142 | 137 | run_final(); |
@@ -567,6 +567,9 @@ BOOL cmd_objinfo(sObject* nextin, sObject* nextout, sRunInfo* runinfo); | ||
567 | 567 | BOOL cmd_kanjicode(sObject* nextin, sObject* nextout, sRunInfo* runinfo); |
568 | 568 | BOOL cmd_defined(sObject* nextin, sObject* nextout, sRunInfo* runinfo); |
569 | 569 | BOOL cmd_funinfo(sObject* nextin, sObject* nextout, sRunInfo* runinfo); |
570 | +BOOL cmd_readline_file_name_completion_null_generator(sObject* nextin, sObject* nextout, sRunInfo* runinfo); | |
571 | +BOOL cmd_readline_replace_line(sObject* nextin, sObject* nextout, sRunInfo* runinfo); | |
572 | +BOOL cmd_readline_point(sObject* nextin, sObject* nextout, sRunInfo* runinfo); | |
570 | 573 | BOOL cmd_readline_read_history(sObject* nextin, sObject* nextout, sRunInfo* runinfo); |
571 | 574 | BOOL cmd_readline_write_history(sObject* nextin, sObject* nextout, sRunInfo* runinfo); |
572 | 575 | BOOL cmd_readline_point_move(sObject* nextin, sObject* nextout, sRunInfo* runinfo); |
@@ -729,13 +732,13 @@ BOOL gc_valid_object(sObject* object); | ||
729 | 732 | |
730 | 733 | BOOL parse(char* p, char* sname, int* sline, sObject* block, sObject** current_object); |
731 | 734 | |
732 | -#define RCODE_BREAK 256 | |
733 | -#define RCODE_RETURN 257 | |
734 | -#define RCODE_EXIT 258 | |
735 | -#define RCODE_SIGNAL_INTERRUPT 259 | |
736 | -#define RCODE_NFUN_FALSE 260 | |
737 | -#define RCODE_NFUN_INVALID_USSING 261 | |
738 | -#define RCODE_NFUN_NULL_INPUT 262 | |
735 | +#define RCODE_BREAK 0x100 | |
736 | +#define RCODE_RETURN 0x200 | |
737 | +#define RCODE_EXIT 0x400 | |
738 | +#define RCODE_SIGNAL_INTERRUPT 0x800 | |
739 | +#define RCODE_NFUN_FALSE 0x1000 | |
740 | +#define RCODE_NFUN_INVALID_USSING 0x2000 | |
741 | +#define RCODE_NFUN_NULL_INPUT 0x4000 | |
739 | 742 | //#define RCODE_COMMAND_NOT_FOUND 262 |
740 | 743 | |
741 | 744 | void xyzsh_kill_all_jobs(); |
@@ -753,6 +756,7 @@ extern sRunInfo* gRunInfoOfRunningObject; | ||
753 | 756 | BOOL bufsiz_write(int fd, char* buf, int buf_len); |
754 | 757 | |
755 | 758 | BOOL load_file(char* fname, sObject* nextin, sObject* nextout, sRunInfo* runinfo, char** argv, int argc); |
759 | +BOOL load_so_file(char* fname, sObject* nextin, sObject* nextout, sRunInfo* runinfo); | |
756 | 760 | |
757 | 761 | int object_gc_children_mark(sObject* self); |
758 | 762 |
@@ -783,11 +787,6 @@ void xyzsh_read_rc_core(char* path); | ||
783 | 787 | void run_init(enum eAppType app_type); |
784 | 788 | void run_final(); |
785 | 789 | |
786 | -#if defined(HAVE_MIGEMO_H) | |
787 | -void migemo_init(); | |
788 | -void migemo_final(); | |
789 | -#endif | |
790 | - | |
791 | 790 | extern sObject* gPrompt; |
792 | 791 | extern sObject* gDirStack; |
793 | 792 |
@@ -815,6 +814,7 @@ BOOL xyzsh_readline_interface_onetime(int* rcode, char* cmdline, int cursor_poin | ||
815 | 814 | char* xyzsh_job_title(int n); |
816 | 815 | int xyzsh_job_num(); |
817 | 816 | BOOL xyzsh_run(int* rcode, sObject* block, char* source_name, fXyzshJobDone xyzsh_job_done_, sObject* nextin, sObject* nextout, int argc, char** argv, sObject* current_object); |
817 | +BOOL xyzsh_eval(int* rcode, char* cmd, char* source_name, fXyzshJobDone xyzsh_job_done_, sObject* nextin, sObject* nextout, int argc, char** argv, sObject* current_object); | |
818 | 818 | |
819 | 819 | void err_msg(char* msg, char* sname, int line, char* command); |
820 | 820 | void err_msg_adding(char* msg, char* sname, int line, char* command); |
@@ -64,11 +64,13 @@ EOS > ~/.xyzsh/menu | ||
64 | 64 | eval $(cat ~/.xyzsh/menu | selector | chomp) |
65 | 65 | ) |
66 | 66 | |
67 | +# when pressing CTRL-X on cmdline, this is called | |
67 | 68 | def macro ( |
68 | 69 | if(! print ~/.xyzsh/macro | -e) ( |
69 | 70 | print <<<EOS |
70 | 71 | whoami | chomp |
71 | 72 | pwd | chomp |
73 | +fselector -multiple | each ( | chomp | quote | pomch ) | join | chomp | |
72 | 74 | EOS > ~/.xyzsh/macro |
73 | 75 | ) |
74 | 76 |
@@ -88,6 +90,28 @@ def times -copy-stackframe ( | ||
88 | 90 | ) |
89 | 91 | ) |
90 | 92 | |
93 | +def max ( | |
94 | + | var -local max_value | |
95 | + | each ( | |
96 | + if(| -gt $max_value) ( | |
97 | + | var -local max_value | |
98 | + ) | |
99 | + ) | |
100 | + | |
101 | + max_value | |
102 | +) | |
103 | + | |
104 | +def min ( | |
105 | + | var -local min_value | |
106 | + | each ( | |
107 | + if(| -lt $min_value ) ( | |
108 | + | var -local min_value | |
109 | + ) | |
110 | + ) | |
111 | + | |
112 | + min_value | |
113 | +) | |
114 | + | |
91 | 115 | # for calling function with the caller-function arguments, options and blocks |
92 | 116 | print <<<'EOS' |
93 | 117 | | eval "| $FUNCTION $(ARGV|each(|chomp|quote|pomch)|join|chomp) $(OPTIONS | each -number 2 (|lines 0 ) | join|chomp) $(block -number | -gt 0 && seq $(block -number|chomp) | each (| - 1 | var num; | block $num | add \a) |chomp | each -La ( | chomp | add -number 0 \( | add -number -1 \)) | join -La)" |