0
|
1 /*
|
|
2 * $Id: rk_modread.c,v 1.2 2001/06/14 18:16:10 ura Exp $
|
|
3 */
|
|
4
|
|
5 /*
|
|
6 * FreeWnn is a network-extensible Kana-to-Kanji conversion system.
|
|
7 * This file is part of FreeWnn.
|
|
8 *
|
|
9 * Copyright Kyoto University Research Institute for Mathematical Sciences
|
|
10 * 1987, 1988, 1989, 1990, 1991, 1992
|
|
11 * Copyright OMRON Corporation. 1987, 1988, 1989, 1990, 1991, 1992, 1999
|
|
12 * Copyright ASTEC, Inc. 1987, 1988, 1989, 1990, 1991, 1992
|
|
13 *
|
|
14 * Author: OMRON SOFTWARE Co., Ltd. <freewnn@rd.kyoto.omronsoft.co.jp>
|
|
15 *
|
|
16 * This program is free software; you can redistribute it and/or modify
|
|
17 * it under the terms of the GNU General Public License as published by
|
|
18 * the Free Software Foundation; either version 2, or (at your option)
|
|
19 * any later version.
|
|
20 *
|
|
21 * This program is distributed in the hope that it will be useful,
|
|
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
24 * GNU General Public License for more details.
|
|
25 *
|
|
26 * You should have received a copy of the GNU General Public License
|
|
27 * along with GNU Emacs; see the file COPYING. If not, write to the
|
|
28 * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
29 *
|
|
30 * Commentary:
|
|
31 *
|
|
32 * Change log:
|
|
33 *
|
|
34 * Last modified date: 8,Feb.1999
|
|
35 *
|
|
36 * Code:
|
|
37 *
|
|
38 */
|
|
39 /***********************************************************************
|
|
40 rk_modread.c
|
|
41 87.11.17 改 正
|
|
42
|
|
43 モード定義表の読み込みを担当するプログラム。
|
|
44 ***********************************************************************/
|
|
45 /* Version 3.1 88/06/15 H.HASHIMOTO
|
|
46 */
|
|
47 #ifndef OMRON_LIB
|
|
48 #include "rk_header.h"
|
|
49 #include "rk_extvars.h"
|
|
50 #ifdef MULTI
|
|
51 #include "rk_multi.h"
|
|
52 #endif /*MULTI*/
|
|
53 #include <sys/types.h>
|
|
54 #include <sys/stat.h>
|
|
55 #include "rext.h"
|
|
56 #ifdef WNNDEFAULT
|
|
57 # include "config.h"
|
|
58 /* マクロLIBDIRの定義(のためだけ)。コンパイル時は、ヘッダファイルの
|
|
59 サーチパスに、Wnnのインクルードファイルのありかを設定しておくこと。 */
|
|
60 #endif
|
|
61 #include <pwd.h>
|
|
62 #endif
|
|
63 #define xyint(X, Y) (((X) << 24) | (Y))
|
|
64 #define Terminator 0 /* intの列(naibu[])の終止コード */
|
|
65 #ifdef OMRON_SPEC
|
|
66 #define mystrcmp(s1, s2) strcmp(s1, s2)
|
|
67 #define mystrcpy(s1, s2) strcpy(s1, s2)
|
|
68 #endif
|
|
69 static void cond_evl (), rd_bcksla (), rd_ctrl (), look_choose (), hyouse (), mystrcpy (), ERMOPN (), ERRMOD ();
|
|
70 static int mystrcmp (), mod_evl (), fnmsrc_tourk (), pathsrc_tourk (),
|
|
71 dspnamsrc_tourk (), modsrc_tourk (), chkchar_getc (), read1tm (), get_hmdir (), rd_string (), ctov (), scan1tm (), modnamchk (), look_cond (), evlcond ();
|
|
72 static char codeeval (), *ename ();
|
|
73
|
|
74 extern char *chrcat (), *strend ();
|
|
75
|
|
76 #ifndef MULTI
|
|
77 /* 88/05/31 V3.1 */
|
|
78 static FILE *modefile; /* モード定義表の fp */
|
|
79
|
|
80 /* 88/06/03 V3.1 */
|
|
81 /* エラー処理のためのもの */
|
|
82 static char *mcurdir; /* モード表のサーチパス */
|
|
83 static char *mcurfnm; /* モード表のファイル名 */
|
|
84 static char *mcurread; /* モード表の現在行bufへのポインタ */
|
|
85 #endif /*!MULTI */
|
|
86
|
|
87 /* キーワードとその内部表現の対応を与える構造体。内部表現を
|
|
88 持たないものに対しては0が与えられている。*/
|
|
89 struct kwdpair
|
|
90 {
|
|
91 char *name;
|
|
92 int code;
|
|
93 };
|
|
94 static /* V3.1 */
|
|
95 struct kwdpair modfn[] = {
|
|
96 "defmode", 0,
|
|
97 "if", xyint (2, 0),
|
|
98 "when", xyint (2, 1),
|
|
99 "path", 0,
|
|
100 "search", 0,
|
|
101 "on_dispmode", xyint (5, 0),
|
|
102 "off_dispmode", xyint (5, 1),
|
|
103 "on_unchg", xyint (6, 0),
|
|
104 "off_unchg", xyint (6, 1),
|
|
105 NULL
|
|
106 }; /* 下を見よ キーワード定義表はまだあと二つあるのだ */
|
|
107
|
|
108 static /* V3.1 */
|
|
109 struct kwdpair modcond[] = {
|
|
110 "not", xyint (3, 0),
|
|
111 "and", xyint (3, 1),
|
|
112 "or", xyint (3, 2),
|
|
113 "true", xyint (3, 3),
|
|
114 "false", xyint (3, 4),
|
|
115 "=", xyint (3, 5),
|
|
116 "!=", xyint (3, 6),
|
|
117 "<", xyint (3, 7),
|
|
118 ">", xyint (3, 8),
|
|
119 NULL
|
|
120 };
|
|
121 static /* V3.1 */
|
|
122 int condarg[] = { 1, 2, 2, 0, 0, 2, 2, 2, 2 }; /* 条件判断関数の引数の個数 */
|
|
123
|
|
124 static /* V3.1 */
|
|
125 struct kwdpair swstat[] = {
|
|
126 "on", 0,
|
|
127 "off", 0,
|
|
128 NULL
|
|
129 };
|
|
130
|
|
131 /** キーワード(if, andなど)が正当なものかチェックし、その番号を返す */
|
|
132 static /* V3.1 */
|
|
133 int
|
|
134 kwdsrc (hyou, wd)
|
|
135 struct kwdpair *hyou; /* どのキーワード表を使うか */
|
|
136 char *wd; /* チェックされるキーワード */
|
|
137 {
|
|
138 fast int i; /* V3.1 */
|
|
139
|
|
140 for (i = 0; hyou[i].name != NULL; i++)
|
|
141 if (!mystrcmp (hyou[i].name, wd))
|
|
142 return (i);
|
|
143 ERRMOD (9);
|
|
144 /*NOTREACHED*/ return (-1);
|
|
145 }
|
|
146
|
|
147 /** 与えられたファイルがディレクトリなら非0を返す */
|
|
148 static /* V3.1 */
|
|
149 int
|
|
150 isdir (fnm)
|
|
151 char *fnm;
|
|
152 {
|
|
153 struct stat statbuf;
|
|
154
|
|
155 /* Bug!!! 88/07/20 H.HASHIMOTO */
|
|
156 /* return(stat(fnm, &statbuf) == 0 && (statbuf.st_mode & S_IFDIR)); */
|
|
157 return (stat (fnm, &statbuf) == 0 && ((statbuf.st_mode & S_IFMT) == S_IFDIR));
|
|
158 }
|
|
159
|
|
160 /* 88/06/10 V3.1 */
|
|
161 /** モード表の読み込み */
|
|
162 #ifdef OMRON_LIB
|
|
163 static
|
|
164 #endif
|
|
165 int
|
|
166 readmode (filename)
|
|
167 char *filename; /* ユーザが指定したモード表の名 */
|
|
168 {
|
|
169 #ifndef MULTI
|
|
170 char modefilename[REALFN + 5]; /* V3.1 */
|
|
171 char pathname[REALFN]; /* V3.1 */
|
|
172 #endif /*!MULTI */
|
|
173
|
|
174 struct stat statbuf; /* V3.1 */
|
|
175 char *buf, *bufp; /* V3.1 */
|
|
176
|
|
177 #ifdef RKMODPATH
|
|
178 char *genv, *pathenv, *pathp;
|
|
179 extern char *getenv (); /* V3.1 */
|
|
180 #endif
|
|
181
|
|
182 /* 88/06/14 V3.1 */
|
|
183 /* モード定義表のパス名の長さチェックを安全性のために、
|
|
184 付け加えておきます。 */
|
|
185 cur_rk_table->mcurdir = ""; /* エラー処理用 *//* V3.1 */
|
|
186 if (strlen (cur_rk_table->mcurfnm = filename) > (REALFN - 1)) /* V3.1 */
|
|
187 ERMOPN (3); /* V3.1 */
|
|
188 strcpy (cur_rk_table->modefilename, filename);
|
|
189 if (*(cur_rk_table->modefilename) == '\0' || *(strend (cur_rk_table->modefilename)) == KUGIRI)
|
|
190 {
|
|
191 strcat (cur_rk_table->modefilename, "mode");
|
|
192 }
|
|
193 else if (isdir (cur_rk_table->modefilename))
|
|
194 {
|
|
195 chrcat (cur_rk_table->modefilename, KUGIRI);
|
|
196 strcat (cur_rk_table->modefilename, "mode");
|
|
197 }
|
|
198 /* 88/06/14 V3.1 */
|
|
199 if (strlen (cur_rk_table->mcurfnm = cur_rk_table->modefilename) > (REALFN - 1)) /* V3.1 */
|
|
200 ERMOPN (3); /* V3.1 */
|
|
201
|
|
202 #ifdef RKMODPATH
|
|
203 /* 88/06/10 V3.1 */
|
|
204 if (!fixednamep (cur_rk_table->modefilename) && (pathenv = genv = getenv (RKMODPATH)) != NULL && *genv != '\0')
|
|
205 {
|
|
206 /* PATHに少なくとも一つのサーチパスがある場合 */
|
|
207 for (;;)
|
|
208 {
|
|
209 for (pathp = cur_rk_table->pathname; *genv != ':' && *genv; genv++)
|
|
210 *pathp++ = *genv;
|
|
211 *pathp = '\0';
|
|
212
|
|
213 if (*(strend (cur_rk_table->pathname)) != KUGIRI)
|
|
214 *pathp++ = KUGIRI;
|
|
215 /* pathの区切りはDG(MV)であっても'/' */
|
|
216
|
|
217 strcpy (pathp, cur_rk_table->modefilename);
|
|
218 if ((stat (cur_rk_table->pathname, &statbuf) == 0) && ((cur_rk_table->modefile = fopen (cur_rk_table->pathname, "r")) != NULL))
|
|
219 {
|
|
220 /* Now Mode-hyo found */
|
|
221 /*
|
|
222 if (cur_rk->flags & RK_VERBOS) {
|
|
223 fprintf(stderr,
|
|
224 "romkan: using Mode-hyo %s ...\r\n",
|
|
225 pathname);
|
|
226 }
|
|
227 */
|
|
228 cur_rk_table->mcurdir = cur_rk_table->pathname;
|
|
229 /* この時点ではファイル名込みだが、
|
|
230 あとでパス名だけになる */
|
|
231 cur_rk_table->mcurfnm = ename (cur_rk_table->modefilename); /* V3.1 */
|
|
232 break;
|
|
233 }
|
|
234
|
|
235 if (*genv != ':')
|
|
236 {
|
|
237 /* Mode-hyo not found */
|
|
238 /*
|
|
239 if (flags & RK_VERBOS){
|
|
240 fprintf(stderr,
|
|
241 "no %s in ",cur_rk->modefilename);
|
|
242 for(genv = pathenv; *genv; genv++){
|
|
243 fputc((*genv == ':' ?
|
|
244 ' ' : *genv), stderr);
|
|
245 }
|
|
246 fprintf(stderr, ".\n");
|
|
247 }
|
|
248 */
|
|
249 ERMOPN (1);
|
|
250 }
|
|
251 /* coutinues searching Mode-hyo */
|
|
252 genv++;
|
|
253 }
|
|
254 }
|
|
255 else
|
|
256 #endif
|
|
257 {
|
|
258 /* 88/06/10 V3.1 */
|
|
259 if (stat (cur_rk_table->modefilename, &statbuf) != 0)
|
|
260 ERMOPN (1);
|
|
261 if ((cur_rk_table->modefile = fopen (cur_rk_table->modefilename, "r")) == NULL)
|
|
262 ERMOPN (2);
|
|
263 /*
|
|
264 if (cur_rk->flags & RK_VERBOS) {
|
|
265 fprintf(stderr, "romkan: using Mode-hyo %s ...\r\n",
|
|
266 cur_rk->modefilename);
|
|
267 }
|
|
268 */
|
|
269 strcpy (cur_rk_table->pathname, cur_rk_table->modefilename);
|
|
270 }
|
|
271
|
|
272 /* サーチパスの先頭に、モード表のあるディレクトリを設定している。 */
|
|
273 *(ename (cur_rk_table->pathname)) = '\0'; /* V3.1 */
|
|
274 pathsrc_tourk (cur_rk_table->pathname); /* V3.1 */
|
|
275
|
|
276 /* 88/06/14 V3.1 */
|
|
277 malloc_for_modenaibu (&(cur_rk_table->rk_modenaibu), statbuf.st_size + 1);
|
|
278 *(cur_rk_table->rk_modenaibu.next) = Terminator;
|
|
279
|
|
280 malloc_for_modebuf (&(cur_rk_table->rk_modebuf), statbuf.st_size + 1);
|
|
281 cur_rk_table->mcurread = buf = cur_rk_table->rk_modebuf.org; /* エラー処理用 *//* V3.1 */
|
|
282
|
|
283 /* モード定義表の読み込み */
|
|
284 while (bufp = buf, read1tm (&bufp, 0)) /* V3.1 */
|
|
285 mod_evl (buf); /* V3.1 */
|
|
286 fclose (cur_rk_table->modefile);
|
|
287
|
|
288 /* 88/06/14 V3.1 */
|
|
289 free_for_modebuf (&(cur_rk_table->rk_modebuf));
|
|
290 realloc_for_modenaibu (&(cur_rk_table->rk_modenaibu));
|
|
291
|
|
292 return (cur_rk_table->rk_taiouhyo.count); /* V3.1 */
|
|
293 }
|
|
294
|
|
295 /** モード表の一かたまり(リスト、ファイル名、モード表示文字列)を
|
|
296 解釈する。返す値は、defmode,search及びpathの時0、それ以外なら1。*/
|
|
297 static /* V3.1 */
|
|
298 int
|
|
299 mod_evl (s)
|
|
300 char *s; /* モード表の内部表現の列へのポインタ */
|
|
301 {
|
|
302 char md1[MDT1LN]; /* V3.1 */
|
|
303 fast char *bgn, *end; /* V3.1 */
|
|
304 fast int num, retval = 1; /* V3.1 */
|
|
305
|
|
306 if (*s != '(')
|
|
307 {
|
|
308 if (*s != '"')
|
|
309 {
|
|
310 num = fnmsrc_tourk (s);
|
|
311 *(cur_rk_table->rk_modenaibu.next++) = xyint (4, num);
|
|
312 }
|
|
313 else
|
|
314 {
|
|
315 s++;
|
|
316 if (*(end = strend (s)) != '"')
|
|
317 ERRMOD (10);
|
|
318 *end = '\0';
|
|
319 num = dspnamsrc_tourk (s);
|
|
320 *(cur_rk_table->rk_modenaibu.next++) = xyint (5, 0);
|
|
321 *(cur_rk_table->rk_modenaibu.next++) = num;
|
|
322 }
|
|
323 }
|
|
324 else
|
|
325 {
|
|
326 s++;
|
|
327 scan1tm (&s, md1, 1);
|
|
328 switch (num = kwdsrc (modfn, md1))
|
|
329 {
|
|
330 case 0: /* defmode */
|
|
331 retval = 0;
|
|
332 scan1tm (&s, md1, 1); /* modename */
|
|
333 num = modsrc_tourk (md1, 0);
|
|
334 if (scan1tm (&s, md1, 0))
|
|
335 { /* 初期on-off */
|
|
336 switch (kwdsrc (swstat, md1))
|
|
337 {
|
|
338 case 0:
|
|
339 cur_rk_table->rk_modesw.point[num] = 1;
|
|
340 break;
|
|
341 case 1:
|
|
342 cur_rk_table->rk_modesw.point[num] = 0;
|
|
343 break;
|
|
344 }
|
|
345 scan1tm (&s, md1, 2); /* あればerr */
|
|
346 }
|
|
347 else
|
|
348 cur_rk_table->rk_modesw.point[num] = 0; /* defaultはoff */
|
|
349 break;
|
|
350 case 1: /* if */
|
|
351 case 2: /* when */
|
|
352 *(cur_rk_table->rk_modenaibu.next++) = modfn[num].code;
|
|
353 scan1tm (&s, md1, 1); /* condition */
|
|
354 cond_evl (md1);
|
|
355 while (scan1tm (&s, md1, 0))
|
|
356 {
|
|
357 if (mod_evl (md1) == 0)
|
|
358 ERRMOD (8);
|
|
359 }
|
|
360 *(cur_rk_table->rk_modenaibu.next++) = Terminator;
|
|
361 break;
|
|
362 case 3: /* path */
|
|
363 /* 88/06/09 V3.1 */
|
|
364 cur_rk_table->rk_path.count = 1;
|
|
365 cur_rk_table->rk_path.next = cur_rk_table->rk_path.point[1];
|
|
366 case 4: /* search */
|
|
367 retval = 0;
|
|
368 /* 88/06/29 V3.1 */
|
|
369 if (cur_rk_table->rk_taiouhyo.point[0] != NULL)
|
|
370 ERRMOD (11);
|
|
371 /* サーチパスの指定はファイル名の出現より
|
|
372 先行しなければならないとしておく。 */
|
|
373
|
|
374 while (scan1tm (&s, md1, 0))
|
|
375 { /* find pathname */
|
|
376 pathsrc_tourk (md1);
|
|
377 }
|
|
378 break;
|
|
379 case 5: /* on_dispmode */
|
|
380 case 6: /* off_dispmode */
|
|
381 *(cur_rk_table->rk_modenaibu.next++) = modfn[num].code;
|
|
382 scan1tm (&s, md1, 1); /* dispmode string */
|
|
383
|
|
384 if (*(bgn = md1) != '"')
|
|
385 ERRMOD (12);
|
|
386 bgn++;
|
|
387 if (*(end = strend (bgn)) != '"')
|
|
388 ERRMOD (10);
|
|
389 *end = '\0';
|
|
390 *(cur_rk_table->rk_modenaibu.next++) = dspnamsrc_tourk (bgn);
|
|
391 scan1tm (&s, md1, 2); /* あればerr */
|
|
392 break;
|
|
393 case 7: /* on-unchg */
|
|
394 case 8: /* off-unchg */
|
|
395 *(cur_rk_table->rk_modenaibu.next++) = modfn[num].code;
|
|
396 scan1tm (&s, md1, 2); /* あればerr */
|
|
397 break;
|
|
398 }
|
|
399
|
|
400 }
|
|
401 *(cur_rk_table->rk_modenaibu.next) = Terminator;
|
|
402 return (retval);
|
|
403 }
|
|
404
|
|
405 /** 条件式(モード名 又はnot,andなどの式)一つを解釈 */
|
|
406 static /* V3.1 */
|
|
407 void
|
|
408 cond_evl (cod)
|
|
409 char *cod; /* 条件式の内部表現の列へのポインタ */
|
|
410 {
|
|
411 char md1[MDT1LN];
|
|
412 fast int num, i; /* V3.1 */
|
|
413
|
|
414 if (*cod != '(')
|
|
415 {
|
|
416 num = modsrc_tourk (cod, 1);
|
|
417 *(cur_rk_table->rk_modenaibu.next++) = xyint (1, num);
|
|
418 }
|
|
419 else
|
|
420 {
|
|
421 cod++;
|
|
422 scan1tm (&cod, md1, 1); /* not;and;or */
|
|
423 num = kwdsrc (modcond, md1);
|
|
424 *(cur_rk_table->rk_modenaibu.next++) = xyint (3, num);
|
|
425 for (i = condarg[num]; i; i--)
|
|
426 {
|
|
427 scan1tm (&cod, md1, 0);
|
|
428 cond_evl (md1);
|
|
429 }
|
|
430 scan1tm (&cod, md1, 2);
|
|
431 }
|
|
432 *(cur_rk_table->rk_modenaibu.next) = Terminator;
|
|
433 }
|
|
434
|
|
435 /* 88/06/09 V3.1 */
|
|
436 static int
|
|
437 serach_in_modetable_struct (ptr, s, np)
|
|
438 fast modetable *ptr;
|
|
439 fast char *s;
|
|
440 fast int *np;
|
|
441 {
|
|
442 fast int n;
|
|
443
|
|
444 for (n = 0; n < ptr->count; n++)
|
|
445 {
|
|
446 if (!mystrcmp (ptr->point[n], s))
|
|
447 {
|
|
448 *np = n;
|
|
449 return (1); /* found */
|
|
450 }
|
|
451 }
|
|
452 *np = n;
|
|
453 return (0); /* not found */
|
|
454 }
|
|
455
|
|
456 /* 88/06/13 V3.1 */
|
|
457 static void
|
|
458 entry_to_modetable_struct (ptr, n, s)
|
|
459 fast modetable *ptr;
|
|
460 int n;
|
|
461 char *s;
|
|
462 {
|
|
463 ptr->point[n] = ptr->next;
|
|
464 mystrcpy (ptr->next, s);
|
|
465 strtail (ptr->next);
|
|
466 ++(ptr->next);
|
|
467 }
|
|
468
|
|
469
|
|
470 /* 88/06/07 V3.1 */
|
|
471 /** sで指定されたファイル名が既登録か探し、なければ登録。但し、既登録か
|
|
472 どうかのチェックは厳密ではないが(例えば、同じファイルでも、
|
|
473 パス名付きと無しとでは、同じと見ない)、ファイル名が既登録かどうか
|
|
474 チェックするのは、メモリ節約のために同じ表を読み込むのを防ぐため
|
|
475 だけなので、それ以外には別に困る点はない。*/
|
|
476 static /* V3.1 */
|
|
477 int
|
|
478 fnmsrc_tourk (s)
|
|
479 char *s;
|
|
480 {
|
|
481 int n;
|
|
482
|
|
483 if (serach_in_modetable_struct (&(cur_rk_table->rk_taiouhyo), s, &n))
|
|
484 return (n);
|
|
485
|
|
486 check_and_realloc_for_modetable_struct (&(cur_rk_table->rk_taiouhyo), n, s, RK_TAIOUHYO_MAX_LOT, RK_TAIOUHYO_MEM_LOT);
|
|
487
|
|
488 /* チェックのみ */
|
|
489 if (!(filnamchk (s)))
|
|
490 ERRMOD (3);
|
|
491
|
|
492 entry_to_modetable_struct (&(cur_rk_table->rk_taiouhyo), n, s);
|
|
493 return (n);
|
|
494 }
|
|
495
|
|
496 /* 88/06/07 V3.1 */
|
|
497 /** sで指定されたサーチパス名が既登録か探し、なければ登録。但し、fnmsrc_
|
|
498 tourk()同様、既登録かどうかのチェックは厳密ではないが問題ない。*/
|
|
499 /* 88/06/07 V3.1 */
|
|
500 static /* V3.1 */
|
|
501 int
|
|
502 pathsrc_tourk (s)
|
|
503 char *s;
|
|
504 {
|
|
505 int n;
|
|
506 char fnm_addsla[MDT1LN];
|
|
507
|
|
508 mystrcpy (fnm_addsla, s);
|
|
509 if (!(*fnm_addsla == '\0' || *(strend (fnm_addsla)) == KUGIRI))
|
|
510 chrcat (fnm_addsla, KUGIRI);
|
|
511 s = fnm_addsla;
|
|
512 /* パス名が'/'で終わってなければ、それを付加する。 */
|
|
513
|
|
514 if (serach_in_modetable_struct (&(cur_rk_table->rk_path), s, &n))
|
|
515 return (n);
|
|
516
|
|
517 check_and_realloc_for_modetable_struct (&(cur_rk_table->rk_path), n, s, RK_PATH_MAX_LOT, RK_PATH_MEM_LOT);
|
|
518
|
|
519 entry_to_modetable_struct (&(cur_rk_table->rk_path), n, s);
|
|
520 return (n);
|
|
521 }
|
|
522
|
|
523 /* 88/06/07 V3.1 */
|
|
524 /** sで指定されたモード表示文字列が既登録か探し、なければ登録 */
|
|
525 static /* V3.1 */
|
|
526 int
|
|
527 dspnamsrc_tourk (s)
|
|
528 char *s;
|
|
529 {
|
|
530 int n;
|
|
531
|
|
532 if (serach_in_modetable_struct (&(cur_rk_table->rk_dspmode), s, &n))
|
|
533 return (n);
|
|
534
|
|
535 check_and_realloc_for_modetable_struct (&(cur_rk_table->rk_dspmode), n, s, RK_DSPMODE_MAX_LOT, RK_DSPMODE_MEM_LOT);
|
|
536
|
|
537 entry_to_modetable_struct (&(cur_rk_table->rk_dspmode), n, s);
|
|
538 return (n);
|
|
539 }
|
|
540
|
|
541 /* 88/06/09 V3.1 */
|
|
542 /** sで指定されたモード名を探し、なければ登録。但し、flgが非0なら、
|
|
543 見つからなければエラー */
|
|
544 static /* V3.1 */
|
|
545 int
|
|
546 modsrc_tourk (s, flg)
|
|
547 char *s;
|
|
548 int flg;
|
|
549 {
|
|
550 int n;
|
|
551
|
|
552 if (!modnamchk (s))
|
|
553 ERRMOD (4); /* V3.1 */
|
|
554
|
|
555 if (serach_in_modetable_struct (&(cur_rk_table->rk_defmode), s, &n))
|
|
556 return (n);
|
|
557
|
|
558 if (flg)
|
|
559 ERRMOD (5);
|
|
560
|
|
561 check_and_realloc_for_modetable_struct (&(cur_rk_table->rk_defmode), n, s, RK_DEFMODE_MAX_LOT, RK_DEFMODE_MEM_LOT);
|
|
562
|
|
563 check_and_realloc_for_modesw (&(cur_rk_table->rk_modesw), n, RK_DEFMODE_MAX_LOT, RK_DEFMODE_MEM_LOT);
|
|
564
|
|
565 entry_to_modetable_struct (&(cur_rk_table->rk_defmode), n, s);
|
|
566 return (n);
|
|
567 }
|
|
568
|
|
569 /** ファイルから一文字読む(空白文字は飛ばす)。読んだ文字がEOFなら0を返す */
|
|
570 static /* V3.1 */
|
|
571 char
|
|
572 fspcpass ()
|
|
573 {
|
|
574 fast int c; /* V3.1 */
|
|
575
|
|
576 while (EOF != (c = chkchar_getc (cur_rk_table->modefile)) && is_nulsp (c));
|
|
577 return (c == EOF ? '\0' : c);
|
|
578 }
|
|
579
|
|
580 /** モード表には空白文字以外のコントロール文字は生では混じらないものと
|
|
581 する。混じっていた場合はチェックしつつ、getcを行う。*/
|
|
582 static /* V3.1 */
|
|
583 int
|
|
584 chkchar_getc (f)
|
|
585 fast FILE *f;
|
|
586 {
|
|
587 fast int c; /* V3.1 */
|
|
588
|
|
589 c = getc (f);
|
|
590 if (is_cntrl (c) && !isspace (c))
|
|
591 {
|
|
592 sprintf (cur_rk_table->mcurread, "\\%03o", c);
|
|
593 ERRMOD (16);
|
|
594 }
|
|
595 return (c);
|
|
596 }
|
|
597
|
|
598 /** モード表の一かたまり(リスト、ファイル名、モード表示文字列)を
|
|
599 切り出す。その際、特殊な表記('^','\'による)は、'\(8進);' の
|
|
600 形に直す。flgが非0なら、EOFでエラーを起こし、')'で0を返す。*/
|
|
601 static /* V3.1 */
|
|
602 int
|
|
603 read1tm (sptr, flg)
|
|
604 char **sptr; /* モード表の内部表現の列へのポインタへのポインタ。
|
|
605 rd_bcksla()、rd_ctrl()、codeeval()でも同様 */
|
|
606 int flg;
|
|
607 {
|
|
608 fast int c; /* V3.1 */
|
|
609 fast char *head; /* V3.1 */
|
|
610 int retval = 1; /* V3.1 */
|
|
611 char *s; /* V3.1 */
|
|
612
|
|
613 s = *sptr;
|
|
614
|
|
615 while ((c = fspcpass ()) == ';')
|
|
616 {
|
|
617 /* 注釈文を検出したら、行末までとばして再試行。 */
|
|
618 while ((c = chkchar_getc (cur_rk_table->modefile)) != '\n' && c != EOF);
|
|
619 }
|
|
620
|
|
621 switch (c)
|
|
622 {
|
|
623 case '\0': /* EOFを表す */
|
|
624 if (flg)
|
|
625 ERRMOD (0);
|
|
626 else
|
|
627 retval = 0;
|
|
628 break;
|
|
629 case ')':
|
|
630 if (flg)
|
|
631 retval = 0;
|
|
632 else
|
|
633 ERRMOD (1);
|
|
634 break;
|
|
635 case '(':
|
|
636 *s++ = c;
|
|
637 *s++ = ' ';
|
|
638 while (read1tm (&s, 1))
|
|
639 *s++ = ' ';
|
|
640 *s++ = ')';
|
|
641 break;
|
|
642 case '"':
|
|
643 *s++ = c;
|
|
644 while ((c = chkchar_getc (cur_rk_table->modefile)) != '"')
|
|
645 {
|
|
646 switch (c)
|
|
647 {
|
|
648 case EOF:
|
|
649 ERRMOD (0);
|
|
650 #ifndef OMRON_SPEC
|
|
651 case '\\':
|
|
652 rd_bcksla (&s);
|
|
653 break;
|
|
654 case '^':
|
|
655 rd_ctrl (&s);
|
|
656 break;
|
|
657 #endif
|
|
658 default:
|
|
659 *s++ = c;
|
|
660 }
|
|
661 }
|
|
662 *s++ = '"';
|
|
663 break;
|
|
664 default:
|
|
665 /* 先頭が @ 又は ~ の時は、特殊処理。 */
|
|
666 if (c == '@')
|
|
667 { /* @HOME, @MODEDIR, @LIBDIR */
|
|
668 *s++ = c;
|
|
669 head = s;
|
|
670 rd_string (&s, 1);
|
|
671
|
|
672 if (mystrcmp ("HOME", head) == 0)
|
|
673 {
|
|
674 s = --head;
|
|
675 if (get_hmdir (&s, (char *) NULL) != 0)
|
|
676 {
|
|
677 cur_rk_table->mcurread = head;
|
|
678 /* エラー表示の調整。抜けずにすぐにエラー表示
|
|
679 ルーチンに行くのでheadの中身は失われない。 */
|
|
680 ERRMOD (13);
|
|
681 }
|
|
682 }
|
|
683 else if (mystrcmp ("MODEDIR", head) == 0)
|
|
684 {
|
|
685 /* 88/06/09 V3.1 */
|
|
686 strcpy (s = --head, cur_rk_table->rk_path.point[0]);
|
|
687 if (KUGIRI == *(s = strend (s)))
|
|
688 *s = '\0';
|
|
689 }
|
|
690 else
|
|
691 #ifdef WNNDEFAULT
|
|
692 if (mystrcmp ("LIBDIR", head) == 0)
|
|
693 {
|
|
694 strcpy (s = --head, LIBDIR);
|
|
695 strtail (s);
|
|
696 }
|
|
697 else
|
|
698 #endif
|
|
699 {
|
|
700 cur_rk_table->mcurread = --head;
|
|
701 ERRMOD (14);
|
|
702 }
|
|
703 }
|
|
704 else if (c == '~')
|
|
705 { /* ~user */
|
|
706 *s++ = c;
|
|
707 head = s;
|
|
708 rd_string (&s, 1);
|
|
709
|
|
710 mystrcpy (head, head);
|
|
711 s = head - 1;
|
|
712 if ((get_hmdir (&s, (*head ? head : NULL))) != 0)
|
|
713 {
|
|
714 cur_rk_table->mcurread = --head;
|
|
715 /* エラー表示の調整 */
|
|
716 ERRMOD (15);
|
|
717 }
|
|
718 }
|
|
719 else
|
|
720 {
|
|
721 ungetc (c, cur_rk_table->modefile);
|
|
722 }
|
|
723 /* 先頭の特殊処理 終わり */
|
|
724
|
|
725 if ((c = rd_string (&s, 0)) == EOF && flg)
|
|
726 ERRMOD (0);
|
|
727 if (c == ')' && !flg)
|
|
728 ERRMOD (1);
|
|
729 }
|
|
730
|
|
731 *s = '\0';
|
|
732 *sptr = s;
|
|
733 return (retval);
|
|
734 }
|
|
735
|
|
736 /* 88/06/03 V3.1 */
|
|
737 /** socの名のユーザのログイン・ディレクトリ名をdestに入れ、*destにその末尾を
|
|
738 指させる。但しsocが空列または、NULLなら自分のログイン・ディレクトリ名、
|
|
739 いずれの場合も、不成功時は、何もしない。返値は、不成功時-1。*/
|
|
740 static /* V3.1 */
|
|
741 int
|
|
742 get_hmdir (dest, soc)
|
|
743 char **dest, *soc;
|
|
744 {
|
|
745 fast struct passwd *usr; /* V3.1 */
|
|
746 extern struct passwd *getpwnam (), *getpwuid (); /* V3.1 */
|
|
747
|
|
748 /* 88/05/26 V3.1 */
|
|
749 if (soc == NULL || *soc == '\0')
|
|
750 {
|
|
751 if (NULL == (usr = getpwuid (getuid ())))
|
|
752 return (-1);
|
|
753 }
|
|
754 else
|
|
755 {
|
|
756 if (NULL == (usr = getpwnam (soc)))
|
|
757 return (-1);
|
|
758 }
|
|
759 strcpy (*dest, usr->pw_dir);
|
|
760 strtail (*dest);
|
|
761 return (0);
|
|
762 }
|
|
763
|
|
764
|
|
765
|
|
766 /** モード表・対応表中の、ファイル名の部分の読み込み。先頭が @ 又は ~ の
|
|
767 時は、特殊処理を行う。引数は、一字読み込み・一字戻し・文字列取り出しの
|
|
768 関数と、結果を入れるエリアの番地へのポインタ、次に読まれる文字を入れる
|
|
769 ポインタ。返値は、正常終了時0、@HOMEでホーム・ディレクトリが取れない時
|
|
770 1、@のあとに変なものが来たら2、~で自分のホーム・ディレクトリが取れない
|
|
771 時3、~のあとに存在しないユーザ名が来たら4。*/
|
|
772 int
|
|
773 readfnm (readchar_func, unreadc_func, readstr_func, areap, lastcptr)
|
|
774 register int (*readchar_func) (), (*unreadc_func) (), (*readstr_func) ();
|
|
775 char **areap;
|
|
776 int *lastcptr;
|
|
777 {
|
|
778 char *head;
|
|
779 register int c;
|
|
780
|
|
781 c = (*readchar_func) ();
|
|
782 if (c == '@')
|
|
783 { /* @HOME, @MODEDIR, @LIBDIR */
|
|
784 *(*areap)++ = c;
|
|
785 head = *areap;
|
|
786 (*readstr_func) (areap, 1);
|
|
787
|
|
788 if (mystrcmp ("HOME", head) == 0)
|
|
789 {
|
|
790 *areap = --head;
|
|
791 if (get_hmdir (areap, (char *) NULL) != 0)
|
|
792 {
|
|
793 *areap = head;
|
|
794 return (1);
|
|
795 }
|
|
796 }
|
|
797 else if (mystrcmp ("MODEDIR", head) == 0)
|
|
798 {
|
|
799 strcpy (*areap = --head, cur_rk_table->pathname);
|
|
800 if (KUGIRI == *(*areap = strend (*areap)))
|
|
801 **areap = '\0';
|
|
802 }
|
|
803 else
|
|
804 #ifdef WNNDEFAULT
|
|
805 if (mystrcmp ("LIBDIR", head) == 0)
|
|
806 {
|
|
807 strcpy (*areap = --head, LIBDIR);
|
|
808 strtail (*areap);
|
|
809 }
|
|
810 else
|
|
811 #endif
|
|
812 {
|
|
813 *areap = --head;
|
|
814 return (2);
|
|
815 }
|
|
816
|
|
817 }
|
|
818 else if (c == '~')
|
|
819 { /* ~user */
|
|
820 int err;
|
|
821
|
|
822 *(*areap)++ = c;
|
|
823 head = *areap;
|
|
824 (*readstr_func) (areap, 1);
|
|
825
|
|
826 mystrcpy (head, head);
|
|
827 *areap = head - 1;
|
|
828 if ((err = get_hmdir (areap, (*head ? head : NULL))) != 0)
|
|
829 {
|
|
830 *areap = --head;
|
|
831 return (err == -2 ? 3 : 4);
|
|
832 }
|
|
833
|
|
834 }
|
|
835 else
|
|
836 {
|
|
837 (*unreadc_func) (c);
|
|
838 }
|
|
839
|
|
840 *lastcptr = (*readstr_func) (areap, 0);
|
|
841 return (0);
|
|
842 }
|
|
843
|
|
844 /** モード表から一文字分取り出す作業を、空白・EOF・括弧のどれかが来るまで
|
|
845 続ける。flgが非0なら、'/'が来ても終わる。返値は、次に読まれる文字。*/
|
|
846 static /* V3.1 */
|
|
847 int
|
|
848 rd_string (sptr, flg)
|
|
849 char **sptr;
|
|
850 int flg;
|
|
851 {
|
|
852 fast int c; /* V3.1 */
|
|
853
|
|
854 while (c = chkchar_getc (cur_rk_table->modefile), !(is_nulsp (c) || c == EOF || c == '(' || c == ')' || (flg == 1 && c == KUGIRI)))
|
|
855 {
|
|
856 switch (c)
|
|
857 {
|
|
858 #ifndef OMRON_SPEC
|
|
859 case '\\':
|
|
860 rd_bcksla (sptr);
|
|
861 break;
|
|
862 case '^':
|
|
863 rd_ctrl (sptr);
|
|
864 break;
|
|
865 #endif
|
|
866 default:
|
|
867 *(*sptr)++ = c;
|
|
868 }
|
|
869 }
|
|
870 **sptr = '\0';
|
|
871 return (ungetc (c, cur_rk_table->modefile));
|
|
872 }
|
|
873
|
|
874 /* 88/06/02 V3.1 */
|
|
875 #ifndef OMRON_SPEC
|
|
876 /** モード表からバックスラッシュ形式の一文字分を取り出し、'\(8進);' の
|
|
877 形に直す。但し、先頭の'\\'は既に読まれたあと。*/
|
|
878 static /* V3.1 */
|
|
879 void
|
|
880 rd_bcksla (sptr)
|
|
881 char **sptr;
|
|
882 {
|
|
883 fast int c, code = 0, digflg = 0; /* V3.1 */
|
|
884
|
|
885 switch (c = chkchar_getc (cur_rk_table->modefile))
|
|
886 {
|
|
887 case 'n':
|
|
888 code = '\n';
|
|
889 digflg = 1;
|
|
890 break;
|
|
891 case 't':
|
|
892 code = '\t';
|
|
893 digflg = 1;
|
|
894 break;
|
|
895 case 'b':
|
|
896 code = '\b';
|
|
897 digflg = 1;
|
|
898 break;
|
|
899 case 'r':
|
|
900 code = '\r';
|
|
901 digflg = 1;
|
|
902 break;
|
|
903 case 'f':
|
|
904 code = '\f';
|
|
905 digflg = 1;
|
|
906 break;
|
|
907 case 'e':
|
|
908 case 'E':
|
|
909 code = ESCCHR;
|
|
910 digflg = 1;
|
|
911 break;
|
|
912 case 'o':
|
|
913 while (c = chkchar_getc (cur_rk_table->modefile), is_octal (c))
|
|
914 {
|
|
915 code <<= 3;
|
|
916 code += ctov (c);
|
|
917 digflg = 1;
|
|
918 }
|
|
919 if (c != ';')
|
|
920 ungetc (c, cur_rk_table->modefile);
|
|
921 break;
|
|
922 case 'd':
|
|
923 while (c = chkchar_getc (cur_rk_table->modefile), is_digit (c))
|
|
924 {
|
|
925 code *= 10;
|
|
926 code += ctov (c);
|
|
927 digflg = 1;
|
|
928 }
|
|
929 if (c != ';')
|
|
930 ungetc (c, cur_rk_table->modefile);
|
|
931 break;
|
|
932 case 'x':
|
|
933 while (c = chkchar_getc (cur_rk_table->modefile), is_xdigit (c))
|
|
934 {
|
|
935 code <<= 4;
|
|
936 code += ctov (c);
|
|
937 digflg = 1;
|
|
938 }
|
|
939 if (c != ';')
|
|
940 ungetc (c, cur_rk_table->modefile);
|
|
941 break;
|
|
942 default:
|
|
943 if (is_octal (c))
|
|
944 {
|
|
945 digflg = 1;
|
|
946 code = ctov (c);
|
|
947 while (c = chkchar_getc (cur_rk_table->modefile), is_octal (c))
|
|
948 {
|
|
949 code <<= 3;
|
|
950 code += ctov (c);
|
|
951 }
|
|
952 if (c != ';')
|
|
953 ungetc (c, cur_rk_table->modefile);
|
|
954 }
|
|
955 else
|
|
956 {
|
|
957 code = c;
|
|
958 digflg = 1;
|
|
959 }
|
|
960 }
|
|
961
|
|
962 if (digflg == 0)
|
|
963 ERRMOD (7);
|
|
964 sprintf (*sptr, "\\%o;", code);
|
|
965 strtail (*sptr);
|
|
966 }
|
|
967
|
|
968
|
|
969 /** モード表からコントロールコード形式の一文字分を取り出し、'\(8進);' の
|
|
970 形に直す。但し、先頭の'^'は既に読まれたあと。*/
|
|
971 static /* V3.1 */
|
|
972 void
|
|
973 rd_ctrl (sptr)
|
|
974 char **sptr;
|
|
975 {
|
|
976 fast int c; /* V3.1 */
|
|
977
|
|
978 if (!(' ' <= (c = chkchar_getc (cur_rk_table->modefile)) && c < '\177'))
|
|
979 ERRMOD (7);
|
|
980 if (c == '?')
|
|
981 c = '\177';
|
|
982 else
|
|
983 c &= 0x1f;
|
|
984
|
|
985 sprintf (*sptr, "\\%o;", c);
|
|
986 strtail (*sptr);
|
|
987 }
|
|
988 #endif
|
|
989
|
|
990 /** 8・10・16進コード用のキャラクタを実際のコードに直す。入力のチェックは
|
|
991 しない。*/
|
|
992 static int
|
|
993 ctov (c)
|
|
994 fast char c;
|
|
995 {
|
|
996 if (is_upper (c))
|
|
997 return (c - 'A' + 10);
|
|
998 if (is_lower (c))
|
|
999 return (c - 'a' + 10);
|
|
1000 return (c - '0');
|
|
1001 }
|
|
1002
|
|
1003 /** リストの中身のscanに専用。')'で0を返す。EOLは来ないはず。
|
|
1004 flg == 1 のとき、取り出しに失敗したらエラー。
|
|
1005 flg == 2 のとき、取り出しに成功したらエラー。
|
|
1006 特殊なコード表記は既に全て '\(8進);' の形に直っている筈。*/
|
|
1007 static /* V3.1 */
|
|
1008 int
|
|
1009 scan1tm (socp, dest, flg)
|
|
1010 char **socp, *dest;
|
|
1011 /* socpの指しているポインタが指している所から取り出してdestに入れる。
|
|
1012 その後、socpが指しているポインタを進める。 */
|
|
1013 int flg;
|
|
1014 {
|
|
1015 fast char c; /* V3.1 */
|
|
1016 fast int retval = 1; /* V3.1 */
|
|
1017
|
|
1018 while (c = *(*socp)++, is_nulsp (c))
|
|
1019 if (c == '\0')
|
|
1020 ERRMOD (6);
|
|
1021 switch (c)
|
|
1022 {
|
|
1023 case ')':
|
|
1024 retval = 0;
|
|
1025 break;
|
|
1026 case '(':
|
|
1027 *dest++ = c;
|
|
1028 *dest++ = ' ';
|
|
1029 while (scan1tm (socp, dest, 0))
|
|
1030 {
|
|
1031 strtail (dest);
|
|
1032 *dest++ = ' ';
|
|
1033 }
|
|
1034 *dest++ = ')';
|
|
1035 break;
|
|
1036 case '"':
|
|
1037 *dest++ = c;
|
|
1038 while ((c = *dest++ = *(*socp)++) != '"')
|
|
1039 {
|
|
1040 if (c == '\\')
|
|
1041 { /* '\(8進);'の解釈 */
|
|
1042 while (c = *dest++ = *(*socp)++, is_octal (c));
|
|
1043 }
|
|
1044 }
|
|
1045 break;
|
|
1046 default:
|
|
1047 *dest++ = c;
|
|
1048 while (!is_nulsp (**socp))
|
|
1049 *dest++ = *(*socp)++;
|
|
1050 }
|
|
1051
|
|
1052 *dest = '\0';
|
|
1053 if (flg == 1 && retval == 0 || flg == 2 && retval == 1)
|
|
1054 ERRMOD (6);
|
|
1055 return (retval);
|
|
1056 }
|
|
1057
|
|
1058 /** モード名として正当かチェック。英数字からなっていればいい */
|
|
1059 static /* V3.1 */
|
|
1060 int
|
|
1061 modnamchk (s)
|
|
1062 fast char *s; /* V3.1 */
|
|
1063 {
|
|
1064 if (is_digit (*s))
|
|
1065 return (0);
|
|
1066 for (; *s; s++)
|
|
1067 {
|
|
1068 if (!is_alnum (*s))
|
|
1069 {
|
|
1070 if (*s != '_')
|
|
1071 {
|
|
1072 return (0);
|
|
1073 }
|
|
1074 }
|
|
1075 }
|
|
1076 return (1);
|
|
1077 /*
|
|
1078 if(is_digit(*s)) return(0);
|
|
1079 for(; *s; s++) if(!is_alnum(*s) && *s != '_') return(0);
|
|
1080 return(1);
|
|
1081 */
|
|
1082 }
|
|
1083
|
|
1084 /** 変換対応表の選択を行う */
|
|
1085 #ifdef OMRON_LIB
|
|
1086 static
|
|
1087 #endif
|
|
1088 void
|
|
1089 choosehyo ()
|
|
1090 {
|
|
1091 fast int i; /* V3.1 */
|
|
1092 int *naibup; /* V3.1 */
|
|
1093
|
|
1094 if (cur_rk->rk_usehyo.usehyo != NULL)
|
|
1095 cur_rk->rk_usehyo.usemaehyo[0] = cur_rk->rk_usehyo.usehyo[0] = cur_rk->rk_usehyo.useatohyo[0] = -1;
|
|
1096 for (i = 0; i < 2; i++)
|
|
1097 {
|
|
1098 cur_rk->dspmod[1][i] = cur_rk->dspmod[0][i];
|
|
1099 cur_rk->dspmod[0][i] = NULL;
|
|
1100 }
|
|
1101
|
|
1102 if ((naibup = cur_rk_table->rk_modenaibu.org) != NULL)
|
|
1103 look_choose (&naibup, 1); /* V3.1 */
|
|
1104 }
|
|
1105
|
|
1106 /** モード表の内部形式を順次見ていき、使用表の選択及びモード表示文字列の
|
|
1107 選択を行っていく。但しflgが0ならスキップするだけ */
|
|
1108 static /* V3.1 */
|
|
1109 void
|
|
1110 look_choose (naibupp, flg)
|
|
1111 int **naibupp; /* モード表の内部表現の列へのポインタへのポインタ。
|
|
1112 look_cond()、evlcond()でも同様 */
|
|
1113 int flg;
|
|
1114 {
|
|
1115 fast int naibu1, naibu2, branch, lcrsl; /* V3.1 */
|
|
1116 int *naibup; /* V3.1 */
|
|
1117
|
|
1118 naibup = *naibupp;
|
|
1119
|
|
1120 while ((naibu1 = *naibup++) != Terminator)
|
|
1121 {
|
|
1122 switch (SHUBET (naibu1))
|
|
1123 {
|
|
1124 case 4: /* 表名 */
|
|
1125 if (flg)
|
|
1126 hyouse (LWRMSK (naibu1));
|
|
1127 break;
|
|
1128 case 2: /* 条件式 */
|
|
1129 branch = LWRMSK (naibu1); /* if;when */
|
|
1130 lcrsl = look_cond (&naibup, flg);
|
|
1131 if (branch == 0 && lcrsl)
|
|
1132 flg = 0;
|
|
1133 break;
|
|
1134 case 5: /* romkanがon・off時それぞれの
|
|
1135 モード表示文字列 */
|
|
1136 naibu2 = *naibup++;
|
|
1137 if (flg)
|
|
1138 cur_rk->dspmod[0][LWRMSK (naibu1)] = cur_rk_table->rk_dspmode.point[naibu2];
|
|
1139 break;
|
|
1140 case 6: /* romkanがそれぞれon・off時のモード表示
|
|
1141 文字列を前のままに */
|
|
1142 if (flg)
|
|
1143 cur_rk->dspmod[0][LWRMSK (naibu1)] = cur_rk->dspmod[1][LWRMSK (naibu1)];
|
|
1144 break;
|
|
1145 default:
|
|
1146 BUGreport (6);
|
|
1147 }
|
|
1148 }
|
|
1149
|
|
1150 *naibupp = naibup;
|
|
1151 }
|
|
1152
|
|
1153 /** *naibupp が、内部表現の列で条件式を表すところを指している筈なので、
|
|
1154 それを評価し、真ならその続きを解釈しにいく。偽なら読み飛ばす。
|
|
1155 返値は、最初に評価した条件式の真偽値。*/
|
|
1156 static /* V3.1 */
|
|
1157 int
|
|
1158 look_cond (naibupp, flg)
|
|
1159 int **naibupp, flg;
|
|
1160 {
|
|
1161 fast int condrsl; /* V3.1 */
|
|
1162 int *naibup;
|
|
1163
|
|
1164 naibup = *naibupp;
|
|
1165
|
|
1166 /* 88/06/06 V3.1 */
|
|
1167 condrsl = evlcond (&naibup); /* 必ず評価しないといけないため */
|
|
1168 look_choose (&naibup, flg &= condrsl);
|
|
1169 *naibupp = naibup;
|
|
1170 return (flg);
|
|
1171 }
|
|
1172
|
|
1173 /** 条件式の真偽値の評価 */
|
|
1174 static /* V3.1 */
|
|
1175 int
|
|
1176 evlcond (naibupp)
|
|
1177 int **naibupp;
|
|
1178 {
|
|
1179 int *naibup, tmpval[ARGMAX]; /* V3.1 */
|
|
1180 fast int naibu1, retval = 0, imax; /* V3.1 */
|
|
1181 fast int i; /* V3.1 */
|
|
1182
|
|
1183 naibup = *naibupp;
|
|
1184
|
|
1185 naibu1 = *naibup++;
|
|
1186 switch (SHUBET (naibu1))
|
|
1187 {
|
|
1188 case 7: /* 数値 */
|
|
1189 retval = *naibup++;
|
|
1190 break;
|
|
1191 case 1: /* モード名 */
|
|
1192 retval = cur_rk->rk_modesw.point[LWRMSK (naibu1)];
|
|
1193 break;
|
|
1194 case 3: /* if;when */
|
|
1195 imax = condarg[LWRMSK (naibu1)];
|
|
1196 for (i = 0; i < imax; i++)
|
|
1197 tmpval[i] = evlcond (&naibup);
|
|
1198 switch (LWRMSK (naibu1))
|
|
1199 {
|
|
1200 /* 上から順にtrue,false,not,and,or */
|
|
1201 case 0:
|
|
1202 retval = !tmpval[0];
|
|
1203 break;
|
|
1204 case 1:
|
|
1205 retval = tmpval[0] && tmpval[1];
|
|
1206 break;
|
|
1207 case 2:
|
|
1208 retval = tmpval[0] || tmpval[1];
|
|
1209 break;
|
|
1210 case 3:
|
|
1211 retval = 1;
|
|
1212 break;
|
|
1213 case 4:
|
|
1214 retval = 0;
|
|
1215 break;
|
|
1216 case 5:
|
|
1217 retval = (tmpval[0] == tmpval[1]);
|
|
1218 break;
|
|
1219 case 6:
|
|
1220 retval = (tmpval[0] != tmpval[1]);
|
|
1221 break;
|
|
1222 case 7:
|
|
1223 retval = ((unsigned int) tmpval[0] < (unsigned int) tmpval[1]);
|
|
1224 break;
|
|
1225 case 8:
|
|
1226 retval = ((unsigned int) tmpval[0] > (unsigned int) tmpval[1]);
|
|
1227 break;
|
|
1228
|
|
1229 }
|
|
1230 }
|
|
1231
|
|
1232 *naibupp = naibup;
|
|
1233 return (retval);
|
|
1234 }
|
|
1235
|
|
1236 /** num番目の表を、使用するものとして登録する。前・本・後処理の区別もする */
|
|
1237 static /* V3.1 */
|
|
1238 void
|
|
1239 hyouse (num)
|
|
1240 int num;
|
|
1241 {
|
|
1242 fast int *ptr = NULL; /* V3.1 */
|
|
1243
|
|
1244 switch (cur_rk_table->rk_hyo.point[num].hyoshu)
|
|
1245 {
|
|
1246 case 1:
|
|
1247 ptr = cur_rk->rk_usehyo.usemaehyo;
|
|
1248 break;
|
|
1249 case 2:
|
|
1250 ptr = cur_rk->rk_usehyo.usehyo;
|
|
1251 break;
|
|
1252 case 3:
|
|
1253 ptr = cur_rk->rk_usehyo.useatohyo;
|
|
1254 break;
|
|
1255 default:
|
|
1256 BUGreport (11);
|
|
1257 }
|
|
1258 if (ptr == NULL)
|
|
1259 return;
|
|
1260 for (; *ptr != -1; ptr++)
|
|
1261 if (*ptr == num)
|
|
1262 return;
|
|
1263 *ptr = num;
|
|
1264 *++ptr = -1;
|
|
1265 }
|
|
1266
|
|
1267 /* 88/06/02 V3.1 */
|
|
1268 #ifndef OMRON_SPEC
|
|
1269 /** strcmpと同等 但し、'\(8進);'も解釈する。*/
|
|
1270 static /* V3.1 */
|
|
1271 int
|
|
1272 mystrcmp (s1, s2)
|
|
1273 char *s1, *s2;
|
|
1274 {
|
|
1275 fast char c1, c2; /* V3.1 */
|
|
1276
|
|
1277 while ((c1 = codeeval (&s1)) == (c2 = codeeval (&s2)))
|
|
1278 if (c1 == '\0')
|
|
1279 return (0);
|
|
1280 return (c1 > c2 ? 1 : -1);
|
|
1281 }
|
|
1282
|
|
1283 /** strcpyと同等 但し'\(8進);'も解釈する。s1 <= s2なら正常動作するはず */
|
|
1284 static /* V3.1 */
|
|
1285 void
|
|
1286 mystrcpy (s1, s2)
|
|
1287 fast char *s1;
|
|
1288 char *s2;
|
|
1289 {
|
|
1290 while (*s1++ = codeeval (&s2));
|
|
1291 }
|
|
1292
|
|
1293 /** 一文字の解釈を行う。普通の文字はそのまま、'\(8進);'は実際のコードに
|
|
1294 直す。その後、文字列へのポインタを一文字分進めておく(少なくとも
|
|
1295 1バイト分進むことが保証されるはず)。*/
|
|
1296 static /* V3.1 */
|
|
1297 char
|
|
1298 codeeval (sptr)
|
|
1299 fast char **sptr; /* V3.1 */
|
|
1300 {
|
|
1301 fast char c; /* V3.1 */
|
|
1302 fast char code = 0; /* V3.1 */
|
|
1303
|
|
1304 if ((c = *(*sptr)++) != '\\')
|
|
1305 return (c);
|
|
1306 while (c = *(*sptr)++, is_octal (c))
|
|
1307 {
|
|
1308 code <<= 3;
|
|
1309 code += ctov (c);
|
|
1310 }
|
|
1311 if (c != ';')
|
|
1312 BUGreport (12);
|
|
1313 return (code);
|
|
1314 }
|
|
1315 #endif
|
|
1316
|
|
1317 /** romkanがon時のモード表示文字列を返す関数。無指定であってRK_DSPNILフラグが
|
|
1318 立っている時は空文字列を返す。*/
|
|
1319 char *
|
|
1320 romkan_dispmode ()
|
|
1321 {
|
|
1322 return (cur_rk->dspmod[0][0] == NULL && (cur_rk_table->flags & RK_DSPNIL) ? "" : cur_rk->dspmod[0][0]); /* V3.1 */
|
|
1323 }
|
|
1324
|
|
1325 /** romkanがoff時のモード表示文字列を返す関数。無指定であってRK_DSPNILフラグ
|
|
1326 が立っている時は空文字列を返す。*/
|
|
1327 char *
|
|
1328 romkan_offmode ()
|
|
1329 {
|
|
1330 return (cur_rk->dspmod[0][1] == NULL && (cur_rk_table->flags & RK_DSPNIL) ? "" : cur_rk->dspmod[0][1]); /* V3.1 */
|
|
1331 }
|
|
1332
|
|
1333 /* 88/06/02 V3.1 */
|
|
1334 /** ファイル名からパス名を除いた部分の先頭を返す。*/
|
|
1335 static char *
|
|
1336 ename (s)
|
|
1337 char *s;
|
|
1338 {
|
|
1339 fast char *p; /* V3.1 */
|
|
1340
|
|
1341 p = rindex (s, KUGIRI);
|
|
1342 return (p == NULL ? s : p + 1);
|
|
1343 }
|
|
1344
|
|
1345 /** ファイル名のチェック。先頭(パス名は除く)が'1'〜'3'でないといけない。
|
|
1346 正当なものなら1〜3(前・本・後処理表の区別を表す)を返し、そうでないと
|
|
1347 0を返す。*/
|
|
1348 #ifdef OMRON_LIB
|
|
1349 static
|
|
1350 #endif
|
|
1351 int
|
|
1352 filnamchk (s)
|
|
1353 char *s;
|
|
1354 {
|
|
1355 fast int c; /* V3.1 */
|
|
1356
|
|
1357 c = *(ename (s)) - '0';
|
|
1358 return ((1 <= c && c <= 3) ? c : 0);
|
|
1359 }
|
|
1360
|
|
1361 /* 88/06/02 V3.1 */
|
|
1362 static void
|
|
1363 ERMOPN (n) /* モード定義表がオープンできない */
|
|
1364 fast unsigned int n; /* V3.1 */
|
|
1365 {
|
|
1366 static char *ermes[] = {
|
|
1367 /* 0 */ "Unprintable error",
|
|
1368 "Mode-hyo does't exist",
|
|
1369 "Can't open Mode-hyo",
|
|
1370 "Too many long Mode-hyo filenames",
|
|
1371 };
|
|
1372
|
|
1373 if (n >= numberof (ermes))
|
|
1374 n = 0;
|
|
1375
|
|
1376 fprintf (stderr, "\r\nromkan: Mode-hyo %s ---\r\n", cur_rk_table->mcurfnm);
|
|
1377 fprintf (stderr, "\tError No.%d: %s.\r\n", n, ermes[n]);
|
|
1378 longjmp (cur_rk_table->env0, 1);
|
|
1379 }
|
|
1380
|
|
1381 /* 88/06/03 V3.1 */
|
|
1382 static void
|
|
1383 ERRMOD (n) /* モード定義表のエラー */
|
|
1384 fast unsigned int n; /* V3.1 */
|
|
1385 {
|
|
1386 static char *ermes[] = {
|
|
1387 /* 0 */ "Table incomplete",
|
|
1388 "')' mismatch",
|
|
1389 "Unprintable error",
|
|
1390 "Illegal filename",
|
|
1391 "Illegal modename",
|
|
1392 /* 5 */ "Undefined mode",
|
|
1393 "Illegal content(s) of list",
|
|
1394 "Illegal ^,\\o,\\x or \\d expression",
|
|
1395 "Illegal defmode",
|
|
1396 "Unrecognized keyword",
|
|
1397 /* 10 */ "Incomplete string",
|
|
1398 "Search path specified after filename",
|
|
1399 "Argument must be a string",
|
|
1400 "Can't get home directory",
|
|
1401 "Illegal @-keyword",
|
|
1402 /* 15 */ "User doesn't exist",
|
|
1403 "Illegal character",
|
|
1404 };
|
|
1405
|
|
1406 if (n >= numberof (ermes))
|
|
1407 n = 2;
|
|
1408
|
|
1409 fprintf (stderr, "\r\nromkan: Mode-hyo %s%s ---\r\n%s\r\n", cur_rk_table->mcurdir, cur_rk_table->mcurfnm, cur_rk_table->mcurread);
|
|
1410 fprintf (stderr, "\tError No.%d: %s.\r\n", n, ermes[n]);
|
|
1411 fclose (cur_rk_table->modefile);
|
|
1412 longjmp (cur_rk_table->env0, 1);
|
|
1413 }
|