Annotation of OpenXM_contrib2/asir2018/parse/lex.c, Revision 1.5
1.1 noro 1: /*
2: * Copyright (c) 1994-2000 FUJITSU LABORATORIES LIMITED
3: * All rights reserved.
4: *
5: * FUJITSU LABORATORIES LIMITED ("FLL") hereby grants you a limited,
6: * non-exclusive and royalty-free license to use, copy, modify and
7: * redistribute, solely for non-commercial and non-profit purposes, the
8: * computer program, "Risa/Asir" ("SOFTWARE"), subject to the terms and
9: * conditions of this Agreement. For the avoidance of doubt, you acquire
10: * only a limited right to use the SOFTWARE hereunder, and FLL or any
11: * third party developer retains all rights, including but not limited to
12: * copyrights, in and to the SOFTWARE.
13: *
14: * (1) FLL does not grant you a license in any way for commercial
15: * purposes. You may use the SOFTWARE only for non-commercial and
16: * non-profit purposes only, such as academic, research and internal
17: * business use.
18: * (2) The SOFTWARE is protected by the Copyright Law of Japan and
19: * international copyright treaties. If you make copies of the SOFTWARE,
20: * with or without modification, as permitted hereunder, you shall affix
21: * to all such copies of the SOFTWARE the above copyright notice.
22: * (3) An explicit reference to this SOFTWARE and its copyright owner
23: * shall be made on your publication or presentation in any form of the
24: * results obtained by use of the SOFTWARE.
25: * (4) In the event that you modify the SOFTWARE, you shall notify FLL by
26: * e-mail at risa-admin@sec.flab.fujitsu.co.jp of the detailed specification
27: * for such modification or the source code of the modified part of the
28: * SOFTWARE.
29: *
30: * THE SOFTWARE IS PROVIDED AS IS WITHOUT ANY WARRANTY OF ANY KIND. FLL
31: * MAKES ABSOLUTELY NO WARRANTIES, EXPRESSED, IMPLIED OR STATUTORY, AND
32: * EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS
33: * FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT OF THIRD PARTIES'
34: * RIGHTS. NO FLL DEALER, AGENT, EMPLOYEES IS AUTHORIZED TO MAKE ANY
35: * MODIFICATIONS, EXTENSIONS, OR ADDITIONS TO THIS WARRANTY.
36: * UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, TORT, CONTRACT,
37: * OR OTHERWISE, SHALL FLL BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY
38: * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, PUNITIVE OR CONSEQUENTIAL
39: * DAMAGES OF ANY CHARACTER, INCLUDING, WITHOUT LIMITATION, DAMAGES
40: * ARISING OUT OF OR RELATING TO THE SOFTWARE OR THIS AGREEMENT, DAMAGES
41: * FOR LOSS OF GOODWILL, WORK STOPPAGE, OR LOSS OF DATA, OR FOR ANY
42: * DAMAGES, EVEN IF FLL SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF
43: * SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. EVEN IF A PART
44: * OF THE SOFTWARE HAS BEEN DEVELOPED BY A THIRD PARTY, THE THIRD PARTY
45: * DEVELOPER SHALL HAVE NO LIABILITY IN CONNECTION WITH THE USE,
46: * PERFORMANCE OR NON-PERFORMANCE OF THE SOFTWARE.
47: *
1.5 ! noro 48: * $OpenXM: OpenXM_contrib2/asir2018/parse/lex.c,v 1.4 2020/10/06 06:31:20 noro Exp $
1.1 noro 49: */
50: #include <ctype.h>
51: #include "ca.h"
52: #include "al.h"
53: #include "base.h"
54: #include "parse.h"
55: #include <sys/types.h>
56: #include <sys/stat.h>
57: #if defined(VISUAL) || defined(__MINGW32__)
58: #include "ytab.h"
59: #else
60: #include "y.tab.h"
61: #endif
62: #if FEP
63: #include <readline/readline.h>
64: #endif
65:
66: static int Getc();
67: static void Ungetc(int c);
68: static void Gets(char *s);
69: static int skipspace();
70:
71: extern INFILE asir_infile;
72: extern struct oTKWD kwd[];
73: extern Obj VOIDobj;
74:
75: extern int main_parser;
76: extern char *parse_strp;
77:
78: #define NBUFSIZ (BUFSIZ*10)
79: #define TBUFSIZ (BUFSIZ)
80:
81: #define REALLOC_NBUF \
82: if ( i >= nbufsize ) {\
83: nbufsize += NBUFSIZ;\
84: if ( nbuf == nbuf0 ) {\
85: nbuf = (char *)MALLOC_ATOMIC(nbufsize);\
86: bcopy(nbuf0,nbuf,nbufsize-NBUFSIZ);\
87: } else\
88: nbuf = REALLOC(nbuf,nbufsize);\
89: }
90:
91: #define REALLOC_TBUF \
92: if ( i >= tbufsize ) {\
93: tbufsize += TBUFSIZ;\
94: if ( tbuf == tbuf0 ) {\
95: tbuf = (char *)MALLOC_ATOMIC(tbufsize);\
96: bcopy(tbuf0,tbuf,tbufsize-TBUFSIZ);\
97: } else\
98: tbuf = REALLOC(tbuf,tbufsize);\
99: }
100:
101: #define READ_ALNUM_NBUF \
102: while ( 1 ) {\
103: c = Getc();\
104: if ( isalnum(c) ) {\
105: REALLOC_NBUF nbuf[i++] = c;\
106: } else\
107: break;\
108: }
109:
110: #define READ_DIGIT_NBUF \
111: while ( 1 ) {\
112: c = Getc();\
113: if ( isdigit(c) ) {\
114: REALLOC_NBUF nbuf[i++] = c;\
115: } else\
116: break;\
117: }
118:
119: int yylex()
120: {
121: #define yylvalp (&yylval)
122: int c,c1;
123: int *ptr;
124: char *cptr;
125: int d,i,j;
126: char nbuf0[NBUFSIZ],tbuf0[TBUFSIZ];
127: char *nbuf, *tbuf;
128: int nbufsize, tbufsize;
129: Z n,n1;
130: Q q;
131: Obj r;
132: int floatingpoint = 0;
133: double dbl;
134: Real real;
135: double atof();
136: extern int bigfloat;
137:
138:
139: /* initialize buffer pointers */
140: nbuf = nbuf0; tbuf = tbuf0;
141: nbufsize = NBUFSIZ; tbufsize = TBUFSIZ;
142:
143: switch ( c = skipspace() ) {
144: case EOF :
145: asir_terminate(2); break;
146: case '0' :
147: while ( ( c = Getc() ) == '0' );
148: if ( c == '.' ) {
149: Ungetc(c); c = '0';
150: } else if ( c == 'x' || c == 'X' ) {
151: for ( i = 0; i < 8; i++ )
152: nbuf[i] = '0';
153: READ_ALNUM_NBUF
154: Ungetc(c); REALLOC_NBUF nbuf[i] = 0;
155: hextoz(nbuf,&n1); r = (Obj)n1;
156: yylvalp->p = (pointer)r;
157: return ( FORMULA );
158: } else if ( c == 'b' || c == 'B' ) {
159: for ( i = 0; i < 32; i++ )
160: nbuf[i] = '0';
161: READ_ALNUM_NBUF
162: Ungetc(c); REALLOC_NBUF nbuf[i] = 0;
163: binarytoz(nbuf,&n1); r = (Obj)n1;
164: yylvalp->p = (pointer)r;
165: return ( FORMULA );
166: } else if ( !isdigit(c) ) {
167: yylvalp->p = 0; Ungetc(c);
168: return ( FORMULA );
169: }
170: break;
171: case '\'' :
172: for ( i = 0; ; i++ ) {
173: c = Getc();
174: if ( c == '\'' )
175: break;
176: if ( c == '\\' )
177: c = Getc();
178: REALLOC_TBUF tbuf[i] = c;
179: }
180: REALLOC_TBUF tbuf[i] = 0;
181: cptr = (char *)MALLOC(strlen(tbuf)+1); strcpy(cptr,tbuf);
182: yylvalp->p = (pointer)cptr;
183: return LCASE; break;
184: case '"' :
185: i = 0;
186: do {
187: c = Getc();
188: if ( c == '\n' ) asir_infile->ln++;
189: if ( c == '\\' ) {
190: c1 = Getc();
191: if ( c1 == 'n' ) {
192: c1 = '\n';
193: }else if ( c1 == 'r' ) {
194: c1 = '\r';
195: }else if ( c1 == 't' ) {
196: c1 = '\t';
197: }else if ( isdigit(c1) ){
198: d = c1 - '0';
199: c1 = Getc();
200: if ( isdigit(c1) ) {
201: d = 8*d + (c1 - '0');
202: c1 = Getc();
203: if ( isdigit(c1) ) {
204: d = 8*d + (c1 - '0');
205: }else {
206: Ungetc(c1);
207: }
208: }else {
209: Ungetc(c1);
210: }
211: c1 = d;
212: }
213: REALLOC_NBUF nbuf[i++] = c1;
214: } else {
215: REALLOC_NBUF nbuf[i++] = c;
216: }
217: } while ( c != '"' );
218: nbuf[i-1] = 0; /* REALLOC_NBUF is not necessary */
219: cptr = (char *)MALLOC(strlen(nbuf)+1);
220: strcpy(cptr,nbuf); yylvalp->p = (pointer) cptr;
221: return ( STR ); break;
222: case '>': case '<': case '=': case '!':
223: if ( (c1 = Getc()) == '=' )
224: switch ( c ) {
225: case '>': yylvalp->i = (int)C_GE; break;
226: case '<': yylvalp->i = (int)C_LE; break;
227: case '=': yylvalp->i = (int)C_EQ; break;
228: case '!': yylvalp->i = (int)C_NE; break;
229: default: break;
230: }
231: else if ( (c == '<' && c1 == '<') || (c == '>' && c1 == '>') )
232: return c;
233: else {
234: Ungetc(c1);
235: switch ( c ) {
236: case '>': yylvalp->i = (int)C_GT; break;
237: case '<': yylvalp->i = (int)C_LT; break;
238: default: return c; break;
239: }
240: }
241: return CMP; break;
242: case '+': case '-': case '*': case '/': case '%': case '^':
243: case '|': case '&':
244: switch ( c ) {
245: case '+': yylvalp->p = (pointer)addfs; break;
246: case '-': yylvalp->p = (pointer)subfs; break;
247: case '*': yylvalp->p = (pointer)mulfs; break;
248: case '/': yylvalp->p = (pointer)divfs; break;
249: case '%': yylvalp->p = (pointer)remfs; break;
250: case '^': yylvalp->p = (pointer)pwrfs; break;
251: default: break;
252: }
253: if ( (c1 = Getc()) == c )
254: switch ( c ) {
255: case '+': case '-': return SELF; break;
256: case '|': return OR; break;
257: case '&': return AND; break;
258: default: Ungetc(c1); return c; break;
259: }
260: else if ( c1 == '=' )
261: return BOPASS;
262: else if ( (c == '-') && (c1 == '>') )
263: return POINT;
264: else {
265: Ungetc(c1); return c;
266: }
267: break;
268: default :
269: break;
270: }
271: if ( isdigit(c) ) {
272: for ( i = 0; i < DLENGTH; i++ )
273: nbuf[i] = '0';
274: REALLOC_NBUF nbuf[i++] = c;
275: READ_DIGIT_NBUF
276: if ( c == '.' ) {
277: floatingpoint = 1;
278:
279: REALLOC_NBUF nbuf[i++] = c;
280: READ_DIGIT_NBUF
281: if ( c == 'e' || c == 'E' ) {
282: REALLOC_NBUF nbuf[i++] = c;
283: c = Getc();
284: if ( (c == '+') || (c == '-') ) {
285: REALLOC_NBUF nbuf[i++] = c;
286: } else
287: Ungetc(c);
288: READ_DIGIT_NBUF
289: }
290: } else if ( c == 'e' || c == 'E' ) {
291: floatingpoint = 1;
292: REALLOC_NBUF nbuf[i++] = c;
293: c = Getc();
294: if ( (c == '+') || (c == '-') ) {
295: REALLOC_NBUF nbuf[i++] = c;
296: } else
297: Ungetc(c);
298: READ_DIGIT_NBUF
299: }
300: Ungetc(c); REALLOC_NBUF nbuf[i] = 0;
301: if ( floatingpoint ) {
302: if ( !bigfloat ) {
303: dbl = (double)atof(nbuf+DLENGTH);
304: MKReal(dbl,real); r = (Obj)real;
305: } else
306: strtobf(nbuf,(BF *)&r);
307: } else {
308: mpz_t z;
309:
310: mpz_init(z);
311: mpz_set_str(z,nbuf,10);
312: MPZTOZ(z,n1); r = (Obj)n1;
313: }
314: yylvalp->p = (pointer)r;
315: return ( FORMULA );
316: } else if ( isalpha(c) || c == ':' || c == '_' ) {
317: if ( c == ':' ) {
318: c1 = Getc();
319: if ( c1 != ':' ) {
320: Ungetc(c1);
321: return c;
322: }
323: c1 = Getc();
324: if ( !isalpha(c1) ) {
325: Ungetc(c1);
326: return COLONCOLON;
327: }
328: i = 0;
329: tbuf[i++] = ':';
330: tbuf[i++] = ':';
331: tbuf[i++] = c1;
332: } else {
333: i = 0;
334: tbuf[i++] = c;
335: }
336: while ( 1 ) {
337: c = Getc();
338: if ( isalpha(c)||isdigit(c)||(c=='_')||(c=='.') ) {
339: REALLOC_TBUF tbuf[i++] = c;
340: } else
341: break;
342: }
343: REALLOC_TBUF tbuf[i] = 0; Ungetc(c);
344: if ( isupper(tbuf[0]) || (tbuf[0] == '_' && isupper(tbuf[1])) ) {
345: cptr = (char *)MALLOC(strlen(tbuf)+1); strcpy(cptr,tbuf);
346: yylvalp->p = (pointer)cptr;
347: return UCASE;
348: } else {
349: for ( i = 0; kwd[i].name && strcmp(tbuf,kwd[i].name); i++ );
350: if ( kwd[i].name ) {
351: yylvalp->i = asir_infile->ln;
352: return kwd[i].token;
353: } else {
354: cptr = (char *)MALLOC(strlen(tbuf)+1); strcpy(cptr,tbuf);
355: yylvalp->p = (pointer)cptr;
356: return LCASE;
357: }
358: }
359: } else if ( c == '@' ) {
360: if ( isdigit(c = Getc()) ) {
361: i = 0;
362: nbuf[i++] = c;
363: READ_DIGIT_NBUF
364: Ungetc(c); REALLOC_NBUF nbuf[i] = 0;
365: yylvalp->i = atoi(nbuf);
366: return ANS;
367: } else if ( c == '@' ) {
368: yylvalp->i = MAX(0,APVS->n-1);
369: return ANS;
370: } else if ( c == '>' || c == '<' || c == '=' || c == '!' ) {
371: if ( (c1 = Getc()) == '=' )
372: switch ( c ) {
373: case '>': yylvalp->i = (int)L_GE; break;
374: case '<': yylvalp->i = (int)L_LE; break;
375: case '=': yylvalp->i = (int)L_EQ; break;
376: case '!': yylvalp->i = (int)L_NE; break;
377: default: break;
378: }
379: else {
380: Ungetc(c1);
381: switch ( c ) {
382: case '>': yylvalp->i = (int)L_GT; break;
383: case '<': yylvalp->i = (int)L_LT; break;
384: case '=': yylvalp->i = (int)L_EQ; break;
385: case '!': yylvalp->i = (int)L_NOT; return FOP_NOT; break;
386: default: break;
387: }
388: }
389: return LOP;
390: } else if ( c == '|' || c == '&' ) {
391: if ( (c1 = Getc()) != c )
392: Ungetc(c1);
393: switch ( c ) {
394: case '|': yylvalp->i = (int)L_OR;
395: return FOP_OR; break;
396: case '&': yylvalp->i = (int)L_AND;
397: return FOP_AND; break;
398: }
399: } else if ( isalpha(c) ) {
400: i = 0;
401: tbuf[i++] = '@';
402: tbuf[i++] = c;
403: while ( 1 ) {
404: c = Getc();
405: if ( isalpha(c) ) {
406: REALLOC_TBUF tbuf[i++] = c;
407: } else
408: break;
409: }
410: Ungetc(c); REALLOC_TBUF tbuf[i] = 0;
411: if ( !strcmp(tbuf,"@p") )
412: return GFPNGEN;
413: else if ( !strcmp(tbuf,"@s") )
414: return GFSNGEN;
415: else if ( !strcmp(tbuf,"@void") ) {
416: yylvalp->p = VOIDobj;
417: return FORMULA;
418: } else if ( !strcmp(tbuf,"@i") ) {
419: extern pointer IU;
420:
421: yylvalp->p = IU;
422: return FORMULA;
423: } else if ( !strcmp(tbuf,"@true") ) {
424: yylvalp->p = F_TRUE;
425: return FORMULA;
426: } else if ( !strcmp(tbuf,"@false") ) {
427: yylvalp->p = F_FALSE;
428: return FORMULA;
429: } else if ( !strcmp(tbuf,"@impl") ) {
430: yylvalp->i = (int)L_IMPL;
431: return FOP_IMPL;
432: } else if ( !strcmp(tbuf,"@repl") ) {
433: yylvalp->i = (int)L_REPL;
434: return FOP_REPL;
435: } else if ( !strcmp(tbuf,"@equiv") ) {
436: yylvalp->i = (int)L_EQUIV;
437: return FOP_EQUIV;
438: } else if ( !strcmp(tbuf,"@grlex") ) {
439: yylvalp->p = Symbol_grlex;
440: return FORMULA;
441: } else if ( !strcmp(tbuf,"@glex") ) {
442: yylvalp->p = Symbol_glex;
443: return FORMULA;
444: } else if ( !strcmp(tbuf,"@lex") ) {
445: yylvalp->p = Symbol_lex;
446: return FORMULA;
447: } else {
448: cptr = (char *)MALLOC(strlen(tbuf)+1); strcpy(cptr,tbuf);
449: yylvalp->p = (pointer)cptr;
450: return LCASE;
451: }
452: } else {
453: Ungetc(c);
454: return GF2NGEN;
455: }
456: } else
457: return ( c );
1.4 noro 458: /* XXX */
459: return 0;
1.1 noro 460: }
461:
1.5 ! noro 462: /* for __fpurge() */
! 463: #if defined(linux)
! 464: #include <stdio_ext.h>
! 465: #endif
! 466:
1.1 noro 467: void purge_stdin()
468: {
1.2 fujimoto 469: #if defined(__FreeBSD__) || defined(__DARWIN__) || defined(ANDROID)
1.1 noro 470: fpurge(stdin);
471: #elif defined(linux)
1.3 fujimoto 472: // stdin->_IO_read_end = stdin->_IO_read_base;
473: // stdin->_IO_read_ptr = stdin->_IO_read_base;
474: __fpurge(stdin);
1.1 noro 475: #elif defined(VISUAL_LIB)
476: void w_purge_stdin();
477:
478: w_purge_stdin();
479: #elif defined(VISUAL) && _MSC_VER >= 1900
480: rewind(stdin);
481: #elif defined(sparc) || defined(__alpha) || defined(__SVR4) || defined(mips) || defined(VISUAL) || defined(__MINGW32__) || defined(_IBMR2)
482: stdin->_ptr = stdin->_base; stdin->_cnt = 0;
483: #elif (defined(__MACH__) && defined(__ppc__)) || defined(__CYGWIN__) || defined(__FreeBSD__) || defined(__INTERIX)
484: stdin->_r = 0; stdin->_p = stdin->_bf._base;
485: #else
486: --->FIXIT
487: #endif
488: }
489:
490: static int skipspace() {
491: int c,c1;
492:
493: for ( c = Getc(); ; )
494: switch ( c ) {
495: case ' ': case '\t': case '\r':
496: c = Getc(); break;
497: case '\n':
498: c = afternl(); break;
499: case '/':
500: if ( (c1 = Getc()) == '*' )
501: c = aftercomment();
502: else {
503: Ungetc(c1); return c;
504: }
505: break;
506: default:
507: return c; break;
508: }
509: }
510:
511: int afternl() {
512: int c,ac,i,quote;
513: char *ptr,*buf0;
514: char *av[BUFSIZ];
515: static int ilevel = 0;
516: char buf[BUFSIZ];
517:
518: if ( !ilevel )
519: asir_infile->ln++;
520: while ( (c = Getc()) == '#' ) {
521: Gets(buf);
522: #define LINE "line"
523: if ( !strncmp(buf,LINE,strlen(LINE)) ) buf0 = buf+strlen(LINE);
524: else buf0 = buf;
525: for ( quote = 0, ptr = buf0; *ptr; ptr++ )
526: if ( *ptr == '"' )
527: quote = quote ? 0 : 1;
528: else if ( quote && (*ptr == ' ') )
529: *ptr = '_';
1.4 noro 530: stoarg(buf0,&ac,av);
531: if ( ac == 3 ) {
1.1 noro 532: if ( (i = atoi(av[2])) == 1 )
533: ilevel++;
534: else if ( i == 2 )
535: ilevel--;
1.4 noro 536: }
1.1 noro 537: if ( !ilevel )
538: asir_infile->ln = atoi(av[0]);
539: }
540: return c;
541: }
542:
543: int aftercomment() {
544: int c,c1;
545:
546: for ( c = Getc(); ; ) {
547: if ( c == '\n' ) asir_infile->ln++;
548: c1 = Getc();
549: if ( (c == '*') && (c1 == '/') )
550: return Getc();
551: else
552: c = c1;
553: }
554: }
555:
556: int myatoi(char *s)
557: {
558: int i,r;
559: for ( i = 0, r = 0; i < DLENGTH; i++ ) r = r * 10 + ( s[i] - '0' );
560: return ( r );
561: }
562:
563: extern int ox_do_copy;
564: extern int I_am_server;
565: extern JMP_BUF main_env;
566: extern int at_root;
567: extern LIST LastStackTrace;
568: extern char *CUR_FUNC;
569:
570: void yyerror(char *s)
571: {
572: STRING fname,name,kwd;
573: USINT u;
574: NODE t;
575: LIST l,l2;
576:
577: if ( main_parser ) {
578: if ( ox_do_copy ) {
579: /* push errors to DebugStack */
580: } else {
581: if ( asir_infile->fp == stdin )
582: fprintf(stderr,"%s\n",s);
583: else
584: fprintf(stderr,"\"%s\", near line %d: %s\n",asir_infile->name,asir_infile->ln,s);
585: }
586: if ( I_am_server ) {
587: if ( NEXT(asir_infile) ) {
588: /* error in a file; record the position */
589: MKSTR(fname,asir_infile->name);
590: if ( CPVS == GPVS )
591: MKSTR(name,"");
592: else
593: MKSTR(name,CUR_FUNC);
594: MKUSINT(u,asir_infile->ln);
595: t = mknode(3,fname,name,u); MKLIST(l,t);
596: /* line number at the toplevel */
597: MKSTR(fname,"toplevel"); MKUSINT(u,at_root);
598: t = mknode(2,fname,u); MKLIST(l2,t);
599: t = mknode(2,l2,l);
600: } else {
601: MKSTR(fname,"toplevel"); MKUSINT(u,asir_infile->ln);
602: t = mknode(2,fname,u); MKLIST(l,t);
603: t = mknode(1,l);
604: }
605: MKLIST(l,t);
606: MKSTR(kwd,"asir_where"); t = mknode(2,kwd,l);
607: MKLIST(LastStackTrace,t);
608: set_lasterror(s);
609: LONGJMP(main_env,1);
610: }
611: } else
612: fprintf(stderr,"exprparse : %s\n",s);
613: }
614:
615: int echoback;
616:
617: extern int do_fep, do_file;
618:
619: unsigned char encrypt_char(unsigned char);
620: unsigned char decrypt_char(unsigned char);
621:
622: int Egetc(FILE *fp)
623: {
624: int c;
625:
626: if ( fp ) {
627: #if FEP
628: if ( do_fep && isatty(fileno(fp)) )
629: c = readline_getc();
630: else
631: #endif
632: c = getc(fp);
633: #if defined(VISUAL) || defined(__MINGW32__)
634: check_intr();
635: #endif
636: if ( c == EOF )
637: return c;
638: if ( asir_infile->encoded )
639: c = decrypt_char((unsigned char)c);
640: return c;
641: } else {
642: c = *parse_strp++;
643: if ( !c )
644: return EOF;
645: else
646: return c;
647: }
648: }
649:
650: void Eungetc(int c,FILE *fp)
651: {
652: if ( fp ) {
653: if ( asir_infile->encoded )
654: c = (int)encrypt_char((unsigned char)c);
655: #if FEP
656: if ( do_fep && isatty(fileno(fp)) )
657: readline_ungetc();
658: else
659: #endif
660: ungetc(c,fp);
661: } else
662: *--parse_strp = c;
663: }
664:
665: static int Getc() {
666: int c;
667:
668: if ( main_parser ) {
669: while ( 1 ) {
670: if ((c = Egetc(asir_infile->fp)) == EOF)
671: if ( NEXT(asir_infile) ) {
672: closecurrentinput();
673: /* if the input is the top level, generate error */
674: if ( !NEXT(asir_infile) )
675: error("end-of-file detected during parsing");
676: else
677: c = Getc();
678: break;
679: } else if ( asir_infile->fp || do_file ) {
680: if ( asir_infile->fp )
681: clearerr(asir_infile->fp);
682: asir_terminate(2);
683: } else {
684: error("end-of-line detected during parsing");
685: }
686: else
687: break;
688: }
689: if ( echoback )
690: fputc(c,asir_out);
691: } else
692: c = *parse_strp++;
693: return ( c );
694: }
695:
696: static void Ungetc(int c) {
697: if ( main_parser ) {
698: Eungetc(c,asir_infile->fp);
699: if ( echoback )
700: fputc('',asir_out);
701: } else
702: *--parse_strp = c;
703: }
704:
705: static void Gets(char *s)
706: {
707: int c;
708:
709: while ( (c = Getc()) != '\n' )
710: *s++ = c;
711: *s = 0;
712: }
713:
714: #if FEP
715:
716: static char *readline_line;
717: static int readline_nc,readline_index;
718: char *readline_console();
719:
720: int readline_getc()
721: {
722: char buf[BUFSIZ];
723:
724: if ( !readline_nc ) {
725: if ( readline_line )
726: free(readline_line);
727: sprompt(buf);
728: readline_line = readline_console(buf);
729: readline_nc = strlen(readline_line);
730: readline_index = 0;
731: }
732: readline_nc--;
733: return readline_line[readline_index++];
734: }
735:
736: void readline_ungetc()
737: {
738: readline_nc++; readline_index--;
739: }
740:
741: char *readline_console(char *prompt)
742: {
743: char *line;
744: int exp_result;
745: char *expansion;
746:
747: while ( 1 ) {
748: line = (char *)readline(prompt);
749: if ( line && *line ) {
750: using_history();
751: exp_result = history_expand(line,&expansion);
752: if ( !exp_result ) {
753: free(expansion);
754: for ( ; isspace((unsigned char)*line); line++ );
755: add_history(line);
756: break;
757: } else if ( exp_result > 0 ) {
758: free(line);
759: line = expansion;
760: break;
761: }
762: }
763: }
764: return line;
765: }
766: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>