File:  [LON-CAPA] / loncom / homework / CAPA-converter / capaLexerDef.flex
Revision 1.21: download - view: text, annotated - select for diffs
Thu Sep 12 15:54:06 2002 UTC (22 years, 3 months ago) by albertel
Branches: MAIN
CVS tags: version_2_9_X, version_2_9_99_0, version_2_9_1, version_2_9_0, version_2_8_X, version_2_8_99_1, version_2_8_99_0, version_2_8_2, version_2_8_1, version_2_8_0, version_2_7_X, version_2_7_99_1, version_2_7_99_0, version_2_7_1, version_2_7_0, version_2_6_X, version_2_6_99_1, version_2_6_99_0, version_2_6_3, version_2_6_2, version_2_6_1, version_2_6_0, version_2_5_X, version_2_5_99_1, version_2_5_99_0, version_2_5_2, version_2_5_1, version_2_5_0, version_2_4_X, version_2_4_99_0, version_2_4_2, version_2_4_1, version_2_4_0, version_2_3_X, version_2_3_99_0, version_2_3_2, version_2_3_1, version_2_3_0, version_2_2_X, version_2_2_99_1, version_2_2_99_0, version_2_2_2, version_2_2_1, version_2_2_0, version_2_1_X, version_2_1_99_3, version_2_1_99_2, version_2_1_99_1, version_2_1_99_0, version_2_1_3, version_2_1_2, version_2_1_1, version_2_1_0, version_2_12_X, version_2_11_X, version_2_11_5_msu, version_2_11_5, version_2_11_4_uiuc, version_2_11_4_msu, version_2_11_4, version_2_11_3_uiuc, version_2_11_3_msu, version_2_11_3, version_2_11_2_uiuc, version_2_11_2_msu, version_2_11_2_educog, version_2_11_2, version_2_11_1, version_2_11_0_RC3, version_2_11_0_RC2, version_2_11_0_RC1, version_2_11_0, version_2_10_X, version_2_10_1, version_2_10_0_RC2, version_2_10_0_RC1, version_2_10_0, version_2_0_X, version_2_0_99_1, version_2_0_2, version_2_0_1, version_2_0_0, version_1_99_3, version_1_99_2, version_1_99_1_tmcc, version_1_99_1, version_1_99_0_tmcc, version_1_99_0, version_1_3_X, version_1_3_3, version_1_3_2, version_1_3_1, version_1_3_0, version_1_2_X, version_1_2_99_1, version_1_2_99_0, version_1_2_1, version_1_2_0, version_1_1_X, version_1_1_99_5, version_1_1_99_4, version_1_1_99_3, version_1_1_99_2, version_1_1_99_1, version_1_1_99_0, version_1_1_3, version_1_1_2, version_1_1_1, version_1_1_0, version_1_0_99_3, version_1_0_99_2, version_1_0_99_1, version_1_0_99, version_1_0_3, version_1_0_2, version_1_0_1, version_1_0_0, version_0_99_5, version_0_99_4, version_0_99_3, version_0_99_2, version_0_99_1, version_0_99_0, version_0_6_2, version_0_6, loncapaMITrelate_1, language_hyphenation_merge, language_hyphenation, conference_2003, bz6209-base, bz6209, bz5969, bz2851, PRINT_INCOMPLETE_base, PRINT_INCOMPLETE, HEAD, GCI_3, GCI_2, GCI_1, BZ5971-printing-apage, BZ5434-fox, BZ4492-merge, BZ4492-feature_horizontal_radioresponse, BZ4492-feature_Support_horizontal_radioresponse, BZ4492-Support_horizontal_radioresponse
- From Mark Lucas,
 Fixes a few things with /DIS in scripts, eval with fml,
braces around variables.

/* The LearningOnline Network with CAPA
 * CAPA lexer dfinition, heavily modified to become a LON-CAPA convertor 
 * $Id: capaLexerDef.flex,v 1.21 2002/09/12 15:54:06 albertel Exp $
 *
 * Copyright Michigan State University Board of Trustees
 *
 * This file is part of the LearningOnline Network with CAPA (LON-CAPA).
 *
 * LON-CAPA is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * LON-CAPA is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with LON-CAPA; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * /home/httpd/html/adm/gpl.txt
 *
 * http://www.lon-capa.org/
 */

/*------------------------------------------------------------------------*/
/*         capaLexerDef.flex   created by Isaac Tsai Jul 15 1996          */
/*                             added /END(variable)                       */
/*                             added /HIN  .... /DIS(variable) ...        */
/*                             Jan 15 1998  /{KeyWord}{KeyWord}{KeyWord}  */
/*                               replaced by /DIS                         */
/*   catch "No /END() statement found"                                    */
/*   catch "/DIS(")" and "/DIS(""")" errors "                             */
/*   catch "/LET var = "                                                  */
/*   add a new token EoL to indicate '\n' '\r''\n' and '\r'               */
/*   This file is based on flex 2.5.3, flex 2.3 apparantly cannot take it :-( */
/*   DONE /RMAP() function July 14, 1998 */
/*   DONE /AND /OR answer formats  July 20, 1998 */
/*   DONE /IF ()  /ENDIF   July 26, 1998 */
/*   DONE /WHILE ()  /ENDWHILE August 10 1998 */
/*   DONE /VERB /ENDVERB    Feb 20 1998  */
/*------------------------------------------------------------------------*/
/**************************************************************************/

%{

#include <stdio.h>
#include <stdlib.h>       /* strtod(), strtol() */
#include <string.h>
#ifdef NeXT
#include <sys/file.h>
#else 
#include <unistd.h>       /* access() */
#endif

#include "capaCommon.h"   /* capa_access() */
#include "capaParser.h"   /* _symbol structure def */
#include "lex_debug.h"    /* defined RETURN(xxx) macro */
#ifdef  YYSTYPE
#undef  YYSTYPE
#endif
#define YYSTYPE  Symbol_p
#include "capaToken.h"    /* from YACC -d capaGrammarDef.y */



/* ============================================== begin of code */

#define LEX_BUFLEN  (8*1024)     /* lexical buffer size (for each opened file) */

#ifdef  YYLMAX 
#undef  YYLMAX
#define YYLMAX   8192
#endif

void yyfatalerror(char*msg);
#define YY_FATAL_ERROR yyfatalerror

#ifdef   LEX_DBUG
#define  LLDBUG_PRL1(xx)        { printf("Line %d ",Current_line[Input_idx]); printf(xx); fflush(stdout); }
#define  LLDBUG_PRL2(xx,yy)     { printf("Line %d ",Current_line[Input_idx]); printf(xx,yy); fflush(stdout); }
#define  LLDBUG_PR1(xx)         { printf(xx); fflush(stdout); }
#define  LLDBUG_PR2(xx,yy)      { printf(xx,yy); fflush(stdout); }
#define  LLDBUG_PR3(xx,yy,zz)   { printf(xx,yy,zz); fflush(stdout); }
#else
#define  LLDBUG_PRL1(xx)        { }
#define  LLDBUG_PRL2(xx,yy)     { }
#define  LLDBUG_PR1(xx)         { }
#define  LLDBUG_PR2(xx,yy)      { }
#define  LLDBUG_PR3(xx,yy,zz)   { }
#endif

#ifdef   LEX_INPUT_DBUG
#define  LIDBUG_PR1(xx)         { printf(xx); fflush(stdout); }
#define  LIDBUG_PR2(xx,yy)      { printf(xx,yy); fflush(stdout); }
#define  LIDBUG_PR3(xx,yy,zz)   { printf(xx,yy,zz); fflush(stdout); }
#else
#define  LIDBUG_PR1(xx)         { }
#define  LIDBUG_PR2(xx,yy)      { }
#define  LIDBUG_PR3(xx,yy,zz)   { }
#endif

#ifdef   USE_DYNAMIC_SYMBOLS
#define  USE_DYNAMIC_LEXBUFS 
#endif

Symbol       *yylval;       /* global pointer to symbol */

FILE         *(Input_stream[MAX_OPENED_FILE]);             /* <-- perhaps we can use linked list */
char          Opened_filename[MAX_OPENED_FILE][QUARTER_K]; /* <-- perhaps we can use linked list */
int           Input_idx;
int           Lexi_pos[MAX_OPENED_FILE];   /* Current position in the line */

#ifdef  USE_DYNAMIC_LEXBUFS
char         *(Lexi_buf[MAX_OPENED_FILE]);          /* Line Buffer for current file  */

#else 
char          Lexi_buf[MAX_OPENED_FILE][LEX_BUFLEN+4];          /* Line Buffer for current file  */

#endif  /* USE_DYNAMIC_LEXBUFS */

char          String_buf[LEX_BUFLEN];              /* Constant String buffer <-- perhaps we can use char pointer  */
char         *Dynamic_buf;
int           Dynamic_buf_max;
int           Dynamic_buf_cur;


static   int  End_of_input;
static   int  Pcount, Bcount; /* static means only available in this file */
/* --------------------------------------------------------------------------- */
/* GLOBAL VARIABLES                                                            */
/* --------------------------------------------------------------------------- */
int           Lexi_line;                   /* Current source file line number, counting from beginning */
extern int    Current_line[MAX_OPENED_FILE];

int           Func_idx;
Symbol        FuncStack[MAX_FUNC_NEST];    /* <-- perhaps we can use linked list */

int           Array_idx;
Symbol       *ArraySymbList_p;
Symbol       *ArraySymbLast_p;
Symbol       *FmlSymbList_p;
Symbol       *FmlSymbLast_p;
int           FmlSymb_cnt;
int           Symb_count;

int           IFcount;
WhileLoop_t   WhileStack[MAX_FUNC_NEST];   /* <-- perhaps we can use linked list */
int           While_idx, Wcount;
int           sccount;		           /* Semi-colon count for MAP and RMAP  */
int           HINTflag=0;
int           EXPflag=0;
int           EVALflag=0;
int           compound_answer=0;
int           essay_answer=0;

#ifdef  USE_DYNAMIC_SYMBOLS
Symbol       *SymbList_p;
Symbol       *SymbLast_p;
#else
Symbol        SymbArray[MAX_SYMB_COUNT];
#endif /* USE_DYNAMIC_SYMBOLS */


char         *Current_char_p;                      /* Collect string constant */
extern        char              *EndText_p;
extern        char              *StartText_p;
extern        Problem_t         *LexiProblem_p;
extern        Problem_t         *LastProblem_p;
int           first_run=1;
int           Stop_Parser;
static        int dosend=1;
static        int firstparam=1;
#define  FLEX

#define  YY_STACK_USED   1  /* for yy_push_state(), yy_pop_state() */

#ifdef   FLEX

int      capaL_unput();
int      capaL_input();


/* YY_INPUT() 
   Controls scanner input.  By default, YY_INPUT reads from the
   file-pointer yyin.  Its action is to place up to max_size
   characters in the character array buf and return in the
   integer variable result either the number of characters read
   or the constant YY_NULL to indicate EOF.  
   max_size is defined to be num_to_read = 8192 in liby
   Following is a sample 
   redefinition of YY_INPUT, in the definitions section of
   the input file:
   
   %{
   #undef YY_INPUT
   #define YY_INPUT(buf,result,max_size)\
   {\
       int c = getchar();\
       result = (c == EOF) ? YY_NULL : (buf[0] = c, 1);\
   }
   %}
 
*/

/* fgets() reads the input stream until 
   n-1 bytes have been read  OR
   a newline character is read and transferred to string  OR
   an EOF (End-of-File) condition is encountered
   
   The string is then terminated with a NULL character.  
  
  ii = fseek(FILE *stream,0L,SEEK_END) ;
  if(ii!=0) { error }
  leng = ftell(FILE *stream) + 1 ;
  fseek(FILE *stream,0L,SEEK_SET) ;
  Lexi_buf[Input_idx] = (char *)capa_malloc(sizeof(char)*leng,1);
  
*/


#ifdef AVOIDYYINPUT
#define MAX_INCLUDE_DEPTH 10
YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
int include_stack_ptr = 0;
#else
#ifdef USE_DYNAMIC_LEXBUFS
#define NEWYYINPUT
#endif

#ifdef  NEWYYINPUT
void newyy_input (char *buf,int *result,int max_size);
#define YY_INPUT(buf,result,max_size) newyy_input(buf,&result,max_size)

#else
#ifdef  USE_DYNAMIC_LEXBUFS

#define  YY_INPUT(buf,result,max_size) \
  { int ii, leng, out_of_char; \
    if (!Lexi_line) { /* was startup */ \
       for(ii=0;ii < MAX_OPENED_FILE;ii++) { \
         Lexi_buf[ii] = NULL; \
         Lexi_pos[ii] = 0; \
         Current_line[ii] = 0; \
       } \
       Input_idx = 0; \
       first_run=0; \
yyin = Input_stream[Input_idx]; LIDBUG_PR1("<<yy_input() startup>>\n"); \
    } \
    out_of_char = 0; \
    if ( Lexi_buf[Input_idx] == NULL ) { \
      Lexi_buf[Input_idx] = (char *)capa_malloc(sizeof(char)*LEX_BUFLEN+1,1); out_of_char=1; \
    } else { \
      if (!Lexi_buf[Input_idx][Lexi_pos[Input_idx]]) { /* test if the line buffer is empty or at the end */ \
        out_of_char=1; \
      } \
    } \
    if( out_of_char ) { \
      if (fgets(Lexi_buf[Input_idx],LEX_BUFLEN-1,Input_stream[Input_idx])==NULL) { /* read in one line */ \
        LIDBUG_PR2("<<yy_input() fgets() returns NULL, input index=%d>>\n",Input_idx); \
        if( (Input_idx > 0) && ( Lexi_buf[Input_idx][Lexi_pos[Input_idx]] == '\0') ) { \
          LIDBUG_PR2("<<yy_input() close an input stream, input index=%d>>\n",Input_idx); \
          fclose(Input_stream[Input_idx]); \
          capa_mfree((char *)Lexi_buf[Input_idx]); \
          Lexi_buf[Input_idx] = NULL; \
          Input_idx--; \
          yyin = Input_stream[Input_idx]; \
          /* (Lexi_pos[Input_idx])++; */ \
          buf[0] = Lexi_buf[Input_idx][Lexi_pos[Input_idx]-1]; \
          result = 1; \
        } else { \
          result = YY_NULL; /* End of File */ \
        } \
      } else { /* successfully read in one line */ \
        if (Lexi_buf[Input_idx]==NULL) puts("Whatup?");\
        leng = strlen(Lexi_buf[Input_idx]); \
        LIDBUG_PR3("<<yy_input() read into buffer a line(leng=%d), input index=%d>>\n",leng,Input_idx);  \
        Lexi_pos[Input_idx] = 0; \
        Lexi_line++; \
        Current_line[Input_idx]++; \
        (Lexi_pos[Input_idx])++; \
        buf[0] = Lexi_buf[Input_idx][Lexi_pos[Input_idx]-1];  \
        /* need to take care of return continuation conditions */ \
        /*  so, we return to one-char-at-a-time approach */ \
        /* for(ii=0;ii<leng;ii++) { */ \
        /*  buf[ii] = Lexi_buf[Input_idx][ii]; */ \
        /* } */ \
        /* buf[ii] = '\0'; */ \
        /* printf("YY_INPUT()(Lexi_line=%d,max size=%d)(%c)",Lexi_line,max_size,buf[0]); */ \
        result = 1; \
      } \
    } else { \
      /* LIDBUG_PR2("<<yy_input() increase Lexi_pos, input index=%d>>\n",Input_idx);  */ \
      (Lexi_pos[Input_idx])++; \
      buf[0] = Lexi_buf[Input_idx][Lexi_pos[Input_idx]-1]; \
      result = 1; \
    } \
    if (Stop_Parser==1) { \
      result = YY_NULL; \
    } \
  }
  
#else 

#define  YY_INPUT(buf,result,max_size) \
  { int ii, leng; \
    if (!Lexi_line) { /* was startup */ \
       for(ii=0;ii < MAX_OPENED_FILE;ii++) { \
         Lexi_buf[ii][0]=0; \
         Lexi_pos[ii] = 0; \
         Current_line[ii] = 0; \
       } \
       Input_idx = 0; \
       first_run=0; \
       yyin = Input_stream[Input_idx]; LIDBUG_PR1("<<yy_input() startup>>\n"); \
    } \
    if (!Lexi_buf[Input_idx][Lexi_pos[Input_idx]]) { /* test if the line buffer is empty or at the end */ \
      if (fgets(Lexi_buf[Input_idx],LEX_BUFLEN-1,Input_stream[Input_idx])==NULL) { /* read in one line */ \
        LIDBUG_PR2("<<yy_input() fgets() returns NULL, input index=%d>>\n",Input_idx); \
        if( (Input_idx > 0) && ( Lexi_buf[Input_idx][Lexi_pos[Input_idx]] == '\0') ) { \
          LIDBUG_PR2("<<yy_input() close an input stream, input index=%d>>\n",Input_idx); \
          fclose(Input_stream[Input_idx]); \
          Input_idx--; \
          yyin = Input_stream[Input_idx]; \
          /* (Lexi_pos[Input_idx])++; */ \
          buf[0] = Lexi_buf[Input_idx][Lexi_pos[Input_idx]-1]; \
          result = 1; \
        } else { \
          result = YY_NULL; /* End of File */ \
        } \
      } else { /* successfully read in one line */ \
        leng = strlen(Lexi_buf[Input_idx]); \
        LIDBUG_PR3("<<yy_input() read into buffer a line(leng=%d), input index=%d>>\n",leng,Input_idx);  \
        Lexi_pos[Input_idx] = 0; \
        Lexi_line++; \
        Current_line[Input_idx]++; \
        (Lexi_pos[Input_idx])++; \
        buf[0] = Lexi_buf[Input_idx][Lexi_pos[Input_idx]-1];  \
        /* need to take care of return continuation conditions */ \
        /*  so, we return to one-char-at-a-time approach */ \
        /* for(ii=0;ii<leng;ii++) { */ \
        /*  buf[ii] = Lexi_buf[Input_idx][ii]; */ \
        /* } */ \
        /* buf[ii] = '\0'; */ \
        /* printf("YY_INPUT()(Lexi_line=%d,max size=%d)(%c)",Lexi_line,max_size,buf[0]); */ \
        result = 1; \
      } \
    } else { \
      /* LIDBUG_PR2("<<yy_input() increase Lexi_pos, input index=%d>>\n",Input_idx);  */ \
      (Lexi_pos[Input_idx])++; \
      buf[0] = Lexi_buf[Input_idx][Lexi_pos[Input_idx]-1]; \
      result = 1; \
    } \
    if (Stop_Parser==1) { \
      result = YY_NULL; \
    } \
  }
#endif  /* USE_DYNAMIC_LEXBUFS */
#endif /*NEWYYINPUT*/
#endif /*AVOIDYYINPUT*/

#else

#undef  input
#undef  unput

#endif

int capa_eof();

%}

Alpha      [a-zA-Z_]
KeyChar    [A-Z]
AlphaNum   [a-zA-Z_0-9]
Number     [0-9]
HexNumber  [0-9a-fA-F]
Space      [ \t]
Spaces     ({Space}*)
FileName   (\"[^"\n]*\")
Qchar      ([0-9a-zA-Z \t!?\._,:;'"`~@#$%\^&\+\-\*=|\[\]{}()])
Operator   ([=\+\-\*/%<>!&|,])
Identifier ([a-zA-Z_][a-zA-Z_0-9]*)
EndLine    ([\r][\n]|[\n])

%a 10500
%o 15000
%k 10000
%p 10000
%n 1000
%x  S_COMMENT   S_HINT S_HINTEXLAINX  S_IMPORT S_EXPLAIN S_ENDX    S_UNIT   S_IGNORE  
%x  S_SKIP      S_VARIABLE S_LET  S_DEFINE     S_TEXT    S_MAP     S_FIGURE S_ANSWER 
%x  S_STRING    S_ANSCONTINUE     S_TRUE_FALSE_STMT      S_WHILE_SKIP
%x  S_NEXT_LINE S_VERB   S_ECHO S_STRINGINANS
%array



%%

<S_IGNORE>{
{EndLine}                       BEGIN S_IGNORE;
[^\n]*$                         BEGIN S_IGNORE;
<<EOF>>                        {
                                  capa_eof();
#ifndef AVOIDYYINPUT
				  yyterminate();
#endif
                               }
}

<S_COMMENT>{
{EndLine}{Spaces}"//"[^\n]*$ {LLDBUG_PRL2("[COMMENT<%s>]\n",yytext); 
			      send("# %s\n",&yytext[2]);
                             }
[^\n]*{EndLine}      {
                       send("\n"); BEGIN S_TEXT;
                     }
}


<S_TEXT>{
^{Spaces}"/LET" |
	   ^{Spaces}"/BEG"                  { LLDBUG_PRL1("[LET]"); Pcount = 0; BEGIN S_LET; start_mode(MODE_SCRIPT,NULL);
}
^{Spaces}"/VERB"                 { 
                                   LLDBUG_PRL1("[VERBATIM]");
                                   BEGIN S_VERB; 
				   start_mode(MODE_OUTTEXT,NULL);
				   send("<PRE>\n");
                                 }
^{Spaces}"/HIN"{Alpha}*{Spaces}  { LLDBUG_PRL1("[HIN]"); 
                               /*    start_mode(MODE_HINT, "");*/
                                   if (!HINTflag) {
                                     start_streams(HINT_DEST,1);
                                     HINTflag=-1;
                                   }
                                   change_destination(HINT_DEST);
                                   send("\t",NULL);
				   BEGIN S_HINT; 
                                 }
^{Spaces}"/EXP"{Alpha}*{Spaces}  { 
                                   if (!EXPflag) {
                                     start_streams(EXP_DEST,1);
                                     EXPflag=-1;
                                   }
                                   change_destination(EXP_DEST);
                                   send("\t",NULL);
                                   LLDBUG_PRL1("[EXP]"); Current_char_p = String_buf;  BEGIN S_EXPLAIN; }
^{Spaces}"/IMP"{Alpha}*{Space}+  { LLDBUG_PRL1("[IMP]"); BEGIN S_IMPORT; end_mode(); }
^{Spaces}"/END"                  { LLDBUG_PRL1("[END]");  
                                    if ( (LexiProblem_p !=NULL) && 
					 (LexiProblem_p->question != NULL) && 
					 (LexiProblem_p->ans_type == 0)) {
				      EndText_p=strsave(LexiProblem_p->question);
				      LexiProblem_p=NULL;
				    } else {
				      EndText_p=NULL;
				    }
				    End_of_input = 1; BEGIN S_IGNORE; 
                                  }
^{Spaces}"/START"[^\n]*          { LLDBUG_PRL1("[START]");  
                                    if (LexiProblem_p !=NULL && 
					LexiProblem_p->question != NULL) {
				      StartText_p=strsave(LexiProblem_p->question);
				    } else {
				      StartText_p=NULL;
				    }
				    BEGIN S_TEXT;
                                  }
                                  
^{Spaces}"/END"{Spaces}[\(]{Spaces}      { LLDBUG_PRL1("[END()]"); BEGIN S_ENDX; }
^"/DEF"                       { Bcount = 0; BEGIN S_DEFINE; RETURN(CAPA_DEF); }
^{Spaces}"/ANS"               { LLDBUG_PRL2("[ANS(%s)]",yytext); 
                                Pcount = 0; 
                                BEGIN S_ANSWER; 
                                end_mode();
				start_mode(MODE_ANSWER,NULL);
                                send("<numericalresponse answer=\""); 
				dosend=1;
				firstparam=1;
                                compound_answer=0;
                                essay_answer=0;
                              }
^{Spaces}"/SUBJECTIVE"        { LLDBUG_PRL1("[SUBJECTIVE ANSWER]"); 
                                Pcount = 0; 
                                BEGIN S_ANSWER;
                                end_mode();
				start_mode(MODE_ANSWER,NULL);
                                send("<essayresponse");
				dosend=1; 
				firstparam=1;                            
                                compound_answer=0;
                                essay_answer=-1;
                              }
^{Spaces}"/MAP"               { LLDBUG_PRL1("[MAP]");  Pcount = 0; sccount = 0; BEGIN S_MAP; start_mode(MODE_SCRIPT,NULL);send("&map("); }
^{Spaces}"/RMAP"              { LLDBUG_PRL1("[RMAP]"); Pcount = 0; sccount = 0; BEGIN S_MAP; start_mode(MODE_SCRIPT,NULL);send("&rmap("); }
^{Spaces}"/ENDWHILE"([^\n])*          { 
                                int i;
                                LLDBUG_PRL2("[ENDWHILE While_idx=<%d>]\n",IFcount);
                                IFcount--;
				end_mode_stream(DEFAULT_DEST,0);
				for(i=0;i<IFcount;i++) {send("\t",NULL);}
				send_stream(0,"</while>");
				send_stream(1,"}");
				if (IFcount == 0) {
				  if (watch_mode[current_dest][1]) {
				    end_streams(DEFAULT_DEST,1);
 				  } else {
				    end_streams(DEFAULT_DEST,0);
				  }
                                  change_destination(DEFAULT_DEST);
				}
				delete_cache();
                                BEGIN S_TEXT;
                              }
"/WHILE"                      |
^{Spaces}"/WHILE"             { 
                                int      i;
                                LLDBUG_PRL2("[WHILE While_idx=<%d>]\n",IFcount);
                                IFcount++;  /* advance the stack pointer */
                                BEGIN S_TRUE_FALSE_STMT;
				if ( IFcount == 1) {
 				  start_streams(DEFAULT_DEST, 2);
                                  change_destination(DEFAULT_DEST);
				  watch_mode[current_dest][1]=1;
				}
				end_mode_stream(DEFAULT_DEST, 0);
				start_mode_stream(DEFAULT_DEST,1,MODE_SCRIPT,NULL);
				for(i=1;i<IFcount;i++) {send("\t",NULL);}
				send_stream(0,"<while condition=\"",NULL);
				send_stream(1,"while (",NULL);
				new_cache();
				start_cache();
                              }
^{Spaces}"/IF"                { int i;
				IFcount++;
                                LLDBUG_PRL2("[IF <IFcount=%d>]",IFcount);
				BEGIN S_TRUE_FALSE_STMT;
				if ( IFcount == 1) {
 				  start_streams(DEFAULT_DEST, 2);
                                  change_destination(DEFAULT_DEST);
				  watch_mode[current_dest][1]=1;
				}
				end_mode_stream(DEFAULT_DEST, 0);
				start_mode_stream(DEFAULT_DEST,1,MODE_SCRIPT,NULL);
				for(i=1;i<IFcount;i++) {send("\t",NULL);}
				send_stream(0,"<block condition=\"",NULL);
				send_stream(1,"if (",NULL);
				new_cache();
				start_cache();
			       }
^{Spaces}"/ELSE"([^\n])*      { int i;
				LLDBUG_PRL2("[ELSE <IFcount=%d>]\n",IFcount);
				end_mode_stream(DEFAULT_DEST,0);
				for(i=1;i<IFcount;i++) {send("\t",NULL);}
 				send_stream(0,
                                      "</block>\n<block condition=\"!(%s)\">",
				      cached_data[current_cache].str);
				send_stream(1,"} else {");
                              }
^{Spaces}"/ENDIF"([^\n])*     { int i;
				IFcount--;
				end_mode_stream(DEFAULT_DEST,0);
				for(i=0;i<IFcount;i++) {send("\t",NULL);}
				send_stream(0,"</block>");
				send_stream(1,"}");
				if (IFcount == 0) {
				  if (watch_mode[current_dest][1]) {
				    end_streams(DEFAULT_DEST,1);
 				  } else {
				    end_streams(DEFAULT_DEST,0);
				  }
                                  change_destination(DEFAULT_DEST);
				}
				delete_cache();
				LLDBUG_PRL2("[ENDIF <IFcount=%d>]\n",IFcount); 
                              }
"/DIS"                        { /* since S_VARIABLE treat {Space} as null, so here we do not match ( */
                                /* so that between /DIS and ( can have as many {Space} as we want */
				start_mode(MODE_OUTTEXT,NULL);
                                LLDBUG_PR1("[DIS<]");
                                init_funcstack();
                                Pcount = 0; BEGIN S_VARIABLE; 
				send("<display>");
				start_delayed();
                              }
{EndLine}                     { LLDBUG_PR1("[EoL within S_TEXT]\n"); /* end of the whole text line */ 
                                send("\n"); }
[\\]{Space}*{EndLine}         { LLDBUG_PR2("[\\EoL continue](%s)",yytext); /* continuation on next line */ }                       
^{Spaces}"//"[^\n]*$		      { LLDBUG_PRL2("[COMMENT<%s>]\n",yytext);
                                        start_mode(MODE_SCRIPT,NULL); 
                                        send("# %s\n",&yytext[2]);
					BEGIN S_COMMENT;
                                      }

[^/\n\\]+$  |
[/]         | 
[\\]                          {  start_mode(MODE_OUTTEXT,NULL);
                                LLDBUG_PR2("[TEXT_LINE<%s>]",yytext);
				send(yytext);
			      }
([^/\n])+[/] |
([^/\n])+[\\]                 { /* matches anything until a '/' or a '\' */
                                start_mode(MODE_OUTTEXT,NULL);
                                LLDBUG_PR2("[TEXT_LINE( )<%s>]",yytext);
                                
                                yyless(yyleng-1); /* push back the last char */
                                BEGIN S_TEXT;
				send(yytext);
                              }
<<EOF>>                       { 
#ifdef AVOIDYYINPUT
                                char    warn_msg[ONE_K];

                                if ( (--include_stack_ptr < 0) || Stop_Parser) {
				  if (Stop_Parser) {
                                    if ( LexiProblem_p!=NULL &&
					 LexiProblem_p->question != NULL)
				      EndText_p=strsave(LexiProblem_p->question);
				    while (include_stack_ptr >= 0) {
				      yy_delete_buffer( YY_CURRENT_BUFFER );
				      yy_switch_to_buffer(
						 include_stack[include_stack_ptr]);
				      --include_stack_ptr;
				    }
				  } else {
				    sprintf(warn_msg,
					"at End-of-File, a /END is needed.\n");
				    capa_msg(MESSAGE_ERROR,warn_msg);
				  }
				  free_problems(LexiProblem_p);
				  LexiProblem_p=NULL;
				  yyterminate();
				} else {
				  yy_delete_buffer( YY_CURRENT_BUFFER );
				  yy_switch_to_buffer(include_stack[include_stack_ptr]);
				}
#else                              
				char    warn_msg[ONE_K];
                                if (!Stop_Parser) { 
				 sprintf(warn_msg,"at End-of-File, a /END is needed.\n");
				 capa_msg(MESSAGE_ERROR,warn_msg);
				} else {
				  if (LexiProblem_p != NULL &&
				      LexiProblem_p->question != NULL)
				    EndText_p=strsave(LexiProblem_p->question);
				}
                                capa_eof(); 
				yyterminate();
#endif
                              }
}


<S_ENDX>{
{Alpha}{AlphaNum}*    { /* DONE: add codes to handle /END() */
				char *question_end=NULL;
				End_of_input = 1;
				if (EndText_p!=NULL) capa_mfree((char*)EndText_p);
				if ((LexiProblem_p!=NULL) &&
				    (LexiProblem_p->question != NULL) &&
				    (LexiProblem_p->ans_type == 0)) {
				  question_end=strsave(LexiProblem_p->question);
				}
                                if( yyleng > 0 ) {
                                  
                                  LLDBUG_PRL2("[END()<%s>]\n",yytext);
                                  /*yylval = find_identifier(yytext);*/
                                
                                  switch(yylval->s_type) {
                                    case IDENTIFIER:
                                    case I_VAR: case I_CONSTANT:
                                    case R_VAR: case R_CONSTANT:
                                         break;
                                    case S_VAR: case S_CONSTANT:
                                         EndText_p = strsave(yylval->s_str);
					 if (question_end) {
					   int leng; char *new_end;
					   leng = strlen(EndText_p) + 
					     strlen(question_end) + 1;
					   new_end = capa_malloc(sizeof(char), leng);
					   strcat(new_end, question_end);
					   strcat(new_end, EndText_p);  
					   capa_mfree(EndText_p);  
					   capa_mfree(question_end);  
					   EndText_p=new_end;
					 }
                                         break;
                                    default: break;
                                  }
                                }
                                BEGIN S_IGNORE;   RETURN(CAPA_END);
                              }
{Space}*                      { /* ignore spaces */ }
[\)]                          { /* a right paren */ 
                                if ( (LexiProblem_p != NULL) &&
				     (LexiProblem_p->question != NULL) && 
				     (LexiProblem_p->ans_type == 0)) {
				  EndText_p=strsave(LexiProblem_p->question);
				} else {
				  EndText_p=NULL;
				}
                                BEGIN S_IGNORE;   
				RETURN(CAPA_END);  
                              }
}

<S_HINT,S_EXPLAIN>{
[/][Dd][Ii][Ss]{Space}*[\(]{Space}*  {  yy_push_state(S_HINTEXLAINX); }
[^/\n]+[/\\]                    { char  *aptr = yytext;
                                  yyless(yyleng-1);
				  send(aptr);
                                }
[/]                            { send("/"); }
[\\]                           { send("\\"); }
[\\]{Space}*[\n]               { LLDBUG_PR1("[\\CR hint explain continue]"); /* Hint and explain continuation */ send("\n\t");}
[^/\n\\]+$                     {char  *aptr = yytext;
                                send(aptr);
                               }
}
<S_HINT>{
{EndLine}                     {  LLDBUG_PR1("[CR hint]");
                                 send("\n"); 
                                 change_destination(DEFAULT_DEST);
                                 BEGIN S_TEXT;
                              }
}
<S_EXPLAIN>{
{EndLine}                     {  LLDBUG_PR1("[CR explain]");
                                 send("\n"); 
                                 change_destination(DEFAULT_DEST);
                                 BEGIN S_TEXT;
                              }
}

<S_HINTEXLAINX>{
{Alpha}{AlphaNum}*            {send("${%s}",yytext);}
{Space}+                      { }
[)]                           {  yy_pop_state(); }
}

<S_IMPORT>{
{FileName}{Space}*             {
                                 char *endquote;
                                 end_mode();
				 start_mode(MODE_IMPORT,NULL);
				 /* Get rid of leading and trailing quotes */
				 endquote = strrchr(yytext,'\"');
                                 *endquote = '\0';
                                 if (yytext[1] == '/') {
                                    send("%s%s",import_prefix,&yytext[1]);
                                 } else {
                                    send("%s",&yytext[1]);
                                 }
				 end_mode();
				 BEGIN S_SKIP;
                               }
{Identifier}{Space}*           { end_mode();
				 start_mode(MODE_IMPORT,NULL);
				 send("${%s}",yytext);
				 end_mode();
                                 BEGIN S_SKIP;
			       }
}

<S_ANSWER>{
[Pp][Ll][Uu][Ss]             { LLDBUG_PR1("[PLUS]"); add_delayed("+");}
[Mm][Ii][Nn][Uu][Ss]         { LLDBUG_PR1("[MINUS]"); add_delayed("-");}

[Cc][Ss]                     { LLDBUG_PR1("[CS]"); send("cs");}
[Cc][Ii]                     { LLDBUG_PR1("[CI]"); send("ci");}
[Mm][Cc]                     { LLDBUG_PR1("[MC]"); send("mc");}
[Ff][Mm][Ll]                 { LLDBUG_PR1("[FORMULA]"); send("fml"); }

[Oo][Nn]                     |
[Yy][Ee][Ss]                 { LLDBUG_PR1("[ON]"); send("on");}
[Oo][Ff][Ff]                 |
[Nn][Oo]                     { LLDBUG_PR1("[OFF]"); send("off");}
[Ff][Mm][Tt]                 { LLDBUG_PR1("[FMT]"); }
[Uu][Nn][Ff][Mm][Tt]         { LLDBUG_PR1("[UNFMT]"); }

[,=]                  { LLDBUG_PR2("[symbol(%s)]",yytext);}
[%]                  { LLDBUG_PR2("[symbol(%s)]",yytext); 
                       if (dosend==1) send("%s",yytext);
                       if (dosend==2) add_delayed("%%%s",yytext);
                     }
[:@#-]                  { LLDBUG_PR2("[symbol(%s)]",yytext); 
                          if (dosend==1) send("%s",yytext);
                          if (dosend==2) add_delayed("%s",yytext);
                        }
"<"                          { LLDBUG_PR2("[symbol(%s)]",yytext);
			       if (!EVALflag) {
                               if (dosend==1) send("%s",yytext);
                               if (dosend==2) add_delayed("%s",yytext);
                             }
                             }
">"                          { LLDBUG_PR2("[symbol(%s)]",yytext);
			       if (!EVALflag) {
                               if (dosend==1) send("%s",yytext);
                               if (dosend==2) add_delayed("%s",yytext);
                               } else {
				 EVALflag = 0;
			       }
                             }

[Pp][Cc][Rr]                 |
[Hh][Gg][Rr]                 { if (firstparam) {
				firstparam=0; 
			       } else {
				add_delayed("\" />\n\t");
			       }
                               add_delayed("<responseparam name=\"hgr\" type=\"on|off\" default=\""); 
                               dosend=2;
                             }
[Tt][Oo][Ll]                 { LLDBUG_PR2("[tol(%s)]",yytext);
                               if (firstparam) {
				 firstparam=0; 
			       } else {
				 add_delayed("\" />\n\t");
			       }
			       add_delayed("<responseparam name=\"tol\" type=\"tolerance\" description=\"Numerical Tolerance\" default=\""); 
                               dosend=2;
                             }
[Ss][Ii][Gg]                 { 
                               LLDBUG_PR2("[SIG(%s)]",yytext); 
                               if (firstparam) {
				 firstparam=0; 
			       } else {
				 add_delayed("\" />\n\t");
			       }
			       add_delayed("<responseparam name=\"sig\" type=\"int_range,0-12\" description=\"Significant Figures\" default=\""); 
                               dosend=2;
                             }

[Ss][Tt][Rr]                 { LLDBUG_PR1("[STR]"); send("\" type=\""); dosend=1; }
[Ee][Vv][Aa][Ll]             |
[Ee][Vv][Aa][Ll][Uu][Aa][Tt][Ee] { LLDBUG_PR1("[EVAL]");send("\" eval=\""); EVALflag=1; dosend=1;}
[Uu][Nn][Ii][Tt]             |
[Uu][Nn][Ii][Tt][Ss]         { LLDBUG_PR1("[UNIT]"); send("\" unit=\""); dosend=1;}

[Ee][Xx][Tt][Ee][Rr][Nn][Aa][Ll]  { LLDBUG_PR1("[EXTERNAL]"); dosend=0; }
[Aa][Nn][Ss][Bb][Oo][Xx]     { LLDBUG_PR1("[SHOW_ANS_BOX]"); dosend=0; }
[Vv][Ee][Rr][Bb][Aa][Tt][Ii][Mm] { LLDBUG_PR1("[VERBATIM]"); dosend=0; }
[Bb][Rr]                     { LLDBUG_PR1("[SHOW_BR]"); dosend=0; }
[Pp][Aa][Tt][Hh]             { send("\" path=\""); dosend=0; }
[Cc][Aa][Ll][Cc]             { send("\" calc=\""); dosend=0; }

[Ee][Xx][Pp][Ll][Aa][Ii][Nn] { LLDBUG_PR1("[EXPLAIN]"); dosend=0; }
[Hh][Ii][Nn][Tt]             { LLDBUG_PR1("[HINT]"); dosend=0; }
[Tt][Rr][Yy]                 |
[Tt][Rr][Ii][Ee][Ss]         { LLDBUG_PR1("[TRY]"); dosend=0; }
[Ww][Gg][Tt]                 { LLDBUG_PR1("[WGT]"); dosend=0; }

[\)]                         { LLDBUG_PR1("[)]"); Pcount--; 
                               if(Pcount==0) {
                                   BEGIN S_ANSCONTINUE; 
                               }
                               if (essay_answer) {
                                 send(">\n\t");
                               } else {
                               send("\">\n\t");
                               }
			       dosend=1;
			       flush_delayed();
			       if (firstparam!=1) send("\" />\n");
                               if (essay_answer) {
			         send("  <textfield>Enter your answer here.</textfield>\n");
                               } else {
			       send("\t<textline />\n");
                               }
                         /* Fill in Hints */ 
			       if ( !is_dest_empty(HINT_DEST) ) {
			         send("\t<hintgroup>\n\t<hintpart on=\"default\">\n\t<startouttext />");
                                 end_streams(HINT_DEST,0);
                                 HINTflag=0;
                                 send("\t<endouttext />\n\t</hintpart>\n\t</hintgroup>\n");
			       }
                               if (essay_answer) {
			         send("</essayresponse>\n");
                               } else {
			         send("</numericalresponse>\n");
			       }

                             }
}

<S_VARIABLE>{
{Alpha}{AlphaNum}*             { LLDBUG_PR2("[ID<%s>]",yytext);
                                 LLDBUG_PR2("[SYMB CNT=<%d>]", Symb_count); 
                                 if(Pcount <= 1) {
                                   if (dosend==1) send("${%s}",yytext); 
                                   if (dosend==2) add_delayed("${%s}",yytext); 
                                 } else {
                                   if (dosend==1) send("$%s",yytext); 
                                   if (dosend==2) add_delayed("$%s",yytext); 
                               }
                             }
}

<S_VARIABLE,S_TRUE_FALSE_STMT,S_LET,S_MAP,S_ANSWER>{
{Alpha}{AlphaNum}*             { LLDBUG_PR2("[ID<%s>]",yytext);
                                 LLDBUG_PR2("[SYMB CNT=<%d>]", Symb_count); 
                                 if (dosend==1) send("$%s",yytext); 
                                 if (dosend==2) add_delayed("$%s",yytext); 
                               }

{Alpha}{AlphaNum}*{Space}*[(]  { if (dosend==1) send("&%s",yytext);
                                 if (dosend==2) add_delayed("&%s",yytext);
				 Pcount++;
                               }
{Alpha}{AlphaNum}*{Space}*[\[]  {
                                   LLDBUG_PR2("[ARRAY<%s>]",yytext);
                                   yyless(yyleng-1); /*<-- push back char '[' */
                                   if (dosend==1) send("$%s",yytext); 
                                   if (dosend==2) add_delayed("$%s",yytext); 
                               }
{Number}*"\."{Number}*[Ee]"+"{Number}+ |
{Number}*"\."{Number}*[Ee]{Number}+    |
{Number}*"\."{Number}*[Ee]"-"{Number}+ |
{Number}+[Ee]"+"{Number}+ |
{Number}+[Ee]{Number}+    |
{Number}+[Ee]"-"{Number}+ |
{Number}+"\."{Number}*    |
"\."{Number}+             {  LLDBUG_PR2("[REAL<%s>]",yytext);
			     if(dosend==1) send("%s",yytext);
			     if(dosend==2) add_delayed("%s",yytext);
			  }

{Number}+                 {  LLDBUG_PR2("[INT<%s>]",yytext);
                             if (dosend==1) send("%s",yytext);
                             if (dosend==2) add_delayed("%s",yytext);
			  }
[\[]                      { LLDBUG_PR1("[dis let ans map '[']");
			    if(dosend==1) send("%s",yytext);
			    if(dosend==2) add_delayed("%s",yytext);
			  }
[\]]                      { LLDBUG_PR1("[dis let ans map ']']");
			    if(dosend==1) send("%s",yytext);
			    if(dosend==2) add_delayed("%s",yytext);
			  }
{Space}+                  { /* LLDBUG_PR1("[SP ignored]");  Ignore Spaces */ }
}

<S_VARIABLE,S_TRUE_FALSE_STMT,S_MAP,S_LET>{
[\"]                      { LLDBUG_PR1("[TF,V,LET,MAP str\" ]"); 
                            Current_char_p = String_buf; 
			    send("'");
                            yy_push_state(S_STRING);
                          }
}

<S_ANSWER>{
[\"]                      { LLDBUG_PR1("[ANS str\" ]"); 
                            Current_char_p = String_buf; 
                            yy_push_state(S_STRINGINANS);
                          }
}

<S_VARIABLE,S_TRUE_FALSE_STMT,S_MAP,S_ANSWER>{
[\(]                      { LLDBUG_PR1("[let if ans map (]"); 
                            Pcount++; 
			    if (Pcount > 1 ) {
			      if (dosend==1) send(yytext);
			      if (dosend==2) add_delayed(yytext);
			    } 
                          }
}

<S_LET>{
[\(]                      { LLDBUG_PR1("[let (]"); 
                            Pcount++; 
			    send(yytext);
                          }
}

<S_VARIABLE>[:]{Number}+[EeFf]   { 
                             end_delayed();
                             send("&format(");
                             flush_delayed();
                             send(",'%s')",yytext+1);
                           }
<S_ANSWER>[:]{Number}+[EeFf]   { 
                             if (dosend) send("\" format=\"%s",yytext+1);
                           }

<S_MAP>{
[;]   { 
        if (sccount==0) {
          send(",[\\");
          sccount++;
        } else if (sccount==1) {
          send("],[");
          sccount++;
        }
       }
[,]     {
        if (sccount==1) {
          send(",\\");
        } else {
          send(",");
        }
      }
[\)]  {
        LLDBUG_PR1("[) in MAP]"); Pcount--; 
        if(Pcount==0) {
          BEGIN S_SKIP; 
        }
        /* you might need a ; in the string below */
        send("]%c;\n",yytext[0]);
        sccount=0;
      }
}

<S_VARIABLE>{
"+"		    { send(".");}
}

<S_VARIABLE,S_TRUE_FALSE_STMT,S_LET,S_MAP>{
"=="                { LLDBUG_PR1("[==]"); send(" eq ");  }
"!="                { LLDBUG_PR1("[!=]"); send(" ne ");  }
">"                 { LLDBUG_PR1("[>]");  send(yytext);  }
">="                { LLDBUG_PR1("[>=]"); send(yytext);  }
"<"                 { LLDBUG_PR1("[<]");  send(yytext);  }
"<="                { LLDBUG_PR1("[<=]"); send(yytext);  }
"&&"                { LLDBUG_PR1("[&&]"); send(yytext);  }
"||"                { LLDBUG_PR1("[||]"); send(yytext);  }
"//"                { if(Pcount==0) {
			 send("; #");
			 BEGIN S_ECHO;
                      }
                    }
[%]                 {send("%%");}
{Operator}          { LLDBUG_PR2("[Op(%c) in VAR,TF_STMT,LET]",yytext[0]); send(yytext); }
}



<S_VARIABLE>{
[\)]                     { LLDBUG_PR1("[)]"); 
                           Pcount--; 
                           if(Pcount == 0) {
			      send("</display>");
                              BEGIN S_TEXT; 
                              flush_delayed();
                           } else {
                              send(yytext); 
                           }
                         }
[\\]{Space}*{EndLine}    { LLDBUG_PR2("[\\EoL continue in S_VARIABLE (DIS?)](%s)",yytext); /* continuation on next line */ }                       
{EndLine}                { LLDBUG_PR1("[EoL within /dis()]\n"); }
.                   { char warn_msg[WARN_MSG_LENGTH]; 
                      sprintf(warn_msg,"When use a VARIABLE, an unexpected char [%c] is encountered.\n",yytext[0]);
                      capa_msg(MESSAGE_ERROR,warn_msg);
                    }
}

<S_TRUE_FALSE_STMT>{
[\)]                     { 
                           LLDBUG_PRL1("[) in TRUE_FALSE]");
			   Pcount--; 
			   if(Pcount == 0)  {
				stop_cache();
				send_stream(0,"\">\n");
				send_stream(1,") {\n");
				BEGIN S_NEXT_LINE;
			   } else {
                                send_stream(0,")");
                                send_stream(1,")");
			   }
			 }
[\\]{Space}*{EndLine}    { 
			   LLDBUG_PR2("[\\EoL continue in S_TRUE_FALSE_STMT](%s)",yytext); /* continuation on next line */ 
			 }                       
{EndLine}                { 
			   LLDBUG_PR1("[EoL within /IF()]\n"); RETURN(EoL);
			 }
.                   { 
		      char warn_msg[WARN_MSG_LENGTH]; 
                      sprintf(warn_msg,"In /IF(), an unexpected char [%c] is encountered.\n",yytext[0]);
                      capa_msg(MESSAGE_ERROR,warn_msg);
                    }
}

<S_STRING>{
[\\][\\]            { /*char  *aptr = yytext;
			while( *aptr )   *Current_char_p++ = *aptr++;*/
                      send(yytext);
                    }
[\\][\"]            { /**Current_char_p++ = '"';*/ send("\\\"");  }
[\\]{Space}*[\n]    { LLDBUG_PR2("[\\CR continue in S_STRING](%s)",yytext); /* continuation on next line */ }                       
[\"]                { /* end of a string constant --   */
                      send("'");
		      yy_pop_state();
		    }
[%]                 { /*Escape percent signs so that vasprintf doesn't choke */
                      send("%%");
                    }
[\']                { /* Escape single quotes so that perl doesn't choke */
                      send("\\\'");
                    }
{EndLine}           { /* check for termination of string constant */
                      char warn_msg[WARN_MSG_LENGTH];
                      
                      sprintf(warn_msg,"STRING not terminated properly, an EoL encountered in the middle.\n%s\n",String_buf);
                      capa_msg(MESSAGE_ERROR,warn_msg);
                      yy_pop_state();
                    }
.                   { /*char  *aptr = yytext;
			while( *aptr )   *Current_char_p++ = *aptr++;*/
                      send(yytext);
                    }
}

<S_STRINGINANS>{
[\\][\\]            { /*char  *aptr = yytext;
			while( *aptr )   *Current_char_p++ = *aptr++;*/
                      if (dosend==1) send("%s",yytext);
		      if (dosend==2) add_delayed("%s",yytext);
                    }
[\\][\"]            { /**Current_char_p++ = '"';*/ 
                      if (dosend==1) send("%s",yytext);
		      if (dosend==2) add_delayed("%s",yytext);
                    }
[\\]{Space}*[\n]    { LLDBUG_PR2("[\\CR continue in S_STRING](%s)",yytext); /* continuation on next line */ }                       
[\"]                { /* end of a string constant --   */
		      yy_pop_state();
		    }
{EndLine}           { /* check for termination of string constant */
                      char warn_msg[WARN_MSG_LENGTH];
                      
                      sprintf(warn_msg,"STRING not terminated properly, an EoL encountered in the middle.\n%s\n",String_buf);
                      capa_msg(MESSAGE_ERROR,warn_msg);
                      yy_pop_state();
                    }
.                   { /*char  *aptr = yytext;
			while( *aptr )   *Current_char_p++ = *aptr++;*/
                      if (dosend==1) send("%s",yytext);
		      if (dosend==2) add_delayed("%s",yytext);
                    }
}

<S_LET>[\)]                  { LLDBUG_PR1("[) in LET]"); Pcount--;send(yytext); }

<S_SKIP>{
[^\n]+$                      {       }
{EndLine}                    { BEGIN S_TEXT; }
}

<S_ECHO>{
[^\n]+$                      { send(yytext); }
{EndLine}                    { send(yytext); BEGIN S_TEXT; }
}

<S_LET,S_ANSWER,S_MAP>{
[\\]{Space}*{EndLine}        { LLDBUG_PR1("[\\EoL let ans map]"); /* continuation */ }
{EndLine}                    { LLDBUG_PR1("[EoL END let ans map]\n"); 
                               if(Pcount == 0) BEGIN S_TEXT; 
                               send(";%s",yytext); 
                             }
}

<S_ANSCONTINUE>{
{Spaces}{EndLine}{Spaces}"/AND"  { LLDBUG_PR1("[AND]");
                                   compound_answer=-1;
                                   /* implicit in LON-CAPA */ }
{Spaces}{EndLine}{Spaces}"/OR"   { LLDBUG_PR1("[OR]"); 
                                   compound_answer=-1;
				   /*RETURN(ANS_OR); */ }
{Spaces}{EndLine}{Spaces}"/ANS" { LLDBUG_PRL2("[ANS(%s)]",yytext); 
                                Pcount = 0; 
                                BEGIN S_ANSWER; 
                                end_mode();
                                if (!compound_answer) {
			          if ( !is_dest_empty(EXP_DEST) ) {
			            send("<postanswerdate>\n\t<startouttext />\n");
                                    end_streams(EXP_DEST,0);
                                    EXPflag=0;
                                    send("\t<endouttext />\n</postanswerdate>\n");
                                    }
                                  send("</part>\n<part>\n"); 
                                }
				start_mode(MODE_ANSWER,NULL);
                                send("<numericalresponse answer=\""); 
				dosend=1;
				firstparam=1;
                                compound_answer=0;
                                essay_answer=0;
                                }
{Spaces}{EndLine}                { 
/* end of answer and/or other answers */
                           LLDBUG_PR1("[complete an answer<EoL>]"); 
			   if ( !is_dest_empty(EXP_DEST) ) {
			     send("<postanswerdate>\n\t<startouttext />\n");
                             end_streams(EXP_DEST,0);
                             EXPflag=0;
                             send("\t<endouttext />\n</postanswerdate>\n");
                           }
                           send("</part>\n<part>\n"); 
                           BEGIN S_TEXT; 
                         }
{Spaces}		{ /* Do nothing */ }
}

<S_NEXT_LINE>{
([.]*){EndLine}          { /* this ignores everything until it hits an EoL */
                           LLDBUG_PRL2("[<S_NEXT_LINE> skip \'%s\' until EoL]\n",yytext); 
                           BEGIN S_TEXT;
                         }
}

<S_WHILE_SKIP>{
^{Spaces}"/WHILE"[^\n]*{EndLine}        { Wcount++;
                                          LLDBUG_PRL2("[SkipWHILE /WHILE <Wcount=%d>]\n",Wcount);   
                                        }
^{Spaces}"/ENDWHILE"[^\n]*{EndLine}     { 
                                          if(Wcount==0) {
                                             LLDBUG_PRL2("[SkipWHILE->/ENDWHILE <Wcount=%d>]\n",Wcount);
                                             BEGIN S_TEXT;
                                          } else {
                                             Wcount--;
                                             LLDBUG_PRL2("[SkipWHILE /ENDWHILE <Wcount=%d>]\n",Wcount);
                                          }
                                        }
{EndLine}                { LLDBUG_PRL1("[SkipWHILE a CR]\n");       }                         
[^\n]*$                  { LLDBUG_PRL2("[SkipWHILE anything <Wcount=%d>]",Wcount);   }
}

<S_VERB>{
^{Spaces}"/ENDVERB" { LLDBUG_PRL1("[END VERB]\n"); 
		      BEGIN S_TEXT;
		      puts("\n</PRE>\n");
		      end_mode();
		    }
.*|{EndLine}         { send(yytext); }
}

%%

/* ========================================================================================== */

extern void
begin_while_skip() { Wcount=0; While_idx--; /* while is FALSE, pop it out from stack */ BEGIN S_WHILE_SKIP; }

extern void
begin_next_line()  { BEGIN S_NEXT_LINE; }

extern void
begin_var() { BEGIN S_VARIABLE; }

extern void
begin_let() { BEGIN S_LET; }

extern void
begin_def() { BEGIN S_DEFINE; }

extern void
begin_ans() { BEGIN S_ANSWER; }

extern void
begin_map() { BEGIN S_MAP; }

extern void
begin_ignore() { BEGIN S_IGNORE; }

extern void
begin_text() { BEGIN S_TEXT; }

extern void
begin_question() { LLDBUG_PR1("[<S_TEXT>]"); 
                   IFcount = 0; While_idx=0; /* initialize some stacks */
                   End_of_input = 0; YY_FLUSH_BUFFER; BEGIN S_TEXT; }

extern void
end_problemset() { End_of_input = 0; YY_FLUSH_BUFFER; BEGIN S_TEXT; }


/* ========================================================================================== */

#define  NUM_KEY   2
int
match_keyword(key) char *key;
{
  char  *keyword[NUM_KEY] = {"/DIS", "/DIR" };
  int    i;
  
  for(i=0;i < NUM_KEY; i++) {
     if( !strncmp(keyword[i], key, 4) ) {
        return (1);
     }
  }
  return (0);
}

int
match_functionid(key) char *key;
{
  char  *keyword[NUM_KEY] = {"/DIS", "/DIR" };
  int    i;
  
  for(i=0;i < NUM_KEY; i++) {
     if( !strncmp(keyword[i], key, 4) ) {
        return (1);
     }
  }
  return (0);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

void  init_funcstack() 
{  
 int ii;
 for(ii=0;ii<Func_idx;ii++) {
   capa_mfree(FuncStack[ii].s_name);
 }
 Func_idx = 0;  
}


/* -------------------------------------------------------------------------- */
/* GET THE NEXT CHARACTER OF THE SOURCE FILE                                  */
/* -------------------------------------------------------------------------- */

#ifdef  FLEX
int   capaL_input()
#else
int                        /* RETURNS: next character */
input()                    /* ARGUMENTS: (none)       */
#endif

{                          /* LOCAL VARIABLES:        */
  static  int startup=1;  /*    First call flag      */
  
  LLDBUG_PRL1("<<capaL_input() is called>>\n");
  if (!Lexi_line) { /* was startup */
       for(Input_idx=0;Input_idx < MAX_OPENED_FILE;Input_idx++) {
         /* for(ii=0;ii<LEX_BUFLEN;ii++) {
           Lexi_buf[Input_idx][ii]=0;
         }
         */
         Lexi_buf[Input_idx][0]=0;
         Lexi_pos[Input_idx] = 0;
       }
       Input_idx = 0;
       startup=0;
       yyin = Input_stream[Input_idx];
  }
  if (!Lexi_buf[Input_idx][Lexi_pos[Input_idx]]) {
    if (fgets(Lexi_buf[Input_idx],LEX_BUFLEN-1,Input_stream[Input_idx])==NULL) { 
      /* EOF? */
      /* no use in flex
         printf("capaL_input()EOF %s\n",Opened_filename[Input_idx+1]); fflush(stdout); */
      return (0);
    }
    Lexi_pos[Input_idx] = 0;
    Lexi_line++;
    printf("input()(%d)\n",Lexi_line);
  }
  (Lexi_pos[Input_idx])++;
  return ( Lexi_buf[Input_idx][Lexi_pos[Input_idx]-1] );
}
 
/******************************************************************************/
/* PUSH BACK ONE CHARACTER OF THE INPUT                                       */
/******************************************************************************/

int                /* RETURNS: nothing     */
capaL_unput(ch)          /* ARGUMENTS:           */
register int ch;   /*    Character to push */
{
   if (ch)   (Lexi_pos[Input_idx])--;
 
   /* unput() stream cannot be re-defined */
   /* unput(ch); inconsistency between YY_INPUT() and internal matched yytext */
   return (0);

}


/******************************************************/

#ifndef DMALLOC

char *       
strsave(char *s) 
{            
   char *p;  
   if (s==NULL) {return s;}
   p=capa_malloc(strlen(s)+1,1);
   strcpy(p,s);
   return (p);
}

#endif

/* =========================================================================== */

#ifndef DMALLOC
char *
capa_malloc(unsigned num,unsigned sz)
{
  char *p;
  p = calloc(num, sz);
  bzero(p, num*sz);  /* added Jan 21 1998 */
  return (p);
}

#endif

#ifndef DMALLOC
void
capa_mfree(p) char *p;
{
  free(p);
}
#endif

void
capa_msg(int type, char *p) 
{ int  idx, i, j;
  int  len;
  char warn_msg[WARN_MSG_LENGTH];
  char tmp_line[ONE_TWO_EIGHT];
  char  *tmp_str;
  
  strcpy(warn_msg,"File: ");
  idx=6;
  for(i=0;i<=Input_idx;i++) {
    len=strlen(Opened_filename[i]);
    for(j=0;j<len;j++) {
      warn_msg[idx++] = Opened_filename[i][j];
    }
    if(i < Input_idx) {
      warn_msg[idx++]='-';
      warn_msg[idx++]='>';
    }
    warn_msg[idx]=0;
  }
  switch (type) {
    case MESSAGE_ERROR:
           sprintf(tmp_line,", Line %d: ERROR:", Current_line[Input_idx]);
           len=strlen(tmp_line);
           for(j=0;j<len;j++) {
              warn_msg[idx++] = tmp_line[j];
           }
           warn_msg[idx]=0;
           append_error(warn_msg); append_error(p);
	   break;
    case MESSAGE_WARN:
    default:
           sprintf(tmp_line,", Line %d: WARNING:", Current_line[Input_idx]);
           len=strlen(tmp_line);
           for(j=0;j<len;j++) {
             warn_msg[idx++] = tmp_line[j];
           }
           warn_msg[idx]=0;
           j = strlen(warn_msg);
           len = strlen(p);
           tmp_str = (char *)capa_malloc(len+j+1,1);
           for(i=0;i<j;i++) {
             tmp_str[i]=warn_msg[i];
           } 
           for(i=j;i<j+len;i++) {
             tmp_str[i] = p[i-j];
           }
           append_warn(type,tmp_str);
           capa_mfree(tmp_str);
           break;
  }
}

/* ======================================================================== */
void
capa_warn_header(int type)
{
  int  idx, i, j;
  int  len;
  char warn_msg[WARN_MSG_LENGTH];
  char tmp_line[ONE_TWO_EIGHT];
  
  strcpy(warn_msg,"File: ");
  idx=6;
  for(i=0;i<=Input_idx;i++) {
    len=strlen(Opened_filename[i]);
    for(j=0;j<len;j++) {
      warn_msg[idx++] = Opened_filename[i][j];
    }
    if(i < Input_idx) {
      warn_msg[idx++]='-';
      warn_msg[idx++]='>';
    }
    warn_msg[idx]=0;
  }
  switch (type) {
    case MESSAGE_ERROR:
      sprintf(tmp_line,", Line %d: ERROR:", Current_line[Input_idx]);
      
      break;
    case MESSAGE_WARN:
      sprintf(tmp_line,", Line %d: WARNING:", Current_line[Input_idx]);break;
    default:
    sprintf(tmp_line,", Line %d: ERROR:", Current_line[Input_idx]);break;
  }
  len=strlen(tmp_line);
  for(j=0;j<len;j++) {
    warn_msg[idx++] = tmp_line[j];
  }
  warn_msg[idx]=0;
  append_error(warn_msg);
}

/* --------------------------------------------------------------------------- */
#ifdef AVOIDYYINPUT

void change_file(char *fname)
{
  char warn_msg[WARN_MSG_LENGTH];
  
  if ( include_stack_ptr >= MAX_INCLUDE_DEPTH ) {
    sprintf(warn_msg,"Includes nested too deeply" );
    capa_msg(MESSAGE_ERROR,warn_msg);
    return;
  }

  include_stack[include_stack_ptr++] = YY_CURRENT_BUFFER;
  yyin = fopen( fname, "r" );
  yy_switch_to_buffer( yy_create_buffer( yyin, YY_BUF_SIZE ) );
}

void
parse_filename(char *line)
{
  char *start, fname[MAX_BUFFER_SIZE],  warn_msg[WARN_MSG_LENGTH];
  int ii,len;

  start = index(line, '\"'); /*** hpux complained */
  if( start == NULL ) {
    sprintf(warn_msg,"/IMP was not given a filename.\n");
    capa_msg(MESSAGE_ERROR,warn_msg);
    return;
  }
  start++; len = strlen(start) - 1;
  ii = 0;
  while( start[ii] != '\"' ) fname[ii++] = start[ii];
  fname[ii] = 0;
  LLDBUG_PR2("[parse_filename<%s>]\n",fname);
  
  change_file(fname);
}

void
parse_import_id(char *line)
{
  char    fname[QUARTER_K], warn_msg[WARN_MSG_LENGTH];
  int     ii, dup_open;
  Symbol *symb_p;
  int     no_error = 0;
  
  ii = 0;
  while( line[ii] != '\0' && line[ii] != ' ' && line[ii] != '\n' && line[ii] != '\t' ) 
    fname[ii++] = line[ii]; 
  fname[ii] = 0;

  LLDBUG_PR2("[parse_import_id<%s>]\n",fname);
  /*symb_p = find_identifier(fname);*/
  
  switch (symb_p->s_type) {
   case IDENTIFIER:
     sprintf(warn_msg,"/IMP %s, var is not defined.\n", fname);
     capa_msg(MESSAGE_ERROR,warn_msg);
     break;
   case I_VAR: case I_CONSTANT: case R_VAR: case R_CONSTANT:
     sprintf(warn_msg,"var cannot be a number.\n");
     capa_msg(MESSAGE_ERROR,warn_msg);
     break;
   case S_VAR:  case S_CONSTANT: sprintf(fname,"%s",symb_p->s_str);
     no_error = 1;
     break;
  }
  if( no_error ) change_file(fname);
}

#else
void
parse_filename(char *line)
{
  char  *start, fname[QUARTER_K], warn_msg[WARN_MSG_LENGTH];
  int    ii, len, dup_open;
  
  /* printf("IMPORT %s\n", line); */
  
  start = index(line, '\"'); /*** hpux complained */
  if( start != NULL ) {
    start++; len = strlen(start) - 1;
    ii = 0;
    while( start[ii] != '\"' ) {
      fname[ii] = start[ii]; ii++;
    }
    fname[ii] = 0;
    LLDBUG_PR2("[parse_filename<%s>]\n",fname);
    if(Input_idx < (MAX_OPENED_FILE -1)) {
      dup_open = 0;
      /* -- no need to check duplicated opening a file 
      for(ii=0;ii<Input_idx;ii++) {
        if(strcmp(Opened_filename[ii],fname)==0) {
          dup_open =1;
        }
      }
      */
      if( !dup_open ) {
          Input_idx++;
          Input_stream[Input_idx]=fopen(fname,"r");
          sprintf(Opened_filename[Input_idx], "%s",fname);
          Current_line[Input_idx] = 0;
      } else {
        /*
          sprintf(warn_msg,"/IMP \"%s\", import file has already been imported.\n",fname);
          capa_msg(MESSAGE_WARN,warn_msg);
        */
          Input_idx++;
          Input_stream[Input_idx]=fopen(fname,"r");
          sprintf(Opened_filename[Input_idx], "%s",fname);
          Current_line[Input_idx] = 0;
      }
    } else {
      sprintf(warn_msg,"/IMP more the %d levels deep ignoring further imports.\n",MAX_OPENED_FILE-1);
      capa_msg(MESSAGE_WARN,warn_msg);
    }
  } else {
    sprintf(warn_msg,"%s, is not a valid file name.\n",line);
    capa_msg(MESSAGE_ERROR,warn_msg);
  }
  
}

void
parse_import_id(char *line)
{
  char    fname[QUARTER_K], warn_msg[WARN_MSG_LENGTH];
  int     ii, dup_open;
  Symbol *symb_p;
  int     no_error = 0;
  
    ii = 0;
    while (line[ii] != '\0' && line[ii] != ' ' && line[ii] != '\n' && line[ii] != '\t') {
      fname[ii] = line[ii]; ii++;
    }
    fname[ii] = 0;
    LLDBUG_PR2("[parse_import_id<%s>]\n",fname);
    /*symb_p = find_identifier(fname);*/
    
    switch (symb_p->s_type) {
      case IDENTIFIER:
	sprintf(warn_msg,"/IMP %s, var is not defined.\n", fname);
	capa_msg(MESSAGE_ERROR,warn_msg);
	break;
      case I_VAR: case I_CONSTANT: case R_VAR: case R_CONSTANT:
	sprintf(warn_msg,"var cannot be a number.\n");
	capa_msg(MESSAGE_ERROR,warn_msg);
	break;
      case S_VAR:
      case S_CONSTANT:
	sprintf(fname,"%s",symb_p->s_str);
	no_error = 1;
	break;
    }
    if( no_error ) {
      if(Input_idx < (MAX_OPENED_FILE -1) ) {
          dup_open = 0;
          /* no need to check duplicated opening a file 
          for(ii=0;ii<Input_idx;ii++) {
            if(strcmp(Opened_filename[ii],fname)==0)  dup_open =1; 
          }
          */
          if( !dup_open ) {
              Input_idx++;
              Input_stream[Input_idx]=fopen(fname,"r");
              sprintf(Opened_filename[Input_idx], "%s",fname);
              Current_line[Input_idx] = 0;
          } else {
            /*  NO warning on duplicated open a file
            sprintf(warn_msg,"/IMP \"%s\", file has already been imported.\n", fname);
            capa_msg(MESSAGE_WARN,warn_msg);
            */
              Input_idx++;
              Input_stream[Input_idx]=fopen(fname,"r");
              sprintf(Opened_filename[Input_idx], "%s",fname);
              Current_line[Input_idx] = 0;
          }
        } else {
          sprintf(warn_msg,"/IMP , too many files has been imported. The maximum is %d files.\n",
              MAX_OPENED_FILE-1);
          capa_msg(MESSAGE_WARN,warn_msg);
        }
      }
}
#endif /*AVOIDYYINPUT*/

void append_dynamic_buf(new_str) char *new_str;
{
  int ii,len;
  
  if(new_str==NULL) return;
  len=strlen(new_str);
#ifdef LEX_DBUG
  printf("before: len %d; Dynamic_buf_cur %d; Dynamic_buf_max %d\n",
	 len,Dynamic_buf_cur,Dynamic_buf_max);
#endif /* LEX_DBUG */    
  if (Dynamic_buf_cur+len+1>Dynamic_buf_max) {
    char *temp_text;
    Dynamic_buf_max=(Dynamic_buf_cur+len)*2;
    temp_text=(char*)capa_malloc(sizeof(char),Dynamic_buf_max);
    strncpy(temp_text,Dynamic_buf,Dynamic_buf_max);
    free(Dynamic_buf);
    Dynamic_buf=temp_text;
  }
  for(ii=0;ii<len;ii++) {
    Dynamic_buf[Dynamic_buf_cur+ii]=new_str[ii];
  }
  Dynamic_buf_cur += len;
  Dynamic_buf[Dynamic_buf_cur+1]='\0';
#ifdef LEX_DBUG
  printf("after: len %d; Dynamic_buf_cur %d; Dynamic_buf_max %d\n",
	 len,Dynamic_buf_cur,Dynamic_buf_max);
  printf("Dyn_buf %s; added %s\n",Dynamic_buf,new_str);
#endif /* LEX_DBUG */    
}

char* parser_status()
{
  char *buf,small[SMALL_LINE_BUFFER];
  int i,j,totlen=0,len,idx=0;
  
  for(i=0;i<=Input_idx;i++) totlen+=strlen(Opened_filename[i])+6;
  buf=capa_malloc(sizeof(char),totlen);
  for(i=0;i<=Input_idx;i++) {
    len=strlen(Opened_filename[i]);
    for(j=0;j<len;j++) buf[idx++] = Opened_filename[i][j];
    buf[idx++] = ':';
    sprintf(small,"%d",Current_line[i]);
    len=strlen(small);
    for(j=0;j<len;j++) buf[idx++] = small[j];
    buf[idx++]=' ';
    buf[idx]='\0';
  }
  return buf;
}

void yyfatalerror(char*msg)
{
  char    warn_msg[WARN_MSG_LENGTH];
  sprintf(warn_msg,"Invalid character[\'%s\']\n",yytext);
  capa_msg(MESSAGE_ERROR,warn_msg);
  capa_msg(MESSAGE_ERROR,msg);
}
void yyerror(char* msg)
{
  char    warn_msg[WARN_MSG_LENGTH];
  sprintf(warn_msg,"%s\n",msg);
  capa_msg(MESSAGE_ERROR,warn_msg);
}

void newyy_input (char *buf,int *result,int max_size) 
{ int ii, leng, out_of_char; 
 if (!Lexi_line) { /* was startup */ 
   for(ii=0;ii < MAX_OPENED_FILE;ii++) { 
     Lexi_buf[ii] = NULL; 
     Lexi_pos[ii] = 0; 
     Current_line[ii] = 0; 
   } 
   Input_idx = 0; 
   first_run=0; 
   yyin = Input_stream[Input_idx]; LIDBUG_PR1("<<yy_input() startup>>\n"); 
 } 
 out_of_char = 0; 
 if ( Lexi_buf[Input_idx] == NULL ) { 
   Lexi_buf[Input_idx] = (char *)capa_malloc(sizeof(char)*LEX_BUFLEN+1,1); out_of_char=1;
 } else { 
   if (!Lexi_buf[Input_idx][Lexi_pos[Input_idx]]) { 
     /* test if the line buffer is empty or at the end */ 
     out_of_char=1; 
   } 
 }
 if( out_of_char ) { 
   if (fgets(Lexi_buf[Input_idx],LEX_BUFLEN-1,Input_stream[Input_idx])==NULL) { 
     /* read in one line */ 
     LIDBUG_PR2("<<yy_input() fgets() returns NULL, input index=%d>>\n",Input_idx); 
     if( (Input_idx > 0) && ( Lexi_buf[Input_idx][Lexi_pos[Input_idx]] == '\0') ) { 
       LIDBUG_PR2("<<yy_input() close an input stream, input index=%d>>\n",Input_idx); 
       fclose(Input_stream[Input_idx]); 
       capa_mfree((char *)Lexi_buf[Input_idx]); 
       Lexi_buf[Input_idx] = NULL; 
       Input_idx--; 
       yyin = Input_stream[Input_idx]; 
       /* (Lexi_pos[Input_idx])++; */ 
       buf[0] = Lexi_buf[Input_idx][Lexi_pos[Input_idx]-1]; 
       *result = 1; 
     } else { 
       *result = YY_NULL; /* End of File */ 
     } 
   } else { /* successfully read in one line */ 
     leng = strlen(Lexi_buf[Input_idx]); 
     LIDBUG_PR3("<<yy_input() read into buffer a line(leng=%d), input index=%d>>\n",
		leng,Input_idx);  
     Lexi_pos[Input_idx] = 0; 
     Lexi_line++; 
     Current_line[Input_idx]++; 
     (Lexi_pos[Input_idx])++; 
     buf[0] = Lexi_buf[Input_idx][Lexi_pos[Input_idx]-1];  
     /* need to take care of return continuation conditions */ 
     /*  so, we return to one-char-at-a-time approach */ 
     /* for(ii=0;ii<leng;ii++) { */ 
     /*  buf[ii] = Lexi_buf[Input_idx][ii]; */ 
     /* } */ 
     /* buf[ii] = '\0'; */ 
     /* printf("YY_INPUT()(Lexi_line=%d,max size=%d)(%c)",Lexi_line,max_size,buf[0]); */ 
     *result = 1; 
   } 
 } else { 
   /* LIDBUG_PR2("<<yy_input() increase Lexi_pos, input index=%d>>\n",Input_idx);  */ 
   (Lexi_pos[Input_idx])++; 
   buf[0] = Lexi_buf[Input_idx][Lexi_pos[Input_idx]-1]; 
   *result = 1; 
 } 
 if (Stop_Parser==1) *result = YY_NULL;  
}

int capa_eof()
{
#ifdef AVOIDYYINPUT
  if ( --include_stack_ptr < 0 ) yyterminate();
  else {
    yy_delete_buffer( YY_CURRENT_BUFFER );
    yy_switch_to_buffer(include_stack[include_stack_ptr]);
  }
#else
  if(Input_idx == 0) {
    fclose(Input_stream[Input_idx]);
    capa_mfree((char *)Lexi_buf[Input_idx]); 
    /*free_problems(LexiProblem_p);*/
    LexiProblem_p=NULL;
    /* printf("\nCAPA EOF\n"); fflush(stdout); */
  }
  end_mode();
  return (0);
#endif /*AVOIDYYINPUT*/
}
/* ------------ */


/* =========================================================== */

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