File:  [LON-CAPA] / capa / capa51 / pProj / capaGrammarDef.y
Revision 1.15: download - view: text, annotated - select for diffs
Thu Sep 14 20:25:12 2000 UTC (23 years, 8 months ago) by albertel
Branches: MAIN
CVS tags: HEAD
- comment updates

    1: /* main CAPA parser
    2:    Copyright (C) 1992-2000 Michigan State University
    3: 
    4:    The CAPA system is free software; you can redistribute it and/or
    5:    modify it under the terms of the GNU General Public License as
    6:    published by the Free Software Foundation; either version 2 of the
    7:    License, or (at your option) any later version.
    8: 
    9:    The CAPA system is distributed in the hope that it will be useful,
   10:    but WITHOUT ANY WARRANTY; without even the implied warranty of
   11:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   12:    General Public License for more details.
   13: 
   14:    You should have received a copy of the GNU General Public
   15:    License along with the CAPA system; see the file COPYING.  If not,
   16:    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   17:    Boston, MA 02111-1307, USA.
   18: 
   19:    As a special exception, you have permission to link this program
   20:    with the TtH/TtM library and distribute executables, as long as you
   21:    follow the requirements of the GNU GPL in regard to all of the
   22:    software in the executable aside from TtH/TtM.
   23: */
   24: 
   25: /* ========================================================================== */
   26: /*            capaGrammarDef.y    created by Isaac Tsai                       */
   27: /*                                1998, 1999 by Isaac Tsai        */
   28: /* no longer there is a length constrain on string concatenation July 13 1998 */
   29: /* /RMAP() function */
   30: /* TODO: new mechanism to collect answer informations */
   31: /*****************************************************************************/
   32: /*****************************************************************************/
   33: /*****************************************************************************/
   34: %{
   35: #include <stdio.h>
   36: #include <ctype.h>
   37: #include <string.h>
   38: #include <math.h>
   39: #include "capaParser.h"   /* _symbol structure def */
   40: #include "capaCommon.h"
   41: #include "capaFunction.h"
   42: #include "capaRQO.h"
   43: #ifdef __hpux
   44: #include <stdlib.h>
   45: #include <alloca.h>
   46: #endif
   47: 
   48: #ifdef   YACC_DBUG
   49: #define  YYDBUG_PR1(xx)        { printf(xx);    fflush(stdout); }
   50: #define  YYDBUG_PR2(xx,yy)     { printf(xx,yy); fflush(stdout); }
   51: #define  YYDBUG_PR3(xx,yy,zz)  { printf(xx,yy,zz); fflush(stdout); }
   52: #define  YYDBUG_PR4(xx,yy,zz,aa)  { printf(xx,yy,zz,aa); fflush(stdout); }
   53: #define  YYDBUG_SYM(xx)        { switch((xx)->s_type) { \
   54:                                      case IDENTIFIER: \
   55:                                               printf("ID(%s)\n",(xx)->s_name);  break; \
   56:                                      case I_VAR:  case I_CONSTANT: \
   57:                                               printf("INT(%d)\n",(xx)->s_int);  break; \
   58:                                      case R_VAR:  case R_CONSTANT: \
   59:                                               printf("REAL(%.16g)\n",(xx)->s_real); break; \
   60:                                      case S_VAR:  case S_CONSTANT: \
   61:                                               printf("STR(%s)\n",(xx)->s_str); break; \
   62:                                } }
   63: #else  /* YACC_DBUG */
   64: #define  YYDBUG_PR1(xx)        { }
   65: #define  YYDBUG_PR2(xx,yy)     { }
   66: #define  YYDBUG_PR3(xx,yy,zz)  { }
   67: #define  YYDBUG_PR4(xx,yy,zz,aa)  { }
   68: #define  YYDBUG_SYM(xx)        { }
   69: #endif /* YACC_DBUG */
   70: 
   71: int   yylex();
   72: void  yyerror(char*);
   73: void  free_calc_expr(Symbol*);
   74: void assign_pts (Symbol *, Symbol *, Symbol *);
   75: /******************************************************************************/
   76: /* GLOBAL VARIABLES                                                           */
   77: /******************************************************************************/
   78: int                Lexi_qnum;
   79: 
   80: extern int         Lexi_line;
   81: extern int         Lexi_pos[MAX_OPENED_FILE];
   82: extern char        Opened_filename[MAX_OPENED_FILE][QUARTER_K];
   83: extern int         Input_idx;
   84: int                Current_line[MAX_OPENED_FILE];
   85: extern int         Func_idx;
   86: extern Symbol      FuncStack[MAX_FUNC_NEST];
   87: extern int         IFstatus[MAX_FUNC_NEST];
   88: extern int         IFcount;
   89: extern int         gUnitError;
   90: 
   91: int                Parsemode_f;    /* Parser mode flag */
   92: 
   93: Problem_t         *FirstProblem_p; /* First problem                    */
   94: Problem_t         *LastProblem_p;  /* Last problem                     */
   95: Problem_t         *LexiProblem_p;  /* Current problem                  */
   96: char              *EndText_p;
   97: char              *StartText_p;
   98: char              *ErrorMsg_p;
   99: int                ErrorMsg_count;
  100: WarnMsg_t         *WarnMsg_p;
  101: int                WarnMsg_count;
  102: int                Answer_infospec;
  103: void              (*Status_Func)();
  104: AnswerInfo_t       CurrAnsInfo;
  105: 
  106: RandQO_t          *QuestionOrder;
  107: PointsList_t      *CurrPtsList;
  108: PointsList_t      *LastPtsList;
  109: 
  110: 
  111: 
  112: 
  113: #ifdef  YYSTYPE
  114: #undef  YYSTYPE
  115: #endif
  116: #define YYSTYPE  Symbol_p
  117: 
  118: 
  119: #define ADD_op          1
  120: #define SUB_op          2
  121: #define MUL_op          3
  122: #define DIV_op          4
  123: #define IDIV_op         5
  124: #define NOT_DEFINED_op  9
  125: 
  126: /*#define  yyerror  printf*/
  127: 
  128: %}
  129: %token       NEW_ID
  130: %token       I_CONSTANT  R_CONSTANT     S_CONSTANT
  131: %token       I_VAR       R_VAR          S_VAR
  132: 
  133: %token       IDENTIFIER  FUNCTION_ID    ARRAY_ID
  134: %token       HINT_LINE   EXPLAIN_LINE   TEXT_LINE    IMPORT_LINE
  135: %token       CAPA_LET  CAPA_DEF  CAPA_DIS   CAPA_END   CAPA_VAR
  136: %token       CAPA_ESC  CAPA_MAP  CAPA_FIG   CAPA_ANS   CAPA_RMAP
  137: %token       CAPA_IF   CAPA_ELSE CAPA_ENDIF CAPA_SUBJ  CAPA_WHILE
  138: %token       CAPA_RQO  CAPA_ENDWHILE        CAPA_START 
  139: %token       ANS_AND         ANS_BOX_SHOW    ANS_CALC        ANS_CI          ANS_COMPARE       ANS_CS
  140: %token       ANS_EVAL        ANS_EXPLAIN     ANS_EXTERNAL    ANS_FMT
  141: %token       ANS_FORMULA     ANS_HINT        ANS_MC          ANS_MINUS
  142: %token       ANS_OFF         ANS_ON          ANS_OR          ANS_ORDERED
  143: %token       ANS_PATH        ANS_PCREDIT     ANS_PLUS        ANS_RANGE       
  144: %token       ANS_SHOW_BR     ANS_SIG         ANS_TOLERANCE   ANS_TRY         ANS_TYPE
  145: %token       ANS_UNFMT       ANS_UNIT        ANS_VERBATIM    ANS_WEIGHT 
  146: %token       VAR_RANGE       VERBATIM
  147: %token       SLASH           FORMAT
  148: %token       EQ_op  NE_op  GT_op  GE_op  LT_op  LE_op  AND_op  OR_op   EoL    
  149: 
  150: %start       prob_set
  151: 
  152: %%
  153: 
  154: prob_set     :  startQ  questions  CAPA_END  { YYDBUG_PR1(" prob_set := startQ questions END\n\n"); }
  155:              ;
  156: 
  157: questions    :  a_line                  { YYDBUG_PR1(" questions <= a_line");
  158:                                           if (Status_Func != NULL) Status_Func();
  159:                                         }
  160:              |  questions  a_line       { YYDBUG_PR1(" questions <= questions a_line");
  161:                                           if (Status_Func != NULL) Status_Func();
  162:                                         }
  163:              ;
  164:              
  165: startL       :  CAPA_LET                { YYDBUG_PR1("\n begin_let::"); } 
  166:              ;
  167:              
  168: startV       :  CAPA_VAR                { YYDBUG_PR1(" begin_var"); } 
  169:              ;
  170:              
  171: startA       :  CAPA_ANS                { YYDBUG_PR1("\n START ANSWER(/ANS)::\n"); 
  172:                                           init_answerinfo(); 
  173:                                         }
  174:              ;
  175: 
  176: startSA      :  CAPA_SUBJ               { YYDBUG_PR1("\n START SUBJECT ANSWER(/SUBJECTIVE)::\n");
  177:                                           init_answerinfo();
  178:                                         }
  179:              ;
  180:              
  181: startM       :  CAPA_MAP                { YYDBUG_PR1("\n begin_map::"); } 
  182:              ;
  183: 
  184: startR       :  CAPA_RMAP               { YYDBUG_PR1("\n begin_rmap::"); } 
  185:              ;
  186: 
  187: startRQO     :  CAPA_RQO                { YYDBUG_PR1("\n begin_rqo::"); } 
  188:              ;
  189: 
  190: ans_and_op   :  ANS_AND                 { add_answer_cnt(ANS_AND); YYDBUG_PR1("(AND ,new an answer info)"); }
  191:              ;
  192:              
  193: ans_or_op    :  ANS_OR                  { add_answer_cnt(ANS_OR); YYDBUG_PR1("(OR ,new an answer info)");  }
  194:              ;
  195: 
  196: a_line       :  startL  statement EoL   { YYDBUG_PR1(" a_line <= startL statement CR\n");  }
  197:              | CAPA_END                 { YYDBUG_PR1(" a_line <=  END\n\n"); }
  198:              |  startRQO rqo_def EoL     { YYDBUG_PR1(" aline <= CAPA_RQO\n");
  199:                                           rqo_finish();
  200:                                         }
  201:              |  CAPA_START              { YYDBUG_PR1(" aline <= CAPA_START\n");
  202: 					  start_question_over();
  203: 	                                }
  204:              |  HINT_LINE               { append_hint($1->s_str); 
  205:                                           YYDBUG_PR2(" a_line <= Hint_line(%s)\n",$1->s_str);
  206:                                           capa_mfree($1->s_str); capa_mfree((char *)$1);
  207:                                         }
  208:              |  EXPLAIN_LINE            { append_explain($1->s_str); 
  209:                                           YYDBUG_PR2(" a_line <= Explain_line(%s)\n",$1->s_str);
  210:                                           capa_mfree($1->s_str); capa_mfree((char*)$1);
  211:                                         }
  212:              |  IMPORT_LINE  EoL        { YYDBUG_PR1(" a_line <= import_line CR\n");  }
  213:              |  q_text EoL              { YYDBUG_PR1(" a_line <= Qtext CR\n"); append_text("\n");  }
  214:              |  answer_expr             { YYDBUG_PR1(" a_line <= answer_expr (init a new prob) CR\n"); 
  215:                                           init_new_prob(); }
  216:              |  if_expr                 { YYDBUG_PR1(" a_line <= if_expr\n");  }
  217:              |  while_expr              { YYDBUG_PR1(" a_line <= while_expr\n");  }
  218:              |  map_expr   EoL          { YYDBUG_PR1(" a_line <= map_expr CR\n");  }
  219:              |  EoL                     { YYDBUG_PR1(" a_line <= (CR)\n");  }
  220:              |  VERBATIM                { YYDBUG_PR1(" a_line <= (VERBATIM)\n");
  221: 	                                  switch(Parsemode_f) {
  222: 					  case TeX_MODE: append_text("\\begin{verbatim}");
  223: 					    break;
  224: 					  case HTML_MODE: append_text("<PRE>");
  225: 					    break;
  226: 					  }
  227:                                           append_text($1->s_str);
  228:                                           capa_mfree($1->s_str); capa_mfree((char *)$1);
  229: 	                                  switch(Parsemode_f) {
  230: 					  case TeX_MODE: append_text("\\end{verbatim}\n");
  231: 					    break;
  232: 					  case HTML_MODE: append_text("</PRE>\n");
  233: 					    break;
  234: 					  }
  235:                                         }
  236:              |  error EoL               { char  warn_msg[WARN_MSG_LENGTH]; 
  237:                                           YYDBUG_PR1(" a_line := ERROR(CR)\n");
  238:                                           sprintf(warn_msg," Question %d: Syntax error.\n", Lexi_qnum+1);
  239:                                           capa_msg(MESSAGE_ERROR,warn_msg); 
  240:                                           begin_text();
  241:                                         }
  242:              
  243:              ;
  244:              
  245: statement    :  IDENTIFIER '=' calc_expr 
  246:                                         { char  warn_msg[WARN_MSG_LENGTH];
  247:                                           
  248: 					if ( $1 != $3 ) { /* /LET a = a */
  249:                                           switch($1->s_type) {
  250:                                              case IDENTIFIER:
  251:                                              case I_VAR: case I_CONSTANT:
  252:                                              case R_VAR: case R_CONSTANT: break;
  253:                                              case S_VAR: case S_CONSTANT: /* free up original used spaces */
  254:                                                     capa_mfree($1->s_str); $1->s_str = NULL; break;
  255:                                              default:    break;
  256:                                           }
  257:                                           switch($3->s_type) {
  258:                                             case IDENTIFIER:
  259:                                                  sprintf(warn_msg,"var \"%s\" not defined before use.\n",$3->s_name);
  260:                                                  capa_msg(MESSAGE_ERROR,warn_msg);
  261:                                                  break;
  262:                                             case I_VAR:  case I_CONSTANT: 
  263:                                                  $1->s_type = I_VAR;
  264:                                                  $1->s_int = $3->s_int; 
  265:                                                  break;
  266:                                             case R_VAR:  case R_CONSTANT:
  267:                                                  $1->s_type = R_VAR;
  268:                                                  $1->s_real = $3->s_real; 
  269:                                                  break;
  270:                                             case S_VAR:  case S_CONSTANT:
  271:                                                  $1->s_type = S_VAR;
  272:                                                  $1->s_str = strsave($3->s_str);
  273:                                                  break;
  274:                                           }
  275:                                           YYDBUG_PR1(" statement <=    ID = calc_expr:: "); YYDBUG_SYM($3);
  276: 					  free_calc_expr($3);
  277: 					}
  278:                                         }
  279:              |  ARRAY_ID '[' calc_expr ']' '=' calc_expr
  280:                                         {    Symbol  *s_p;
  281:                                              char     warn_msg[WARN_MSG_LENGTH];
  282: 
  283: 					     s_p = get_array_symbol($1,$3,1);
  284:                                              switch(s_p->s_type) {
  285:                                                case IDENTIFIER:
  286:                                                case I_VAR: case I_CONSTANT:
  287:                                                case R_VAR: case R_CONSTANT: break;
  288:                                                case S_VAR: case S_CONSTANT: 
  289:                                                     capa_mfree(s_p->s_str); s_p->s_str = NULL; break;
  290:                                                default:    break;
  291:                                              }
  292:                                              switch($6->s_type) {
  293:                                                case IDENTIFIER:
  294:                                                  sprintf(warn_msg,"var \"%s\" not defined before use.\n",$6->s_name);
  295:                                                  capa_msg(MESSAGE_ERROR,warn_msg);
  296:                                                  break;
  297:                                                case I_VAR:  case I_CONSTANT: 
  298:                                                  s_p->s_type = I_VAR;
  299:                                                  s_p->s_int = $6->s_int;
  300:                                                  break;
  301:                                                case R_VAR:  case R_CONSTANT:
  302:                                                  s_p->s_type = R_VAR;
  303:                                                  s_p->s_real = $6->s_real; 
  304:                                                  break;
  305:                                                case S_VAR:  case S_CONSTANT:
  306:                                                  s_p->s_type = S_VAR;
  307:                                                  s_p->s_str = strsave($6->s_str);
  308:                                                  break;
  309:                                              }
  310:                                              free_calc_expr($6);
  311:                                         }
  312:              ;
  313: 
  314: rqo_def      :  rqo_speca             { rqo_1spec(); }
  315:              |  rqo_speca ',' rqo_def { rqo_2spec(); }
  316:              ;
  317: 
  318: rqo_speca    : an_integer                 {start_rqo_type(SINGLE);append_rqo($1);}
  319:              | an_integer '!'             {start_rqo_type(IMMOBILE);append_rqo($1);}
  320:              | an_integer '-' an_integer  {start_rqo_type(RANGE);append_rqo($1);
  321:                                            append_rqo($3);
  322:                                           }
  323:              | an_integer '~' rqo_specb   {prefix_rqo($1);}
  324:              | an_integer '+' rqo_specc   {prefix_rqo($1);}
  325:              ;
  326: 
  327: rqo_specb    : an_integer                 {start_rqo_type(ALL_MIX);append_rqo($1);}
  328:              | an_integer '~' rqo_specb   {prefix_rqo($1);}
  329:              | an_integer '+' an_integer  {start_rqo_type(LAST_FIXED);append_rqo($1);
  330:                                            append_rqo($3);}
  331:              ;
  332: 
  333: rqo_specc    : an_integer                 {start_rqo_type(ALL_FIXED);append_rqo($1);}
  334:              | an_integer '+' rqo_specd   {prefix_rqo($1);}
  335:              | an_integer '~' rqo_spece   {prefix_rqo($1);}
  336:              ;
  337: 
  338: rqo_specd    : an_integer                 {start_rqo_type(ALL_FIXED);append_rqo($1);}
  339:              | an_integer '+' rqo_specd   {prefix_rqo($1);}
  340:              ;
  341: 
  342: rqo_spece    : an_integer                 {start_rqo_type(FIRST_FIXED);append_rqo($1);}
  343:              | an_integer '~' rqo_spece   {prefix_rqo($1);}
  344:              | an_integer '+' an_integer  {start_rqo_type(BOTH_FIXED);append_rqo($1);
  345:                                            append_rqo($3);}
  346:              ;
  347: 
  348: 
  349: q_text       :  TEXT_LINE               { append_text($1->s_str);
  350:                                           capa_mfree($1->s_str); capa_mfree((char *)$1);
  351:                                         }
  352:              |  var_expr                {   }
  353:              |  q_text var_expr         {   }
  354:              |  q_text TEXT_LINE        { append_text($2->s_str); 
  355:                                           capa_mfree($2->s_str); capa_mfree((char *)$2);
  356:                                         }
  357:              ;
  358:              
  359: if_expr      :  CAPA_IF '(' calc_expr  ')'
  360:                                         { int leng=0; /* begin_next_line(); no use, can be get rid of */
  361:                                           YYDBUG_PR2("(IF expr <IFcount=%d>)\n",IFcount);
  362:                                           switch($3->s_type) {
  363:                                             case IDENTIFIER: 
  364:                                                    IFstatus[IFcount] = IF_FALSE;
  365:                                                    begin_next_line();
  366:                                                    break;
  367:                                             case I_CONSTANT: case I_VAR: 
  368:                                                    if(!$3->s_int) {
  369:                                                       IFstatus[IFcount] = IF_FALSE;
  370:                                                       begin_if_skip();
  371:                                                    } else {
  372:                                                       IFstatus[IFcount] = IF_TRUE;
  373:                                                       begin_next_line();
  374:                                                    } 
  375:                                                    break;
  376:                                             case R_CONSTANT: case R_VAR:
  377:                                                    if($3->s_real == 0.0) {
  378:                                                       IFstatus[IFcount] = IF_FALSE;
  379:                                                       begin_if_skip();
  380:                                                    }else{
  381:                                                       IFstatus[IFcount] = IF_TRUE;
  382:                                                       begin_next_line();
  383:                                                    }
  384:                                                    break;
  385:                                             case S_CONSTANT: 
  386: 					           if ( $3->s_str) {
  387: 						      leng = strlen($3->s_str);
  388:                                                       capa_mfree($3->s_str);
  389:                                                    } 
  390:                                                    if(leng == 0) {
  391:                                                       IFstatus[IFcount] = IF_FALSE;
  392:                                                       begin_if_skip();
  393:                                                    }else{
  394:                                                       IFstatus[IFcount] = IF_TRUE;
  395:                                                       begin_next_line();
  396:                                                    }
  397:                                                    break;
  398:                                             case S_VAR:
  399: 					           if ( $3->s_str) {
  400: 						      leng = strlen($3->s_str);
  401:                                                       capa_mfree($3->s_str);
  402:                                                    }
  403: 						   if(leng == 0) {
  404:                                                       IFstatus[IFcount] = IF_FALSE;
  405:                                                       begin_if_skip();
  406:                                                    }else{
  407:                                                       IFstatus[IFcount] = IF_TRUE;
  408:                                                       begin_next_line();
  409:                                                    }
  410:                                                    break;
  411:                                           }
  412: 					  capa_mfree((char*)$3);
  413:                                         }
  414:              ;
  415: 
  416: while_expr   :  CAPA_WHILE '(' calc_expr  ')'
  417:                                         {
  418:                                           int leng; 
  419:                                           YYDBUG_PR1("(WHILE expr)\n");
  420:                                           switch($3->s_type) {
  421:                                             case IDENTIFIER: /* undefined identifier regarded as false */
  422:                                                    begin_while_skip();
  423:                                                    break;
  424:                                             case I_CONSTANT: case I_VAR: 
  425:                                                    if(!$3->s_int) {
  426:                                                       begin_while_skip();
  427:                                                    } else {
  428:                                                       begin_next_line(); /* skip to EoL and begin S_TEXT */
  429:                                                    } 
  430:                                                    break;
  431:                                             case R_CONSTANT: case R_VAR:
  432:                                                    if($3->s_real == 0.0) {
  433:                                                       begin_while_skip();
  434:                                                    }else{
  435:                                                       begin_next_line(); /* skip to EoL and begin S_TEXT */
  436:                                                    }
  437:                                                    break;
  438:                                             case S_CONSTANT: 
  439:                                                    leng = strlen($3->s_str);
  440:                                                    capa_mfree($3->s_str);
  441:                                                    if(leng == 0) {
  442:                                                       begin_while_skip();
  443:                                                    }else{
  444:                                                       begin_next_line(); /* skip to EoL and begin S_TEXT */
  445:                                                    }
  446:                                                    break;
  447:                                             case S_VAR:
  448:                                                    leng = strlen($3->s_str);
  449:                                                    if(leng == 0) {
  450:                                                       begin_while_skip();
  451:                                                    }else{
  452:                                                       begin_next_line(); /* skip to EoL and begin S_TEXT */
  453:                                                    }
  454:                                                    break;
  455:                                           }
  456: 					  capa_mfree((char*)$3);
  457:                                         }
  458:              ;
  459: 
  460: var_expr     :  startV '(' formated_ans  ')'
  461:                                         { display_var( $3 ) ; }
  462:              ;
  463:              
  464: answer_expr  : answer_spec              { finish_answer_info(); 
  465:                                         }
  466:              | answer_expr ans_and_op  answer_spec
  467:                                         { finish_answer_info(); 
  468:                                           YYDBUG_PR1(" answer_expr <-- AND answers (copy answerinfo)\n"); }
  469:              | answer_expr ans_or_op   answer_spec
  470:                                         { finish_answer_info(); 
  471:                                           YYDBUG_PR1(" answer_expr <-- OR answers (copy answerinfo)\n"); 
  472: }             | startSA  '(' answer_info ')'
  473:                                         { YYDBUG_PR1("\n subjective answer\n");
  474: 					  finish_answer_info();
  475:                                           LexiProblem_p->ans_type = ANSWER_IS_SUBJECTIVE;
  476:                                         }
  477:              | startSA  '(' ')'
  478:                                         { YYDBUG_PR1("\n subjective answer\n");
  479: 					  finish_answer_info();
  480:                                           LexiProblem_p->ans_type = ANSWER_IS_SUBJECTIVE;
  481:                                         }
  482:              
  483:              ;
  484:              
  485: answer_spec  : startA '(' formated_ans  ')'
  486:                                         { assign_answer( $3 );
  487:                                           YYDBUG_PR1("\nASSIGN Answer\n");
  488:                                         }
  489:              | startA '(' formated_ans ',' answer_info ')'
  490:                                         { assign_answer( $3 );
  491:                                           YYDBUG_PR1("\nASSIGN Answers + Answer Info\n");
  492:                                         }
  493:              ;
  494: 	     
  495: answer_info  : ans_infospec
  496: 	     | answer_info ',' ans_infospec
  497: 	     ;
  498: 
  499: 
  500: ans_infospec : ANS_TOLERANCE '=' a_number
  501:                                        { YYDBUG_PR1(" ans_infospec:= TOL=a_number");
  502:                                          assign_tolerance(TOL_ABSOLUTE,$3);
  503:                                        }
  504:              | ANS_TOLERANCE '=' IDENTIFIER
  505:                                        { assign_tolerance(TOL_ABSOLUTE,$3);
  506:                                        }
  507:              | ANS_TOLERANCE '=' IDENTIFIER '%'
  508:                                        { assign_tolerance(TOL_PERCENTAGE,$3);
  509:                                        }
  510:              | ANS_TOLERANCE '=' a_number '%'
  511:                                        { assign_tolerance(TOL_PERCENTAGE,$3);
  512:                                        }
  513: 	     | ANS_COMPARE '=' answer_comp {       }
  514: 	     | ANS_SIG '='  answer_sig     {       }
  515: 	     | ANS_WEIGHT '=' an_integer
  516: 	                               {  assign_weight( $3 );
  517: 	                               }
  518: 	     | ANS_WEIGHT '=' IDENTIFIER
  519: 	                               {  assign_weight( $3 );
  520: 	                               }
  521: 	     | ANS_HINT '=' an_integer {  assign_hint( $3 );
  522: 	                               }
  523: 	     | ANS_HINT '=' IDENTIFIER {  assign_hint( $3 );
  524: 	                               }
  525: 	     | ANS_PCREDIT '=' ANS_ON  {  LexiProblem_p->partial_cdt = 1;
  526: 	                               }
  527: 	     | ANS_PCREDIT '=' ANS_OFF {  LexiProblem_p->partial_cdt = 0;
  528: 	                               }
  529: 	     | ANS_SHOW_BR '=' ANS_ON  {  LexiProblem_p->show_br = DO_SHOW;
  530: 	                               }
  531: 	     | ANS_SHOW_BR '=' ANS_OFF {  LexiProblem_p->show_br = DONOT_SHOW;
  532: 	                               }
  533: 	     | ANS_VERBATIM '=' ANS_ON  {  LexiProblem_p->verbatim = DO_VERBATIM;
  534: 	                                }
  535: 	     | ANS_VERBATIM '=' ANS_OFF {  LexiProblem_p->verbatim = DONOT_VERBATIM;
  536: 	                                }
  537: 	     | ANS_BOX_SHOW '=' ANS_ON {  LexiProblem_p->show_ans_box  = DO_SHOW;
  538: 	                               }
  539: 	     | ANS_BOX_SHOW '=' ANS_OFF {  LexiProblem_p->show_ans_box = DONOT_SHOW;
  540: 	                               }                          
  541: 	     | ANS_CALC '=' ANS_FMT    {  CurrAnsInfo.ans_calc = CALC_FORMATED;
  542: 	                               }
  543: 	     | ANS_CALC '=' ANS_UNFMT  {  CurrAnsInfo.ans_calc = CALC_UNFORMATED;
  544: 	                               } 
  545: 	     | ANS_TRY '=' an_integer  {  assign_try_limits( $3 );
  546: 	                               }
  547: 	     | ANS_TRY '=' IDENTIFIER  {  assign_try_limits( $3 );
  548: 	                               }
  549: 	     | ANS_UNIT '=' S_CONSTANT {  assign_units( $3 ); capa_mfree($3->s_str); capa_mfree((char *)$3);
  550: 	                               }
  551: 	     | ANS_UNIT '=' IDENTIFIER {  assign_units( $3 );
  552: 	                               }
  553: 	     | ANS_EVAL '=' var_range {  CurrAnsInfo.ans_pts_list = CurrPtsList; 
  554: 	                                 CurrPtsList=NULL; LastPtsList = NULL;  
  555: 	                               }
  556: 	     ;
  557: 
  558: 
  559: var_range    :  '<' S_CONSTANT '@'  pt_list  '>'     { assign_id_list( $2 ); 
  560:                                                        capa_mfree($2->s_str); 
  561:                                                        capa_mfree((char *)$2);
  562:                                                      }
  563:              |  '<' IDENTIFIER '@'  pt_list  '>'     { assign_id_list( $2 );  }
  564:              ;
  565: 
  566: pt_list      :   pt_list  ','  point_coord          { int idx;
  567:                                                       idx = LastPtsList->pts_idx; idx++;
  568:                                                       LastPtsList->pts_next = new_ptslist( $3 );
  569:                                                       LastPtsList = LastPtsList->pts_next;
  570:                                                       LastPtsList->pts_idx = idx;
  571:                                                       CurrPtsList->pts_idx = idx;
  572:                                                       if( $3->s_type == S_CONSTANT ) {
  573:                                                         capa_mfree($3->s_str); capa_mfree((char *)$3);
  574:                                                       }
  575:                                                     }
  576:              |   pt_list  ','  pt_range             { }
  577:              |   point_coord                        { CurrPtsList = new_ptslist( $1 );  
  578:                                                       LastPtsList = CurrPtsList;
  579:                                                       if( $1->s_type == S_CONSTANT ) {
  580:                                                         capa_mfree($1->s_str); capa_mfree((char *)$1);
  581:                                                       }
  582:                                                     }
  583:              |   pt_range                           { }
  584:              ;
  585: 
  586: pt_range     :   point_coord   ':'  point_coord  '#'  IDENTIFIER   
  587:                               { 
  588: 				assign_pts($1,$3,$5);
  589: 				/*PointsList_t *pt;
  590: 			        if( LastPtsList != NULL ) {
  591: 				  LastPtsList->pts_next = gen_ptslist( $1, $3, $5 );
  592: 				  pt = LastPtsList->pts_next;
  593: 				  while( pt->pts_next != NULL ) {
  594: 				    pt = pt->pts_next;
  595: 				  }
  596: 				  LastPtsList = pt;
  597: 				} else {
  598: 				  CurrPtsList = gen_ptslist( $1, $3, $5 );
  599: 				  LastPtsList = CurrPtsList;
  600: 				}
  601: 				if( $1->s_type == S_CONSTANT ) {
  602: 				  capa_mfree($1->s_str); capa_mfree((char *)$1);
  603: 				}
  604: 				if( $3->s_type == S_CONSTANT ) {
  605: 				  capa_mfree($3->s_str); capa_mfree((char *)$3);
  606: 				}
  607: 				*/
  608: 			      }
  609:              |   point_coord   ':'  point_coord  '#'  ARRAY_ID '[' calc_expr ']'
  610:                               { assign_pts($1,$3,get_array_symbol($5,$7,1)); }
  611:              |   point_coord   ':'  point_coord  '#'  a_number     
  612:                               { 
  613: 				assign_pts($1,$3,$5);
  614: 				/*PointsList_t *pt;
  615: 			      
  616: 				 if( LastPtsList != NULL ) {
  617: 				   LastPtsList->pts_next = gen_ptslist( $1, $3, $5 );
  618: 				   pt = LastPtsList->pts_next;
  619: 				   while( pt->pts_next != NULL ) {
  620: 				     pt = pt->pts_next;
  621: 				   }
  622: 				   LastPtsList = pt;
  623: 				 } else {
  624: 				   CurrPtsList = gen_ptslist( $1, $3, $5 );
  625: 				   LastPtsList = CurrPtsList;
  626: 				 }
  627: 				 if( $1->s_type == S_CONSTANT ) {
  628: 				   capa_mfree($1->s_str); capa_mfree((char *)$1);
  629: 				 }
  630: 				 if( $3->s_type == S_CONSTANT ) {
  631: 				   capa_mfree($3->s_str); capa_mfree((char *)$3);
  632: 				 }
  633: 				 if( $5->s_type == I_CONSTANT || $5->s_type == R_CONSTANT) {
  634: 				   capa_mfree((char *)$5);
  635: 				 }
  636: 				*/
  637: 			      }
  638:              ;
  639: 
  640: 
  641: point_coord  :   IDENTIFIER                 { $$ = $1;  }
  642:              |   ARRAY_ID '[' calc_expr ']' { $$ = get_array_symbol($1,$3,1); }
  643:              |   S_CONSTANT                 { $$ = $1;  }
  644:              ;
  645: 
  646: 
  647: 	     
  648: formated_ans : calc_expr               { $1->s_distype = DEFAULT_FORMAT;
  649:                                          $$ = $1;
  650:                                          $1->s_format = NULL;
  651:                                          YYDBUG_PR2(" formated_ans := calc_expr (type %d)",$1->s_type);
  652:                                        }
  653:              | calc_expr FORMAT        { $1->s_distype = $2->s_distype;
  654:                                          $1->s_format  = strsave($2->s_str); /* **** */
  655:                                          capa_mfree($2->s_str); capa_mfree((char *)$2);
  656:                                          $$ = $1;
  657:                                          YYDBUG_PR1(" formated_ans <= calc_expr FORMAT");
  658:                                        }
  659:              ;
  660:              
  661:              
  662: 
  663: answer_sig   : an_integer              { assign_sigs( $1->s_int,$1->s_int);
  664:                                          capa_mfree((char *)$1);
  665: 	                               }
  666:              | an_integer ANS_PLUS  an_integer
  667:                                        { assign_sigs($1->s_int,$1->s_int + $3->s_int);
  668:                                          capa_mfree((char *)$1);  capa_mfree((char *)$3);
  669: 	                               }
  670:              | an_integer ANS_MINUS an_integer
  671:                                        { assign_sigs($1->s_int - $3->s_int,$1->s_int);
  672:                                          capa_mfree((char *)$1);  capa_mfree((char *)$3);
  673: 	                               }
  674:              | an_integer ANS_PLUS  an_integer ANS_MINUS an_integer
  675:                                        { assign_sigs($1->s_int - $5->s_int,$1->s_int + $3->s_int);
  676:                                          capa_mfree((char *)$1);  capa_mfree((char *)$3); capa_mfree((char *)$5);
  677: 	                               }
  678: 	     | an_integer ANS_MINUS  an_integer ANS_PLUS an_integer
  679:                                        { assign_sigs($1->s_int - $3->s_int,$1->s_int + $5->s_int);
  680:                                          capa_mfree((char *)$1);  capa_mfree((char *)$3); capa_mfree((char *)$5);
  681: 	                               }
  682:              ;
  683:              
  684: answer_comp  : ANS_CS                  {  CurrAnsInfo.ans_type = ANSWER_IS_STRING_CS; }
  685:              | ANS_CI                  {  CurrAnsInfo.ans_type = ANSWER_IS_STRING_CI; }
  686:              | ANS_MC                  {  CurrAnsInfo.ans_type = ANSWER_IS_CHOICE;    }
  687:              | ANS_FORMULA             {  CurrAnsInfo.ans_type = ANSWER_IS_FORMULA;   }
  688:              | ANS_EXTERNAL            {  CurrAnsInfo.ans_type = ANSWER_IS_EXTERNAL;  }
  689:              ;
  690: 
  691: 
  692: map_expr     : startM '(' basic_constr ';' var_list ';' arg_list ')'
  693:                                       { char   key[SMALL_LINE_BUFFER];
  694:                                         char   warn_msg[WARN_MSG_LENGTH];
  695:                                         int    result=0;
  696: 
  697:                                         YYDBUG_PR1(" map_expr body executed\n");
  698:                                         sprintf(key,"%ld",$3->s_int);
  699:                                         if( $5->s_argc ==  $7->s_argc ) {
  700:                                           result=do_map(key, $5->s_argp, $7->s_argp, $5->s_argc, FORWARD_MAP);
  701: 					} else {
  702: 					  if ($5->s_argc==1) {
  703: 					    Symbol *a_sp;
  704: 					    a_sp=build_array_list($5,$7->s_argc);
  705: 					    result=do_map(key, a_sp->s_argp, $7->s_argp, a_sp->s_argc, FORWARD_MAP);
  706: 					    free_arglist(a_sp->s_argp);
  707: 					    a_sp->s_argp=NULL;
  708: 					  } else {
  709: 					    sprintf(warn_msg,"/MAP arg. counts are not matched.\n");
  710: 					    capa_msg(MESSAGE_ERROR,warn_msg);
  711: 					  }
  712:                                         }
  713: 					if (result!=0) {
  714: 					    sprintf(warn_msg,
  715: 						    "/MAP had invalid arguments.\n");
  716: 					    capa_msg(MESSAGE_ERROR,warn_msg);
  717: 					}
  718:                                         free_arglist($5->s_argp);
  719: 					$5->s_argp=NULL;
  720: 					free_arglist($7->s_argp);
  721: 					$7->s_argp=NULL;
  722:                                       }
  723:              | startR '(' basic_constr ';' var_list ';' arg_list ')'
  724:                                       { char   key[SMALL_LINE_BUFFER];
  725:                                         char   warn_msg[WARN_MSG_LENGTH];
  726: 					int    result=0;
  727: 
  728:                                         YYDBUG_PR1(" rmap_expr body executed\n");
  729:                                         sprintf(key,"%ld",$3->s_int);
  730:                                         if( $5->s_argc ==  $7->s_argc ) {
  731:                                           result=do_map(key, $5->s_argp, $7->s_argp, $5->s_argc, REVERSE_MAP);
  732:                                           
  733:                                         } else {
  734: 					  if ($5->s_argc==1) {
  735: 					    Symbol *a_sp;
  736: 					    a_sp=build_array_list($5,$7->s_argc);
  737: 					    result=do_map(key, a_sp->s_argp, $7->s_argp, a_sp->s_argc, FORWARD_MAP);
  738: 					    free_arglist(a_sp->s_argp);
  739: 					    a_sp->s_argp=NULL;
  740: 					  } else {
  741: 					    sprintf(warn_msg,"/RMAP arg. counts are not matched.\n");
  742: 					    capa_msg(MESSAGE_ERROR,warn_msg);
  743: 					  }
  744:                                         }
  745: 					if (result!=0) {
  746: 					    sprintf(warn_msg,
  747: 						    "/MAP had invalid arguments.\n");
  748: 					    capa_msg(MESSAGE_ERROR,warn_msg);
  749: 					}
  750:                                         free_arglist($5->s_argp);
  751: 					$5->s_argp=NULL;
  752:                                         free_arglist($7->s_argp);
  753: 					$7->s_argp=NULL;
  754:                                       }
  755:              ;
  756: 
  757: 
  758: 
  759: calc_expr    : calc_expr EQ_op  block  { $$ = symbols_op($1, $3, EQ_op);  }
  760:              | calc_expr NE_op  block  { $$ = symbols_op($1, $3, NE_op);  }
  761:              | calc_expr GE_op  block  { $$ = symbols_op($1, $3, GE_op);  }
  762:              | calc_expr GT_op  block  { $$ = symbols_op($1, $3, GT_op);  }
  763:              | calc_expr LE_op  block  { $$ = symbols_op($1, $3, LE_op);  }
  764:              | calc_expr LT_op  block  { $$ = symbols_op($1, $3, LT_op);  }
  765:              | calc_expr AND_op block  { $$ = symbols_op($1, $3, AND_op); }
  766:              | calc_expr OR_op  block  { $$ = symbols_op($1, $3, OR_op);  }
  767:              | block                   { $$ = $1; 
  768:                                          YYDBUG_PR1(" calc_expr <= block "); YYDBUG_SYM($1);   }
  769:              ;
  770: 
  771: block        : block '+' term          { $$ = symbols_op($1, $3, ADD_op); YYDBUG_PR1("block <= block '+' term "); YYDBUG_SYM($$); }
  772:              | block '-' term          { $$ = symbols_op($1, $3, SUB_op); }
  773:              | term                    { $$ = $1; YYDBUG_PR2(" block <= term YYSTATE(%d) ",yystate); YYDBUG_SYM($1);   }
  774:              ;
  775: 
  776: term         : term '*' basic_constr   { $$ = symbols_op($1, $3, MUL_op); }
  777:              | term '/' basic_constr   { $$ = symbols_op($1, $3, DIV_op); }
  778:              | term '%' basic_constr   { $$ = symbols_op($1, $3, IDIV_op); }
  779:              | basic_constr            { $$ = $1; 
  780:                                          YYDBUG_PR1(" term <= basic_constr "); YYDBUG_SYM($1);   }
  781:              ;
  782: 
  783: basic_constr : FUNCTION_ID '('  ')'   {  int tmp;
  784:                                          
  785:                                          Func_idx--;
  786:                                          if(Func_idx >= 0 ) {
  787:                                            tmp = match_function(FuncStack[Func_idx].s_name,0);
  788:                                            $$ = do_function(tmp, 0, NULL );
  789:                                            capa_mfree(FuncStack[Func_idx].s_name);
  790:                                          }
  791:                                          
  792:                                       }
  793:              | FUNCTION_ID '(' arg_list ')'
  794:                                       {  int  tmp;
  795:                                       
  796:                                          Func_idx--;
  797:                                          YYDBUG_PR4(" basic_constr <= FUNCTION<%s><argc=%d> YYSTATE(%d) ",
  798:                                              FuncStack[Func_idx].s_name,$3->s_argc,yystate);
  799:                                          
  800:                                          if(Func_idx >= 0 ) {
  801:                                            tmp = match_function(FuncStack[Func_idx].s_name,$3->s_argc);
  802: 					   $$ = do_function(tmp, $3->s_argc, $3->s_argp);
  803: 					   capa_mfree(FuncStack[Func_idx].s_name);
  804: 					   free_arglist($3->s_argp);
  805: 					   $3->s_argp=NULL;
  806:                                          }
  807:                                          YYDBUG_PR1(" basic_constr <= RETURN FUNCT "); YYDBUG_SYM($$);
  808:                                          
  809:                                       }
  810:              | an_array               {   $$ = $1;   }                         
  811:              | IDENTIFIER             { /* do not free identifier */ 
  812:                                           $$ = $1;
  813:                                       }
  814:              | '-' basic_constr       { $$ = $2;
  815:                                           switch($2->s_type) {
  816:                                             case I_VAR:      $$ = (Symbol *)capa_malloc(sizeof(Symbol),1);
  817:                                                              $$->s_type = I_CONSTANT;
  818:                                             case I_CONSTANT: $$->s_int =    - $2->s_int; break;
  819:                                             case R_VAR: $$ = (Symbol *)capa_malloc(sizeof(Symbol),1);
  820:                                                         $$->s_type = R_CONSTANT;
  821:                                             case R_CONSTANT: $$->s_real =   (-1.0)*($2->s_real); 
  822:                                                              break;
  823:                                             case S_VAR:
  824:                                             case S_CONSTANT: break;
  825:                                             default:         break;
  826:                                           }
  827:                                         }
  828:              | '+' basic_constr         { $$ = $2; }
  829:              | S_CONSTANT               { $$ = $1; }
  830:              | a_number                 { $$ = $1; }
  831:              | '(' calc_expr ')'        { $$ = $2; }
  832:              ;
  833: 
  834: arg_list     : arg_list ',' calc_expr   { $$ = $1;
  835:                                           $$->s_argc++;
  836:                                           $$->s_argp = addto_arglist($1->s_argp, $3); 
  837:                                         }
  838:              | calc_expr                { $$ = $1;
  839:                                           $$->s_argc = 1;
  840:                                           $$->s_argp = new_arglist($1);
  841:                                         }
  842:              ;
  843: 
  844: 
  845: var_list     : IDENTIFIER               { /* do not free identifier */
  846:                                           YYDBUG_PR1(" var_list <= ID");
  847:                                           $$ = $1;
  848:                                           $$->s_argc = 1;
  849:                                           $$->s_argp = new_arglist($1);
  850:                                         }
  851:              | ARRAY_ID '[' calc_expr ']'{
  852:                                           YYDBUG_PR1(" var_list <= ARRAYID,calc");
  853:                                           $$ = get_array_symbol($1,$3,1);
  854:                                           $$->s_argc = 1;
  855:                                           $$->s_argp = new_arglist($$);
  856: 	                                 }
  857:              | var_list ',' ARRAY_ID '[' calc_expr ']' {
  858:                                           YYDBUG_PR1(" var_list <= var_list,ARRAYID,calc");
  859: 	                                  $$ = $1;
  860: 					  $$->s_argc++;
  861: 					  $$->s_argp = addto_arglist($1->s_argp, 
  862: 							    get_array_symbol($3,$5,1));
  863:                                         }
  864:              | var_list ',' IDENTIFIER  { /* do not free identifier */
  865:                                           YYDBUG_PR1(" var_list <= var_list,ID");
  866:                                           $$ = $1;
  867:                                           $$->s_argc++;
  868:                                           $$->s_argp = addto_arglist($1->s_argp, $3); 
  869:                                         }
  870:              ;
  871: 
  872: 
  873: a_number     : an_integer               { $$ = $1; }
  874:              | a_real                   { $$ = $1; }
  875:              ;
  876:              
  877: an_integer   : I_CONSTANT               { $$ = $1; }
  878:              ;
  879:              
  880: a_real       : R_CONSTANT               { $$ = $1; } 
  881:              ;
  882: 
  883: an_array     : ARRAY_ID '[' calc_expr ']'     {   
  884:                                          YYDBUG_PR1(" an_array <= ARRAY_ID '['calc_expr ']' ");
  885:                                          $$=get_array_symbol($1,$3,1);   
  886:                                                } 
  887:              ;
  888: 
  889: startQ       :                  { /* first matching will occur before first line of input text */
  890:                                   YYDBUG_PR1(" startQ := begin_question\n");
  891:                                   begin_question(); Answer_infospec = 0; 
  892:                                 }
  893:              ;
  894: 
  895: 
  896: 
  897: %%
  898: /* ============================================================================  */
  899: ExpNode_p
  900: mk_node(op, left, right) int op; ExpNode_p left; ExpNode_p right;
  901: { 
  902:   ExpNode     *np;
  903:   
  904:   np = (ExpNode* )malloc(sizeof(ExpNode));
  905:   np->e_type       = op;
  906:   np->e_lsibp      = left;
  907:   np->e_rsibp      = right;
  908:   left->e_parentp  = np;
  909:   right->e_parentp = np;
  910:   return (np);
  911: }
  912: 
  913: ExpNode_p
  914: mk_leaf(type, valp) int type; Symbol_p valp;
  915: {
  916:   ExpNode     *np;
  917:   
  918:   np = (ExpNode*)malloc(sizeof(ExpNode));
  919:   np->e_type = IDENTIFIER;
  920:   np->e_sp = valp;
  921:   return (np);
  922:   
  923: }
  924: 
  925: /* ------------------------------------------------------------- */
  926: void free_calc_expr(Symbol *expr)
  927: {
  928:   switch(expr->s_type) {
  929:   case I_CONSTANT:
  930:   case R_CONSTANT: capa_mfree((char *)expr); break;
  931:   case S_CONSTANT: capa_mfree(expr->s_str); capa_mfree((char *)expr); break;
  932:   default: break;
  933:   }
  934: }
  935: 
  936: /* this is the entry point to array symbol retrieval */
  937: /* array main name and index are  used to locate the symbol */
  938: /* name of the array is used to retrieve the array symbol */
  939: 
  940: Symbol* get_array_symbol ( name,index,free_symbols ) 
  941: Symbol *name,*index;int free_symbols;
  942: {
  943:   Symbol  *s_p, *a_p;
  944:   char    *key, *tmp;
  945:   int      leng, idx_len;
  946:   leng = strlen(name->s_name)+8; /* [ ] */
  947:   
  948:   switch(index->s_type) {
  949:     case I_VAR:
  950:     case I_CONSTANT: tmp = (char *)capa_malloc(64,1);
  951:       sprintf(tmp,"%ld",index->s_int);
  952:       break;
  953:     case R_VAR: 
  954:     case R_CONSTANT: tmp = (char *)capa_malloc(64,1);
  955:       sprintf(tmp,"%g",index->s_real);
  956:       break;
  957:     case S_VAR:
  958:     case S_CONSTANT: idx_len = strlen(index->s_str); tmp = (char *)capa_malloc(idx_len+4,1);
  959:       sprintf(tmp,"\"%s\"",index->s_str); /* string array index is a bit different from integer one */
  960:       break;
  961:     default:         break;
  962:   }
  963:   idx_len = strlen(tmp);
  964:   
  965:   key = (char *)capa_malloc(idx_len+leng,1);
  966:   sprintf(key,"%s[%s]",name->s_name,tmp);
  967:   
  968:   a_p = find_arrayid(name->s_name);   /* use the array name to search array tree */
  969:                                       /* did not check for error! */
  970:   s_p = find_array_by_index(a_p,key); /* use the index portion to search along array linked list */
  971:   capa_mfree((char *)tmp); capa_mfree((char *)key);
  972:   
  973:   if (free_symbols) { /* free both the name symbol and index symbol */
  974:     if( (index->s_type == I_CONSTANT) || (index->s_type == R_CONSTANT) ) 
  975:       capa_mfree((char *)index);
  976:     if(index->s_type == S_CONSTANT) {
  977:       capa_mfree(index->s_str); capa_mfree((char *)index); 
  978:     }
  979:     capa_mfree(name->s_name);  capa_mfree((char *)name);
  980:   }
  981:   return (s_p);
  982: }
  983: 
  984: Symbol * build_array_list(ar_name,num_elem)
  985: Symbol *ar_name;int num_elem;
  986: {
  987:   int     i;
  988:   Symbol *arg_list,*a_p;
  989:   char    idx_str[MAX_BUFFER_SIZE];
  990:   
  991:   a_p = find_arrayid(ar_name->s_name);
  992:   i = 1;
  993:   sprintf(idx_str,"%s[%d]",ar_name->s_name,i); /* create array elements with integer index */
  994:   arg_list = find_array_by_index(a_p,idx_str); /* will create a new element if not found */
  995:   arg_list->s_argc=1;
  996:   arg_list->s_argp=new_arglist(arg_list);
  997:   
  998:   for (i=2;i<=num_elem;i++) {
  999:       sprintf(idx_str,"%s[%d]",ar_name->s_name,i);
 1000:       arg_list->s_argc++;
 1001:       arg_list->s_argp=addto_arglist(arg_list->s_argp,find_array_by_index(a_p,idx_str));
 1002:   }
 1003:   return arg_list;
 1004: }
 1005: 
 1006: 
 1007: 
 1008: 
 1009: 
 1010: 
 1011: 
 1012: /* ------------------------------------------------------------- */
 1013: void        
 1014: append_text(str) char *str;  
 1015: {            
 1016:   char *q;  
 1017:   int   i;  
 1018:  
 1019:   if (!LexiProblem_p->question) {
 1020:       if (!(q = capa_malloc(strlen(str)+1,1)))  printf("No room to append.");
 1021:       strncpy(q,str,strlen(str)+1);
 1022:   } else {
 1023:       i =  strlen(LexiProblem_p->question);
 1024:       i += (strlen(str)+1);
 1025:       q =  capa_malloc(i,1);  /* *** */
 1026:       if (!q)  printf("No room to append().");
 1027:       strcat(strncpy(q,LexiProblem_p->question, strlen(LexiProblem_p->question)+1), str);
 1028:       capa_mfree(LexiProblem_p->question);
 1029:   }
 1030:   LexiProblem_p->question=q;
 1031: }
 1032:  
 1033: /******************************************************************************/
 1034: /* ADD A STRING TO THE CURRENT HINT TEXT BLOCK                                */
 1035: /******************************************************************************/
 1036: void             /* RETURNS: nothing */
 1037: append_hint(str) /* ARGUMENTS:       */
 1038: char *str;       /*    String to add */
 1039: {                /* LOCAL VARIABLES: */
 1040:    char *q;      /*    New string    */
 1041:  
 1042:    if (!LexiProblem_p->hint) {
 1043:       if (!(q = capa_malloc(strlen(str)+1,1)))
 1044:          printf("no room");
 1045:       strncpy(q,str,strlen(str)+1);
 1046:    } else {
 1047:       if (!(q = capa_malloc(strlen(LexiProblem_p->hint)+strlen(str)+1,1)))
 1048:          printf("no room");
 1049:       strcat(strncpy(q,LexiProblem_p->hint,strlen(LexiProblem_p->hint)), str);
 1050:       capa_mfree(LexiProblem_p->hint);
 1051:    }
 1052:    LexiProblem_p->hint=q;
 1053:    /* printf("APPEND HINT: %s\n", str); */
 1054: }
 1055: /******************************************************************************/
 1056: /* ADD A STRING TO THE CURRENT EXPLAIN TEXT BLOCK                                */
 1057: /******************************************************************************/
 1058: void             /* RETURNS: nothing */
 1059: append_explain(str) /* ARGUMENTS:       */
 1060: char *str;       /*    String to add */
 1061: {                /* LOCAL VARIABLES: */
 1062:    char *q;      /*    New string    */
 1063:  
 1064:    if (!LexiProblem_p->explain) {
 1065:       if (!(q = capa_malloc(strlen(str)+1,1)))
 1066:          printf("no room");
 1067:       strncpy(q,str, strlen(str)+1);
 1068:    } else {
 1069:       if (!(q = capa_malloc(strlen(LexiProblem_p->explain)+strlen(str)+1,1)))
 1070:          printf("no room");
 1071:       strcat(strncpy(q,LexiProblem_p->explain,strlen(LexiProblem_p->explain)+1), str);
 1072:       capa_mfree(LexiProblem_p->explain);
 1073:    }
 1074:    LexiProblem_p->explain=q;
 1075:    /* printf("APPEND EXPLAIN: %s\n", str); */
 1076: }
 1077: 
 1078: void        
 1079: append_error(str) char *str;  
 1080: {            
 1081:   char *q;  
 1082:   int   i;  
 1083: 
 1084:   ErrorMsg_count++;
 1085:   if (!ErrorMsg_p) {
 1086:       if (!(q = capa_malloc(strlen(str)+1,1)))  printf("No room in append.");
 1087:       strncpy(q,str,strlen(str)+1);
 1088:   } else {
 1089:       i =  strlen(ErrorMsg_p);
 1090:       i += (strlen(str)+1);
 1091:       q =  capa_malloc(i,1);  /* *** */
 1092:       if (!q)  printf("No room in append()");
 1093:       strcat(strncpy(q,ErrorMsg_p, strlen(ErrorMsg_p)+1), str);
 1094:       capa_mfree(ErrorMsg_p);
 1095:   }
 1096:   ErrorMsg_p=q;
 1097:   /* printf("APPEND ERROR: %s\n", str); */
 1098: }
 1099: void        
 1100: append_warn(type,str) int type;char *str;  
 1101: {            
 1102:   WarnMsg_t  *p, *t;
 1103:   char       *q;  
 1104: 
 1105:   WarnMsg_count++;
 1106:   if (!WarnMsg_p) {
 1107:       if (!(p = (WarnMsg_t *)capa_malloc(sizeof(WarnMsg_t),1)))  printf("No room in create WarnMsg_t.");
 1108:       if (!(q = capa_malloc(strlen(str)+1,1)))      printf("No room in allocating space for warn msg.");
 1109:       strncpy(q,str,strlen(str)+1);
 1110:       p->warn_next = NULL;
 1111:       p->warn_type = type;
 1112:       p->warn_str = q;
 1113:       WarnMsg_p=p;
 1114:   } else {
 1115:       for(t=WarnMsg_p;t->warn_next;t=t->warn_next) {   } /* do nothing within for loop */
 1116:       if (!(p = (WarnMsg_t *)capa_malloc(sizeof(WarnMsg_t),1)))  printf("No room in create WarnMsg_t.");
 1117:       if (!(q = capa_malloc(strlen(str)+1,1)))      printf("No room in allocating space for warn msg.");
 1118:       strncpy(q,str,strlen(str)+1);
 1119:       p->warn_next = NULL;
 1120:       p->warn_type = type;
 1121:       p->warn_str = q;
 1122:       t->warn_next = p;
 1123:   }
 1124: }
 1125: 
 1126: /*****************************************************************************/
 1127: /*********** if *b is a constant symbol, destroy (free) b ********************/
 1128: /*********** if *a is a var symbol, create a new symbol **********************/
 1129: /*                 do not free(*a)     */
 1130: /*  If either a or b is invalid it propagates the error up the parse tree    */
 1131: Symbol *
 1132: symbols_op(a, b, op) Symbol *a; Symbol *b; int op;
 1133: {
 1134:   int     type,  new, leng;
 1135:   long    tmp_i, tmp_j;
 1136:   double  tmp_p, tmp_q;
 1137:   char    a_str[QUARTER_K], *b_str=NULL, *r_strp;
 1138:   char    warn_msg[ONE_K];
 1139:   Symbol *a_symp;
 1140:   
 1141: if( a->s_type == IDENTIFIER || b->s_type == IDENTIFIER ) {
 1142:    if(a->s_type == IDENTIFIER) { /* a is IDENTIFIER */
 1143:      sprintf(warn_msg,"var \"%s\" not defined before use.\n", a->s_name);
 1144:      capa_msg(MESSAGE_ERROR,warn_msg);
 1145:      return (a);
 1146:    } else { /* b is IDENTIFIER */
 1147:      sprintf(warn_msg,"var \"%s\" not defined before use.\n",b->s_name);
 1148:      capa_msg(MESSAGE_ERROR,warn_msg);
 1149:      return (b);
 1150:    }
 1151:  } else {  /* a and b are neither identifiers */
 1152:   if( (a->s_type == I_VAR) ||
 1153:       (a->s_type == R_VAR) ||
 1154:       (a->s_type == S_VAR) )  {
 1155:         a_symp = (Symbol *)capa_malloc(sizeof(Symbol),1);  /* *** */
 1156:         new = 1;
 1157:   } else {
 1158:         new = 0;
 1159:         a_symp = a; /* re-use symbol *a */
 1160:   }
 1161:   if( ((a->s_type == I_CONSTANT)||(a->s_type == I_VAR)) && 
 1162:       ((b->s_type == I_CONSTANT)||(b->s_type == I_VAR)) ) { /* both a and b are integer */
 1163:     type = I_CONSTANT;
 1164:     switch( op ) {
 1165:       case ADD_op: a_symp->s_int = a->s_int +  b->s_int ; break;
 1166:       case SUB_op: a_symp->s_int = a->s_int -  b->s_int ; break;
 1167:       case MUL_op: a_symp->s_int = a->s_int *  b->s_int ; break;
 1168:       case DIV_op: if(b->s_int != 0) {
 1169:                      a_symp->s_int = a->s_int /  b->s_int ; 
 1170:                    } else {
 1171:                      sprintf(warn_msg,"division (/) by zero!\n");
 1172:                      capa_msg(MESSAGE_ERROR,warn_msg);
 1173:                    } break;
 1174:       case IDIV_op: if(b->s_int != 0) {
 1175:                       a_symp->s_int = (a->s_int %  b->s_int );
 1176:                     } else {
 1177:                       sprintf(warn_msg,"integer division (%%) by zero!\n");
 1178:                       capa_msg(MESSAGE_ERROR,warn_msg);
 1179:                     } break;
 1180:       case EQ_op:   a_symp->s_int = ((a->s_int ==  b->s_int)? 1: 0); break;
 1181:       case NE_op:   a_symp->s_int = ((a->s_int ==  b->s_int)? 0: 1); break;
 1182:       case GT_op:   a_symp->s_int = ((a->s_int >   b->s_int)? 1: 0); break;
 1183:       case GE_op:   a_symp->s_int = ((a->s_int >=  b->s_int)? 1: 0); break;
 1184:       case LT_op:   a_symp->s_int = ((a->s_int <   b->s_int)? 1: 0); break;
 1185:       case LE_op:   a_symp->s_int = ((a->s_int <=  b->s_int)? 1: 0); break;
 1186:       case AND_op:  a_symp->s_int = ((a->s_int &&  b->s_int)? 1: 0); break;
 1187:       case OR_op:   a_symp->s_int = ((a->s_int ||  b->s_int)? 1: 0); break;
 1188:     }
 1189:   } else {  /* a, b neither are integers */
 1190:     if( (a->s_type == S_VAR) || (a->s_type == S_CONSTANT) || 
 1191:         (b->s_type == S_VAR) || (b->s_type == S_CONSTANT) ) { /* either a or b is a string */
 1192:       type = S_CONSTANT;  /* the return type is a string */
 1193:       if( (a->s_type == S_VAR) || (a->s_type == S_CONSTANT) ) { /* a is a string */
 1194: 	if (a->s_str == NULL || 
 1195: 	    (((b->s_type == S_VAR) || (b->s_type == S_CONSTANT)) && b->s_str == NULL)) {
 1196: 	  if (a->s_str == NULL) {
 1197: 	    sprintf(warn_msg,"variable %s has not yet been assigned a value.\n",a->s_name);
 1198: 	    capa_msg(MESSAGE_ERROR,warn_msg);
 1199: 	  }
 1200: 	  if (((b->s_type == S_VAR) || (b->s_type == S_CONSTANT)) && b->s_str == NULL) {
 1201: 	    sprintf(warn_msg,"variable %s has not yet been assigned a value.\n",a->s_name);
 1202: 	    capa_msg(MESSAGE_ERROR,warn_msg);
 1203: 	  }
 1204: 	} else { /* a is a valid string */
 1205: 	  switch( b->s_type ) {
 1206: 	  case I_VAR:
 1207: 	  case I_CONSTANT:
 1208: 	    leng = SMALL_LINE_BUFFER; /* assuming a long integer does not exceed 128 digits*/
 1209: 	    b_str= capa_malloc(sizeof(char), leng);
 1210: 	    sprintf(b_str,"%ld", b->s_int);
 1211: 	    break;
 1212: 	  case R_VAR:
 1213: 	  case R_CONSTANT:
 1214: 	    leng = SMALL_LINE_BUFFER;/*assuming a double does not exceed128chars*/
 1215: 	    b_str= capa_malloc(sizeof(char), leng);
 1216: 	    sprintf(b_str,"%.15g", b->s_real);
 1217: 	    break;
 1218: 	  case S_VAR:
 1219: 	  case S_CONSTANT: /* DONE: get rid of limitations on b_str[] */
 1220: 	    leng =  strlen( b->s_str ) +  1;
 1221: 	    b_str= capa_malloc(sizeof(char), leng);
 1222: 	    sprintf(b_str,"%s",b->s_str);
 1223: 	    /*if(b->s_type == S_CONSTANT)  capa_mfree(b->s_str);*/
 1224: 	    break;
 1225: 	  }
 1226: 	  switch( op ) {
 1227: 	  case ADD_op:
 1228: 	    leng =  strlen( a->s_str ) + strlen(b_str) + 1;
 1229: 	    r_strp = capa_malloc(sizeof(char), leng);    /* **** */
 1230: 	    strcat(r_strp, a->s_str);
 1231: 	    strcat(r_strp, b_str);  /* concatenate two strings together */
 1232: 	    if( !new )   capa_mfree(a->s_str);  
 1233: 	    a_symp->s_str = r_strp;
 1234: 	    break;
 1235: 	  case SUB_op:
 1236: 	  case MUL_op:
 1237: 	  case DIV_op:
 1238: 	  case IDIV_op:
 1239: 	    if( !new )   capa_mfree(a->s_str);
 1240: 	    a_symp->s_str = strsave("<<Op NOT DEFINED>>");
 1241: 	    sprintf(warn_msg,"integer division (%%) cannot accept string operand!\n");
 1242: 	    capa_msg(MESSAGE_ERROR,warn_msg);
 1243: 	    break;
 1244: 	  case EQ_op: a_symp->s_int = (strcmp(a->s_str, b_str) == 0? 1: 0);
 1245: 	    type = I_CONSTANT;  break;
 1246: 	  case NE_op: a_symp->s_int = (strcmp(a->s_str, b_str) == 0? 0: 1);
 1247: 	    type = I_CONSTANT;  break;
 1248: 	  case GT_op: a_symp->s_int = (strcmp(a->s_str, b_str) > 0? 1: 0);
 1249: 	    type = I_CONSTANT;  break;
 1250: 	  case GE_op: a_symp->s_int = (strcmp(a->s_str, b_str) >= 0? 1: 0);
 1251: 	    type = I_CONSTANT;  break;
 1252: 	  case LT_op: a_symp->s_int = (strcmp(a->s_str, b_str) < 0? 1: 0);
 1253: 	    type = I_CONSTANT;  break;
 1254: 	  case LE_op: a_symp->s_int = (strcmp(a->s_str, b_str) <= 0? 1: 0);
 1255: 	    type = I_CONSTANT;  break;
 1256: 	  case AND_op: 
 1257: 	    if( (a->s_str[0] != 0) && (b_str[0] != 0)) {
 1258: 	      a_symp->s_int = 1;
 1259: 	    } else {
 1260: 	      a_symp->s_int = 0;
 1261: 	    } 
 1262: 	    type = I_CONSTANT;  break;
 1263: 	  case OR_op: 
 1264: 	    if( (a->s_str[0] != 0) || (b_str[0] != 0)) {
 1265: 	      a_symp->s_int = 1;
 1266: 	    } else {
 1267: 	      a_symp->s_int = 0;
 1268: 	    } 
 1269: 	    type = I_CONSTANT;  break;
 1270: 	  }
 1271: 	}
 1272: 	if (b_str!=NULL) capa_mfree(b_str);
 1273:       } else {  /* b is string and a is either integer or real */
 1274:         switch( a->s_type ) {
 1275:          case I_VAR:
 1276:          case I_CONSTANT:
 1277:                    sprintf(a_str,"%ld", a->s_int);     break;
 1278:          case R_VAR:
 1279:          case R_CONSTANT:
 1280:                    sprintf(a_str,"%.15g", a->s_real);  break;
 1281:         }
 1282:         switch( op ) {
 1283:          case ADD_op:
 1284:                    leng =  strlen( b->s_str ) + strlen(a_str) + 1;
 1285:                    r_strp = capa_malloc(sizeof(char), leng);   /* *** */
 1286:                    strcat(r_strp, a_str);
 1287:                    strcat(r_strp, b->s_str);
 1288:                    /*if( b->s_type == S_CONSTANT )  capa_mfree(b->s_str);*/
 1289:                    a_symp->s_str = r_strp;              break;
 1290:          case SUB_op:
 1291:          case MUL_op:
 1292:          case DIV_op:
 1293:          case IDIV_op:
 1294:                    a_symp->s_str = strsave("<<Op NOT DEFINED>>");
 1295:                    sprintf(warn_msg,"integer division (%%) cannot accept string operand!\n");
 1296:                    capa_msg(MESSAGE_ERROR,warn_msg);
 1297:                    break;
 1298:          case EQ_op: a_symp->s_int = (strcmp(a_str, b->s_str) == 0? 1: 0);
 1299:                      type = I_CONSTANT;  break;
 1300:          case NE_op: a_symp->s_int = (strcmp(a_str, b->s_str) == 0? 0: 1);
 1301:                      type = I_CONSTANT;  break;
 1302:          case GT_op: a_symp->s_int = (strcmp(a_str, b->s_str) > 0? 1: 0);
 1303:                      type = I_CONSTANT;  break;
 1304:          case GE_op: a_symp->s_int = (strcmp(a_str, b->s_str) >= 0? 1: 0);
 1305:                      type = I_CONSTANT;  break;
 1306:          case LT_op: a_symp->s_int = (strcmp(a_str, b->s_str) < 0? 1: 0);
 1307:                      type = I_CONSTANT;  break;
 1308:          case LE_op: a_symp->s_int = (strcmp(a_str,b->s_str) <= 0? 1: 0);
 1309:                      type = I_CONSTANT;  break;
 1310:          case AND_op: if( (a_str[0] != 0) && (b->s_str[0] != 0)) {
 1311:                        a_symp->s_int = 1;
 1312:                       } else {
 1313:                        a_symp->s_int = 0;
 1314:                       } 
 1315:                      type = I_CONSTANT;  break;
 1316:          case OR_op: if( (a_str[0] != 0) || (b_str[0] != 0)) {
 1317:                        a_symp->s_int = 1;
 1318:                       } else {
 1319:                        a_symp->s_int = 0;
 1320:                       } 
 1321:                      type = I_CONSTANT;  break;
 1322:         }
 1323:       }
 1324:       
 1325:     } else { /* both a and b are real */
 1326:       type = R_CONSTANT;
 1327:       if( (a->s_type == R_CONSTANT)||(a->s_type == R_VAR) ) {
 1328:         tmp_p = a->s_real;
 1329:       } else {
 1330:         tmp_p = (double)a->s_int;
 1331:       }
 1332:       if( (b->s_type == R_CONSTANT)||(b->s_type == R_VAR) ) {
 1333:         tmp_q = b->s_real;
 1334:       } else {
 1335:         tmp_q = (double)b->s_int;
 1336:       }
 1337:       switch( op ) {
 1338:         case ADD_op: a_symp->s_real =  tmp_p + tmp_q ; break;
 1339:         case SUB_op: a_symp->s_real =  tmp_p - tmp_q ; break;
 1340:         case MUL_op: a_symp->s_real =  tmp_p * tmp_q ; break;
 1341:         case DIV_op: if(tmp_q != 0.0) {
 1342:                        a_symp->s_real =  tmp_p / tmp_q ; 
 1343:                      } else {
 1344:                        /* printf("FDIVISION by ZERO\n"); */
 1345:                        sprintf(warn_msg,"division (/) by zero!\n");
 1346:                        capa_msg(MESSAGE_ERROR,warn_msg);
 1347:                      }
 1348:                      break;
 1349:         case IDIV_op: if(tmp_q != 0.0 ) {
 1350:                         tmp_i =  (long)tmp_p;
 1351:                         tmp_j =  (long)tmp_q;
 1352:                         a_symp->s_int = tmp_i % tmp_j;
 1353:                         type = I_CONSTANT;
 1354:                      } else {
 1355:                        /* printf("DIVISION by ZERO\n"); */
 1356:                        sprintf(warn_msg,"division (/) by zero!\n");
 1357:                        capa_msg(MESSAGE_ERROR,warn_msg);
 1358:                      }
 1359:                       break;
 1360:         case EQ_op:   type = I_CONSTANT;
 1361:                       a_symp->s_int = ((tmp_p ==  tmp_q)? 1: 0); break;
 1362:         case NE_op:   type = I_CONSTANT;
 1363:                       a_symp->s_int = ((tmp_p ==  tmp_q)? 0: 1); break;
 1364:         case GT_op:   type = I_CONSTANT;
 1365:                       a_symp->s_int = ((tmp_p >   tmp_q)? 1: 0); break;
 1366:         case GE_op:   type = I_CONSTANT;
 1367:                       a_symp->s_int = ((tmp_p >=  tmp_q)? 1: 0); break;
 1368:         case LT_op:   type = I_CONSTANT;
 1369:                       a_symp->s_int = ((tmp_p <   tmp_q)? 1: 0); break;
 1370:         case LE_op:   type = I_CONSTANT;
 1371:                       a_symp->s_int = ((tmp_p <=  tmp_q)? 1: 0); break;
 1372:         case AND_op:  type = I_CONSTANT;
 1373:                       a_symp->s_int = ((tmp_p &&  tmp_q)? 1: 0); break;
 1374:         case OR_op:   type = I_CONSTANT;
 1375:                       a_symp->s_int = ((tmp_p ||  tmp_q)? 1: 0); break;
 1376:       }
 1377:     }
 1378:   }
 1379:   if( (b->s_type == I_CONSTANT) ||
 1380:       (b->s_type == R_CONSTANT) )    capa_mfree((char *)b);     /* free symbol *b only */
 1381:   if( (b->s_type == S_CONSTANT) ) {  
 1382:     capa_mfree((char *)b->s_str);  
 1383:     capa_mfree((char *)b); 
 1384:   }
 1385:   a_symp->s_type =  type;
 1386:   return (a_symp);
 1387:  } 
 1388: }
 1389: 
 1390: /* ------------------------------------------------------ */
 1391: char *
 1392: format_toTeX( real ) char *real;
 1393: {
 1394:   int     idx, length, fraclength, i_exp;
 1395:   char   *expo_p, fracS[SMALL_LINE_BUFFER], result[ONE_K], *areal;
 1396:   char    warn_msg[WARN_MSG_LENGTH];
 1397:   
 1398:   length = strlen(real);
 1399:   if( index( real, 'e' ) == NULL ) {
 1400:     if( index( real, 'E' ) == NULL ) {
 1401:       sprintf(result,"%s", real);
 1402:     } else {
 1403:       expo_p = index(real, 'E'); /*** hpux complained */
 1404:       fraclength = length - strlen(expo_p);
 1405:       expo_p++; if(expo_p[0] == '+') expo_p++;
 1406:       sscanf(expo_p,"%d",&i_exp);
 1407:       for(idx=0;idx<fraclength;idx++) fracS[idx] = real[idx];
 1408:       fracS[fraclength] = 0;
 1409:       if(i_exp == 0 ) {
 1410:         sprintf(result,"$%s$", fracS);
 1411:       } else {
 1412:         sprintf(result,"$%s \\times 10^{%d}$", fracS, i_exp);
 1413:       }
 1414:     }
 1415:   } else {
 1416:     if( index( real, 'E' ) == NULL ) {
 1417:       expo_p = index(real, 'e'); /*** hpux complained */
 1418:       fraclength = length - strlen(expo_p);
 1419:       expo_p++; if(expo_p[0] == '+') expo_p++;
 1420:       sscanf(expo_p,"%d",&i_exp);
 1421:       for(idx=0;idx<fraclength;idx++) fracS[idx] = real[idx];
 1422:       fracS[fraclength] = 0;
 1423:       if(i_exp == 0 ) {
 1424:         sprintf(result,"$%s$", fracS);
 1425:       } else {
 1426:         sprintf(result,"$%s \\times 10^{%d}$", fracS, i_exp);
 1427:       }
 1428:     } else {
 1429:       sprintf(result,"<<Ill-formed REAL>>");
 1430:       sprintf(warn_msg,"number %s is not a valid real number!\n",real);
 1431:       capa_msg(MESSAGE_ERROR,warn_msg);
 1432:     }
 1433:   }
 1434:   areal = (char *) capa_malloc(strlen(result)+1, 1);
 1435:   strcpy(areal,result);
 1436:   return (areal);
 1437: }
 1438: /* ------------------------------------------------------ */
 1439: char *
 1440: format_toHTML( real ) char *real;
 1441: {
 1442:   int     idx, length, fraclength, i_exp;
 1443:   char   *expo_p, fracS[SMALL_LINE_BUFFER], result[ONE_K], *areal;
 1444:   char    warn_msg[WARN_MSG_LENGTH];
 1445:   
 1446:   length = strlen(real);
 1447:   if( index( real, 'e' ) == NULL ) {
 1448:     if( index( real, 'E' ) == NULL ) {
 1449:       sprintf(result,"%s", real);
 1450:     } else {
 1451:       expo_p = index(real, 'E'); /*** hpux complained */
 1452:       fraclength = length - strlen(expo_p);
 1453:       expo_p++; if(expo_p[0] == '+') expo_p++;
 1454:       sscanf(expo_p,"%d",&i_exp);
 1455:       for(idx=0;idx<fraclength;idx++) fracS[idx] = real[idx];
 1456:       fracS[fraclength] = 0;
 1457:       if(i_exp == 0 ) {
 1458:         sprintf(result,"%s", fracS);
 1459:       } else {
 1460:         sprintf(result,"%s&#215;10<sup>%d</sup>", fracS, i_exp); /* &#215 is code for x */
 1461:       }
 1462:     }
 1463:   } else { /* the string contains 'e' char */
 1464:     if( index( real, 'E' ) == NULL ) {
 1465:       expo_p = index(real, 'e'); /*** hpux complained */
 1466:       fraclength = length - strlen(expo_p);
 1467:       expo_p++; if(expo_p[0] == '+') expo_p++;
 1468:       sscanf(expo_p,"%d",&i_exp);
 1469:       for(idx=0;idx<fraclength;idx++) fracS[idx] = real[idx];
 1470:       fracS[fraclength] = 0;
 1471:       if(i_exp == 0 ) {
 1472:         sprintf(result,"%s", fracS);
 1473:       } else {
 1474:         sprintf(result,"%s&#215;10<sup>%d</sup>", fracS, i_exp); /* &#215 is code for x */
 1475:       }
 1476:     } else {
 1477:       sprintf(result,"<<Ill-formed REAL>>");
 1478:       sprintf(warn_msg,"number %s is not a valid real number!\n",real);
 1479:       capa_msg(MESSAGE_ERROR,warn_msg);
 1480:     }
 1481:   }
 1482:   areal = (char *) capa_malloc(strlen(result)+1, 1);
 1483:   strcpy(areal,result);
 1484:   return (areal);
 1485: }
 1486: /* -- This routine is called when a /ANS is encountered -- */
 1487: void
 1488: init_answerinfo()
 1489: {
 1490: 
 1491:   CurrAnsInfo.ans_str      = NULL;
 1492:   CurrAnsInfo.ans_type     = 0;
 1493:   CurrAnsInfo.ans_calc     = CALC_DEFAULT;
 1494:   CurrAnsInfo.ans_tol_type = TOL_ABSOLUTE;
 1495:   CurrAnsInfo.ans_tol      = TOL_DEFAULT;
 1496:   CurrAnsInfo.ans_sig_ub   = SIG_UB_DEFAULT;
 1497:   CurrAnsInfo.ans_sig_lb   = SIG_LB_DEFAULT;
 1498:   CurrAnsInfo.ans_id_list  = NULL;
 1499:   CurrAnsInfo.ans_pts_list = NULL;
 1500:   CurrAnsInfo.ans_fmt[0]      = '\0';
 1501:   CurrAnsInfo.ans_unit_str[0] = '\0';
 1502:   CurrAnsInfo.ans_unit     = NULL;
 1503:   CurrAnsInfo.ans_next     = NULL;
 1504: }
 1505: /* when encountered a /DIS(variable)  */
 1506: void
 1507: display_var( s )Symbol *s;
 1508: {
 1509:   char    *aline;
 1510:   char    *tmp_p;
 1511:   char    warn_msg[WARN_MSG_LENGTH];
 1512: 
 1513:                           
 1514:   switch(s->s_type) {
 1515:     case IDENTIFIER:
 1516:            aline = (char *)capa_malloc(sizeof(char)*ONE_K,1);
 1517:            sprintf(aline,"VAR \"%s\" NOT DEFINED!", s->s_name);
 1518:            sprintf(warn_msg,"display var \"%s\" not defined before use.\n",s->s_name);
 1519:            capa_msg(MESSAGE_ERROR,warn_msg);
 1520:           break;
 1521:     case I_VAR:  case I_CONSTANT:
 1522:            aline = (char *)capa_malloc(sizeof(char)*ONE_K,1);
 1523:            sprintf(aline, "%ld", s->s_int);
 1524:           break;
 1525:     case R_VAR:  case R_CONSTANT:
 1526:            aline = (char *)capa_malloc(sizeof(char)*ONE_K,1);
 1527:            if(Parsemode_f == TeX_MODE) {
 1528:              if(s->s_distype == DEFAULT_FORMAT ) {
 1529:                 sprintf(aline,"%.15g",s->s_real);
 1530:              } else {
 1531:                 sprintf(aline,s->s_format,s->s_real);
 1532:              }
 1533:              tmp_p = format_toTeX(aline);
 1534:              sprintf(aline,"%s",tmp_p);
 1535:              capa_mfree( (char *)tmp_p);
 1536:                                                       
 1537:            } else {
 1538:              if(Parsemode_f == HTML_MODE ) {
 1539:                 if(s->s_distype == DEFAULT_FORMAT ) {
 1540:                    sprintf(aline,"%.15g",s->s_real);
 1541:                 } else {
 1542:                    sprintf(aline,s->s_format,s->s_real);
 1543:                 }
 1544:                 tmp_p = format_toHTML(aline);
 1545:                 sprintf(aline,"%s",tmp_p);
 1546:                 capa_mfree( (char *)tmp_p);
 1547:               } else {
 1548:                 if(s->s_distype == DEFAULT_FORMAT ) {
 1549:                   sprintf(aline,"%.15g",s->s_real);
 1550:                 } else {
 1551:                   sprintf(aline,s->s_format,s->s_real);   
 1552:                 }
 1553:               }
 1554:             }
 1555:            break;
 1556:      case S_VAR:  case S_CONSTANT:  
 1557:             if (s->s_str == NULL) {
 1558: 	      sprintf(warn_msg,"variable %s has not yet been assigned a value.\n",
 1559: 		      s->s_name);
 1560: 	      capa_msg(MESSAGE_ERROR,warn_msg);
 1561: 	      aline=(char *)capa_malloc(9,1);
 1562: 	      sprintf(aline,"NO VALUE");
 1563:             } else {
 1564: 	      aline = (char *)capa_malloc(strlen(s->s_str)+1,1);
 1565: 	      sprintf(aline,"%s",s->s_str);
 1566: 	    }
 1567:            break;
 1568:    }
 1569:    append_text(aline);
 1570:    capa_mfree((char *)aline);
 1571:    if(s->s_format) { capa_mfree((char *)s->s_format); }
 1572:    s->s_format = NULL;
 1573:    switch(s->s_type) { /* free up spaces taken by constants */
 1574:      case I_CONSTANT:
 1575:      case R_CONSTANT: capa_mfree((char *)s); break;
 1576:      case S_CONSTANT: capa_mfree(s->s_str); capa_mfree((char *)s); break;
 1577:      default:  break;
 1578:    }
 1579: 
 1580: }
 1581: 
 1582: /* Assign the correct answer to CurrAnsInfo first */
 1583: void
 1584: assign_answer( s ) Symbol *s;
 1585: {
 1586:   char    aline[QUARTER_K];
 1587:   char    warn_msg[WARN_MSG_LENGTH];
 1588:                                           
 1589:   /*problem_default(LexiProblem_p);*/
 1590:   switch(s->s_type) {
 1591:     case IDENTIFIER:
 1592:             sprintf(warn_msg,"File %s, Line %3d: in /ANS, var %s not defined before use.\n",
 1593:               Opened_filename[Input_idx],Current_line[Input_idx],s->s_name);
 1594:             capa_msg(MESSAGE_ERROR,warn_msg);
 1595:             CurrAnsInfo.ans_str = strsave("ANSWER NOT DEFINED!");
 1596:             CurrAnsInfo.ans_type = ANSWER_IS_STRING_CI;
 1597:             sprintf(CurrAnsInfo.ans_fmt,"%%s");
 1598: 	    if (CurrAnsInfo.ans_tol == 0.0) {
 1599: 		sprintf(warn_msg, "File %s, Line %3d: answer has a numerical value of %ld and an implicit zero tolerance.\n",
 1600: 		  Opened_filename[Input_idx],Current_line[Input_idx],s->s_int);
 1601: 		capa_msg(MESSAGE_WARN,warn_msg);
 1602: 	    }
 1603: 	break;
 1604:      case I_VAR:  case I_CONSTANT:
 1605:             sprintf(aline, "%ld", s->s_int);
 1606:             CurrAnsInfo.ans_str = strsave(aline);
 1607:             CurrAnsInfo.ans_type = ANSWER_IS_INTEGER;
 1608:             sprintf(CurrAnsInfo.ans_fmt,"%%ld");
 1609:         break;
 1610:      case R_VAR:  case R_CONSTANT:
 1611:             if(s->s_distype == DEFAULT_FORMAT ) {
 1612:                sprintf(aline,"%.15g",s->s_real);
 1613:                sprintf(CurrAnsInfo.ans_fmt,"%%.15g");
 1614:             } else {
 1615:                sprintf(aline,"%.15g",s->s_real);
 1616:                strcpy(CurrAnsInfo.ans_fmt,s->s_format);  
 1617:             }
 1618:             CurrAnsInfo.ans_str = strsave(aline);
 1619:             CurrAnsInfo.ans_type = ANSWER_IS_FLOAT;
 1620:             if( CurrAnsInfo.ans_tol == 0.0 ) {
 1621:                 sprintf(warn_msg,"File %s, Line %3d: answer has a numerical value of %s and a zero tolerance.\n",
 1622:                         Opened_filename[Input_idx],Current_line[Input_idx],aline);
 1623:                 capa_msg(MESSAGE_WARN,warn_msg);
 1624:             }
 1625:          break;
 1626:      case S_VAR:  case S_CONSTANT:
 1627:             CurrAnsInfo.ans_str = strsave(s->s_str);
 1628:             if (s->s_str!=NULL && (strlen(s->s_str)>ANSWER_STRING_LENG-1)) {
 1629: 	      sprintf(warn_msg,"File %s, Line %3d: answer is too long, max allowed length is %d, current answer is %d\n",
 1630: 		      Opened_filename[Input_idx],Current_line[Input_idx],
 1631: 		      ANSWER_STRING_LENG-1, strlen(s->s_str));
 1632: 	      capa_msg(MESSAGE_ERROR,warn_msg);
 1633: 	      CurrAnsInfo.ans_str[ANSWER_STRING_LENG-1]='\0';
 1634: 	    }
 1635:             if ( !CurrAnsInfo.ans_type ) { /* not yet specified by str=  answer info */ 
 1636:               CurrAnsInfo.ans_type = ANSWER_IS_STRING_CI;
 1637:             }
 1638:             sprintf(CurrAnsInfo.ans_fmt,"%%s");
 1639:          break;
 1640:    }
 1641:    if(s->s_format) { 
 1642:        capa_mfree((char *)s->s_format);
 1643:    }
 1644:    s->s_format = NULL;
 1645:    switch(s->s_type) {
 1646:       case I_CONSTANT:
 1647:       case R_CONSTANT: capa_mfree((char *)s); break;
 1648:       case S_CONSTANT: capa_mfree(s->s_str); capa_mfree((char *)s); break;
 1649:      default:  break;
 1650:    }
 1651: 
 1652: }
 1653: 
 1654: /* Assign tolerance to CurrAnsInfo first */
 1655: void
 1656: assign_tolerance(tol_type, s) int tol_type; Symbol *s;
 1657: {
 1658:   char  warn_msg[WARN_MSG_LENGTH];
 1659:   
 1660:   CurrAnsInfo.ans_tol_type  = tol_type;
 1661:   switch( s->s_type ) {
 1662:       case IDENTIFIER:
 1663:             sprintf(warn_msg,"TOL = var, \"%s\" not defined before use.\n",s->s_name);
 1664:             capa_msg(MESSAGE_ERROR,warn_msg);
 1665:             CurrAnsInfo.ans_tol = 0.0;
 1666:           break;
 1667:        case I_VAR: case I_CONSTANT: 
 1668:            CurrAnsInfo.ans_tol =(double)s->s_int;
 1669:           break;
 1670:        case R_VAR: case R_CONSTANT:
 1671:            CurrAnsInfo.ans_tol = s->s_real;
 1672:           break;
 1673:        case S_VAR: case S_CONSTANT: CurrAnsInfo.ans_tol = 0.0;
 1674:           break;
 1675:    }
 1676:   free_calc_expr(s);
 1677: }
 1678: 
 1679: /* Problem weight is per problem based */
 1680: void
 1681: assign_weight( s ) Symbol *s;
 1682: { char warn_msg[WARN_MSG_LENGTH];
 1683:   YYDBUG_PR1(" weight = identifier\n");
 1684:   switch( s->s_type ) {
 1685:     case IDENTIFIER:
 1686:             sprintf(warn_msg,"WGT = var, \"%s\" not defined before use.\n", s->s_name);
 1687:             capa_msg(MESSAGE_ERROR,warn_msg);
 1688:             LexiProblem_p->weight = WEIGHT_DEFAULT;
 1689:            break;
 1690:     case I_VAR: case I_CONSTANT:
 1691:             if( s->s_int < 0 ) {
 1692:               sprintf(warn_msg,"WGT = %ld, weight cannot be less than zero.\n", s->s_int);
 1693: 	      capa_msg(MESSAGE_ERROR,warn_msg);
 1694: 	      LexiProblem_p->weight = WEIGHT_DEFAULT;
 1695:             } else {
 1696:               LexiProblem_p->weight = s->s_int; 
 1697:             }
 1698:             break;
 1699:      case R_VAR: case R_CONSTANT:
 1700:             if( s->s_real < 0.0 ) {
 1701:                sprintf(warn_msg,"WGT = %g, weight cannot be less than zero.\n", s->s_real);
 1702: 	       capa_msg(MESSAGE_ERROR,warn_msg);
 1703: 	       LexiProblem_p->weight = WEIGHT_DEFAULT;
 1704:             } else {
 1705:                LexiProblem_p->weight = (int)(s->s_real); 
 1706:             }
 1707:             break;
 1708:       case S_VAR: case S_CONSTANT: LexiProblem_p->weight = WEIGHT_DEFAULT; break;
 1709:     }
 1710:   free_calc_expr(s);
 1711: }
 1712: /* Answer try limit is per problem based */
 1713: void
 1714: assign_try_limits( s ) Symbol *s;
 1715: { char warn_msg[WARN_MSG_LENGTH];
 1716:   switch( s->s_type ) {
 1717:     case IDENTIFIER:
 1718: 	    sprintf(warn_msg,"TRY = var, \"%s\" not defined before use.\n",s->s_name);
 1719:             capa_msg(MESSAGE_ERROR,warn_msg);
 1720:             LexiProblem_p->tries = MAX_TRIES;
 1721:            break;
 1722:     case I_VAR: case I_CONSTANT:
 1723:             if(s->s_int <= 0) {
 1724: 	       sprintf(warn_msg,"TRIES = %ld, tries cannot be less than or equal to zero.\n",s->s_int);
 1725: 	       capa_msg(MESSAGE_ERROR,warn_msg);
 1726: 	       LexiProblem_p->tries = MAX_TRIES;
 1727: 	    } else {
 1728: 	       LexiProblem_p->tries = s->s_int;
 1729: 	    }
 1730: 	   break;
 1731:      case R_VAR:  case R_CONSTANT:
 1732:             if(s->s_real <= 0.0) {
 1733: 	       sprintf(warn_msg,"TRIES = %g, tries cannot be less than or equal to zero.\n",s->s_real);
 1734: 	       capa_msg(MESSAGE_ERROR,warn_msg);
 1735: 	       LexiProblem_p->tries = MAX_TRIES;
 1736: 	     } else {
 1737: 	       LexiProblem_p->tries = (int)(s->s_real);
 1738: 	     }
 1739:             break;
 1740:       case S_VAR: case S_CONSTANT: LexiProblem_p->tries = MAX_TRIES; break;
 1741:    }	    
 1742:   free_calc_expr(s);
 1743: }
 1744: /* Answer hint is per problem based */
 1745: void
 1746: assign_hint( s ) Symbol *s;
 1747: {  char warn_msg[WARN_MSG_LENGTH];
 1748: 	                                 
 1749:     switch( s->s_type ) {
 1750:       case IDENTIFIER:
 1751:                sprintf(warn_msg,"HINT = var, \"%s\" not defined before use.\n", s->s_name);
 1752:                capa_msg(MESSAGE_ERROR,warn_msg);
 1753:                LexiProblem_p->show_hint = SHOW_HINT_DEFAULT;
 1754:              break;
 1755:       case I_VAR: case I_CONSTANT:
 1756:                if( s->s_int < 0 ) {
 1757:                   sprintf(warn_msg,"HINT = %ld, show hint cannot be less than zero.\n", s->s_int);
 1758: 	          capa_msg(MESSAGE_ERROR,warn_msg);
 1759: 	          LexiProblem_p->show_hint = SHOW_HINT_DEFAULT;
 1760:                } else {
 1761:                   LexiProblem_p->show_hint = s->s_int; 
 1762:                }
 1763:              break;
 1764:        case R_VAR: case R_CONSTANT:
 1765:                if( s->s_real < 0.0 ) {
 1766:                   sprintf(warn_msg,"HINT = %g, show hint cannot be less than zero.\n", s->s_real);
 1767: 	          capa_msg(MESSAGE_ERROR,warn_msg);
 1768: 	          LexiProblem_p->show_hint = SHOW_HINT_DEFAULT;
 1769:                } else {
 1770:                   LexiProblem_p->weight = (int)(s->s_real); 
 1771:                }
 1772:              break;
 1773:        case S_VAR: case S_CONSTANT: LexiProblem_p->show_hint = SHOW_HINT_DEFAULT; break;
 1774:     }
 1775:   free_calc_expr(s);
 1776: }
 1777: 
 1778: /* Assign answer units string to CurrAnsInfo first */
 1779: void
 1780: assign_units( s ) Symbol *s;
 1781: {
 1782:   char    symb_str[ONE_TWO_EIGHT];
 1783:   char    warn_msg[WARN_MSG_LENGTH];
 1784:   
 1785:   switch( s->s_type ) {
 1786:     case IDENTIFIER:
 1787:            sprintf(warn_msg,"UNIT = var, \"%s\" not defined before use.\n", s->s_name);
 1788:            capa_msg(MESSAGE_ERROR,warn_msg);
 1789:            break;
 1790:     case I_VAR: case I_CONSTANT:
 1791:            sprintf(warn_msg,"UNIT = %ld, unit cannot be a number.\n", s->s_int);
 1792:            capa_msg(MESSAGE_ERROR,warn_msg);
 1793:            break;
 1794:     case R_VAR: case R_CONSTANT:
 1795:            sprintf(warn_msg,"UNIT = %g, unit cannot be a number.\n", s->s_real);
 1796: 	   capa_msg(MESSAGE_ERROR,warn_msg);
 1797:            break;
 1798:     case S_VAR: case S_CONSTANT:
 1799:            strcpy(symb_str,s->s_str);
 1800: 	   strcpy(CurrAnsInfo.ans_unit_str,symb_str);
 1801: 	   CurrAnsInfo.ans_unit = u_parse_unit(symb_str);
 1802: 	   if (gUnitError) {
 1803: 	      sprintf(warn_msg,"Error in unit specified: %s\n",symb_str);
 1804: 	      capa_msg(MESSAGE_ERROR,warn_msg);
 1805: 	   }
 1806: 	break;
 1807:   }
 1808: }
 1809: void
 1810: assign_sigs( lb, ub ) int lb; int ub;
 1811: {
 1812:   CurrAnsInfo.ans_sig_lb = lb;
 1813:   CurrAnsInfo.ans_sig_ub = ub;
 1814: }
 1815: 
 1816: void
 1817: assign_id_list( s ) Symbol *s;
 1818: {
 1819:   char    warn_msg[WARN_MSG_LENGTH];
 1820:   
 1821:   switch( s->s_type ) {
 1822:     case IDENTIFIER:
 1823:            sprintf(warn_msg,"Eval = < ID @ Pts >, \"%s\" not defined before use.\n", s->s_name);
 1824:            capa_msg(MESSAGE_ERROR,warn_msg);
 1825:            break;
 1826:     case I_VAR: case I_CONSTANT:
 1827:            sprintf(warn_msg,"Eval = < %ld @ Pts >, ID cannot be a number.\n", s->s_int);
 1828:            capa_msg(MESSAGE_ERROR,warn_msg);
 1829:            break;
 1830:     case R_VAR: case R_CONSTANT:
 1831:            sprintf(warn_msg,"Eval = < %.16g @ Pts >, ID cannot be a number.\n", s->s_real);
 1832: 	   capa_msg(MESSAGE_ERROR,warn_msg);
 1833:            break;
 1834:     case S_VAR: case S_CONSTANT:
 1835: 	   CurrAnsInfo.ans_id_list = strsave(s->s_str);
 1836: 	   break;
 1837:   }
 1838: }
 1839: 
 1840: /* void assign_pts ( Symbol* coord1, Symbol* coord2, Symbol* num) { */
 1841: void assign_pts (coord1, coord2, num)Symbol *coord1;Symbol *coord2;Symbol *num;
 1842: {
 1843:   PointsList_t *pt;
 1844:   if( LastPtsList != NULL ) {
 1845:     LastPtsList->pts_next = gen_ptslist( coord1, coord2, num );
 1846:     pt = LastPtsList->pts_next;
 1847:     while( pt->pts_next != NULL ) {
 1848:       pt = pt->pts_next;
 1849:     }
 1850:     LastPtsList = pt;
 1851:   } else {
 1852:     CurrPtsList = gen_ptslist( coord1, coord2, num );
 1853:     LastPtsList = CurrPtsList;
 1854:   }
 1855:   if(coord1->s_type == S_CONSTANT) {
 1856:     capa_mfree(coord1->s_str); capa_mfree((char *)coord1);
 1857:   }
 1858:   if(coord2->s_type == S_CONSTANT) {
 1859:     capa_mfree(coord2->s_str); capa_mfree((char *)coord2);
 1860:   }
 1861:   if(num->s_type == I_CONSTANT || num->s_type == R_CONSTANT) {
 1862:     capa_mfree((char *)num);
 1863:   }
 1864: }
 1865: 
 1866: /* =========================================================================== */
 1867: 
 1868: 
 1869: 
 1870: 
 1871: 
 1872: 
 1873: /* =========================================================================== */
 1874: 
 1875: void start_question_over()
 1876: {
 1877:   free_problems(LexiProblem_p);
 1878:   LexiProblem_p = (Problem_t *) capa_malloc(sizeof(Problem_t),1); 
 1879:   problem_default(LexiProblem_p);
 1880:   begin_question();
 1881: }
 1882: 
 1883: void
 1884: init_new_prob()
 1885: {
 1886:   if (LastProblem_p) {
 1887:      LastProblem_p->next = LexiProblem_p;
 1888:   } else {
 1889:      FirstProblem_p      = LexiProblem_p;
 1890:   }
 1891:   LastProblem_p = LexiProblem_p;
 1892:   Lexi_qnum++;  
 1893:   LexiProblem_p = (Problem_t *) capa_malloc(sizeof(Problem_t),1); /* *** */
 1894:   problem_default(LexiProblem_p);
 1895: }
 1896: void
 1897: add_answer_cnt(op)int op;
 1898: {
 1899:   LexiProblem_p->ans_cnt++;
 1900:   if(LexiProblem_p->ans_op == 0) { /* the very first /AND or /OR */
 1901:     LexiProblem_p->ans_op = op;
 1902:   } else {
 1903:     if( LexiProblem_p->ans_op != op ) { char    warn_msg[WARN_MSG_LENGTH];
 1904:       sprintf(warn_msg,"When specifying multiple answers, either /AND or /OR can be used, but not both.\n");
 1905:       capa_msg(MESSAGE_ERROR,warn_msg);
 1906:     }
 1907:   }
 1908: }
 1909: 
 1910: /* -- called when forming answer_expr */
 1911: void
 1912: finish_answer_info()
 1913: {
 1914:   AnswerInfo_t  *ai;
 1915:   
 1916:   if( LexiProblem_p->ans_cnt == 1 ) {  /* Only one answer is defined */
 1917:       LexiProblem_p->answer    = CurrAnsInfo.ans_str;
 1918:       LexiProblem_p->ans_type  = CurrAnsInfo.ans_type;
 1919:       LexiProblem_p->calc      = CurrAnsInfo.ans_calc;
 1920:       LexiProblem_p->tol_type  = CurrAnsInfo.ans_tol_type;
 1921:       LexiProblem_p->tolerance = CurrAnsInfo.ans_tol;
 1922:       LexiProblem_p->sig_ubound= CurrAnsInfo.ans_sig_ub;
 1923:       LexiProblem_p->sig_lbound= CurrAnsInfo.ans_sig_lb;
 1924:       LexiProblem_p->id_list   = CurrAnsInfo.ans_id_list;
 1925:       LexiProblem_p->pts_list  = CurrAnsInfo.ans_pts_list;
 1926:       strcpy(LexiProblem_p->ans_fmt,CurrAnsInfo.ans_fmt);
 1927:       strcpy(LexiProblem_p->unit_str,CurrAnsInfo.ans_unit_str);
 1928:       LexiProblem_p->ans_unit  = CurrAnsInfo.ans_unit;
 1929:   } else {
 1930:       ai = (AnswerInfo_t  *)capa_malloc(sizeof(AnswerInfo_t),1);
 1931:       ai->ans_str       = CurrAnsInfo.ans_str;
 1932:       ai->ans_type      = CurrAnsInfo.ans_type;
 1933:       ai->ans_calc      = CurrAnsInfo.ans_calc;
 1934:       ai->ans_tol_type  = CurrAnsInfo.ans_tol_type;
 1935:       ai->ans_tol       = CurrAnsInfo.ans_tol;
 1936:       ai->ans_sig_ub    = CurrAnsInfo.ans_sig_ub;
 1937:       ai->ans_sig_lb    = CurrAnsInfo.ans_sig_lb;
 1938:       ai->ans_id_list   = CurrAnsInfo.ans_id_list;
 1939:       ai->ans_pts_list  = CurrAnsInfo.ans_pts_list;
 1940:       strcpy(ai->ans_fmt,CurrAnsInfo.ans_fmt);
 1941:       strcpy(ai->ans_unit_str,CurrAnsInfo.ans_unit_str);
 1942:       ai->ans_unit      = CurrAnsInfo.ans_unit;
 1943:       ai->ans_next      = NULL;
 1944:       if(LexiProblem_p->ans_cnt == 2) {
 1945:         LexiProblem_p->ans_list = ai;
 1946:       } else {
 1947:         (LexiProblem_p->ans_list_last)->ans_next = ai;
 1948:       }
 1949:       LexiProblem_p->ans_list_last = ai;
 1950:   }
 1951: 
 1952: }
 1953: 
 1954: /* === End of capaGrammarDef.y ============================================= */
 1955: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>
500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.