1: /*------------------------------------------------------------------------*/
2: /* capaLexerDef.flex created by Isaac Tsai Jul 15 1996 */
3: /* added /END(variable) */
4: /* added /HIN .... /DIS(variable) ... */
5: /* Jan 15 1998 /{KeyWord}{KeyWord}{KeyWord} */
6: /* replaced by /DIS */
7: /* catch "No /END() statement found" */
8: /* catch "/DIS(")" and "/DIS(""")" errors " */
9: /* catch "/LET var = " */
10: /* add a new token EoL to indicate '\n' '\r''\n' and '\r' */
11: /* This file is based on flex 2.5.3, flex 2.3 apparantly cannot take it :-( */
12: /* DONE /RMAP() function July 14, 1998 */
13: /* DONE /AND /OR answer formats July 20, 1998 */
14: /* DONE /IF () /ENDIF July 26, 1998 */
15: /* DONE /WHILE () /ENDWHILE August 10 1998 */
16: /* DONE /VERB /ENDVERB Feb 20 1998 */
17: /*------------------------------------------------------------------------*/
18: /**************************************************************************/
19:
20: %{
21:
22: #include <stdio.h>
23: #include <stdlib.h> /* strtod(), strtol() */
24: #include <string.h>
25: #ifdef NeXT
26: #include <sys/file.h>
27: #else
28: #include <unistd.h> /* access() */
29: #endif
30:
31: #include "capaCommon.h" /* capa_access() */
32: #include "capaParser.h" /* _symbol structure def */
33: #include "lex_debug.h" /* defined RETURN(xxx) macro */
34: #ifdef YYSTYPE
35: #undef YYSTYPE
36: #endif
37: #define YYSTYPE Symbol_p
38: #include "capaToken.h" /* from YACC -d capaGrammarDef.y */
39:
40:
41:
42: /* ============================================== begin of code */
43:
44: #define LEX_BUFLEN (8*1024) /* lexical buffer size (for each opened file) */
45:
46: #ifdef YYLMAX
47: #undef YYLMAX
48: #define YYLMAX 8192
49: #endif
50:
51: void yyfatalerror(char*msg);
52: #define YY_FATAL_ERROR yyfatalerror
53:
54: #ifdef LEX_DBUG
55: #define LLDBUG_PRL1(xx) { printf("Line %d ",Current_line[Input_idx]); printf(xx); fflush(stdout); }
56: #define LLDBUG_PRL2(xx,yy) { printf("Line %d ",Current_line[Input_idx]); printf(xx,yy); fflush(stdout); }
57: #define LLDBUG_PR1(xx) { printf(xx); fflush(stdout); }
58: #define LLDBUG_PR2(xx,yy) { printf(xx,yy); fflush(stdout); }
59: #define LLDBUG_PR3(xx,yy,zz) { printf(xx,yy,zz); fflush(stdout); }
60: #else
61: #define LLDBUG_PRL1(xx) { }
62: #define LLDBUG_PRL2(xx,yy) { }
63: #define LLDBUG_PR1(xx) { }
64: #define LLDBUG_PR2(xx,yy) { }
65: #define LLDBUG_PR3(xx,yy,zz) { }
66: #endif
67:
68: #ifdef LEX_INPUT_DBUG
69: #define LIDBUG_PR1(xx) { printf(xx); fflush(stdout); }
70: #define LIDBUG_PR2(xx,yy) { printf(xx,yy); fflush(stdout); }
71: #define LIDBUG_PR3(xx,yy,zz) { printf(xx,yy,zz); fflush(stdout); }
72: #else
73: #define LIDBUG_PR1(xx) { }
74: #define LIDBUG_PR2(xx,yy) { }
75: #define LIDBUG_PR3(xx,yy,zz) { }
76: #endif
77:
78: #ifdef USE_DYNAMIC_SYMBOLS
79: #define USE_DYNAMIC_LEXBUFS
80: #endif
81:
82: Symbol *yylval; /* global pointer to symbol */
83:
84: FILE *(Input_stream[MAX_OPENED_FILE]); /* <-- perhaps we can use linked list */
85: char Opened_filename[MAX_OPENED_FILE][QUARTER_K]; /* <-- perhaps we can use linked list */
86: int Input_idx;
87: int Lexi_pos[MAX_OPENED_FILE]; /* Current position in the line */
88:
89: #ifdef USE_DYNAMIC_LEXBUFS
90: char *(Lexi_buf[MAX_OPENED_FILE]); /* Line Buffer for current file */
91:
92: #else
93: char Lexi_buf[MAX_OPENED_FILE][LEX_BUFLEN+4]; /* Line Buffer for current file */
94:
95: #endif /* USE_DYNAMIC_LEXBUFS */
96:
97: char String_buf[LEX_BUFLEN]; /* Constant String buffer <-- perhaps we can use char pointer */
98: char *Dynamic_buf;
99: int Dynamic_buf_max;
100: int Dynamic_buf_cur;
101:
102:
103: static int End_of_input;
104: static int Pcount, Bcount; /* static means only available in this file */
105: /* --------------------------------------------------------------------------- */
106: /* GLOBAL VARIABLES */
107: /* --------------------------------------------------------------------------- */
108: int Lexi_line; /* Current source file line number, counting from beginning */
109: extern int Current_line[MAX_OPENED_FILE];
110:
111: int Func_idx;
112: Symbol FuncStack[MAX_FUNC_NEST]; /* <-- perhaps we can use linked list */
113:
114: int Array_idx;
115: Symbol *ArraySymbList_p;
116: Symbol *ArraySymbLast_p;
117: Symbol *FmlSymbList_p;
118: Symbol *FmlSymbLast_p;
119: int FmlSymb_cnt;
120: int Symb_count;
121:
122: int IFstatus[MAX_FUNC_NEST]; /* <-- perhaps we can use linked list */
123: int IFcurrent[MAX_FUNC_NEST]; /* <-- perhaps we can use linked list */
124: int IFcount;
125: WhileLoop_t WhileStack[MAX_FUNC_NEST]; /* <-- perhaps we can use linked list */
126: int While_idx, Wcount;
127:
128: #ifdef USE_DYNAMIC_SYMBOLS
129: Symbol *SymbList_p;
130: Symbol *SymbLast_p;
131: #else
132: Symbol SymbArray[MAX_SYMB_COUNT];
133: #endif /* USE_DYNAMIC_SYMBOLS */
134:
135:
136: char *Current_char_p; /* Collect string constant */
137: extern char *EndText_p;
138: extern char *StartText_p;
139: extern Problem_t *LexiProblem_p;
140: extern Problem_t *LastProblem_p;
141: int first_run=1;
142: int Stop_Parser;
143: #define FLEX
144:
145: #define YY_STACK_USED 1 /* for yy_push_state(), yy_pop_state() */
146:
147: #ifdef FLEX
148:
149: int capaL_unput();
150: int capaL_input();
151:
152:
153: /* YY_INPUT()
154: Controls scanner input. By default, YY_INPUT reads from the
155: file-pointer yyin. Its action is to place up to max_size
156: characters in the character array buf and return in the
157: integer variable result either the number of characters read
158: or the constant YY_NULL to indicate EOF.
159: max_size is defined to be num_to_read = 8192 in liby
160: Following is a sample
161: redefinition of YY_INPUT, in the definitions section of
162: the input file:
163:
164: %{
165: #undef YY_INPUT
166: #define YY_INPUT(buf,result,max_size)\
167: {\
168: int c = getchar();\
169: result = (c == EOF) ? YY_NULL : (buf[0] = c, 1);\
170: }
171: %}
172:
173: */
174:
175: /* fgets() reads the input stream until
176: n-1 bytes have been read OR
177: a newline character is read and transferred to string OR
178: an EOF (End-of-File) condition is encountered
179:
180: The string is then terminated with a NULL character.
181:
182: ii = fseek(FILE *stream,0L,SEEK_END) ;
183: if(ii!=0) { error }
184: leng = ftell(FILE *stream) + 1 ;
185: fseek(FILE *stream,0L,SEEK_SET) ;
186: Lexi_buf[Input_idx] = (char *)capa_malloc(sizeof(char)*leng,1);
187:
188: */
189:
190:
191: #ifdef AVOIDYYINPUT
192: #define MAX_INCLUDE_DEPTH 10
193: YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
194: int include_stack_ptr = 0;
195: #else
196: #ifdef USE_DYNAMIC_LEXBUFS
197: #define NEWYYINPUT
198: #endif
199:
200: #ifdef NEWYYINPUT
201: void newyy_input (char *buf,int *result,int max_size);
202: #define YY_INPUT(buf,result,max_size) newyy_input(buf,&result,max_size)
203:
204: #else
205: #ifdef USE_DYNAMIC_LEXBUFS
206:
207: #define YY_INPUT(buf,result,max_size) \
208: { int ii, leng, out_of_char; \
209: if (!Lexi_line) { /* was startup */ \
210: for(ii=0;ii < MAX_OPENED_FILE;ii++) { \
211: Lexi_buf[ii] = NULL; \
212: Lexi_pos[ii] = 0; \
213: Current_line[ii] = 0; \
214: } \
215: Input_idx = 0; \
216: first_run=0; \
217: yyin = Input_stream[Input_idx]; LIDBUG_PR1("<<yy_input() startup>>\n"); \
218: } \
219: out_of_char = 0; \
220: if ( Lexi_buf[Input_idx] == NULL ) { \
221: Lexi_buf[Input_idx] = (char *)capa_malloc(sizeof(char)*LEX_BUFLEN+1,1); out_of_char=1; \
222: } else { \
223: if (!Lexi_buf[Input_idx][Lexi_pos[Input_idx]]) { /* test if the line buffer is empty or at the end */ \
224: out_of_char=1; \
225: } \
226: } \
227: if( out_of_char ) { \
228: if (fgets(Lexi_buf[Input_idx],LEX_BUFLEN-1,Input_stream[Input_idx])==NULL) { /* read in one line */ \
229: LIDBUG_PR2("<<yy_input() fgets() returns NULL, input index=%d>>\n",Input_idx); \
230: if( (Input_idx > 0) && ( Lexi_buf[Input_idx][Lexi_pos[Input_idx]] == '\0') ) { \
231: LIDBUG_PR2("<<yy_input() close an input stream, input index=%d>>\n",Input_idx); \
232: fclose(Input_stream[Input_idx]); \
233: capa_mfree((char *)Lexi_buf[Input_idx]); \
234: Lexi_buf[Input_idx] = NULL; \
235: Input_idx--; \
236: yyin = Input_stream[Input_idx]; \
237: /* (Lexi_pos[Input_idx])++; */ \
238: buf[0] = Lexi_buf[Input_idx][Lexi_pos[Input_idx]-1]; \
239: result = 1; \
240: } else { \
241: result = YY_NULL; /* End of File */ \
242: } \
243: } else { /* successfully read in one line */ \
244: if (Lexi_buf[Input_idx]==NULL) puts("Whatup?");\
245: leng = strlen(Lexi_buf[Input_idx]); \
246: LIDBUG_PR3("<<yy_input() read into buffer a line(leng=%d), input index=%d>>\n",leng,Input_idx); \
247: Lexi_pos[Input_idx] = 0; \
248: Lexi_line++; \
249: Current_line[Input_idx]++; \
250: (Lexi_pos[Input_idx])++; \
251: buf[0] = Lexi_buf[Input_idx][Lexi_pos[Input_idx]-1]; \
252: /* need to take care of return continuation conditions */ \
253: /* so, we return to one-char-at-a-time approach */ \
254: /* for(ii=0;ii<leng;ii++) { */ \
255: /* buf[ii] = Lexi_buf[Input_idx][ii]; */ \
256: /* } */ \
257: /* buf[ii] = '\0'; */ \
258: /* printf("YY_INPUT()(Lexi_line=%d,max size=%d)(%c)",Lexi_line,max_size,buf[0]); */ \
259: result = 1; \
260: } \
261: } else { \
262: /* LIDBUG_PR2("<<yy_input() increase Lexi_pos, input index=%d>>\n",Input_idx); */ \
263: (Lexi_pos[Input_idx])++; \
264: buf[0] = Lexi_buf[Input_idx][Lexi_pos[Input_idx]-1]; \
265: result = 1; \
266: } \
267: if (Stop_Parser==1) { \
268: result = YY_NULL; \
269: } \
270: }
271:
272: #else
273:
274: #define YY_INPUT(buf,result,max_size) \
275: { int ii, leng; \
276: if (!Lexi_line) { /* was startup */ \
277: for(ii=0;ii < MAX_OPENED_FILE;ii++) { \
278: Lexi_buf[ii][0]=0; \
279: Lexi_pos[ii] = 0; \
280: Current_line[ii] = 0; \
281: } \
282: Input_idx = 0; \
283: first_run=0; \
284: yyin = Input_stream[Input_idx]; LIDBUG_PR1("<<yy_input() startup>>\n"); \
285: } \
286: if (!Lexi_buf[Input_idx][Lexi_pos[Input_idx]]) { /* test if the line buffer is empty or at the end */ \
287: if (fgets(Lexi_buf[Input_idx],LEX_BUFLEN-1,Input_stream[Input_idx])==NULL) { /* read in one line */ \
288: LIDBUG_PR2("<<yy_input() fgets() returns NULL, input index=%d>>\n",Input_idx); \
289: if( (Input_idx > 0) && ( Lexi_buf[Input_idx][Lexi_pos[Input_idx]] == '\0') ) { \
290: LIDBUG_PR2("<<yy_input() close an input stream, input index=%d>>\n",Input_idx); \
291: fclose(Input_stream[Input_idx]); \
292: Input_idx--; \
293: yyin = Input_stream[Input_idx]; \
294: /* (Lexi_pos[Input_idx])++; */ \
295: buf[0] = Lexi_buf[Input_idx][Lexi_pos[Input_idx]-1]; \
296: result = 1; \
297: } else { \
298: result = YY_NULL; /* End of File */ \
299: } \
300: } else { /* successfully read in one line */ \
301: leng = strlen(Lexi_buf[Input_idx]); \
302: LIDBUG_PR3("<<yy_input() read into buffer a line(leng=%d), input index=%d>>\n",leng,Input_idx); \
303: Lexi_pos[Input_idx] = 0; \
304: Lexi_line++; \
305: Current_line[Input_idx]++; \
306: (Lexi_pos[Input_idx])++; \
307: buf[0] = Lexi_buf[Input_idx][Lexi_pos[Input_idx]-1]; \
308: /* need to take care of return continuation conditions */ \
309: /* so, we return to one-char-at-a-time approach */ \
310: /* for(ii=0;ii<leng;ii++) { */ \
311: /* buf[ii] = Lexi_buf[Input_idx][ii]; */ \
312: /* } */ \
313: /* buf[ii] = '\0'; */ \
314: /* printf("YY_INPUT()(Lexi_line=%d,max size=%d)(%c)",Lexi_line,max_size,buf[0]); */ \
315: result = 1; \
316: } \
317: } else { \
318: /* LIDBUG_PR2("<<yy_input() increase Lexi_pos, input index=%d>>\n",Input_idx); */ \
319: (Lexi_pos[Input_idx])++; \
320: buf[0] = Lexi_buf[Input_idx][Lexi_pos[Input_idx]-1]; \
321: result = 1; \
322: } \
323: if (Stop_Parser==1) { \
324: result = YY_NULL; \
325: } \
326: }
327: #endif /* USE_DYNAMIC_LEXBUFS */
328: #endif /*NEWYYINPUT*/
329: #endif /*AVOIDYYINPUT*/
330:
331: #else
332:
333: #undef input
334: #undef unput
335:
336: #endif
337:
338: int capa_eof();
339: %}
340:
341: Alpha [a-zA-Z_]
342: KeyChar [A-Z]
343: AlphaNum [a-zA-Z_0-9]
344: Number [0-9]
345: HexNumber [0-9a-fA-F]
346: Space [ \t]
347: Spaces ({Space}*)
348: FileName (\"[^"\n]*\")
349: Qchar ([0-9a-zA-Z \t!?\._,:;'"`~@#$%\^&\+\-\*=|\[\]{}()])
350: Operator ([=\+\-\*/%<>!&|,])
351: Identifier ([a-zA-Z_][a-zA-Z_0-9]*)
352: EndLine ([\r][\n]|[\n])
353:
354: %a 10500
355: %o 15000
356: %k 10000
357: %p 10000
358: %n 1000
359: %x S_COMMENT S_HINT S_HINTEXLAINX S_IMPORT S_EXPLAIN S_ENDX S_UNIT S_IGNORE
360: %x S_SKIP S_VARIABLE S_LET S_DEFINE S_TEXT S_MAP S_FIGURE S_ANSWER
361: %x S_STRING S_ANSCONTINUE S_TRUE_FALSE_STMT S_IF_SKIP S_WHILE_SKIP
362: %x S_NEXT_LINE S_VERB
363: %array
364:
365:
366:
367: %%
368:
369: <S_IGNORE>{
370: {EndLine} BEGIN S_IGNORE;
371: [^\n]*$ BEGIN S_IGNORE;
372: <<EOF>> {
373: capa_eof();
374: #ifndef AVOIDYYINPUT
375: yyterminate();
376: #endif
377: }
378: }
379:
380: <S_COMMENT>{
381: ^{Spaces}"//"[^\n]*$ { LLDBUG_PRL2("[COMMENT<%s>]\n",yytext);
382: send(&yytext[2]);
383: send("\n");
384: BEGIN S_COMMENT;
385: }
386: . { send("</comment>\n"); BEGIN S_TEXT; }
387: }
388:
389: <S_TEXT>{
390: ^{Spaces}"/LET" |
391: ^{Spaces}"/BEG" { LLDBUG_PRL1("[LET]"); Pcount = 0; init_funcstack(); BEGIN S_LET; RETURN(CAPA_LET); }
392: ^{Spaces}"/VERB" {
393: LLDBUG_PRL1("[VERBATIM]");
394: Dynamic_buf = (char *)capa_malloc(sizeof(char),10);
395: Dynamic_buf_max = 10;
396: Dynamic_buf_cur = 0;
397: Dynamic_buf[0] = '\0';
398: BEGIN S_VERB;
399: }
400: ^{Spaces}"/HIN"{Alpha}*{Spaces} { LLDBUG_PRL1("[HIN]"); Current_char_p = String_buf; BEGIN S_HINT; }
401: ^{Spaces}"/EXP"{Alpha}*{Spaces} { LLDBUG_PRL1("[EXP]"); Current_char_p = String_buf; BEGIN S_EXPLAIN; }
402: ^{Spaces}"/IMP"{Alpha}*{Space}+ { LLDBUG_PRL1("[IMP]"); BEGIN S_IMPORT; }
403: ^{Spaces}"/END" { LLDBUG_PRL1("[END]");
404: if ( (LexiProblem_p !=NULL) &&
405: (LexiProblem_p->question != NULL) &&
406: (LexiProblem_p->ans_type == 0)) {
407: EndText_p=strsave(LexiProblem_p->question);
408: LexiProblem_p=NULL;
409: } else {
410: EndText_p=NULL;
411: }
412: End_of_input = 1; BEGIN S_IGNORE;RETURN(CAPA_END);
413: }
414: ^{Spaces}"/START"[^\n]* { LLDBUG_PRL1("[START]");
415: if (LexiProblem_p !=NULL &&
416: LexiProblem_p->question != NULL) {
417: StartText_p=strsave(LexiProblem_p->question);
418: } else {
419: StartText_p=NULL;
420: }
421: BEGIN S_TEXT;
422: RETURN(CAPA_START);
423: }
424:
425: ^{Spaces}"/END"{Spaces}[\(]{Spaces} { LLDBUG_PRL1("[END()]"); BEGIN S_ENDX; }
426: ^"/DEF" { Bcount = 0; BEGIN S_DEFINE; RETURN(CAPA_DEF); }
427: ^{Spaces}"/ANS" { LLDBUG_PRL2("[ANS(%s)]",yytext); Pcount = 0; BEGIN S_ANSWER; RETURN(CAPA_ANS); }
428: ^{Spaces}"/SUBJECTIVE" { LLDBUG_PRL1("[SUBJECTIVE ANSWER]"); Pcount = 0; BEGIN S_ANSWER; RETURN(CAPA_SUBJ); }
429: ^{Spaces}"/MAP" { LLDBUG_PRL1("[MAP]"); Pcount = 0; BEGIN S_MAP; RETURN(CAPA_MAP); }
430: ^{Spaces}"/RMAP" { LLDBUG_PRL1("[RMAP]"); Pcount = 0; BEGIN S_MAP; RETURN(CAPA_RMAP); }
431: ^{Spaces}"/ENDWHILE"([^\n])* { long int file_pos;
432: int top_item, input_idx;
433: LLDBUG_PRL2("[ENDWHILE While_idx=<%d>]\n",While_idx);
434:
435: top_item = While_idx - 1;
436: if( top_item < 0 ) { /* strange things must have happened here! */
437:
438: } else {
439: input_idx = WhileStack[top_item].input_idx;
440: file_pos = WhileStack[top_item].pos_idx;
441: Current_line[input_idx] = WhileStack[top_item].line_idx;
442: Lexi_pos[input_idx] = 0;
443: fseek(Input_stream[input_idx],file_pos,SEEK_SET);
444: fgets(Lexi_buf[input_idx],LEX_BUFLEN-1,Input_stream[input_idx]);
445: While_idx--;
446: }
447: BEGIN S_TEXT;
448: }
449: "/WHILE" |
450: ^{Spaces}"/WHILE" { long int file_pos;
451: int leng;
452: LLDBUG_PRL2("[WHILE While_idx=<%d>]\n",While_idx);
453: leng = strlen(Lexi_buf[Input_idx]); /* length of current line */
454: /* <-- because we use fgets() to read input,
455: thus ftell() will give the starting position of next line */
456: WhileStack[While_idx].input_idx = Input_idx;
457: file_pos = ftell(Input_stream[Input_idx]);
458: file_pos -= leng; /* calibrate the current line length */
459: WhileStack[While_idx].pos_idx = file_pos; /* begin of current line */
460: WhileStack[While_idx].line_idx = Current_line[Input_idx];
461: While_idx++; /* advance the stack pointer */
462:
463: BEGIN S_TRUE_FALSE_STMT; RETURN(CAPA_WHILE);
464:
465: }
466: ^{Spaces}"/IF" { IFcount++; IFcurrent[IFcount] = RUN_IF_PORTION;
467: LLDBUG_PRL2("[IF <IFcount=%d>]",IFcount); BEGIN S_TRUE_FALSE_STMT; RETURN(CAPA_IF); }
468: ^{Spaces}"/ELSE"([^\n])* { LLDBUG_PRL2("[ELSE <IFcount=%d>]\n",IFcount);
469: IFcurrent[IFcount] = RUN_ELSE_PORTION;
470: if( IFstatus[IFcount] == IF_TRUE ) {
471: LLDBUG_PRL1("[ELSE begin Skip]\n");
472: BEGIN S_IF_SKIP;
473: }
474: }
475: ^{Spaces}"/ENDIF"([^\n])* { IFcount--; LLDBUG_PRL2("[ENDIF <IFcount=%d>]\n",IFcount);
476: }
477: "/AND" { LLDBUG_PRL1("[AND]"); BEGIN S_ANSCONTINUE; RETURN(ANS_AND); }
478: "/DIS" { /* since S_VARIABLE treat {Space} as null, so here we do not match ( */
479: /* so that between /DIS and ( can have as many {Space} as we want */
480: LLDBUG_PR1("[DIS<]");
481: init_funcstack();
482: Pcount = 0; BEGIN S_VARIABLE;
483: RETURN(CAPA_VAR);
484: }
485: "/OR" { LLDBUG_PRL1("[OR]"); BEGIN S_ANSCONTINUE; RETURN(ANS_OR); }
486: {EndLine} { LLDBUG_PR1("[EoL within S_TEXT]\n"); /* end of the whole text line */
487: RETURN(EoL); }
488: [\\]{Space}*{EndLine} { LLDBUG_PR2("[\\EoL continue](%s)",yytext); /* continuation on next line */ }
489: ^{Spaces}"//"[^\n]*{EndLine} { LLDBUG_PRL2("[COMMENT<%s>]\n",yytext);
490: send("<comment>\n");
491: send(&yytext[2]);
492: BEGIN S_COMMENT;
493: }
494: [^/\n\\]+$ |
495: [/] |
496: [\\] { yylval = (Symbol *) capa_malloc(1, sizeof(Symbol));
497: yylval->s_str = strsave(yytext);
498: LLDBUG_PR2("[TEXT_LINE<%s>]",yytext);
499: RETURN(TEXT_LINE);
500: }
501: ([^/\n])+[/] |
502: ([^/\n])+[\\] { /* matches anything until a '/' or a '\' */
503: LLDBUG_PR2("[TEXT_LINE( )<%s>]",yytext);
504:
505: yyless(yyleng-1); /* push back the last char */
506: yylval = (Symbol *) capa_malloc(1, sizeof(Symbol));
507: yylval->s_str = strsave(yytext);
508:
509: BEGIN S_TEXT;
510: RETURN(TEXT_LINE);
511: }
512: <<EOF>> {
513: #ifdef AVOIDYYINPUT
514: char warn_msg[ONE_K];
515:
516: if ( (--include_stack_ptr < 0) || Stop_Parser) {
517: if (Stop_Parser) {
518: if ( LexiProblem_p!=NULL &&
519: LexiProblem_p->question != NULL)
520: EndText_p=strsave(LexiProblem_p->question);
521: while (include_stack_ptr >= 0) {
522: yy_delete_buffer( YY_CURRENT_BUFFER );
523: yy_switch_to_buffer(
524: include_stack[include_stack_ptr]);
525: --include_stack_ptr;
526: }
527: } else {
528: sprintf(warn_msg,
529: "at End-of-File, a /END is needed.\n");
530: capa_msg(MESSAGE_ERROR,warn_msg);
531: }
532: free_problems(LexiProblem_p);
533: LexiProblem_p=NULL;
534: yyterminate();
535: } else {
536: yy_delete_buffer( YY_CURRENT_BUFFER );
537: yy_switch_to_buffer(include_stack[include_stack_ptr]);
538: }
539: #else
540: char warn_msg[ONE_K];
541: if (!Stop_Parser) {
542: sprintf(warn_msg,"at End-of-File, a /END is needed.\n");
543: capa_msg(MESSAGE_ERROR,warn_msg);
544: } else {
545: if (LexiProblem_p != NULL &&
546: LexiProblem_p->question != NULL)
547: EndText_p=strsave(LexiProblem_p->question);
548: }
549: capa_eof();
550: yyterminate();
551: #endif
552: }
553: }
554:
555:
556: <S_ENDX>{
557: {Alpha}{AlphaNum}* { /* DONE: add codes to handle /END() */
558: char *question_end=NULL;
559: End_of_input = 1;
560: if (EndText_p!=NULL) capa_mfree((char*)EndText_p);
561: if ((LexiProblem_p!=NULL) &&
562: (LexiProblem_p->question != NULL) &&
563: (LexiProblem_p->ans_type == 0)) {
564: question_end=strsave(LexiProblem_p->question);
565: }
566: if( yyleng > 0 ) {
567:
568: LLDBUG_PRL2("[END()<%s>]\n",yytext);
569: /*yylval = find_identifier(yytext);*/
570:
571: switch(yylval->s_type) {
572: case IDENTIFIER:
573: case I_VAR: case I_CONSTANT:
574: case R_VAR: case R_CONSTANT:
575: break;
576: case S_VAR: case S_CONSTANT:
577: EndText_p = strsave(yylval->s_str);
578: if (question_end) {
579: int leng; char *new_end;
580: leng = strlen(EndText_p) +
581: strlen(question_end) + 1;
582: new_end = capa_malloc(sizeof(char), leng);
583: strcat(new_end, question_end);
584: strcat(new_end, EndText_p);
585: capa_mfree(EndText_p);
586: capa_mfree(question_end);
587: EndText_p=new_end;
588: }
589: break;
590: default: break;
591: }
592: }
593: BEGIN S_IGNORE; RETURN(CAPA_END);
594: }
595: {Space}* { /* ignore spaces */ }
596: [\)] { /* a right paren */
597: if ( (LexiProblem_p != NULL) &&
598: (LexiProblem_p->question != NULL) &&
599: (LexiProblem_p->ans_type == 0)) {
600: EndText_p=strsave(LexiProblem_p->question);
601: } else {
602: EndText_p=NULL;
603: }
604: BEGIN S_IGNORE;
605: RETURN(CAPA_END);
606: }
607: }
608:
609: <S_HINT,S_EXPLAIN>{
610: [/][Dd][Ii][Ss]{Space}*[\(]{Space}* { yy_push_state(S_HINTEXLAINX); }
611: [^/\n]+[/\\] { char *aptr = yytext;
612: int ii;
613:
614: yyless(yyleng-1);
615: for(ii=0;ii<yyleng;ii++) {
616: *Current_char_p++ = *aptr++;
617: }
618:
619: }
620: [/] { *Current_char_p++ = '/'; }
621: [\\] { *Current_char_p++ = '\\'; }
622: [\\]{Space}*[\n] { LLDBUG_PR1("[\\CR hint explain continue]"); /* Hint and explain continuation */ }
623: [^/\n\\]+$ { char *aptr = yytext;
624: int ii;
625: for(ii=0;ii<yyleng;ii++) {
626: *Current_char_p++ = *aptr++;
627: }
628: }
629: }
630: <S_HINT>{
631: {EndLine} { LLDBUG_PR1("[CR hint]");
632: yylval = (Symbol *) capa_malloc(1, sizeof(Symbol));
633: *Current_char_p++ = '\n'; *Current_char_p = '\0';
634: yylval->s_str = strsave(String_buf);
635: BEGIN S_TEXT; RETURN(HINT_LINE);
636: }
637: }
638: <S_EXPLAIN>{
639: {EndLine} { LLDBUG_PR1("[CR explain]");
640: yylval = (Symbol *) capa_malloc(1, sizeof(Symbol));
641: *Current_char_p++ = '\n'; *Current_char_p = '\0';
642: yylval->s_str = strsave(String_buf);
643: BEGIN S_TEXT; RETURN(EXPLAIN_LINE);
644: }
645: }
646:
647: <S_HINTEXLAINX>{
648: {Alpha}{AlphaNum}* { char *aptr;
649: char tmp_str[QUARTER_K],warn_msg[ONE_K];
650: int ii, len;
651: Symbol *tmp_p;
652:
653: /*tmp_p = find_identifier(yytext);*/
654: switch(tmp_p->s_type) {
655: case IDENTIFIER:
656: sprintf(warn_msg,"var %s not defined.\n", yytext);
657: capa_msg(MESSAGE_ERROR,warn_msg);
658: break;
659: case I_VAR:
660: case I_CONSTANT:
661: sprintf(tmp_str,"%ld",tmp_p->s_int);
662: len = strlen(tmp_str);
663: for(ii=0;ii< len;ii++) {
664: *Current_char_p++ = tmp_str[ii];
665: }
666: break;
667: case R_VAR:
668: case R_CONSTANT:
669: sprintf(tmp_str,"%g",tmp_p->s_real);
670: len = strlen(tmp_str);
671: for(ii=0;ii< len;ii++) {
672: *Current_char_p++ = tmp_str[ii];
673: }
674: break;
675: case S_VAR:
676: case S_CONSTANT:
677: len = strlen(tmp_p->s_str);
678: aptr = tmp_p->s_str;
679: for(ii=0;ii< len;ii++) {
680: *Current_char_p++ = *aptr++;
681: }
682: break;
683: }
684: }
685: {Space}+ { }
686: [)] { yy_pop_state(); }
687: }
688:
689: <S_IMPORT>{
690: {FileName}{Space}* { parse_filename(yytext); BEGIN S_SKIP; }
691: {Identifier}{Space}* { parse_import_id(yytext); BEGIN S_SKIP; }
692: }
693:
694: <S_ANSWER>{
695: [Pp][Ll][Uu][Ss] { LLDBUG_PR1("[PLUS]"); RETURN(ANS_PLUS); }
696: [Mm][Ii][Nn][Uu][Ss] { LLDBUG_PR1("[MINUS]"); RETURN(ANS_MINUS); }
697: [Cc][Ss] { LLDBUG_PR1("[CS]"); RETURN(ANS_CS); }
698: [Cc][Ii] { LLDBUG_PR1("[CI]"); RETURN(ANS_CI); }
699: [Mm][Cc] { LLDBUG_PR1("[MC]"); RETURN(ANS_MC); }
700: [Oo][Nn] |
701: [Yy][Ee][Ss] { LLDBUG_PR1("[ON]"); RETURN(ANS_ON); }
702: [Oo][Ff][Ff] |
703: [Nn][Oo] { LLDBUG_PR1("[OFF]"); RETURN(ANS_OFF); }
704: [Ff][Mm][Ll] { LLDBUG_PR1("[FORMULA]"); RETURN(ANS_FORMULA); }
705: [Ff][Mm][Tt] { LLDBUG_PR1("[FMT]"); RETURN(ANS_FMT); }
706: [Uu][Nn][Ff][Mm][Tt] { LLDBUG_PR1("[UNFMT]"); RETURN(ANS_UNFMT); }
707: [,:%=@#-] { LLDBUG_PR2("[symbol(%s)]",yytext); return(yytext[0]); }
708: "<" { LLDBUG_PR2("[symbol(%s)]",yytext); return(yytext[0]); }
709: ">" { LLDBUG_PR2("[symbol(%s)]",yytext); return(yytext[0]); }
710: [Ss][Ii][Gg] { LLDBUG_PR2("[SIG(%s)]",yytext); RETURN(ANS_SIG); }
711: [Tt][Oo][Ll] { LLDBUG_PR2("[tol(%s)]",yytext); RETURN(ANS_TOLERANCE); }
712: [Ss][Tt][Rr] { LLDBUG_PR1("[STR]"); RETURN(ANS_COMPARE); }
713: [Ww][Gg][Tt] { LLDBUG_PR1("[WGT]"); RETURN(ANS_WEIGHT); }
714: [Pp][Cc][Rr] |
715: [Hh][Gg][Rr] { RETURN(ANS_PCREDIT); }
716: [Pp][Aa][Tt][Hh] { RETURN(ANS_PATH); }
717: [Cc][Aa][Ll][Cc] { RETURN(ANS_CALC); }
718: [Tt][Rr][Yy] |
719: [Tt][Rr][Ii][Ee][Ss] { LLDBUG_PR1("[TRY]"); RETURN(ANS_TRY); }
720: [Uu][Nn][Ii][Tt] |
721: [Uu][Nn][Ii][Tt][Ss] { LLDBUG_PR1("[UNIT]"); RETURN(ANS_UNIT); }
722: [Bb][Rr] { LLDBUG_PR1("[SHOW_BR]"); RETURN(ANS_SHOW_BR); }
723: [Vv][Ee][Rr][Bb][Aa][Tt][Ii][Mm] { LLDBUG_PR1("[VERBATIM]"); RETURN(ANS_VERBATIM); }
724: [Aa][Nn][Ss][Bb][Oo][Xx] { LLDBUG_PR1("[SHOW_ANS_BOX]"); RETURN(ANS_BOX_SHOW); }
725: [Hh][Ii][Nn][Tt] { LLDBUG_PR1("[HINT]"); RETURN(ANS_HINT); }
726: [Ee][Xx][Pp][Ll][Aa][Ii][Nn] { LLDBUG_PR1("[EXPLAIN]"); RETURN(ANS_EXPLAIN); }
727: [Ee][Xx][Tt][Ee][Rr][Nn][Aa][Ll] { LLDBUG_PR1("[EXTERNAL]"); RETURN(ANS_EXTERNAL); }
728: [Ee][Vv][Aa][Ll] |
729: [Ee][Vv][Aa][Ll][Uu][Aa][Tt][Ee] { LLDBUG_PR1("[EVAL]"); RETURN(ANS_EVAL); }
730: [\)] { LLDBUG_PR1("[)]"); Pcount--;
731: if(Pcount==0) {
732: BEGIN S_ANSCONTINUE;
733: }
734: return(yytext[0]);
735: }
736: }
737:
738: <S_VARIABLE,S_TRUE_FALSE_STMT,S_LET,S_ANSWER,S_MAP>{
739: {Alpha}{AlphaNum}* { LLDBUG_PR2("[ID<%s>]",yytext);LLDBUG_PR2("[SYMB CNT=<%d>]", Symb_count);
740: /*yylval = find_identifier(yytext);*/ RETURN(IDENTIFIER);
741: }
742:
743: {Alpha}{AlphaNum}*{Space}*[(] { char aline[MAX_FUNC_NAME];
744: int i;
745: for(i=0;i < (yyleng-1); i++) {
746: if( yytext[i] == ' ' || yytext[i] == '\t' ||
747: yytext[i] == 0 || yytext[i] == '(' ) break;
748: aline[i] = yytext[i];
749: }
750: aline[i] = 0;
751: LLDBUG_PR3("[FUNCT<%s:%d>]",aline,Func_idx);
752: (FuncStack[Func_idx]).s_type = FUNCTION_ID;
753: (FuncStack[Func_idx]).s_name = strsave(aline); /* free it in parser() */
754: Func_idx++;
755: yyless(yyleng-1); /* <-- push back '(' char */
756: RETURN(FUNCTION_ID);
757: }
758: {Alpha}{AlphaNum}*{Space}*[\[] { char aline[MAX_FUNC_NAME];
759: int i;
760: for(i=0;i < (yyleng-1); i++) {
761: if( yytext[i] == ' ' || yytext[i] == '\t' ||
762: yytext[i] == 0 || yytext[i] == '[' ) break;
763: aline[i] = yytext[i];
764: }
765: aline[i] = 0;
766: LLDBUG_PR2("[ARRAY<%s>]",aline);
767:
768: yylval = (Symbol *) capa_malloc(1, sizeof(Symbol)); /* *** */
769: yylval->s_name = strsave(aline); /* free it in parser() */
770: yylval->s_type = ARRAY_ID;
771:
772: yyless(yyleng-1); /* <-- push back char '[' */
773: RETURN(ARRAY_ID);
774: }
775: {Number}*"\."{Number}*[Ee]"+"{Number}+ |
776: {Number}*"\."{Number}*[Ee]{Number}+ |
777: {Number}*"\."{Number}*[Ee]"-"{Number}+ |
778: {Number}+[Ee]"+"{Number}+ |
779: {Number}+[Ee]{Number}+ |
780: {Number}+[Ee]"-"{Number}+ |
781: {Number}+"\."{Number}* |
782: "\."{Number}+ { yylval = (Symbol *) capa_malloc(1, sizeof(Symbol)); /* *** */
783: yylval->s_real = strtod(yytext, (char **) 0);
784: yylval->s_type = R_CONSTANT;
785: LLDBUG_PR2("[REAL<%s>]",yytext);
786: RETURN(R_CONSTANT);
787: }
788:
789: {Number}+ { yylval = (Symbol *) capa_malloc(1, sizeof(Symbol)); /* *** */
790: yylval->s_int = strtol(yytext, (char **) 0, 0);
791: yylval->s_type= I_CONSTANT;
792: LLDBUG_PR2("[INT<%s>]",yytext);
793: RETURN(I_CONSTANT);
794: }
795: [\(] { LLDBUG_PR1("[dis let ans map (]"); Pcount++; return(yytext[0]); }
796: [\[] { LLDBUG_PR1("[dis let ans map '[']"); return(yytext[0]); }
797: [\]] { LLDBUG_PR1("[dis let ans map ']']"); return(yytext[0]); }
798: {Space}+ { /* LLDBUG_PR1("[SP ignored]"); Ignore Spaces */ }
799: [\"] { LLDBUG_PR1("[TF,V,LET,ANS,MAP str\" ]");
800: Current_char_p = String_buf;
801: yy_push_state(S_STRING);
802: }
803: }
804:
805: <S_VARIABLE,S_ANSWER>[:]{Number}+[EeFf] { char num[ONE_TWO_EIGHT], fmt[SMALL_LINE_BUFFER];
806: int i;
807: LLDBUG_PR2("[FORMAT<%s>]",yytext);
808: for(i=0;i<yyleng-2;i++) {
809: num[i] = yytext[i+1];
810: }
811: num[yyleng-2] = 0; /* terminate the numerical string */
812: yylval = (Symbol *) capa_malloc(1, sizeof(Symbol));
813: i = strtol(num, (char **) 0, 0);
814: yylval->s_type=FORMAT;
815: switch( yytext[yyleng-1] ) {
816: case 'e': sprintf(fmt,"%%.%de", i);
817: yylval->s_distype = E_FORMAT; break;
818: case 'E': sprintf(fmt,"%%.%dE", i);
819: yylval->s_distype = E_FORMAT; break;
820: case 'f':
821: case 'F': sprintf(fmt,"%%.%df", i);
822: yylval->s_distype = F_FORMAT; break;
823: }
824: yylval->s_str = strsave(fmt);
825: RETURN(FORMAT);
826: }
827:
828: <S_VARIABLE,S_TRUE_FALSE_STMT,S_LET,S_MAP>{
829: "==" { LLDBUG_PR1("[==]"); RETURN(EQ_op); }
830: "!=" { LLDBUG_PR1("[!=]"); RETURN(NE_op); }
831: ">" { LLDBUG_PR1("[>]"); RETURN(GT_op); }
832: ">=" { LLDBUG_PR1("[>=]"); RETURN(GE_op); }
833: "<" { LLDBUG_PR1("[<]"); RETURN(LT_op); }
834: "<=" { LLDBUG_PR1("[<=]"); RETURN(LE_op); }
835: "&&" { LLDBUG_PR1("[&&]"); RETURN(AND_op); }
836: "||" { LLDBUG_PR1("[||]"); RETURN(OR_op); }
837: "//" { if(Pcount==0) BEGIN S_SKIP; }
838: {Operator} { LLDBUG_PR2("[Op(%c) in VAR,TF_STMT,LET]",yytext[0]); return(yytext[0]); }
839: }
840:
841:
842:
843: <S_VARIABLE>{
844: [\)] { LLDBUG_PR1("[)]"); Pcount--; if(Pcount == 0) BEGIN S_TEXT; return(yytext[0]); }
845: [\\]{Space}*{EndLine} { LLDBUG_PR2("[\\EoL continue in S_VARIABLE (DIS?)](%s)",yytext); /* continuation on next line */ }
846: {EndLine} { LLDBUG_PR1("[EoL within /dis()]\n"); RETURN(EoL); }
847: . { char warn_msg[WARN_MSG_LENGTH];
848: sprintf(warn_msg,"When use a VARIABLE, an unexpected char [%c] is encountered.\n",yytext[0]);
849: capa_msg(MESSAGE_ERROR,warn_msg);
850: }
851: }
852:
853: <S_TRUE_FALSE_STMT>{
854: [\)] { LLDBUG_PRL1("[) in TRUE_FALSE]"); Pcount--; if(Pcount == 0) BEGIN S_NEXT_LINE; return(yytext[0]); }
855: [\\]{Space}*{EndLine} { LLDBUG_PR2("[\\EoL continue in S_TRUE_FALSE_STMT](%s)",yytext); /* continuation on next line */ }
856: {EndLine} { LLDBUG_PR1("[EoL within /IF()]\n"); RETURN(EoL); }
857: . { char warn_msg[WARN_MSG_LENGTH];
858: sprintf(warn_msg,"In /IF(), an unexpected char [%c] is encountered.\n",yytext[0]);
859: capa_msg(MESSAGE_ERROR,warn_msg);
860: }
861: }
862:
863: <S_STRING>{
864: [\\][\\] { char *aptr = yytext;
865: while( *aptr ) *Current_char_p++ = *aptr++;
866: }
867: [\\][\"] { *Current_char_p++ = '"'; }
868: [\\]{Space}*[\n] { LLDBUG_PR2("[\\CR continue in S_STRING](%s)",yytext); /* continuation on next line */ }
869: [\"] { /* end of a string constant -- */
870: yylval = (Symbol *) capa_malloc(1, sizeof(Symbol));
871: *Current_char_p = '\0';
872: yylval->s_str = strsave(String_buf); /* **** */
873: yylval->s_type = S_CONSTANT;
874: /* printf("STRING:%s\n", String_buf); */
875: LLDBUG_PR2("[%s\"END str]",String_buf);
876: yy_pop_state();
877: RETURN(S_CONSTANT); }
878: {EndLine} { /* check for termination of string constant */
879: char warn_msg[WARN_MSG_LENGTH];
880:
881: *Current_char_p = '\0';
882: sprintf(warn_msg,"STRING not terminated properly, an EoL encountered in the middle.\n%s\n",String_buf);
883: capa_msg(MESSAGE_ERROR,warn_msg);
884: yy_pop_state();
885: }
886: . { char *aptr = yytext;
887: while( *aptr ) *Current_char_p++ = *aptr++;
888: }
889: }
890:
891: <S_LET>[\)] { LLDBUG_PR1("[) in LET]"); Pcount--; return(yytext[0]); }
892:
893: <S_SKIP>{
894: [^\n]+$ { }
895: {EndLine} { BEGIN S_TEXT; RETURN(EoL); }
896: }
897:
898: <S_LET,S_ANSWER,S_MAP>{
899: [\\]{Space}*{EndLine} { LLDBUG_PR1("[\\EoL let ans map]"); /* continuation */ }
900: {EndLine} { LLDBUG_PR1("[EoL END let ans map]\n"); if(Pcount == 0) BEGIN S_TEXT; RETURN(EoL); }
901: }
902:
903: <S_MAP>{
904: [;,] { LLDBUG_PR2("[%c]",yytext[0]); return(yytext[0]); }
905: [\)] { LLDBUG_PR1("[) in MAP]"); Pcount--;
906: if(Pcount==0) {
907: BEGIN S_SKIP;
908: }
909: return(yytext[0]);
910: }
911: }
912:
913: <S_ANSCONTINUE>{
914: {Space}+ { /* ignore white spaces */ }
915: [\\]{Space}*{EndLine} { /* continuation */ }
916: {EndLine} { /* end of answer and/or other answers */ LLDBUG_PR1("[complete an answer<EoL>]");
917: BEGIN S_TEXT; }
918: "/AND" { LLDBUG_PR1("[AND]"); RETURN(ANS_AND); }
919: "/OR" { LLDBUG_PR1("[OR]"); RETURN(ANS_OR); }
920: }
921:
922: <S_IF_SKIP>{
923: ^{Spaces}"/IF"[^\n]*{EndLine} { IFcount++; LLDBUG_PRL2("[Skip IF <IFcount=%d>]\n",IFcount);
924: IFstatus[IFcount] = IF_DONT_CARE;
925: }
926: ^{Spaces}"/ELSE"[^\n]*{EndLine} { LLDBUG_PRL2("[Skip ELSE <IFcount=%d>]",IFcount);
927: IFcurrent[IFcount]=RUN_ELSE_PORTION;
928: if( IFstatus[IFcount] == IF_FALSE ) {
929: LLDBUG_PRL1("[ELSE begin TEXT CR]\n");
930: BEGIN S_TEXT;
931: }
932: if( IFstatus[IFcount] == IF_TRUE ) {
933: LLDBUG_PRL1("[ELSE THIS SHOULD NEVER HAPPEN.]\n");
934: }
935: }
936: ^{Spaces}"/ENDIF"[^\n]*{EndLine} { IFcount--; LLDBUG_PRL2("[Skip ENDIF <IFcount=%d>]\n",IFcount);
937: if( IFcount == 0 ) {
938: LLDBUG_PRL1("[ENDIF begin TEXT CR]\n");
939: BEGIN S_TEXT;
940: }
941: if( (IFcurrent[IFcount] == RUN_IF_PORTION )&&(IFstatus[IFcount] == IF_TRUE)) {
942: LLDBUG_PRL1("[ENDIF begin TEXT CR]\n");
943: BEGIN S_TEXT;
944: }
945: if( (IFcurrent[IFcount] == RUN_ELSE_PORTION )&&(IFstatus[IFcount] == IF_FALSE)) {
946: LLDBUG_PRL1("[ENDIF begin TEXT CR]\n");
947: BEGIN S_TEXT;
948: }
949: }
950: {EndLine} { LLDBUG_PRL1("[SkipIF a CR]\n"); }
951: [^\n]*$ { LLDBUG_PRL2("[SkipIF anything <IFcount=%d>]",IFcount); }
952: }
953: <S_NEXT_LINE>{
954: ([.]*){EndLine} { /* this ignores everything until it hits an EoL */
955: LLDBUG_PRL2("[<S_NEXT_LINE> skip \'%s\' until EoL]\n",yytext);
956: BEGIN S_TEXT;
957: }
958: }
959:
960: <S_WHILE_SKIP>{
961: ^{Spaces}"/WHILE"[^\n]*{EndLine} { Wcount++;
962: LLDBUG_PRL2("[SkipWHILE /WHILE <Wcount=%d>]\n",Wcount);
963: }
964: ^{Spaces}"/ENDWHILE"[^\n]*{EndLine} {
965: if(Wcount==0) {
966: LLDBUG_PRL2("[SkipWHILE->/ENDWHILE <Wcount=%d>]\n",Wcount);
967: BEGIN S_TEXT;
968: } else {
969: Wcount--;
970: LLDBUG_PRL2("[SkipWHILE /ENDWHILE <Wcount=%d>]\n",Wcount);
971: }
972: }
973: {EndLine} { LLDBUG_PRL1("[SkipWHILE a CR]\n"); }
974: [^\n]*$ { LLDBUG_PRL2("[SkipWHILE anything <Wcount=%d>]",Wcount); }
975: }
976:
977: <S_VERB>{
978: ^{Spaces}"/ENDVERB" { LLDBUG_PRL1("[END VERB]\n");
979: yylval = (Symbol *) capa_malloc(1, sizeof(Symbol));
980: yylval->s_str = strsave(Dynamic_buf); /* **** */
981: yylval->s_type = S_CONSTANT;
982: capa_mfree(Dynamic_buf);
983: Dynamic_buf_cur=-1;
984: Dynamic_buf_max=0;
985: BEGIN S_TEXT; RETURN(VERBATIM);
986: }
987: .*|{EndLine} { append_dynamic_buf(yytext); }
988: }
989:
990: %%
991:
992: /* ========================================================================================== */
993: extern void
994: begin_if_skip() { BEGIN S_IF_SKIP; }
995:
996: extern void
997: begin_while_skip() { Wcount=0; While_idx--; /* while is FALSE, pop it out from stack */ BEGIN S_WHILE_SKIP; }
998:
999: extern void
1000: begin_next_line() { BEGIN S_NEXT_LINE; }
1001:
1002: extern void
1003: begin_var() { BEGIN S_VARIABLE; }
1004:
1005: extern void
1006: begin_let() { BEGIN S_LET; }
1007:
1008: extern void
1009: begin_def() { BEGIN S_DEFINE; }
1010:
1011: extern void
1012: begin_ans() { BEGIN S_ANSWER; }
1013:
1014: extern void
1015: begin_map() { BEGIN S_MAP; }
1016:
1017: extern void
1018: begin_ignore() { BEGIN S_IGNORE; }
1019:
1020: extern void
1021: begin_text() { BEGIN S_TEXT; }
1022:
1023: extern void
1024: begin_question() { LLDBUG_PR1("[<S_TEXT>]");
1025: IFcount = 0; While_idx=0; /* initialize some stacks */
1026: End_of_input = 0; YY_FLUSH_BUFFER; BEGIN S_TEXT; }
1027:
1028: extern void
1029: end_problemset() { End_of_input = 0; YY_FLUSH_BUFFER; BEGIN S_TEXT; }
1030:
1031:
1032: /* ========================================================================================== */
1033:
1034: #define NUM_KEY 2
1035: int
1036: match_keyword(key) char *key;
1037: {
1038: char *keyword[NUM_KEY] = {"/DIS", "/DIR" };
1039: int i;
1040:
1041: for(i=0;i < NUM_KEY; i++) {
1042: if( !strncmp(keyword[i], key, 4) ) {
1043: return (1);
1044: }
1045: }
1046: return (0);
1047: }
1048:
1049: int
1050: match_functionid(key) char *key;
1051: {
1052: char *keyword[NUM_KEY] = {"/DIS", "/DIR" };
1053: int i;
1054:
1055: for(i=0;i < NUM_KEY; i++) {
1056: if( !strncmp(keyword[i], key, 4) ) {
1057: return (1);
1058: }
1059: }
1060: return (0);
1061: }
1062: /* -------------------------------------------------------------------------- */
1063: /* -------------------------------------------------------------------------- */
1064:
1065: void init_funcstack()
1066: {
1067: int ii;
1068: for(ii=0;ii<Func_idx;ii++) {
1069: capa_mfree(FuncStack[ii].s_name);
1070: }
1071: Func_idx = 0;
1072: }
1073:
1074:
1075: /* -------------------------------------------------------------------------- */
1076: /* GET THE NEXT CHARACTER OF THE SOURCE FILE */
1077: /* -------------------------------------------------------------------------- */
1078:
1079: #ifdef FLEX
1080: int capaL_input()
1081: #else
1082: int /* RETURNS: next character */
1083: input() /* ARGUMENTS: (none) */
1084: #endif
1085:
1086: { /* LOCAL VARIABLES: */
1087: static int startup=1; /* First call flag */
1088:
1089: LLDBUG_PRL1("<<capaL_input() is called>>\n");
1090: if (!Lexi_line) { /* was startup */
1091: for(Input_idx=0;Input_idx < MAX_OPENED_FILE;Input_idx++) {
1092: /* for(ii=0;ii<LEX_BUFLEN;ii++) {
1093: Lexi_buf[Input_idx][ii]=0;
1094: }
1095: */
1096: Lexi_buf[Input_idx][0]=0;
1097: Lexi_pos[Input_idx] = 0;
1098: }
1099: Input_idx = 0;
1100: startup=0;
1101: yyin = Input_stream[Input_idx];
1102: }
1103: if (!Lexi_buf[Input_idx][Lexi_pos[Input_idx]]) {
1104: if (fgets(Lexi_buf[Input_idx],LEX_BUFLEN-1,Input_stream[Input_idx])==NULL) {
1105: /* EOF? */
1106: /* no use in flex
1107: printf("capaL_input()EOF %s\n",Opened_filename[Input_idx+1]); fflush(stdout); */
1108: return (0);
1109: }
1110: Lexi_pos[Input_idx] = 0;
1111: Lexi_line++;
1112: printf("input()(%d)\n",Lexi_line);
1113: }
1114: (Lexi_pos[Input_idx])++;
1115: return ( Lexi_buf[Input_idx][Lexi_pos[Input_idx]-1] );
1116: }
1117:
1118: /******************************************************************************/
1119: /* PUSH BACK ONE CHARACTER OF THE INPUT */
1120: /******************************************************************************/
1121:
1122: int /* RETURNS: nothing */
1123: capaL_unput(ch) /* ARGUMENTS: */
1124: register int ch; /* Character to push */
1125: {
1126: if (ch) (Lexi_pos[Input_idx])--;
1127:
1128: /* unput() stream cannot be re-defined */
1129: /* unput(ch); inconsistency between YY_INPUT() and internal matched yytext */
1130: return (0);
1131:
1132: }
1133:
1134:
1135: /******************************************************/
1136:
1137: #ifndef DMALLOC
1138:
1139: char *
1140: strsave(char *s)
1141: {
1142: char *p;
1143: if (s==NULL) {return s;}
1144: p=capa_malloc(strlen(s)+1,1);
1145: strcpy(p,s);
1146: return (p);
1147: }
1148:
1149: #endif
1150:
1151: /* =========================================================================== */
1152:
1153: #ifndef DMALLOC
1154: char *
1155: capa_malloc(unsigned num,unsigned sz)
1156: {
1157: char *p;
1158: p = calloc(num, sz);
1159: bzero(p, num*sz); /* added Jan 21 1998 */
1160: return (p);
1161: }
1162:
1163: #endif
1164:
1165: #ifndef DMALLOC
1166: void
1167: capa_mfree(p) char *p;
1168: {
1169: free(p);
1170: }
1171: #endif
1172:
1173: void
1174: capa_msg(int type, char *p)
1175: { int idx, i, j;
1176: int len;
1177: char warn_msg[WARN_MSG_LENGTH];
1178: char tmp_line[ONE_TWO_EIGHT];
1179: char *tmp_str;
1180:
1181: strcpy(warn_msg,"File: ");
1182: idx=6;
1183: for(i=0;i<=Input_idx;i++) {
1184: len=strlen(Opened_filename[i]);
1185: for(j=0;j<len;j++) {
1186: warn_msg[idx++] = Opened_filename[i][j];
1187: }
1188: if(i < Input_idx) {
1189: warn_msg[idx++]='-';
1190: warn_msg[idx++]='>';
1191: }
1192: warn_msg[idx]=0;
1193: }
1194: switch (type) {
1195: case MESSAGE_ERROR:
1196: sprintf(tmp_line,", Line %d: ERROR:", Current_line[Input_idx]);
1197: len=strlen(tmp_line);
1198: for(j=0;j<len;j++) {
1199: warn_msg[idx++] = tmp_line[j];
1200: }
1201: warn_msg[idx]=0;
1202: append_error(warn_msg); append_error(p);
1203: break;
1204: case MESSAGE_WARN:
1205: default:
1206: sprintf(tmp_line,", Line %d: WARNING:", Current_line[Input_idx]);
1207: len=strlen(tmp_line);
1208: for(j=0;j<len;j++) {
1209: warn_msg[idx++] = tmp_line[j];
1210: }
1211: warn_msg[idx]=0;
1212: j = strlen(warn_msg);
1213: len = strlen(p);
1214: tmp_str = (char *)capa_malloc(len+j+1,1);
1215: for(i=0;i<j;i++) {
1216: tmp_str[i]=warn_msg[i];
1217: }
1218: for(i=j;i<j+len;i++) {
1219: tmp_str[i] = p[i-j];
1220: }
1221: append_warn(type,tmp_str);
1222: capa_mfree(tmp_str);
1223: break;
1224: }
1225: }
1226:
1227: /* ======================================================================== */
1228: void
1229: capa_warn_header(int type)
1230: {
1231: int idx, i, j;
1232: int len;
1233: char warn_msg[WARN_MSG_LENGTH];
1234: char tmp_line[ONE_TWO_EIGHT];
1235:
1236: strcpy(warn_msg,"File: ");
1237: idx=6;
1238: for(i=0;i<=Input_idx;i++) {
1239: len=strlen(Opened_filename[i]);
1240: for(j=0;j<len;j++) {
1241: warn_msg[idx++] = Opened_filename[i][j];
1242: }
1243: if(i < Input_idx) {
1244: warn_msg[idx++]='-';
1245: warn_msg[idx++]='>';
1246: }
1247: warn_msg[idx]=0;
1248: }
1249: switch (type) {
1250: case MESSAGE_ERROR:
1251: sprintf(tmp_line,", Line %d: ERROR:", Current_line[Input_idx]);
1252:
1253: break;
1254: case MESSAGE_WARN:
1255: sprintf(tmp_line,", Line %d: WARNING:", Current_line[Input_idx]);break;
1256: default:
1257: sprintf(tmp_line,", Line %d: ERROR:", Current_line[Input_idx]);break;
1258: }
1259: len=strlen(tmp_line);
1260: for(j=0;j<len;j++) {
1261: warn_msg[idx++] = tmp_line[j];
1262: }
1263: warn_msg[idx]=0;
1264: append_error(warn_msg);
1265: }
1266:
1267: /* --------------------------------------------------------------------------- */
1268: #ifdef AVOIDYYINPUT
1269:
1270: void change_file(char *fname)
1271: {
1272: char warn_msg[WARN_MSG_LENGTH];
1273:
1274: if ( include_stack_ptr >= MAX_INCLUDE_DEPTH ) {
1275: sprintf(warn_msg,"Includes nested too deeply" );
1276: capa_msg(MESSAGE_ERROR,warn_msg);
1277: return;
1278: }
1279:
1280: include_stack[include_stack_ptr++] = YY_CURRENT_BUFFER;
1281: yyin = fopen( fname, "r" );
1282: yy_switch_to_buffer( yy_create_buffer( yyin, YY_BUF_SIZE ) );
1283: }
1284:
1285: void
1286: parse_filename(char *line)
1287: {
1288: char *start, fname[MAX_BUFFER_SIZE], warn_msg[WARN_MSG_LENGTH];
1289: int ii,len;
1290:
1291: start = index(line, '\"'); /*** hpux complained */
1292: if( start == NULL ) {
1293: sprintf(warn_msg,"/IMP was not given a filename.\n");
1294: capa_msg(MESSAGE_ERROR,warn_msg);
1295: return;
1296: }
1297: start++; len = strlen(start) - 1;
1298: ii = 0;
1299: while( start[ii] != '\"' ) fname[ii++] = start[ii];
1300: fname[ii] = 0;
1301: LLDBUG_PR2("[parse_filename<%s>]\n",fname);
1302:
1303: change_file(fname);
1304: }
1305:
1306: void
1307: parse_import_id(char *line)
1308: {
1309: char fname[QUARTER_K], warn_msg[WARN_MSG_LENGTH];
1310: int ii, dup_open;
1311: Symbol *symb_p;
1312: int no_error = 0;
1313:
1314: ii = 0;
1315: while( line[ii] != '\0' && line[ii] != ' ' && line[ii] != '\n' && line[ii] != '\t' )
1316: fname[ii++] = line[ii];
1317: fname[ii] = 0;
1318:
1319: LLDBUG_PR2("[parse_import_id<%s>]\n",fname);
1320: /*symb_p = find_identifier(fname);*/
1321:
1322: switch (symb_p->s_type) {
1323: case IDENTIFIER:
1324: sprintf(warn_msg,"/IMP %s, var is not defined.\n", fname);
1325: capa_msg(MESSAGE_ERROR,warn_msg);
1326: break;
1327: case I_VAR: case I_CONSTANT: case R_VAR: case R_CONSTANT:
1328: sprintf(warn_msg,"var cannot be a number.\n");
1329: capa_msg(MESSAGE_ERROR,warn_msg);
1330: break;
1331: case S_VAR: case S_CONSTANT: sprintf(fname,"%s",symb_p->s_str);
1332: no_error = 1;
1333: break;
1334: }
1335: if( no_error ) change_file(fname);
1336: }
1337:
1338: #else
1339: void
1340: parse_filename(char *line)
1341: {
1342: char *start, fname[QUARTER_K], warn_msg[WARN_MSG_LENGTH];
1343: int ii, len, dup_open;
1344:
1345: /* printf("IMPORT %s\n", line); */
1346:
1347: start = index(line, '\"'); /*** hpux complained */
1348: if( start != NULL ) {
1349: start++; len = strlen(start) - 1;
1350: ii = 0;
1351: while( start[ii] != '\"' ) {
1352: fname[ii] = start[ii]; ii++;
1353: }
1354: fname[ii] = 0;
1355: LLDBUG_PR2("[parse_filename<%s>]\n",fname);
1356: if(Input_idx < (MAX_OPENED_FILE -1)) {
1357: dup_open = 0;
1358: /* -- no need to check duplicated opening a file
1359: for(ii=0;ii<Input_idx;ii++) {
1360: if(strcmp(Opened_filename[ii],fname)==0) {
1361: dup_open =1;
1362: }
1363: }
1364: */
1365: if( !dup_open ) {
1366: Input_idx++;
1367: Input_stream[Input_idx]=fopen(fname,"r");
1368: sprintf(Opened_filename[Input_idx], "%s",fname);
1369: Current_line[Input_idx] = 0;
1370: } else {
1371: /*
1372: sprintf(warn_msg,"/IMP \"%s\", import file has already been imported.\n",fname);
1373: capa_msg(MESSAGE_WARN,warn_msg);
1374: */
1375: Input_idx++;
1376: Input_stream[Input_idx]=fopen(fname,"r");
1377: sprintf(Opened_filename[Input_idx], "%s",fname);
1378: Current_line[Input_idx] = 0;
1379: }
1380: } else {
1381: sprintf(warn_msg,"/IMP more the %d levels deep ignoring further imports.\n",MAX_OPENED_FILE-1);
1382: capa_msg(MESSAGE_WARN,warn_msg);
1383: }
1384: } else {
1385: sprintf(warn_msg,"%s, is not a valid file name.\n",line);
1386: capa_msg(MESSAGE_ERROR,warn_msg);
1387: }
1388:
1389: }
1390:
1391: void
1392: parse_import_id(char *line)
1393: {
1394: char fname[QUARTER_K], warn_msg[WARN_MSG_LENGTH];
1395: int ii, dup_open;
1396: Symbol *symb_p;
1397: int no_error = 0;
1398:
1399: ii = 0;
1400: while (line[ii] != '\0' && line[ii] != ' ' && line[ii] != '\n' && line[ii] != '\t') {
1401: fname[ii] = line[ii]; ii++;
1402: }
1403: fname[ii] = 0;
1404: LLDBUG_PR2("[parse_import_id<%s>]\n",fname);
1405: /*symb_p = find_identifier(fname);*/
1406:
1407: switch (symb_p->s_type) {
1408: case IDENTIFIER:
1409: sprintf(warn_msg,"/IMP %s, var is not defined.\n", fname);
1410: capa_msg(MESSAGE_ERROR,warn_msg);
1411: break;
1412: case I_VAR: case I_CONSTANT: case R_VAR: case R_CONSTANT:
1413: sprintf(warn_msg,"var cannot be a number.\n");
1414: capa_msg(MESSAGE_ERROR,warn_msg);
1415: break;
1416: case S_VAR:
1417: case S_CONSTANT:
1418: sprintf(fname,"%s",symb_p->s_str);
1419: no_error = 1;
1420: break;
1421: }
1422: if( no_error ) {
1423: if(Input_idx < (MAX_OPENED_FILE -1) ) {
1424: dup_open = 0;
1425: /* no need to check duplicated opening a file
1426: for(ii=0;ii<Input_idx;ii++) {
1427: if(strcmp(Opened_filename[ii],fname)==0) dup_open =1;
1428: }
1429: */
1430: if( !dup_open ) {
1431: Input_idx++;
1432: Input_stream[Input_idx]=fopen(fname,"r");
1433: sprintf(Opened_filename[Input_idx], "%s",fname);
1434: Current_line[Input_idx] = 0;
1435: } else {
1436: /* NO warning on duplicated open a file
1437: sprintf(warn_msg,"/IMP \"%s\", file has already been imported.\n", fname);
1438: capa_msg(MESSAGE_WARN,warn_msg);
1439: */
1440: Input_idx++;
1441: Input_stream[Input_idx]=fopen(fname,"r");
1442: sprintf(Opened_filename[Input_idx], "%s",fname);
1443: Current_line[Input_idx] = 0;
1444: }
1445: } else {
1446: sprintf(warn_msg,"/IMP , too many files has been imported. The maximum is %d files.\n",
1447: MAX_OPENED_FILE-1);
1448: capa_msg(MESSAGE_WARN,warn_msg);
1449: }
1450: }
1451: }
1452: #endif /*AVOIDYYINPUT*/
1453:
1454: void append_dynamic_buf(new_str) char *new_str;
1455: {
1456: int ii,len;
1457:
1458: if(new_str==NULL) return;
1459: len=strlen(new_str);
1460: #ifdef LEX_DBUG
1461: printf("before: len %d; Dynamic_buf_cur %d; Dynamic_buf_max %d\n",
1462: len,Dynamic_buf_cur,Dynamic_buf_max);
1463: #endif /* LEX_DBUG */
1464: if (Dynamic_buf_cur+len+1>Dynamic_buf_max) {
1465: char *temp_text;
1466: Dynamic_buf_max=(Dynamic_buf_cur+len)*2;
1467: temp_text=(char*)capa_malloc(sizeof(char),Dynamic_buf_max);
1468: strncpy(temp_text,Dynamic_buf,Dynamic_buf_max);
1469: free(Dynamic_buf);
1470: Dynamic_buf=temp_text;
1471: }
1472: for(ii=0;ii<len;ii++) {
1473: Dynamic_buf[Dynamic_buf_cur+ii]=new_str[ii];
1474: }
1475: Dynamic_buf_cur += len;
1476: Dynamic_buf[Dynamic_buf_cur+1]='\0';
1477: #ifdef LEX_DBUG
1478: printf("after: len %d; Dynamic_buf_cur %d; Dynamic_buf_max %d\n",
1479: len,Dynamic_buf_cur,Dynamic_buf_max);
1480: printf("Dyn_buf %s; added %s\n",Dynamic_buf,new_str);
1481: #endif /* LEX_DBUG */
1482: }
1483:
1484: char* parser_status()
1485: {
1486: char *buf,small[SMALL_LINE_BUFFER];
1487: int i,j,totlen=0,len,idx=0;
1488:
1489: for(i=0;i<=Input_idx;i++) totlen+=strlen(Opened_filename[i])+6;
1490: buf=capa_malloc(sizeof(char),totlen);
1491: for(i=0;i<=Input_idx;i++) {
1492: len=strlen(Opened_filename[i]);
1493: for(j=0;j<len;j++) buf[idx++] = Opened_filename[i][j];
1494: buf[idx++] = ':';
1495: sprintf(small,"%d",Current_line[i]);
1496: len=strlen(small);
1497: for(j=0;j<len;j++) buf[idx++] = small[j];
1498: buf[idx++]=' ';
1499: buf[idx]='\0';
1500: }
1501: return buf;
1502: }
1503:
1504: void yyfatalerror(char*msg)
1505: {
1506: char warn_msg[WARN_MSG_LENGTH];
1507: sprintf(warn_msg,"Invalid character[\'%s\']\n",yytext);
1508: capa_msg(MESSAGE_ERROR,warn_msg);
1509: capa_msg(MESSAGE_ERROR,msg);
1510: }
1511: void yyerror(char* msg)
1512: {
1513: char warn_msg[WARN_MSG_LENGTH];
1514: sprintf(warn_msg,"%s\n",msg);
1515: capa_msg(MESSAGE_ERROR,warn_msg);
1516: }
1517:
1518: void newyy_input (char *buf,int *result,int max_size)
1519: { int ii, leng, out_of_char;
1520: if (!Lexi_line) { /* was startup */
1521: for(ii=0;ii < MAX_OPENED_FILE;ii++) {
1522: Lexi_buf[ii] = NULL;
1523: Lexi_pos[ii] = 0;
1524: Current_line[ii] = 0;
1525: }
1526: Input_idx = 0;
1527: first_run=0;
1528: yyin = Input_stream[Input_idx]; LIDBUG_PR1("<<yy_input() startup>>\n");
1529: }
1530: out_of_char = 0;
1531: if ( Lexi_buf[Input_idx] == NULL ) {
1532: Lexi_buf[Input_idx] = (char *)capa_malloc(sizeof(char)*LEX_BUFLEN+1,1); out_of_char=1;
1533: } else {
1534: if (!Lexi_buf[Input_idx][Lexi_pos[Input_idx]]) {
1535: /* test if the line buffer is empty or at the end */
1536: out_of_char=1;
1537: }
1538: }
1539: if( out_of_char ) {
1540: if (fgets(Lexi_buf[Input_idx],LEX_BUFLEN-1,Input_stream[Input_idx])==NULL) {
1541: /* read in one line */
1542: LIDBUG_PR2("<<yy_input() fgets() returns NULL, input index=%d>>\n",Input_idx);
1543: if( (Input_idx > 0) && ( Lexi_buf[Input_idx][Lexi_pos[Input_idx]] == '\0') ) {
1544: LIDBUG_PR2("<<yy_input() close an input stream, input index=%d>>\n",Input_idx);
1545: fclose(Input_stream[Input_idx]);
1546: capa_mfree((char *)Lexi_buf[Input_idx]);
1547: Lexi_buf[Input_idx] = NULL;
1548: Input_idx--;
1549: yyin = Input_stream[Input_idx];
1550: /* (Lexi_pos[Input_idx])++; */
1551: buf[0] = Lexi_buf[Input_idx][Lexi_pos[Input_idx]-1];
1552: *result = 1;
1553: } else {
1554: *result = YY_NULL; /* End of File */
1555: }
1556: } else { /* successfully read in one line */
1557: leng = strlen(Lexi_buf[Input_idx]);
1558: LIDBUG_PR3("<<yy_input() read into buffer a line(leng=%d), input index=%d>>\n",
1559: leng,Input_idx);
1560: Lexi_pos[Input_idx] = 0;
1561: Lexi_line++;
1562: Current_line[Input_idx]++;
1563: (Lexi_pos[Input_idx])++;
1564: buf[0] = Lexi_buf[Input_idx][Lexi_pos[Input_idx]-1];
1565: /* need to take care of return continuation conditions */
1566: /* so, we return to one-char-at-a-time approach */
1567: /* for(ii=0;ii<leng;ii++) { */
1568: /* buf[ii] = Lexi_buf[Input_idx][ii]; */
1569: /* } */
1570: /* buf[ii] = '\0'; */
1571: /* printf("YY_INPUT()(Lexi_line=%d,max size=%d)(%c)",Lexi_line,max_size,buf[0]); */
1572: *result = 1;
1573: }
1574: } else {
1575: /* LIDBUG_PR2("<<yy_input() increase Lexi_pos, input index=%d>>\n",Input_idx); */
1576: (Lexi_pos[Input_idx])++;
1577: buf[0] = Lexi_buf[Input_idx][Lexi_pos[Input_idx]-1];
1578: *result = 1;
1579: }
1580: if (Stop_Parser==1) *result = YY_NULL;
1581: }
1582:
1583: int capa_eof()
1584: {
1585: #ifdef AVOIDYYINPUT
1586: if ( --include_stack_ptr < 0 ) yyterminate();
1587: else {
1588: yy_delete_buffer( YY_CURRENT_BUFFER );
1589: yy_switch_to_buffer(include_stack[include_stack_ptr]);
1590: }
1591: #else
1592: if(Input_idx == 0) {
1593: fclose(Input_stream[Input_idx]);
1594: capa_mfree((char *)Lexi_buf[Input_idx]);
1595: /*free_problems(LexiProblem_p);*/
1596: LexiProblem_p=NULL;
1597: /* printf("\nCAPA EOF\n"); fflush(stdout); */
1598: }
1599: return (0);
1600: #endif /*AVOIDYYINPUT*/
1601: }
1602: /* ------------ */
1603:
1604:
1605: /* =========================================================== */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>