File:  [LON-CAPA] / loncom / homework / CAPA-converter / capaLexerDef.flex
Revision 1.13: download - view: text, annotated - select for diffs
Thu Nov 29 18:43:55 2001 UTC (22 years, 8 months ago) by albertel
Branches: MAIN
CVS tags: HEAD
- protecting more % (mlucas)

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

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