File:  [LON-CAPA] / loncom / homework / CAPA-converter / capaGrammarDef.y
Revision 1.4: download - view: text, annotated - select for diffs
Tue Dec 4 15:17:57 2001 UTC (22 years, 5 months ago) by albertel
Branches: MAIN
CVS tags: version_2_9_X, version_2_9_99_0, version_2_9_1, version_2_9_0, version_2_8_X, version_2_8_99_1, version_2_8_99_0, version_2_8_2, version_2_8_1, version_2_8_0, version_2_7_X, version_2_7_99_1, version_2_7_99_0, version_2_7_1, version_2_7_0, version_2_6_X, version_2_6_99_1, version_2_6_99_0, version_2_6_3, version_2_6_2, version_2_6_1, version_2_6_0, version_2_5_X, version_2_5_99_1, version_2_5_99_0, version_2_5_2, version_2_5_1, version_2_5_0, version_2_4_X, version_2_4_99_0, version_2_4_2, version_2_4_1, version_2_4_0, version_2_3_X, version_2_3_99_0, version_2_3_2, version_2_3_1, version_2_3_0, version_2_2_X, version_2_2_99_1, version_2_2_99_0, version_2_2_2, version_2_2_1, version_2_2_0, version_2_1_X, version_2_1_99_3, version_2_1_99_2, version_2_1_99_1, version_2_1_99_0, version_2_1_3, version_2_1_2, version_2_1_1, version_2_1_0, version_2_12_X, version_2_11_X, version_2_11_4_uiuc, version_2_11_4_msu, version_2_11_4, version_2_11_3_uiuc, version_2_11_3_msu, version_2_11_3, version_2_11_2_uiuc, version_2_11_2_msu, version_2_11_2_educog, version_2_11_2, version_2_11_1, version_2_11_0_RC3, version_2_11_0_RC2, version_2_11_0_RC1, version_2_11_0, version_2_10_X, version_2_10_1, version_2_10_0_RC2, version_2_10_0_RC1, version_2_10_0, version_2_0_X, version_2_0_99_1, version_2_0_2, version_2_0_1, version_2_0_0, version_1_99_3, version_1_99_2, version_1_99_1_tmcc, version_1_99_1, version_1_99_0_tmcc, version_1_99_0, version_1_3_X, version_1_3_3, version_1_3_2, version_1_3_1, version_1_3_0, version_1_2_X, version_1_2_99_1, version_1_2_99_0, version_1_2_1, version_1_2_0, version_1_1_X, version_1_1_99_5, version_1_1_99_4, version_1_1_99_3, version_1_1_99_2, version_1_1_99_1, version_1_1_99_0, version_1_1_3, version_1_1_2, version_1_1_1, version_1_1_0, version_1_0_99_3, version_1_0_99_2, version_1_0_99_1, version_1_0_99, version_1_0_3, version_1_0_2, version_1_0_1, version_1_0_0, version_0_99_5, version_0_99_4, version_0_99_3, version_0_99_2, version_0_99_1, version_0_99_0, version_0_6_2, version_0_6, version_0_5_1, version_0_5, version_0_4, stable_2002_spring, stable_2002_july, stable_2002_april, stable_2001_fall, loncapaMITrelate_1, language_hyphenation_merge, language_hyphenation, conference_2003, bz6209-base, bz6209, bz5969, bz2851, STABLE, PRINT_INCOMPLETE_base, PRINT_INCOMPLETE, HEAD, GCI_3, GCI_2, GCI_1, BZ5971-printing-apage, BZ5434-fox, BZ4492-merge, BZ4492-feature_horizontal_radioresponse, BZ4492-feature_Support_horizontal_radioresponse, BZ4492-Support_horizontal_radioresponse
- GPL headers

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

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.