• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
Aucun tag

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

シェルスクリプト言語xyzshのソースコード。


Commit MetaInfo

Révision5503b30d3381b9831ffbc9792e9591e23444e5ea (tree)
l'heure2012-10-26 18:06:01
Auteurab25q <ab25cq@gmai...>
Commiterab25q

Message de Log

v1.1.1 relese

Change Summary

Modification

--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,4 +1,12 @@
11
2+2012 18th Octorber version 1.1.1
3+
4+ add "defined" inner command. see help
5+
6+ add "kanjicode" inner command. see help
7+
8+ fixed help bug
9+
210 2012 18th Octorber version 1.1.0
311
412 fixed break in while loop bug
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
1-Copyright (c) 2012 Yamanaka Gorou
1+Copyright (c) 2012 ab25cq
22
33 Permission is hereby granted, free of charge, to any person obtaining a copy
44 of this software and associated documentation files (the "Software"), to deal
--- a/TODO
+++ b/TODO
@@ -1,4 +1,6 @@
11 +++ 入れたい機能 +++++++++++++++++++++++++++++++++++++++++++++++++++++
2+run_functionなど_stackframeのところがおかしい
3+
24 リファレンスの引数
35
46 オブジェクトの絶対パス
@@ -16,6 +18,8 @@ glob 内部コマンド
1618
1719 $$() $でオプションの内容が入っていたら、オプションとして使う
1820
21+エラーメッセージが分かりにくい
22+
1923 +++ 機能のバグ +++++++++++++++++++++++++++++++++++++++++++++++++++++
2024 エラー出力のリダイレクト
2125
--- a/completion.xyzsh
+++ b/completion.xyzsh
@@ -44,6 +44,10 @@ completion sweep (
4444 hash COMPLETION_OPTIONS -key sweep
4545 )
4646
47+completion defined (
48+ self | egrep -v external\ program\$ | egrep -v native\ function\$ | egrep -v '^root:|^self:|^parent:|^run:'| root::scan '(^.+?):'
49+)
50+
4751 completion var (
4852 self | egrep ': var$' | root::scan '(^.+?):'
4953 hash COMPLETION_OPTIONS -key var
--- a/configure
+++ b/configure
@@ -3042,7 +3042,7 @@ fi
30423042 #####################################################################
30433043 # check operating systems
30443044 #####################################################################
3045-SO_VERSION=1.4.5
3045+SO_VERSION=1.5.0
30463046
30473047 { $as_echo "$as_me:${as_lineno-$LINENO}: checking Operating System" >&5
30483048 $as_echo_n "checking Operating System... " >&6; }
@@ -3205,7 +3205,7 @@ CFLAGS="-DSYSCONFDIR=\"\\\"$sysconfdir/xyzsh/\\\"\" -DDATAROOTDIR=\"\\\"$dataroo
32053205
32063206
32073207
3208-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/memchecker.o src/object.o src/cmd_num.o src/cmd_curses.o"
3208+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/memchecker.o src/object.o src/uobject.o src/cmd_num.o src/cmd_curses.o"
32093209
32103210 #####################################################################
32113211 # ncurses settings
--- a/configure.in
+++ b/configure.in
@@ -189,7 +189,7 @@ CFLAGS="-DSYSCONFDIR=\"\\\"$sysconfdir/xyzsh/\\\"\" -DDATAROOTDIR=\"\\\"$dataroo
189189
190190 AC_SUBST(CFLAGS)
191191
192-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/memchecker.o src/object.o src/cmd_num.o src/cmd_curses.o"
192+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/memchecker.o src/object.o src/uobject.o src/cmd_num.o src/cmd_curses.o"
193193
194194 #####################################################################
195195 # ncurses settings
--- a/help.xyzsh
+++ b/help.xyzsh
@@ -2,16 +2,16 @@ class Help (
22 def set_helps_ja (
33 | chomp | split -multi-line -La \n-\n | each -La -number 2 (
44 | lines -La 0 (
5- | chomp | split | lines 0 (|print) | var -local cmd_name
6- | chomp | var -local cmdline
5+ | chomp | split | lines 0 (|print) | var -local CMD_NAME
6+ | chomp | var -local CMDLINE
77 ) 1 (
8- | chomp | ary -local explain
8+ | chomp | ary -local EXPLAIN
99 )
1010
11- var cmd_name | chomp
11+ var CMD_NAME | chomp
1212 print \a
13- var cmdline | add \n
14- ary explain | chomp
13+ var CMDLINE | add \n
14+ ary EXPLAIN | chomp
1515 print \a
1616 ) | hash -La HELPS.ja
1717 )
@@ -19,16 +19,16 @@ class Help (
1919 def set_helps (
2020 | chomp | split -multi-line -La \n-\n | each -La -number 2 (
2121 | lines -La 0 (
22- | chomp | split | lines 0 (|print) | var -local cmd_name
23- | chomp | var -local cmdline
22+ | chomp | split | lines 0 (|print) | var -local CMD_NAME
23+ | chomp | var -local CMDLINE
2424 ) 1 (
25- | chomp | ary -local explain
25+ | chomp | ary -local EXPLAIN
2626 )
2727
28- var cmd_name | chomp
28+ var CMD_NAME | chomp
2929 print \a
30- var cmdline | add \n
31- ary explain | chomp
30+ var CMDLINE | add \n
31+ ary EXPLAIN | chomp
3232 print \a
3333 ) | hash -La HELPS
3434 )
@@ -71,6 +71,19 @@ class Help (
7171 object help ( Help )
7272
7373 print <<<'EOS'
74+defined オブジェクト
75+-
76+オブジェクトが定義されていたら真を返す
77+-
78+kanjicode
79+-
80+現在の漢字コードを表示する。
81+
82+-byte バイトに設定する
83+-sjis sjisに設定する
84+-eucjp eucjpに設定する
85+-utf8 utf8に設定する
86+-
7487 funinfo
7588 -
7689 実行中の関数もしくはクラスの情報を得る
@@ -913,6 +926,19 @@ EOS | help::set_helps_ja
913926 ### English Help ##################################################
914927
915928 print <<<'EOS'
929+defined (object name)
930+-
931+if object is defined, return true
932+-
933+kanjicode
934+-
935+show language setting
936+
937+-byte change language setting to byte
938+-sjis change language setting to SJIS(for Japanese)
939+-eucjp change language setting to EUCJP(for Japanese)
940+-utf8 change language setting to UTF8
941+-
916942 funinfo
917943 -
918944 output running function or class information.
--- a/src/block.c
+++ b/src/block.c
@@ -270,8 +270,8 @@ static void sCommand_copy_deeply(sCommand* dest, sCommand* src)
270270 }
271271 dest->mArgsRuntime[i] = NULL;
272272 */
273- dest->mArgsRuntime = MALLOC(sizeof(char*)*8);
274- dest->mArgsSizeRuntime = 8;
273+ dest->mArgsRuntime = MALLOC(sizeof(char*)*3);
274+ dest->mArgsSizeRuntime = 3;
275275 dest->mArgsNumRuntime = 0;
276276
277277 dest->mBlocks = MALLOC(sizeof(sObject*)*src->mBlocksSize);
@@ -308,6 +308,8 @@ static void sCommand_copy_deeply(sCommand* dest, sCommand* src)
308308 }
309309 dest->mMessagesNum = src->mMessagesNum;
310310 }
311+
312+ dest->mRedirectsFileNamesRuntime = NULL;
311313 }
312314
313315 static void sCommand_copy_deeply_stack(sCommand* dest, sCommand* src)
@@ -355,8 +357,8 @@ static void sCommand_copy_deeply_stack(sCommand* dest, sCommand* src)
355357 }
356358 dest->mArgsRuntime[i] = NULL;
357359 */
358- dest->mArgsRuntime = MALLOC(sizeof(char*)*8);
359- dest->mArgsSizeRuntime = 8;
360+ dest->mArgsRuntime = MALLOC(sizeof(char*)*3);
361+ dest->mArgsSizeRuntime = 3;
360362 dest->mArgsNumRuntime = 0;
361363
362364 dest->mBlocks = MALLOC(sizeof(sObject*)*src->mBlocksSize);
@@ -394,6 +396,8 @@ static void sCommand_copy_deeply_stack(sCommand* dest, sCommand* src)
394396 }
395397 dest->mMessagesNum = src->mMessagesNum;
396398 }
399+
400+ dest->mRedirectsFileNamesRuntime = NULL;
397401 }
398402
399403 static void sCommand_copy_deeply_malloc(sCommand* dest, sCommand* src)
@@ -441,8 +445,8 @@ static void sCommand_copy_deeply_malloc(sCommand* dest, sCommand* src)
441445 }
442446 dest->mArgsRuntime[i] = NULL;
443447 */
444- dest->mArgsRuntime = MALLOC(sizeof(char*)*8);
445- dest->mArgsSizeRuntime = 8;
448+ dest->mArgsRuntime = MALLOC(sizeof(char*)*3);
449+ dest->mArgsSizeRuntime = 3;
446450 dest->mArgsNumRuntime = 0;
447451
448452 dest->mBlocks = MALLOC(sizeof(sObject*)*src->mBlocksSize);
@@ -480,6 +484,8 @@ static void sCommand_copy_deeply_malloc(sCommand* dest, sCommand* src)
480484 }
481485 dest->mMessagesNum = src->mMessagesNum;
482486 }
487+
488+ dest->mRedirectsFileNamesRuntime = NULL;
483489 }
484490
485491 void sCommand_delete(sCommand* self)
@@ -513,10 +519,13 @@ void sCommand_delete(sCommand* self)
513519
514520 if(self->mBlocks) FREE(self->mBlocks);
515521
516- for(i=0; i<self->mRedirectsNum; i++) {
517- FREE(self->mRedirectsFileNames[i]);
522+ if(self->mRedirectsFileNames) {
523+ for(i=0; i<self->mRedirectsNum; i++) {
524+ FREE(self->mRedirectsFileNames[i]);
525+ }
526+ FREE(self->mRedirectsFileNames);
518527 }
519- if(self->mRedirectsFileNames) FREE(self->mRedirectsFileNames);
528+
520529 if(self->mRedirects) FREE(self->mRedirects);
521530
522531 if(self->mRedirectsFileNamesRuntime) {
@@ -564,10 +573,12 @@ void sCommand_delete_malloc(sCommand* self)
564573 }
565574 if(self->mBlocks) FREE(self->mBlocks);
566575
567- for(i=0; i<self->mRedirectsNum; i++) {
568- FREE(self->mRedirectsFileNames[i]);
576+ if(self->mRedirectsFileNames) {
577+ for(i=0; i<self->mRedirectsNum; i++) {
578+ FREE(self->mRedirectsFileNames[i]);
579+ }
580+ FREE(self->mRedirectsFileNames);
569581 }
570- if(self->mRedirectsFileNames) FREE(self->mRedirectsFileNames);
571582 if(self->mRedirects) FREE(self->mRedirects);
572583
573584 if(self->mRedirectsFileNamesRuntime) {
@@ -672,7 +683,12 @@ static void sStatment_copy_deeply(sStatment* dest, sStatment* source)
672683 sCommand_copy_deeply(dest->mCommands + i, source->mCommands + i);
673684 }
674685
675- dest->mFName = STRDUP(source->mFName);
686+ if(source->mFName) {
687+ dest->mFName = STRDUP(source->mFName);
688+ }
689+ else {
690+ dest->mFName = NULL;
691+ }
676692 dest->mLine = source->mLine;
677693
678694 dest->mFlags = source->mFlags;
@@ -687,7 +703,12 @@ static void sStatment_copy_deeply_stack(sStatment* dest, sStatment* source)
687703 sCommand_copy_deeply_stack(dest->mCommands + i, source->mCommands + i);
688704 }
689705
690- dest->mFName = STRDUP(source->mFName);
706+ if(source->mFName) {
707+ dest->mFName = STRDUP(source->mFName);
708+ }
709+ else {
710+ dest->mFName = NULL;
711+ }
691712 dest->mLine = source->mLine;
692713
693714 dest->mFlags = source->mFlags;
@@ -702,7 +723,12 @@ static void sStatment_copy_deeply_malloc(sStatment* dest, sStatment* source)
702723 sCommand_copy_deeply_malloc(dest->mCommands + i, source->mCommands + i);
703724 }
704725
705- dest->mFName = STRDUP(source->mFName);
726+ if(source->mFName) {
727+ dest->mFName = STRDUP(source->mFName);
728+ }
729+ else {
730+ dest->mFName = NULL;
731+ }
706732 dest->mLine = source->mLine;
707733
708734 dest->mFlags = source->mFlags;
--- a/src/cmd_base.c
+++ b/src/cmd_base.c
@@ -255,10 +255,10 @@ BOOL cmd_stackframe(sObject* nextin, sObject* nextout, sRunInfo* runinfo)
255255 sCommand* command = runinfo->mCommand;
256256 char buf[BUFSIZ];
257257
258- hash_it* it = hash_loop_begin(SFUN(runinfo->mRunningObject).mLocalObjects);
258+ uobject_it* it = uobject_loop_begin(SFUN(runinfo->mRunningObject).mLocalObjects);
259259 while(it) {
260- sObject* object2 = hash_loop_item(it);
261- char* key = hash_loop_key(it);
260+ sObject* object2 = uobject_loop_item(it);
261+ char* key = uobject_loop_key(it);
262262
263263 char*obj_kind[16] = {
264264 NULL, "var", "array", "hash", "list", "native function", "block", "file dicriptor", "job", "object", "memchecker", "function", "class", "external program", "completion", "external object"
@@ -271,10 +271,10 @@ BOOL cmd_stackframe(sObject* nextin, sObject* nextout, sRunInfo* runinfo)
271271 return FALSE;
272272 }
273273
274- it = hash_loop_next(it);
274+ it = uobject_loop_next(it);
275275 }
276276
277- if(hash_count(SFUN(runinfo->mRunningObject).mLocalObjects) == 0) {
277+ if(uobject_count(SFUN(runinfo->mRunningObject).mLocalObjects) == 0) {
278278 runinfo->mRCode = 1;
279279 }
280280 else {
@@ -395,7 +395,7 @@ BOOL cmd_sweep(sObject* nextin, sObject* nextout, sRunInfo* runinfo)
395395 char* var_name = command->mArgsRuntime[i];
396396 sObject* current_object = runinfo->mCurrentObject;
397397
398- sObject* item = hash_item(current_object, var_name);
398+ sObject* item = uobject_item(current_object, var_name);
399399
400400 if(item && item->mUserObject) {
401401 if(item != gCurrentObject || strcmp(var_name, SUOBJECT(item).mName) != 0) {
@@ -673,9 +673,9 @@ static BOOL xyzsh_seek_external_programs(char* path, sObject* sys, char* sname,
673673 && strcmp(entry->d_name, "..") != 0
674674 &&
675675 (stat_.st_mode & S_IXUSR ||stat_.st_mode & S_IXGRP||stat_.st_mode & S_IXOTH)
676- && hash_item(sys, entry->d_name) == NULL)
676+ && uobject_item(sys, entry->d_name) == NULL)
677677 {
678- hash_put(sys, entry->d_name, EXTPROG_NEW_GC(path2, TRUE));
678+ uobject_put(sys, entry->d_name, EXTPROG_NEW_GC(path2, TRUE));
679679 }
680680 }
681681
@@ -700,7 +700,7 @@ BOOL xyzsh_rehash(char* sname, int sline)
700700 }
701701
702702 sObject* sys = UOBJECT_NEW_GC(8, gRootObject, "sys", FALSE);
703- hash_put(gRootObject, "sys", sys);
703+ uobject_put(gRootObject, "sys", sys);
704704 uobject_init(sys);
705705
706706 char buf[PATH_MAX+1];
@@ -798,7 +798,7 @@ BOOL cmd_prompt(sObject* nextin, sObject* nextout, sRunInfo* runinfo)
798798 sCommand* command = runinfo->mCommand;
799799 if(command->mBlocksNum == 1) {
800800 gPrompt = block_clone_gc(command->mBlocks[0], T_BLOCK, FALSE);
801- hash_put(gxyzshObject, "_prompt", gPrompt);
801+ uobject_put(gxyzshObject, "_prompt", gPrompt);
802802 runinfo->mRCode = 0;
803803 }
804804
@@ -870,3 +870,85 @@ BOOL cmd_block(sObject* nextin, sObject* nextout, sRunInfo* runinfo)
870870
871871 return TRUE;
872872 }
873+
874+BOOL cmd_kanjicode(sObject* nextin, sObject* nextout, sRunInfo* runinfo)
875+{
876+ sCommand* command = runinfo->mCommand;
877+
878+ if(sCommand_option_item(command, "-byte")) {
879+ gKanjiCode = kByte;
880+ runinfo->mRCode = 0;
881+ }
882+ else if(sCommand_option_item(command, "-utf8")) {
883+ gKanjiCode = kUtf8;
884+ runinfo->mRCode = 0;
885+ }
886+ else if(sCommand_option_item(command, "-sjis")) {
887+ gKanjiCode = kSjis;
888+ runinfo->mRCode = 0;
889+ }
890+ else if(sCommand_option_item(command, "-eucjp")) {
891+ gKanjiCode = kEucjp;
892+ runinfo->mRCode = 0;
893+ }
894+ else {
895+ if(gKanjiCode == kUtf8) {
896+ if(!fd_write(nextout, "utf8", 4)) {
897+ err_msg("interrupt", runinfo->mSName, runinfo->mSLine, command->mArgs[0]);
898+ runinfo->mRCode = RCODE_SIGNAL_INTERRUPT;
899+ return FALSE;
900+ }
901+ if(!fd_write(nextout, "\n", 1)) {
902+ err_msg("interrupt", runinfo->mSName, runinfo->mSLine, command->mArgs[0]);
903+ runinfo->mRCode = RCODE_SIGNAL_INTERRUPT;
904+ return FALSE;
905+ }
906+
907+ runinfo->mRCode = 0;
908+ }
909+ else if(gKanjiCode == kByte) {
910+ if(!fd_write(nextout, "byte", 4)) {
911+ err_msg("interrupt", runinfo->mSName, runinfo->mSLine, command->mArgs[0]);
912+ runinfo->mRCode = RCODE_SIGNAL_INTERRUPT;
913+ return FALSE;
914+ }
915+ if(!fd_write(nextout, "\n", 1)) {
916+ err_msg("interrupt", runinfo->mSName, runinfo->mSLine, command->mArgs[0]);
917+ runinfo->mRCode = RCODE_SIGNAL_INTERRUPT;
918+ return FALSE;
919+ }
920+
921+ runinfo->mRCode = 0;
922+ }
923+ else if(gKanjiCode == kSjis) {
924+ if(!fd_write(nextout, "sjis", 4)) {
925+ err_msg("interrupt", runinfo->mSName, runinfo->mSLine, command->mArgs[0]);
926+ runinfo->mRCode = RCODE_SIGNAL_INTERRUPT;
927+ return FALSE;
928+ }
929+ if(!fd_write(nextout, "\n", 1)) {
930+ err_msg("interrupt", runinfo->mSName, runinfo->mSLine, command->mArgs[0]);
931+ runinfo->mRCode = RCODE_SIGNAL_INTERRUPT;
932+ return FALSE;
933+ }
934+
935+ runinfo->mRCode = 0;
936+ }
937+ else if(gKanjiCode == kEucjp) {
938+ if(!fd_write(nextout, "eucjp", 5)) {
939+ err_msg("interrupt", runinfo->mSName, runinfo->mSLine, command->mArgs[0]);
940+ runinfo->mRCode = RCODE_SIGNAL_INTERRUPT;
941+ return FALSE;
942+ }
943+ if(!fd_write(nextout, "\n", 1)) {
944+ err_msg("interrupt", runinfo->mSName, runinfo->mSLine, command->mArgs[0]);
945+ runinfo->mRCode = RCODE_SIGNAL_INTERRUPT;
946+ return FALSE;
947+ }
948+
949+ runinfo->mRCode = 0;
950+ }
951+ }
952+
953+ return TRUE;
954+}
--- a/src/cmd_condition.c
+++ b/src/cmd_condition.c
@@ -624,25 +624,25 @@ void clear_matching_info_variable()
624624 {
625625 char buf[128];
626626 snprintf(buf, 128, "");
627- hash_put(gRootObject, "MATCH", STRING_NEW_GC(buf, FALSE));
627+ uobject_put(gRootObject, "MATCH", STRING_NEW_GC(buf, FALSE));
628628
629629 snprintf(buf, 128, "");
630- hash_put(gRootObject, "PREMATCH", STRING_NEW_GC(buf, FALSE));
630+ uobject_put(gRootObject, "PREMATCH", STRING_NEW_GC(buf, FALSE));
631631
632632 snprintf(buf, 128, "");
633- hash_put(gRootObject, "POSTMATCH", STRING_NEW_GC(buf, FALSE));
633+ uobject_put(gRootObject, "POSTMATCH", STRING_NEW_GC(buf, FALSE));
634634
635635 snprintf(buf, 128, "");
636- hash_put(gRootObject, "MATCH_NUMBER", STRING_NEW_GC(buf, FALSE));
636+ uobject_put(gRootObject, "MATCH_NUMBER", STRING_NEW_GC(buf, FALSE));
637637
638638 snprintf(buf, 128, "");
639- hash_put(gRootObject, "LAST_MATCH", STRING_NEW_GC(buf, FALSE));
639+ uobject_put(gRootObject, "LAST_MATCH", STRING_NEW_GC(buf, FALSE));
640640
641641 int i;
642642 for(i=0; i<10; i++) {
643643 char name[128];
644644 snprintf(name, 128, "%d", i);
645- hash_put(gRootObject, name, STRING_NEW_GC(buf, FALSE));
645+ uobject_put(gRootObject, name, STRING_NEW_GC(buf, FALSE));
646646 }
647647 }
648648
@@ -690,17 +690,17 @@ BOOL cmd_condition_re(sObject* nextin, sObject* nextout, sRunInfo* runinfo)
690690
691691 if(r2 >= 0) {
692692 if(region->beg[0] > 0) {
693- hash_put(gRootObject, "PREMATCH", STRING_NEW_GC3(target, region->beg[0], FALSE));
693+ uobject_put(gRootObject, "PREMATCH", STRING_NEW_GC3(target, region->beg[0], FALSE));
694694 }
695695
696696 const int size = region->end[0] - region->beg[0];
697697
698- hash_put(gRootObject, "MATCH", STRING_NEW_GC3(target + region->beg[0], size, FALSE));
699- hash_put(gRootObject, "0", STRING_NEW_GC3(target + region->beg[0], size, FALSE));
698+ uobject_put(gRootObject, "MATCH", STRING_NEW_GC3(target + region->beg[0], size, FALSE));
699+ uobject_put(gRootObject, "0", STRING_NEW_GC3(target + region->beg[0], size, FALSE));
700700
701701 const int n = strlen(target)-region->end[0];
702702 if(n > 0) {
703- hash_put(gRootObject, "POSTMATCH", STRING_NEW_GC3(target + region->end[0], n, FALSE));
703+ uobject_put(gRootObject, "POSTMATCH", STRING_NEW_GC3(target + region->end[0], n, FALSE));
704704 }
705705
706706 int i;
@@ -710,7 +710,7 @@ BOOL cmd_condition_re(sObject* nextin, sObject* nextout, sRunInfo* runinfo)
710710 char name[16];
711711 snprintf(name, 16, "%d", i);
712712
713- hash_put(gRootObject, name, STRING_NEW_GC3(target + region->beg[i], size, FALSE));
713+ uobject_put(gRootObject, name, STRING_NEW_GC3(target + region->beg[i], size, FALSE));
714714 }
715715
716716 if(region->num_regs > 0) {
@@ -718,12 +718,12 @@ BOOL cmd_condition_re(sObject* nextin, sObject* nextout, sRunInfo* runinfo)
718718
719719 const int size = region->end[n] - region->beg[n];
720720
721- hash_put(gRootObject, "LAST_MATCH", STRING_NEW_GC3(target + region->beg[n], size, FALSE));
721+ uobject_put(gRootObject, "LAST_MATCH", STRING_NEW_GC3(target + region->beg[n], size, FALSE));
722722 }
723723
724724 char buf[128];
725725 snprintf(buf, 128, "%d", region->num_regs);
726- hash_put(gRootObject, "MATCH_NUMBER", STRING_NEW_GC(buf, FALSE));
726+ uobject_put(gRootObject, "MATCH_NUMBER", STRING_NEW_GC(buf, FALSE));
727727
728728 if(verbose) {
729729 int point = str_pointer2kanjipos(code, target, target + r2);
--- a/src/cmd_obj.c
+++ b/src/cmd_obj.c
@@ -29,10 +29,10 @@ BOOL cmd_mshow(sObject* nextin, sObject* nextout, sRunInfo* runinfo)
2929 sCommand* command = runinfo->mCommand;
3030
3131 sObject* object = runinfo->mRecieverObject;
32- hash_it* it = hash_loop_begin(object);
32+ uobject_it* it = uobject_loop_begin(object);
3333 while(it) {
34- sObject* object2 = hash_loop_item(it);
35- char* key = hash_loop_key(it);
34+ sObject* object2 = uobject_loop_item(it);
35+ char* key = uobject_loop_key(it);
3636
3737 char buf[BUFSIZ];
3838 char*obj_kind[16] = {
@@ -46,7 +46,7 @@ BOOL cmd_mshow(sObject* nextin, sObject* nextout, sRunInfo* runinfo)
4646 return FALSE;
4747 }
4848
49- it = hash_loop_next(it);
49+ it = uobject_loop_next(it);
5050 }
5151
5252 runinfo->mRCode = 0;
@@ -64,7 +64,7 @@ static BOOL entry_fun(sObject* nextin, sObject* nextout, sRunInfo* runinfo, sObj
6464 block = fun_clone_from_stack_block_gc(block, TRUE, NULL); // block is a stack object, so change the memory manager from stack to gc
6565
6666 if(sCommand_option_item(command, "-inherit")) {
67- sObject* parent = hash_item(object, command->mArgsRuntime[1]);
67+ sObject* parent = uobject_item(object, command->mArgsRuntime[1]);
6868 if(parent) {
6969 if(type == T_FUN && (TYPE(parent) == T_FUN || TYPE(parent) == T_NFUN)
7070 || type == T_CLASS && TYPE(parent) == T_CLASS)
@@ -127,7 +127,7 @@ static BOOL entry_fun(sObject* nextin, sObject* nextout, sRunInfo* runinfo, sObj
127127 }
128128 }
129129
130- hash_put(object, command->mArgsRuntime[1], block);
130+ uobject_put(object, command->mArgsRuntime[1], block);
131131
132132 return TRUE;
133133 }
@@ -268,6 +268,30 @@ BOOL cmd_class(sObject* nextin, sObject* nextout, sRunInfo* runinfo)
268268 return TRUE;
269269 }
270270
271+BOOL cmd_defined(sObject* nextin, sObject* nextout, sRunInfo* runinfo)
272+{
273+ sCommand* command = runinfo->mCommand;
274+
275+ if(command->mArgsNumRuntime > 1) {
276+ sObject* object = runinfo->mCurrentObject;
277+ int i;
278+ for(i=1; i<command->mArgsNumRuntime; i++) {
279+ sObject* reciever = runinfo->mCurrentObject;
280+ sObject* obj = access_object(command->mArgsRuntime[i], &reciever, runinfo->mRunningObject);
281+
282+ if(obj) {
283+ runinfo->mRCode = 0;
284+ }
285+ else {
286+ runinfo->mRCode = RCODE_NFUN_FALSE;
287+ break;
288+ }
289+ }
290+ }
291+
292+ return TRUE;
293+}
294+
271295 BOOL cmd_inherit(sObject* nextin, sObject* nextout, sRunInfo* runinfo)
272296 {
273297 sCommand* command = runinfo->mCommand;
@@ -474,10 +498,10 @@ BOOL cmd_var(sObject* nextin, sObject* nextout, sRunInfo* runinfo)
474498 if(i-1 < max) {
475499 sObject* new_var = STRING_NEW_GC(vector_item(SFD(nextin).fdbuf.mLines, i-1), TRUE);
476500 string_chomp(new_var);
477- hash_put(object, command->mArgsRuntime[i], new_var);
501+ uobject_put(object, command->mArgsRuntime[i], new_var);
478502 }
479503 else {
480- hash_put(object, command->mArgsRuntime[i], STRING_NEW_GC("", TRUE));
504+ uobject_put(object, command->mArgsRuntime[i], STRING_NEW_GC("", TRUE));
481505 }
482506 }
483507
@@ -514,7 +538,7 @@ BOOL cmd_object(sObject* nextin, sObject* nextout, sRunInfo* runinfo)
514538 int i;
515539 for(i=1; i<command->mArgsNumRuntime; i++) {
516540 sObject* new_object = UOBJECT_NEW_GC(8, object, command->mArgsRuntime[i], TRUE);
517- hash_put(object, command->mArgsRuntime[i], new_object);
541+ uobject_put(object, command->mArgsRuntime[i], new_object);
518542 uobject_init(new_object);
519543
520544 int rcode = 0;
@@ -531,7 +555,7 @@ BOOL cmd_object(sObject* nextin, sObject* nextout, sRunInfo* runinfo)
531555 int i;
532556 for(i=1; i<command->mArgsNumRuntime; i++) {
533557 sObject* new_object = UOBJECT_NEW_GC(8, object, command->mArgsRuntime[i], TRUE);
534- hash_put(object, command->mArgsRuntime[i], new_object);
558+ uobject_put(object, command->mArgsRuntime[i], new_object);
535559 uobject_init(new_object);
536560 runinfo->mRCode = 0;
537561 }
@@ -618,7 +642,7 @@ BOOL cmd_co(sObject* nextin, sObject* nextout, sRunInfo* runinfo)
618642 sCommand* command = runinfo->mCommand;
619643
620644 if(command->mArgsNumRuntime == 2) {
621- sObject* new_current = hash_item(gCurrentObject, command->mArgsRuntime[1]);
645+ sObject* new_current = uobject_item(gCurrentObject, command->mArgsRuntime[1]);
622646 if(new_current && TYPE(new_current) == T_UOBJECT) {
623647 gCurrentObject = new_current;
624648 runinfo->mRCode = 0;
@@ -741,7 +765,7 @@ BOOL cmd_ref(sObject* nextin, sObject* nextout, sRunInfo* runinfo)
741765 int type = memchecker_item(gMemChecker, mem);
742766
743767 if(type >= 0) {
744- hash_put(object, command->mArgsRuntime[i+1], mem);
768+ uobject_put(object, command->mArgsRuntime[i+1], mem);
745769 }
746770 else {
747771 err_msg("invalid adress. it's not memory managed by a xyzsh gabage collecter", runinfo->mSName, runinfo->mSLine, command->mArgs[0]);
@@ -964,7 +988,7 @@ BOOL cmd_ary(sObject* nextin, sObject* nextout, sRunInfo* runinfo)
964988 return FALSE;
965989 }
966990
967- hash_put(object, command->mArgsRuntime[1], new_ary);
991+ uobject_put(object, command->mArgsRuntime[1], new_ary);
968992 for(i=0; i<max; i++) {
969993 sObject* new_var = STRING_NEW_GC(vector_item(SFD(nextin).fdbuf.mLines, i), FALSE);
970994 string_chomp(new_var);
@@ -1172,7 +1196,7 @@ BOOL cmd_hash(sObject* nextin, sObject* nextout, sRunInfo* runinfo)
11721196 return FALSE;
11731197 }
11741198
1175- hash_put(object, command->mArgsRuntime[1], new_hash);
1199+ uobject_put(object, command->mArgsRuntime[1], new_hash);
11761200 sObject* key = STRING_NEW_STACK("");
11771201 for(i=0; i<max; i++) {
11781202 if((i % 2) == 0) {
--- a/src/cmd_str.c
+++ b/src/cmd_str.c
@@ -1177,17 +1177,17 @@ BOOL cmd_sub(sObject* nextin, sObject* nextout, sRunInfo* runinfo)
11771177
11781178 const int size = region->beg[0] - (p - target);
11791179 if(size > 0) {
1180- hash_put(gRootObject, "PREMATCH", STRING_NEW_GC3(p, size, FALSE));
1180+ uobject_put(gRootObject, "PREMATCH", STRING_NEW_GC3(p, size, FALSE));
11811181 }
11821182
11831183 const int size2 = region->end[0] - region->beg[0];
11841184
1185- hash_put(gRootObject, "MATCH", STRING_NEW_GC3(target + region->beg[0], size2, FALSE));
1186- hash_put(gRootObject, "0", STRING_NEW_GC3(target + region->beg[0], size2, FALSE));
1185+ uobject_put(gRootObject, "MATCH", STRING_NEW_GC3(target + region->beg[0], size2, FALSE));
1186+ uobject_put(gRootObject, "0", STRING_NEW_GC3(target + region->beg[0], size2, FALSE));
11871187
11881188 const int n = strlen(target)-region->end[0];
11891189 if(n > 0) {
1190- hash_put(gRootObject, "POSTMATCH", STRING_NEW_GC3(target + region->end[0], n, FALSE));
1190+ uobject_put(gRootObject, "POSTMATCH", STRING_NEW_GC3(target + region->end[0], n, FALSE));
11911191 }
11921192
11931193 int i;
@@ -1197,7 +1197,7 @@ BOOL cmd_sub(sObject* nextin, sObject* nextout, sRunInfo* runinfo)
11971197 char name[16];
11981198 snprintf(name, 16, "%d", i);
11991199
1200- hash_put(gRootObject, name, STRING_NEW_GC3(target + region->beg[i], size, FALSE));
1200+ uobject_put(gRootObject, name, STRING_NEW_GC3(target + region->beg[i], size, FALSE));
12011201 }
12021202
12031203 if(region->num_regs > 0) {
@@ -1205,12 +1205,12 @@ BOOL cmd_sub(sObject* nextin, sObject* nextout, sRunInfo* runinfo)
12051205
12061206 const int size = region->end[n] - region->beg[n];
12071207
1208- hash_put(gRootObject, "LAST_MATCH", STRING_NEW_GC3(target + region->beg[n], size, FALSE));
1208+ uobject_put(gRootObject, "LAST_MATCH", STRING_NEW_GC3(target + region->beg[n], size, FALSE));
12091209 }
12101210
12111211 char buf[128];
12121212 snprintf(buf, 128, "%d", region->num_regs);
1213- hash_put(gRootObject, "MATCH_NUMBER", STRING_NEW_GC(buf, FALSE));
1213+ uobject_put(gRootObject, "MATCH_NUMBER", STRING_NEW_GC(buf, FALSE));
12141214
12151215 fd_clear(nextin2);
12161216 fd_clear(nextout2);
@@ -1358,7 +1358,7 @@ BOOL cmd_sub(sObject* nextin, sObject* nextout, sRunInfo* runinfo)
13581358
13591359 char buf[128];
13601360 snprintf(buf, 128, "%d", sub_count);
1361- hash_put(gRootObject, "SUB_COUNT", STRING_NEW_GC(buf, FALSE));
1361+ uobject_put(gRootObject, "SUB_COUNT", STRING_NEW_GC(buf, FALSE));
13621362
13631363 if(sub_count > 0) {
13641364 if(SFD(nextin).fdbuf.mBufLen == 0) {
@@ -1488,17 +1488,17 @@ BOOL cmd_scan(sObject* nextin, sObject* nextout, sRunInfo* runinfo)
14881488
14891489 const int size = region->beg[0] - (p - target);
14901490 if(size > 0) {
1491- hash_put(gRootObject, "PREMATCH", STRING_NEW_GC3(p, size, FALSE));
1491+ uobject_put(gRootObject, "PREMATCH", STRING_NEW_GC3(p, size, FALSE));
14921492 }
14931493
14941494 const int size2 = region->end[0] - region->beg[0];
14951495
1496- hash_put(gRootObject, "MATCH", STRING_NEW_GC3(target + region->beg[0], size2, FALSE));
1497- hash_put(gRootObject, "0", STRING_NEW_GC3(target + region->beg[0], size2, FALSE));
1496+ uobject_put(gRootObject, "MATCH", STRING_NEW_GC3(target + region->beg[0], size2, FALSE));
1497+ uobject_put(gRootObject, "0", STRING_NEW_GC3(target + region->beg[0], size2, FALSE));
14981498
14991499 const int n = strlen(target)-region->end[0];
15001500 if(n > 0) {
1501- hash_put(gRootObject, "POSTMATCH", STRING_NEW_GC3(target + region->end[0], n, FALSE));
1501+ uobject_put(gRootObject, "POSTMATCH", STRING_NEW_GC3(target + region->end[0], n, FALSE));
15021502 }
15031503
15041504 int i;
@@ -1508,7 +1508,7 @@ BOOL cmd_scan(sObject* nextin, sObject* nextout, sRunInfo* runinfo)
15081508 char name[16];
15091509 snprintf(name, 16, "%d", i);
15101510
1511- hash_put(gRootObject, name, STRING_NEW_GC3(target + region->beg[i], size, FALSE));
1511+ uobject_put(gRootObject, name, STRING_NEW_GC3(target + region->beg[i], size, FALSE));
15121512 }
15131513
15141514 if(region->num_regs > 0) {
@@ -1516,12 +1516,12 @@ BOOL cmd_scan(sObject* nextin, sObject* nextout, sRunInfo* runinfo)
15161516
15171517 const int size = region->end[n] - region->beg[n];
15181518
1519- hash_put(gRootObject, "LAST_MATCH", STRING_NEW_GC3(target + region->beg[n], size, FALSE));
1519+ uobject_put(gRootObject, "LAST_MATCH", STRING_NEW_GC3(target + region->beg[n], size, FALSE));
15201520 }
15211521
15221522 char buf[128];
15231523 snprintf(buf, 128, "%d", region->num_regs);
1524- hash_put(gRootObject, "MATCH_NUMBER", STRING_NEW_GC(buf, FALSE));
1524+ uobject_put(gRootObject, "MATCH_NUMBER", STRING_NEW_GC(buf, FALSE));
15251525
15261526 int rcode = 0;
15271527 if(!run(block, nextin2, nextout, &rcode, runinfo->mCurrentObject, runinfo->mRunningObject)) {
@@ -1600,7 +1600,7 @@ BOOL cmd_scan(sObject* nextin, sObject* nextout, sRunInfo* runinfo)
16001600
16011601 char buf[128];
16021602 snprintf(buf, 128, "%d", match_count);
1603- hash_put(gRootObject, "MATCH_COUNT", STRING_NEW_GC(buf, FALSE));
1603+ uobject_put(gRootObject, "MATCH_COUNT", STRING_NEW_GC(buf, FALSE));
16041604
16051605 if(match_count > 0) {
16061606 if(SFD(nextin).fdbuf.mBufLen == 0) {
--- a/src/gc.c
+++ b/src/gc.c
@@ -200,17 +200,18 @@ void gc_init(int pool_size)
200200 gCompletionObject = UOBJECT_NEW_GC(8, gRootObject, "compl", FALSE);
201201 uobject_init(gCompletionObject);
202202
203- hash_put(gRootObject, "compl", gCompletionObject);
203+ uobject_put(gRootObject, "compl", gCompletionObject);
204204
205205 gxyzshObject = UOBJECT_NEW_GC(8, NULL, "xyzsh", FALSE);
206206 gStackFrames = VECTOR_NEW_GC(8, FALSE);
207- hash_put(gxyzshObject, "_stackframes", gStackFrames);
207+ uobject_put(gxyzshObject, "_stackframes", gStackFrames);
208208 }
209209
210210 void gc_final()
211211 {
212212 /// sweep all user objects ///
213- hash_clear(gRootObject);
213+ uobject_clear(gRootObject);
214+ uobject_clear(gxyzshObject);
214215 if(gAppType == kATConsoleApp) {
215216 printf("sweeped %d objects...\n", gc_sweep());
216217 }
--- a/src/hash.c
+++ b/src/hash.c
@@ -1,6 +1,7 @@
11 #include "config.h"
22 #include <stdio.h>
33 #include <string.h>
4+#include <assert.h>
45 #include "xyzsh/xyzsh.h"
56
67 hash_it* hash_it_new(char* key, void* item, hash_it* coll_it, hash_it* next_it, sObject* hash)
@@ -92,6 +93,7 @@ sObject* hash_new_from_stack(int size)
9293
9394 void hash_delete_gc(sObject* self)
9495 {
96+ assert(TYPE(self) == T_HASH);
9597 hash_it* it = SHASH(self).mEntryIt;
9698
9799 while(it) {
@@ -105,6 +107,7 @@ void hash_delete_gc(sObject* self)
105107
106108 void hash_delete_stack(sObject* self)
107109 {
110+ assert(TYPE(self) == T_HASH);
108111 hash_it* it = SHASH(self).mEntryIt;
109112
110113 while(it) {
@@ -118,6 +121,7 @@ void hash_delete_stack(sObject* self)
118121
119122 void hash_delete_malloc(sObject* self)
120123 {
124+ assert(TYPE(self) == T_HASH);
121125 hash_it* it = SHASH(self).mEntryIt;
122126
123127 while(it) {
@@ -133,6 +137,8 @@ void hash_delete_malloc(sObject* self)
133137
134138 static unsigned int get_hash_value(sObject* self, char* key)
135139 {
140+ assert(TYPE(self) == T_HASH);
141+
136142 unsigned int i = 0;
137143 while(*key) {
138144 i += *key;
@@ -144,6 +150,7 @@ static unsigned int get_hash_value(sObject* self, char* key)
144150
145151 static void resize(sObject* self)
146152 {
153+ assert(TYPE(self) == T_HASH);
147154 const int table_size = SHASH(self).mTableSize;
148155
149156 SHASH(self).mTableSize *= 5;
@@ -165,6 +172,8 @@ static void resize(sObject* self)
165172
166173 void hash_put(sObject* self, char* key, void* item)
167174 {
175+ assert(TYPE(self) == T_HASH);
176+
168177 if(SHASH(self).mCounter >= SHASH(self).mTableSize) {
169178 resize(self);
170179 }
@@ -190,6 +199,7 @@ void hash_put(sObject* self, char* key, void* item)
190199
191200 static void erase_from_list(sObject* self, hash_it* rit)
192201 {
202+ assert(TYPE(self) == T_HASH);
193203 if(rit == SHASH(self).mEntryIt) {
194204 SHASH(self).mEntryIt = rit->mNextIt;
195205 }
@@ -209,6 +219,7 @@ static void erase_from_list(sObject* self, hash_it* rit)
209219
210220 BOOL hash_erase(sObject* self, char* key)
211221 {
222+ assert(TYPE(self) == T_HASH);
212223 const unsigned int hash_value = get_hash_value(self, key);
213224 hash_it* it = SHASH(self).mTable[hash_value];
214225
@@ -249,6 +260,7 @@ BOOL hash_erase(sObject* self, char* key)
249260
250261 void hash_clear(sObject* self)
251262 {
263+ assert(TYPE(self) == T_HASH);
252264 int i;
253265 int max;
254266 hash_it* it = SHASH(self).mEntryIt;
@@ -267,6 +279,7 @@ void hash_clear(sObject* self)
267279
268280 void hash_replace(sObject* self, char* key, void* item)
269281 {
282+ assert(TYPE(self) == T_HASH);
270283 hash_it* it = SHASH(self).mTable[get_hash_value(self, key)];
271284
272285 if(it) {
@@ -283,6 +296,8 @@ void hash_replace(sObject* self, char* key, void* item)
283296
284297 void hash_show(sObject* self, char* fname)
285298 {
299+ assert(TYPE(self) == T_HASH);
300+
286301 char tmp[8096];
287302 int i;
288303 int max;
@@ -318,6 +333,8 @@ void hash_show(sObject* self, char* fname)
318333
319334 void* hash_item(sObject* self, char* key)
320335 {
336+ assert(TYPE(self) == T_HASH);
337+
321338 hash_it* it = SHASH(self).mTable[ get_hash_value(self, key) ];
322339
323340 while(it) {
@@ -330,6 +347,8 @@ void* hash_item(sObject* self, char* key)
330347
331348 void* hash_item_addr(sObject* self, char* key)
332349 {
350+ assert(TYPE(self) == T_HASH);
351+
333352 hash_it* it = SHASH(self).mTable[ get_hash_value(self, key) ];
334353 while(it) {
335354 if(strcmp(key, it->mKey) == 0) return &it->mItem;
@@ -341,6 +360,8 @@ void* hash_item_addr(sObject* self, char* key)
341360
342361 char* hash_key(sObject* self, void* item)
343362 {
363+ assert(TYPE(self) == T_HASH);
364+
344365 hash_it* it = SHASH(self).mEntryIt;
345366
346367 while(it) {
@@ -353,16 +374,37 @@ char* hash_key(sObject* self, void* item)
353374
354375 int hash_count(sObject* self)
355376 {
377+ assert(TYPE(self) == T_HASH);
378+
356379 return SHASH(self).mCounter;
357380 }
358381
359-hash_it* hash_loop_begin(sObject* self) { return SHASH(self).mEntryIt; }
360-void* hash_loop_item(hash_it* it) { return it->mItem; }
361-char* hash_loop_key(hash_it* it) { return it->mKey; }
362-hash_it* hash_loop_next(hash_it* it) { return it->mNextIt; }
382+hash_it* hash_loop_begin(sObject* self)
383+{
384+ assert(TYPE(self) == T_HASH);
385+
386+ return SHASH(self).mEntryIt;
387+}
388+
389+void* hash_loop_item(hash_it* it)
390+{
391+ return it->mItem;
392+}
393+
394+char* hash_loop_key(hash_it* it)
395+{
396+ return it->mKey;
397+}
398+
399+hash_it* hash_loop_next(hash_it* it)
400+{
401+ return it->mNextIt;
402+}
363403
364404 int hash_gc_children_mark(sObject* self)
365405 {
406+ assert(TYPE(self) == T_HASH);
407+
366408 int count = 0;
367409
368410 hash_it* it = SHASH(self).mEntryIt;
--- a/src/interface.c
+++ b/src/interface.c
@@ -93,6 +93,7 @@ static char* prompt()
9393 char* buf = readline(SFD(nextout).fdbuf.mBuf);
9494
9595 (void)vector_pop_back(gStackFrames);
96+
9697 stack_end_stack();
9798
9899 return buf;
@@ -118,13 +119,12 @@ BOOL xyzsh_run(int* rcode, sObject* block, char* source_name, fXyzshJobDone xyzs
118119 for(i=0; i<argc; i++) {
119120 vector_add(argv2, STRING_NEW_GC(argv[i], FALSE));
120121 }
121- hash_put(SFUN(fun).mLocalObjects, "ARGV", argv2);
122+ uobject_put(SFUN(fun).mLocalObjects, "ARGV", argv2);
122123
123124 SFUN(fun).mRunInfo = NULL;
124125
125126 if(!run(block, nextin, nextout, rcode, current_object, fun)) {
126127 xyzsh_restore_signal_default();
127-
128128 (void)vector_pop_back(gStackFrames);
129129
130130 stack_end_stack();
@@ -137,7 +137,6 @@ BOOL xyzsh_run(int* rcode, sObject* block, char* source_name, fXyzshJobDone xyzs
137137 xyzsh_restore_signal_default();
138138
139139 (void)vector_pop_back(gStackFrames);
140-
141140 stack_end_stack();
142141
143142 /// wait background job
@@ -286,15 +285,13 @@ BOOL xyzsh_readline_interface_onetime(int* rcode, char* cmdline, int cursor_poin
286285 for(i=0; i<argc; i++) {
287286 vector_add(argv2, STRING_NEW_GC(argv[i], FALSE));
288287 }
289- hash_put(SFUN(fun).mLocalObjects, "ARGV", argv2);
288+ uobject_put(SFUN(fun).mLocalObjects, "ARGV", argv2);
290289
291290 SFUN(fun).mRunInfo = NULL;
292291
293292 if(!run(block, gStdin, gStdout, rcode, gCurrentObject, fun)) {
294293 xyzsh_restore_signal_default();
295294
296- (void)vector_pop_back(gStackFrames);
297-
298295 if(*rcode == RCODE_BREAK) {
299296 fprintf(stderr, "invalid break. Not in a loop\n");
300297 }
@@ -319,6 +316,7 @@ BOOL xyzsh_readline_interface_onetime(int* rcode, char* cmdline, int cursor_poin
319316 if(*rcode != 0) {
320317 fprintf(stderr, "return code is %d\n", *rcode);
321318 }
319+ (void)vector_pop_back(gStackFrames);
322320 stack_end_stack();
323321
324322 /// wait background job
@@ -328,9 +326,8 @@ BOOL xyzsh_readline_interface_onetime(int* rcode, char* cmdline, int cursor_poin
328326
329327 return FALSE;
330328 }
331- readline_signal();
332-
333329 (void)vector_pop_back(gStackFrames);
330+ readline_signal();
334331 }
335332 else {
336333 xyzsh_restore_signal_default();
@@ -448,7 +445,7 @@ void xyzsh_readline_interface(char* cmdline, int cursor_point, char** argv, int
448445 for(i=0; i<argc; i++) {
449446 vector_add(argv2, STRING_NEW_GC(argv[i], FALSE));
450447 }
451- hash_put(SFUN(fun).mLocalObjects, "ARGV", argv2);
448+ uobject_put(SFUN(fun).mLocalObjects, "ARGV", argv2);
452449
453450 SFUN(fun).mRunInfo = NULL;
454451
@@ -462,7 +459,6 @@ void xyzsh_readline_interface(char* cmdline, int cursor_point, char** argv, int
462459 }
463460 else if(rcode == RCODE_EXIT) {
464461 stack_end_stack();
465- (void)vector_pop_back(gStackFrames);
466462 break;
467463 }
468464 else {
@@ -470,9 +466,8 @@ void xyzsh_readline_interface(char* cmdline, int cursor_point, char** argv, int
470466 fprintf(stderr, "%s", string_c_str(gErrMsg));
471467 }
472468 }
473- readline_signal();
474-
475469 (void)vector_pop_back(gStackFrames);
470+ readline_signal();
476471 }
477472 else {
478473 fprintf(stderr, "parser error\n");
@@ -560,7 +555,7 @@ void xyzsh_opt_c(char* cmd, char** argv, int argc)
560555 for(i=0; i<argc; i++) {
561556 vector_add(argv2, STRING_NEW_GC(argv[i], FALSE));
562557 }
563- hash_put(SFUN(fun).mLocalObjects, "ARGV", argv2);
558+ uobject_put(SFUN(fun).mLocalObjects, "ARGV", argv2);
564559
565560 if(!run(block, gStdin, gStdout, &rcode, gRootObject, fun)) {
566561 if(rcode == RCODE_BREAK) {
@@ -576,8 +571,8 @@ void xyzsh_opt_c(char* cmd, char** argv, int argc)
576571 fprintf(stderr, "%s", string_c_str(gErrMsg));
577572 }
578573 }
579- xyzsh_restore_signal_default();
580574 (void)vector_pop_back(gStackFrames);
575+ xyzsh_restore_signal_default();
581576 }
582577 else {
583578 fprintf(stderr, "parser error\n");
@@ -620,6 +615,6 @@ void xyzsh_add_inner_command(sObject* object, char* name, fXyzshNativeFun comman
620615 }
621616 va_end(args);
622617
623- hash_put(object, name, nfun);
618+ uobject_put(object, name, nfun);
624619 }
625620
--- a/src/object.c
+++ b/src/object.c
@@ -3,272 +3,6 @@
33 #include <string.h>
44 #include <stdio.h>
55
6-sObject* uobject_new_from_gc(int size, sObject* parent, char* name, BOOL user_object)
7-{
8- sObject* self = gc_get_free_object(T_UOBJECT, user_object);
9-
10- SHASH(self).mTableSize = size;
11- SHASH(self).mTable = (hash_it**)MALLOC(sizeof(hash_it*) * size);
12- memset(SHASH(self).mTable, 0, sizeof(hash_it*)*size);
13-
14- SHASH(self).mEntryIt = NULL;
15-
16- SHASH(self).mCounter = 0;
17-
18- if(parent) SUOBJECT(self).mParent = parent; else SUOBJECT(self).mParent = self;
19-
20- SUOBJECT(self).mName = STRDUP(name);
21-
22- return self;
23-}
24-
25-sObject* uobject_new_from_stack(int size, sObject* parent, char* name)
26-{
27- sObject* self = stack_get_free_object(T_UOBJECT);
28-
29- SHASH(self).mTableSize = size;
30- SHASH(self).mTable = (hash_it**)MALLOC(sizeof(hash_it*) * size);
31- memset(SHASH(self).mTable, 0, sizeof(hash_it*)*size);
32-
33- SHASH(self).mEntryIt = NULL;
34-
35- SHASH(self).mCounter = 0;
36-
37- if(parent) SUOBJECT(self).mParent = parent; else SUOBJECT(self).mParent = self;
38-
39- SUOBJECT(self).mName = STRDUP(name);
40-
41- return self;
42-}
43-
44-sObject* gInherit;
45-
46-void uobject_root_init(sObject* self)
47-{
48- hash_put(self, "unset", NFUN_NEW_GC(cmd_unset, NULL, TRUE));
49- sObject* readline = UOBJECT_NEW_GC(8, self, "rl", TRUE);
50- uobject_init(readline);
51- hash_put(self, "rl", readline);
52-
53- hash_put(readline, "insert_text", NFUN_NEW_GC(cmd_readline_insert_text, NULL, TRUE));
54- hash_put(readline, "delete_text", NFUN_NEW_GC(cmd_readline_delete_text, NULL, TRUE));
55- hash_put(readline, "clear_screen", NFUN_NEW_GC(cmd_readline_clear_screen, NULL, TRUE));
56- hash_put(readline, "point_move", NFUN_NEW_GC(cmd_readline_point_move, NULL, TRUE));
57- hash_put(readline, "read_history", NFUN_NEW_GC(cmd_readline_read_history, NULL, TRUE));
58- hash_put(readline, "write_history", NFUN_NEW_GC(cmd_readline_write_history, NULL, TRUE));
59- hash_put(self, "completion", NFUN_NEW_GC(cmd_completion, NULL, TRUE));
60- hash_put(self, "p", NFUN_NEW_GC(cmd_p, NULL, TRUE));
61- hash_put(self, "jobs", NFUN_NEW_GC(cmd_jobs, NULL, TRUE));
62- hash_put(self, "gcinfo", NFUN_NEW_GC(cmd_gcinfo, NULL, TRUE));
63- hash_put(self, "stackinfo", NFUN_NEW_GC(cmd_stackinfo, NULL, TRUE));
64- hash_put(self, "fg", NFUN_NEW_GC(cmd_fg, NULL, TRUE));
65- hash_put(self, "exit", NFUN_NEW_GC(cmd_exit, NULL, TRUE));
66- hash_put(self, "fselector", NFUN_NEW_GC(cmd_fselector, NULL, TRUE));
67- hash_put(self, "sweep", NFUN_NEW_GC(cmd_sweep, NULL, TRUE));
68- hash_put(self, "subshell", NFUN_NEW_GC(cmd_subshell, NULL, TRUE));
69- hash_put(self, "print", NFUN_NEW_GC(cmd_print, NULL, TRUE));
70- hash_put(self, "if", NFUN_NEW_GC(cmd_if, NULL, TRUE));
71- hash_put(self, "break", NFUN_NEW_GC(cmd_break, NULL, TRUE));
72- hash_put(self, "while", NFUN_NEW_GC(cmd_while, NULL, TRUE));
73- hash_put(self, "return", NFUN_NEW_GC(cmd_return, NULL, TRUE));
74- hash_put(self, "rehash", NFUN_NEW_GC(cmd_rehash, NULL, TRUE));
75- hash_put(self, "true", NFUN_NEW_GC(cmd_true, NULL, TRUE));
76- hash_put(self, "false", NFUN_NEW_GC(cmd_false, NULL, TRUE));
77- hash_put(self, "write", NFUN_NEW_GC(cmd_write, NULL, TRUE));
78- hash_put(self, "quote", NFUN_NEW_GC(cmd_quote, NULL, TRUE));
79- hash_put(self, "load", NFUN_NEW_GC(cmd_load, NULL, TRUE));
80- gInherit = NFUN_NEW_GC(cmd_inherit, NULL, TRUE);
81- hash_put(self, "inherit", gInherit);
82- hash_put(self, "eval", NFUN_NEW_GC(cmd_eval, NULL, TRUE));
83- hash_put(self, "object", NFUN_NEW_GC(cmd_object, NULL, TRUE));
84- hash_put(self, "pwo", NFUN_NEW_GC(cmd_pwo, NULL, TRUE));
85- hash_put(self, "co", NFUN_NEW_GC(cmd_co, NULL, TRUE));
86- hash_put(self, "ref", NFUN_NEW_GC(cmd_ref, NULL, TRUE));
87- hash_put(self, "length", NFUN_NEW_GC(cmd_length, NULL, TRUE));
88- hash_put(self, "export", NFUN_NEW_GC(cmd_export, NULL, TRUE));
89- hash_put(self, "x", NFUN_NEW_GC(cmd_x , NULL, TRUE));
90- hash_put(self, "stackframe", NFUN_NEW_GC(cmd_stackframe, NULL, TRUE));
91- hash_put(self, "msleep", NFUN_NEW_GC(cmd_msleep, NULL, TRUE));
92- hash_put(self, "raise", NFUN_NEW_GC(cmd_raise, NULL, TRUE));
93- hash_put(self, "cd", NFUN_NEW_GC(cmd_cd, NULL, TRUE));
94- hash_put(self, "popd", NFUN_NEW_GC(cmd_popd, NULL, TRUE));
95- hash_put(self, "pushd", NFUN_NEW_GC(cmd_pushd, NULL, TRUE));
96- hash_put(self, "block", NFUN_NEW_GC(cmd_block, NULL, TRUE));
97- hash_put(self, "lc", NFUN_NEW_GC(cmd_lc, NULL, TRUE));
98- hash_put(self, "uc", NFUN_NEW_GC(cmd_uc, NULL, TRUE));
99- hash_put(self, "chomp", NFUN_NEW_GC(cmd_chomp, NULL, TRUE));
100- hash_put(self, "chop", NFUN_NEW_GC(cmd_chop, NULL, TRUE));
101- hash_put(self, "pomch", NFUN_NEW_GC(cmd_pomch, NULL, TRUE));
102- hash_put(self, "funinfo", NFUN_NEW_GC(cmd_funinfo, NULL, TRUE));
103- hash_put(self, "printf", NFUN_NEW_GC(cmd_printf, NULL, TRUE));
104- hash_put(self, "join", NFUN_NEW_GC(cmd_join, NULL, TRUE));
105- hash_put(self, "lines", NFUN_NEW_GC(cmd_lines, NULL, TRUE));
106- hash_put(self, "rows", NFUN_NEW_GC(cmd_rows, NULL, TRUE));
107- hash_put(self, "scan", NFUN_NEW_GC(cmd_scan, NULL, TRUE));
108- hash_put(self, "split", NFUN_NEW_GC(cmd_split, NULL, TRUE));
109- hash_put(self, "try", NFUN_NEW_GC(cmd_try, NULL, TRUE));
110- hash_put(self, "errmsg", NFUN_NEW_GC(cmd_errmsg, NULL, TRUE));
111- hash_put(self, "prompt", NFUN_NEW_GC(cmd_prompt, NULL, TRUE));
112-
113- hash_put(self, "-n", NFUN_NEW_GC(cmd_condition_n, NULL, TRUE));
114- hash_put(self, "-z", NFUN_NEW_GC(cmd_condition_z, NULL, TRUE));
115- hash_put(self, "-b", NFUN_NEW_GC(cmd_condition_b, NULL, TRUE));
116- hash_put(self, "-c", NFUN_NEW_GC(cmd_condition_c, NULL, TRUE));
117- hash_put(self, "-d", NFUN_NEW_GC(cmd_condition_d, NULL, TRUE));
118- hash_put(self, "-f", NFUN_NEW_GC(cmd_condition_f, NULL, TRUE));
119- hash_put(self, "-h", NFUN_NEW_GC(cmd_condition_h, NULL, TRUE));
120- hash_put(self, "-L", NFUN_NEW_GC(cmd_condition_l, NULL, TRUE));
121- hash_put(self, "-p", NFUN_NEW_GC(cmd_condition_p, NULL, TRUE));
122- hash_put(self, "-t", NFUN_NEW_GC(cmd_condition_t, NULL, TRUE));
123- hash_put(self, "-S", NFUN_NEW_GC(cmd_condition_s2, NULL, TRUE));
124- hash_put(self, "-g", NFUN_NEW_GC(cmd_condition_g, NULL, TRUE));
125- hash_put(self, "-k", NFUN_NEW_GC(cmd_condition_k, NULL, TRUE));
126- hash_put(self, "-u", NFUN_NEW_GC(cmd_condition_u, NULL, TRUE));
127- hash_put(self, "-r", NFUN_NEW_GC(cmd_condition_r, NULL, TRUE));
128- hash_put(self, "-w", NFUN_NEW_GC(cmd_condition_w, NULL, TRUE));
129- hash_put(self, "-x", NFUN_NEW_GC(cmd_condition_x, NULL, TRUE));
130- hash_put(self, "-O", NFUN_NEW_GC(cmd_condition_o, NULL, TRUE));
131- hash_put(self, "-G", NFUN_NEW_GC(cmd_condition_g2, NULL, TRUE));
132- hash_put(self, "-e", NFUN_NEW_GC(cmd_condition_e, NULL, TRUE));
133- hash_put(self, "-s", NFUN_NEW_GC(cmd_condition_s, NULL, TRUE));
134- hash_put(self, "=", NFUN_NEW_GC(cmd_condition_eq, NULL, TRUE));
135- hash_put(self, "!=", NFUN_NEW_GC(cmd_condition_neq, NULL, TRUE));
136- hash_put(self, "-slt", NFUN_NEW_GC(cmd_condition_slt, NULL, TRUE));
137- hash_put(self, "-sgt", NFUN_NEW_GC(cmd_condition_sgt, NULL, TRUE));
138- hash_put(self, "-sle", NFUN_NEW_GC(cmd_condition_sle, NULL, TRUE));
139- hash_put(self, "-sge", NFUN_NEW_GC(cmd_condition_sge, NULL, TRUE));
140- hash_put(self, "-eq", NFUN_NEW_GC(cmd_condition_eq2, NULL, TRUE));
141- hash_put(self, "-ne", NFUN_NEW_GC(cmd_condition_ne, NULL, TRUE));
142- hash_put(self, "-lt", NFUN_NEW_GC(cmd_condition_lt, NULL, TRUE));
143- hash_put(self, "-le", NFUN_NEW_GC(cmd_condition_le, NULL, TRUE));
144- hash_put(self, "-gt", NFUN_NEW_GC(cmd_condition_gt, NULL, TRUE));
145- hash_put(self, "-ge", NFUN_NEW_GC(cmd_condition_ge, NULL, TRUE));
146- hash_put(self, "-nt", NFUN_NEW_GC(cmd_condition_nt, NULL, TRUE));
147- hash_put(self, "-ot", NFUN_NEW_GC(cmd_condition_ot, NULL, TRUE));
148- hash_put(self, "-ef", NFUN_NEW_GC(cmd_condition_ef, NULL, TRUE));
149- hash_put(self, "=~", NFUN_NEW_GC(cmd_condition_re, NULL, TRUE));
150- hash_put(self, "++", NFUN_NEW_GC(cmd_plusplus, NULL, TRUE));
151- hash_put(self, "--", NFUN_NEW_GC(cmd_minusminus, NULL, TRUE));
152- hash_put(self, "+", NFUN_NEW_GC(cmd_plus, NULL, TRUE));
153- hash_put(self, "-", NFUN_NEW_GC(cmd_minus, NULL, TRUE));
154- hash_put(self, "*", NFUN_NEW_GC(cmd_mult, NULL, TRUE));
155- hash_put(self, "/", NFUN_NEW_GC(cmd_div, NULL, TRUE));
156- hash_put(self, "mod", NFUN_NEW_GC(cmd_mod, NULL, TRUE));
157- hash_put(self, "pow", NFUN_NEW_GC(cmd_pow, NULL, TRUE));
158- hash_put(self, "abs", NFUN_NEW_GC(cmd_abs, NULL, TRUE));
159- hash_put(self, "selector", NFUN_NEW_GC(cmd_selector, NULL, TRUE));
160- hash_put(self, "sort", NFUN_NEW_GC(cmd_sort, NULL, TRUE));
161- hash_put(self, "readline", NFUN_NEW_GC(cmd_readline, NULL, TRUE));
162-#if defined(HAVE_MIGEMO_H)
163- hash_put(self, "migemo_match", NFUN_NEW_GC(cmd_migemo_match, NULL, TRUE));
164-#endif
165-
166- hash_put(self, "sub", NFUN_NEW_GC(cmd_sub, NULL, TRUE));
167- hash_put(self, "time", NFUN_NEW_GC(cmd_time, NULL, TRUE));
168-
169- sObject* nfun = NFUN_NEW_GC(cmd_hash, NULL, TRUE);
170- (void)nfun_put_option_with_argument(nfun, STRDUP("-key"));
171- hash_put(self, "hash", nfun);
172- nfun = NFUN_NEW_GC(cmd_ary, NULL, TRUE);
173- (void)nfun_put_option_with_argument(nfun, STRDUP("-index"));
174- (void)nfun_put_option_with_argument(nfun, STRDUP("-append"));
175- hash_put(self, "ary", nfun);
176-
177- nfun = NFUN_NEW_GC(cmd_var, NULL, TRUE);
178- (void)nfun_put_option_with_argument(nfun, STRDUP("-index"));
179- hash_put(self, "var", nfun);
180-
181- nfun = NFUN_NEW_GC(cmd_add, NULL, TRUE);
182- (void)nfun_put_option_with_argument(nfun, STRDUP("-number"));
183- hash_put(self, "add", nfun);
184-
185- nfun = NFUN_NEW_GC(cmd_del, NULL, TRUE);
186- (void)nfun_put_option_with_argument(nfun, STRDUP("-number"));
187- hash_put(self, "del", nfun);
188-
189- nfun = NFUN_NEW_GC(cmd_index, NULL, TRUE);
190- (void)nfun_put_option_with_argument(nfun, STRDUP("-number"));
191- (void)nfun_put_option_with_argument(nfun, STRDUP("-count"));
192- hash_put(self, "index", nfun);
193-
194- nfun = NFUN_NEW_GC(cmd_rindex, NULL, TRUE);
195- (void)nfun_put_option_with_argument(nfun, STRDUP("-number"));
196- (void)nfun_put_option_with_argument(nfun, STRDUP("-count"));
197- hash_put(self, "rindex", nfun);
198-
199- nfun = NFUN_NEW_GC(cmd_each, NULL, TRUE);
200- (void)nfun_put_option_with_argument(nfun, STRDUP("-number"));
201- hash_put(self, "each", nfun);
202-
203- nfun = NFUN_NEW_GC(cmd_def, NULL, TRUE);
204- (void)nfun_put_option_with_argument(nfun, STRDUP("-option-with-argument"));
205- hash_put(self, "def", nfun);
206-
207- nfun = NFUN_NEW_GC(cmd_class, NULL, TRUE);
208- (void)nfun_put_option_with_argument(nfun, STRDUP("-option-with-argument"));
209- hash_put(self, "class", nfun);
210-
211- clear_matching_info_variable();
212-}
213-
214-void uobject_init(sObject* self)
215-{
216- hash_put(self, "run", NFUN_NEW_GC(cmd_mrun, NULL, FALSE));
217- hash_put(self, "self", self);
218- hash_put(self, "root", gRootObject);
219- hash_put(self, "parent", SUOBJECT(self).mParent);
220- hash_put(self, "show", NFUN_NEW_GC(cmd_mshow, NULL, FALSE));
221-}
222-
223-void uobject_delete_gc(sObject* self)
224-{
225- hash_it* it = SHASH(self).mEntryIt;
226-
227- while(it) {
228- hash_it* next_it = it->mNextIt;
229- hash_it_release(it, self);
230- it = next_it;
231- }
232-
233- FREE(SHASH(self).mTable);
234- FREE(SUOBJECT(self).mName);
235-}
236-
237-void uobject_delete_stack(sObject* self)
238-{
239- hash_it* it = SHASH(self).mEntryIt;
240-
241- while(it) {
242- hash_it* next_it = it->mNextIt;
243- hash_it_release(it, self);
244- it = next_it;
245- }
246-
247- FREE(SHASH(self).mTable);
248- FREE(SUOBJECT(self).mName);
249-}
250-
251-int uobject_gc_children_mark(sObject* self)
252-{
253- int count = 0;
254-
255- hash_it* it = SHASH(self).mEntryIt;
256- while(it) {
257- sObject* item = it->mItem;
258-
259- if((item->mFlg & GC_MARK) == 0) {
260- item->mFlg |= GC_MARK;
261- count++;
262-
263- count += object_gc_children_mark(item);
264- }
265-
266- it = it->mNextIt;
267- }
268-
269- return count;
270-}
271-
2726 sObject* nfun_new_from_gc(fXyzshNativeFun fun, sObject* parent, BOOL user_object)
2737 {
2748 sObject* self = gc_get_free_object(T_NFUN, user_object);
@@ -370,12 +104,12 @@ sObject* access_object(char* name, sObject** current, sObject* running_object)
370104 {
371105 sObject* object;
372106 if(running_object) {
373- object = hash_item(SFUN(running_object).mLocalObjects, name);
107+ object = uobject_item(SFUN(running_object).mLocalObjects, name);
374108 if(object) { return object; }
375109 }
376110
377111 while(1) {
378- object = hash_item(*current, name);
112+ object = uobject_item(*current, name);
379113
380114 if(object || *current == gRootObject) { return object; }
381115
@@ -385,10 +119,10 @@ sObject* access_object(char* name, sObject** current, sObject* running_object)
385119
386120 sObject* access_object2(char* name, sObject* current, sObject* running_object)
387121 {
388- sObject* object = hash_item(SFUN(running_object).mLocalObjects, name);
122+ sObject* object = uobject_item(SFUN(running_object).mLocalObjects, name);
389123 if(object) return object;
390124
391- return hash_item(current, name);
125+ return uobject_item(current, name);
392126 }
393127
394128 sObject* access_object3(char* name, sObject** current)
@@ -396,7 +130,7 @@ sObject* access_object3(char* name, sObject** current)
396130 sObject* object;
397131
398132 while(1) {
399- object = hash_item(*current, name);
133+ object = uobject_item(*current, name);
400134
401135 if(object || *current == gRootObject) { return object; }
402136
--- a/src/parser.c
+++ b/src/parser.c
@@ -865,7 +865,7 @@ static BOOL read_command(char** p, sCommand* command, sStatment* statment, sObje
865865 if(object && TYPE(object) == T_UOBJECT) {
866866 int i;
867867 for(i=1; i<command->mMessagesNum; i++) {
868- object = hash_item(object, command->mMessages[i]);
868+ object = uobject_item(object, command->mMessages[i]);
869869
870870 if(object == NULL || TYPE(object) != T_UOBJECT) {
871871 break;
--- a/src/readline.c
+++ b/src/readline.c
@@ -57,7 +57,7 @@ static char* message_completion(const char* text, int stat)
5757 sObject* messages = STRING_NEW_STACK("");
5858
5959 while(1) {
60- object = hash_item(current, command->mMessages[0]);
60+ object = uobject_item(current, command->mMessages[0]);
6161 if(object || current == gRootObject) break;
6262 current = SUOBJECT((current)).mParent;
6363 }
@@ -68,17 +68,17 @@ static char* message_completion(const char* text, int stat)
6868 if(object && TYPE(object) == T_UOBJECT) {
6969 int i;
7070 for(i=1; i<command->mMessagesNum; i++) {
71- object = hash_item(object, command->mMessages[i]);
71+ object = uobject_item(object, command->mMessages[i]);
7272 if(object == NULL || TYPE(object) != T_UOBJECT) break;
7373 string_push_back(messages, command->mMessages[i]);
7474 string_push_back(messages, "::");
7575 }
7676
7777 if(object && TYPE(object) == T_UOBJECT) {
78- hash_it* it = hash_loop_begin(object);
78+ uobject_it* it = uobject_loop_begin(object);
7979 while(it) {
80- char* key = hash_loop_key(it);
81- sObject* item = hash_loop_item(it);
80+ char* key = uobject_loop_key(it);
81+ sObject* item = uobject_loop_item(it);
8282
8383 sObject* candidate = STRING_NEW_STACK(string_c_str(messages));
8484 string_push_back(candidate, key);
@@ -96,7 +96,7 @@ static char* message_completion(const char* text, int stat)
9696 vector_add(gCompletionArray, string_c_str(candidate));
9797 }
9898
99- it = hash_loop_next(it);
99+ it = uobject_loop_next(it);
100100 }
101101
102102 vector_sort(gCompletionArray, name_sort);
@@ -136,21 +136,21 @@ static char* all_program_completion(const char* text, int stat)
136136
137137 sObject* current = gReadlineCurrentObject;
138138 while(1) {
139- hash_it* it = hash_loop_begin(current);
139+ uobject_it* it = uobject_loop_begin(current);
140140 while(it) {
141- char* key = hash_loop_key(it);
142- sObject* object = hash_loop_item(it);
141+ char* key = uobject_loop_key(it);
142+ sObject* object = uobject_loop_item(it);
143143
144144 if(hash_item(hash, key) == NULL) {
145145 hash_put(hash, key, object);
146146
147- sObject* candidate = STRING_NEW_STACK(hash_loop_key(it));
147+ sObject* candidate = STRING_NEW_STACK(uobject_loop_key(it));
148148 if(TYPE(object) == T_UOBJECT) {
149- if(hash_item(object, "main")) {
149+ if(uobject_item(object, "main")) {
150150 vector_add(gCompletionArray, string_c_str(candidate));
151151 }
152152 else {
153- sObject* candidate2 = STRING_NEW_STACK(hash_loop_key(it));
153+ sObject* candidate2 = STRING_NEW_STACK(uobject_loop_key(it));
154154 string_push_back(candidate2, "::");
155155 vector_add(gCompletionArray, string_c_str(candidate2));
156156 }
@@ -160,7 +160,7 @@ static char* all_program_completion(const char* text, int stat)
160160 }
161161 }
162162
163- it = hash_loop_next(it);
163+ it = uobject_loop_next(it);
164164 }
165165
166166 if(current == gRootObject) break;
@@ -193,21 +193,21 @@ static char* program_completion(const char* text, int stat)
193193
194194 sObject* current = gReadlineCurrentObject;
195195 while(1) {
196- hash_it* it = hash_loop_begin(current);
196+ uobject_it* it = uobject_loop_begin(current);
197197 while(it) {
198- char* key = hash_loop_key(it);
199- sObject* object = hash_loop_item(it);
198+ char* key = uobject_loop_key(it);
199+ sObject* object = uobject_loop_item(it);
200200
201201 if(hash_item(hash, key) == NULL) {
202202 hash_put(hash, key, object);
203203
204- sObject* candidate = STRING_NEW_STACK(hash_loop_key(it));
204+ sObject* candidate = STRING_NEW_STACK(uobject_loop_key(it));
205205 if(TYPE(object) == T_UOBJECT) {
206- if(hash_item(object, "main")) {
206+ if(uobject_item(object, "main")) {
207207 vector_add(gCompletionArray, string_c_str(candidate));
208208 }
209209 else {
210- sObject* candidate2 = STRING_NEW_STACK(hash_loop_key(it));
210+ sObject* candidate2 = STRING_NEW_STACK(uobject_loop_key(it));
211211 string_push_back(candidate2, "::");
212212 vector_add(gCompletionArray, string_c_str(candidate2));
213213 }
@@ -217,7 +217,7 @@ static char* program_completion(const char* text, int stat)
217217 }
218218 }
219219
220- it = hash_loop_next(it);
220+ it = uobject_loop_next(it);
221221 }
222222
223223 if(current == gRootObject) break;
@@ -328,23 +328,23 @@ static char* env_completion(const char* text, int stat_)
328328
329329 sObject* current = gReadlineCurrentObject;
330330 while(1) {
331- hash_it* it = hash_loop_begin(current);
331+ uobject_it* it = uobject_loop_begin(current);
332332 while(it) {
333- char* key = hash_loop_key(it);
334- sObject* object = hash_loop_item(it);
333+ char* key = uobject_loop_key(it);
334+ sObject* object = uobject_loop_item(it);
335335
336336 if(hash_item(hash, key) == NULL) {
337337 if(TYPE(object) == T_STRING || TYPE(object) == T_VECTOR || TYPE(object) == T_HASH) {
338338 hash_put(hash, key, object);
339339
340340 sObject* candidate = STRING_NEW_STACK("");
341- string_push_back(candidate, hash_loop_key(it));
341+ string_push_back(candidate, uobject_loop_key(it));
342342
343343 vector_add(gCompletionArray, string_c_str(candidate));
344344 }
345345 }
346346
347- it = hash_loop_next(it);
347+ it = uobject_loop_next(it);
348348 }
349349
350350 if(current == gRootObject) break;
@@ -407,7 +407,7 @@ static void get_current_completion_object(sObject** completion_object, sObject**
407407 if(*current_object != gRootObject) {
408408 sObject* parent_object = SUOBJECT(*current_object).mParent;
409409 get_current_completion_object(completion_object, &parent_object);
410- if(*completion_object) *completion_object = hash_item(*completion_object, SUOBJECT(*current_object).mName);
410+ if(*completion_object) *completion_object = uobject_item(*completion_object, SUOBJECT(*current_object).mName);
411411 }
412412 }
413413
@@ -416,7 +416,7 @@ static sObject* access_object_compl(char* name, sObject** current)
416416 sObject* object;
417417
418418 while(1) {
419- object = hash_item(*current, name);
419+ object = uobject_item(*current, name);
420420
421421 if(object || *current == gCompletionObject) { return object; }
422422
@@ -511,7 +511,7 @@ char** readline_on_complete(const char* text, int start, int end)
511511 int i;
512512 for(i=1; i<command->mMessagesNum; i++) {
513513 if(object && TYPE(object) == T_UOBJECT) {
514- object = hash_item(object, command->mMessages[i]);
514+ object = uobject_item(object, command->mMessages[i]);
515515 }
516516 else {
517517 break;
@@ -519,10 +519,10 @@ char** readline_on_complete(const char* text, int start, int end)
519519 }
520520
521521 if(object && TYPE(object) == T_UOBJECT) {
522- ucompletion = hash_item(object, command->mArgs[0]);
522+ ucompletion = uobject_item(object, command->mArgs[0]);
523523
524524 if(ucompletion == NULL) {
525- ucompletion = hash_item(object, "__all__");;
525+ ucompletion = uobject_item(object, "__all__");;
526526 }
527527 }
528528 else {
@@ -599,7 +599,7 @@ char** readline_on_complete(const char* text, int start, int end)
599599 vector_add(argv, STRING_NEW_GC("", FALSE));
600600 vector_add(argv, STRING_NEW_GC("", FALSE));
601601 }
602- hash_put(SFUN(fun).mLocalObjects, "ARGV", argv);
602+ uobject_put(SFUN(fun).mLocalObjects, "ARGV", argv);
603603
604604 int rcode = 0;
605605 xyzsh_set_signal();
@@ -607,12 +607,12 @@ char** readline_on_complete(const char* text, int start, int end)
607607 readline_signal();
608608 fprintf(stderr, "\nrun time error\n");
609609 fprintf(stderr, "%s", string_c_str(gErrMsg));
610- vector_pop_back(gStackFrames);
610+ (void)vector_pop_back(gStackFrames);
611611 stack_end_stack();
612612 return NULL;
613613 }
614+ (void)vector_pop_back(gStackFrames);
614615 readline_signal();
615- vector_pop_back(gStackFrames);
616616
617617 fd_split(nextout, kLF);
618618
@@ -649,10 +649,10 @@ BOOL cmd_completion(sObject* nextin, sObject* nextout, sRunInfo* runinfo)
649649 }
650650 p+=2;
651651
652- sObject* object2 = hash_item(object, string_c_str(str));
652+ sObject* object2 = uobject_item(object, string_c_str(str));
653653 if(object2 == NULL || TYPE(object2) !=T_UOBJECT) {
654654 sObject* new_object = UOBJECT_NEW_GC(8, object, string_c_str(str), TRUE);
655- hash_put(object, string_c_str(str), new_object);
655+ uobject_put(object, string_c_str(str), new_object);
656656 uobject_init(new_object);
657657
658658 object = new_object;
@@ -668,7 +668,7 @@ BOOL cmd_completion(sObject* nextin, sObject* nextout, sRunInfo* runinfo)
668668 }
669669 }
670670 if(object && TYPE(object) == T_UOBJECT && string_c_str(str)[0] != 0) {
671- hash_put(object, string_c_str(str), COMPLETION_NEW_GC(block, FALSE));
671+ uobject_put(object, string_c_str(str), COMPLETION_NEW_GC(block, FALSE));
672672 }
673673 else {
674674 err_msg("There is no object", runinfo->mSName, runinfo->mSLine, command->mArgsRuntime[i]);
@@ -818,9 +818,9 @@ static int readline_macro(int count, int key)
818818 fprintf(stderr, "%s", string_c_str(gErrMsg));
819819 }
820820 }
821+ (void)vector_pop_back(gStackFrames);
821822 readline_signal();
822823 //xyzsh_restore_signal_default();
823- (void)vector_pop_back(gStackFrames);
824824 }
825825 else {
826826 fprintf(stderr, "parser error\n");
--- a/src/run.c
+++ b/src/run.c
@@ -39,7 +39,7 @@ void run_init(enum eAppType app_type)
3939 gStdout = FD_NEW_STACK(kFDKindBuf, 0);
4040 gStderr = FD_NEW_STACK(kFDKindBuf, 0);
4141 gJobs = VECTOR_NEW_GC(16, FALSE);
42- hash_put(gxyzshObject, "_jobs", gJobs);
42+ uobject_put(gxyzshObject, "_jobs", gJobs);
4343
4444 xyzsh_job_done = NULL;
4545
@@ -811,7 +811,7 @@ BOOL run_function(sObject* fun, sObject* nextin, sObject* nextout, sRunInfo* run
811811 for(i=0; i<argc; i++) {
812812 vector_add(argv2, STRING_NEW_GC(argv[i], FALSE));
813813 }
814- hash_put(SFUN(fun).mLocalObjects, "ARGV", argv2);
814+ uobject_put(SFUN(fun).mLocalObjects, "ARGV", argv2);
815815
816816 sCommand* command = runinfo->mCommand;
817817 sObject* options = HASH_NEW_GC(16, FALSE);
@@ -825,7 +825,7 @@ BOOL run_function(sObject* fun, sObject* nextin, sObject* nextout, sRunInfo* run
825825 }
826826 }
827827 }
828- hash_put(SFUN(fun).mLocalObjects, "OPTIONS", options);
828+ uobject_put(SFUN(fun).mLocalObjects, "OPTIONS", options);
829829
830830 sObject* arg_blocks = SFUN(fun).mArgBlocks;
831831 SFUN(fun).mArgBlocks = VECTOR_NEW_GC(16, FALSE);
@@ -849,10 +849,10 @@ BOOL run_function(sObject* fun, sObject* nextin, sObject* nextout, sRunInfo* run
849849 }
850850 }
851851
852-runinfo->mRCode = rcode;
853-
854852 (void)vector_pop_back(gStackFrames);
855853
854+runinfo->mRCode = rcode;
855+
856856 SFUN(fun).mLocalObjects = local_objects;
857857 SFUN(fun).mArgBlocks = arg_blocks;
858858 SFUN(fun).mRunInfo = runinfo2;
@@ -955,7 +955,7 @@ static BOOL run_object(sObject* object, sObject* nextin, sObject* nextout, sRunI
955955 break;
956956
957957 case T_UOBJECT: {
958- sObject* main_obj = hash_item(object, "main");
958+ sObject* main_obj = uobject_item(object, "main");
959959 runinfo->mRecieverObject = object;
960960
961961 if(main_obj) {
@@ -1254,7 +1254,7 @@ static BOOL statment_tree(sStatment* statment, sObject* pipein, sObject* pipeout
12541254 while(i < command->mMessagesNum) {
12551255 if(object && TYPE(object) == T_UOBJECT) {
12561256 reciever = object;
1257- object = hash_item(object, command->mMessages[i++]);
1257+ object = uobject_item(object, command->mMessages[i++]);
12581258 }
12591259 else {
12601260 err_msg("invalid message passing", runinfo->mSName, runinfo->mSLine, command->mArgs[0]);
@@ -1264,7 +1264,7 @@ static BOOL statment_tree(sStatment* statment, sObject* pipein, sObject* pipeout
12641264
12651265 if(object && TYPE(object) == T_UOBJECT) {
12661266 reciever = object;
1267- object = hash_item(object, command->mArgs[0]);
1267+ object = uobject_item(object, command->mArgs[0]);
12681268
12691269 if(object == gInherit) {
12701270 sObject* running_object = runinfo->mRunningObject;
@@ -1724,7 +1724,7 @@ BOOL load_file(char* fname, sObject* nextin, sObject* nextout, sRunInfo* runinfo
17241724 for(i=0; i<argc; i++) {
17251725 vector_add(argv2, STRING_NEW_GC(argv[i], FALSE));
17261726 }
1727- hash_put(SFUN(fun).mLocalObjects, "ARGV", argv2);
1727+ uobject_put(SFUN(fun).mLocalObjects, "ARGV", argv2);
17281728
17291729 if(!run(block, nextin, nextout, &rcode, runinfo->mCurrentObject, fun))
17301730 {
@@ -1733,22 +1733,21 @@ BOOL load_file(char* fname, sObject* nextin, sObject* nextout, sRunInfo* runinfo
17331733 else {
17341734 runinfo->mRCode = rcode;
17351735
1736- stack_end_stack();
17371736 (void)vector_pop_back(gStackFrames);
1737+ stack_end_stack();
17381738 return FALSE;
17391739 }
17401740 }
1741+ (void)vector_pop_back(gStackFrames);
17411742 }
17421743 else {
17431744 FREE(buf);
17441745 sCommand* command = runinfo->mCommand;
17451746 err_msg_adding("parser error", runinfo->mSName, runinfo->mSLine, "parser");
17461747 stack_end_stack();
1747- (void)vector_pop_back(gStackFrames);
17481748 return FALSE;
17491749 }
17501750
1751- (void)vector_pop_back(gStackFrames);
17521751 stack_end_stack();
17531752
17541753 return TRUE;
--- /dev/null
+++ b/src/uobject.c
@@ -0,0 +1,428 @@
1+#include "config.h"
2+#include "xyzsh/xyzsh.h"
3+#include <string.h>
4+#include <stdio.h>
5+#include <assert.h>
6+
7+static unsigned int get_uobject_value(sObject* self, char* key)
8+{
9+ unsigned int i = 0;
10+ while(*key) {
11+ i += *key;
12+ key++;
13+ }
14+
15+ return i % SUOBJECT(self).mTableSize;
16+}
17+
18+static void resize(sObject* self)
19+{
20+ const int table_size = SUOBJECT(self).mTableSize;
21+
22+ SUOBJECT(self).mTableSize *= 5;
23+ FREE(SUOBJECT(self).mTable);
24+ SUOBJECT(self).mTable = (uobject_it**)MALLOC(sizeof(uobject_it*) * SUOBJECT(self).mTableSize);
25+ memset(SUOBJECT(self).mTable, 0, sizeof(uobject_it*)*SUOBJECT(self).mTableSize);
26+
27+ uobject_it* it = SUOBJECT(self).mEntryIt;
28+ while(it) {
29+ unsigned int uobject_key = get_uobject_value(self, it->mKey);
30+
31+ it->mCollisionIt = SUOBJECT(self).mTable[uobject_key];
32+
33+ SUOBJECT(self).mTable[uobject_key] = it;
34+
35+ it = it->mNextIt;
36+ }
37+}
38+
39+
40+uobject_it* uobject_it_new(char* key, void* item, uobject_it* coll_it, uobject_it* next_it, sObject* hash)
41+{
42+ uobject_it* it = (uobject_it*)MALLOC(sizeof(uobject_it));
43+
44+ it->mKey = STRDUP(key);
45+
46+ it->mItem = item;
47+ it->mCollisionIt = coll_it;
48+
49+ it->mNextIt = next_it;
50+
51+ return it;
52+}
53+
54+void uobject_it_release(uobject_it* it, sObject* hash)
55+{
56+ FREE(it->mKey);
57+
58+ FREE(it);
59+}
60+
61+
62+sObject* uobject_new_from_gc(int size, sObject* parent, char* name, BOOL user_object)
63+{
64+ sObject* self = gc_get_free_object(T_UOBJECT, user_object);
65+
66+ SUOBJECT(self).mTableSize = size;
67+ SUOBJECT(self).mTable = (uobject_it**)MALLOC(sizeof(uobject_it*) * size);
68+ memset(SUOBJECT(self).mTable, 0, sizeof(uobject_it*)*size);
69+
70+ SUOBJECT(self).mEntryIt = NULL;
71+
72+ SUOBJECT(self).mCounter = 0;
73+
74+ if(parent) SUOBJECT(self).mParent = parent; else SUOBJECT(self).mParent = self;
75+
76+ SUOBJECT(self).mName = STRDUP(name);
77+
78+ return self;
79+}
80+
81+sObject* uobject_new_from_stack(int size, sObject* parent, char* name)
82+{
83+ sObject* self = stack_get_free_object(T_UOBJECT);
84+
85+ SUOBJECT(self).mTableSize = size;
86+ SUOBJECT(self).mTable = (uobject_it**)MALLOC(sizeof(uobject_it*) * size);
87+ memset(SUOBJECT(self).mTable, 0, sizeof(uobject_it*)*size);
88+
89+ SUOBJECT(self).mEntryIt = NULL;
90+
91+ SUOBJECT(self).mCounter = 0;
92+
93+ if(parent) SUOBJECT(self).mParent = parent; else SUOBJECT(self).mParent = self;
94+
95+ SUOBJECT(self).mName = STRDUP(name);
96+
97+ return self;
98+}
99+
100+sObject* gInherit;
101+
102+void uobject_root_init(sObject* self)
103+{
104+ assert(TYPE(self) == T_UOBJECT);
105+
106+ uobject_put(self, "unset", NFUN_NEW_GC(cmd_unset, NULL, TRUE));
107+ sObject* readline = UOBJECT_NEW_GC(8, self, "rl", TRUE);
108+ uobject_init(readline);
109+ uobject_put(self, "rl", readline);
110+
111+ uobject_put(readline, "insert_text", NFUN_NEW_GC(cmd_readline_insert_text, NULL, TRUE));
112+ uobject_put(readline, "delete_text", NFUN_NEW_GC(cmd_readline_delete_text, NULL, TRUE));
113+ uobject_put(readline, "clear_screen", NFUN_NEW_GC(cmd_readline_clear_screen, NULL, TRUE));
114+ uobject_put(readline, "point_move", NFUN_NEW_GC(cmd_readline_point_move, NULL, TRUE));
115+ uobject_put(readline, "read_history", NFUN_NEW_GC(cmd_readline_read_history, NULL, TRUE));
116+ uobject_put(readline, "write_history", NFUN_NEW_GC(cmd_readline_write_history, NULL, TRUE));
117+ uobject_put(self, "completion", NFUN_NEW_GC(cmd_completion, NULL, TRUE));
118+ uobject_put(self, "p", NFUN_NEW_GC(cmd_p, NULL, TRUE));
119+ uobject_put(self, "jobs", NFUN_NEW_GC(cmd_jobs, NULL, TRUE));
120+ uobject_put(self, "gcinfo", NFUN_NEW_GC(cmd_gcinfo, NULL, TRUE));
121+ uobject_put(self, "stackinfo", NFUN_NEW_GC(cmd_stackinfo, NULL, TRUE));
122+ uobject_put(self, "fg", NFUN_NEW_GC(cmd_fg, NULL, TRUE));
123+ uobject_put(self, "exit", NFUN_NEW_GC(cmd_exit, NULL, TRUE));
124+ uobject_put(self, "fselector", NFUN_NEW_GC(cmd_fselector, NULL, TRUE));
125+ uobject_put(self, "sweep", NFUN_NEW_GC(cmd_sweep, NULL, TRUE));
126+ uobject_put(self, "subshell", NFUN_NEW_GC(cmd_subshell, NULL, TRUE));
127+ uobject_put(self, "print", NFUN_NEW_GC(cmd_print, NULL, TRUE));
128+ uobject_put(self, "if", NFUN_NEW_GC(cmd_if, NULL, TRUE));
129+ uobject_put(self, "break", NFUN_NEW_GC(cmd_break, NULL, TRUE));
130+ uobject_put(self, "while", NFUN_NEW_GC(cmd_while, NULL, TRUE));
131+ uobject_put(self, "return", NFUN_NEW_GC(cmd_return, NULL, TRUE));
132+ uobject_put(self, "rehash", NFUN_NEW_GC(cmd_rehash, NULL, TRUE));
133+ uobject_put(self, "true", NFUN_NEW_GC(cmd_true, NULL, TRUE));
134+ uobject_put(self, "false", NFUN_NEW_GC(cmd_false, NULL, TRUE));
135+ uobject_put(self, "write", NFUN_NEW_GC(cmd_write, NULL, TRUE));
136+ uobject_put(self, "quote", NFUN_NEW_GC(cmd_quote, NULL, TRUE));
137+ uobject_put(self, "load", NFUN_NEW_GC(cmd_load, NULL, TRUE));
138+ gInherit = NFUN_NEW_GC(cmd_inherit, NULL, TRUE);
139+ uobject_put(self, "inherit", gInherit);
140+ uobject_put(self, "eval", NFUN_NEW_GC(cmd_eval, NULL, TRUE));
141+ uobject_put(self, "object", NFUN_NEW_GC(cmd_object, NULL, TRUE));
142+ uobject_put(self, "pwo", NFUN_NEW_GC(cmd_pwo, NULL, TRUE));
143+ uobject_put(self, "co", NFUN_NEW_GC(cmd_co, NULL, TRUE));
144+ uobject_put(self, "ref", NFUN_NEW_GC(cmd_ref, NULL, TRUE));
145+ uobject_put(self, "length", NFUN_NEW_GC(cmd_length, NULL, TRUE));
146+ uobject_put(self, "export", NFUN_NEW_GC(cmd_export, NULL, TRUE));
147+ uobject_put(self, "x", NFUN_NEW_GC(cmd_x , NULL, TRUE));
148+ uobject_put(self, "stackframe", NFUN_NEW_GC(cmd_stackframe, NULL, TRUE));
149+ uobject_put(self, "msleep", NFUN_NEW_GC(cmd_msleep, NULL, TRUE));
150+ uobject_put(self, "raise", NFUN_NEW_GC(cmd_raise, NULL, TRUE));
151+ uobject_put(self, "cd", NFUN_NEW_GC(cmd_cd, NULL, TRUE));
152+ uobject_put(self, "popd", NFUN_NEW_GC(cmd_popd, NULL, TRUE));
153+ uobject_put(self, "pushd", NFUN_NEW_GC(cmd_pushd, NULL, TRUE));
154+ uobject_put(self, "block", NFUN_NEW_GC(cmd_block, NULL, TRUE));
155+ uobject_put(self, "lc", NFUN_NEW_GC(cmd_lc, NULL, TRUE));
156+ uobject_put(self, "uc", NFUN_NEW_GC(cmd_uc, NULL, TRUE));
157+ uobject_put(self, "chomp", NFUN_NEW_GC(cmd_chomp, NULL, TRUE));
158+ uobject_put(self, "chop", NFUN_NEW_GC(cmd_chop, NULL, TRUE));
159+ uobject_put(self, "pomch", NFUN_NEW_GC(cmd_pomch, NULL, TRUE));
160+ uobject_put(self, "funinfo", NFUN_NEW_GC(cmd_funinfo, NULL, TRUE));
161+ uobject_put(self, "printf", NFUN_NEW_GC(cmd_printf, NULL, TRUE));
162+ uobject_put(self, "join", NFUN_NEW_GC(cmd_join, NULL, TRUE));
163+ uobject_put(self, "lines", NFUN_NEW_GC(cmd_lines, NULL, TRUE));
164+ uobject_put(self, "rows", NFUN_NEW_GC(cmd_rows, NULL, TRUE));
165+ uobject_put(self, "scan", NFUN_NEW_GC(cmd_scan, NULL, TRUE));
166+ uobject_put(self, "split", NFUN_NEW_GC(cmd_split, NULL, TRUE));
167+ uobject_put(self, "try", NFUN_NEW_GC(cmd_try, NULL, TRUE));
168+ uobject_put(self, "errmsg", NFUN_NEW_GC(cmd_errmsg, NULL, TRUE));
169+ uobject_put(self, "prompt", NFUN_NEW_GC(cmd_prompt, NULL, TRUE));
170+ uobject_put(self, "defined", NFUN_NEW_GC(cmd_defined, NULL, TRUE));
171+
172+ uobject_put(self, "-n", NFUN_NEW_GC(cmd_condition_n, NULL, TRUE));
173+ uobject_put(self, "-z", NFUN_NEW_GC(cmd_condition_z, NULL, TRUE));
174+ uobject_put(self, "-b", NFUN_NEW_GC(cmd_condition_b, NULL, TRUE));
175+ uobject_put(self, "-c", NFUN_NEW_GC(cmd_condition_c, NULL, TRUE));
176+ uobject_put(self, "-d", NFUN_NEW_GC(cmd_condition_d, NULL, TRUE));
177+ uobject_put(self, "-f", NFUN_NEW_GC(cmd_condition_f, NULL, TRUE));
178+ uobject_put(self, "-h", NFUN_NEW_GC(cmd_condition_h, NULL, TRUE));
179+ uobject_put(self, "-L", NFUN_NEW_GC(cmd_condition_l, NULL, TRUE));
180+ uobject_put(self, "-p", NFUN_NEW_GC(cmd_condition_p, NULL, TRUE));
181+ uobject_put(self, "-t", NFUN_NEW_GC(cmd_condition_t, NULL, TRUE));
182+ uobject_put(self, "-S", NFUN_NEW_GC(cmd_condition_s2, NULL, TRUE));
183+ uobject_put(self, "-g", NFUN_NEW_GC(cmd_condition_g, NULL, TRUE));
184+ uobject_put(self, "-k", NFUN_NEW_GC(cmd_condition_k, NULL, TRUE));
185+ uobject_put(self, "-u", NFUN_NEW_GC(cmd_condition_u, NULL, TRUE));
186+ uobject_put(self, "-r", NFUN_NEW_GC(cmd_condition_r, NULL, TRUE));
187+ uobject_put(self, "-w", NFUN_NEW_GC(cmd_condition_w, NULL, TRUE));
188+ uobject_put(self, "-x", NFUN_NEW_GC(cmd_condition_x, NULL, TRUE));
189+ uobject_put(self, "-O", NFUN_NEW_GC(cmd_condition_o, NULL, TRUE));
190+ uobject_put(self, "-G", NFUN_NEW_GC(cmd_condition_g2, NULL, TRUE));
191+ uobject_put(self, "-e", NFUN_NEW_GC(cmd_condition_e, NULL, TRUE));
192+ uobject_put(self, "-s", NFUN_NEW_GC(cmd_condition_s, NULL, TRUE));
193+ uobject_put(self, "=", NFUN_NEW_GC(cmd_condition_eq, NULL, TRUE));
194+ uobject_put(self, "!=", NFUN_NEW_GC(cmd_condition_neq, NULL, TRUE));
195+ uobject_put(self, "-slt", NFUN_NEW_GC(cmd_condition_slt, NULL, TRUE));
196+ uobject_put(self, "-sgt", NFUN_NEW_GC(cmd_condition_sgt, NULL, TRUE));
197+ uobject_put(self, "-sle", NFUN_NEW_GC(cmd_condition_sle, NULL, TRUE));
198+ uobject_put(self, "-sge", NFUN_NEW_GC(cmd_condition_sge, NULL, TRUE));
199+ uobject_put(self, "-eq", NFUN_NEW_GC(cmd_condition_eq2, NULL, TRUE));
200+ uobject_put(self, "-ne", NFUN_NEW_GC(cmd_condition_ne, NULL, TRUE));
201+ uobject_put(self, "-lt", NFUN_NEW_GC(cmd_condition_lt, NULL, TRUE));
202+ uobject_put(self, "-le", NFUN_NEW_GC(cmd_condition_le, NULL, TRUE));
203+ uobject_put(self, "-gt", NFUN_NEW_GC(cmd_condition_gt, NULL, TRUE));
204+ uobject_put(self, "-ge", NFUN_NEW_GC(cmd_condition_ge, NULL, TRUE));
205+ uobject_put(self, "-nt", NFUN_NEW_GC(cmd_condition_nt, NULL, TRUE));
206+ uobject_put(self, "-ot", NFUN_NEW_GC(cmd_condition_ot, NULL, TRUE));
207+ uobject_put(self, "-ef", NFUN_NEW_GC(cmd_condition_ef, NULL, TRUE));
208+ uobject_put(self, "=~", NFUN_NEW_GC(cmd_condition_re, NULL, TRUE));
209+ uobject_put(self, "++", NFUN_NEW_GC(cmd_plusplus, NULL, TRUE));
210+ uobject_put(self, "--", NFUN_NEW_GC(cmd_minusminus, NULL, TRUE));
211+ uobject_put(self, "+", NFUN_NEW_GC(cmd_plus, NULL, TRUE));
212+ uobject_put(self, "-", NFUN_NEW_GC(cmd_minus, NULL, TRUE));
213+ uobject_put(self, "*", NFUN_NEW_GC(cmd_mult, NULL, TRUE));
214+ uobject_put(self, "/", NFUN_NEW_GC(cmd_div, NULL, TRUE));
215+ uobject_put(self, "mod", NFUN_NEW_GC(cmd_mod, NULL, TRUE));
216+ uobject_put(self, "pow", NFUN_NEW_GC(cmd_pow, NULL, TRUE));
217+ uobject_put(self, "abs", NFUN_NEW_GC(cmd_abs, NULL, TRUE));
218+ uobject_put(self, "selector", NFUN_NEW_GC(cmd_selector, NULL, TRUE));
219+ uobject_put(self, "sort", NFUN_NEW_GC(cmd_sort, NULL, TRUE));
220+ uobject_put(self, "readline", NFUN_NEW_GC(cmd_readline, NULL, TRUE));
221+ uobject_put(self, "kanjicode", NFUN_NEW_GC(cmd_kanjicode, NULL, TRUE));
222+#if defined(HAVE_MIGEMO_H)
223+ uobject_put(self, "migemo_match", NFUN_NEW_GC(cmd_migemo_match, NULL, TRUE));
224+#endif
225+
226+ uobject_put(self, "sub", NFUN_NEW_GC(cmd_sub, NULL, TRUE));
227+ uobject_put(self, "time", NFUN_NEW_GC(cmd_time, NULL, TRUE));
228+
229+ sObject* nfun = NFUN_NEW_GC(cmd_hash, NULL, TRUE);
230+ (void)nfun_put_option_with_argument(nfun, STRDUP("-key"));
231+ uobject_put(self, "hash", nfun);
232+ nfun = NFUN_NEW_GC(cmd_ary, NULL, TRUE);
233+ (void)nfun_put_option_with_argument(nfun, STRDUP("-index"));
234+ (void)nfun_put_option_with_argument(nfun, STRDUP("-append"));
235+ uobject_put(self, "ary", nfun);
236+
237+ nfun = NFUN_NEW_GC(cmd_var, NULL, TRUE);
238+ (void)nfun_put_option_with_argument(nfun, STRDUP("-index"));
239+ uobject_put(self, "var", nfun);
240+
241+ nfun = NFUN_NEW_GC(cmd_add, NULL, TRUE);
242+ (void)nfun_put_option_with_argument(nfun, STRDUP("-number"));
243+ uobject_put(self, "add", nfun);
244+
245+ nfun = NFUN_NEW_GC(cmd_del, NULL, TRUE);
246+ (void)nfun_put_option_with_argument(nfun, STRDUP("-number"));
247+ uobject_put(self, "del", nfun);
248+
249+ nfun = NFUN_NEW_GC(cmd_index, NULL, TRUE);
250+ (void)nfun_put_option_with_argument(nfun, STRDUP("-number"));
251+ (void)nfun_put_option_with_argument(nfun, STRDUP("-count"));
252+ uobject_put(self, "index", nfun);
253+
254+ nfun = NFUN_NEW_GC(cmd_rindex, NULL, TRUE);
255+ (void)nfun_put_option_with_argument(nfun, STRDUP("-number"));
256+ (void)nfun_put_option_with_argument(nfun, STRDUP("-count"));
257+ uobject_put(self, "rindex", nfun);
258+
259+ nfun = NFUN_NEW_GC(cmd_each, NULL, TRUE);
260+ (void)nfun_put_option_with_argument(nfun, STRDUP("-number"));
261+ uobject_put(self, "each", nfun);
262+
263+ nfun = NFUN_NEW_GC(cmd_def, NULL, TRUE);
264+ (void)nfun_put_option_with_argument(nfun, STRDUP("-option-with-argument"));
265+ uobject_put(self, "def", nfun);
266+
267+ nfun = NFUN_NEW_GC(cmd_class, NULL, TRUE);
268+ (void)nfun_put_option_with_argument(nfun, STRDUP("-option-with-argument"));
269+ uobject_put(self, "class", nfun);
270+
271+ clear_matching_info_variable();
272+}
273+
274+void uobject_init(sObject* self)
275+{
276+ assert(TYPE(self) == T_UOBJECT);
277+
278+ uobject_put(self, "run", NFUN_NEW_GC(cmd_mrun, NULL, FALSE));
279+ uobject_put(self, "self", self);
280+ uobject_put(self, "root", gRootObject);
281+ uobject_put(self, "parent", SUOBJECT(self).mParent);
282+ uobject_put(self, "show", NFUN_NEW_GC(cmd_mshow, NULL, FALSE));
283+}
284+
285+void uobject_delete_gc(sObject* self)
286+{
287+ assert(TYPE(self) == T_UOBJECT);
288+
289+ uobject_it* it = SUOBJECT(self).mEntryIt;
290+
291+ while(it) {
292+ uobject_it* next_it = it->mNextIt;
293+ uobject_it_release(it, self);
294+ it = next_it;
295+ }
296+
297+ FREE(SUOBJECT(self).mTable);
298+ FREE(SUOBJECT(self).mName);
299+}
300+
301+void uobject_delete_stack(sObject* self)
302+{
303+ assert(TYPE(self) == T_UOBJECT);
304+
305+ uobject_it* it = SUOBJECT(self).mEntryIt;
306+
307+ while(it) {
308+ uobject_it* next_it = it->mNextIt;
309+ uobject_it_release(it, self);
310+ it = next_it;
311+ }
312+
313+ FREE(SUOBJECT(self).mTable);
314+ FREE(SUOBJECT(self).mName);
315+}
316+
317+int uobject_gc_children_mark(sObject* self)
318+{
319+ assert(TYPE(self) == T_UOBJECT);
320+
321+ int count = 0;
322+
323+ uobject_it* it = SUOBJECT(self).mEntryIt;
324+ while(it) {
325+ sObject* item = it->mItem;
326+
327+ if((item->mFlg & GC_MARK) == 0) {
328+ item->mFlg |= GC_MARK;
329+ count++;
330+
331+ count += object_gc_children_mark(item);
332+ }
333+
334+ it = it->mNextIt;
335+ }
336+
337+ return count;
338+}
339+
340+void uobject_put(sObject* self, char* key, void* item)
341+{
342+ assert(TYPE(self) == T_UOBJECT);
343+
344+ if(SUOBJECT(self).mCounter >= SUOBJECT(self).mTableSize) {
345+ resize(self);
346+ }
347+
348+ unsigned int uobject_key = get_uobject_value(self, key);
349+
350+ uobject_it* it = SUOBJECT(self).mTable[ uobject_key ];
351+ while(it) {
352+ if(strcmp(key, it->mKey) == 0) {
353+ it->mItem = item;
354+ return;
355+ }
356+ it = it->mCollisionIt;
357+ }
358+
359+ uobject_it* new_it
360+ = uobject_it_new(key, item, SUOBJECT(self).mTable[uobject_key], SUOBJECT(self).mEntryIt, self);
361+
362+ SUOBJECT(self).mTable[uobject_key] = new_it;
363+ SUOBJECT(self).mEntryIt = new_it;
364+ SUOBJECT(self).mCounter++;
365+}
366+
367+void* uobject_item(sObject* self, char* key)
368+{
369+ assert(TYPE(self) == T_UOBJECT);
370+
371+ uobject_it* it = SUOBJECT(self).mTable[ get_uobject_value(self, key) ];
372+
373+ while(it) {
374+ if(strcmp(key, it->mKey) == 0) return it->mItem;
375+ it = it->mCollisionIt;
376+ }
377+
378+ return NULL;
379+}
380+
381+void uobject_clear(sObject* self)
382+{
383+ assert(TYPE(self) == T_UOBJECT);
384+
385+ int i;
386+ int max;
387+ uobject_it* it = SUOBJECT(self).mEntryIt;
388+
389+ while(it) {
390+ uobject_it* next_it = it->mNextIt;
391+ uobject_it_release(it, self);
392+ it = next_it;
393+ }
394+
395+ memset(SUOBJECT(self).mTable, 0, sizeof(uobject_it*)*SUOBJECT(self).mTableSize);
396+
397+ SUOBJECT(self).mEntryIt = NULL;
398+ SUOBJECT(self).mCounter = 0;
399+}
400+
401+uobject_it* uobject_loop_begin(sObject* self)
402+{
403+ assert(TYPE(self) == T_UOBJECT);
404+
405+ return SUOBJECT(self).mEntryIt;
406+}
407+
408+void* uobject_loop_item(uobject_it* it)
409+{
410+ return it->mItem;
411+}
412+
413+char* uobject_loop_key(uobject_it* it)
414+{
415+ return it->mKey;
416+}
417+
418+uobject_it* uobject_loop_next(uobject_it* it)
419+{
420+ return it->mNextIt;
421+}
422+
423+int uobject_count(sObject* self)
424+{
425+ assert(TYPE(self) == T_UOBJECT);
426+
427+ return SUOBJECT(self).mCounter;
428+}
--- a/src/xyzsh.c
+++ b/src/xyzsh.c
@@ -107,12 +107,12 @@ static void xyzsh_read_rc()
107107 xyzsh_read_rc_core(user_rc_path);
108108
109109
110-// hash_put(gRootObject, "test", sTestObj_new("AAA", 1));
110+// uobject_put(gRootObject, "test", sTestObj_new("AAA", 1));
111111 }
112112
113113 void xyzsh_init(enum eAppType app_type, BOOL no_runtime_script)
114114 {
115- setenv("XYZSH_VERSION", "1.1.0", 1);
115+ setenv("XYZSH_VERSION", "1.1.1", 1);
116116 setenv("XYZSH_DATAROOTDIR", DATAROOTDIR, 1);
117117
118118 stack_init(1);;
@@ -132,7 +132,7 @@ void xyzsh_init(enum eAppType app_type, BOOL no_runtime_script)
132132 xyzsh_readline_init(FALSE);
133133
134134 gDirStack = VECTOR_NEW_GC(10, FALSE);
135- hash_put(gxyzshObject, "_dir_stack", gDirStack);
135+ uobject_put(gxyzshObject, "_dir_stack", gDirStack);
136136
137137 char* term_env = getenv("TERM");
138138 if(term_env != NULL && strcmp(term_env, "") != 0) {
--- a/src/xyzsh/xyzsh.h
+++ b/src/xyzsh/xyzsh.h
@@ -307,11 +307,20 @@ typedef struct {
307307 BOOL mSuspended;
308308 } job_obj;
309309
310+typedef struct _uobject_it {
311+ char* mKey;
312+
313+ void* mItem;
314+ struct _uobject_it* mCollisionIt;
315+
316+ struct _uobject_it* mNextIt;
317+} uobject_it;
318+
310319 typedef struct { // a user object can be treated like a hash_obj
311- hash_it** mTable;
320+ uobject_it** mTable;
312321 int mTableSize;
313322
314- hash_it* mEntryIt;
323+ uobject_it* mEntryIt;
315324
316325 int mCounter;
317326
@@ -438,8 +447,18 @@ sObject* extobj_new_from_gc(void* object, fExtObjMarkFun mark_fun, fExtObjFreeFu
438447
439448 sObject* uobject_new_from_gc(int size, sObject* parent, char* name, BOOL user_object);
440449 sObject* uobject_new_from_stack(int size, sObject* object, char* name);
450+void uobject_put(sObject* self, char* key, void* item);
441451 void uobject_init(sObject* self);
442452 void uobject_root_init(sObject* self);
453+void uobject_put(sObject* self, char* key, void* item);
454+void* uobject_item(sObject* self, char* key);
455+void uobject_clear(sObject* self);
456+
457+uobject_it* uobject_loop_begin(sObject* self);
458+void* uobject_loop_item(uobject_it* it);
459+char* uobject_loop_key(uobject_it* it);
460+uobject_it* uobject_loop_next(uobject_it* it);
461+int uobject_count(sObject* self);
443462
444463 #define UOBJECT_NEW_GC(o, o2, o3, o4) uobject_new_from_gc(o, o2, o3, o4)
445464 #define UOBJECT_NEW_STACK(o, o2, o3) uobject_new_from_stack(o, o2, o3)
@@ -478,6 +497,8 @@ BOOL xyzsh_rehash(char* sname, int sline);
478497 #if defined(HAVE_MIGEMO_H)
479498 BOOL cmd_migemo_match(sObject* nextin, sObject* nextout, sRunInfo* runinfo);
480499 #endif
500+BOOL cmd_kanjicode(sObject* nextin, sObject* nextout, sRunInfo* runinfo);
501+BOOL cmd_defined(sObject* nextin, sObject* nextout, sRunInfo* runinfo);
481502 BOOL cmd_funinfo(sObject* nextin, sObject* nextout, sRunInfo* runinfo);
482503 BOOL cmd_readline_read_history(sObject* nextin, sObject* nextout, sRunInfo* runinfo);
483504 BOOL cmd_readline_write_history(sObject* nextin, sObject* nextout, sRunInfo* runinfo);
@@ -795,5 +816,7 @@ void readline_write_history();
795816 void readline_read_history();
796817 void xyzsh_read_rc_core(char* path);
797818
819+extern sObject* gStackFrames;
820+
798821 #endif
799822
--- a/xyzsh.xyzsh
+++ b/xyzsh.xyzsh
@@ -1,3 +1,5 @@
1+kanjicode -byte
2+
13 ### make xyzsh setting directory ###
24 print ~/.xyzsh | if(| -e) (
35 | if(! | -d) (