File:  [LON-CAPA] / loncom / homework / CAPA-converter / capaLexerDef.flex
Revision 1.3: download - view: text, annotated - select for diffs
Mon May 15 20:33:33 2000 UTC (24 years, 2 months ago) by albertel
Branches: MAIN
CVS tags: HEAD
- supports text lines and formatted emebbed /DIS
- combines sections of <block> and <script>
- properly parenthesises objects
- <import>

    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: 
  342: Alpha      [a-zA-Z_]
  343: KeyChar    [A-Z]
  344: AlphaNum   [a-zA-Z_0-9]
  345: Number     [0-9]
  346: HexNumber  [0-9a-fA-F]
  347: Space      [ \t]
  348: Spaces     ({Space}*)
  349: FileName   (\"[^"\n]*\")
  350: Qchar      ([0-9a-zA-Z \t!?\._,:;'"`~@#$%\^&\+\-\*=|\[\]{}()])
  351: Operator   ([=\+\-\*/%<>!&|,])
  352: Identifier ([a-zA-Z_][a-zA-Z_0-9]*)
  353: EndLine    ([\r][\n]|[\n])
  354: 
  355: %a 10500
  356: %o 15000
  357: %k 10000
  358: %p 10000
  359: %n 1000
  360: %x  S_COMMENT   S_HINT S_HINTEXLAINX  S_IMPORT S_EXPLAIN S_ENDX    S_UNIT   S_IGNORE  
  361: %x  S_SKIP      S_VARIABLE S_LET  S_DEFINE     S_TEXT    S_MAP     S_FIGURE S_ANSWER 
  362: %x  S_STRING    S_ANSCONTINUE     S_TRUE_FALSE_STMT      S_IF_SKIP S_WHILE_SKIP
  363: %x  S_NEXT_LINE S_VERB
  364: %array
  365: 
  366: 
  367: 
  368: %%
  369: 
  370: <S_IGNORE>{
  371: {EndLine}                       BEGIN S_IGNORE;
  372: [^\n]*$                         BEGIN S_IGNORE;
  373: <<EOF>>                        {
  374:                                   capa_eof();
  375: #ifndef AVOIDYYINPUT
  376: 				  yyterminate();
  377: #endif
  378:                                }
  379: }
  380: 
  381: <S_COMMENT>{
  382: {EndLine}{Spaces}"//"[^\n]*$ {LLDBUG_PRL2("[COMMENT<%s>]\n",yytext); 
  383: 			      send("%s",yytext);
  384:                              }
  385: [^\n]*{EndLine}      {
  386:                        send("\n"); BEGIN S_TEXT;
  387:                      }
  388: }
  389: 
  390: 
  391: <S_TEXT>{
  392: ^{Spaces}"/LET" |
  393: 	   ^{Spaces}"/BEG"                  { LLDBUG_PRL1("[LET]"); Pcount = 0; BEGIN S_LET; start_mode(MODE_SCRIPT,NULL);
  394: }
  395: ^{Spaces}"/VERB"                 { 
  396:                                    LLDBUG_PRL1("[VERBATIM]");
  397: 				   Dynamic_buf = (char *)capa_malloc(sizeof(char),10);
  398: 				   Dynamic_buf_max = 10;
  399: 				   Dynamic_buf_cur = 0;
  400: 				   Dynamic_buf[0] = '\0';
  401:                                    BEGIN S_VERB; 
  402:                                  }
  403: ^{Spaces}"/HIN"{Alpha}*{Spaces}  { LLDBUG_PRL1("[HIN]"); 
  404:                                    start_mode(MODE_BLOCK,
  405: 					      "condition=\"&hinton\"");
  406: 				   BEGIN S_HINT; 
  407:                                  }
  408: ^{Spaces}"/EXP"{Alpha}*{Spaces}  { start_mode(MODE_BLOCK,"condition=&explanation");
  409:                                    LLDBUG_PRL1("[EXP]"); Current_char_p = String_buf;  BEGIN S_EXPLAIN; }
  410: ^{Spaces}"/IMP"{Alpha}*{Space}+  { LLDBUG_PRL1("[IMP]"); BEGIN S_IMPORT; }
  411: ^{Spaces}"/END"                  { LLDBUG_PRL1("[END]");  
  412:                                     if ( (LexiProblem_p !=NULL) && 
  413: 					 (LexiProblem_p->question != NULL) && 
  414: 					 (LexiProblem_p->ans_type == 0)) {
  415: 				      EndText_p=strsave(LexiProblem_p->question);
  416: 				      LexiProblem_p=NULL;
  417: 				    } else {
  418: 				      EndText_p=NULL;
  419: 				    }
  420: 				    End_of_input = 1; BEGIN S_IGNORE;RETURN(CAPA_END); 
  421:                                   }
  422: ^{Spaces}"/START"[^\n]*          { LLDBUG_PRL1("[START]");  
  423:                                     if (LexiProblem_p !=NULL && 
  424: 					LexiProblem_p->question != NULL) {
  425: 				      StartText_p=strsave(LexiProblem_p->question);
  426: 				    } else {
  427: 				      StartText_p=NULL;
  428: 				    }
  429: 				    BEGIN S_TEXT;
  430: 				    RETURN(CAPA_START); 
  431:                                   }
  432:                                   
  433: ^{Spaces}"/END"{Spaces}[\(]{Spaces}      { LLDBUG_PRL1("[END()]"); BEGIN S_ENDX; }
  434: ^"/DEF"                       { Bcount = 0; BEGIN S_DEFINE; RETURN(CAPA_DEF); }
  435: ^{Spaces}"/ANS"               { LLDBUG_PRL2("[ANS(%s)]",yytext); Pcount = 0; BEGIN S_ANSWER; RETURN(CAPA_ANS); }
  436: ^{Spaces}"/SUBJECTIVE"        { LLDBUG_PRL1("[SUBJECTIVE ANSWER]"); Pcount = 0; BEGIN S_ANSWER; RETURN(CAPA_SUBJ); }
  437: ^{Spaces}"/MAP"               { LLDBUG_PRL1("[MAP]");  Pcount = 0; BEGIN S_MAP;   RETURN(CAPA_MAP); }
  438: ^{Spaces}"/RMAP"              { LLDBUG_PRL1("[RMAP]"); Pcount = 0; BEGIN S_MAP;   RETURN(CAPA_RMAP); }
  439: ^{Spaces}"/ENDWHILE"([^\n])*          { long int  file_pos;       
  440:                                 int   top_item, input_idx;
  441:                                 LLDBUG_PRL2("[ENDWHILE While_idx=<%d>]\n",While_idx);
  442:                                 
  443:                                 top_item = While_idx - 1;
  444:                                 if( top_item < 0 ) { /* strange things must have happened here! */
  445:                                   
  446:                                 } else {
  447:                                   input_idx = WhileStack[top_item].input_idx;
  448:                                   file_pos = WhileStack[top_item].pos_idx;
  449:                                   Current_line[input_idx] = WhileStack[top_item].line_idx;
  450:                                   Lexi_pos[input_idx] = 0;
  451:                                   fseek(Input_stream[input_idx],file_pos,SEEK_SET);
  452:                                   fgets(Lexi_buf[input_idx],LEX_BUFLEN-1,Input_stream[input_idx]);
  453:                                   While_idx--;
  454:                                 }
  455:                                 BEGIN S_TEXT;
  456:                               }
  457: "/WHILE"                      |
  458: ^{Spaces}"/WHILE"             { long int file_pos;
  459:                                 int      leng;
  460:                                 LLDBUG_PRL2("[WHILE While_idx=<%d>]\n",While_idx);
  461:                                 leng = strlen(Lexi_buf[Input_idx]);  /* length of current line */
  462:                                 /* <-- because we use fgets() to read input, 
  463:                                        thus ftell() will give the starting position of next line */
  464:                                 WhileStack[While_idx].input_idx = Input_idx;
  465:                                 file_pos = ftell(Input_stream[Input_idx]);
  466:                                 file_pos -= leng;  /* calibrate the current line length */
  467:                                 WhileStack[While_idx].pos_idx = file_pos;  /* begin of current line */
  468:                                 WhileStack[While_idx].line_idx = Current_line[Input_idx];
  469:                                 While_idx++;  /* advance the stack pointer */
  470:                                 
  471:                                 BEGIN S_TRUE_FALSE_STMT; RETURN(CAPA_WHILE); 
  472:                                 
  473:                               }
  474: ^{Spaces}"/IF"                { IFcount++; IFcurrent[IFcount] = RUN_IF_PORTION;
  475:                                 LLDBUG_PRL2("[IF <IFcount=%d>]",IFcount);  BEGIN S_TRUE_FALSE_STMT; RETURN(CAPA_IF); }
  476: ^{Spaces}"/ELSE"([^\n])*        { LLDBUG_PRL2("[ELSE <IFcount=%d>]\n",IFcount); 
  477:                                 IFcurrent[IFcount] = RUN_ELSE_PORTION;
  478:                                 if( IFstatus[IFcount] == IF_TRUE ) {
  479:                                   LLDBUG_PRL1("[ELSE begin Skip]\n");
  480:                                   BEGIN S_IF_SKIP;
  481:                                 }
  482:                               }
  483: ^{Spaces}"/ENDIF"([^\n])*    { IFcount--; LLDBUG_PRL2("[ENDIF <IFcount=%d>]\n",IFcount); 
  484:                               }
  485: "/AND"                        { LLDBUG_PRL1("[AND]"); BEGIN S_ANSCONTINUE; RETURN(ANS_AND); }
  486: "/DIS"                        { /* since S_VARIABLE treat {Space} as null, so here we do not match ( */
  487:                                 /* so that between /DIS and ( can have as many {Space} as we want */
  488:                                 LLDBUG_PR1("[DIS<]");
  489:                                 init_funcstack();
  490:                                 Pcount = 0; BEGIN S_VARIABLE; 
  491: 				start_delayed();
  492:                               }
  493: "/OR"                         { LLDBUG_PRL1("[OR]"); BEGIN S_ANSCONTINUE;  RETURN(ANS_OR); }
  494: {EndLine}                     { LLDBUG_PR1("[EoL within S_TEXT]\n"); /* end of the whole text line */ 
  495:                                 send("\n"); }
  496: [\\]{Space}*{EndLine}         { LLDBUG_PR2("[\\EoL continue](%s)",yytext); /* continuation on next line */ }                       
  497: ^{Spaces}"//"[^\n]*$		      { LLDBUG_PRL2("[COMMENT<%s>]\n",yytext);
  498:                                         start_mode(MODE_COMMENT,NULL); 
  499:                                         send("%s\n",yytext);
  500: 					BEGIN S_COMMENT;
  501:                                       }
  502: 
  503: [^/\n\\]+$  |
  504: [/]         | 
  505: [\\]                          {  start_mode(MODE_OUTTEXT,NULL);
  506:                                  yylval = (Symbol *) capa_malloc(1, sizeof(Symbol));
  507:                                 yylval->s_str = strsave(yytext);
  508:                                 LLDBUG_PR2("[TEXT_LINE<%s>]",yytext);
  509: 			        //RETURN(TEXT_LINE); 
  510: 			      }
  511: ([^/\n])+[/] |
  512: ([^/\n])+[\\]                 { /* matches anything until a '/' or a '\' */
  513:                                 start_mode(MODE_OUTTEXT,NULL);
  514:                                 LLDBUG_PR2("[TEXT_LINE( )<%s>]",yytext);
  515:                                 
  516:                                 yyless(yyleng-1); /* push back the last char */
  517:                                 BEGIN S_TEXT;
  518: 				send(yytext);
  519:                               }
  520: <<EOF>>                       { 
  521: #ifdef AVOIDYYINPUT
  522:                                 char    warn_msg[ONE_K];
  523: 
  524:                                 if ( (--include_stack_ptr < 0) || Stop_Parser) {
  525: 				  if (Stop_Parser) {
  526:                                     if ( LexiProblem_p!=NULL &&
  527: 					 LexiProblem_p->question != NULL)
  528: 				      EndText_p=strsave(LexiProblem_p->question);
  529: 				    while (include_stack_ptr >= 0) {
  530: 				      yy_delete_buffer( YY_CURRENT_BUFFER );
  531: 				      yy_switch_to_buffer(
  532: 						 include_stack[include_stack_ptr]);
  533: 				      --include_stack_ptr;
  534: 				    }
  535: 				  } else {
  536: 				    sprintf(warn_msg,
  537: 					"at End-of-File, a /END is needed.\n");
  538: 				    capa_msg(MESSAGE_ERROR,warn_msg);
  539: 				  }
  540: 				  free_problems(LexiProblem_p);
  541: 				  LexiProblem_p=NULL;
  542: 				  yyterminate();
  543: 				} else {
  544: 				  yy_delete_buffer( YY_CURRENT_BUFFER );
  545: 				  yy_switch_to_buffer(include_stack[include_stack_ptr]);
  546: 				}
  547: #else                              
  548: 				char    warn_msg[ONE_K];
  549:                                 if (!Stop_Parser) { 
  550: 				 sprintf(warn_msg,"at End-of-File, a /END is needed.\n");
  551: 				 capa_msg(MESSAGE_ERROR,warn_msg);
  552: 				} else {
  553: 				  if (LexiProblem_p != NULL &&
  554: 				      LexiProblem_p->question != NULL)
  555: 				    EndText_p=strsave(LexiProblem_p->question);
  556: 				}
  557:                                 capa_eof(); 
  558: 				yyterminate();
  559: #endif
  560:                               }
  561: }
  562: 
  563: 
  564: <S_ENDX>{
  565: {Alpha}{AlphaNum}*    { /* DONE: add codes to handle /END() */
  566: 				char *question_end=NULL;
  567: 				End_of_input = 1;
  568: 				if (EndText_p!=NULL) capa_mfree((char*)EndText_p);
  569: 				if ((LexiProblem_p!=NULL) &&
  570: 				    (LexiProblem_p->question != NULL) &&
  571: 				    (LexiProblem_p->ans_type == 0)) {
  572: 				  question_end=strsave(LexiProblem_p->question);
  573: 				}
  574:                                 if( yyleng > 0 ) {
  575:                                   
  576:                                   LLDBUG_PRL2("[END()<%s>]\n",yytext);
  577:                                   /*yylval = find_identifier(yytext);*/
  578:                                 
  579:                                   switch(yylval->s_type) {
  580:                                     case IDENTIFIER:
  581:                                     case I_VAR: case I_CONSTANT:
  582:                                     case R_VAR: case R_CONSTANT:
  583:                                          break;
  584:                                     case S_VAR: case S_CONSTANT:
  585:                                          EndText_p = strsave(yylval->s_str);
  586: 					 if (question_end) {
  587: 					   int leng; char *new_end;
  588: 					   leng = strlen(EndText_p) + 
  589: 					     strlen(question_end) + 1;
  590: 					   new_end = capa_malloc(sizeof(char), leng);
  591: 					   strcat(new_end, question_end);
  592: 					   strcat(new_end, EndText_p);  
  593: 					   capa_mfree(EndText_p);  
  594: 					   capa_mfree(question_end);  
  595: 					   EndText_p=new_end;
  596: 					 }
  597:                                          break;
  598:                                     default: break;
  599:                                   }
  600:                                 }
  601:                                 BEGIN S_IGNORE;   RETURN(CAPA_END);
  602:                               }
  603: {Space}*                      { /* ignore spaces */ }
  604: [\)]                          { /* a right paren */ 
  605:                                 if ( (LexiProblem_p != NULL) &&
  606: 				     (LexiProblem_p->question != NULL) && 
  607: 				     (LexiProblem_p->ans_type == 0)) {
  608: 				  EndText_p=strsave(LexiProblem_p->question);
  609: 				} else {
  610: 				  EndText_p=NULL;
  611: 				}
  612:                                 BEGIN S_IGNORE;   
  613: 				RETURN(CAPA_END);  
  614:                               }
  615: }
  616: 
  617: <S_HINT,S_EXPLAIN>{
  618: [/][Dd][Ii][Ss]{Space}*[\(]{Space}*  {  yy_push_state(S_HINTEXLAINX); }
  619: [^/\n]+[/\\]                    { char  *aptr = yytext;
  620:                                   int    ii;
  621:                                 
  622:                                   yyless(yyleng-1);
  623: 				  send(aptr);
  624:                                 }
  625: [/]                            { send("/"); }
  626: [\\]                           { send("\\"); }
  627: [\\]{Space}*[\n]               { LLDBUG_PR1("[\\CR hint explain continue]"); /* Hint and explain continuation */ }
  628: [^/\n\\]+$                     {char  *aptr = yytext;
  629:                                 int    ii;
  630: 				send(aptr);
  631:                                }
  632: }
  633: <S_HINT>{
  634: {EndLine}                     {  LLDBUG_PR1("[CR hint]");
  635:                                  send("\n"); 
  636:                                  BEGIN S_TEXT;
  637:                               }
  638: }
  639: <S_EXPLAIN>{
  640: {EndLine}                     {  LLDBUG_PR1("[CR explain]");
  641:                                  yylval = (Symbol *) capa_malloc(1, sizeof(Symbol));
  642: 		                *Current_char_p++ = '\n'; *Current_char_p = '\0';
  643: 	                         yylval->s_str = strsave(String_buf);
  644:                                  BEGIN S_TEXT; RETURN(EXPLAIN_LINE); 
  645:                               }
  646: }
  647: 
  648: <S_HINTEXLAINX>{
  649: {Alpha}{AlphaNum}*            { char   *aptr;
  650:                                 char    tmp_str[QUARTER_K],warn_msg[ONE_K];
  651:                                 int     ii, len;
  652:                                 Symbol *tmp_p;
  653:                                 
  654:                                 /*tmp_p = find_identifier(yytext);*/
  655:                                 switch(tmp_p->s_type) {
  656:                                   case IDENTIFIER:
  657:                                         sprintf(warn_msg,"var %s not defined.\n", yytext);
  658:                                         capa_msg(MESSAGE_ERROR,warn_msg);
  659:                                        break;
  660:                                   case I_VAR:
  661:                                   case I_CONSTANT: 
  662:                                          sprintf(tmp_str,"%ld",tmp_p->s_int);
  663:                                          len = strlen(tmp_str);
  664:                                          for(ii=0;ii< len;ii++) {
  665:                                            *Current_char_p++ = tmp_str[ii];
  666:                                          }
  667:                                        break;
  668:                                   case R_VAR:
  669:                                   case R_CONSTANT: 
  670:                                          sprintf(tmp_str,"%g",tmp_p->s_real);
  671:                                          len = strlen(tmp_str);
  672:                                          for(ii=0;ii< len;ii++) {
  673:                                            *Current_char_p++ = tmp_str[ii];
  674:                                          }
  675:                                        break;
  676:                                   case S_VAR:
  677:                                   case S_CONSTANT: 
  678:                                          len = strlen(tmp_p->s_str);
  679:                                          aptr = tmp_p->s_str;
  680:                                          for(ii=0;ii< len;ii++) {
  681:                                            *Current_char_p++ = *aptr++;
  682:                                          }
  683:                                        break;
  684:                                 }
  685: 				printf("FIXME!Hint: %s\n",yytext);
  686:                               }
  687: {Space}+                      { }
  688: [)]                           {  yy_pop_state(); }
  689: }
  690: 
  691: <S_IMPORT>{
  692: {FileName}{Space}*             { end_mode();send("<import>%s</import>\n",yytext); BEGIN S_SKIP; }
  693: {Identifier}{Space}*           { end_mode();send("<import>$%s</import>\n",yytext);  BEGIN S_SKIP; }
  694: }
  695: 
  696: <S_ANSWER>{
  697: [Pp][Ll][Uu][Ss]             { LLDBUG_PR1("[PLUS]");  RETURN(ANS_PLUS); }
  698: [Mm][Ii][Nn][Uu][Ss]         { LLDBUG_PR1("[MINUS]"); RETURN(ANS_MINUS); }
  699: [Cc][Ss]                     { LLDBUG_PR1("[CS]");    RETURN(ANS_CS); }
  700: [Cc][Ii]                     { LLDBUG_PR1("[CI]");    RETURN(ANS_CI); }
  701: [Mm][Cc]                     { LLDBUG_PR1("[MC]");    RETURN(ANS_MC); }
  702: [Oo][Nn]                     |
  703: [Yy][Ee][Ss]                 { LLDBUG_PR1("[ON]");    RETURN(ANS_ON); }
  704: [Oo][Ff][Ff]                 |
  705: [Nn][Oo]                     { LLDBUG_PR1("[OFF]");   RETURN(ANS_OFF); }
  706: [Ff][Mm][Ll]                 { LLDBUG_PR1("[FORMULA]");   RETURN(ANS_FORMULA); }
  707: [Ff][Mm][Tt]                 { LLDBUG_PR1("[FMT]");   RETURN(ANS_FMT); }
  708: [Uu][Nn][Ff][Mm][Tt]         { LLDBUG_PR1("[UNFMT]"); RETURN(ANS_UNFMT); }
  709: [,:%=@#-]                  { LLDBUG_PR2("[symbol(%s)]",yytext); return(yytext[0]); }
  710: "<"                          { LLDBUG_PR2("[symbol(%s)]",yytext); return(yytext[0]); }
  711: ">"                          { LLDBUG_PR2("[symbol(%s)]",yytext); return(yytext[0]); }
  712: [Ss][Ii][Gg]                 { LLDBUG_PR2("[SIG(%s)]",yytext);  RETURN(ANS_SIG); }
  713: [Tt][Oo][Ll]                 { LLDBUG_PR2("[tol(%s)]",yytext);  RETURN(ANS_TOLERANCE); }
  714: [Ss][Tt][Rr]                 { LLDBUG_PR1("[STR]");   RETURN(ANS_COMPARE); }
  715: [Ww][Gg][Tt]                 { LLDBUG_PR1("[WGT]");   RETURN(ANS_WEIGHT); }
  716: [Pp][Cc][Rr]                 |
  717: [Hh][Gg][Rr]                 { RETURN(ANS_PCREDIT); }
  718: [Pp][Aa][Tt][Hh]             { RETURN(ANS_PATH); }
  719: [Cc][Aa][Ll][Cc]             { RETURN(ANS_CALC); }
  720: [Tt][Rr][Yy]                 |
  721: [Tt][Rr][Ii][Ee][Ss]         { LLDBUG_PR1("[TRY]");     RETURN(ANS_TRY); }
  722: [Uu][Nn][Ii][Tt]             |
  723: [Uu][Nn][Ii][Tt][Ss]         { LLDBUG_PR1("[UNIT]");    RETURN(ANS_UNIT); }
  724: [Bb][Rr]                     { LLDBUG_PR1("[SHOW_BR]"); RETURN(ANS_SHOW_BR);  }
  725: [Vv][Ee][Rr][Bb][Aa][Tt][Ii][Mm] { LLDBUG_PR1("[VERBATIM]"); RETURN(ANS_VERBATIM); }
  726: [Aa][Nn][Ss][Bb][Oo][Xx]     { LLDBUG_PR1("[SHOW_ANS_BOX]"); RETURN(ANS_BOX_SHOW);  }
  727: [Hh][Ii][Nn][Tt]             { LLDBUG_PR1("[HINT]");    RETURN(ANS_HINT); }
  728: [Ee][Xx][Pp][Ll][Aa][Ii][Nn] { LLDBUG_PR1("[EXPLAIN]"); RETURN(ANS_EXPLAIN); }
  729: [Ee][Xx][Tt][Ee][Rr][Nn][Aa][Ll]  { LLDBUG_PR1("[EXTERNAL]"); RETURN(ANS_EXTERNAL); }
  730: [Ee][Vv][Aa][Ll]             |
  731: [Ee][Vv][Aa][Ll][Uu][Aa][Tt][Ee]             { LLDBUG_PR1("[EVAL]"); RETURN(ANS_EVAL); }
  732: [\)]                         { LLDBUG_PR1("[)]"); Pcount--; 
  733:                                if(Pcount==0) {
  734:                                    BEGIN S_ANSCONTINUE; 
  735:                                }
  736:                                return(yytext[0]); 
  737:                              }
  738: }
  739: 
  740: <S_VARIABLE,S_TRUE_FALSE_STMT,S_LET,S_ANSWER,S_MAP>{
  741: {Alpha}{AlphaNum}*             { LLDBUG_PR2("[ID<%s>]",yytext);LLDBUG_PR2("[SYMB CNT=<%d>]", Symb_count); 
  742: send("$%s",yytext); 
  743:                                }
  744: 
  745: {Alpha}{AlphaNum}*{Space}*[(]  { char aline[MAX_FUNC_NAME];
  746:                                  int  i;          
  747: 				 send("&%s",yytext);
  748: 				 Pcount++;
  749:                                }
  750: {Alpha}{AlphaNum}*{Space}*[\[]  {  char aline[MAX_FUNC_NAME];
  751:                                    int  i;   
  752:                                    for(i=0;i < (yyleng-1); i++) {
  753:                                      if( yytext[i] == ' ' || yytext[i] == '\t' || 
  754:                                          yytext[i] == 0   || yytext[i] == '[' )    break;
  755:                                      aline[i] = yytext[i];
  756:                                    }
  757:                                    aline[i] = 0;
  758:                                    LLDBUG_PR2("[ARRAY<%s>]",aline);
  759:                                    
  760:                                    yylval = (Symbol *) capa_malloc(1, sizeof(Symbol)); /* *** */
  761:                                    yylval->s_name = strsave(aline); /* free it in parser() */
  762:                                    yylval->s_type = ARRAY_ID;
  763:                                    
  764:                                    yyless(yyleng-1); /* <-- push back char '[' */
  765:                                    RETURN(ARRAY_ID);
  766:                                }
  767: {Number}*"\."{Number}*[Ee]"+"{Number}+ |
  768: {Number}*"\."{Number}*[Ee]{Number}+    |
  769: {Number}*"\."{Number}*[Ee]"-"{Number}+ |
  770: {Number}+[Ee]"+"{Number}+ |
  771: {Number}+[Ee]{Number}+    |
  772: {Number}+[Ee]"-"{Number}+ |
  773: {Number}+"\."{Number}*    |
  774: "\."{Number}+             {  
  775:                              LLDBUG_PR2("[REAL<%s>]",yytext);
  776: 			     send(yytext);
  777: 			  }
  778: 
  779: {Number}+                 {  
  780:                              LLDBUG_PR2("[INT<%s>]",yytext);
  781:                              send(yytext);
  782: 			  }
  783: [\(]                      { LLDBUG_PR1("[dis let ans map (]"); Pcount++; if (Pcount > 1 ) {send(yytext);} }
  784: [\[]                      { LLDBUG_PR1("[dis let ans map '[']");         return(yytext[0]); }
  785: [\]]                      { LLDBUG_PR1("[dis let ans map ']']");         return(yytext[0]); }
  786: {Space}+                  { /* LLDBUG_PR1("[SP ignored]");  Ignore Spaces */ }
  787: [\"]                      { LLDBUG_PR1("[TF,V,LET,ANS,MAP str\" ]"); 
  788:                             Current_char_p = String_buf; 
  789: 			    send("\"");
  790:                             yy_push_state(S_STRING);
  791:                           }
  792: }
  793: 
  794: <S_VARIABLE,S_ANSWER>[:]{Number}+[EeFf]   { 
  795:                              end_delayed();
  796:                              send("&format(");
  797:                              flush_delayed();
  798:                              send(",\"%s\")",yytext+1);
  799:                            }
  800: 
  801: <S_VARIABLE,S_TRUE_FALSE_STMT,S_LET,S_MAP>{
  802: "=="                { LLDBUG_PR1("[==]"); RETURN(EQ_op);  }
  803: "!="                { LLDBUG_PR1("[!=]"); RETURN(NE_op);  }
  804: ">"                 { LLDBUG_PR1("[>]");  RETURN(GT_op);  }
  805: ">="                { LLDBUG_PR1("[>=]"); RETURN(GE_op);  }
  806: "<"                 { LLDBUG_PR1("[<]");  RETURN(LT_op);  }
  807: "<="                { LLDBUG_PR1("[<=]"); RETURN(LE_op);  }
  808: "&&"                { LLDBUG_PR1("[&&]"); RETURN(AND_op); }
  809: "||"                { LLDBUG_PR1("[||]"); RETURN(OR_op);  }
  810: "//"                { if(Pcount==0) BEGIN S_SKIP;         }
  811: {Operator}          { LLDBUG_PR2("[Op(%c) in VAR,TF_STMT,LET]",yytext[0]); send(yytext); }
  812: }
  813: 
  814: 
  815: 
  816: <S_VARIABLE>{
  817: [\)]                     { LLDBUG_PR1("[)]"); 
  818:                            Pcount--; 
  819:                            if(Pcount == 0) {
  820:                               BEGIN S_TEXT; 
  821:                               flush_delayed();
  822:                            } else {
  823:                               send(yytext); 
  824:                            }
  825:                          }
  826: [\\]{Space}*{EndLine}    { LLDBUG_PR2("[\\EoL continue in S_VARIABLE (DIS?)](%s)",yytext); /* continuation on next line */ }                       
  827: {EndLine}                { LLDBUG_PR1("[EoL within /dis()]\n"); }
  828: .                   { char warn_msg[WARN_MSG_LENGTH]; 
  829:                       sprintf(warn_msg,"When use a VARIABLE, an unexpected char [%c] is encountered.\n",yytext[0]);
  830:                       capa_msg(MESSAGE_ERROR,warn_msg);
  831:                     }
  832: }
  833: 
  834: <S_TRUE_FALSE_STMT>{
  835: [\)]                     { LLDBUG_PRL1("[) in TRUE_FALSE]"); Pcount--; if(Pcount == 0)  BEGIN S_NEXT_LINE; return(yytext[0]); }
  836: [\\]{Space}*{EndLine}    { LLDBUG_PR2("[\\EoL continue in S_TRUE_FALSE_STMT](%s)",yytext); /* continuation on next line */ }                       
  837: {EndLine}                { LLDBUG_PR1("[EoL within /IF()]\n"); RETURN(EoL); }
  838: .                   { char warn_msg[WARN_MSG_LENGTH]; 
  839:                       sprintf(warn_msg,"In /IF(), an unexpected char [%c] is encountered.\n",yytext[0]);
  840:                       capa_msg(MESSAGE_ERROR,warn_msg);
  841:                     }
  842: }
  843: 
  844: <S_STRING>{
  845: [\\][\\]            { /*char  *aptr = yytext;
  846: 			while( *aptr )   *Current_char_p++ = *aptr++;*/
  847:                       send(yytext);
  848:                     }
  849: [\\][\"]            { /**Current_char_p++ = '"';*/ send("\\\"");  }
  850: [\\]{Space}*[\n]    { LLDBUG_PR2("[\\CR continue in S_STRING](%s)",yytext); /* continuation on next line */ }                       
  851: [\"]                { /* end of a string constant --   */
  852:                       send("\"");
  853: 		      yy_pop_state();
  854: 		    }
  855: {EndLine}           { /* check for termination of string constant */
  856:                       char warn_msg[WARN_MSG_LENGTH];
  857:                       
  858:                       sprintf(warn_msg,"STRING not terminated properly, an EoL encountered in the middle.\n%s\n",String_buf);
  859:                       capa_msg(MESSAGE_ERROR,warn_msg);
  860:                       yy_pop_state();
  861:                     }
  862: .                   { /*char  *aptr = yytext;
  863: 			while( *aptr )   *Current_char_p++ = *aptr++;*/
  864:                       send(yytext);
  865:                     }
  866: }
  867: 
  868: <S_LET>[\)]                  { LLDBUG_PR1("[) in LET]"); Pcount--;send(yytext); }
  869: 
  870: <S_SKIP>{
  871: [^\n]+$                      {       }
  872: {EndLine}                    { BEGIN S_TEXT; }
  873: }
  874: 
  875: <S_LET,S_ANSWER,S_MAP>{
  876: [\\]{Space}*{EndLine}        { LLDBUG_PR1("[\\EoL let ans map]"); /* continuation */ }
  877: {EndLine}                    { LLDBUG_PR1("[EoL END let ans map]\n"); if(Pcount == 0) BEGIN S_TEXT; send(yytext); }
  878: }
  879: 
  880: <S_MAP>{
  881: [;,]                         { LLDBUG_PR2("[%c]",yytext[0]); return(yytext[0]);  }
  882: [\)]                         { LLDBUG_PR1("[) in MAP]"); Pcount--; 
  883:                                if(Pcount==0) {
  884:                                    BEGIN S_SKIP; 
  885:                                }
  886:                                return(yytext[0]); 
  887:                              }
  888: }
  889: 
  890: <S_ANSCONTINUE>{
  891: {Space}+                 { /* ignore white spaces */ }
  892: [\\]{Space}*{EndLine}    { /* continuation */ }
  893: {EndLine}                { /* end of answer and/or other answers */ LLDBUG_PR1("[complete an answer<EoL>]"); 
  894:                            BEGIN S_TEXT; }
  895: "/AND"                   { LLDBUG_PR1("[AND]"); RETURN(ANS_AND); }
  896: "/OR"                    { LLDBUG_PR1("[OR]");  RETURN(ANS_OR);  }
  897: }
  898: 
  899: <S_IF_SKIP>{
  900: ^{Spaces}"/IF"[^\n]*{EndLine}    { IFcount++; LLDBUG_PRL2("[Skip IF <IFcount=%d>]\n",IFcount); 
  901:                                    IFstatus[IFcount] = IF_DONT_CARE;
  902:                                  }
  903: ^{Spaces}"/ELSE"[^\n]*{EndLine}  {  LLDBUG_PRL2("[Skip ELSE <IFcount=%d>]",IFcount);
  904:                             IFcurrent[IFcount]=RUN_ELSE_PORTION; 
  905:                             if( IFstatus[IFcount] == IF_FALSE ) {
  906:                                LLDBUG_PRL1("[ELSE begin TEXT CR]\n");
  907:                                BEGIN S_TEXT;
  908:                             } 
  909:                             if( IFstatus[IFcount] == IF_TRUE ) {
  910:                                LLDBUG_PRL1("[ELSE THIS SHOULD NEVER HAPPEN.]\n");
  911:                             }
  912:                          }
  913: ^{Spaces}"/ENDIF"[^\n]*{EndLine} { IFcount--; LLDBUG_PRL2("[Skip ENDIF <IFcount=%d>]\n",IFcount);
  914:                             if( IFcount == 0 ) {
  915:                                LLDBUG_PRL1("[ENDIF begin TEXT CR]\n");
  916:                                BEGIN S_TEXT;
  917:                             }
  918:                             if( (IFcurrent[IFcount] == RUN_IF_PORTION )&&(IFstatus[IFcount] == IF_TRUE)) {
  919:                                LLDBUG_PRL1("[ENDIF begin TEXT CR]\n");
  920:                                BEGIN S_TEXT;
  921:                             }
  922:                             if( (IFcurrent[IFcount] == RUN_ELSE_PORTION )&&(IFstatus[IFcount] == IF_FALSE)) {
  923:                                LLDBUG_PRL1("[ENDIF begin TEXT CR]\n");
  924:                                BEGIN S_TEXT;
  925:                             }
  926:                          }
  927: {EndLine}                { LLDBUG_PRL1("[SkipIF a CR]\n");       }
  928: [^\n]*$                  { LLDBUG_PRL2("[SkipIF anything <IFcount=%d>]",IFcount);   }
  929: }
  930: <S_NEXT_LINE>{
  931: ([.]*){EndLine}          { /* this ignores everything until it hits an EoL */
  932:                            LLDBUG_PRL2("[<S_NEXT_LINE> skip \'%s\' until EoL]\n",yytext); 
  933:                            BEGIN S_TEXT;
  934:                          }
  935: }
  936: 
  937: <S_WHILE_SKIP>{
  938: ^{Spaces}"/WHILE"[^\n]*{EndLine}        { Wcount++;
  939:                                           LLDBUG_PRL2("[SkipWHILE /WHILE <Wcount=%d>]\n",Wcount);   
  940:                                         }
  941: ^{Spaces}"/ENDWHILE"[^\n]*{EndLine}     { 
  942:                                           if(Wcount==0) {
  943:                                              LLDBUG_PRL2("[SkipWHILE->/ENDWHILE <Wcount=%d>]\n",Wcount);
  944:                                              BEGIN S_TEXT;
  945:                                           } else {
  946:                                              Wcount--;
  947:                                              LLDBUG_PRL2("[SkipWHILE /ENDWHILE <Wcount=%d>]\n",Wcount);
  948:                                           }
  949:                                         }
  950: {EndLine}                { LLDBUG_PRL1("[SkipWHILE a CR]\n");       }                         
  951: [^\n]*$                  { LLDBUG_PRL2("[SkipWHILE anything <Wcount=%d>]",Wcount);   }
  952: }
  953: 
  954: <S_VERB>{
  955: ^{Spaces}"/ENDVERB" { LLDBUG_PRL1("[END VERB]\n"); 
  956:                       yylval = (Symbol *) capa_malloc(1, sizeof(Symbol));
  957: 		      yylval->s_str = strsave(Dynamic_buf);  /* ****   */
  958: 		      yylval->s_type = S_CONSTANT;  
  959: 		      capa_mfree(Dynamic_buf);
  960: 		      Dynamic_buf_cur=-1;
  961: 		      Dynamic_buf_max=0;
  962: 		      BEGIN S_TEXT;   RETURN(VERBATIM);   
  963: 		    }
  964: .*|{EndLine}         { append_dynamic_buf(yytext); }
  965: }
  966: 
  967: %%
  968: 
  969: /* ========================================================================================== */
  970: extern void
  971: begin_if_skip() { BEGIN S_IF_SKIP; }
  972: 
  973: extern void
  974: begin_while_skip() { Wcount=0; While_idx--; /* while is FALSE, pop it out from stack */ BEGIN S_WHILE_SKIP; }
  975: 
  976: extern void
  977: begin_next_line()  { BEGIN S_NEXT_LINE; }
  978: 
  979: extern void
  980: begin_var() { BEGIN S_VARIABLE; }
  981: 
  982: extern void
  983: begin_let() { BEGIN S_LET; }
  984: 
  985: extern void
  986: begin_def() { BEGIN S_DEFINE; }
  987: 
  988: extern void
  989: begin_ans() { BEGIN S_ANSWER; }
  990: 
  991: extern void
  992: begin_map() { BEGIN S_MAP; }
  993: 
  994: extern void
  995: begin_ignore() { BEGIN S_IGNORE; }
  996: 
  997: extern void
  998: begin_text() { BEGIN S_TEXT; }
  999: 
 1000: extern void
 1001: begin_question() { LLDBUG_PR1("[<S_TEXT>]"); 
 1002:                    IFcount = 0; While_idx=0; /* initialize some stacks */
 1003:                    End_of_input = 0; YY_FLUSH_BUFFER; BEGIN S_TEXT; }
 1004: 
 1005: extern void
 1006: end_problemset() { End_of_input = 0; YY_FLUSH_BUFFER; BEGIN S_TEXT; }
 1007: 
 1008: 
 1009: /* ========================================================================================== */
 1010: 
 1011: #define  NUM_KEY   2
 1012: int
 1013: match_keyword(key) char *key;
 1014: {
 1015:   char  *keyword[NUM_KEY] = {"/DIS", "/DIR" };
 1016:   int    i;
 1017:   
 1018:   for(i=0;i < NUM_KEY; i++) {
 1019:      if( !strncmp(keyword[i], key, 4) ) {
 1020:         return (1);
 1021:      }
 1022:   }
 1023:   return (0);
 1024: }
 1025: 
 1026: int
 1027: match_functionid(key) char *key;
 1028: {
 1029:   char  *keyword[NUM_KEY] = {"/DIS", "/DIR" };
 1030:   int    i;
 1031:   
 1032:   for(i=0;i < NUM_KEY; i++) {
 1033:      if( !strncmp(keyword[i], key, 4) ) {
 1034:         return (1);
 1035:      }
 1036:   }
 1037:   return (0);
 1038: }
 1039: /* -------------------------------------------------------------------------- */
 1040: /* -------------------------------------------------------------------------- */
 1041: 
 1042: void  init_funcstack() 
 1043: {  
 1044:  int ii;
 1045:  for(ii=0;ii<Func_idx;ii++) {
 1046:    capa_mfree(FuncStack[ii].s_name);
 1047:  }
 1048:  Func_idx = 0;  
 1049: }
 1050: 
 1051: 
 1052: /* -------------------------------------------------------------------------- */
 1053: /* GET THE NEXT CHARACTER OF THE SOURCE FILE                                  */
 1054: /* -------------------------------------------------------------------------- */
 1055: 
 1056: #ifdef  FLEX
 1057: int   capaL_input()
 1058: #else
 1059: int                        /* RETURNS: next character */
 1060: input()                    /* ARGUMENTS: (none)       */
 1061: #endif
 1062: 
 1063: {                          /* LOCAL VARIABLES:        */
 1064:   static  int startup=1;  /*    First call flag      */
 1065:   
 1066:   LLDBUG_PRL1("<<capaL_input() is called>>\n");
 1067:   if (!Lexi_line) { /* was startup */
 1068:        for(Input_idx=0;Input_idx < MAX_OPENED_FILE;Input_idx++) {
 1069:          /* for(ii=0;ii<LEX_BUFLEN;ii++) {
 1070:            Lexi_buf[Input_idx][ii]=0;
 1071:          }
 1072:          */
 1073:          Lexi_buf[Input_idx][0]=0;
 1074:          Lexi_pos[Input_idx] = 0;
 1075:        }
 1076:        Input_idx = 0;
 1077:        startup=0;
 1078:        yyin = Input_stream[Input_idx];
 1079:   }
 1080:   if (!Lexi_buf[Input_idx][Lexi_pos[Input_idx]]) {
 1081:     if (fgets(Lexi_buf[Input_idx],LEX_BUFLEN-1,Input_stream[Input_idx])==NULL) { 
 1082:       /* EOF? */
 1083:       /* no use in flex
 1084:          printf("capaL_input()EOF %s\n",Opened_filename[Input_idx+1]); fflush(stdout); */
 1085:       return (0);
 1086:     }
 1087:     Lexi_pos[Input_idx] = 0;
 1088:     Lexi_line++;
 1089:     printf("input()(%d)\n",Lexi_line);
 1090:   }
 1091:   (Lexi_pos[Input_idx])++;
 1092:   return ( Lexi_buf[Input_idx][Lexi_pos[Input_idx]-1] );
 1093: }
 1094:  
 1095: /******************************************************************************/
 1096: /* PUSH BACK ONE CHARACTER OF THE INPUT                                       */
 1097: /******************************************************************************/
 1098: 
 1099: int                /* RETURNS: nothing     */
 1100: capaL_unput(ch)          /* ARGUMENTS:           */
 1101: register int ch;   /*    Character to push */
 1102: {
 1103:    if (ch)   (Lexi_pos[Input_idx])--;
 1104:  
 1105:    /* unput() stream cannot be re-defined */
 1106:    /* unput(ch); inconsistency between YY_INPUT() and internal matched yytext */
 1107:    return (0);
 1108: 
 1109: }
 1110: 
 1111: 
 1112: /******************************************************/
 1113: 
 1114: #ifndef DMALLOC
 1115: 
 1116: char *       
 1117: strsave(char *s) 
 1118: {            
 1119:    char *p;  
 1120:    if (s==NULL) {return s;}
 1121:    p=capa_malloc(strlen(s)+1,1);
 1122:    strcpy(p,s);
 1123:    return (p);
 1124: }
 1125: 
 1126: #endif
 1127: 
 1128: /* =========================================================================== */
 1129: 
 1130: #ifndef DMALLOC
 1131: char *
 1132: capa_malloc(unsigned num,unsigned sz)
 1133: {
 1134:   char *p;
 1135:   p = calloc(num, sz);
 1136:   bzero(p, num*sz);  /* added Jan 21 1998 */
 1137:   return (p);
 1138: }
 1139: 
 1140: #endif
 1141: 
 1142: #ifndef DMALLOC
 1143: void
 1144: capa_mfree(p) char *p;
 1145: {
 1146:   free(p);
 1147: }
 1148: #endif
 1149: 
 1150: void
 1151: capa_msg(int type, char *p) 
 1152: { int  idx, i, j;
 1153:   int  len;
 1154:   char warn_msg[WARN_MSG_LENGTH];
 1155:   char tmp_line[ONE_TWO_EIGHT];
 1156:   char  *tmp_str;
 1157:   
 1158:   strcpy(warn_msg,"File: ");
 1159:   idx=6;
 1160:   for(i=0;i<=Input_idx;i++) {
 1161:     len=strlen(Opened_filename[i]);
 1162:     for(j=0;j<len;j++) {
 1163:       warn_msg[idx++] = Opened_filename[i][j];
 1164:     }
 1165:     if(i < Input_idx) {
 1166:       warn_msg[idx++]='-';
 1167:       warn_msg[idx++]='>';
 1168:     }
 1169:     warn_msg[idx]=0;
 1170:   }
 1171:   switch (type) {
 1172:     case MESSAGE_ERROR:
 1173:            sprintf(tmp_line,", Line %d: ERROR:", Current_line[Input_idx]);
 1174:            len=strlen(tmp_line);
 1175:            for(j=0;j<len;j++) {
 1176:               warn_msg[idx++] = tmp_line[j];
 1177:            }
 1178:            warn_msg[idx]=0;
 1179:            append_error(warn_msg); append_error(p);
 1180: 	   break;
 1181:     case MESSAGE_WARN:
 1182:     default:
 1183:            sprintf(tmp_line,", Line %d: WARNING:", Current_line[Input_idx]);
 1184:            len=strlen(tmp_line);
 1185:            for(j=0;j<len;j++) {
 1186:              warn_msg[idx++] = tmp_line[j];
 1187:            }
 1188:            warn_msg[idx]=0;
 1189:            j = strlen(warn_msg);
 1190:            len = strlen(p);
 1191:            tmp_str = (char *)capa_malloc(len+j+1,1);
 1192:            for(i=0;i<j;i++) {
 1193:              tmp_str[i]=warn_msg[i];
 1194:            } 
 1195:            for(i=j;i<j+len;i++) {
 1196:              tmp_str[i] = p[i-j];
 1197:            }
 1198:            append_warn(type,tmp_str);
 1199:            capa_mfree(tmp_str);
 1200:            break;
 1201:   }
 1202: }
 1203: 
 1204: /* ======================================================================== */
 1205: void
 1206: capa_warn_header(int type)
 1207: {
 1208:   int  idx, i, j;
 1209:   int  len;
 1210:   char warn_msg[WARN_MSG_LENGTH];
 1211:   char tmp_line[ONE_TWO_EIGHT];
 1212:   
 1213:   strcpy(warn_msg,"File: ");
 1214:   idx=6;
 1215:   for(i=0;i<=Input_idx;i++) {
 1216:     len=strlen(Opened_filename[i]);
 1217:     for(j=0;j<len;j++) {
 1218:       warn_msg[idx++] = Opened_filename[i][j];
 1219:     }
 1220:     if(i < Input_idx) {
 1221:       warn_msg[idx++]='-';
 1222:       warn_msg[idx++]='>';
 1223:     }
 1224:     warn_msg[idx]=0;
 1225:   }
 1226:   switch (type) {
 1227:     case MESSAGE_ERROR:
 1228:       sprintf(tmp_line,", Line %d: ERROR:", Current_line[Input_idx]);
 1229:       
 1230:       break;
 1231:     case MESSAGE_WARN:
 1232:       sprintf(tmp_line,", Line %d: WARNING:", Current_line[Input_idx]);break;
 1233:     default:
 1234:     sprintf(tmp_line,", Line %d: ERROR:", Current_line[Input_idx]);break;
 1235:   }
 1236:   len=strlen(tmp_line);
 1237:   for(j=0;j<len;j++) {
 1238:     warn_msg[idx++] = tmp_line[j];
 1239:   }
 1240:   warn_msg[idx]=0;
 1241:   append_error(warn_msg);
 1242: }
 1243: 
 1244: /* --------------------------------------------------------------------------- */
 1245: #ifdef AVOIDYYINPUT
 1246: 
 1247: void change_file(char *fname)
 1248: {
 1249:   char warn_msg[WARN_MSG_LENGTH];
 1250:   
 1251:   if ( include_stack_ptr >= MAX_INCLUDE_DEPTH ) {
 1252:     sprintf(warn_msg,"Includes nested too deeply" );
 1253:     capa_msg(MESSAGE_ERROR,warn_msg);
 1254:     return;
 1255:   }
 1256: 
 1257:   include_stack[include_stack_ptr++] = YY_CURRENT_BUFFER;
 1258:   yyin = fopen( fname, "r" );
 1259:   yy_switch_to_buffer( yy_create_buffer( yyin, YY_BUF_SIZE ) );
 1260: }
 1261: 
 1262: void
 1263: parse_filename(char *line)
 1264: {
 1265:   char *start, fname[MAX_BUFFER_SIZE],  warn_msg[WARN_MSG_LENGTH];
 1266:   int ii,len;
 1267: 
 1268:   start = index(line, '\"'); /*** hpux complained */
 1269:   if( start == NULL ) {
 1270:     sprintf(warn_msg,"/IMP was not given a filename.\n");
 1271:     capa_msg(MESSAGE_ERROR,warn_msg);
 1272:     return;
 1273:   }
 1274:   start++; len = strlen(start) - 1;
 1275:   ii = 0;
 1276:   while( start[ii] != '\"' ) fname[ii++] = start[ii];
 1277:   fname[ii] = 0;
 1278:   LLDBUG_PR2("[parse_filename<%s>]\n",fname);
 1279:   
 1280:   change_file(fname);
 1281: }
 1282: 
 1283: void
 1284: parse_import_id(char *line)
 1285: {
 1286:   char    fname[QUARTER_K], warn_msg[WARN_MSG_LENGTH];
 1287:   int     ii, dup_open;
 1288:   Symbol *symb_p;
 1289:   int     no_error = 0;
 1290:   
 1291:   ii = 0;
 1292:   while( line[ii] != '\0' && line[ii] != ' ' && line[ii] != '\n' && line[ii] != '\t' ) 
 1293:     fname[ii++] = line[ii]; 
 1294:   fname[ii] = 0;
 1295: 
 1296:   LLDBUG_PR2("[parse_import_id<%s>]\n",fname);
 1297:   /*symb_p = find_identifier(fname);*/
 1298:   
 1299:   switch (symb_p->s_type) {
 1300:    case IDENTIFIER:
 1301:      sprintf(warn_msg,"/IMP %s, var is not defined.\n", fname);
 1302:      capa_msg(MESSAGE_ERROR,warn_msg);
 1303:      break;
 1304:    case I_VAR: case I_CONSTANT: case R_VAR: case R_CONSTANT:
 1305:      sprintf(warn_msg,"var cannot be a number.\n");
 1306:      capa_msg(MESSAGE_ERROR,warn_msg);
 1307:      break;
 1308:    case S_VAR:  case S_CONSTANT: sprintf(fname,"%s",symb_p->s_str);
 1309:      no_error = 1;
 1310:      break;
 1311:   }
 1312:   if( no_error ) change_file(fname);
 1313: }
 1314: 
 1315: #else
 1316: void
 1317: parse_filename(char *line)
 1318: {
 1319:   char  *start, fname[QUARTER_K], warn_msg[WARN_MSG_LENGTH];
 1320:   int    ii, len, dup_open;
 1321:   
 1322:   /* printf("IMPORT %s\n", line); */
 1323:   
 1324:   start = index(line, '\"'); /*** hpux complained */
 1325:   if( start != NULL ) {
 1326:     start++; len = strlen(start) - 1;
 1327:     ii = 0;
 1328:     while( start[ii] != '\"' ) {
 1329:       fname[ii] = start[ii]; ii++;
 1330:     }
 1331:     fname[ii] = 0;
 1332:     LLDBUG_PR2("[parse_filename<%s>]\n",fname);
 1333:     if(Input_idx < (MAX_OPENED_FILE -1)) {
 1334:       dup_open = 0;
 1335:       /* -- no need to check duplicated opening a file 
 1336:       for(ii=0;ii<Input_idx;ii++) {
 1337:         if(strcmp(Opened_filename[ii],fname)==0) {
 1338:           dup_open =1;
 1339:         }
 1340:       }
 1341:       */
 1342:       if( !dup_open ) {
 1343:           Input_idx++;
 1344:           Input_stream[Input_idx]=fopen(fname,"r");
 1345:           sprintf(Opened_filename[Input_idx], "%s",fname);
 1346:           Current_line[Input_idx] = 0;
 1347:       } else {
 1348:         /*
 1349:           sprintf(warn_msg,"/IMP \"%s\", import file has already been imported.\n",fname);
 1350:           capa_msg(MESSAGE_WARN,warn_msg);
 1351:         */
 1352:           Input_idx++;
 1353:           Input_stream[Input_idx]=fopen(fname,"r");
 1354:           sprintf(Opened_filename[Input_idx], "%s",fname);
 1355:           Current_line[Input_idx] = 0;
 1356:       }
 1357:     } else {
 1358:       sprintf(warn_msg,"/IMP more the %d levels deep ignoring further imports.\n",MAX_OPENED_FILE-1);
 1359:       capa_msg(MESSAGE_WARN,warn_msg);
 1360:     }
 1361:   } else {
 1362:     sprintf(warn_msg,"%s, is not a valid file name.\n",line);
 1363:     capa_msg(MESSAGE_ERROR,warn_msg);
 1364:   }
 1365:   
 1366: }
 1367: 
 1368: void
 1369: parse_import_id(char *line)
 1370: {
 1371:   char    fname[QUARTER_K], warn_msg[WARN_MSG_LENGTH];
 1372:   int     ii, dup_open;
 1373:   Symbol *symb_p;
 1374:   int     no_error = 0;
 1375:   
 1376:     ii = 0;
 1377:     while (line[ii] != '\0' && line[ii] != ' ' && line[ii] != '\n' && line[ii] != '\t') {
 1378:       fname[ii] = line[ii]; ii++;
 1379:     }
 1380:     fname[ii] = 0;
 1381:     LLDBUG_PR2("[parse_import_id<%s>]\n",fname);
 1382:     /*symb_p = find_identifier(fname);*/
 1383:     
 1384:     switch (symb_p->s_type) {
 1385:       case IDENTIFIER:
 1386: 	sprintf(warn_msg,"/IMP %s, var is not defined.\n", fname);
 1387: 	capa_msg(MESSAGE_ERROR,warn_msg);
 1388: 	break;
 1389:       case I_VAR: case I_CONSTANT: case R_VAR: case R_CONSTANT:
 1390: 	sprintf(warn_msg,"var cannot be a number.\n");
 1391: 	capa_msg(MESSAGE_ERROR,warn_msg);
 1392: 	break;
 1393:       case S_VAR:
 1394:       case S_CONSTANT:
 1395: 	sprintf(fname,"%s",symb_p->s_str);
 1396: 	no_error = 1;
 1397: 	break;
 1398:     }
 1399:     if( no_error ) {
 1400:       if(Input_idx < (MAX_OPENED_FILE -1) ) {
 1401:           dup_open = 0;
 1402:           /* no need to check duplicated opening a file 
 1403:           for(ii=0;ii<Input_idx;ii++) {
 1404:             if(strcmp(Opened_filename[ii],fname)==0)  dup_open =1; 
 1405:           }
 1406:           */
 1407:           if( !dup_open ) {
 1408:               Input_idx++;
 1409:               Input_stream[Input_idx]=fopen(fname,"r");
 1410:               sprintf(Opened_filename[Input_idx], "%s",fname);
 1411:               Current_line[Input_idx] = 0;
 1412:           } else {
 1413:             /*  NO warning on duplicated open a file
 1414:             sprintf(warn_msg,"/IMP \"%s\", file has already been imported.\n", fname);
 1415:             capa_msg(MESSAGE_WARN,warn_msg);
 1416:             */
 1417:               Input_idx++;
 1418:               Input_stream[Input_idx]=fopen(fname,"r");
 1419:               sprintf(Opened_filename[Input_idx], "%s",fname);
 1420:               Current_line[Input_idx] = 0;
 1421:           }
 1422:         } else {
 1423:           sprintf(warn_msg,"/IMP , too many files has been imported. The maximum is %d files.\n",
 1424:               MAX_OPENED_FILE-1);
 1425:           capa_msg(MESSAGE_WARN,warn_msg);
 1426:         }
 1427:       }
 1428: }
 1429: #endif /*AVOIDYYINPUT*/
 1430: 
 1431: void append_dynamic_buf(new_str) char *new_str;
 1432: {
 1433:   int ii,len;
 1434:   
 1435:   if(new_str==NULL) return;
 1436:   len=strlen(new_str);
 1437: #ifdef LEX_DBUG
 1438:   printf("before: len %d; Dynamic_buf_cur %d; Dynamic_buf_max %d\n",
 1439: 	 len,Dynamic_buf_cur,Dynamic_buf_max);
 1440: #endif /* LEX_DBUG */    
 1441:   if (Dynamic_buf_cur+len+1>Dynamic_buf_max) {
 1442:     char *temp_text;
 1443:     Dynamic_buf_max=(Dynamic_buf_cur+len)*2;
 1444:     temp_text=(char*)capa_malloc(sizeof(char),Dynamic_buf_max);
 1445:     strncpy(temp_text,Dynamic_buf,Dynamic_buf_max);
 1446:     free(Dynamic_buf);
 1447:     Dynamic_buf=temp_text;
 1448:   }
 1449:   for(ii=0;ii<len;ii++) {
 1450:     Dynamic_buf[Dynamic_buf_cur+ii]=new_str[ii];
 1451:   }
 1452:   Dynamic_buf_cur += len;
 1453:   Dynamic_buf[Dynamic_buf_cur+1]='\0';
 1454: #ifdef LEX_DBUG
 1455:   printf("after: len %d; Dynamic_buf_cur %d; Dynamic_buf_max %d\n",
 1456: 	 len,Dynamic_buf_cur,Dynamic_buf_max);
 1457:   printf("Dyn_buf %s; added %s\n",Dynamic_buf,new_str);
 1458: #endif /* LEX_DBUG */    
 1459: }
 1460: 
 1461: char* parser_status()
 1462: {
 1463:   char *buf,small[SMALL_LINE_BUFFER];
 1464:   int i,j,totlen=0,len,idx=0;
 1465:   
 1466:   for(i=0;i<=Input_idx;i++) totlen+=strlen(Opened_filename[i])+6;
 1467:   buf=capa_malloc(sizeof(char),totlen);
 1468:   for(i=0;i<=Input_idx;i++) {
 1469:     len=strlen(Opened_filename[i]);
 1470:     for(j=0;j<len;j++) buf[idx++] = Opened_filename[i][j];
 1471:     buf[idx++] = ':';
 1472:     sprintf(small,"%d",Current_line[i]);
 1473:     len=strlen(small);
 1474:     for(j=0;j<len;j++) buf[idx++] = small[j];
 1475:     buf[idx++]=' ';
 1476:     buf[idx]='\0';
 1477:   }
 1478:   return buf;
 1479: }
 1480: 
 1481: void yyfatalerror(char*msg)
 1482: {
 1483:   char    warn_msg[WARN_MSG_LENGTH];
 1484:   sprintf(warn_msg,"Invalid character[\'%s\']\n",yytext);
 1485:   capa_msg(MESSAGE_ERROR,warn_msg);
 1486:   capa_msg(MESSAGE_ERROR,msg);
 1487: }
 1488: void yyerror(char* msg)
 1489: {
 1490:   char    warn_msg[WARN_MSG_LENGTH];
 1491:   sprintf(warn_msg,"%s\n",msg);
 1492:   capa_msg(MESSAGE_ERROR,warn_msg);
 1493: }
 1494: 
 1495: void newyy_input (char *buf,int *result,int max_size) 
 1496: { int ii, leng, out_of_char; 
 1497:  if (!Lexi_line) { /* was startup */ 
 1498:    for(ii=0;ii < MAX_OPENED_FILE;ii++) { 
 1499:      Lexi_buf[ii] = NULL; 
 1500:      Lexi_pos[ii] = 0; 
 1501:      Current_line[ii] = 0; 
 1502:    } 
 1503:    Input_idx = 0; 
 1504:    first_run=0; 
 1505:    yyin = Input_stream[Input_idx]; LIDBUG_PR1("<<yy_input() startup>>\n"); 
 1506:  } 
 1507:  out_of_char = 0; 
 1508:  if ( Lexi_buf[Input_idx] == NULL ) { 
 1509:    Lexi_buf[Input_idx] = (char *)capa_malloc(sizeof(char)*LEX_BUFLEN+1,1); out_of_char=1;
 1510:  } else { 
 1511:    if (!Lexi_buf[Input_idx][Lexi_pos[Input_idx]]) { 
 1512:      /* test if the line buffer is empty or at the end */ 
 1513:      out_of_char=1; 
 1514:    } 
 1515:  }
 1516:  if( out_of_char ) { 
 1517:    if (fgets(Lexi_buf[Input_idx],LEX_BUFLEN-1,Input_stream[Input_idx])==NULL) { 
 1518:      /* read in one line */ 
 1519:      LIDBUG_PR2("<<yy_input() fgets() returns NULL, input index=%d>>\n",Input_idx); 
 1520:      if( (Input_idx > 0) && ( Lexi_buf[Input_idx][Lexi_pos[Input_idx]] == '\0') ) { 
 1521:        LIDBUG_PR2("<<yy_input() close an input stream, input index=%d>>\n",Input_idx); 
 1522:        fclose(Input_stream[Input_idx]); 
 1523:        capa_mfree((char *)Lexi_buf[Input_idx]); 
 1524:        Lexi_buf[Input_idx] = NULL; 
 1525:        Input_idx--; 
 1526:        yyin = Input_stream[Input_idx]; 
 1527:        /* (Lexi_pos[Input_idx])++; */ 
 1528:        buf[0] = Lexi_buf[Input_idx][Lexi_pos[Input_idx]-1]; 
 1529:        *result = 1; 
 1530:      } else { 
 1531:        *result = YY_NULL; /* End of File */ 
 1532:      } 
 1533:    } else { /* successfully read in one line */ 
 1534:      leng = strlen(Lexi_buf[Input_idx]); 
 1535:      LIDBUG_PR3("<<yy_input() read into buffer a line(leng=%d), input index=%d>>\n",
 1536: 		leng,Input_idx);  
 1537:      Lexi_pos[Input_idx] = 0; 
 1538:      Lexi_line++; 
 1539:      Current_line[Input_idx]++; 
 1540:      (Lexi_pos[Input_idx])++; 
 1541:      buf[0] = Lexi_buf[Input_idx][Lexi_pos[Input_idx]-1];  
 1542:      /* need to take care of return continuation conditions */ 
 1543:      /*  so, we return to one-char-at-a-time approach */ 
 1544:      /* for(ii=0;ii<leng;ii++) { */ 
 1545:      /*  buf[ii] = Lexi_buf[Input_idx][ii]; */ 
 1546:      /* } */ 
 1547:      /* buf[ii] = '\0'; */ 
 1548:      /* printf("YY_INPUT()(Lexi_line=%d,max size=%d)(%c)",Lexi_line,max_size,buf[0]); */ 
 1549:      *result = 1; 
 1550:    } 
 1551:  } else { 
 1552:    /* LIDBUG_PR2("<<yy_input() increase Lexi_pos, input index=%d>>\n",Input_idx);  */ 
 1553:    (Lexi_pos[Input_idx])++; 
 1554:    buf[0] = Lexi_buf[Input_idx][Lexi_pos[Input_idx]-1]; 
 1555:    *result = 1; 
 1556:  } 
 1557:  if (Stop_Parser==1) *result = YY_NULL;  
 1558: }
 1559: 
 1560: int capa_eof()
 1561: {
 1562: #ifdef AVOIDYYINPUT
 1563:   if ( --include_stack_ptr < 0 ) yyterminate();
 1564:   else {
 1565:     yy_delete_buffer( YY_CURRENT_BUFFER );
 1566:     yy_switch_to_buffer(include_stack[include_stack_ptr]);
 1567:   }
 1568: #else
 1569:   if(Input_idx == 0) {
 1570:     fclose(Input_stream[Input_idx]);
 1571:     capa_mfree((char *)Lexi_buf[Input_idx]); 
 1572:     /*free_problems(LexiProblem_p);*/
 1573:     LexiProblem_p=NULL;
 1574:     /* printf("\nCAPA EOF\n"); fflush(stdout); */
 1575:   }
 1576:   return (0);
 1577: #endif /*AVOIDYYINPUT*/
 1578: }
 1579: /* ------------ */
 1580: 
 1581: 
 1582: /* =========================================================== */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>