Annotation of OpenXM_contrib2/asir2000/parse/lex.c, Revision 1.19
1.4 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
1.5 noro 26: * e-mail at risa-admin@sec.flab.fujitsu.co.jp of the detailed specification
1.4 noro 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.19 ! noro 48: * $OpenXM: OpenXM_contrib2/asir2000/parse/lex.c,v 1.18 2001/10/09 01:36:24 noro Exp $
1.4 noro 49: */
1.1 noro 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>
1.10 noro 57: #if defined(VISUAL)
58: #include "ytab.h"
59: #else
1.1 noro 60: #include "y.tab.h"
1.10 noro 61: #endif
1.1 noro 62:
1.18 noro 63: static int Getc();
64: static void Ungetc(int c);
65: static void Gets(char *s);
66: static int skipspace();
67:
68: extern INFILE asir_infile;
1.1 noro 69: extern struct oTKWD kwd[];
70:
71: extern int main_parser;
72: extern char *parse_strp;
1.11 noro 73: extern int recv_intr;
1.1 noro 74:
1.2 noro 75: #define NBUFSIZ (BUFSIZ*10)
76: #define TBUFSIZ (BUFSIZ)
77:
78: #define REALLOC_NBUF \
79: if ( i >= nbufsize ) {\
80: nbufsize += NBUFSIZ;\
81: if ( nbuf == nbuf0 ) {\
82: nbuf = (char *)MALLOC_ATOMIC(nbufsize);\
83: bcopy(nbuf0,nbuf,nbufsize-NBUFSIZ);\
84: } else\
85: nbuf = REALLOC(nbuf,nbufsize);\
86: }
87:
88: #define REALLOC_TBUF \
89: if ( i >= tbufsize ) {\
90: tbufsize += TBUFSIZ;\
91: if ( tbuf == tbuf0 ) {\
92: tbuf = (char *)MALLOC_ATOMIC(tbufsize);\
93: bcopy(tbuf0,tbuf,tbufsize-TBUFSIZ);\
94: } else\
95: tbuf = REALLOC(tbuf,tbufsize);\
96: }
97:
98: #define READ_ALNUM_NBUF \
99: while ( 1 ) {\
100: c = Getc();\
101: if ( isalnum(c) ) {\
102: REALLOC_NBUF nbuf[i++] = c;\
103: } else\
104: break;\
105: }
106:
107: #define READ_DIGIT_NBUF \
108: while ( 1 ) {\
109: c = Getc();\
110: if ( isdigit(c) ) {\
111: REALLOC_NBUF nbuf[i++] = c;\
112: } else\
113: break;\
114: }
115:
1.18 noro 116: int yylex()
1.1 noro 117: {
118: #define yylvalp (&yylval)
119: register int c,c1;
120: register int *ptr;
121: char *cptr;
122: int d,i,j;
1.2 noro 123: char nbuf0[NBUFSIZ],tbuf0[TBUFSIZ];
124: char *nbuf, *tbuf;
125: int nbufsize, tbufsize;
1.1 noro 126: N n,n1;
127: Q q;
128: Obj r;
129:
1.2 noro 130: /* initialize buffer pointers */
131: nbuf = nbuf0; tbuf = tbuf0;
132: nbufsize = NBUFSIZ; tbufsize = TBUFSIZ;
133:
1.1 noro 134: switch ( c = skipspace() ) {
135: case EOF :
136: asir_terminate(2); break;
137: case '0' :
138: while ( ( c = Getc() ) == '0' );
139: if ( c == '.' ) {
140: Ungetc(c); c = '0';
141: } else if ( c == 'x' ) {
142: for ( i = 0; i < 8; i++ )
143: nbuf[i] = '0';
1.2 noro 144: READ_ALNUM_NBUF
145: Ungetc(c); REALLOC_NBUF nbuf[i] = 0;
1.1 noro 146: hexton(nbuf,&n1);
147: NTOQ(n1,1,q); r = (Obj)q;
148: yylvalp->p = (pointer)r;
149: return ( FORMULA );
150: } else if ( c == 'b' ) {
151: for ( i = 0; i < 32; i++ )
152: nbuf[i] = '0';
1.2 noro 153: READ_ALNUM_NBUF
154: Ungetc(c); REALLOC_NBUF nbuf[i] = 0;
1.1 noro 155: binaryton(nbuf,&n1);
156: NTOQ(n1,1,q); r = (Obj)q;
157: yylvalp->p = (pointer)r;
158: return ( FORMULA );
159: } else if ( !isdigit(c) ) {
160: yylvalp->p = 0; Ungetc(c);
161: return ( FORMULA );
162: }
163: break;
164: case '\'' :
165: for ( i = 0; ; i++ ) {
166: c = Getc();
167: if ( c == '\'' )
168: break;
169: if ( c == '\\' )
170: c = Getc();
1.2 noro 171: REALLOC_TBUF tbuf[i] = c;
1.1 noro 172: }
1.2 noro 173: REALLOC_TBUF tbuf[i] = 0;
1.1 noro 174: cptr = (char *)MALLOC(strlen(tbuf)+1); strcpy(cptr,tbuf);
175: yylvalp->p = (pointer)cptr;
176: return LCASE; break;
177: case '"' :
178: i = 0;
179: do {
180: c = Getc();
181: if ( c == '\\' ) {
182: c1 = Getc();
183: if ( c1 == 'n' )
184: c1 = '\n';
1.2 noro 185: REALLOC_NBUF nbuf[i++] = c1;
186: } else {
187: REALLOC_NBUF nbuf[i++] = c;
188: }
1.1 noro 189: } while ( c != '"' );
1.2 noro 190: nbuf[i-1] = 0; /* REALLOC_NBUF is not necessary */
1.1 noro 191: cptr = (char *)MALLOC(strlen(nbuf)+1);
192: strcpy(cptr,nbuf); yylvalp->p = (pointer) cptr;
193: return ( STR ); break;
194: case '>': case '<': case '=': case '!':
195: if ( (c1 = Getc()) == '=' )
196: switch ( c ) {
197: case '>': yylvalp->i = (int)C_GE; break;
198: case '<': yylvalp->i = (int)C_LE; break;
199: case '=': yylvalp->i = (int)C_EQ; break;
200: case '!': yylvalp->i = (int)C_NE; break;
201: default: break;
202: }
203: else if ( (c == '<' && c1 == '<') || (c == '>' && c1 == '>') )
204: return c;
205: else {
206: Ungetc(c1);
207: switch ( c ) {
208: case '>': yylvalp->i = (int)C_GT; break;
209: case '<': yylvalp->i = (int)C_LT; break;
210: default: return c; break;
211: }
212: }
213: return CMP; break;
214: case '+': case '-': case '*': case '/': case '%': case '^':
215: case '|': case '&':
216: switch ( c ) {
217: case '+': yylvalp->p = (pointer)addfs; break;
218: case '-': yylvalp->p = (pointer)subfs; break;
219: case '*': yylvalp->p = (pointer)mulfs; break;
220: case '/': yylvalp->p = (pointer)divfs; break;
221: case '%': yylvalp->p = (pointer)remfs; break;
222: case '^': yylvalp->p = (pointer)pwrfs; break;
223: default: break;
224: }
225: if ( (c1 = Getc()) == c )
226: switch ( c ) {
227: case '+': case '-': return SELF; break;
228: case '|': return OR; break;
229: case '&': return AND; break;
230: default: Ungetc(c1); return c; break;
231: }
232: else if ( c1 == '=' )
233: return BOPASS;
234: else if ( (c == '-') && (c1 == '>') )
235: return POINT;
236: else {
237: Ungetc(c1); return c;
238: }
239: break;
240: default :
241: break;
242: }
243: if ( isdigit(c) ) {
244: for ( i = 0; i < DLENGTH; i++ )
245: nbuf[i] = '0';
1.2 noro 246: REALLOC_NBUF nbuf[i++] = c;
247: READ_DIGIT_NBUF
1.1 noro 248: if ( c == '.' ) {
249: double dbl;
250: Real real;
251: double atof();
252: extern int bigfloat;
253:
1.2 noro 254: REALLOC_NBUF nbuf[i++] = c;
255: READ_DIGIT_NBUF
1.1 noro 256: if ( c == 'e' ) {
1.2 noro 257: REALLOC_NBUF nbuf[i++] = c;
258: c = Getc();
259: if ( (c == '+') || (c == '-') ) {
260: REALLOC_NBUF nbuf[i++] = c;
261: } else
262: Ungetc(c);
263: READ_DIGIT_NBUF
1.1 noro 264: }
1.2 noro 265: Ungetc(c); REALLOC_NBUF nbuf[i] = 0;
1.1 noro 266: #if PARI
267: if ( !bigfloat ) {
268: dbl = (double)atof(nbuf+DLENGTH);
269: MKReal(dbl,real); r = (Obj)real;
270: } else
271: strtobf(nbuf,(BF *)&r);
272: #else
273: dbl = (double)atof(nbuf+DLENGTH);
274: MKReal(dbl,real); r = (Obj)real;
275: #endif
276: } else {
277: Ungetc(c);
278: i -= DLENGTH; d = (i%DLENGTH?i/DLENGTH+1:i/DLENGTH);
279: n = NALLOC(d); PL(n) = d;
280: for ( j = 0, ptr = BD(n); j < d; j++ ,i -= DLENGTH )
281: ptr[j] = myatoi(nbuf+i);
282: bnton(DBASE,n,&n1);
283: NTOQ(n1,1,q); r = (Obj)q;
284: /* optobj(&r); */
285: }
286: yylvalp->p = (pointer)r;
287: return ( FORMULA );
288: } else if ( isalpha(c) ) {
1.2 noro 289: i = 0;
290: tbuf[i++] = c;
291: while ( 1 ) {
292: c = Getc();
293: if ( isalpha(c)||isdigit(c)||(c=='_') ) {
294: REALLOC_TBUF tbuf[i++] = c;
295: } else
296: break;
297: }
298: REALLOC_TBUF tbuf[i] = 0; Ungetc(c);
1.1 noro 299: if ( isupper(tbuf[0]) ) {
300: cptr = (char *)MALLOC(strlen(tbuf)+1); strcpy(cptr,tbuf);
301: yylvalp->p = (pointer)cptr;
302: return UCASE;
303: } else {
304: for ( i = 0; kwd[i].name && strcmp(tbuf,kwd[i].name); i++ );
305: if ( kwd[i].name ) {
306: yylvalp->i = asir_infile->ln;
307: return kwd[i].token;
308: } else {
309: cptr = (char *)MALLOC(strlen(tbuf)+1); strcpy(cptr,tbuf);
310: yylvalp->p = (pointer)cptr;
311: return LCASE;
312: }
313: }
314: } else if ( c == '@' ) {
315: if ( isdigit(c = Getc()) ) {
1.2 noro 316: i = 0;
317: nbuf[i++] = c;
318: READ_DIGIT_NBUF
319: Ungetc(c); REALLOC_NBUF nbuf[i] = 0;
320: yylvalp->i = atoi(nbuf);
1.1 noro 321: return ANS;
322: } else if ( c == '@' ) {
323: yylvalp->i = MAX(0,APVS->n-1);
324: return ANS;
325: } else if ( c == '>' || c == '<' || c == '=' || c == '!' ) {
326: if ( (c1 = Getc()) == '=' )
327: switch ( c ) {
328: case '>': yylvalp->i = (int)L_GE; break;
329: case '<': yylvalp->i = (int)L_LE; break;
330: case '=': yylvalp->i = (int)L_EQ; break;
331: case '!': yylvalp->i = (int)L_NE; break;
332: default: break;
333: }
334: else {
335: Ungetc(c1);
336: switch ( c ) {
337: case '>': yylvalp->i = (int)L_GT; break;
338: case '<': yylvalp->i = (int)L_LT; break;
339: case '=': yylvalp->i = (int)L_EQ; break;
340: case '!': yylvalp->i = (int)L_NOT; return FOP_NOT; break;
341: default: break;
342: }
343: }
344: return LOP;
345: } else if ( c == '|' || c == '&' ) {
346: if ( (c1 = Getc()) != c )
347: Ungetc(c1);
348: switch ( c ) {
349: case '|': yylvalp->i = (int)L_OR;
350: return FOP_OR; break;
351: case '&': yylvalp->i = (int)L_AND;
352: return FOP_AND; break;
353: }
354: } else if ( isalpha(c) ) {
1.2 noro 355: i = 0;
356: tbuf[i++] = '@';
357: tbuf[i++] = c;
358: while ( 1 ) {
359: c = Getc();
360: if ( isalpha(c) ) {
361: REALLOC_TBUF tbuf[i++] = c;
362: } else
363: break;
364: }
365: Ungetc(c); REALLOC_TBUF tbuf[i] = 0;
1.1 noro 366: if ( !strcmp(tbuf,"@p") )
367: return GFPNGEN;
1.17 noro 368: else if ( !strcmp(tbuf,"@s") )
369: return GFSNGEN;
1.1 noro 370: else if ( !strcmp(tbuf,"@i") ) {
371: extern pointer IU;
372:
373: yylvalp->p = IU;
374: return FORMULA;
375: } else if ( !strcmp(tbuf,"@true") ) {
376: yylvalp->p = F_TRUE;
377: return FORMULA;
378: } else if ( !strcmp(tbuf,"@false") ) {
379: yylvalp->p = F_FALSE;
380: return FORMULA;
381: } else if ( !strcmp(tbuf,"@impl") ) {
382: yylvalp->i = (int)L_IMPL;
383: return FOP_IMPL;
384: } else if ( !strcmp(tbuf,"@repl") ) {
385: yylvalp->i = (int)L_REPL;
386: return FOP_REPL;
387: } else if ( !strcmp(tbuf,"@equiv") ) {
388: yylvalp->i = (int)L_EQUIV;
389: return FOP_EQUIV;
390: } else {
391: cptr = (char *)MALLOC(strlen(tbuf)+1); strcpy(cptr,tbuf);
392: yylvalp->p = (pointer)cptr;
393: return LCASE;
394: }
395: } else {
396: Ungetc(c);
397: return GF2NGEN;
398: }
399: } else
400: return ( c );
1.6 noro 401: }
402:
403: void purge_stdin()
404: {
1.7 noro 405: #if defined(__FreeBSD__)
1.6 noro 406: fpurge(stdin);
407: #elif defined(linux)
408: stdin->_IO_read_end = stdin->_IO_read_base;
409: stdin->_IO_read_ptr = stdin->_IO_read_base;
1.10 noro 410: #elif defined(VISUAL_LIB)
1.18 noro 411: void w_purge_stdin();
412:
1.10 noro 413: w_purge_stdin();
1.16 noro 414: #elif defined(sparc) || defined(__alpha) || defined(__SVR4) || defined(mips) || defined(VISUAL) || defined(_IBMR2)
1.6 noro 415: stdin->_ptr = stdin->_base; stdin->_cnt = 0;
1.19 ! noro 416: #elif (defined(__MACH__) && defined(__ppc__)) || defined(__CYGWIN__)
1.15 noro 417: stdin->_r = 0; stdin->_p = stdin->_bf._base;
1.6 noro 418: #else
419: --->FIXIT
420: #endif
1.1 noro 421: }
422:
423: static int skipspace() {
424: int c,c1;
425:
426: for ( c = Getc(); ; )
427: switch ( c ) {
1.14 noro 428: case ' ': case '\t': case '\r':
1.1 noro 429: c = Getc(); break;
430: case '\n':
431: c = afternl(); break;
432: case '/':
433: if ( (c1 = Getc()) == '*' )
434: c = aftercomment();
435: else {
436: Ungetc(c1); return c;
437: }
438: break;
439: default:
440: return c; break;
441: }
442: }
443:
444: int afternl() {
445: int c,ac,i,quote;
446: char *ptr;
447: char *av[BUFSIZ];
448: static int ilevel = 0;
449: char buf[BUFSIZ];
450:
451: if ( !ilevel )
452: asir_infile->ln++;
453: while ( (c = Getc()) == '#' ) {
454: Gets(buf);
455: for ( quote = 0, ptr = buf; *ptr; ptr++ )
456: if ( *ptr == '"' )
457: quote = quote ? 0 : 1;
458: else if ( quote && (*ptr == ' ') )
459: *ptr = '_';
460: stoarg(buf,&ac,av);
461: if ( ac == 3 )
462: if ( (i = atoi(av[2])) == 1 )
463: ilevel++;
464: else if ( i == 2 )
465: ilevel--;
466: if ( !ilevel )
467: asir_infile->ln = atoi(av[0]);
468: }
469: return c;
470: }
471:
472: int aftercomment() {
473: int c,c1;
474:
475: for ( c = Getc(); ; ) {
476: c1 = Getc();
477: if ( (c == '*') && (c1 == '/') )
478: return Getc();
479: else
480: c = c1;
481: }
482: }
483:
1.18 noro 484: int myatoi(char *s)
1.1 noro 485: {
486: int i,r;
487: for ( i = 0, r = 0; i < DLENGTH; i++ ) r = r * 10 + ( s[i] - '0' );
488: return ( r );
489: }
490:
491: extern int ox_do_copy;
492:
1.18 noro 493: void yyerror(char *s)
1.1 noro 494: {
495: if ( main_parser )
496: if ( ox_do_copy ) {
497: /* push errors to DebugStack */
498: } else {
499: if ( asir_infile->fp == stdin )
500: fprintf(stderr,"%s\n",s);
501: else
502: fprintf(stderr,"\"%s\", near line %d: %s\n",asir_infile->name,asir_infile->ln,s);
503: }
504: else
505: fprintf(stderr,"exprparse : %s\n",s);
506: }
507:
508: int echoback;
509:
510: extern int read_exec_file, do_fep, do_file;
511:
512: unsigned char encrypt_char(unsigned char);
513: unsigned char decrypt_char(unsigned char);
514:
1.18 noro 515: int Egetc(FILE *fp)
1.1 noro 516: {
517: int c;
518:
519: if ( fp ) {
1.13 noro 520: #if FEP
521: if ( do_fep && isatty(fileno(fp)) )
522: c = readline_getc();
523: else
524: #endif
525: c = getc(fp);
1.11 noro 526: #if defined(VISUAL)
527: if ( recv_intr ) {
528: #include <signal.h>
529: if ( recv_intr == 1 ) {
530: recv_intr = 0;
531: int_handler(SIGINT);
532: } else {
533: recv_intr = 0;
534: ox_usr1_handler(0);
535: }
536: }
537: #endif
1.1 noro 538: if ( c == EOF )
539: return c;
540: if ( asir_infile->encoded )
541: c = decrypt_char((unsigned char)c);
542: return c;
1.3 noro 543: } else if ( read_exec_file )
544: return EOF;
545: else {
1.1 noro 546: c = *parse_strp++;
547: if ( !c )
548: return EOF;
549: else
550: return c;
551: }
552: }
553:
1.18 noro 554: void Eungetc(int c,FILE *fp)
1.1 noro 555: {
556: if ( fp ) {
557: if ( asir_infile->encoded )
558: c = (int)encrypt_char((unsigned char)c);
1.13 noro 559: #if FEP
560: if ( do_fep && isatty(fileno(fp)) )
561: readline_ungetc();
562: else
563: #endif
564: ungetc(c,fp);
1.1 noro 565: } else
566: *--parse_strp = c;
567: }
568:
569: static int Getc() {
570: int c;
571:
572: if ( main_parser ) {
573: while ( 1 ) {
574: if ((c = Egetc(asir_infile->fp)) == EOF)
575: if ( NEXT(asir_infile) ) {
576: closecurrentinput();
1.9 noro 577: /* if the input is the top level, generate error */
578: if ( !NEXT(asir_infile) )
579: error("end-of-file detected during parsing");
580: else
581: c = Getc();
1.1 noro 582: break;
583: } else if ( read_exec_file || do_file )
584: asir_terminate(2);
585: else {
586: if ( asir_infile->fp )
587: clearerr(asir_infile->fp);
588: }
589: else
590: break;
591: }
592: if ( echoback )
593: fputc(c,asir_out);
594: } else
595: c = *parse_strp++;
596: return ( c );
597: }
598:
1.18 noro 599: static void Ungetc(int c) {
1.1 noro 600: if ( main_parser ) {
601: Eungetc(c,asir_infile->fp);
602: if ( echoback )
603: fputc('',asir_out);
604: } else
605: *--parse_strp = c;
606: }
607:
1.18 noro 608: static void Gets(char *s)
1.1 noro 609: {
610: int c;
611:
612: while ( (c = Getc()) != '\n' )
613: *s++ = c;
614: *s = 0;
615: }
1.12 saito 616:
617: #if FEP
618:
619: static char *readline_line;
620: static int readline_nc,readline_index;
621: char *readline_console();
622:
623: int readline_getc()
624: {
625: char buf[BUFSIZ];
626:
627: if ( !readline_nc ) {
628: if ( readline_line )
629: free(readline_line);
630: sprompt(buf);
631: readline_line = readline_console(buf);
632: readline_nc = strlen(readline_line);
633: readline_index = 0;
634: }
635: readline_nc--;
636: return readline_line[readline_index++];
637: }
638:
639: void readline_ungetc()
640: {
641: readline_nc++; readline_index--;
642: }
643:
1.18 noro 644: char *readline_console(char *prompt)
1.12 saito 645: {
646: char *line;
647: int exp_result;
648: char *expansion;
649:
650: while ( 1 ) {
651: line = (char *)readline(prompt);
652: if ( line && *line ) {
653: using_history();
654: exp_result = history_expand(line,&expansion);
655: if ( !exp_result ) {
656: free(expansion);
657: for ( ; isspace(*line); line++ );
658: add_history(line);
659: break;
660: } else if ( exp_result > 0 ) {
661: free(line);
662: line = expansion;
663: break;
664: }
665: }
666: }
667: return line;
668: }
669: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>