1 /* Copyright 1992 NEC Corporation, Tokyo, Japan.
2  *
3  * Permission to use, copy, modify, distribute and sell this software
4  * and its documentation for any purpose is hereby granted without
5  * fee, provided that the above copyright notice appear in all copies
6  * and that both that copyright notice and this permission notice
7  * appear in supporting documentation, and that the name of NEC
8  * Corporation not be used in advertising or publicity pertaining to
9  * distribution of the software without specific, written prior
10  * permission.  NEC Corporation makes no representations about the
11  * suitability of this software for any purpose.  It is provided "as
12  * is" without express or implied warranty.
13  *
14  * NEC CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
16  * NO EVENT SHALL NEC CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
18  * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
19  * OTHER TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20  * PERFORMANCE OF THIS SOFTWARE.
21  */
22 
23 #if !defined(lint) && !defined(__CODECENTER__)
24 static char rcsid[] = "$Id: lisp.c,v 1.11.2.1 2004/04/26 22:49:21 aida_s Exp $";
25 #endif
26 
27 /*
28 ** main program of lisp
29 */
30 #include "lisp.h"
31 #include "patchlevel.h"
32 
33 #include <signal.h>
34 
35 static FILE *outstream = (FILE *)0;
36 
37 static char *celltop, *cellbtm, *freecell;
38 static char *memtop;
39 
40 static int ncells = CELLSIZE;
41 
42 static initIS();
43 static void finIS();
44 static allocarea(), skipspaces(), zaplin(), isterm();
45 static void prins();
46 static list mkatm(), read1(), ratom(), ratom2(), rstring();
47 static int tyipeek(), tyi();
48 static void tyo pro((int));
49 static void defatms(), epush();
50 static void push(), pop();
51 static int  evpsh();
52 static void freearea(), print();
53 static list getatm(), getatmz(), newsymbol(), copystring();
54 static list assq(), pop1();
55 static list Lprogn(), Lcons(), Lread();
56 static list Leval(), Lprint(), Lmodestr(), Lputd(), Lxcons(), Lncons();
57 static list NumAcc(), StrAcc();
58 
59 /* parameter stack */
60 
61 static list	*stack, *sp;
62 
63 /* environment stack	*/
64 
65 static list	*estack, *esp;
66 
67 /* oblist */
68 
69 static list	*oblist;	/* oblist hashing array		*/
70 
71 #define LISPERROR	-1
72 
73 typedef struct {
74   FILE *f;
75   char *name;
76   unsigned line;
77 } lispfile;
78 
79 static lispfile *files;
80 static int  filep;
81 
82 /* lisp read buffer & read pointer */
83 
84 static char *readbuf;		/* read buffer	*/
85 static char *readptr;		/* read pointer	*/
86 
87 /* error functions	*/
88 
89 static void	argnerr(), numerr(), error();
90 
91 /* multiple values */
92 
93 #define MAXVALUES 16
94 static list *values;	/* multiple values here	*/
95 static int  valuec;	/* number of values here	*/
96 
97 /* symbols */
98 
99 static list QUOTE, T, _LAMBDA, _MACRO, COND, USER;
100 static list BUSHU, GRAMMAR, RENGO, KATAKANA, HIRAGANA, HYPHEN;
101 
102 #include <setjmp.h>
103 
104 static struct lispcenv {
105   jmp_buf jmp_env;
106   int     base_stack;
107   int     base_estack;
108 } *env; /* environment for setjmp & longjmp	*/
109 static int  jmpenvp = MAX_DEPTH;
110 
111 static jmp_buf fatal_env;
112 
113 /* external functions
114 
115    �����ؿ��ϰʲ��Σ���
116 
117   (1) clisp_init()  --  �������ޥ����ե�������ɤि��ν�������
118 
119     lisp �ν������Ԥ�ɬ�פʥ���� allocate ���롣
120 
121   (2) clisp_fin()   --  �������ޥ����ɤ߹����Ѥ��ΰ��������롣
122 
123     �嵭�ν���������������������롣
124 
125   (3) YYparse_by_rcfilename((char *)s) -- �������ޥ����ե�������ɤ߹��ࡣ
126 
127     s �ǻ��ꤵ�줿�ե�����̾�Υ������ޥ����ե�������ɤ߹���ǥ�����
128     �ޥ����������Ԥ����ե����뤬¸�ߤ���� 1 ���֤������Ǥʤ����
129     0 ���֤���
130 
131  */
132 
133 #ifdef __STDC__
134 static list getatmz(char *);
135 #else
136 static list getatmz();
137 #endif
138 
139 /*********************************************************************
140  *                      wchar_t replace begin                        *
141  *********************************************************************/
142 #ifdef wchar_t
143 # error "wchar_t is already defined"
144 #endif
145 #define wchar_t cannawc
146 
147 
148 int
clisp_init()149 clisp_init()
150 {
151   int  i;
152 
153   if ( !allocarea() ) {
154     return 0;
155   }
156 
157   if ( !initIS() ) {
158     freearea();
159     return 0;
160   }
161 
162   /* stack pointer initialization	*/
163   sp = stack + STKSIZE;
164   esp = estack + STKSIZE;
165   epush(NIL);
166 
167   /* initialize read pointer	*/
168   readptr = readbuf;
169   *readptr = '\0';
170   files[filep = 0].f = stdin;
171   files[filep].name = (char *)0;
172   files[filep].line = 0;
173 
174   /* oblist initialization	*/
175   for (i = 0; i < BUFSIZE ; i++)
176     oblist[i] = 0;
177 
178   /* symbol definitions */
179   defatms();
180   return 1;
181 }
182 
183 #ifndef NO_EXTEND_MENU
184 static void
fillMenuEntry()185 fillMenuEntry()
186 {
187   extern extraFunc *FindExtraFunc(), *extrafuncp;
188   extraFunc *p, *fp;
189   int i, n, fid;
190   menuitem *mb;
191 
192   for (p = extrafuncp ; p ; p = p->next) {
193     if (p->keyword == EXTRA_FUNC_DEFMENU) {
194       n = p->u.menuptr->nentries;
195       mb = p->u.menuptr->body;
196       for (i = 0 ; i < n ; i++, mb++) {
197 	if (mb->flag == MENU_SUSPEND) {
198 	  list l = (list)mb->u.misc;
199 	  fid = symbolpointer(l)->fid;
200 	  if (fid < CANNA_FN_MAX_FUNC) {
201 	    goto just_a_func;
202 	  }
203 	  else {
204 	    fp = FindExtraFunc(fid);
205 	    if (fp && fp->keyword == EXTRA_FUNC_DEFMENU) {
206 	      mb->u.menu_next = fp->u.menuptr;
207 	      mb->flag = MENU_MENU;
208 	    }
209 	    else {
210 	    just_a_func:
211 	      mb->u.fnum = fid;
212 	      mb->flag = MENU_FUNC;
213 	    }
214 	  }
215 	}
216       }
217     }
218   }
219 }
220 #endif /* NO_EXTEND_MENU */
221 
222 #define UNTYIUNIT 32
223 static char *untyibuf = 0;
224 static int untyisize = 0, untyip = 0;
225 
226 void
clisp_fin()227 clisp_fin()
228 {
229 #ifndef NO_EXTEND_MENU
230   /* ����������äơ�menu ��Ϣ�Υǡ��������� */
231   fillMenuEntry();
232 #endif
233 
234   finIS();
235 
236   while (filep >= 0) {
237     if (files[filep].f && files[filep].f != stdin) {
238       fclose(files[filep].f);
239     }
240     if (files[filep].name) {
241       free(files[filep].name);
242     }
243     filep--;
244   }
245 
246   freearea();
247   if (untyisize) {
248     free(untyibuf);
249     untyisize = 0;
250     untyibuf = (char *)0;
251   }
252 }
253 
254 int
YYparse_by_rcfilename(s)255 YYparse_by_rcfilename(s)
256 char *s;
257 {
258   extern ckverbose;
259   int retval = 0;
260   FILE *f;
261   FILE *saved_outstream;
262 
263   if (setjmp(fatal_env)) {
264     retval = 0;
265     goto quit_parse_rcfile;
266   }
267 
268   if (jmpenvp <= 0) { /* �Ƶ������������� */
269     return 0;
270   }
271   jmpenvp--;
272 
273   if (ckverbose >= CANNA_HALF_VERBOSE) {
274     saved_outstream = outstream;
275     outstream = stdout;
276   }
277 
278   f = fopen(s, "r");
279   if (f) {
280     if (ckverbose == CANNA_FULL_VERBOSE) {
281       printf("�������ޥ����ե�����Ȥ��� \"%s\" ���Ѥ��ޤ���\n", s);
282     }
283     files[++filep].f = f;
284     files[filep].name = malloc(strlen(s) + 1);
285     if (files[filep].name) {
286       strcpy(files[filep].name, s);
287     }
288     else {
289       filep--;
290       fclose(f);
291       goto quit_parse_rcfile;
292     }
293     files[filep].line = 0;
294 
295     setjmp(env[jmpenvp].jmp_env);
296     env[jmpenvp].base_stack = sp - stack;
297     env[jmpenvp].base_estack = esp - estack;
298 
299     for (;;) {
300       push(Lread(0));
301       if (valuec > 1 && null(values[1])) {
302 	break;
303       }
304       (void)Leval(1);
305     }
306     retval = 1;
307   }
308 
309   if (ckverbose >= CANNA_HALF_VERBOSE) {
310     outstream = saved_outstream;
311   }
312 
313   jmpenvp++;
314  quit_parse_rcfile:
315   return retval;
316 }
317 
318 #define WITH_MAIN
319 #ifdef WITH_MAIN
320 
321 static void
intr(sig)322 intr(sig)
323 int sig;
324 /* ARGSUSED */
325 {
326   error("Interrupt:",NON);
327   /* NOTREACHED */
328 }
329 
330 /* cfuncdef
331 
332    parse_string -- ʸ�����ѡ������롣
333 
334 */
335 
parse_string(str)336 parse_string(str)
337 char *str;
338 {
339   char *readbufbk;
340 
341   if (clisp_init() == 0) {
342     return -1;
343   }
344 
345   /* read buffer �Ȥ���Ϳ����줿ʸ����Ȥ� */
346   readbufbk = readbuf;
347   readptr = readbuf = str;
348 
349   if (setjmp(fatal_env)) {
350     goto quit_parse_string;
351   }
352 
353   if (jmpenvp <= 0) { /* �Ƶ������������� */
354     return -1;
355   }
356 
357   jmpenvp--;
358   files[++filep].f = (FILE *)0;
359   files[filep].name = (char *)0;
360   files[filep].line = 0;
361 
362   setjmp(env[jmpenvp].jmp_env);
363   env[jmpenvp].base_stack = sp - stack;
364   env[jmpenvp].base_estack = esp - estack;
365 
366   for (;;) {
367     list t;
368 
369     t = Lread(0);
370     if (valuec > 1 && null(values[1])) {
371       break;
372     }
373     else {
374       push(t);
375       Leval(1);
376     }
377   }
378   jmpenvp++;
379  quit_parse_string:
380   readbuf = readbufbk;
381   clisp_fin();
382   return 0;
383 }
384 
385 static void intr();
386 
387 void
clisp_main()388 clisp_main()
389 {
390   if (clisp_init() == 0) {	/* initialize data area	& etc..	*/
391     fprintf(stderr, "CannaLisp: initialization failed.\n");
392     exit(1);
393   }
394 
395   if (setjmp(fatal_env)) {
396     goto quit_clisp_main;
397   }
398 
399   if (jmpenvp <= 0) { /* �Ƶ������������� */
400     return;
401   }
402   jmpenvp--;
403 
404   fprintf(stderr,"CannaLisp listener %d.%d%s\n",
405 	  CANNA_MAJOR_MINOR / 1000, CANNA_MAJOR_MINOR % 1000,
406 	  CANNA_PATCH_LEVEL);
407 
408   outstream = stdout;
409 
410   setjmp(env[jmpenvp].jmp_env);
411   env[jmpenvp].base_stack = sp - stack;
412   env[jmpenvp].base_estack = esp - estack;
413 
414   signal(SIGINT, intr);
415   for (;;) {
416     prins("-> ");		/* prompt	*/
417     push(Lread(0));
418     if (valuec > 1 && null(values[1])) {
419       break;
420     }
421     push(Leval(1));
422     if (sp[0] == LISPERROR) {
423       (void)pop1();
424     }
425     else {
426       (void)Lprint(1);
427       prins("\n");
428     }
429   }
430   jmpenvp++;
431  quit_clisp_main:
432   prins("\nGoodbye.\n");
433   clisp_fin();
434 }
435 
436 #endif /* WITH_MAIN */
437 
438 static int longestkeywordlen;
439 
440 typedef struct {
441   char *seq;
442   int id;
443 } SeqToID;
444 
445 static SeqToID keywordtable[] = {
446   {"Space"      ,' '},
447   {"Escape"     ,'\033'},
448   {"Tab"        ,'\t'},
449   {"Nfer"       ,CANNA_KEY_Nfer},
450   {"Xfer"       ,CANNA_KEY_Xfer},
451   {"Backspace"  ,'\b'},
452   {"Delete"     ,'\177'},
453   {"Insert"     ,CANNA_KEY_Insert},
454   {"Rollup"     ,CANNA_KEY_Rollup},
455   {"Rolldown"   ,CANNA_KEY_Rolldown},
456   {"Up"         ,CANNA_KEY_Up},
457   {"Left"       ,CANNA_KEY_Left},
458   {"Right"      ,CANNA_KEY_Right},
459   {"Down"       ,CANNA_KEY_Down},
460   {"Home"       ,CANNA_KEY_Home},
461   {"Clear"      ,'\013'},
462   {"Help"       ,CANNA_KEY_Help},
463   {"End"        ,CANNA_KEY_End},
464   {"Enter"      ,'\n'},
465   {"Return"     ,'\r'},
466 /* "F1" is processed by program */
467   {"F2"         ,CANNA_KEY_F2},
468   {"F3"         ,CANNA_KEY_F3},
469   {"F4"         ,CANNA_KEY_F4},
470   {"F5"         ,CANNA_KEY_F5},
471   {"F6"         ,CANNA_KEY_F6},
472   {"F7"         ,CANNA_KEY_F7},
473   {"F8"         ,CANNA_KEY_F8},
474   {"F9"         ,CANNA_KEY_F9},
475   {"F10"        ,CANNA_KEY_F10},
476 /* "Pf1" is processed by program */
477   {"Pf2"        ,CANNA_KEY_PF2},
478   {"Pf3"        ,CANNA_KEY_PF3},
479   {"Pf4"        ,CANNA_KEY_PF4},
480   {"Pf5"        ,CANNA_KEY_PF5},
481   {"Pf6"        ,CANNA_KEY_PF6},
482   {"Pf7"        ,CANNA_KEY_PF7},
483   {"Pf8"        ,CANNA_KEY_PF8},
484   {"Pf9"        ,CANNA_KEY_PF9},
485   {"Pf10"       ,CANNA_KEY_PF10},
486   {"Hiragana"   ,CANNA_KEY_HIRAGANA},
487   {"Katakana"   ,CANNA_KEY_KATAKANA},
488   {"Hankakuzenkaku" ,CANNA_KEY_HANKAKUZENKAKU},
489   {"Eisu"       ,CANNA_KEY_EISU},
490   {"S-Nfer"     ,CANNA_KEY_Shift_Nfer},
491   {"S-Xfer"     ,CANNA_KEY_Shift_Xfer},
492   {"S-Up"       ,CANNA_KEY_Shift_Up},
493   {"S-Down"     ,CANNA_KEY_Shift_Down},
494   {"S-Left"     ,CANNA_KEY_Shift_Left},
495   {"S-Right"    ,CANNA_KEY_Shift_Right},
496   {"C-Nfer"     ,CANNA_KEY_Cntrl_Nfer},
497   {"C-Xfer"     ,CANNA_KEY_Cntrl_Xfer},
498   {"C-Up"       ,CANNA_KEY_Cntrl_Up},
499   {"C-Down"     ,CANNA_KEY_Cntrl_Down},
500   {"C-Left"     ,CANNA_KEY_Cntrl_Left},
501   {"C-Right"    ,CANNA_KEY_Cntrl_Right},
502   {0            ,0},
503 };
504 
505 #define charToNum(c) charToNumTbl[(c) - ' ']
506 
507 static int *charToNumTbl;
508 
509 typedef struct {
510   int id;
511   int *tbl;
512 } seqlines;
513 
514 static seqlines *seqTbl;	/* ������ɽ(�ºݤˤ�ɽ��ɽ) */
515 static int nseqtbl;		/* ���֤ο������֤ο�����ɽ������ */
516 static int nseq;
517 static int seqline;
518 
519 static
initIS()520 initIS()
521 {
522   SeqToID *p;
523   char *s;
524   int i;
525   seqlines seqTbls[1024];
526 
527   seqTbl = (seqlines *)0;
528   seqline = 0;
529   nseqtbl = 0;
530   nseq = 0;
531   longestkeywordlen = 0;
532   for (i = 0 ; i < 1024 ; i++) {
533     seqTbls[i].tbl = (int *)0;
534     seqTbls[i].id = 0;
535   }
536   charToNumTbl = (int *)calloc('~' - ' ' + 1, sizeof(int));
537   if ( !charToNumTbl ) {
538     return 0;
539   }
540 
541   /* �ޤ���ʸ���Ȥ��Ƥ��뤫��Ĵ�٤롣
542      nseq �ϻȤ��Ƥ���ʸ������꣱�礭���ͤǤ��� */
543   for (p = keywordtable ; p->id ; p++) {
544     int len = 0;
545     for (s = p->seq ; *s ; s++) {
546       if ( !charToNumTbl[*s - ' '] ) {
547 	charToNumTbl[*s - ' '] = nseq; /* ��ʸ���˥��ꥢ���ֹ���� */
548 	nseq++;
549       }
550       len ++;
551     }
552     if (len > longestkeywordlen) {
553       longestkeywordlen = len;
554     }
555   }
556   /* ʸ����ʬ�Υơ��֥� */
557   seqTbls[nseqtbl].tbl = (int *)calloc(nseq, sizeof(int));
558   if ( !seqTbls[nseqtbl].tbl ) {
559     goto initISerr;
560   }
561   nseqtbl++;
562   for (p = keywordtable ; p->id ; p++) {
563     int line, nextline;
564 
565     line = 0;
566     for (s = p->seq ; *s ; s++) {
567       if (seqTbls[line].tbl == 0) { /* �ơ��֥뤬�ʤ� */
568 	seqTbls[line].tbl = (int *)calloc(nseq, sizeof(int));
569 	if ( !seqTbls[line].tbl ) {
570 	  goto initISerr;
571 	}
572       }
573       nextline = seqTbls[line].tbl[charToNum(*s)];
574       /* ���ʤߤˡ�charToNum(*s) �����Фˣ��ˤʤ�ʤ� */
575       if ( nextline ) {
576 	line = nextline;
577       }
578       else { /* �ǽ�˥����������� */
579 	line = seqTbls[line].tbl[charToNum(*s)] = nseqtbl++;
580       }
581     }
582     seqTbls[line].id = p->id;
583   }
584   seqTbl = (seqlines *)calloc(nseqtbl, sizeof(seqlines));
585   if ( !seqTbl ) {
586     goto initISerr;
587   }
588   for (i = 0 ; i < nseqtbl ; i++) {
589     seqTbl[i].id  = seqTbls[i].id;
590     seqTbl[i].tbl = seqTbls[i].tbl;
591   }
592   return 1;
593 
594  initISerr:
595   free(charToNumTbl);
596   charToNumTbl = (int *)0;
597   if (seqTbl) {
598     free(seqTbl);
599     seqTbl = (seqlines *)0;
600   }
601   for (i = 0 ; i < nseqtbl ; i++) {
602     if (seqTbls[i].tbl) {
603       free(seqTbls[i].tbl);
604       seqTbls[i].tbl = (int *)0;
605     }
606   }
607   return 0;
608 }
609 
610 static void
finIS()611 finIS() /* identifySequence ���Ѥ���������������� */
612 {
613   int i;
614 
615   if (seqTbl) {
616     for (i = 0 ; i < nseqtbl ; i++) {
617       if (seqTbl[i].tbl) free(seqTbl[i].tbl);
618       seqTbl[i].tbl = (int *)0;
619     }
620     free(seqTbl);
621     seqTbl = (seqlines *)0;
622   }
623   if (charToNumTbl) {
624     free(charToNumTbl);
625     charToNumTbl = (int *)0;
626   }
627 }
628 
629 /* cvariable
630 
631   seqline: identifySequence �Ǥξ��֤��ݻ������ѿ�
632 
633  */
634 
635 #define CONTINUE 1
636 #define END	 0
637 
638 static
identifySequence(c,val)639 identifySequence(c, val)
640 unsigned c;
641 int *val;
642 {
643   int nextline;
644 
645   if (' ' <= c && c <= '~' && charToNum(c) &&
646       (nextline = seqTbl[seqline].tbl[charToNum(c)]) ) {
647     seqline = nextline;
648     *val = seqTbl[seqline].id;
649     if (*val) {
650       seqline = 0;
651       return END;
652     }
653     else {
654       return CONTINUE; /* continue */
655     }
656   }
657   else {
658     *val = -1;
659     seqline = 0;
660     return END;
661   }
662 }
663 
664 
665 static int
alloccell()666 alloccell()
667 {
668   int  cellsize, odd;
669   char *p;
670 
671   cellsize = ncells * sizeof(list);
672   p = malloc(cellsize);
673   if (p == (char *)0) {
674     return 0;
675   }
676   memtop = p;
677   odd = (int)((pointerint)memtop % sizeof(list));
678   freecell = celltop = memtop + (odd ? (sizeof(list)) - odd : 0);
679   cellbtm = memtop + cellsize - odd;
680   return 1;
681 }
682 
683 /* ���ޤ��Ԥ��ʤ��ä��飰���֤� */
684 
685 static
allocarea()686 allocarea()
687 {
688   /* �ޤ��ϥ����ΰ� */
689   if (alloccell()) {
690     /* �����å��ΰ� */
691     stack = (list *)calloc(STKSIZE, sizeof(list));
692     if (stack) {
693       estack = (list *)calloc(STKSIZE, sizeof(list));
694       if (estack) {
695 	/* oblist */
696 	oblist = (list *)calloc(BUFSIZE, sizeof(list));
697 	if (oblist) {
698 	  /* I/O */
699 	  filep = 0;
700 	  files = (lispfile *)calloc(MAX_DEPTH, sizeof(lispfile));
701 	  if (files) {
702 	    readbuf = malloc(BUFSIZE);
703 	    if (readbuf) {
704 	      /* jump env */
705 	      jmpenvp = MAX_DEPTH;
706 	      env = (struct lispcenv *)
707 		calloc(MAX_DEPTH, sizeof(struct lispcenv));
708 	      if (env) {
709 		/* multiple values returning buffer */
710 		valuec = 1;
711 		values = (list *)calloc(MAXVALUES, sizeof(list));
712 		if (values) {
713 		  return 1;
714 		}
715 		free(env);
716 	      }
717 	      free(readbuf);
718 	    }
719 	    free(files);
720 	  }
721 	  free(oblist);
722 	}
723 	free(estack);
724       }
725       free(stack);
726     }
727     free(memtop);
728   }
729   return 0;
730 }
731 
732 static void
freearea()733 freearea()
734 {
735   free((char *)memtop);
736   free((char *)stack);
737   free((char *)estack);
738   free((char *)oblist);
739   free((char *)files);
740   free((char *)env);
741   free((char *)readbuf);
742   if (values) {
743     free(values);
744     values = 0;
745   }
746 }
747 
748 static list
getatmz(name)749 getatmz(name)
750 char *name;
751 {
752   int  key;
753   char *p;
754 
755   for (p = name, key = 0 ; *p ; p++)
756     key += *p;
757   return getatm(name,key);
758 }
759 
760 /* mkatm -
761 	making symbol function	*/
762 
763 static list
mkatm(name)764 mkatm(name)
765 char *name;
766 {
767   list temp;
768   struct atomcell *newatom;
769 
770   temp = newsymbol(name);
771   newatom = symbolpointer(temp);
772   newatom->value = (*name == ':') ? (list)temp : (list)UNBOUND;
773   newatom->plist = NIL;			/* set null plist	*/
774   newatom->ftype = UNDEF;		/* set undef func-type	*/
775   newatom->func  = (list (*)())0;	/* Don't kill this line	*/
776   newatom->valfunc  = (list (*)())0;	/* Don't kill this line	*/
777   newatom->hlink = NIL;		/* no hash linking	*/
778   newatom->mid = -1;
779   newatom->fid = -1;
780 
781   return temp;
782 }
783 
784 /* getatm -- get atom from the oblist if possible	*/
785 
786 static list
getatm(name,key)787 getatm(name,key)
788 char *name;
789 int  key;
790 {
791   list p;
792   struct atomcell *atomp;
793 
794   key &= 0x00ff;
795   for (p = oblist[key] ; p ;) {
796     atomp = symbolpointer(p);
797     if (!strcmp(atomp->pname, name)) {
798       return p;
799     }
800     p = atomp->hlink;
801   }
802   p = mkatm(name);
803   atomp = symbolpointer(p);
804   atomp->hlink = oblist[key];
805   oblist[key] = p;
806   return p;
807 }
808 
809 #define MESSAGE_MAX 256
810 
811 static void
error(msg,v)812 error(msg,v)
813 char *msg;
814 list v;
815 /* ARGSUSED */
816 {
817   char buf[MESSAGE_MAX];
818 
819   prins(msg);
820   if (v != (list)NON)
821     print(v);
822   if (files[filep].f == stdin) {
823     prins("\n");
824   }
825   else {
826     if (files[filep].name) {
827       sprintf(buf, " (%s near line %d)\n",
828 	      files[filep].name, files[filep].line);
829     }
830     else {
831       sprintf(buf, " (near line %d)\n", files[filep].line);
832     }
833     prins(buf);
834   }
835   sp = &stack[env[jmpenvp].base_stack];
836   esp = &estack[env[jmpenvp].base_estack];
837 /*  epush(NIL); */
838   longjmp(env[jmpenvp].jmp_env,YES);
839 }
840 
841 static void
fatal(msg,v)842 fatal(msg,v)
843 char *msg;
844 list v;
845 /* ARGSUSED */
846 {
847   char buf[MESSAGE_MAX];
848 
849   prins(msg);
850   if (v != (list)NON)
851     print(v);
852   if (files[filep].f == stdin) {
853     prins("\n");
854   }
855   else {
856     if (files[filep].name) {
857       sprintf(buf, " (%s near line %d)\n",
858 	      files[filep].name, files[filep].line);
859     }
860     else {
861       sprintf(buf, " (near line %d)\n", files[filep].line);
862     }
863     prins(buf);
864   }
865   longjmp(fatal_env, 1);
866 }
867 
868 static void
argnerr(msg)869 argnerr(msg)
870 char *msg;
871 {
872   prins("incorrect number of args to ");
873   error(msg, NON);
874   /* NOTREACHED */
875 }
876 
877 static void
numerr(fn,arg)878 numerr(fn,arg)
879 char *fn;
880 list arg;
881 {
882   prins("Non-number ");
883   if (fn) {
884     prins("to ");
885     prins(fn);
886   }
887   error(": ",arg);
888   /* NOTREACHED */
889 }
890 
891 static void
lisp_strerr(fn,arg)892 lisp_strerr(fn,arg)
893 char *fn;
894 list arg;
895 {
896   prins("Non-string ");
897   if (fn) {
898     prins("to ");
899     prins(fn);
900   }
901   error(": ",arg);
902   /* NOTREACHED */
903 }
904 
905 static list
Lread(n)906 Lread(n)
907 int n;
908 {
909   list t;
910 
911   argnchk("read",0);
912   valuec = 1;
913   if ((t = read1()) == (list)LISPERROR) {
914     readptr = readbuf;
915     *readptr = '\0';
916     if (files[filep].f != stdin) {
917       if (files[filep].f)
918 	fclose(files[filep].f);
919       if (files[filep].name) {
920 	free(files[filep].name);
921       }
922       filep--;
923     }
924     values[0] = NIL;
925     values[1] = NIL;
926     valuec = 2;
927     return(NIL);
928   }
929   else {
930     values[0] = t;
931     values[1] = T;
932     valuec = 2;
933     return(t);
934   }
935   /* NOTREACHED */
936 }
937 
938 static void untyi pro((int));
939 static list rcharacter pro((void));
940 
941 static list
read1()942 read1()
943 {
944   int  c;
945   list p, *pp;
946   list t;
947   char *eofmsg = "EOF hit in reading a list : ";
948 
949  lab:
950   if ( !skipspaces() ) {
951     return((list)LISPERROR);
952   }
953   switch (c = tyi()) {
954   case '(':
955     push(NIL);
956     p = Lncons(1);	/* get a new cell	*/
957     car(p) = p;
958     push(p);
959     pp = sp;
960 
961     for (;;) {
962     lab2:
963       if ( !skipspaces() ) {
964 	error(eofmsg,cdr(*pp));
965 	/* NOTREACHED */
966       }
967       switch (c = tyi()) {
968       case ';':
969 	zaplin();
970 	goto lab2;
971       case ')':
972 	return(cdr(pop1()));
973       case '.':
974 	if ( !(c = tyipeek()) ) {
975 	  error(eofmsg,cdr(*pp));
976 	  /* NOTREACHED */
977 	}
978 	else if ( !isterm(c) ) {
979 	  push(ratom2('.'));
980 	  push(NIL);
981 	  car(*pp) = cdar(*pp) = Lcons(2);
982 	  break;
983 	}
984 	else {
985 	  cdar(*pp) = read1();
986 	  if (cdar(*pp) == (list)LISPERROR) {
987 	    error(eofmsg,cdr(*pp));
988 	    /* NOTREACHED */
989 	  }
990 	  while (')' != (c = tyi()))
991 	    if ( !c ) {
992 	      error(eofmsg,cdr(*pp));
993 	      /* NOTREACHED */
994 	    }
995 	  return(cdr(pop1()));
996 	}
997       default:
998 	untyi(c);
999 	if ((t = read1()) == (list)LISPERROR) {
1000 	  error(eofmsg,cdr(*pp));
1001 	  /* NOTREACHED */
1002 	}
1003 	push(t);
1004 	push(NIL);
1005 	car(*pp) = cdar(*pp) = Lcons(2);
1006       }
1007     }
1008   case '\'':
1009     push(QUOTE);
1010     if ((t = read1()) == (list)LISPERROR) {
1011       error(eofmsg,NIL);
1012       /* NOTREACHED */
1013     }
1014     push(t);
1015     push(NIL);
1016     push(Lcons(2));
1017     return Lcons(2);
1018   case '"':
1019     return rstring();
1020   case '?':
1021     return rcharacter();
1022   case ';':
1023     zaplin();
1024     goto lab;
1025   default:
1026     untyi(c);
1027     return ratom();
1028   }
1029 }
1030 
1031 /* skipping spaces function -
1032 	if eof read then return NO	*/
1033 
1034 static
skipspaces()1035 skipspaces()
1036 {
1037   int c;
1038 
1039   while ((c = tyi()) <= ' ') {
1040     if ( !c ) {
1041       return(NO);
1042     }
1043 #ifdef QUIT_IF_BINARY_CANNARC
1044 /* �¤� fatal() �ˤ��Ƥ��ޤ��� read �Ǥ��ʤ��ä��Ȼפ������Υե������
1045    õ���˹Ԥ��ΤǤ��ޤ��ɤ��ʤ���return ��������Ȥ�����Ѥ��ʤ���Ф�
1046    ��ʤ������ݤʤΤǡ��Ȥꤢ�������� */
1047     if (c != '\033' && c != '\n' && c != '\r' && c!= '\t' && c < ' ') {
1048       fatal("read: Binary data read.", NON);
1049     }
1050 #endif
1051   }
1052   untyi(c);
1053   return(YES);
1054 }
1055 
1056 /* skip reading until '\n' -
1057 	if eof read then return NO	*/
1058 
1059 static
zaplin()1060 zaplin()
1061 {
1062 	int c;
1063 
1064 	while ((c = tyi()) != '\n')
1065 		if ( !c )
1066 			return(NO);
1067 	return(YES);
1068 }
1069 
1070 static void gc();
1071 
1072 static list
newcons()1073 newcons()
1074 {
1075   list retval;
1076 
1077   if (freecell + sizeof(struct cell) >= cellbtm) {
1078     gc();
1079   }
1080   retval = CONS_TAG | (freecell - celltop);
1081   freecell += sizeof(struct cell);
1082   return retval;
1083 }
1084 
1085 static list
newsymbol(name)1086 newsymbol(name)
1087 char *name;
1088 {
1089   list retval;
1090   struct atomcell *temp;
1091   int namesize;
1092 
1093   namesize = strlen(name);
1094   namesize = ((namesize / sizeof(list)) + 1) * sizeof(list); /* +1��'\0'��ʬ */
1095   if (freecell + (sizeof(struct atomcell)) + namesize >= cellbtm) {
1096     gc();
1097   }
1098   temp = (struct atomcell *)freecell;
1099   retval = SYMBOL_TAG | (freecell - celltop);
1100   freecell += sizeof(struct atomcell);
1101   (void)strcpy(freecell, name);
1102   temp->pname = freecell;
1103   freecell += namesize;
1104 
1105   return retval;
1106 }
1107 
1108 static void patom();
1109 
1110 static void
print(l)1111 print(l)
1112 list l;
1113 {
1114 	if ( !l )	/* case NIL	*/
1115 		prins("nil");
1116 	else if (atom(l))
1117 		patom(l);
1118 	else {
1119 		tyo('(');
1120 		print(car(l));
1121 		for (l = cdr(l) ; l ; l = cdr(l)) {
1122 			tyo(' ');
1123 			if (atom(l)) {
1124 				tyo('.');
1125 				tyo(' ');
1126 				patom(l);
1127 				break;
1128 			}
1129 			else
1130 				print(car(l));
1131 		}
1132 		tyo(')');
1133 	}
1134 }
1135 
1136 
1137 
1138 /*
1139 ** read atom
1140 */
1141 
1142 
1143 static list
ratom()1144 ratom()
1145 {
1146 	return(ratom2(tyi()));
1147 }
1148 
1149 /* read atom with the first one character -
1150 	check if the token is numeric or pure symbol & return proper value */
1151 
1152 static isnum();
1153 
1154 static list
ratom2(a)1155 ratom2(a)
1156 int  a;
1157 {
1158   int  i, c, flag;
1159   char atmbuf[BUFSIZE];
1160 
1161   flag = NO;
1162   if (a == '\\') {
1163     flag = YES;
1164     a = tyi();
1165   }
1166   atmbuf[0] = a;
1167   for (i = 1, c = tyi(); !isterm(c) ; i++, c = tyi()) {
1168     if ( !c ) {
1169       error("Eof hit in reading symbol.", NON);
1170       /* NOTREACHED */
1171     }
1172     if (c == '\\') {
1173       flag = YES;
1174     }
1175     if (i < BUFSIZE) {
1176       atmbuf[i] = c;
1177     }
1178     else {
1179       error("Too long symbol name read", NON);
1180       /* NOTREACHED */
1181     }
1182   }
1183   untyi(c);
1184   if (i < BUFSIZE) {
1185     atmbuf[i] = '\0';
1186   }
1187   else {
1188     error("Too long symbol name read", NON);
1189     /* NOTREACHED */
1190   }
1191   if ( !flag && isnum(atmbuf)) {
1192     return(mknum(atoi(atmbuf)));
1193   }
1194   else if ( !flag && !strcmp("nil",atmbuf) ) {
1195     return(NIL);
1196   }
1197   else {
1198     return (getatmz(atmbuf));
1199   }
1200 }
1201 
1202 static list
rstring()1203 rstring()
1204 {
1205   char strb[BUFSIZE];
1206   int c;
1207   int strp = 0;
1208 
1209   while ((c = tyi()) != '"') {
1210     if ( !c ) {
1211       error("Eof hit in reading a string.", NON);
1212       /* NOTREACHED */
1213     }
1214     if (strp < BUFSIZE) {
1215       if (c == '\\') {
1216 	untyi(c);
1217 	c = (char)(((canna_uintptr_t)rcharacter()) & 0xff);
1218       }
1219       strb[strp++] = (char)c;
1220     }
1221     else {
1222       error("Too long string read.", NON);
1223       /* NOTREACHED */
1224     }
1225   }
1226   if (strp < BUFSIZE) {
1227     strb[strp] = '\0';
1228   }
1229   else {
1230     error("Too long string read.", NON);
1231     /* NOTREACHED */
1232   }
1233 
1234   return copystring(strb, strp);
1235 }
1236 
1237 /* rcharacter -- ��ʸ���ɤ����롣 */
1238 
1239 static list
rcharacter()1240 rcharacter()
1241 {
1242   char *tempbuf;
1243   unsigned ch;
1244   list retval;
1245   int bufp;
1246 
1247   tempbuf = malloc(longestkeywordlen + 1);
1248   if ( !tempbuf ) {
1249     fatal("read: malloc failed in reading character.", NON);
1250     /* NOTREACHED */
1251   }
1252   bufp = 0;
1253 
1254   ch = tyi();
1255   if (ch == '\\') {
1256     int code, res;
1257 
1258     do { /* ������ɤȾȹ礹�� */
1259       tempbuf[bufp++] = ch = tyi();
1260       res = identifySequence(ch, &code);
1261     } while (res == CONTINUE);
1262     if (code != -1) { /* ������ɤȰ��פ����� */
1263       retval = mknum(code);
1264     }
1265     else if (bufp > 2 && tempbuf[0] == 'C' && tempbuf[1] == '-') {
1266       while (bufp > 3) {
1267 	untyi(tempbuf[--bufp]);
1268       }
1269       retval = mknum(tempbuf[2] & (' ' - 1));
1270     }
1271     else if (bufp == 3 && tempbuf[0] == 'F' && tempbuf[1] == '1') {
1272       untyi(tempbuf[2]);
1273       retval = mknum(CANNA_KEY_F1);
1274     }
1275     else if (bufp == 4 && tempbuf[0] == 'P' && tempbuf[1] == 'f' &&
1276 	     tempbuf[2] == '1') {
1277       untyi(tempbuf[3]);
1278       retval = mknum(CANNA_KEY_PF1);
1279     }
1280     else { /* �������� */
1281       while (bufp > 1) {
1282 	untyi(tempbuf[--bufp]);
1283       }
1284       ch = (unsigned)(unsigned char)tempbuf[0];
1285       goto return_char;
1286     }
1287   }
1288   else {
1289   return_char:
1290     if (ch == 0x8f) { /* SS3 */
1291       ch <<= 8;
1292       ch += tyi();
1293       goto shift_more;
1294     }
1295     else if (ch & 0x80) { /* ���������ܸ�˰�¸���Ƥ��� */
1296     shift_more:
1297       ch <<= 8;
1298       ch += tyi();
1299     }
1300     retval = mknum(ch);
1301   }
1302 
1303   free(tempbuf);
1304   return retval;
1305 }
1306 
isnum(name)1307 static isnum(name)
1308 char *name;
1309 {
1310 	if (*name == '-') {
1311 		name++;
1312 		if ( !*name )
1313 			return(NO);
1314 	}
1315 	for(; *name ; name++) {
1316 		if (*name < '0' || '9' < *name) {
1317 			if (*name != '.' || *(name + 1)) {
1318 				return(NO);
1319 			}
1320 		}
1321 	}
1322 	return(YES);
1323 }
1324 
1325 /* tyi -- input one character from buffered stream	*/
1326 
1327 static void
untyi(c)1328 untyi(c)
1329 int c;
1330 {
1331   if (readbuf < readptr) {
1332     *--readptr = c;
1333   }
1334   else {
1335     if (untyip >= untyisize) {
1336       if (untyisize == 0) {
1337 	untyibuf = malloc(UNTYIUNIT);
1338 	if (untyibuf) {
1339 	  untyisize = UNTYIUNIT;
1340 	}
1341       }
1342       else {
1343 	untyibuf = realloc(untyibuf, UNTYIUNIT + untyisize);
1344 	if (untyibuf) {
1345 	  untyisize += UNTYIUNIT;
1346 	}
1347       }
1348     }
1349     if (untyip < untyisize) { /* ����Ǥ�����å����� */
1350       untyibuf[untyip++] = c;
1351     }
1352   }
1353 }
1354 
1355 static int
tyi()1356 tyi()
1357 {
1358   char *gets(), *fgets();
1359 
1360   if (untyibuf) {
1361     int ret = untyibuf[--untyip];
1362     if (untyip == 0) {
1363       free(untyibuf);
1364       untyibuf = (char *)0;
1365       untyisize = 0;
1366     }
1367     return ret;
1368   }
1369 
1370   if (readptr && *readptr) {
1371     return ((int)(unsigned char)*readptr++);
1372   }
1373   else if (!files[filep].f) {
1374     return NO;
1375   }
1376   else if (files[filep].f == stdin) {
1377     readptr = fgets(readbuf, BUFSIZE, stdin);
1378     files[filep].line++;
1379     if ( !readptr ) {
1380       return NO;
1381     }
1382     else {
1383       return tyi();
1384     }
1385   }
1386   else {
1387     readptr = fgets(readbuf,BUFSIZE,files[filep].f);
1388     files[filep].line++;
1389     if (readptr) {
1390       return(tyi());
1391     }
1392     else {
1393       return(NO);
1394     }
1395   }
1396   /* NOTREACHED */
1397 }
1398 
1399 /* tyipeek -- input one character without advance the read pointer	*/
1400 
1401 static int
tyipeek()1402 tyipeek()
1403 {
1404   int c = tyi();
1405   untyi(c);
1406   return c;
1407 }
1408 
1409 /* tyo -- output one character	*/
1410 
tyo(c)1411 static void tyo(c)
1412 int c;
1413 {
1414   if (outstream) {
1415     (void)putc(c, outstream);
1416   }
1417 }
1418 
1419 
1420 /* prins -
1421 	print string	*/
1422 
prins(s)1423 static void prins(s)
1424 char *s;
1425 {
1426 	while (*s) {
1427 		tyo(*s++);
1428 	}
1429 }
1430 
1431 
1432 /* isterm -
1433 	check if the character is terminating the lisp expression	*/
1434 
isterm(c)1435 static isterm(c)
1436 int  c;
1437 {
1438 	if (c <= ' ')
1439 		return(YES);
1440 	else {
1441 		switch (c)
1442 		{
1443 		case '(':
1444 		case ')':
1445 		case ';':
1446 			return(YES);
1447 		default:
1448 			return(NO);
1449 		}
1450 	}
1451 }
1452 
1453 /* push down an S-expression to parameter stack	*/
1454 
1455 static void
push(value)1456 push(value)
1457 list value;
1458 {
1459   if (sp <= stack) {
1460     error("Stack over flow",NON);
1461     /* NOTREACHED */
1462   }
1463   else
1464     *--sp = value;
1465 }
1466 
1467 /* pop up n S-expressions from parameter stack	*/
1468 
1469 static void
pop(x)1470 pop(x)
1471 int  x;
1472 {
1473   if (0 < x && sp >= &stack[STKSIZE]) {
1474     error("Stack under flow",NON);
1475     /* NOTREACHED */
1476   }
1477   sp += x;
1478 }
1479 
1480 /* pop up an S-expression from parameter stack	*/
1481 
1482 static list
pop1()1483 pop1()
1484 {
1485   if (sp >= &stack[STKSIZE]) {
1486     error("Stack under flow",NON);
1487     /* NOTREACHED */
1488   }
1489   return(*sp++);
1490 }
1491 
1492 static void
epush(value)1493 epush(value)
1494 list value;
1495 {
1496   if (esp <= estack) {
1497     error("Estack over flow",NON);
1498     /* NOTREACHED */
1499   }
1500   else
1501     *--esp = value;
1502 }
1503 
1504 static list
epop()1505 epop()
1506 {
1507   if (esp >= &estack[STKSIZE]) {
1508     error("Lstack under flow",NON);
1509     /* NOTREACHED */
1510   }
1511   return(*esp++);
1512 }
1513 
1514 
1515 /*
1516 ** output function for lisp S-Expression
1517 */
1518 
1519 
1520 /*
1521 **  print atom function
1522 **  please make sure it is an atom (not list)
1523 **  no check is done here.
1524 */
1525 
1526 static void
patom(atm)1527 patom(atm)
1528 list atm;
1529 {
1530   char namebuf[BUFSIZE];
1531 
1532   if (constp(atm)) {
1533     if (numberp(atm)) {
1534       (void)sprintf(namebuf,"%d",(int)xnum(atm));
1535       prins(namebuf);
1536     }
1537     else {		/* this is a string */
1538       int i, len = xstrlen(atm);
1539       char *s = xstring(atm);
1540 
1541       tyo('"');
1542       for (i = 0 ; i < len ; i++) {
1543 	tyo(s[i]);
1544       }
1545       tyo('"');
1546     }
1547   }
1548   else {
1549     prins(symbolpointer(atm)->pname);
1550   }
1551 }
1552 
1553 static void markcopycell();
1554 
1555 static char *oldcelltop;
1556 static char *oldcellp;
1557 
1558 #define oldpointer(x) (oldcelltop + celloffset(x))
1559 
1560 static void
gc()1561 gc() /* ���ԡ������Υ����٥����쥯�����Ǥ��� */
1562 {
1563   int i;
1564   list *p;
1565   static int under_gc = 0;
1566 
1567   if (under_gc) {
1568     fatal("GC: memory exhausted.", NON);
1569   }
1570   else {
1571     under_gc = 1;
1572   }
1573 
1574   oldcellp = memtop; oldcelltop = celltop;
1575 
1576   if ( !alloccell() ) {
1577     fatal("GC: failed in allocating new cell area.", NON);
1578     /* NOTREACHED */
1579   }
1580 
1581   for (i = 0 ; i < BUFSIZE ; i++) {
1582     markcopycell(oblist + i);
1583   }
1584   for (p = sp ; p < &stack[STKSIZE] ; p++) {
1585     markcopycell(p);
1586   }
1587   for (p = esp ; p < &estack[STKSIZE] ; p++) {
1588     markcopycell(p);
1589   }
1590   for (i = 0 ; i < valuec ; i++) {
1591     markcopycell(values + i);
1592   }
1593   markcopycell(&T);
1594   markcopycell(&QUOTE);
1595   markcopycell(&_LAMBDA);
1596   markcopycell(&_MACRO);
1597   markcopycell(&COND);
1598   markcopycell(&USER);
1599   markcopycell(&BUSHU);
1600   markcopycell(&GRAMMAR);
1601   markcopycell(&RENGO);
1602   markcopycell(&KATAKANA);
1603   markcopycell(&HIRAGANA);
1604   markcopycell(&HYPHEN);
1605   free(oldcellp);
1606   if ((freecell - celltop) * 2 > cellbtm -celltop) {
1607     ncells = (freecell - celltop) * 2 / sizeof(list);
1608   }
1609   under_gc = 0;
1610 }
1611 
1612 static char *Strncpy();
1613 
1614 static list
allocstring(n)1615 allocstring(n)
1616 int n;
1617 {
1618   int namesize;
1619   list retval;
1620 
1621   namesize = ((n + (sizeof(pointerint)) + 1 + 3)/ sizeof(list)) * sizeof(list);
1622   if (freecell + namesize >= cellbtm) { /* gc ��ϵ��������ʤ��Ϥ� */
1623     gc();
1624   }
1625   ((struct stringcell *)freecell)->length = n;
1626   retval = STRING_TAG | (freecell - celltop);
1627   freecell += namesize;
1628   return retval;
1629 }
1630 
1631 static list
copystring(s,n)1632 copystring(s, n)
1633 char *s;
1634 int n;
1635 {
1636   list retval;
1637 
1638   retval = allocstring(n);
1639   (void)Strncpy(xstring(retval), s, n);
1640   xstring(retval)[n] = '\0';
1641   return retval;
1642 }
1643 
1644 static list
copycons(l)1645 copycons(l)
1646 struct cell *l;
1647 {
1648   list newcell;
1649 
1650   newcell = newcons();
1651   car(newcell) = l->head;
1652   cdr(newcell) = l->tail;
1653   return newcell;
1654 }
1655 
1656 static void
markcopycell(addr)1657 markcopycell(addr)
1658 list *addr;
1659 {
1660   list temp;
1661  redo:
1662   if (null(*addr) || numberp(*addr)) {
1663     return;
1664   }
1665   else if (alreadycopied(oldpointer(*addr))) {
1666     *addr = newaddr(gcfield(oldpointer(*addr)));
1667     return;
1668   }
1669   else if (stringp(*addr)) {
1670     temp = copystring(((struct stringcell *)oldpointer(*addr))->str,
1671 		      ((struct stringcell *)oldpointer(*addr))->length);
1672     gcfield(oldpointer(*addr)) = mkcopied(temp);
1673     *addr = temp;
1674     return;
1675   }
1676   else if (consp(*addr)) {
1677     temp = copycons((struct cell *)(oldpointer(*addr)));
1678     gcfield(oldpointer(*addr)) = mkcopied(temp);
1679     *addr = temp;
1680     markcopycell(&car(temp));
1681     addr = &cdr(temp);
1682     goto redo;
1683   }
1684   else { /* symbol */
1685     struct atomcell *newatom, *oldatom;
1686 
1687     oldatom = (struct atomcell *)(oldpointer(*addr));
1688     temp = newsymbol(oldatom->pname);
1689     newatom = symbolpointer(temp);
1690     newatom->value = oldatom->value;
1691     newatom->plist = oldatom->plist;
1692     newatom->ftype = oldatom->ftype;
1693     newatom->func  = oldatom->func;
1694     newatom->fid   = oldatom->fid;
1695     newatom->mid   = oldatom->mid;
1696     newatom->valfunc  = oldatom->valfunc;
1697     newatom->hlink = oldatom->hlink;
1698 
1699     gcfield(oldpointer(*addr)) = mkcopied(temp);
1700     *addr = temp;
1701 
1702     if (newatom->value != (list)UNBOUND) {
1703       markcopycell(&newatom->value);
1704     }
1705     markcopycell(&newatom->plist);
1706     if (newatom->ftype == EXPR || newatom->ftype == MACRO) {
1707       markcopycell((int *)&newatom->func);
1708     }
1709     addr = &newatom->hlink;
1710     goto redo;
1711   }
1712 }
1713 
1714 static list
bindall(var,par,a,e)1715 bindall(var,par,a,e)
1716 list var, par, a, e;
1717 {
1718   list *pa, *pe, retval;
1719 
1720   push(a); pa = sp;
1721   push(e); pe = sp;
1722  retry:
1723   if (constp(var)) {
1724     pop(2);
1725     return(*pa);
1726   }
1727   else if (atom(var)) {
1728     push(var);
1729     push(par);
1730     push(Lcons(2));
1731     push(*pa);
1732     retval = Lcons(2);
1733     pop(2);
1734     return retval;
1735   }
1736   else if (atom(par)) {
1737     error("Bad macro form ",e);
1738     /* NOTREACHED */
1739   }
1740   push(par);
1741   push(var);
1742   *pa = bindall(car(var),car(par),*pa,*pe);
1743   var = cdr(pop1());
1744   par = cdr(pop1());
1745   goto retry;
1746   /* NOTREACHED */
1747 }
1748 
1749 static list
Lquote()1750 Lquote()
1751 {
1752 	list p;
1753 
1754 	p = pop1();
1755 	if (atom(p))
1756 		return(NIL);
1757 	else
1758 		return(car(p));
1759 }
1760 
1761 static list
Leval(n)1762 Leval(n)
1763 int n;
1764 {
1765   list e, t, s, tmp, aa, *pe, *pt, *ps, *paa;
1766   list fn, (*cfn)(), *pfn;
1767   int i, j;
1768   argnchk("eval",1);
1769   e = sp[0];
1770   pe = sp;
1771   if (atom(e)) {
1772     if (constp(e)) {
1773       pop1();
1774       return(e);
1775     }
1776     else {
1777       struct atomcell *sym;
1778 
1779       t = assq(e, *esp);
1780       if (t) {
1781 	(void)pop1();
1782 	return(cdr(t));
1783       }
1784       else if ((sym = symbolpointer(e))->valfunc) {
1785 	(void)pop1();
1786 	return (sym->valfunc)(VALGET, 0);
1787       }
1788       else {
1789 	if ((t = (sym->value)) != (list)UNBOUND) {
1790 	  pop1();
1791 	  return(t);
1792 	}
1793 	else {
1794 	  error("Unbound variable: ",*pe);
1795 	  /* NOTREACHED */
1796 	}
1797       }
1798     }
1799   }
1800   else if (constp((fn = car(e)))) {	/* not atom	*/
1801     error("eval: undefined function ", fn);
1802     /* NOTREACHED */
1803   }
1804   else if (atom(fn)) {
1805     switch (symbolpointer(fn)->ftype) {
1806     case UNDEF:
1807       error("eval: undefined function ", fn);
1808       /* NOTREACHED */
1809       break;
1810     case SUBR:
1811       cfn = symbolpointer(fn)->func;
1812       i = evpsh(cdr(e));
1813       epush(NIL);
1814       t = (*cfn)(i);
1815       epop();
1816       pop1();
1817       return (t);
1818     case SPECIAL:
1819       push(cdr(e));
1820       t = (*(symbolpointer(fn)->func))();
1821       pop1();
1822       return (t);
1823     case EXPR:
1824       fn = (list)(symbolpointer(fn)->func);
1825       aa = NIL; /* previous env won't be used */
1826     expr:
1827       if (atom(fn) || car(fn) != _LAMBDA || atom(cdr(fn))) {
1828 	error("eval: bad lambda form ", fn);
1829 	/* NOTREACHED */
1830       }
1831 /* Lambda binding begins here ...					*/
1832       s = cdr(e);		/* actual parameter	*/
1833       t = cadr(fn);		/* lambda list		*/
1834       push(s); ps = sp;
1835       push(t); pt = sp;
1836       push(fn); pfn = sp;
1837       push(aa); paa = sp;
1838       i = 0;			/* count of variables	*/
1839       for (; consp(*ps) && consp(*pt) ; *ps = cdr(*ps), *pt = cdr(*pt)) {
1840 	if (consp(car(*pt))) {
1841 	  tmp = cdar(*pt);	/* push the cdr of element */
1842 	  if (!(atom(tmp) || null(cdr(tmp)))) {
1843 	    push(cdr(tmp));
1844 	    push(T);
1845 	    push(Lcons(2));
1846 	    i++;
1847 	  }
1848 	  push(caar(*pt));
1849 	}
1850 	else {
1851 	  push(car(*pt));
1852 	}
1853 	push(car(*ps));
1854 	push(Leval(1));
1855 	push(Lcons(2));
1856 	i++;
1857       }
1858       for (; consp(*pt) ; *pt = cdr(*pt)) {
1859 	if (atom(car(*pt))) {
1860 	  error("Too few actual parameters ",*pe);
1861 	  /* NOTREACHED */
1862 	}
1863 	else {
1864 	  tmp = cdar(*pt);
1865 	  if (!(atom(tmp) || null(cdr(tmp)))) {
1866 	    push(cdr(tmp));
1867 	    push(NIL);
1868 	    push(Lcons(2));
1869 	    i++;
1870 	  }
1871 	  push(caar(*pt));
1872 	  tmp = cdar(*pt); /* restore for GC */
1873 	  if (atom(tmp))
1874 	    push(NIL);
1875 	  else {
1876 	    push(car(tmp));
1877 	    push(Leval(1));
1878 	  }
1879 	  push(Lcons(2));
1880 	  i++;
1881 	}
1882       }
1883       if (null(*pt) && consp(*ps)) {
1884 	error("Too many actual arguments ",*pe);
1885 	/* NOTREACHED */
1886       }
1887       else if (*pt) {
1888 	push(*pt);
1889 	for (j = 1 ; consp(*ps) ; j++) {
1890 	  push(car(*ps));
1891 	  push(Leval(1));
1892 	  *ps = cdr(*ps);
1893 	}
1894 	push(NIL);
1895 	for (; j ; j--) {
1896 	  push(Lcons(2));
1897 	}
1898 	i++;
1899       }
1900       push(*paa);
1901       for (; i ; i--) {
1902 	push(Lcons(2));
1903       }
1904 /* Lambda binding finished, and a new environment is established.	*/
1905       epush(pop1());	/* set the new environment	*/
1906       push(cddr(*pfn));
1907       t = Lprogn();
1908       epop();
1909       pop(5);
1910       return (t);
1911     case MACRO:
1912       fn = (list)(symbolpointer(fn)->func);
1913       if (atom(fn) || car(fn) != _MACRO || atom(cdr(fn))) {
1914 	error("eval: bad macro form ",fn);
1915 	/* NOTREACHED */
1916       }
1917       s = cdr(e);	/* actual parameter	*/
1918       t = cadr(fn);	/* lambda list	*/
1919       push(fn);
1920       epush(bindall(t,s,NIL,e));
1921       push(cddr(pop1()));
1922       t = Lprogn();
1923       epop();
1924       push(t);
1925       push(t);
1926       s = Leval(1);
1927       t = pop1();
1928       if (!atom(t)) {
1929 	car(*pe) = car(t);
1930 	cdr(*pe) = cdr(t);
1931       }
1932       pop1();
1933       return (s);
1934     case CMACRO:
1935       push(e);
1936       push(t = (*(symbolpointer(fn)->func))());
1937       push(t);
1938       s = Leval(1);
1939       t = pop1();
1940       if (!atom(t)) {
1941 	car(e) = car(t);
1942 	cdr(e) = cdr(t);
1943       }
1944       pop1();
1945       return (s);
1946     default:
1947       error("eval: unrecognized ftype used in ", fn);
1948       /* NOTREACHED */
1949       break;
1950     }
1951     /* NOTREACHED */
1952   }
1953   else {	/* fn is list (lambda expression)	*/
1954     aa = *esp; /* previous environment is also used */
1955     goto expr;
1956   }
1957   /* maybe NOTREACHED */
1958   return NIL;
1959 }
1960 
1961 static list
assq(e,a)1962 assq(e,a)
1963 list e, a;
1964 {
1965   list i;
1966 
1967   for (i = a ; i ; i = cdr(i)) {
1968     if (consp(car(i)) && e == caar(i)) {
1969       return(car(i));
1970     }
1971   }
1972   return((list)NIL);
1973 }
1974 
1975 /* eval each argument and push down each value to parameter stack	*/
1976 
1977 static int
evpsh(args)1978 evpsh(args)
1979 list args;
1980 {
1981   int  counter;
1982   list temp;
1983 
1984   counter = 0;
1985   while (consp(args)) {
1986     push(args);
1987     push(car(args));
1988     temp = Leval(1);
1989     args = cdr(pop1());
1990     counter++;
1991     push(temp);
1992   }
1993   return (counter);
1994 }
1995 
1996 /*
1997 static int
1998 psh(args)
1999 list args;
2000 {
2001   int  counter;
2002 
2003   counter = 0;
2004   while (consp(args)) {
2005     push(car(args));
2006     counter++;
2007     args = cdr(args);
2008   }
2009   return (counter);
2010 }
2011 */
2012 
2013 static list
Lprogn()2014 Lprogn()
2015 {
2016   list val, *pf;
2017 
2018   val = NIL;
2019   pf = sp;
2020   for (; consp(*pf) ; *pf = cdr(*pf)) {
2021     symbolpointer(T)->value = T;
2022     push(car(*pf));
2023     val = Leval(1);
2024   }
2025   pop1();
2026   return (val);
2027 }
2028 
2029 static list
Lcons(n)2030 Lcons(n)
2031 int n;
2032 {
2033 	list temp;
2034 
2035 	argnchk("cons",2);
2036 	temp = newcons();
2037 	cdr(temp) = pop1();
2038 	car(temp) = pop1();
2039 	return(temp);
2040 }
2041 
2042 static list
Lncons(n)2043 Lncons(n)
2044 int n;
2045 {
2046 	list temp;
2047 
2048 	argnchk("ncons",1);
2049 	temp = newcons();
2050 	car(temp) = pop1();
2051 	cdr(temp) = NIL;
2052 	return(temp);
2053 }
2054 
2055 static list
Lxcons(n)2056 Lxcons(n)
2057 int n;
2058 {
2059 	list temp;
2060 
2061 	argnchk("cons",2);
2062 	temp = newcons();
2063 	car(temp) = pop1();
2064 	cdr(temp) = pop1();
2065 	return(temp);
2066 }
2067 
2068 static list
Lprint(n)2069 Lprint(n)
2070 int n;
2071 {
2072 	print(sp[0]);
2073 	pop(n);
2074 	return (T);
2075 }
2076 
2077 static list
Lset(n)2078 Lset(n)
2079 int n;
2080 {
2081   list val, t;
2082   list var;
2083   struct atomcell *sym;
2084 
2085   argnchk("set",2);
2086   val = pop1();
2087   var = pop1();
2088   if (!symbolp(var)) {
2089     error("set/setq: bad variable type  ",var);
2090     /* NOTREACHED */
2091   }
2092   sym = symbolpointer(var);
2093   t = assq(var,*esp);
2094   if (t) {
2095     return cdr(t) = val;
2096   }
2097   else if (sym->valfunc) {
2098     return (*(sym->valfunc))(VALSET, val);
2099   }
2100   else {
2101     return sym->value = val;	/* global set	*/
2102   }
2103 }
2104 
2105 static list
Lsetq()2106 Lsetq()
2107 {
2108   list a, *pp;
2109 
2110   a = NIL;
2111   for (pp = sp; consp(*pp) ; *pp = cdr(*pp)) {
2112     push(car(*pp));
2113     *pp = cdr(*pp);
2114     if ( atom(*pp) ) {
2115       error("Odd number of args to setq",NON);
2116       /* NOTREACHED */
2117     }
2118     push(car(*pp));
2119     push(Leval(1));
2120     a = Lset(2);
2121   }
2122   pop1();
2123   return(a);
2124 }
2125 
2126 static int equal();
2127 
2128 static list
Lequal(n)2129 Lequal(n)
2130 int n;
2131 {
2132   argnchk("equal (=)",2);
2133   if (equal(pop1(),pop1()))
2134     return(T);
2135   else
2136     return(NIL);
2137 }
2138 
2139 /* null ʸ���ǽ����ʤ� strncmp */
2140 
2141 static int
Strncmp(x,y,len)2142 Strncmp(x, y, len)
2143 char *x, *y;
2144 int len;
2145 {
2146   int i;
2147 
2148   for (i = 0 ; i < len ; i++) {
2149     if (x[i] != y[i]) {
2150       return (x[i] - y[i]);
2151     }
2152   }
2153   return 0;
2154 }
2155 
2156 /* null ʸ���ǽ����ʤ� strncpy */
2157 
2158 static char *
Strncpy(x,y,len)2159 Strncpy(x, y, len)
2160 char *x, *y;
2161 int len;
2162 {
2163   int i;
2164 
2165   for (i = 0 ; i < len ; i++) {
2166     x[i] = y[i];
2167   }
2168   return x;
2169 }
2170 
2171 static int
equal(x,y)2172 equal(x,y)
2173 list x, y;
2174 {
2175  equaltop:
2176   if (x == y)
2177     return(YES);
2178   else if (null(x) || null(y))
2179     return(NO);
2180   else if (numberp(x) || numberp(y)) {
2181     return NO;
2182   }
2183   else if (stringp(x)) {
2184     if (stringp(y)) {
2185       return ((xstrlen(x) == xstrlen(y)) ?
2186 	      (!Strncmp(xstring(x), xstring(y), xstrlen(x))) : 0);
2187     }
2188     else {
2189       return NO;
2190     }
2191   }
2192   else if (symbolp(x) || symbolp(y)) {
2193     return(NO);
2194   }
2195   else {
2196     if (equal(car(x), car(y))) {
2197       x = cdr(x);
2198       y = cdr(y);
2199       goto equaltop;
2200     }
2201     else
2202       return(NO);
2203   }
2204 }
2205 
2206 static list
Lgreaterp(n)2207 Lgreaterp(n)
2208 int n;
2209 {
2210   list p;
2211   pointerint x, y;
2212 
2213   if ( !n )
2214     return(T);
2215   else {
2216     p = pop1();
2217     if (!numberp(p)) {
2218       numerr("greaterp",p);
2219       /* NOTREACHED */
2220     }
2221     x = xnum(p);
2222     for (n-- ; n ; n--) {
2223       p = pop1();
2224       if (!numberp(p)) {
2225 	numerr("greaterp",p);
2226 	/* NOTREACHED */
2227       }
2228       y = xnum(p);
2229       if (y <= x)		/* !(y > x)	*/
2230 	return(NIL);
2231       x = y;
2232     }
2233     return(T);
2234   }
2235 }
2236 
2237 static list
Llessp(n)2238 Llessp(n)
2239 int n;
2240 {
2241   list p;
2242   pointerint x, y;
2243 
2244   if ( !n )
2245     return(T);
2246   else {
2247     p = pop1();
2248     if (!numberp(p)) {
2249       numerr("lessp",p);
2250       /* NOTREACHED */
2251     }
2252     x = xnum(p);
2253     for (n-- ; n ; n--) {
2254       p = pop1();
2255       if (!numberp(p)) {
2256 	numerr("lessp",p);
2257 	/* NOTREACHED */
2258       }
2259       y = xnum(p);
2260       if (y >= x)		/* !(y < x)	*/
2261 	return(NIL);
2262       x = y;
2263     }
2264     return(T);
2265   }
2266 }
2267 
2268 static list
Leq(n)2269 Leq(n)
2270 int n;
2271 {
2272   list f;
2273 
2274   argnchk("eq",2);
2275   f = pop1();
2276   if (f == pop1())
2277     return(T);
2278   else
2279     return(NIL);
2280 }
2281 
2282 static list
Lcond()2283 Lcond()
2284 {
2285   list *pp, t, a, c;
2286 
2287   pp = sp;
2288   for (; consp(*pp) ; *pp = cdr(*pp)) {
2289     t = car(*pp);
2290     if (atom(t)) {
2291       pop1();
2292       return (NIL);
2293     }
2294     else {
2295       push(cdr(t));
2296       if ((c = car(t)) == T || (push(c), (a = Leval(1)))) {
2297 	/* if non NIL */
2298 	t = pop1();
2299 	if (null(t)) {	/* if cdr is NIL */
2300 	  (void)pop1();
2301 	  return (a);
2302 	}
2303 	else {
2304 	  (void)pop1();
2305 	  push(t);
2306 	  return(Lprogn());
2307 	}
2308       }
2309       else {
2310 	(void)pop1();
2311       }
2312     }
2313   }
2314   pop1();
2315   return (NIL);
2316 }
2317 
2318 static list
Lnull(n)2319 Lnull(n)
2320 int n;
2321 {
2322   argnchk("null",1);
2323   if (pop1())
2324     return NIL;
2325   else
2326     return T;
2327 }
2328 
2329 static list
Lor()2330 Lor()
2331 {
2332   list *pp, t;
2333 
2334   for (pp = sp; consp(*pp) ; *pp = cdr(*pp)) {
2335     push(car(*pp));
2336     t = Leval(1);
2337     if (t) {
2338       pop1();
2339       return(t);
2340     }
2341   }
2342   pop1();
2343   return(NIL);
2344 }
2345 
2346 static list
Land()2347 Land()
2348 {
2349   list *pp, t;
2350 
2351   t = T;
2352   for (pp = sp; consp(*pp) ; *pp = cdr(*pp)) {
2353     push(car(*pp));
2354     if ( !(t = Leval(1)) ) {
2355       pop1();
2356       return(NIL);
2357     }
2358   }
2359   pop1();
2360   return(t);
2361 }
2362 
2363 static list
Lplus(n)2364 Lplus(n)
2365 int n;
2366 {
2367   list t;
2368   int  i;
2369   pointerint sum;
2370 
2371   i = n;
2372   sum = 0;
2373   while (i--) {
2374     t = sp[i];
2375     if ( !numberp(t) ) {
2376       numerr("+",t);
2377       /* NOTREACHED */
2378     }
2379     else {
2380       sum += xnum(t);
2381     }
2382   }
2383   pop(n);
2384   return(mknum(sum));
2385 }
2386 
2387 static list
Ltimes(n)2388 Ltimes(n)
2389 int n;
2390 {
2391   list t;
2392   int  i;
2393   pointerint sum;
2394 
2395   i = n;
2396   sum = 1;
2397   while (i--) {
2398     t = sp[i];
2399     if ( !numberp(t) ) {
2400       numerr("*",t);
2401       /* NOTREACHED */
2402     }
2403     else
2404       sum *= xnum(t);
2405   }
2406   pop(n);
2407   return(mknum(sum));
2408 }
2409 
2410 static list
Ldiff(n)2411 Ldiff(n)
2412 int n;
2413 {
2414   list t;
2415   int  i;
2416   pointerint sum;
2417 
2418   if ( !n )
2419     return(mknum(0));
2420   t = sp[n - 1];
2421   if ( !numberp(t) ) {
2422     numerr("-",t);
2423     /* NOTREACHED */
2424   }
2425   sum = xnum(t);
2426   if (n == 1) {
2427     pop1();
2428     return(mknum(-sum));
2429   }
2430   else {
2431     i = n - 1;
2432     while (i--) {
2433       t = sp[i];
2434       if ( !numberp(t) ) {
2435 	numerr("-",t);
2436 	/* NOTREACHED */
2437       }
2438       else
2439 	sum -= xnum(t);
2440     }
2441     pop(n);
2442     return(mknum(sum));
2443   }
2444 }
2445 
2446 static list
Lquo(n)2447 Lquo(n)
2448 int n;
2449 {
2450   list t;
2451   int  i;
2452   pointerint sum;
2453 
2454   if ( !n )
2455     return(mknum(1));
2456   t = sp[n - 1];
2457   if ( !numberp(t) ) {
2458     numerr("/",t);
2459     /* NOTREACHED */
2460   }
2461   sum = xnum(t);
2462   i = n - 1;
2463   while (i--) {
2464     t = sp[i];
2465     if ( !numberp(t) ) {
2466       numerr("/",t);
2467       /* NOTREACHED */
2468     }
2469     else if (xnum(t) != 0) {
2470       sum = sum / (pointerint)xnum(t); /* CP/M68K is bad...	*/
2471     }
2472     else { /* division by zero */
2473       error("Division by zero",NON);
2474     }
2475   }
2476   pop(n);
2477   return(mknum(sum));
2478 }
2479 
2480 static list
Lrem(n)2481 Lrem(n)
2482 int n;
2483 {
2484   list t;
2485   int  i;
2486   pointerint sum;
2487 
2488   if ( !n )
2489     return(mknum(0));
2490   t = sp[n - 1];
2491   if ( !numberp(t) ) {
2492     numerr("%",t);
2493     /* NOTREACHED */
2494   }
2495   sum = xnum(t);
2496   i = n - 1;
2497   while (i--) {
2498     t = sp[i];
2499     if ( !numberp(t) ) {
2500       numerr("%",t);
2501       /* NOTREACHED */
2502     }
2503     else if (xnum(t) != 0) {
2504       sum = sum % (pointerint)xnum(t); /* CP/M68K is bad ..	*/
2505     }
2506     else { /* division by zero */
2507       error("Division by zero",NON);
2508     }
2509   }
2510   pop(n);
2511   return(mknum(sum));
2512 }
2513 
2514 /*
2515  *	Garbage Collection
2516  */
2517 
2518 static list
Lgc(n)2519 Lgc(n)
2520 int n;
2521 {
2522   argnchk("gc",0);
2523   gc();
2524   return(NIL);
2525 }
2526 
2527 static list
Lusedic(n)2528 Lusedic(n)
2529 int n;
2530 {
2531   int i;
2532   list retval = NIL, temp;
2533   int dictype;
2534   extern struct dicname *kanjidicnames;
2535   struct dicname *kanjidicname;
2536   extern int auto_define;
2537   extern char *kataautodic;
2538 #ifdef HIRAGANAAUTO
2539   extern char *hiraautodic;
2540 #endif
2541 
2542   for (i = n ; i ; i--) {
2543     temp = sp[i - 1];
2544     dictype = DIC_PLAIN;
2545     if (symbolp(temp) && i - 1 > 0) {
2546       if (temp == USER) {
2547 	dictype = DIC_USER;
2548       }
2549       else if (temp == BUSHU) {
2550 	dictype = DIC_BUSHU;
2551       }
2552       else if (temp == GRAMMAR) {
2553 	dictype = DIC_GRAMMAR;
2554       }
2555       else if (temp == RENGO) {
2556 	dictype = DIC_RENGO;
2557       }
2558       else if (temp == KATAKANA) {
2559 	dictype = DIC_KATAKANA;
2560         auto_define = 1;
2561       }
2562       else if (temp == HIRAGANA) {
2563 	dictype = DIC_HIRAGANA;
2564       }
2565       i--; temp = sp[i - 1];
2566     }
2567     if (stringp(temp)) {
2568       kanjidicname  = (struct dicname *)malloc(sizeof(struct dicname));
2569       if (kanjidicname) {
2570 	kanjidicname->name = malloc(strlen(xstring(temp)) + 1);
2571 	if (kanjidicname->name) {
2572 	  strcpy(kanjidicname->name , xstring(temp));
2573 	  kanjidicname->dictype = dictype;
2574 	  kanjidicname->dicflag = DIC_NOT_MOUNTED;
2575 	  kanjidicname->next = kanjidicnames;
2576 	  kanjidicnames = kanjidicname;
2577 	  if (kanjidicname->dictype == DIC_KATAKANA) {
2578 	    if (!kataautodic) { /* only the first one is valid */
2579 	      kataautodic = kanjidicname->name;
2580 	    }
2581 	  }
2582 #ifdef HIRAGANAAUTO
2583 	  else if (kanjidicname->dictype == DIC_HIRAGANA) {
2584 	    if (!hiraautodic) { /* only the first one is valid */
2585 	      hiraautodic = kanjidicname->name;
2586 	    }
2587 	  }
2588 #endif
2589 	  retval = T;
2590 	  continue;
2591 	}
2592 	free((char *)kanjidicname);
2593       }
2594     }
2595   }
2596   pop(n);
2597   return retval;
2598 }
2599 
2600 static list
Llist(n)2601 Llist(n)
2602 int n;
2603 {
2604 	push(NIL);
2605 	for (; n ; n--) {
2606 		push(Lcons(2));
2607 	}
2608 	return (pop1());
2609 }
2610 
2611 static list
Lcopysym(n)2612 Lcopysym(n)
2613 int n;
2614 {
2615   list src, dst;
2616   struct atomcell *dsta, *srca;
2617 
2618   argnchk("copy-symbol",2);
2619   src = pop1();
2620   dst = pop1();
2621   if (!symbolp(dst)) {
2622     error("copy-symbol: bad arg  ", dst);
2623     /* NOTREACHED */
2624   }
2625   if (!symbolp(src)) {
2626     error("copy-symbol: bad arg  ", src);
2627     /* NOTREACHED */
2628   }
2629   dsta = symbolpointer(dst);
2630   srca = symbolpointer(src);
2631   dsta->plist   = srca->plist;
2632   dsta->value   = srca->value;
2633   dsta->ftype   = srca->ftype;
2634   dsta->func    = srca->func;
2635   dsta->valfunc = srca->valfunc;
2636   dsta->mid     = srca->mid;
2637   dsta->fid     = srca->fid;
2638   return src;
2639 }
2640 
2641 static list
Lload(n)2642 Lload(n)
2643 int n;
2644 {
2645   list p, t;
2646   FILE *instream, *fopen();
2647 
2648   argnchk("load",1);
2649   p = pop1();
2650   if ( !stringp(p) ) {
2651     error("load: illegal file name  ",p);
2652     /* NOTREACHED */
2653   }
2654   if ((instream = fopen(xstring(p), "r")) == (FILE *)NULL) {
2655     error("load: file not found  ",p);
2656     /* NOTREACHED */
2657   }
2658   prins("[load ");
2659   print(p);
2660   prins("]\n");
2661 
2662   if (jmpenvp <= 0) { /* �Ƶ������������� */
2663     return NIL;
2664   }
2665   jmpenvp--;
2666   files[++filep].f = instream;
2667   files[filep].name = malloc(xstrlen(p) + 1);
2668   if (files[filep].name) {
2669     strcpy(files[filep].name, xstring(p));
2670   }
2671   files[filep].line = 0;
2672 
2673   setjmp(env[jmpenvp].jmp_env);
2674   env[jmpenvp].base_stack = sp - stack;
2675   env[jmpenvp].base_estack = esp - estack;
2676 
2677   for (;;) {
2678     t = Lread(0);
2679     if (valuec > 1 && null(values[1])) {
2680       break;
2681     }
2682     else {
2683       push(t);
2684       Leval(1);
2685     }
2686   }
2687   jmpenvp++;
2688   return(T);
2689 }
2690 
2691 static list
Lmodestr(n)2692 Lmodestr(n)
2693 int n;
2694 {
2695   list p;
2696   int mode;
2697 
2698   argnchk(S_SetModeDisp, 2);
2699   if ( !null(p = sp[0]) && !stringp(p) ) {
2700     lisp_strerr(S_SetModeDisp, p);
2701     /* NOTREACHED */
2702   }
2703   if (!symbolp(sp[1]) || (mode = symbolpointer(sp[1])->mid) == -1) {
2704     error("Illegal mode ", sp[1]);
2705     /* NOTREACHED */
2706   }
2707   changeModeName(mode, null(p) ? 0 : xstring(p));
2708   pop(2);
2709   return p;
2710 }
2711 
2712 /* ��ǽ���������μ��Ф� */
2713 
2714 static int
xfseq(fname,l,arr,arrsize)2715 xfseq(fname, l, arr, arrsize)
2716 char *fname;
2717 list l;
2718 unsigned char *arr;
2719 int arrsize;
2720 {
2721   int i;
2722 
2723   if (atom(l)) {
2724     if (symbolp(l) &&
2725 	(arr[0] = (unsigned char)(symbolpointer(l)->fid)) != 255) {
2726       arr[1] = 0;
2727     }
2728     else {
2729       prins(fname);
2730       error(": illegal function ", l);
2731       /* NOTREACHED */
2732     }
2733     return 1;
2734   }
2735   else {
2736     for (i = 0 ; i < arrsize - 1 && consp(l) ; i++, l = cdr(l)) {
2737       list temp = car(l);
2738 
2739       if (!symbolp(temp) ||
2740 	  (arr[i] = (unsigned char)(symbolpointer(temp)->fid)) == 255) {
2741 	prins(fname);
2742 	error(": illegal function ", temp);
2743 	/* NOTREACHED */
2744       }
2745     }
2746     arr[i] = 0;
2747     return i;
2748   }
2749 }
2750 
2751 static list
Lsetkey(n)2752 Lsetkey(n)
2753 int n;
2754 {
2755   list p;
2756   int mode, slen;
2757   unsigned char fseq[256];
2758   unsigned char keyseq[256];
2759   int retval;
2760 
2761   argnchk(S_SetKey, 3);
2762   if ( !stringp(p = sp[1]) ) {
2763     lisp_strerr(S_SetKey, p);
2764     /* NOTREACHED */
2765   }
2766   if (!symbolp(sp[2]) || (mode = symbolpointer(sp[2])->mid) < 0 ||
2767       (CANNA_MODE_MAX_REAL_MODE <= mode &&
2768        mode < CANNA_MODE_MAX_IMAGINARY_MODE &&
2769        mode != CANNA_MODE_HenkanNyuryokuMode)) {
2770     error("Illegal mode for set-key ", sp[2]);
2771     /* NOTREACHED */
2772   }
2773   if (xfseq(S_SetKey, sp[0], fseq, 256)) {
2774     slen = xstrlen(p);
2775     Strncpy((char *)keyseq, xstring(p), slen);
2776     keyseq[slen] = 255;
2777     retval = changeKeyfunc(mode, (unsigned)keyseq[0],
2778 		           slen > 1 ? CANNA_FN_UseOtherKeymap :
2779                            (fseq[1] != 0 ? CANNA_FN_FuncSequence : fseq[0]),
2780                            fseq, keyseq);
2781     if (retval == NG) {
2782       error("Insufficient memory.", NON);
2783       /* NOTREACHED */
2784     }
2785   }
2786   pop(3);
2787   return p;
2788 }
2789 
2790 static list
Lgsetkey(n)2791 Lgsetkey(n)
2792 int n;
2793 {
2794   list p;
2795   int slen;
2796   unsigned char fseq[256];
2797   unsigned char keyseq[256];
2798   int retval;
2799 
2800   argnchk(S_GSetKey, 2);
2801   if ( !stringp(p = sp[1]) ) {
2802     lisp_strerr(S_GSetKey, p);
2803     /* NOTREACHED */
2804   }
2805   if (xfseq(S_GSetKey, sp[0], fseq, 256)) {
2806     slen = xstrlen(p);
2807     Strncpy((char *)keyseq, xstring(p), slen);
2808     keyseq[slen] = 255;
2809     retval = changeKeyfuncOfAll((unsigned)keyseq[0],
2810                slen > 1 ? CANNA_FN_UseOtherKeymap :
2811                (fseq[1] != 0 ? CANNA_FN_FuncSequence : fseq[0]),
2812                fseq, keyseq);
2813     if (retval == NG) {
2814       error("Insufficient memory.", NON);
2815       /* NOTREACHED */
2816     }
2817     pop(2);
2818     return p;
2819   }
2820   else {
2821     pop(2);
2822     return NIL;
2823   }
2824 }
2825 
2826 static list
Lputd(n)2827 Lputd(n)
2828 int n;
2829 {
2830   list body, a;
2831   list sym;
2832   struct atomcell *symp;
2833 
2834   argnchk("putd",2);
2835   a = body = pop1();
2836   sym = pop1();
2837   symp = symbolpointer(sym);
2838   if (constp(sym) || consp(sym)) {
2839     error("putd: function name must be a symbol : ",sym);
2840     /* NOTREACHED */
2841   }
2842   if (null(body)) {
2843     symp->ftype = UNDEF;
2844     symp->func = (list (*)())UNDEF;
2845   }
2846   else if (consp(body)) {
2847     if (car(body) == _MACRO) {
2848       symp->ftype = MACRO;
2849       symp->func = (list (*)())body;
2850     }
2851     else {
2852       symp->ftype = EXPR;
2853       symp->func = (list (*)())body;
2854     }
2855   }
2856   return(a);
2857 }
2858 
2859 static list
Ldefun()2860 Ldefun()
2861 {
2862   list form, res;
2863 
2864   form = sp[0];
2865   if (atom(form)) {
2866     error("defun: illegal form ",form);
2867     /* NOTREACHED */
2868   }
2869   push(car(form));
2870   push(_LAMBDA);
2871   push(cdr(form));
2872   push(Lcons(2));
2873   Lputd(2);
2874   res = car(pop1());
2875   return (res);
2876 }
2877 
2878 static list
Ldefmacro()2879 Ldefmacro()
2880 {
2881   list form, res;
2882 
2883   form = sp[0];
2884   if (atom(form)) {
2885     error("defmacro: illegal form ",form);
2886     /* NOTREACHED */
2887   }
2888   push(res = car(form));
2889   push(_MACRO);
2890   push(cdr(form));
2891   push(Lcons(2));
2892   Lputd(2);
2893   pop1();
2894   return (res);
2895 }
2896 
2897 static list
Lcar(n)2898 Lcar(n)
2899 int n;
2900 {
2901   list f;
2902 
2903   argnchk("car",1);
2904   f = pop1();
2905   if (!f)
2906     return(NIL);
2907   else if (atom(f)) {
2908     error("Bad arg to car ",f);
2909     /* NOTREACHED */
2910   }
2911   return(car(f));
2912 }
2913 
2914 static list
Lcdr(n)2915 Lcdr(n)
2916 int n;
2917 {
2918   list f;
2919 
2920   argnchk("cdr",1);
2921   f = pop1();
2922   if (!f)
2923     return(NIL);
2924   else if (atom(f)) {
2925     error("Bad arg to cdr ",f);
2926     /* NOTREACHED */
2927   }
2928   return(cdr(f));
2929 }
2930 
2931 static list
Latom(n)2932 Latom(n)
2933 int n;
2934 {
2935   list f;
2936 
2937   argnchk("atom",1);
2938   f = pop1();
2939   if (atom(f))
2940     return(T);
2941   else
2942     return(NIL);
2943 }
2944 
2945 static list
Llet()2946 Llet()
2947 {
2948   list lambda, args, p, *pp, *pq, *pl, *px;
2949 
2950   px = sp;
2951   *px = cdr(*px);
2952   if (atom(*px)) {
2953     (void)pop1();
2954     return(NIL);
2955   }
2956   else {
2957     push(NIL);
2958     args = Lncons(1);
2959     push(args); pq = sp;
2960     push(NIL);
2961     lambda = p = Lncons(1);
2962     push(lambda);
2963 
2964     push(p); pp = sp;
2965     push(*pq); pq = sp;
2966     push(NIL); pl = sp;
2967     for (*pl = car(*px) ; consp(*pl) ; *pl = cdr(*pl)) {
2968       if (atom(car(*pl))) {
2969 	push(car(*pl));
2970 	*pp = cdr(*pp) = Lncons(1);
2971 	push(NIL);
2972 	*pq = cdr(*pq) = Lncons(1);
2973       }
2974       else if (atom(cdar(*pl))) {
2975 	push(caar(*pl));
2976 	*pp = cdr(*pp) = Lncons(1);
2977 	push(NIL);
2978 	*pq = cdr(*pq) = Lncons(1);
2979       }
2980       else {
2981 	push(caar(*pl));
2982 	*pp = cdr(*pp) = Lncons(1);
2983 	push(cadr(car(*pl)));
2984 	*pq = cdr(*pq) = Lncons(1);
2985       }
2986     }
2987     pop(3);
2988     sp[0] = cdr(sp[0]);
2989     sp[1] = cdr(sp[1]);
2990     push(cdr(*px));
2991     push(Lcons(2));
2992     push(_LAMBDA);
2993     push(Lxcons(2));
2994     p = Lxcons(2);
2995     (void)pop1();
2996     return(p);
2997   }
2998 }
2999 
3000 /* (if con tr . falist) -> (cond (con tr) (t . falist))*/
3001 
3002 static list
Lif()3003 Lif()
3004 {
3005   list x, *px, retval;
3006 
3007   x = cdr(sp[0]);
3008   if (atom(x) || atom(cdr(x))) {
3009     (void)pop1();
3010     return NIL;
3011   }
3012   else {
3013     push(x); px = sp;
3014 
3015     push(COND);
3016 
3017     push(car(x));
3018     push(cadr(x));
3019     push(Llist(2));
3020 
3021     push(T);
3022     push(cddr(*px));
3023     push(Lcons(2));
3024 
3025     retval = Llist(3);
3026     pop(2);
3027     return retval;
3028   }
3029 }
3030 
3031 static list
Lunbindkey(n)3032 Lunbindkey(n)
3033 int n;
3034 {
3035   unsigned char fseq[2];
3036   static unsigned char keyseq[2] = {(unsigned char)CANNA_KEY_Undefine,
3037 				      (unsigned char)255};
3038   int mode;
3039   list retval;
3040 
3041   argnchk(S_UnbindKey, 2);
3042   if (!symbolp(sp[1]) || (mode = symbolpointer(sp[1])->mid) == -1) {
3043     error("Illegal mode ", sp[1]);
3044     /* NOTREACHED */
3045   }
3046   if (xfseq(S_UnbindKey, sp[0], fseq, 2)) {
3047     int ret;
3048     ret = changeKeyfunc(mode, CANNA_KEY_Undefine,
3049                         fseq[1] != 0 ? CANNA_FN_FuncSequence : fseq[0],
3050                         fseq, keyseq);
3051     if (ret == NG) {
3052       error("Insufficient memory.", NON);
3053       /* NOTREACHED */
3054     }
3055     retval = T;
3056   }
3057   else {
3058     retval = NIL;
3059   }
3060   pop(2);
3061   return retval;
3062 }
3063 
3064 static list
Lgunbindkey(n)3065 Lgunbindkey(n)
3066 int n;
3067 {
3068   unsigned char fseq[2];
3069   static unsigned char keyseq[2] = {(unsigned char)CANNA_KEY_Undefine,
3070 				      (unsigned char)255};
3071   list retval;
3072 
3073   argnchk(S_GUnbindKey, 1);
3074   if (xfseq(S_GUnbindKey, sp[0], fseq, 2)) {
3075     int ret;
3076     ret = changeKeyfuncOfAll(CANNA_KEY_Undefine,
3077 		       fseq[1] != 0 ? CANNA_FN_FuncSequence : fseq[0],
3078 		       fseq, keyseq);
3079     if (ret == NG) {
3080       error("Insufficient memory.", NON);
3081       /* NOTREACHED */
3082     }
3083     retval = T;
3084   }
3085   else {
3086     retval = NIL;
3087   }
3088   (void)pop1();
3089   return retval;
3090 }
3091 
3092 #define DEFMODE_MEMORY      0
3093 #define DEFMODE_NOTSTRING   1
3094 #define DEFMODE_ILLFUNCTION 2
3095 
3096 static list
Ldefmode()3097 Ldefmode()
3098 {
3099   list form, *sym, e, *p, fn, rd, md, us;
3100   extern extraFunc *extrafuncp;
3101   extern int nothermodes;
3102   extraFunc *extrafunc = (extraFunc *)0;
3103   int i, j;
3104   int ecode;
3105   list l, edata;
3106 
3107   form = pop1();
3108   if (atom(form)) {
3109     error("Bad form ", form);
3110     /* NOTREACHED */
3111   }
3112   push(car(form));
3113   sym = sp;
3114   if (!symbolp(*sym)) {
3115     error("Symbol data expected ", *sym);
3116     /* NOTREACHED */
3117   }
3118 
3119   /* ������ץå��夹�� */
3120   for (i = 0, e = cdr(form) ; i < 4 ; i++, e = cdr(e)) {
3121     if (atom(e)) {
3122       for (j = i ; j < 4 ; j++) {
3123 	push(NIL);
3124       }
3125       break;
3126     }
3127     push(car(e));
3128   }
3129   if (consp(e)) {
3130     error("Bad form ", form);
3131     /* NOTREACHED */
3132   }
3133 
3134   /* ɾ������ */
3135   for (i = 0, p = sym - 1 ; i < 4 ; i++, p--) {
3136     push(*p);
3137     push(Leval(1));
3138   }
3139   us = pop1();
3140   fn = pop1();
3141   rd = pop1();
3142   md = pop1();
3143   pop(4);
3144 
3145   ecode = DEFMODE_MEMORY;
3146   extrafunc = (extraFunc *)malloc(sizeof(extraFunc));
3147   if (extrafunc) {
3148     /* ����ܥ�δؿ��ͤȤ��Ƥ���� */
3149     symbolpointer(*sym)->mid = CANNA_MODE_MAX_IMAGINARY_MODE + nothermodes;
3150     symbolpointer(*sym)->fid =
3151       extrafunc->fnum = CANNA_FN_MAX_FUNC + nothermodes;
3152 
3153     /* �ǥե���Ȥ����� */
3154     extrafunc->display_name = (wchar_t *)NULL;
3155     extrafunc->u.modeptr = (newmode *)malloc(sizeof(newmode));
3156     if (extrafunc->u.modeptr) {
3157       KanjiMode kanjimode;
3158 
3159       extrafunc->u.modeptr->romaji_table = (char *)0;
3160       extrafunc->u.modeptr->romdic = (struct RkRxDic *)0;
3161       extrafunc->u.modeptr->romdic_owner = 0;
3162       extrafunc->u.modeptr->flags = CANNA_YOMI_IGNORE_USERSYMBOLS;
3163       extrafunc->u.modeptr->emode = (KanjiMode)0;
3164 
3165       /* �⡼�ɹ�¤�Τκ��� */
3166       kanjimode = (KanjiMode)malloc(sizeof(KanjiModeRec));
3167       if (kanjimode) {
3168 	int searchfunc();
3169 	extern KanjiModeRec empty_mode;
3170 	extern BYTE *emptymap;
3171 
3172 	kanjimode->func = searchfunc;
3173 	kanjimode->keytbl = emptymap;
3174 	kanjimode->flags =
3175 	  CANNA_KANJIMODE_TABLE_SHARED | CANNA_KANJIMODE_EMPTY_MODE;
3176 	kanjimode->ftbl = empty_mode.ftbl;
3177 	extrafunc->u.modeptr->emode = kanjimode;
3178 
3179 	/* �⡼��ɽ��ʸ���� */
3180 	ecode = DEFMODE_NOTSTRING;
3181 	edata = md;
3182 	if (stringp(md) || null(md)) {
3183 	  if (stringp(md)) {
3184 	    extrafunc->display_name = WString(xstring(md));
3185 	  }
3186 	  ecode = DEFMODE_MEMORY;
3187 	  if (null(md) || extrafunc->display_name) {
3188 	    /* ���޻������Ѵ��ơ��֥� */
3189 	    ecode = DEFMODE_NOTSTRING;
3190 	    edata = rd;
3191 	    if (stringp(rd) || null(rd)) {
3192 	      char *newstr;
3193 	      long f = extrafunc->u.modeptr->flags;
3194 
3195 	      if (stringp(rd)) {
3196 		newstr = malloc(strlen(xstring(rd)) + 1);
3197 	      }
3198 	      ecode = DEFMODE_MEMORY;
3199 	      if (null(rd) || newstr) {
3200 		if (!null(rd)) {
3201 		  strcpy(newstr, xstring(rd));
3202 		  extrafunc->u.modeptr->romaji_table = newstr;
3203 		}
3204 		/* �¹Ե�ǽ */
3205 		for (e = fn ; consp(e) ; e = cdr(e)) {
3206 		  l = car(e);
3207 		  if (symbolp(l) && symbolpointer(l)->fid) {
3208 		    switch (symbolpointer(l)->fid) {
3209 		    case CANNA_FN_Kakutei:
3210 		      f |= CANNA_YOMI_KAKUTEI;
3211 		      break;
3212 		    case CANNA_FN_Henkan:
3213 		      f |= CANNA_YOMI_HENKAN;
3214 		      break;
3215 		    case CANNA_FN_Zenkaku:
3216 		      f |= CANNA_YOMI_ZENKAKU;
3217 		      break;
3218 		    case CANNA_FN_Hankaku:
3219 		      f |= CANNA_YOMI_HANKAKU;
3220 		      break;
3221 		    case CANNA_FN_Hiragana:
3222 		      f |= CANNA_YOMI_HIRAGANA;
3223 		      break;
3224 		    case CANNA_FN_Katakana:
3225 		      f |= CANNA_YOMI_KATAKANA;
3226 		      break;
3227 		    case CANNA_FN_Romaji:
3228 		      f |= CANNA_YOMI_ROMAJI;
3229 		      break;
3230 		      /* �ʲ��Ϥ��Τ������ */
3231 		    case CANNA_FN_ToUpper:
3232 		      break;
3233 		    case CANNA_FN_Capitalize:
3234 		      break;
3235 		    case CANNA_FN_ToLower:
3236 		      break;
3237 		    default:
3238 		      goto defmode_not_function;
3239 		    }
3240 		  }
3241 		  else {
3242 		    goto defmode_not_function;
3243 		  }
3244 		}
3245 		extrafunc->u.modeptr->flags = f;
3246 
3247 		/* �桼������ܥ�λ��Ѥ�̵ͭ */
3248 		if (us) {
3249 		  extrafunc->u.modeptr->flags &=
3250 		    ~CANNA_YOMI_IGNORE_USERSYMBOLS;
3251 		}
3252 
3253 		extrafunc->keyword = EXTRA_FUNC_DEFMODE;
3254 		extrafunc->next = extrafuncp;
3255 		extrafuncp = extrafunc;
3256 		nothermodes++;
3257 		return pop1();
3258 
3259 	      defmode_not_function:
3260 		ecode = DEFMODE_ILLFUNCTION;
3261 		edata = l;
3262 		if (!null(rd)) {
3263 		  free(newstr);
3264 		}
3265 	      }
3266 	    }
3267 	    if (extrafunc->display_name) {
3268 	      WSfree(extrafunc->display_name);
3269 	    }
3270 	  }
3271 	}
3272 	free((char *)kanjimode);
3273       }
3274       free((char *)extrafunc->u.modeptr);
3275     }
3276     free((char *)extrafunc);
3277   }
3278   switch (ecode) {
3279   case DEFMODE_MEMORY:
3280     error("Insufficient memory", NON);
3281   case DEFMODE_NOTSTRING:
3282     error("String data expected ", edata);
3283   case DEFMODE_ILLFUNCTION:
3284     error("defmode: illegal subfunction ", edata);
3285   }
3286   /* NOTREACHED */
3287 }
3288 
3289 static list
Ldefsym()3290 Ldefsym()
3291 {
3292   list form, res, e;
3293   int i, ncand, group;
3294   wchar_t cand[1024], *p, *mcand, **acand, key, xkey;
3295   int mcandsize;
3296   extern nkeysup;
3297   extern keySupplement keysup[];
3298 
3299   form = sp[0];
3300   if (atom(form)) {
3301     error("Illegal form ",form);
3302     /* NOTREACHED */
3303   }
3304   /* �ޤ����������� */
3305   for (ncand = 0 ; consp(form) ; ) {
3306     e = car(form);
3307     if (!numberp(e)) {
3308       error("Key data expected ", e);
3309       /* NOTREACHED */
3310     }
3311     if (null(cdr(form))) {
3312       error("Illegal form ",sp[0]);
3313       /* NOTREACHED */
3314     }
3315     if (numberp(car(cdr(form)))) {
3316       form = cdr(form);
3317     }
3318     for (i = 0, form = cdr(form) ; consp(form) ; i++, form = cdr(form)) {
3319       e = car(form);
3320       if (!stringp(e)) {
3321 	break;
3322       }
3323     }
3324     if (ncand == 0) {
3325       ncand = i;
3326     }
3327     else if (ncand != i) {
3328       error("Inconsist number for each key definition ", sp[0]);
3329       /* NOTREACHED */
3330     }
3331   }
3332 
3333   group = nkeysup;
3334 
3335   for (form = sp[0] ; consp(form) ;) {
3336     if (nkeysup >= MAX_KEY_SUP) {
3337       error("Too many symbol definitions", sp[0]);
3338       /* NOTREACHED */
3339     }
3340     /* The following lines are for xkey translation rule */
3341     key = (wchar_t)xnum(car(form));
3342     if (numberp(car(cdr(form)))) {
3343       xkey = (wchar_t)xnum(car(cdr(form)));
3344       form = cdr(form);
3345     }
3346     else {
3347       xkey = key;
3348     }
3349     p = cand;
3350     for (form = cdr(form) ; consp(form) ; form = cdr(form)) {
3351       int len;
3352 
3353       e = car(form);
3354       if (!stringp(e)) {
3355 	break;
3356       }
3357       len = MBstowcs(p, xstring(e), 1024 - (p - cand));
3358       p += len;
3359       *p++ = (wchar_t)0;
3360     }
3361     *p++ = (wchar_t)0;
3362     mcandsize = p - cand;
3363     mcand = (wchar_t *)malloc(mcandsize * sizeof(wchar_t));
3364     if (mcand == 0) {
3365       error("Insufficient memory", NON);
3366       /* NOTREACHED */
3367     }
3368     acand = (wchar_t **)calloc(ncand + 1, sizeof(wchar_t *));
3369     if (acand == 0) {
3370       free(mcand);
3371       error("Insufficient memory", NON);
3372       /* NOTREACHED */
3373     }
3374 
3375     for (i = 0 ; i < p - cand ; i++) {
3376       mcand[i] = cand[i];
3377     }
3378     for (i = 0, p = mcand ; i < ncand ; i++) {
3379       acand[i] = p;
3380       while (*p++)
3381 	/* EMPTY */
3382 	;
3383     }
3384     acand[i] = 0;
3385     /* �ºݤ˳�Ǽ���� */
3386     keysup[nkeysup].key = key;
3387     keysup[nkeysup].xkey = xkey;
3388     keysup[nkeysup].groupid = group;
3389     keysup[nkeysup].ncand = ncand;
3390     keysup[nkeysup].cand = acand;
3391     keysup[nkeysup].fullword = mcand;
3392     nkeysup++;
3393   }
3394   res = car(pop1());
3395   return (res);
3396 }
3397 
3398 #ifndef NO_EXTEND_MENU
3399 
3400 /*
3401    defselection �ǰ�����ʸ������Ф������ɬ�פʤΤǡ��ʲ����������
3402  */
3403 
3404 #define SS2	((char)0x8e)
3405 #define SS3	((char)0x8f)
3406 
3407 #define G0	0
3408 #define G1	1
3409 #define G2	2
3410 #define G3	3
3411 
3412 static int cswidth[4] = {1, 2, 2, 3};
3413 
3414 
3415 /*
3416    getKutenCode -- ʸ���ζ��������ɤ���Ф�
3417  */
3418 
3419 static int
getKutenCode(data,ku,ten)3420 getKutenCode(data, ku, ten)
3421 char *data;
3422 int *ku, *ten;
3423 {
3424   int codeset;
3425 
3426   *ku = (data[0] & 0x7f) - 0x20;
3427   *ten = (data[1] & 0x7f) - 0x20;
3428   if (*data == SS2) {
3429     codeset = G2;
3430     *ku = 0;
3431   }
3432   else if (*data == SS3) {
3433     codeset = G3;
3434     *ku = *ten;
3435     *ten = (data[2] & 0x7f) - 0x20;
3436   }
3437   else if (*data & 0x80) {
3438     codeset = G1;
3439   }
3440   else {
3441     codeset = G0;
3442     *ten = *ku;
3443     *ku = 0;
3444   }
3445   return codeset;
3446 }
3447 
3448 /*
3449    howManuCharsAre -- defselection ���ϰϻ��ꤷ������
3450                       �����ϰ���ο޷�ʸ���θĿ����֤�
3451  */
3452 
3453 static int
howManyCharsAre(tdata,edata,tku,tten,codeset)3454 howManyCharsAre(tdata, edata, tku, tten, codeset)
3455 char *tdata, *edata;
3456 int *tku, *tten, *codeset;
3457 {
3458   int eku, eten, kosdata, koedata;
3459 
3460   kosdata = getKutenCode(tdata, tku, tten);
3461   koedata = getKutenCode(edata, &eku, &eten);
3462   if (kosdata != koedata) {
3463     return 0;
3464   }
3465   else {
3466     *codeset = kosdata;
3467     return ((eku - *tku) * 94 + eten - *tten + 1);
3468   }
3469 }
3470 
3471 
3472 /*
3473    pickupChars -- �ϰ���ο޷�ʸ������Ф�
3474  */
3475 
3476 static char *
pickupChars(tku,tten,num,kodata)3477 pickupChars(tku, tten, num, kodata)
3478 int tku, tten, num, kodata;
3479 {
3480   char *dptr, *tdptr, *edptr;
3481 
3482   dptr = (char *)malloc(num * cswidth[kodata] + 1);
3483   if (dptr) {
3484     tdptr = dptr;
3485     edptr = dptr + num * cswidth[kodata];
3486     for (; dptr < edptr ; tten++) {
3487       if (tten > 94) {
3488         tku++;
3489         tten = 1;
3490       }
3491       switch(kodata) {
3492         case G0:
3493           *dptr++ = (tten + 0x20);
3494           break;
3495         case G1:
3496           *dptr++ = (tku + 0x20) | 0x80;
3497           *dptr++ = (tten + 0x20) | 0x80;
3498           break;
3499         case G2:
3500           *dptr++ = SS2;
3501           *dptr++ = (tten + 0x20) | 0x80;
3502           break;
3503         case G3:
3504           *dptr++ = SS3;
3505           *dptr++ = (tku + 0x20) | 0x80;
3506           *dptr++ = (tten + 0x20) | 0x80;
3507           break;
3508         default:
3509           break;
3510       }
3511     }
3512     *dptr++ = '\0';
3513     return tdptr;
3514   }
3515   else {
3516     error("Insufficient memory", NON);
3517     /* NOTREACHED */
3518   }
3519 }
3520 
3521 /*
3522    numtostr -- Key data ����ʸ������Ф�
3523  */
3524 
3525 static void
numtostr(num,str)3526 numtostr(num, str)
3527 unsigned long num;
3528 char *str;
3529 {
3530   if (num & 0xff0000) {
3531     *str++ = (char)((num >> 16) & 0xff);
3532   }
3533   if (num & 0xff00) {
3534     *str++ = (char)((num >> 8) & 0xff);
3535   }
3536   *str++ = (char)(num & 0xff);
3537   *str = '\0';
3538 }
3539 
3540 /*
3541   defselection -- ʸ�����������
3542 
3543   �Է�����
3544   (defselection function-symbol "�⡼��ɽ��" '(character-list))
3545  */
3546 
3547 static list
Ldefselection()3548 Ldefselection()
3549 {
3550   list form, sym, e, e2, md, kigo_list, buf;
3551   extern extraFunc *extrafuncp;
3552   extern int nothermodes;
3553   int i, len, cs, nkigo_data = 0, kigolen = 0;
3554   wchar_t *p, *kigo_str, **akigo_data;
3555   extraFunc *extrafunc = (extraFunc *)0;
3556 
3557   form = sp[0];
3558 
3559   if (atom(form) || atom(cdr(form)) || atom(cdr(cdr(form)))) {
3560     error("Illegal form ",form);
3561     /* NOTREACHED */
3562   }
3563 
3564   sym = car(form);
3565   if (!symbolp(sym)) {
3566     error("Symbol data expected ", sym);
3567     /* NOTREACHED */
3568   }
3569 
3570   md = car(cdr(form));
3571   if (!stringp(md) && !null(md)) {
3572     error("String data expected ", md);
3573     /* NOTREACHED */
3574   }
3575 
3576   push(car(cdr(cdr(form))));
3577   push(Leval(1));
3578 
3579   kigo_list = sp[0];
3580   if (atom(kigo_list)) {
3581     error("Illegal form ", kigo_list);
3582     /* NOTREACHED */
3583   }
3584 
3585   /* �ޤ��ΰ����ݤ��� */
3586   buf = kigo_list;
3587   while (!atom(buf)) {
3588     if (!atom(cdr(buf)) && (car(cdr(buf)) == HYPHEN)) {
3589       /* �ϰϻ���ΤȤ� */
3590       if (atom(cdr(cdr(buf)))) {
3591         error("Illegal form ", buf);
3592         /* NOTREACHED */
3593       }
3594       else {
3595         int sku, sten, num;
3596         char ss[4], ee[4];
3597 
3598         e = car(buf);
3599         if (!numberp(e)) {
3600           error("Key data expected ", e);
3601           /* NOTREACHED */
3602         }
3603         e2 = car(cdr(cdr(buf)));
3604         if (!numberp(e2)) {
3605           error("Key data expected ", e2);
3606           /* NOTREACHED */
3607         }
3608 
3609         numtostr(xnum(e), ss);
3610         numtostr(xnum(e2), ee);
3611         num = howManyCharsAre(ss, ee, &sku, &sten, &cs);
3612         if (num <= 0) {
3613           error("Inconsistent range of charcter code ", buf);
3614           /* NOTREACHED */
3615         }
3616         kigolen = kigolen + (cswidth[cs] + 1) * num;
3617         nkigo_data += num;
3618       }
3619       buf = cdr(cdr(cdr(buf)));
3620     }
3621     else {
3622      /* ���ǻ���ΤȤ� */
3623       char xx[4], *xxp;
3624 
3625       e = car(buf);
3626       if (!numberp(e) && !stringp(e)) {
3627         error("Key or string data expected ", e);
3628         /* NOTREACHED */
3629       }
3630       else if (numberp(e)) {
3631         numtostr(xnum(e), xx);
3632         xxp = xx;
3633       }
3634       else {
3635         xxp = xstring(e);
3636       }
3637 
3638       for ( ; *xxp ; xxp += cswidth[cs] ) {
3639         if (*xxp == SS2) {
3640           cs = G2;
3641         }
3642         else if (*xxp == SS3) {
3643           cs = G3;
3644         }
3645         else if (*xxp & 0x80) {
3646           cs = G1;
3647         }
3648         else {
3649           cs = G0;
3650         }
3651         kigolen = kigolen + cswidth[cs];
3652       }
3653       kigolen += 1;  /* �����ǤκǸ�� \0 ������� */
3654       nkigo_data++;
3655       buf = cdr(buf);
3656     }
3657   }
3658 
3659   kigo_str = (wchar_t *)malloc(kigolen * sizeof(wchar_t));
3660   if (!kigo_str) {
3661     error("Insufficient memory ", NON);
3662     /* NOTREACHED */
3663   }
3664   p = kigo_str;
3665 
3666   /* ��������Ф� */
3667   while (!atom(kigo_list)) {
3668     if (!atom(cdr(kigo_list)) && (car(cdr(kigo_list)) == HYPHEN)) {
3669     /* �ϰϻ���ΤȤ� */
3670       int sku, sten, codeset, num;
3671       char *ww, *sww, *eww, ss[4], ee[4], bak;
3672 
3673       e = car(kigo_list);
3674       e2 = car(cdr(cdr(kigo_list)));
3675       numtostr(xnum(e), ss);
3676       numtostr(xnum(e2), ee);
3677       num = howManyCharsAre(ss, ee, &sku, &sten, &codeset);
3678       sww = ww = pickupChars(sku, sten, num, codeset);
3679       cs = cswidth[codeset];
3680       eww = ww + num * cs;
3681       while (ww < eww) {
3682         bak = ww[cs];
3683         ww[cs] = '\0';
3684         len = MBstowcs(p, ww, kigolen - (p - kigo_str));
3685         p += len;
3686         *p++ = (wchar_t)0;
3687         ww += cs;
3688         ww[0] = bak;
3689       }
3690       free(sww);
3691       kigo_list = cdr(cdr(cdr(kigo_list)));
3692     }
3693     else {
3694       /* ���ǻ���ΤȤ� */
3695       char xx[4], *xxp;
3696 
3697       e = car(kigo_list);
3698       if (numberp(e)) {
3699         numtostr(xnum(e), xx);
3700         xxp = xx;
3701       }
3702       else {
3703         xxp = xstring(e);
3704       }
3705       len = MBstowcs(p, xxp, kigolen - (p - kigo_str));
3706       p += len;
3707       *p++ = (wchar_t)0;
3708       kigo_list = cdr(kigo_list);
3709     }
3710   }
3711 
3712   akigo_data = (wchar_t **)calloc(nkigo_data + 1, sizeof(wchar_t *));
3713   if (akigo_data == 0) {
3714     free(kigo_str);
3715     error("Insufficient memory", NON);
3716     /* NOTREACHED */
3717   }
3718 
3719   for (i = 0, p = kigo_str ; i < nkigo_data ; i++) {
3720     akigo_data[i] = p;
3721     while (*p++)
3722       /* EMPTY */
3723       ;
3724   }
3725 
3726   /* �ΰ����ݤ��� */
3727   extrafunc = (extraFunc *)malloc(sizeof(extraFunc));
3728   if (!extrafunc) {
3729     free((char *)kigo_str);
3730     free((char *)akigo_data);
3731     error("Insufficient memory", NON);
3732     /* NOTREACHED */
3733   }
3734   extrafunc->u.kigoptr = (kigoIchiran *)malloc(sizeof(kigoIchiran));
3735   if (!extrafunc->u.kigoptr) {
3736     free((char *)kigo_str);
3737     free((char *)akigo_data);
3738     free((char *)extrafunc);
3739     error("Insufficient memory", NON);
3740     /* NOTREACHED */
3741   }
3742 
3743   /* ����ܥ�δؿ��ͤȤ��Ƥ���� */
3744   symbolpointer(sym)->mid = extrafunc->u.kigoptr->kigo_mode
3745                           = CANNA_MODE_MAX_IMAGINARY_MODE + nothermodes;
3746   symbolpointer(sym)->fid = extrafunc->fnum
3747                           = CANNA_FN_MAX_FUNC + nothermodes;
3748 
3749   /* �ºݤ˳�Ǽ���� */
3750   extrafunc->u.kigoptr->kigo_data = akigo_data;
3751   extrafunc->u.kigoptr->kigo_str = kigo_str;
3752   extrafunc->u.kigoptr->kigo_size = nkigo_data;
3753   if (stringp(md)) {
3754     extrafunc->display_name = WString(xstring(md));
3755   }
3756   else {
3757     extrafunc->display_name = (wchar_t *)0;
3758   }
3759 
3760   extrafunc->keyword = EXTRA_FUNC_DEFSELECTION;
3761   extrafunc->next = extrafuncp;
3762   extrafuncp = extrafunc;
3763   pop(2);
3764   nothermodes++;
3765   return sym;
3766 }
3767 
3768 /*
3769   defmenu -- ��˥塼�����
3770 
3771   �Է�����
3772   (defmenu first-menu
3773     ("��Ͽ" touroku)
3774     ("���������" server))
3775  */
3776 
3777 static list
Ldefmenu()3778 Ldefmenu()
3779 {
3780   list form, sym, e;
3781   extern extraFunc *extrafuncp;
3782   extern int nothermodes;
3783   extraFunc *extrafunc = (extraFunc *)0;
3784   int i, n, clen, len;
3785   wchar_t foo[512];
3786   menustruct *men;
3787   menuitem *menubody;
3788   wchar_t *wp, **wpp;
3789   extern menustruct *allocMenu();
3790 
3791   form = sp[0];
3792   if (atom(form) || atom(cdr(form))) {
3793     error("Bad form ", form);
3794     /* NOTREACHED */
3795   }
3796   sym = car(form);
3797   if (!symbolp(sym)) {
3798     error("Symbol data expected ", sym);
3799     /* NOTREACHED */
3800   }
3801 
3802   /* ����������롣�Ĥ��Ǥ�ɽ��ʸ�����ʸ����������� */
3803   for (n = 0, clen = 0, e = cdr(form) ; !atom(e) ; n++, e = cdr(e)) {
3804     list l = car(e), d, fn;
3805     if (atom(l) || atom(cdr(l))) {
3806       error("Bad form ", form);
3807     }
3808     d = car(l);
3809     fn = car(cdr(l));
3810     if (!stringp(d) || !symbolp(fn)) {
3811       error("Bad form ", form);
3812     }
3813     len = MBstowcs(foo, xstring(d), 512);
3814     if (len >= 0) {
3815       clen += len + 1;
3816     }
3817   }
3818 
3819   extrafunc = (extraFunc *)malloc(sizeof(extraFunc));
3820   if (extrafunc) {
3821     men = allocMenu(n, clen);
3822     if (men) {
3823       menubody = men->body;
3824       /* �����ȥ�ʸ����ǡ����Хåե��˥��ԡ� */
3825       for (i = 0, wp = men->titledata, wpp = men->titles, e = cdr(form) ;
3826 	   i < n ; i++, e = cdr(e)) {
3827 	len = MBstowcs(wp, xstring(car(car(e))), 512);
3828 	*wpp++ = wp;
3829 	wp += len + 1;
3830 
3831 	menubody[i].flag = MENU_SUSPEND;
3832 	menubody[i].u.misc = (char *)car(cdr(car(e)));
3833       }
3834       men->nentries = n;
3835 
3836       /* ����ܥ�δؿ��ͤȤ��Ƥ���� */
3837       symbolpointer(sym)->mid =
3838 	men->modeid = CANNA_MODE_MAX_IMAGINARY_MODE + nothermodes;
3839       symbolpointer(sym)->fid =
3840 	extrafunc->fnum = CANNA_FN_MAX_FUNC + nothermodes;
3841       extrafunc->keyword = EXTRA_FUNC_DEFMENU;
3842       extrafunc->display_name = (wchar_t *)0;
3843       extrafunc->u.menuptr = men;
3844 
3845       extrafunc->next = extrafuncp;
3846       extrafuncp = extrafunc;
3847       nothermodes++;
3848       (void)pop1();
3849       return sym;
3850     }
3851     free((char *)extrafunc);
3852   }
3853   error("Insufficient memory", NON);
3854   /* NOTREACHED */
3855 }
3856 #endif /* NO_EXTEND_MENU */
3857 
3858 static list
Lsetinifunc(n)3859 Lsetinifunc(n)
3860 int n;
3861 {
3862   unsigned char fseq[256];
3863   int i, len;
3864   list ret = NIL;
3865   extern BYTE *initfunc;
3866 
3867   argnchk(S_SetInitFunc, 1);
3868 
3869   len = xfseq(S_SetInitFunc, sp[0], fseq, 256);
3870 
3871   if (len > 0) {
3872     if (initfunc) free(initfunc);
3873     initfunc = (BYTE *)malloc(len + 1);
3874     if (!initfunc) {
3875       error("Insufficient memory", NON);
3876       /* NOTREACHED */
3877     }
3878     for (i = 0 ; i < len ; i++) {
3879       initfunc[i] = fseq[i];
3880     }
3881     initfunc[i] = 0;
3882     ret = T;
3883   }
3884   (void)pop1();
3885   return ret;
3886 }
3887 
3888 static list
Lboundp(n)3889 Lboundp(n)
3890 int n;
3891 {
3892   list e;
3893   struct atomcell *sym;
3894 
3895   argnchk("boundp",1);
3896   e = pop1();
3897 
3898   if (!atom(e)) {
3899     error("boundp: bad arg ", e);
3900     /* NOTREACHED */
3901   }
3902   else if (constp(e)) {
3903     error("boundp: bad arg ", e);
3904     /* NOTREACHED */
3905   }
3906 
3907   if (assq(e, *esp)) {
3908     return T;
3909   }
3910   else if ((sym = symbolpointer(e))->valfunc) {
3911     return T;
3912   }
3913   else {
3914     if (sym->value != (list)UNBOUND) {
3915       return T;
3916     }
3917     else {
3918       return NIL;
3919     }
3920   }
3921 }
3922 
3923 static list
Lfboundp(n)3924 Lfboundp(n)
3925 int n;
3926 {
3927   list e;
3928 
3929   argnchk("fboundp",1);
3930   e = pop1();
3931 
3932   if (!atom(e)) {
3933     error("fboundp: bad arg ", e);
3934     /* NOTREACHED */
3935   }
3936   else if (constp(e)) {
3937     error("fboundp: bad arg ", e);
3938     /* NOTREACHED */
3939   }
3940   if (symbolpointer(e)->ftype == UNDEF) {
3941     return NIL;
3942   }
3943   else {
3944     return T;
3945   }
3946 }
3947 
3948 static list
Lgetenv(n)3949 Lgetenv(n)
3950 int n;
3951 {
3952   list e;
3953   char strbuf[256], *ret, *getenv();
3954   list retval;
3955 
3956   argnchk("getenv",1);
3957   e = sp[0];
3958 
3959   if (!stringp(e)) {
3960     error("getenv: bad arg ", e);
3961     /* NOTREACHED */
3962   }
3963 
3964   strncpy(strbuf, xstring(e), xstrlen(e));
3965   strbuf[xstrlen(e)] = '\0';
3966   ret = getenv(strbuf);
3967   if (ret) {
3968     retval = copystring(ret, strlen(ret));
3969   }
3970   else {
3971     retval = NIL;
3972   }
3973   (void)pop1();
3974   return retval;
3975 }
3976 
3977 static list
LdefEscSeq(n)3978 LdefEscSeq(n)
3979 int n;
3980 {
3981   extern void (*keyconvCallback)();
3982 
3983   argnchk("define-esc-sequence",3);
3984 
3985   if (!stringp(sp[2])) {
3986     error("define-esc-sequence: bad arg ", sp[2]);
3987     /* NOTREACHED */
3988   }
3989   if (!stringp(sp[1])) {
3990     error("define-esc-sequence: bad arg ", sp[1]);
3991     /* NOTREACHED */
3992   }
3993   if (!numberp(sp[0])) {
3994     error("define-esc-sequence: bad arg ", sp[0]);
3995     /* NOTREACHED */
3996   }
3997   if (keyconvCallback) {
3998     (*keyconvCallback)(CANNA_CTERMINAL,
3999 		       xstring(sp[2]), xstring(sp[1]), xnum(sp[0]));
4000   }
4001   pop(3);
4002   return NIL;
4003 }
4004 
4005 static list
Lconcat(n)4006 Lconcat(n)
4007 int n;
4008 {
4009   list t, res;
4010   int  i, len;
4011   char *p;
4012 
4013   /* �ޤ�Ĺ��������롣 */
4014   for (len= 0, i = n ; i-- ;) {
4015     t = sp[i];
4016     if (!stringp(t)) {
4017       lisp_strerr("concat", t);
4018       /* NOTREACHED */
4019     }
4020     len += xstrlen(t);
4021   }
4022   res = allocstring(len);
4023   for (p = xstring(res), i = n ; i-- ;) {
4024     t = sp[i];
4025     len = xstrlen(t);
4026     Strncpy(p, xstring(t), len);
4027     p += len;
4028   }
4029   *p = '\0';
4030   pop(n);
4031   return res;
4032 }
4033 
4034 /* lispfuncend */
4035 
4036 extern char *RkGetServerHost();
4037 
4038 static void
ObtainVersion()4039 ObtainVersion()
4040 {
4041 #if !defined(STANDALONE) && !defined(WIN_CANLISP)
4042   int a, b;
4043   char *serv;
4044   extern int protocol_version, server_version;
4045   extern char *server_name;
4046 
4047   serv = RkGetServerHost();
4048   if (!serv) {
4049     serv = DICHOME;
4050   }
4051   RkwInitialize(serv);
4052 
4053   /* �ץ�ȥ���С������ */
4054   RkwGetProtocolVersion(&a, &b);
4055   protocol_version = a * 1000 + b;
4056 
4057   /* �����ХС������ */
4058   RkwGetServerVersion(&a, &b);
4059   server_version = a * 1000 + b;
4060 
4061   /* ������̾ */
4062   if (server_name)
4063     free(server_name);
4064   server_name = malloc(strlen(DEFAULT_CANNA_SERVER_NAME) + 1);
4065   if (server_name) {
4066     strcpy(server_name, DEFAULT_CANNA_SERVER_NAME);
4067   }
4068 
4069   RkwFinalize();
4070 #endif /* STANDALONE */
4071 }
4072 
4073 /* �ѿ����������Τ���δؿ� */
4074 
4075 static list
VTorNIL(var,setp,arg)4076 VTorNIL(var, setp, arg)
4077 BYTE *var;
4078 int setp;
4079 list arg;
4080 {
4081   if (setp == VALSET) {
4082     *var = (arg == NIL) ? 0 : 1;
4083     return arg;
4084   }
4085   else { /* get */
4086     return *var ? T : NIL;
4087   }
4088 }
4089 
4090 static list
StrAcc(var,setp,arg)4091 StrAcc(var, setp, arg)
4092 char **var;
4093 int setp;
4094 list arg;
4095 {
4096   if (setp == VALSET) {
4097     if (null(arg) || stringp(arg)) {
4098       if (*var) {
4099 	free(*var);
4100       }
4101       if (stringp(arg)) {
4102 	*var = malloc(strlen(xstring(arg)) + 1);
4103 	if (*var) {
4104 	  strcpy(*var, xstring(arg));
4105 	  return arg;
4106 	}
4107 	else {
4108 	  error("Insufficient memory.", NON);
4109 	  /* NOTREACHED */
4110 	}
4111       }
4112       else {
4113 	*var = (char *)0;
4114 	return NIL;
4115       }
4116     }
4117     else {
4118       lisp_strerr((char *)0, arg);
4119       /* NOTREACHED */
4120     }
4121   }
4122   /* else { .. */
4123   if (*var) {
4124     return copystring(*var, strlen(*var));
4125   }
4126   else {
4127     return NIL;
4128   }
4129   /* end else .. } */
4130 }
4131 
4132 static list
NumAcc(var,setp,arg)4133 NumAcc(var, setp, arg)
4134 int *var;
4135 int setp;
4136 list arg;
4137 {
4138   if (setp == VALSET) {
4139     if (numberp(arg)) {
4140       *var = (int)xnum(arg);
4141       return arg;
4142     }
4143     else {
4144       numerr((char *)0, arg);
4145       /* NOTREACHED */
4146     }
4147   }
4148   return (list)mknum(*var);
4149 }
4150 
4151 /* �������鲼���������ޥ������ɲ������ɤ���������ʬ */
4152 
4153 /* �ºݤΥ��������ؿ� */
4154 
4155 #define DEFVAR(fn, acc, ty, var) \
4156 static list fn(setp, arg) int setp; list arg; { \
4157   extern ty var; return acc(&var, setp, arg); }
4158 
4159 #define DEFVAREX(fn, acc, var) \
4160 static list fn(setp, arg) int setp; list arg; { \
4161   extern struct CannaConfig cannaconf; return acc(&var, setp, arg); }
4162 
Vnkouhobunsetsu(setp,arg)4163 static list Vnkouhobunsetsu(setp, arg) int setp; list arg;
4164 {
4165   extern int nKouhoBunsetsu;
4166 
4167   arg = NumAcc(&nKouhoBunsetsu, setp, arg);
4168 #ifdef RESTRICT_NKOUHOBUNSETSU
4169   if (nKouhoBunsetsu < 3 || nKouhoBunsetsu > 60)
4170     nKouhoBunsetsu = 16;
4171 #else
4172   if (nKouhoBunsetsu < 0) {
4173     nKouhoBunsetsu = 0;
4174   }
4175 #endif
4176   return arg;
4177 }
4178 
VProtoVer(setp,arg)4179 static list VProtoVer(setp, arg) int setp; list arg;
4180 {
4181 #ifndef STANDALONE
4182   extern protocol_version;
4183 
4184   if (protocol_version < 0) {
4185     ObtainVersion();
4186   }
4187   return NumAcc(&protocol_version, setp, arg);
4188 #endif /* STANDALONE */
4189 }
4190 
VServVer(setp,arg)4191 static list VServVer(setp, arg) int setp; list arg;
4192 {
4193 #ifndef STANDALONE
4194   extern server_version;
4195 
4196   if (server_version < 0) {
4197     ObtainVersion();
4198   }
4199   return NumAcc(&server_version, setp, arg);
4200 #endif /* STANDALONE */
4201 }
4202 
VServName(setp,arg)4203 static list VServName(setp, arg) int setp; list arg;
4204 {
4205 #ifndef STANDALONE
4206   extern char *server_name;
4207 
4208   if (!server_name) {
4209     ObtainVersion();
4210   }
4211   return StrAcc(&server_name, setp, arg);
4212 #endif /* STANDALONE */
4213 }
4214 
4215 static list
VCannaDir(setp,arg)4216 VCannaDir(setp, arg) int setp; list arg;
4217 {
4218   char *canna_dir = CANNALIBDIR;
4219 
4220   if (setp == VALGET) {
4221     return StrAcc(&canna_dir, setp, arg);
4222   }
4223   else {
4224     return NIL;
4225   }
4226 }
4227 
VCodeInput(setp,arg)4228 static list VCodeInput(setp, arg) int setp; list arg;
4229 {
4230   extern struct CannaConfig cannaconf;
4231   static char *input_code[CANNA_MAX_CODE] = {"jis", "sjis", "kuten"};
4232 
4233   if (setp == VALSET) {
4234     if (null(arg) || stringp(arg)) {
4235       if (stringp(arg)) {
4236 	int i;
4237 	char *s = xstring(arg);
4238 
4239 	for (i = 0 ; i < CANNA_MAX_CODE ; i++) {
4240 	  if (!strcmp(s, input_code[i])) {
4241 	    cannaconf.code_input = i;
4242 	    break;
4243 	  }
4244 	}
4245 	if (i < CANNA_MAX_CODE) {
4246 	  return arg;
4247 	}
4248 	else {
4249 	  return NIL;
4250 	}
4251       }
4252       else {
4253 	cannaconf.code_input = 0; /* use default */
4254 	return copystring(input_code[0], strlen(input_code[0]));
4255       }
4256     }
4257     else {
4258       lisp_strerr((char *)0, arg);
4259       /* NOTREACHED */
4260     }
4261   }
4262   /* else { .. */
4263   if (/* 0 <= cannaconf.code_input && /* unsigned �ˤ����ΤǾ�Ĺ�ˤʤä� */
4264       cannaconf.code_input <= CANNA_CODE_KUTEN) {
4265     return copystring(input_code[cannaconf.code_input],
4266 		      strlen(input_code[cannaconf.code_input]));
4267   }
4268   else {
4269     return NIL;
4270   }
4271   /* end else .. } */
4272 }
4273 
4274 
4275 DEFVAR(Vromkana         ,StrAcc  ,char * ,RomkanaTable)
4276 DEFVAR(Venglish         ,StrAcc  ,char * ,EnglishTable)
4277 
4278 DEFVAREX(Vnhenkan       ,NumAcc          ,cannaconf.kouho_threshold)
4279 DEFVAREX(Vndisconnect   ,NumAcc          ,cannaconf.strokelimit)
4280 DEFVAREX(VCannaVersion  ,NumAcc          ,cannaconf.CannaVersion)
4281 DEFVAREX(VIndexSeparator,NumAcc          ,cannaconf.indexSeparator)
4282 
4283 DEFVAREX(Vgakushu       ,VTorNIL         ,cannaconf.Gakushu)
4284 DEFVAREX(Vcursorw       ,VTorNIL         ,cannaconf.CursorWrap)
4285 DEFVAREX(Vselectd       ,VTorNIL         ,cannaconf.SelectDirect)
4286 DEFVAREX(Vnumeric       ,VTorNIL         ,cannaconf.HexkeySelect)
4287 DEFVAREX(Vbunsets       ,VTorNIL         ,cannaconf.BunsetsuKugiri)
4288 DEFVAREX(Vcharact       ,VTorNIL         ,cannaconf.ChBasedMove)
4289 DEFVAREX(Vreverse       ,VTorNIL         ,cannaconf.ReverseWidely)
4290 DEFVAREX(VreverseWord   ,VTorNIL         ,cannaconf.ReverseWord)
4291 DEFVAREX(Vquitich       ,VTorNIL         ,cannaconf.QuitIchiranIfEnd)
4292 DEFVAREX(Vkakutei       ,VTorNIL         ,cannaconf.kakuteiIfEndOfBunsetsu)
4293 DEFVAREX(Vstayaft       ,VTorNIL         ,cannaconf.stayAfterValidate)
4294 DEFVAREX(Vbreakin       ,VTorNIL         ,cannaconf.BreakIntoRoman)
4295 DEFVAREX(Vgrammati      ,VTorNIL         ,cannaconf.grammaticalQuestion)
4296 DEFVAREX(Vforceka       ,VTorNIL         ,cannaconf.forceKana)
4297 DEFVAREX(Vkouhoco       ,VTorNIL         ,cannaconf.kCount)
4298 DEFVAREX(Vauto          ,VTorNIL         ,cannaconf.chikuji)
4299 DEFVAREX(VlearnNumTy    ,VTorNIL         ,cannaconf.LearnNumericalType)
4300 DEFVAREX(VBSasQuit      ,VTorNIL         ,cannaconf.BackspaceBehavesAsQuit)
4301 DEFVAREX(Vinhibi        ,VTorNIL         ,cannaconf.iListCB)
4302 DEFVAREX(Vkeepcupos     ,VTorNIL         ,cannaconf.keepCursorPosition)
4303 DEFVAREX(VAbandon       ,VTorNIL         ,cannaconf.abandonIllegalPhono)
4304 DEFVAREX(VHexStyle      ,VTorNIL         ,cannaconf.hexCharacterDefiningStyle)
4305 DEFVAREX(VKojin         ,VTorNIL         ,cannaconf.kojin)
4306 DEFVAREX(VIndexHankaku  ,VTorNIL         ,cannaconf.indexHankaku)
4307 DEFVAREX(VAllowNext     ,VTorNIL         ,cannaconf.allowNextInput)
4308 DEFVAREX(VkanaGaku      ,VTorNIL         ,cannaconf.doKatakanaGakushu)
4309 DEFVAREX(VhiraGaku      ,VTorNIL         ,cannaconf.doHiraganaGakushu)
4310 DEFVAREX(VChikujiContinue ,VTorNIL       ,cannaconf.ChikujiContinue)
4311 DEFVAREX(VRenbunContinue  ,VTorNIL       ,cannaconf.RenbunContinue)
4312 DEFVAREX(VMojishuContinue ,VTorNIL       ,cannaconf.MojishuContinue)
4313 DEFVAREX(VcRealBS       ,VTorNIL         ,cannaconf.chikujiRealBackspace)
4314 DEFVAREX(VIgnoreCase    ,VTorNIL         ,cannaconf.ignore_case)
4315 DEFVAREX(VRomajiYuusen  ,VTorNIL         ,cannaconf.romaji_yuusen)
4316 DEFVAREX(VAutoSync      ,VTorNIL         ,cannaconf.auto_sync)
4317 DEFVAREX(VQuicklyEscape ,VTorNIL         ,cannaconf.quickly_escape)
4318 DEFVAREX(VInhibitHankana,VTorNIL         ,cannaconf.InhibitHankakuKana)
4319 DEFVAREX(VDelayConnect  ,VTorNIL         ,cannaconf.DelayConnect)
4320 
4321 #ifdef DEFINE_SOMETHING
4322 DEFVAR(Vchikuji_debug, VTorNIL, int, chikuji_debug)
4323 #endif
4324 
4325 /* Lisp �δؿ��� C �δؿ����б�ɽ */
4326 
4327 static struct atomdefs initatom[] = {
4328   {"quote"		,SPECIAL,Lquote		},
4329   {"setq"		,SPECIAL,Lsetq		},
4330   {"set"		,SUBR	,Lset		},
4331   {"equal"		,SUBR	,Lequal		},
4332   {"="			,SUBR	,Lequal		},
4333   {">"			,SUBR	,Lgreaterp	},
4334   {"<"			,SUBR	,Llessp		},
4335   {"progn"		,SPECIAL,Lprogn		},
4336   {"eq"			,SUBR	,Leq   		},
4337   {"cond"		,SPECIAL,Lcond		},
4338   {"null"		,SUBR	,Lnull		},
4339   {"not"		,SUBR	,Lnull		},
4340   {"and"		,SPECIAL,Land		},
4341   {"or"			,SPECIAL,Lor		},
4342   {"+"			,SUBR	,Lplus		},
4343   {"-"			,SUBR	,Ldiff		},
4344   {"*"			,SUBR	,Ltimes		},
4345   {"/"			,SUBR	,Lquo		},
4346   {"%"			,SUBR	,Lrem		},
4347   {"gc"			,SUBR	,Lgc		},
4348   {"load"		,SUBR	,Lload		},
4349   {"list"		,SUBR	,Llist		},
4350   {"sequence"		,SUBR	,Llist		},
4351   {"defun"		,SPECIAL,Ldefun		},
4352   {"defmacro"		,SPECIAL,Ldefmacro	},
4353   {"cons"		,SUBR	,Lcons		},
4354   {"car"		,SUBR	,Lcar		},
4355   {"cdr"		,SUBR	,Lcdr		},
4356   {"atom"		,SUBR	,Latom		},
4357   {"let"		,CMACRO	,Llet		},
4358   {"if"			,CMACRO	,Lif		},
4359   {"boundp"		,SUBR	,Lboundp	},
4360   {"fboundp"		,SUBR	,Lfboundp	},
4361   {"getenv"		,SUBR	,Lgetenv	},
4362   {"copy-symbol"	,SUBR	,Lcopysym	},
4363   {"concat"		,SUBR	,Lconcat	},
4364   {S_FN_UseDictionary	,SUBR	,Lusedic	},
4365   {S_SetModeDisp	,SUBR	,Lmodestr	},
4366   {S_SetKey		,SUBR	,Lsetkey	},
4367   {S_GSetKey		,SUBR	,Lgsetkey	},
4368   {S_UnbindKey		,SUBR	,Lunbindkey	},
4369   {S_GUnbindKey		,SUBR	,Lgunbindkey	},
4370   {S_DefMode		,SPECIAL,Ldefmode	},
4371   {S_DefSymbol		,SPECIAL,Ldefsym	},
4372 #ifndef NO_EXTEND_MENU
4373   {S_DefSelection	,SPECIAL,Ldefselection	},
4374   {S_DefMenu		,SPECIAL,Ldefmenu	},
4375 #endif
4376   {S_SetInitFunc	,SUBR	,Lsetinifunc	},
4377   {S_defEscSequence	,SUBR	,LdefEscSeq	},
4378   {0			,UNDEF	,0		}, /* DUMMY */
4379 };
4380 
4381 static void
deflispfunc()4382 deflispfunc()
4383 {
4384   struct atomdefs *p;
4385 
4386   for (p = initatom ; p->symname ; p++) {
4387     struct atomcell *atomp;
4388     list temp;
4389 
4390     temp = getatmz(p->symname);
4391     atomp = symbolpointer(temp);
4392     atomp->ftype = p->symtype;
4393     if (atomp->ftype != UNDEF) {
4394       atomp->func = p->symfunc;
4395     }
4396   }
4397 }
4398 
4399 
4400 /* �ѿ�ɽ */
4401 
4402 static struct cannavardefs cannavars[] = {
4403   {S_VA_RomkanaTable		,Vromkana},
4404   {S_VA_EnglishTable		,Venglish},
4405   {S_VA_CursorWrap		,Vcursorw},
4406   {S_VA_SelectDirect		,Vselectd},
4407   {S_VA_NumericalKeySelect	,Vnumeric},
4408   {S_VA_BunsetsuKugiri		,Vbunsets},
4409   {S_VA_CharacterBasedMove	,Vcharact},
4410   {S_VA_ReverseWidely		,Vreverse},
4411   {S_VA_ReverseWord		,VreverseWord},
4412   {S_VA_Gakushu			,Vgakushu},
4413   {S_VA_QuitIfEOIchiran		,Vquitich},
4414   {S_VA_KakuteiIfEOBunsetsu	,Vkakutei},
4415   {S_VA_StayAfterValidate	,Vstayaft},
4416   {S_VA_BreakIntoRoman		,Vbreakin},
4417   {S_VA_NHenkanForIchiran	,Vnhenkan},
4418   {S_VA_GrammaticalQuestion	,Vgrammati},
4419   {"gramatical-question"	,Vgrammati}, /* �����Υ��ڥ�ߥ��εߺ� */
4420   {S_VA_ForceKana		,Vforceka},
4421   {S_VA_KouhoCount		,Vkouhoco},
4422   {S_VA_Auto			,Vauto},
4423   {S_VA_LearnNumericalType	,VlearnNumTy},
4424   {S_VA_BackspaceBehavesAsQuit	,VBSasQuit},
4425   {S_VA_InhibitListCallback	,Vinhibi},
4426   {S_VA_nKouhoBunsetsu		,Vnkouhobunsetsu},
4427   {S_VA_keepCursorPosition	,Vkeepcupos},
4428   {S_VA_CannaVersion		,VCannaVersion},
4429   {S_VA_Abandon			,VAbandon},
4430   {S_VA_HexDirect		,VHexStyle},
4431   {S_VA_ProtocolVersion		,VProtoVer},
4432   {S_VA_ServerVersion		,VServVer},
4433   {S_VA_ServerName		,VServName},
4434   {S_VA_CannaDir		,VCannaDir},
4435   {S_VA_Kojin			,VKojin},
4436   {S_VA_IndexHankaku	       	,VIndexHankaku},
4437   {S_VA_IndexSeparator	       	,VIndexSeparator},
4438   {S_VA_AllowNextInput		,VAllowNext},
4439   {S_VA_doKatakanaGakushu	,VkanaGaku},
4440   {S_VA_doHiraganaGakushu	,VhiraGaku},
4441 #ifdef	DEFINE_SOMETHING
4442   {S_VA_chikuji_debug		,Vchikuji_debug},
4443 #endif	/* DEFINE_SOMETHING */
4444   {S_VA_ChikujiContinue		,VChikujiContinue},
4445   {S_VA_RenbunContinue		,VRenbunContinue},
4446   {S_VA_MojishuContinue		,VMojishuContinue},
4447   {S_VA_ChikujiRealBackspace	,VcRealBS},
4448   {S_VA_nDisconnectServer	,Vndisconnect},
4449   {S_VA_ignoreCase		,VIgnoreCase},
4450   {S_VA_RomajiYuusen		,VRomajiYuusen},
4451   {S_VA_AutoSync		,VAutoSync},
4452   {S_VA_QuicklyEscape		,VQuicklyEscape},
4453   {S_VA_InhibitHanKana		,VInhibitHankana},
4454   {S_VA_CodeInput		,VCodeInput},
4455   {S_VA_DelayConnect		,VDelayConnect},
4456   {0				,0},
4457 };
4458 
4459 static void
defcannavar()4460 defcannavar()
4461 {
4462   struct cannavardefs *p;
4463 
4464   for (p = cannavars ; p->varname ; p++) {
4465     symbolpointer(getatmz(p->varname))->valfunc = p->varfunc;
4466   }
4467 }
4468 
4469 
4470 
4471 /* �⡼��ɽ */
4472 
4473 static struct cannamodedefs cannamodes[] = {
4474   {S_AlphaMode			,CANNA_MODE_AlphaMode},
4475   {S_YomiganaiMode		,CANNA_MODE_EmptyMode},
4476   {S_YomiMode			,CANNA_MODE_YomiMode},
4477   {S_MojishuMode		,CANNA_MODE_JishuMode},
4478   {S_TankouhoMode		,CANNA_MODE_TankouhoMode},
4479   {S_IchiranMode		,CANNA_MODE_IchiranMode},
4480   {S_KigouMode			,CANNA_MODE_KigoMode},
4481   {S_YesNoMode			,CANNA_MODE_YesNoMode},
4482   {S_OnOffMode			,CANNA_MODE_OnOffMode},
4483   {S_ShinshukuMode		,CANNA_MODE_AdjustBunsetsuMode},
4484 
4485   {S_AutoYomiMode		,CANNA_MODE_ChikujiYomiMode},
4486   {S_AutoBunsetsuMode		,CANNA_MODE_ChikujiTanMode},
4487 
4488   {S_HenkanNyuuryokuMode	,CANNA_MODE_HenkanNyuryokuMode},
4489   {S_HexMode			,CANNA_MODE_HexMode},
4490   {S_BushuMode			,CANNA_MODE_BushuMode},
4491   {S_ExtendMode			,CANNA_MODE_ExtendMode},
4492   {S_RussianMode		,CANNA_MODE_RussianMode},
4493   {S_GreekMode			,CANNA_MODE_GreekMode},
4494   {S_LineMode			,CANNA_MODE_LineMode},
4495   {S_ChangingServerMode		,CANNA_MODE_ChangingServerMode},
4496   {S_HenkanMethodMode		,CANNA_MODE_HenkanMethodMode},
4497   {S_DeleteDicMode		,CANNA_MODE_DeleteDicMode},
4498   {S_TourokuMode		,CANNA_MODE_TourokuMode},
4499   {S_TourokuHinshiMode		,CANNA_MODE_TourokuHinshiMode},
4500   {S_TourokuDicMode		,CANNA_MODE_TourokuDicMode},
4501   {S_QuotedInsertMode		,CANNA_MODE_QuotedInsertMode},
4502   {S_BubunMuhenkanMode		,CANNA_MODE_BubunMuhenkanMode},
4503   {S_MountDicMode		,CANNA_MODE_MountDicMode},
4504   {S_ZenHiraHenkanMode		,CANNA_MODE_ZenHiraHenkanMode},
4505   {S_HanHiraHenkanMode		,CANNA_MODE_HanHiraHenkanMode},
4506   {S_ZenKataHenkanMode		,CANNA_MODE_ZenKataHenkanMode},
4507   {S_HanKataHenkanMode		,CANNA_MODE_HanKataHenkanMode},
4508   {S_ZenAlphaHenkanMode		,CANNA_MODE_ZenAlphaHenkanMode},
4509   {S_HanAlphaHenkanMode		,CANNA_MODE_HanAlphaHenkanMode},
4510   {S_ZenHiraKakuteiMode		,CANNA_MODE_ZenHiraKakuteiMode},
4511   {S_HanHiraKakuteiMode		,CANNA_MODE_HanHiraKakuteiMode},
4512   {S_ZenKataKakuteiMode		,CANNA_MODE_ZenKataKakuteiMode},
4513   {S_HanKataKakuteiMode		,CANNA_MODE_HanKataKakuteiMode},
4514   {S_ZenAlphaKakuteiMode	,CANNA_MODE_ZenAlphaKakuteiMode},
4515   {S_HanAlphaKakuteiMode	,CANNA_MODE_HanAlphaKakuteiMode},
4516   {0				,0},
4517 };
4518 
4519 static void
defcannamode()4520 defcannamode()
4521 {
4522   struct cannamodedefs *p;
4523 
4524   for (p = cannamodes ; p->mdname ; p++) {
4525     symbolpointer(getatmz(p->mdname))->mid = p->mdid;
4526   }
4527 }
4528 
4529 
4530 
4531 /* ��ǽɽ */
4532 
4533 static struct cannafndefs cannafns[] = {
4534   {S_FN_Undefined		,CANNA_FN_Undefined},
4535   {S_FN_SelfInsert		,CANNA_FN_FunctionalInsert},
4536   {S_FN_QuotedInsert		,CANNA_FN_QuotedInsert},
4537   {S_FN_JapaneseMode		,CANNA_FN_JapaneseMode},
4538   {S_AlphaMode			,CANNA_FN_AlphaMode},
4539   {S_HenkanNyuuryokuMode	,CANNA_FN_HenkanNyuryokuMode},
4540   {S_HexMode			,CANNA_FN_HexMode},
4541   {S_BushuMode			,CANNA_FN_BushuMode},
4542   {S_KigouMode			,CANNA_FN_KigouMode},
4543   {S_FN_Forward			,CANNA_FN_Forward},
4544   {S_FN_Backward		,CANNA_FN_Backward},
4545   {S_FN_Next			,CANNA_FN_Next},
4546   {S_FN_Prev			,CANNA_FN_Prev},
4547   {S_FN_BeginningOfLine		,CANNA_FN_BeginningOfLine},
4548   {S_FN_EndOfLine		,CANNA_FN_EndOfLine},
4549   {S_FN_DeleteNext		,CANNA_FN_DeleteNext},
4550   {S_FN_DeletePrevious		,CANNA_FN_DeletePrevious},
4551   {S_FN_KillToEndOfLine		,CANNA_FN_KillToEndOfLine},
4552   {S_FN_Henkan			,CANNA_FN_Henkan},
4553   {S_FN_HenkanNaive		,CANNA_FN_HenkanOrInsert}, /* for compati */
4554   {S_FN_HenkanOrSelfInsert	,CANNA_FN_HenkanOrInsert},
4555   {S_FN_HenkanOrDoNothing	,CANNA_FN_HenkanOrNothing},
4556   {S_FN_Kakutei			,CANNA_FN_Kakutei},
4557   {S_FN_Extend			,CANNA_FN_Extend},
4558   {S_FN_Shrink			,CANNA_FN_Shrink},
4559   {S_ShinshukuMode		,CANNA_FN_AdjustBunsetsu},
4560   {S_FN_Quit			,CANNA_FN_Quit},
4561   {S_ExtendMode			,CANNA_FN_ExtendMode},
4562   {S_FN_Touroku			,CANNA_FN_Touroku},
4563   {S_FN_ConvertAsHex		,CANNA_FN_ConvertAsHex},
4564   {S_FN_ConvertAsBushu		,CANNA_FN_ConvertAsBushu},
4565   {S_FN_KouhoIchiran		,CANNA_FN_KouhoIchiran},
4566   {S_FN_BubunMuhenkan		,CANNA_FN_BubunMuhenkan},
4567   {S_FN_Zenkaku			,CANNA_FN_Zenkaku},
4568   {S_FN_Hankaku			,CANNA_FN_Hankaku},
4569   {S_FN_ToUpper			,CANNA_FN_ToUpper},
4570   {S_FN_Capitalize		,CANNA_FN_Capitalize},
4571   {S_FN_ToLower			,CANNA_FN_ToLower},
4572   {S_FN_Hiragana		,CANNA_FN_Hiragana},
4573   {S_FN_Katakana		,CANNA_FN_Katakana},
4574   {S_FN_Romaji			,CANNA_FN_Romaji},
4575   {S_FN_KanaRotate		,CANNA_FN_KanaRotate},
4576   {S_FN_RomajiRotate		,CANNA_FN_RomajiRotate},
4577   {S_FN_CaseRotate		,CANNA_FN_CaseRotate},
4578   {S_FN_BaseHiragana		,CANNA_FN_BaseHiragana},
4579   {S_FN_BaseKatakana		,CANNA_FN_BaseKatakana},
4580   {S_FN_BaseKana		,CANNA_FN_BaseKana},
4581   {S_FN_BaseEisu		,CANNA_FN_BaseEisu},
4582   {S_FN_BaseZenkaku		,CANNA_FN_BaseZenkaku},
4583   {S_FN_BaseHankaku		,CANNA_FN_BaseHankaku},
4584   {S_FN_BaseKakutei		,CANNA_FN_BaseKakutei},
4585   {S_FN_BaseHenkan		,CANNA_FN_BaseHenkan},
4586   {S_FN_BaseHiraKataToggle	,CANNA_FN_BaseHiraKataToggle},
4587   {S_FN_BaseZenHanToggle	,CANNA_FN_BaseZenHanToggle},
4588   {S_FN_BaseKanaEisuToggle	,CANNA_FN_BaseKanaEisuToggle},
4589   {S_FN_BaseKakuteiHenkanToggle	,CANNA_FN_BaseKakuteiHenkanToggle},
4590   {S_FN_BaseRotateForward	,CANNA_FN_BaseRotateForward},
4591   {S_FN_BaseRotateBackward	,CANNA_FN_BaseRotateBackward},
4592   {S_FN_Mark			,CANNA_FN_Mark},
4593   {S_FN_Temporary		,CANNA_FN_TemporalMode},
4594   {S_FN_SyncDic			,CANNA_FN_SyncDic},
4595   {S_RussianMode		,CANNA_FN_RussianMode},
4596   {S_GreekMode			,CANNA_FN_GreekMode},
4597   {S_LineMode			,CANNA_FN_LineMode},
4598   {S_FN_DefineDicMode		,CANNA_FN_DefineDicMode},
4599   {S_FN_DeleteDicMode		,CANNA_FN_DeleteDicMode},
4600   {S_FN_DicMountMode		,CANNA_FN_DicMountMode},
4601   {S_FN_EnterChikujiMode	,CANNA_FN_EnterChikujiMode},
4602   {S_FN_EnterRenbunMode		,CANNA_FN_EnterRenbunMode},
4603   {S_FN_DisconnectServer	,CANNA_FN_DisconnectServer},
4604   {S_FN_ChangeServerMode	,CANNA_FN_ChangeServerMode},
4605   {S_FN_ShowServer		,CANNA_FN_ShowServer},
4606   {S_FN_ShowGakushu		,CANNA_FN_ShowGakushu},
4607   {S_FN_ShowVersion		,CANNA_FN_ShowVersion},
4608   {S_FN_ShowPhonogramFile	,CANNA_FN_ShowPhonogramFile},
4609   {S_FN_ShowCannaFile		,CANNA_FN_ShowCannaFile},
4610   {S_FN_PageUp			,CANNA_FN_PageUp},
4611   {S_FN_PageDown		,CANNA_FN_PageDown},
4612   {S_FN_Edit			,CANNA_FN_Edit},
4613   {S_FN_BubunKakutei		,CANNA_FN_BubunKakutei},
4614   {S_FN_HenkanRegion		,CANNA_FN_HenkanRegion},
4615   {S_FN_PhonoEdit		,CANNA_FN_PhonoEdit},
4616   {S_FN_DicEdit			,CANNA_FN_DicEdit},
4617   {S_FN_Configure		,CANNA_FN_Configure},
4618   {S_FN_KanaRotate		,CANNA_FN_KanaRotate},
4619   {S_FN_RomajiRotate		,CANNA_FN_RomajiRotate},
4620   {S_FN_CaseRotate		,CANNA_FN_CaseRotate},
4621   {0				,0},
4622 };
4623 
4624 static void
defcannafunc()4625 defcannafunc()
4626 {
4627   struct cannafndefs *p;
4628 
4629   for (p = cannafns ; p->fnname ; p++) {
4630     symbolpointer(getatmz(p->fnname))->fid = p->fnid;
4631   }
4632 }
4633 
4634 
4635 static void
defatms()4636 defatms()
4637 {
4638   deflispfunc();
4639   defcannavar();
4640   defcannamode();
4641   defcannafunc();
4642   QUOTE		= getatmz("quote");
4643   T		= getatmz("t");
4644   _LAMBDA	= getatmz("lambda");
4645   _MACRO	= getatmz("macro");
4646   COND		= getatmz("cond");
4647   USER		= getatmz(":user");
4648   BUSHU		= getatmz(":bushu");
4649   RENGO		= getatmz(":rengo");
4650   KATAKANA	= getatmz(":katakana");
4651   HIRAGANA	= getatmz(":hiragana");
4652   GRAMMAR       = getatmz(":grammar");
4653   HYPHEN	= getatmz("-");
4654   symbolpointer(T)->value = T;
4655 }
4656 
4657 #ifndef wchar_t
4658 # error "wchar_t is already undefined"
4659 #endif
4660 #undef wchar_t
4661 /*********************************************************************
4662  *                       wchar_t replace end                         *
4663  *********************************************************************/
4664 /* vim: set sw=2: */
4665