File:  [LON-CAPA] / capa / capa51 / pProj / capaFunction.c
Revision 1.3: download - view: text, annotated - select for diffs
Thu Dec 16 22:18:35 1999 UTC (24 years, 5 months ago) by albertel
Branches: MAIN
CVS tags: HEAD
- capadiscuss doesn't protect html before sending it out, but rather
  before writing it to the file
- added function managermode(0 and fixed answers to use it, and all
  programs that call answers to support the new functionality
- qzparse got a large amount of cleaning up done.

    1: 
    2: /* =||>>================================================================<<||= */
    3: /* 45678901234567890123456789012345678901234567890123456789012345678901234567 */
    4: /*  copyrighted by Isaac Tsai, 1996, 1997, 1998, 1999, 2000                   */
    5: /* =||>>================================================================<<||= */
    6: 
    7: #include <stdlib.h>
    8: #include <string.h>
    9: #include <math.h>
   10: 
   11: #include "capaParser.h"    /* Symbol_p */
   12: #include "capaFunction.h"  /* RANDOM_F etc. */
   13: #include "capaToken.h"
   14: #include "capaCommon.h"
   15: #include "ranlib.h"
   16: 
   17: 
   18: char        Parse_class[QUARTER_K];
   19: int         Parse_set;
   20: int         Parse_section; 
   21: char        Parse_student_number[MAX_STUDENT_NUMBER+1];
   22: char        Parse_name[MAX_NAME_CHAR+1];
   23: long        capaid_plus_gen;
   24: int         managermode;
   25: 
   26: extern int         Parsemode_f;
   27: 
   28: extern int         Lexi_qnum; 
   29: extern char        Opened_filename[MAX_OPENED_FILE][QUARTER_K];
   30: extern int         Input_idx;
   31: extern int         Current_line[MAX_OPENED_FILE];
   32: 
   33: extern int         Func_idx;
   34: extern Symbol      FuncStack[MAX_FUNC_NEST];
   35: 
   36: /* --------------------------------------------------------------------------- */
   37: int
   38: match_function(func, argc) char *func; int argc;
   39: {
   40:   if( !strcmp(func,"random") )         return (((argc==2 || argc==3)? RANDOM_F : MIS_ARG_COUNT));
   41:   if( !strcmp(func,"choose") )         return (CHOOSE_F);
   42:   if( !strcmp(func,"tex") )            return (((argc==2)? TEX_F: MIS_ARG_COUNT));
   43:   if( !strcmp(func,"var_in_tex") )     return (VAR_IN_TEX_F);
   44:   if( !strcmp(func,"html") )           return (((argc==1)? HTML_F: MIS_ARG_COUNT));
   45:   if( !strcmp(func,"web") )            return (((argc==3)? WEB_F: MIS_ARG_COUNT));
   46:   if( !strcmp(func,"pin") )            return (((argc<2)? PIN_F: MIS_ARG_COUNT));
   47:   if( !strcmp(func,"capa_id") )        return (((argc<2)? PIN_F: MIS_ARG_COUNT));
   48:   if( !strcmp(func,"class") )          return (((argc==0)? CLASS_F: MIS_ARG_COUNT));
   49:   if( !strcmp(func,"section") )        return (((argc==0)? SECTION_F: MIS_ARG_COUNT));
   50:   if( !strcmp(func,"set") )            return (((argc==0)? SET_F: MIS_ARG_COUNT));
   51:   if( !strcmp(func,"problem") )        return (((argc==0)? PROBLEM_F: MIS_ARG_COUNT));
   52:   if( !strcmp(func,"name") )           return (((argc==0)? NAME_F: MIS_ARG_COUNT));
   53:   if( !strcmp(func,"student_number") ) return (((argc==0)? SNUMBER_F: MIS_ARG_COUNT));
   54:   if( !strcmp(func,"due_date") )       return (((argc<2)? DUE_DATE_F: MIS_ARG_COUNT));
   55:   if( !strcmp(func,"due_day") )        return (((argc<2)? DUE_DAY_F: MIS_ARG_COUNT));
   56:   if( !strcmp(func,"open_date") )      return (((argc<2)? OPEN_DATE_F: MIS_ARG_COUNT));
   57:   if( !strcmp(func,"answer_date") )    return (((argc<2)? ANSWER_DATE_F: MIS_ARG_COUNT));
   58:   if( !strcmp(func,"to_string") )      return (((argc==1 || argc==2)? TO_STRING_F: MIS_ARG_COUNT));
   59:   if( !strcmp(func,"sub_string") )     return (((argc==2 || argc==3)? SUB_STRING_F: MIS_ARG_COUNT));
   60:   if( !strcmp(func,"strlen") )         return (((argc==1)? STRLEN_F: MIS_ARG_COUNT));
   61:   if( !strcmp(func,"get_seed") )       return (((argc==0)? GET_SEED_F: MIS_ARG_COUNT));
   62:   if( !strcmp(func,"set_seed") )       return (((argc==1)? SET_SEED_F: MIS_ARG_COUNT));
   63:   if( !strcmp(func,"array_index") )    return (((argc==1)? ARRAY_INDEX_F: MIS_ARG_COUNT));
   64:   if( !strcmp(func,"array_sorted_index") )    return (((argc==2)? ARRAY_SORTED_INDEX_F: MIS_ARG_COUNT));
   65:   if( !strcmp(func,"array_max") )      return (((argc==1)? ARRAY_MAX_F: MIS_ARG_COUNT));
   66:   if( !strcmp(func,"array_min") )      return (((argc==1)? ARRAY_MIN_F: MIS_ARG_COUNT));
   67:   if( !strcmp(func,"array_moments") )  return (((argc==2)? ARRAY_MOMENTS_F: MIS_ARG_COUNT));
   68:   if( !strcmp(func,"array_var") )      return (((argc==1)? ARRAY_VARIANCE_F: MIS_ARG_COUNT));
   69:   if( !strcmp(func,"array_std_dev") )  return (((argc==1)? ARRAY_STD_DEV_F: MIS_ARG_COUNT));
   70:   if( !strcmp(func,"array_skewness") ) return (((argc==1)? ARRAY_SKEWNESS_F: MIS_ARG_COUNT));
   71:   if( !strcmp(func,"to_int") )         return (((argc==1)? TO_INT_F: MIS_ARG_COUNT));
   72:   if( !strcmp(func,"format") )         return (FORMAT_F);
   73:   if( !strcmp(func,"pick") )           return (((argc> 1)? PICK_F: MIS_ARG_COUNT));
   74:   if( !strcmp(func,"sin") )            return (((argc==1)? SIN_F:  MIS_ARG_COUNT));
   75:   if( !strcmp(func,"cos") )            return (((argc==1)? COS_F:  MIS_ARG_COUNT));
   76:   if( !strcmp(func,"tan") )            return (((argc==1)? TAN_F:  MIS_ARG_COUNT));
   77:   if( !strcmp(func,"asin") )           return (((argc==1)? ASIN_F: MIS_ARG_COUNT));
   78:   if( !strcmp(func,"acos") )           return (((argc==1)? ACOS_F: MIS_ARG_COUNT));
   79:   if( !strcmp(func,"atan") )           return (((argc==1)? ATAN_F: MIS_ARG_COUNT));
   80:   if( !strcmp(func,"sinh") )           return (((argc==1)? SINH_F:  MIS_ARG_COUNT));
   81:   if( !strcmp(func,"cosh") )           return (((argc==1)? COSH_F:  MIS_ARG_COUNT));
   82:   if( !strcmp(func,"tanh") )           return (((argc==1)? TANH_F:  MIS_ARG_COUNT));
   83:   if( !strcmp(func,"asinh") )          return (((argc==1)? ASINH_F:  MIS_ARG_COUNT));
   84:   if( !strcmp(func,"acosh") )          return (((argc==1)? ACOSH_F:  MIS_ARG_COUNT));
   85:   if( !strcmp(func,"atanh") )          return (((argc==1)? ATANH_F:  MIS_ARG_COUNT));
   86:   if( !strcmp(func,"atan2") )          return (((argc==2)? ATANTWO_F:  MIS_ARG_COUNT));
   87:   if( !strcmp(func,"j0") )             return (((argc==1)? J_ZERO_F:  MIS_ARG_COUNT));
   88:   if( !strcmp(func,"j1") )             return (((argc==1)? J_ONE_F:  MIS_ARG_COUNT));
   89:   if( !strcmp(func,"jn") )             return (((argc==2)? J_N_F:  MIS_ARG_COUNT));
   90:   if( !strcmp(func,"y0") )             return (((argc==1)? Y_ZERO_F:  MIS_ARG_COUNT));
   91:   if( !strcmp(func,"y1") )             return (((argc==1)? Y_ONE_F:  MIS_ARG_COUNT));
   92:   if( !strcmp(func,"yn") )             return (((argc==2)? Y_N_F:  MIS_ARG_COUNT));
   93:   if( !strcmp(func,"log") )            return (((argc==1)? LOG_F:  MIS_ARG_COUNT));
   94:   if( !strcmp(func,"log10") )          return (((argc==1)? LOG_TEN_F: MIS_ARG_COUNT));
   95:   if( !strcmp(func,"exp") )            return (((argc==1)? EXP_F:  MIS_ARG_COUNT));
   96:   if( !strcmp(func,"pow") )            return (((argc==2)? POW_F:  MIS_ARG_COUNT));
   97:   if( !strcmp(func,"erf") )            return (((argc==1)? ERF_F:  MIS_ARG_COUNT));
   98:   if( !strcmp(func,"erfc") )           return (((argc==1)? ERFC_F: MIS_ARG_COUNT));
   99:   if( !strcmp(func,"sqrt") )           return (((argc==1)? SQRT_F: MIS_ARG_COUNT));
  100:   if( !strcmp(func,"min") )            return (MIN_F);
  101:   if( !strcmp(func,"max") )            return (MAX_F);
  102:   if( !strcmp(func,"abs") )            return (((argc==1)? ABS_F: MIS_ARG_COUNT));
  103:   if( !strcmp(func,"floor") )          return (((argc==1)? FLOOR_F: MIS_ARG_COUNT));
  104:   if( !strcmp(func,"ceil") )           return (((argc==1)? CEIL_F: MIS_ARG_COUNT));
  105:   if( !strcmp(func,"sgn") )            return (((argc==1)? SGN_F: MIS_ARG_COUNT));
  106:   if( !strcmp(func,"mod") )            return (((argc==2)? MOD_F: MIS_ARG_COUNT));
  107:   if( !strcmp(func,"remainder") )      return (((argc==2)? REMAINDER_F: MIS_ARG_COUNT));
  108:   if( !strcmp(func,"factorial") )      return (((argc==1)? FACTORIAL_F: MIS_ARG_COUNT));
  109:   if( !strcmp(func,"roundto") )        return (((argc==2)? ROUNDTO_F: MIS_ARG_COUNT));
  110:   if( !strcmp(func,"eval_formula") )   return (((argc==3)? EVALUATE_F: MIS_ARG_COUNT));
  111:   if( !strcmp(func,"capa_id_plus") )   return (((argc==1 || argc==2)? CAPAID_PLUS: MIS_ARG_COUNT));
  112:   if( !strcmp(func,"seat_number") )    return (((argc <2)? SEAT_NUMBER: MIS_ARG_COUNT));
  113:   if( !strcmp(func,"duration") )       return (((argc==0)? DURATION: MIS_ARG_COUNT));
  114:   if( !strcmp(func,"is_open") )        return (((argc <2)? IS_OPEN_F: MIS_ARG_COUNT));
  115:   if( !strcmp(func,"is_due") )         return (((argc <2)? IS_DUE_F: MIS_ARG_COUNT));
  116:   if( !strcmp(func,"is_answer") )      return (((argc <2)? IS_ANSWER_F: MIS_ARG_COUNT));
  117:   if( !strcmp(func,"correct") )        return (((argc <3)? CORRECT_F: MIS_ARG_COUNT));
  118:   if( !strcmp(func,"grade") )          return (((argc <3)? GRADE_F: MIS_ARG_COUNT));
  119:   if( !strcmp(func,"tries") )          return (((argc <3)? TRIES_F: MIS_ARG_COUNT));
  120:   if( !strcmp(func,"managermode"))     return (((argc==0)? MANAGERMODE_F:MIS_ARG_COUNT));
  121:   return (UNKNOWN_F);
  122: }
  123: 
  124: /**********************************************************/
  125: 
  126: 
  127: #ifdef    SGN
  128: #undef    SGN
  129: #endif
  130: #define   SGN(xx)  ( (xx) > 0 ? 1 : ( (xx) == 0 ? 0 : -1) )
  131: 
  132: 
  133: #define   MAX_DOUBLE         1.7976931348623157E+308
  134: #define   MIN_DOUBLE         2.2250738585072014E-308
  135: 
  136: #define   INT_DIV     0
  137: #define   REAL_DIV    1
  138: #define   INT_LOWER   0
  139: #define   REAL_LOWER  2
  140: #define   INT_UPPER   0
  141: #define   REAL_UPPER  4
  142: 
  143: #define   ALL_INTEGER  0
  144: 
  145: int which_set(argc,argp,resultp)
  146: int         argc;
  147: ArgNode_t  *argp; 
  148: Symbol     *resultp;
  149: {
  150:   char        aline[MAX_BUFFER_SIZE], tmpS[MAX_BUFFER_SIZE];
  151:   int result=Parse_set;
  152:   if( argc == 1 ) {
  153:     if( (FIRST_ARGTYPE(argp) == S_VAR ) || 
  154: 	(FIRST_ARGTYPE(argp) == S_CONSTANT ) ) {
  155:       sprintf(aline,"<<ARG TYPE MISMATCH>>");
  156:       resultp->s_type = S_CONSTANT;
  157:       resultp->s_str = strsave(aline);
  158:       sprintf(tmpS, "function %s() cannot accept string as argument.\n", 
  159: 	      FuncStack[Func_idx].s_name);
  160:       capa_msg(MESSAGE_ERROR,tmpS);
  161:       result=-1;
  162:     } else {
  163:       if( (FIRST_ARGTYPE(argp) == I_VAR ) || 
  164: 	  (FIRST_ARGTYPE(argp) == I_CONSTANT ) ) {
  165: 	result = FIRST_ARGINT(argp);
  166:       } else {
  167: 	result = FIRST_ARGREAL(argp);
  168:       }
  169:     }
  170:   }
  171:   return result;
  172: }
  173: 
  174: Symbol *                
  175: do_function(func,argc,argp) 
  176: int         func;           
  177: int         argc;
  178: ArgNode_t  *argp; 
  179: {                
  180:   Symbol     *resultp;
  181:   ArgNode_t  *tmpArgp;
  182:   char        aline[MAX_BUFFER_SIZE], tmpS[MAX_BUFFER_SIZE], fmt_str[FORMAT_STRING_LENG];
  183:   char        num_str[SMALL_LINE_BUFFER],date_str[SMALL_LINE_BUFFER];
  184:   double      tmpA=0.0, tmpB=0.0;
  185:   int         slots, noError, errCode, mo, yy, dd, hh, mm, tmpInt;
  186:   long        rout;
  187:   char       *wday[9] =  {"Sat,", "Sun,", "Mon,", "Tue,", "Wed,", "Thr,", "Fri,", "Sat,", "\0"};
  188:   char       *month[14] =  { "UNKNOWN", "Jan", "Feb", "Mar", "Apr", "May", "Jun", 
  189:                          "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "\0"};
  190:   
  191:   resultp = (Symbol *)capa_malloc(1,sizeof(Symbol));
  192:   
  193:   switch(func) {
  194:     case RANDOM_F: { int    type_flag=0;
  195:               double r_lower=0.0, r_upper=1.0, r_division=1.0;
  196: 
  197:               errCode = 0; rout = ignlgi();
  198:               switch( FIRST_ARGTYPE(argp) ) {
  199:                 case I_VAR: case I_CONSTANT: break;
  200:                 case R_VAR: case R_CONSTANT: type_flag = (type_flag | 1); break;
  201:                 case S_VAR: case S_CONSTANT: errCode = 1; break;
  202:               }
  203:               switch( SECOND_ARGTYPE(argp) ) {
  204:                 case I_VAR: case I_CONSTANT: break;
  205:                 case R_VAR: case R_CONSTANT: type_flag = (type_flag | 2); break;
  206:                 case S_VAR: case S_CONSTANT: errCode = 2; break;
  207:               }
  208:               if( argc == 3 ) {
  209:                 switch( THIRD_ARGTYPE(argp) ) {
  210:                  case I_VAR: case I_CONSTANT: break;
  211:                  case R_VAR: case R_CONSTANT: type_flag = (type_flag | 4); break;
  212:                  case S_VAR: case S_CONSTANT: errCode = 4; break;
  213:                 }
  214:               }
  215:               if( errCode == 0 ) {
  216:                 if( argc == 3 ) {
  217:                    switch(type_flag) {
  218:                    case 0: r_division = (double)FIRST_ARGINT(argp); 
  219:                            r_upper = (double)SECOND_ARGINT(argp);
  220:                            r_lower = (double)THIRD_ARGINT(argp);    break;
  221:                    case 2: r_division = (double)FIRST_ARGINT(argp);
  222:                            r_upper = SECOND_ARGREAL(argp);
  223:                            r_lower = (double)THIRD_ARGINT(argp);    break;
  224:                    case 4: r_division = (double)FIRST_ARGINT(argp);
  225:                            r_upper = (double)SECOND_ARGINT(argp);
  226:                            r_lower = THIRD_ARGREAL(argp);           break;
  227:                    case 6: r_division = (double)FIRST_ARGINT(argp);
  228:                            r_upper = SECOND_ARGREAL(argp);
  229:                            r_lower = THIRD_ARGREAL(argp);           break;
  230:                    case 1: r_division = FIRST_ARGREAL(argp);
  231:                            r_upper = (double)SECOND_ARGINT(argp);
  232:                            r_lower = (double)THIRD_ARGINT(argp);    break;
  233:                    case 3: r_division = FIRST_ARGREAL(argp);
  234:                            r_upper = SECOND_ARGREAL(argp);
  235:                            r_lower = (double)THIRD_ARGINT(argp);    break;
  236:                    case 5: r_division = FIRST_ARGREAL(argp);
  237:                            r_upper = (double)SECOND_ARGINT(argp);
  238:                            r_lower = THIRD_ARGREAL(argp);           break;
  239:                    case 7: r_division = FIRST_ARGREAL(argp);
  240:                            r_upper = SECOND_ARGREAL(argp);
  241:                            r_lower = THIRD_ARGREAL(argp);           break;
  242:                   }
  243:                 } else { /* two args */
  244:                   switch(type_flag) {
  245:                    case 0: r_upper = (double)FIRST_ARGINT(argp);
  246:                            r_lower = (double)SECOND_ARGINT(argp);   break;
  247:                    case 1: r_upper = FIRST_ARGREAL(argp);
  248:                            r_lower = (double)SECOND_ARGINT(argp);   break;
  249:                    case 2: r_upper = (double)FIRST_ARGINT(argp);
  250:                            r_lower = SECOND_ARGREAL(argp);          break;
  251:                    case 3: r_upper = FIRST_ARGREAL(argp);
  252:                            r_lower = SECOND_ARGREAL(argp);          break;
  253:                   }
  254:                   r_division = 1.0;
  255:                }
  256:                if( r_upper >= r_lower ) {
  257:                  slots = 1 + (int)floor( (r_upper - r_lower)/r_division );
  258:                  if( type_flag == 0 ) {
  259:                     resultp->s_type = I_CONSTANT;
  260:                     resultp->s_int = (int)r_lower + ((int)r_division)*(rout % slots );
  261:                  } else {
  262:                     resultp->s_type = R_CONSTANT;
  263:                     resultp->s_real = r_lower + r_division*(double)(rout % slots );
  264:                  }
  265:                } else {
  266:                  resultp->s_type = S_CONSTANT;
  267:                  resultp->s_str = strsave("<<2ND ARG MUST .GE. 1ST ARG>>");
  268:                  sprintf(tmpS,"random()'s second arg. must be greater than the first arg.\n");
  269:                  capa_msg(MESSAGE_ERROR,tmpS);
  270:                }
  271:               } else {
  272:                 resultp->s_type = S_CONSTANT;
  273:                 resultp->s_str = strsave("<<ARG CANNOT BE STRING>>");
  274:                 sprintf(tmpS,"random() cannot accept string as argument.\n");
  275:                 capa_msg(MESSAGE_ERROR,tmpS);
  276:               }
  277:           } break;
  278:     case CHOOSE_F: { int        ii, pick=1;
  279:                      ArgNode_t *tmpArgp;
  280:                      
  281:                      noError = 1;
  282:                      tmpArgp = argp; ii=0;
  283:                      while( ii < argc-1 ) {tmpArgp = tmpArgp->a_next; ii++; }
  284:                      switch( FIRST_ARGTYPE(tmpArgp) ) {
  285:                        case IDENTIFIER:
  286:                          sprintf(tmpS,"The first argument to choose(): \"%s\" has not been defined yet. I will choose the first element.\n",FIRST_ARGNAME(tmpArgp));
  287:                          capa_msg(MESSAGE_ERROR,tmpS);
  288:                          pick = 1;
  289:                          break;
  290:                        case I_VAR: case I_CONSTANT:
  291:                          pick = FIRST_ARGINT(tmpArgp); break;
  292:                        case R_VAR: case R_CONSTANT:
  293:                          pick = (int)FIRST_ARGREAL(tmpArgp); 
  294:                          sprintf(tmpS,"The first argument to choose() is a real number: \"%.15g\", it must be an integer, I will use %d instead.\n",FIRST_ARGREAL(tmpArgp),pick);
  295:                          capa_msg(MESSAGE_ERROR,tmpS);
  296:                          break;
  297:                        case S_VAR: case S_CONSTANT:
  298:                          resultp->s_type = S_CONSTANT;
  299:                          resultp->s_str = strsave("CHOOSE: first argument must be an integer");
  300:                          sprintf(tmpS,"The first argument to choose() cannot be a string, I will choose the first element.\n");
  301:                          capa_msg(MESSAGE_ERROR,tmpS);
  302:                          pick = 1;
  303:                          break;      
  304:                      }
  305:                      if( noError ) {
  306:                        if( (pick <= 0) || (pick > argc-1) ) { 
  307:                          sprintf(tmpS,"The first argument to choose() is out of bounds, tt is %d, but should be in the range [1,%d].\n", pick, argc-1);
  308:                          capa_msg(MESSAGE_ERROR,tmpS);
  309:                          pick = argc-1;
  310:                        } else { pick = argc - pick; }
  311:                        for(ii=1,tmpArgp = argp;(ii < pick)&&(ii < argc-1);ii++) { tmpArgp =  tmpArgp->a_next; }
  312:                        
  313:                        resultp->s_type = (tmpArgp->a_sp)->s_type;
  314:                        switch((tmpArgp->a_sp)->s_type) {
  315:                          case IDENTIFIER: 
  316:                               sprintf(tmpS,"The variable \"%s\" selected by choose() has not yet been defined.\n",(tmpArgp->a_sp)->s_name);
  317:                               capa_msg(MESSAGE_ERROR,tmpS);
  318:                               resultp->s_type = S_CONSTANT;
  319:                               resultp->s_str = strsave(tmpS);
  320:                               break;
  321:                          case I_VAR: case I_CONSTANT:
  322:                               resultp->s_type = I_CONSTANT;
  323:                               resultp->s_int = (tmpArgp->a_sp)->s_int; break;
  324:                          case R_VAR: case R_CONSTANT:
  325:                               resultp->s_type = R_CONSTANT;
  326:                               resultp->s_real = (tmpArgp->a_sp)->s_real; break;
  327:                          case S_VAR: case S_CONSTANT:
  328:                               resultp->s_type = S_CONSTANT;
  329:                               resultp->s_str = strsave((tmpArgp->a_sp)->s_str); break; /********* */
  330:                        }
  331:                        
  332:                      }
  333:                      
  334:                  } break;
  335:     case PIN_F: { 
  336:                   if (-1==(tmpInt=which_set(argc,argp,resultp))) break;
  337:                   resultp->s_type = I_CONSTANT;
  338:                   resultp->s_int=capa_PIN(Parse_student_number,tmpInt,0);
  339:                 }
  340:                 break;
  341:     case CLASS_F: {
  342:                   resultp->s_type = S_CONSTANT;
  343:                   if(strlen(Parse_class) != 0 ) {
  344:                     resultp->s_str=strsave(Parse_class);
  345:                   } else {
  346:                     resultp->s_str=strsave("UNKNOWN");
  347:                   }
  348:                  }
  349:                   break;
  350:     case SECTION_F:{ resultp->s_type = I_CONSTANT;
  351:                      resultp->s_int = Parse_section;
  352:                    } break;
  353:     case PROBLEM_F:{ resultp->s_type = I_CONSTANT;
  354:                      resultp->s_int= Lexi_qnum+1;
  355:                    } break;
  356:     case SET_F:    { resultp->s_type = I_CONSTANT;
  357:                      resultp->s_int=Parse_set;
  358:                    } break;
  359:     case NAME_F:   {
  360:                      resultp->s_type = S_CONSTANT;
  361:                      resultp->s_str=strsave(Parse_name);
  362:                    } break;
  363:     case SNUMBER_F: {
  364:                      resultp->s_type = S_CONSTANT;
  365:                      resultp->s_str=strsave(Parse_student_number);
  366:                    } break;
  367:     case IS_DUE_F: 
  368:     case IS_ANSWER_F: 
  369:     case IS_OPEN_F: {
  370:                       int whichDate=CHECK_OPEN_DATE;
  371:                       if (-1==(tmpInt=which_set(argc,argp,resultp))) break;
  372: 		      resultp->s_type = I_CONSTANT;
  373:                       switch(func) {
  374: 		      case IS_OPEN_F: whichDate=CHECK_OPEN_DATE;break;
  375: 		      case IS_DUE_F: whichDate=CHECK_DUE_DATE;break;
  376: 		      case IS_ANSWER_F: whichDate=CHECK_ANS_DATE;break;
  377: 		      }
  378: 		      if( capa_check_date(whichDate,Parse_student_number,
  379: 					  Parse_section,tmpInt) < 0 ) {
  380: 			resultp->s_int = 0;
  381: 		      } else {
  382: 			resultp->s_int = 1;
  383: 		      }
  384:                     } break;
  385:     case DUE_DATE_F:
  386:              { if (-1==(tmpInt=which_set(argc,argp,resultp))) break;
  387:                resultp->s_type = S_CONSTANT;
  388:                if(capa_get_date(CHECK_DUE_DATE,Parse_student_number,Parse_section,tmpInt,date_str) > 0 ) {
  389:                  sscanf(date_str,"%4d/%2d/%2d %2d:%2d",&yy, &mo, &dd, &hh, &mm);
  390:                  sprintf(aline, "%s %s %2d, %4d at %02d:%02d", 
  391:                    wday[weekday(yy,mo,dd)], month[mo], dd, yy, hh, mm);
  392:                  resultp->s_str= strsave(aline);
  393:                } else {
  394:                  resultp->s_str= strsave("UNKNOWN");
  395:                }
  396:              } break;
  397:     case DUE_DAY_F:
  398:              { if (-1==(tmpInt=which_set(argc,argp,resultp))) break;
  399:                resultp->s_type = S_CONSTANT;
  400:                if(capa_get_date(CHECK_DUE_DATE,Parse_student_number,Parse_section,tmpInt,date_str) > 0 ) {
  401:                  sscanf(date_str,"%4d/%2d/%2d %2d:%2d",&yy, &mm, &dd, &hh, &mm);
  402:                  sprintf(aline, "%s %s %2d, %4d", 
  403:                    wday[weekday(yy,mo,dd)], month[mo], dd, yy); 
  404:                  resultp->s_str= strsave(aline);
  405:                } else {
  406:                  resultp->s_str= strsave("UNKNOWN");
  407:                }
  408:              } break;         
  409:     case OPEN_DATE_F:
  410:              { if (-1==(tmpInt=which_set(argc,argp,resultp))) break;
  411:                resultp->s_type = S_CONSTANT;
  412:                if(capa_get_date(CHECK_OPEN_DATE,Parse_student_number,Parse_section,tmpInt,date_str) > 0 ) {
  413:                  sscanf(date_str,"%4d/%2d/%2d %2d:%2d",&yy, &mm, &dd, &hh, &mm);
  414:                  sprintf(aline, "%s %s %2d, %4d at %02d:%02d", 
  415:                    wday[weekday(yy,mo,dd)], month[mo], dd, yy, hh, mm); 
  416:                  resultp->s_str= strsave(aline);
  417:                } else {
  418:                  resultp->s_str= strsave("UNKNOWN");
  419:                }
  420:              } break;
  421:     case ANSWER_DATE_F:
  422:              { if (-1==(tmpInt=which_set(argc,argp,resultp))) break;
  423:                resultp->s_type = S_CONSTANT;
  424:                if(capa_get_date(CHECK_ANS_DATE,Parse_student_number,Parse_section,tmpInt,date_str) > 0 ) {
  425:                  sscanf(date_str,"%4d/%2d/%2d %2d:%2d",&yy, &mo, &dd, &hh, &mm);
  426:                  sprintf(aline, "%s %s %2d, %4d at %02d:%02d", 
  427:                    wday[weekday(yy,mo,dd)], month[mo], dd, yy, hh, mm); 
  428:                  resultp->s_str= strsave(aline);
  429:                } else {
  430:                  resultp->s_str= strsave("UNKNOWN");
  431:                }
  432:              } break;
  433:     case STRLEN_F: {
  434:                   resultp->s_type = I_CONSTANT;
  435:                switch( FIRST_ARGTYPE(argp) ) {
  436:                   case I_VAR:
  437:                   case I_CONSTANT:
  438:                          resultp->s_type = S_CONSTANT;
  439:                          sprintf(tmpS,"strlen() only accepts string variable, not integer.\n");
  440: 			 capa_msg(MESSAGE_ERROR,tmpS);
  441: 			 resultp->s_str=strsave(tmpS);
  442:                          break;
  443:                   case R_VAR:
  444:                   case R_CONSTANT:
  445:                          resultp->s_type = S_CONSTANT;
  446:                          sprintf(tmpS,"strlen() only accepts string variable, not float number.\n");
  447: 			 capa_msg(MESSAGE_ERROR,tmpS);
  448: 			 resultp->s_str=strsave(tmpS);
  449:                          break;
  450:                   case S_VAR:
  451:                   case S_CONSTANT:
  452:                          resultp->s_int = strlen( FIRST_ARGSTR(argp) );
  453:                          break;
  454: 		  case IDENTIFIER:
  455: 			 sprintf(tmpS,"Unknown variable, %s, argument to function strlen()\n",argp->a_sp->s_name);
  456: 			 capa_msg(MESSAGE_ERROR,tmpS);
  457: 			 resultp->s_str=strsave(tmpS);
  458: 			 break;
  459:                }
  460:              } break;
  461:     case TO_STRING_F:
  462:             { char aline[MAX_BUFFER_SIZE],rline[MAX_BUFFER_SIZE];
  463:               
  464:               resultp->s_type = S_CONSTANT;
  465: 
  466:               if( argc == 1 ) {
  467:                 switch( FIRST_ARGTYPE(argp) ) {
  468:                   case I_VAR:
  469:                   case I_CONSTANT:
  470:                          sprintf(aline,"%ld",FIRST_ARGINT(argp));
  471:                          resultp->s_str = strsave(aline); break;
  472:                   case R_VAR:
  473:                   case R_CONSTANT:
  474:                          sprintf(aline,"%.15g",FIRST_ARGREAL(argp));
  475:                          resultp->s_str = strsave(aline); break;
  476:                   case S_VAR:
  477:                   case S_CONSTANT:
  478:                          resultp->s_str = strsave(FIRST_ARGSTR(argp)); break;
  479: 		  case IDENTIFIER:
  480: 			 sprintf(tmpS,"Unknown variable, %s, argument to function to_string()\n",argp->a_sp->s_name);
  481: 			 capa_msg(MESSAGE_ERROR,tmpS);
  482: 			 resultp->s_str=strsave(tmpS);
  483: 			 break;
  484:                 }
  485:               } else {
  486:                 switch( FIRST_ARGTYPE(argp) ) {
  487:                   case I_VAR:
  488:                   case I_CONSTANT:
  489:                   case R_VAR:
  490:                   case R_CONSTANT: 
  491:                          sprintf(tmpS,
  492:                           "to_string()'s second arg. must be a string.\n");
  493:                          capa_msg(MESSAGE_ERROR,tmpS);
  494:                          sprintf(aline,"%%.15g");
  495:                          break;
  496:                   case S_VAR:
  497:                   case S_CONSTANT: 
  498:                          sprintf(aline,"%%%s",FIRST_ARGSTR(argp));
  499:                          break;
  500: 		  case IDENTIFIER:
  501: 			 sprintf(tmpS,"Unknown variable, %s, argument to function to_string()\n",argp->a_next->a_sp->s_name);
  502: 			 capa_msg(MESSAGE_ERROR,tmpS);
  503: 			 resultp->s_str=strsave(tmpS);
  504: 			 break;
  505: 
  506:                 }
  507:                 switch( SECOND_ARGTYPE(argp) ) {
  508:                   case I_VAR:
  509:                   case I_CONSTANT:
  510:                          sprintf(aline,"%ld",SECOND_ARGINT(argp));
  511:                          resultp->s_str = strsave(aline);  break;
  512:                   case R_VAR:
  513:                   case R_CONSTANT:
  514:                          sprintf(rline,aline,SECOND_ARGREAL(argp));
  515:                          resultp->s_str = strsave(rline);  break;
  516:                   case S_VAR:
  517:                   case S_CONSTANT: 
  518:                          resultp->s_str = strsave(SECOND_ARGSTR(argp));
  519:                          break;
  520: 		  case IDENTIFIER:
  521: 			 sprintf(tmpS,"Unknown variable, %s, argument to function to_string()\n",argp->a_sp->s_name);
  522: 			 capa_msg(MESSAGE_ERROR,tmpS);
  523: 			 resultp->s_str=strsave(tmpS);
  524: 			 break;
  525:                 }
  526:               }
  527:             } break;
  528:     case SUB_STRING_F: /* sub_string(str, 2), 1 is the first char */
  529:                        /* sub_string(str, 3, 5) means start from the third char and take 5 chars */
  530:             { int   idx=1, leng, rleng=0,ii;
  531:               char *a_str, *b_str;
  532:               
  533:               resultp->s_type = S_CONSTANT;
  534:               if( argc == 2 ) { /* two arguments format */
  535:                 switch( FIRST_ARGTYPE(argp) ) {
  536:                   case IDENTIFIER:
  537:                          sprintf(tmpS,
  538:                           "sub_string()'s second arg. must be an integer.\n");
  539:                          capa_msg(MESSAGE_ERROR,tmpS);
  540:                          break;
  541:                   case I_VAR:
  542:                   case I_CONSTANT:
  543:                          idx = FIRST_ARGINT(argp);
  544:                          break;
  545:                   case R_VAR:
  546:                   case R_CONSTANT: 
  547:                          idx = (int) FIRST_ARGREAL(argp);
  548:                          break;
  549:                   case S_VAR:
  550:                   case S_CONSTANT: 
  551:                          sprintf(tmpS,
  552:                           "sub_string()'s second arg. must be an integer.\n");
  553:                          capa_msg(MESSAGE_ERROR,tmpS);
  554:                          break;
  555:                 }
  556:                 switch( SECOND_ARGTYPE(argp) ) {
  557:                   case IDENTIFIER:
  558:                          sprintf(tmpS,
  559:                           "sub_string()'s first arg. is not defined before use.\n");
  560:                          capa_msg(MESSAGE_ERROR,tmpS);
  561:                          break;
  562:                   case I_VAR:
  563:                   case I_CONSTANT:
  564:                          sprintf(tmpS,
  565:                           "sub_string()'s first arg. cannot be an integer.\n");
  566:                          capa_msg(MESSAGE_ERROR,tmpS);
  567:                          break;
  568:                   case R_VAR:
  569:                   case R_CONSTANT:
  570:                          sprintf(tmpS,
  571:                           "sub_string()'s first arg. cannot be a number.\n");
  572:                          capa_msg(MESSAGE_ERROR,tmpS);
  573:                          break;
  574:                   case S_VAR:
  575:                   case S_CONSTANT:
  576:                          a_str = SECOND_ARGSTR(argp);
  577:                          leng = strlen(a_str);
  578:                          if( (idx<1) || (idx > leng) ) {
  579:                            sprintf(tmpS, "sub_string()'s second arg. is out of range.\n");
  580:                            capa_msg(MESSAGE_ERROR,tmpS);
  581:                            idx = 1;
  582:                          } 
  583:                          b_str = (char *)&a_str[idx-1];
  584:                          resultp->s_str = strsave(b_str);
  585:                          
  586:                          if( SECOND_ARGTYPE(argp) == S_CONSTANT) {
  587: 			   /* freed in free arg_list */
  588: 			   /* capa_mfree((char *)SECOND_ARGSTR(argp)); */
  589:                          }
  590:                          break;
  591:                 }
  592:               } else { /* three arguments format sub_string(string, start, length) */
  593:                 switch( FIRST_ARGTYPE(argp) ) {
  594:                   case IDENTIFIER:
  595:                          sprintf(tmpS,
  596:                           "sub_string()'s third arg. must be an integer.\n");
  597:                          capa_msg(MESSAGE_ERROR,tmpS);
  598:                          break;
  599:                   case I_VAR:
  600:                   case I_CONSTANT:
  601:                          rleng = FIRST_ARGINT(argp);
  602:                          break;
  603:                   case R_VAR:
  604:                   case R_CONSTANT: 
  605:                          rleng = (int) FIRST_ARGREAL(argp);
  606:                          break;
  607:                   case S_VAR:
  608:                   case S_CONSTANT: 
  609:                          sprintf(tmpS,
  610:                           "sub_string()'s third arg. must be an integer.\n");
  611:                          capa_msg(MESSAGE_ERROR,tmpS);
  612:                          break;
  613:                 }
  614:                 switch( SECOND_ARGTYPE(argp) ) {
  615:                   case IDENTIFIER:
  616:                          sprintf(tmpS,
  617:                           "sub_string()'s second arg. must be an integer.\n");
  618:                          capa_msg(MESSAGE_ERROR,tmpS);
  619:                          break;
  620:                   case I_VAR:
  621:                   case I_CONSTANT:
  622:                          idx = SECOND_ARGINT(argp);
  623:                          break;
  624:                   case R_VAR:
  625:                   case R_CONSTANT: 
  626:                          idx = (int) SECOND_ARGREAL(argp);
  627:                          break;
  628:                   case S_VAR:
  629:                   case S_CONSTANT: 
  630:                          sprintf(tmpS,
  631:                           "sub_string()'s second arg. must be an integer.\n");
  632:                          capa_msg(MESSAGE_ERROR,tmpS);
  633:                          break;
  634:                 }
  635:                 switch( THIRD_ARGTYPE(argp) ) {
  636:                   case IDENTIFIER:
  637:                          sprintf(tmpS,
  638:                           "sub_string()'s first arg. is not defined before use.\n");
  639:                          capa_msg(MESSAGE_ERROR,tmpS);
  640:                          break;
  641:                   case I_VAR:
  642:                   case I_CONSTANT:
  643:                          sprintf(tmpS,
  644:                           "sub_string()'s first arg. cannot be an integer.\n");
  645:                          capa_msg(MESSAGE_ERROR,tmpS);
  646:                          break;
  647:                   case R_VAR:
  648:                   case R_CONSTANT:
  649:                          sprintf(tmpS,
  650:                           "sub_string()'s first arg. cannot be a number.\n");
  651:                          capa_msg(MESSAGE_ERROR,tmpS);
  652:                          break;
  653:                   case S_VAR:
  654:                   case S_CONSTANT:
  655:                          a_str = THIRD_ARGSTR(argp);
  656:                          leng = strlen(a_str);
  657:                          if( (idx < 1) || (idx > leng) ) {
  658:                            sprintf(tmpS, "sub_string()'s second arg. is out of range.\n");
  659:                            capa_msg(MESSAGE_ERROR,tmpS);
  660:                            idx = 1;
  661:                          }
  662:                          if( (rleng<1) || ((rleng+idx-1) > leng)) {
  663:                            
  664:                            rleng = leng - idx + 1;
  665:                          }
  666:                          b_str = (char *)capa_malloc((rleng+1)*sizeof(char),1);
  667:                          for(ii=idx-1;ii<(rleng+idx-1);ii++) {
  668:                              b_str[ii-idx+1] = a_str[ii];
  669:                          }
  670:                          resultp->s_str = strsave(b_str);
  671:                          capa_mfree(b_str);
  672:                          
  673:                          if( THIRD_ARGTYPE(argp) == S_CONSTANT) {
  674: 			   /* handled in free_arglist() */
  675: 			   /* capa_mfree((char *)THIRD_ARGSTR(argp)); */
  676:                          }
  677:                          break;
  678:                 }
  679:               }
  680:             } break;
  681:     case PICK_F: { int    ii, pick=1;
  682:               ArgNode_t  *tmpArgp;
  683:               
  684:               noError = 1;
  685:               rout = ignlgi();
  686:               tmpArgp = argp; ii=0;
  687:               while( ii < argc-1 ) {tmpArgp = tmpArgp->a_next; ii++; }
  688:               switch( FIRST_ARGTYPE(tmpArgp) ) {
  689:                 case I_VAR:
  690:                 case I_CONSTANT:
  691:                        pick = FIRST_ARGINT(tmpArgp); 
  692:                        if( (pick <= 0 ) || (pick > argc-1) )  {
  693:                          noError = 0;
  694:                          resultp->s_type = S_CONSTANT;
  695:                          resultp->s_str = strsave("PICK: first arg out of bound.");
  696:                        }
  697:                        break;
  698:                 case R_VAR:
  699:                 case R_CONSTANT:
  700:                        pick = (int)FIRST_ARGREAL(tmpArgp);
  701:                        if( (pick <= 0 ) || (pick > argc-1) )  {
  702:                          noError = 0;
  703:                          resultp->s_type = S_CONSTANT;
  704:                          resultp->s_str = strsave("PICK: first arg out of bound.");
  705:                        }
  706:                        break;
  707:                 case S_VAR:
  708:                 case S_CONSTANT: noError = 0;
  709:                        resultp->s_type = S_CONSTANT;
  710:                        resultp->s_str = strsave("PICK: first arg must be int");
  711:                        break;      
  712:               }
  713:               if( noError ) {
  714:                 for( ii=0; ii< pick; ii++) {
  715:                 }
  716:               }
  717:             }
  718:             break;
  719:     case GET_SEED_F: 
  720:             { long  seed1, seed2;
  721:               char *tmp;
  722:               
  723:               getsd(&seed1,&seed2);
  724:               tmp = (char *)capa_malloc(32,1);
  725:               sprintf(tmp,"%ld,%ld",seed1,seed2);
  726:               resultp->s_type = S_CONSTANT;
  727:               resultp->s_str  = strsave(tmp);
  728:               capa_mfree(tmp);
  729:             } break;
  730:     case SET_SEED_F:
  731:             { long  seed1, seed2;
  732: 	      int leng;
  733:               
  734:               switch( FIRST_ARGTYPE(argp) ) {
  735:                 case I_VAR: case I_CONSTANT: break;
  736:                 case R_VAR: case R_CONSTANT: break;
  737:                 case S_VAR: case S_CONSTANT: 
  738:                        leng = strlen(FIRST_ARGSTR(argp));
  739: 		       if( (index(FIRST_ARGSTR(argp), ' ') != NULL) ) {
  740: 			 sscanf(FIRST_ARGSTR(argp),"%ld,%ld", &seed1, &seed2);
  741:                          setall(seed1,seed2);
  742:                        }
  743:                        
  744:                        break;
  745:               }
  746:               resultp->s_type = I_CONSTANT;
  747:               resultp->s_int  = 0;
  748:             } break;
  749:    case ARRAY_MOMENTS_F: /* it */
  750:             { 
  751:               char       *tmp_input;
  752:               Symbol     *r_p;
  753:               
  754:               switch( FIRST_ARGTYPE(argp) ) {
  755:                 case I_VAR: case I_CONSTANT:
  756:                 case R_VAR: case R_CONSTANT: 
  757:                       resultp->s_type = S_CONSTANT;
  758:                       resultp->s_str  = strsave("<<ARG. OF THIS FUNCTION MUST BE AN ARRAY NAME>>");
  759:                       sprintf(tmpS,"array_moments()'s arg. must be a name of an array.\n");
  760:                       capa_msg(MESSAGE_ERROR,tmpS);
  761:                       errCode = 1;
  762:                       break;
  763:                 case S_VAR: case S_CONSTANT: 
  764:                        tmp_input = strsave(FIRST_ARGSTR(argp));
  765:                        errCode = 0;
  766:                        break;
  767:                 case IDENTIFIER:
  768:                        tmp_input = strsave(FIRST_ARGNAME(argp));
  769:                        errCode = 0;
  770:                        break;
  771:               }
  772:               if( errCode == 0 ) {
  773:                 switch( SECOND_ARGTYPE(argp) ) {
  774:                   case I_VAR: case I_CONSTANT: 
  775:                   case R_VAR: case R_CONSTANT: 
  776:                       resultp->s_type = S_CONSTANT;
  777:                       resultp->s_str  = strsave("<<ARG. OF THIS FUNCTION MUST BE AN ARRAY NAME>>");
  778:                       sprintf(tmpS,"array_moments()'s arg. must be a name of an array.\n");
  779:                       capa_msg(MESSAGE_ERROR,tmpS);
  780:                       errCode = 1;
  781:                       break;
  782:                   case S_VAR: case S_CONSTANT:
  783:                       r_p = array_moments(SECOND_ARGSTR(argp),tmp_input);
  784:                       capa_mfree((char *)tmp_input);
  785:                       /* fprintf(stdout,"DONE array_moments()\n"); fflush(stdout); */
  786:                       break;
  787:                   case IDENTIFIER:
  788:                       r_p = array_moments(SECOND_ARGNAME(argp),tmp_input);
  789:                       capa_mfree((char *)tmp_input);
  790:                       
  791:                       break;
  792:                 }
  793:                 if(errCode == 0 ) {
  794:                   capa_mfree((char *)resultp);
  795:                   resultp = r_p;
  796:                 }
  797:               }
  798:               
  799:             } break;
  800:     case ARRAY_SORTED_INDEX_F:  /* array_sorted_index(array_name_str, sort_type) */
  801:             {              
  802:               switch( FIRST_ARGTYPE(argp) ) {
  803:                 case I_VAR: case I_CONSTANT: 
  804:                        switch( FIRST_ARGINT(argp) ) {
  805:                            case  ASCEND_SORT:     break;
  806:                            case  DESCEND_SORT:    break;
  807:                            case  NUMERICAL_SORT:  break;
  808:                            default: break;
  809:                        }
  810:                        
  811:                        break;
  812:                 case R_VAR: case R_CONSTANT: break;
  813:                 case S_VAR: case S_CONSTANT: 
  814:                        
  815:                        
  816:                        break;
  817:               }
  818:               resultp->s_type = S_CONSTANT;
  819:               resultp->s_str  = strsave("NOT YET");
  820:             } break;
  821:     
  822:     case ARRAY_MAX_F: 
  823:     case ARRAY_MIN_F:
  824:             { int         min;
  825:               Symbol     *r_p;
  826:               
  827:               min = ((func==ARRAY_MIN_F)? 1 : 0);           
  828:               switch( FIRST_ARGTYPE(argp) ) {
  829:                 case I_VAR: case I_CONSTANT: 
  830:                 case R_VAR: case R_CONSTANT: 
  831:                       resultp->s_type = S_CONSTANT;
  832:                       resultp->s_str  = strsave("<<ARG. OF THIS FUNCTION MUST BE AN ARRAY NAME>>");
  833:                       sprintf(tmpS,"%s()'s arg. must be a name of an array.\n",(min ? "min" : "max"));
  834:                       capa_msg(MESSAGE_ERROR,tmpS);
  835:                       break;
  836:                 case S_VAR: case S_CONSTANT: /* this allows the use of min(array[1]) which array[1]="another" */
  837:                       r_p = array_min_max(FIRST_ARGSTR(argp),min);
  838:                       if( r_p == NULL ) { /* array name is not in array tree */
  839:                         resultp->s_type = S_CONSTANT;
  840:                         resultp->s_str  = strsave("<<STRING ARRAY NAME IS NOT YET DEFINED!>>");
  841:                       } else {
  842:                       /*
  843:                        fprintf(stdout,"min_max():: STR arg. R=%g\n",r_p->s_real); fflush(stdout);
  844:                       */
  845:                         capa_mfree((char *)resultp);
  846:                         resultp = r_p;
  847:                       }
  848:                       break;
  849:                 case IDENTIFIER:
  850:                       r_p = array_min_max(FIRST_ARGNAME(argp),min);
  851:                       if( r_p == NULL ) { /* array name is not in array tree */
  852:                         /* fprintf(stdout,"min_max() return NULL\n"); fflush(stdout); */
  853:                         resultp->s_type = S_CONSTANT;
  854:                         resultp->s_str  = strsave("<<ARRAY NAME IS NOT YET DEFINED!>>");
  855:                       } else {
  856:                         /*
  857:                          fprintf(stdout,"min_max():: ID arg. R=%g\n",r_p->s_real); fflush(stdout);
  858:                         */
  859:                         capa_mfree((char *)resultp);
  860:                         resultp = r_p;
  861:                       }
  862:                       break;
  863:               }
  864:             } break;       
  865:     case SIN_F:
  866:     case COS_F:
  867:     case TAN_F:
  868:     case ASIN_F:
  869:     case ACOS_F:
  870:     case ATAN_F:
  871:     case SINH_F:
  872:     case COSH_F:
  873:     case TANH_F:
  874:     case ASINH_F:
  875:     case ACOSH_F:
  876:     case ATANH_F:
  877:     case J_ZERO_F:
  878:     case J_ONE_F:
  879:     case Y_ZERO_F:
  880:     case Y_ONE_F:
  881:     case LOG_F:
  882:     case LOG_TEN_F:
  883:     case EXP_F:
  884:     case ERF_F:
  885:     case ERFC_F:
  886:     case ABS_F:
  887:     case SQRT_F:
  888:     case FLOOR_F:
  889:     case CEIL_F:
  890:     case SGN_F:{  if( (FIRST_ARGTYPE(argp) == S_VAR ) || (FIRST_ARGTYPE(argp) == S_CONSTANT ) ) {
  891:                     sprintf(aline,"<<ARG TYPE MISMATCH>>");
  892:                     resultp->s_type = S_CONSTANT;
  893:                     resultp->s_str = strsave(aline);
  894:                     sprintf(tmpS,"function %s() cannot accept string as argument.\n", FuncStack[Func_idx].s_name);
  895:                     capa_msg(MESSAGE_ERROR,tmpS);
  896:                   } else {
  897:                     if( (FIRST_ARGTYPE(argp) == I_VAR ) || (FIRST_ARGTYPE(argp) == I_CONSTANT ) ) {
  898:                       tmpA = (double)FIRST_ARGINT(argp);
  899:                     } else {
  900:                       tmpA = (double)FIRST_ARGREAL(argp);
  901:                     }
  902:                     resultp->s_type = R_CONSTANT;
  903:                     switch(func) {
  904:                        case SIN_F:     resultp->s_real = sin(tmpA); break;
  905:                        case COS_F:     resultp->s_real = cos(tmpA); break;
  906:                        case TAN_F:     resultp->s_real = tan(tmpA); break;
  907:                        case ASIN_F:    if(fabs(tmpA) <= 1.0) {
  908:                                          resultp->s_real = asin(tmpA);
  909:                                        } else {
  910:                                          resultp->s_type = S_CONSTANT;
  911:                                          sprintf(aline,"<<ARG OUT OF BOUND>>");
  912:                                          resultp->s_str = strsave(aline);
  913:                                          sprintf(tmpS, "asin()'s arg. is not in the range of [-1.0,+1.0].\n");
  914:                                          capa_msg(MESSAGE_ERROR,tmpS);
  915:                                        }
  916:                                        break;
  917:                        case ACOS_F:    if(fabs(tmpA) <= 1.0) {
  918:                                          resultp->s_real = acos(tmpA); 
  919:                                        } else {
  920:                                          resultp->s_type = S_CONSTANT;
  921:                                          sprintf(aline,"<<ARG OUT OF BOUND>>");
  922:                                          resultp->s_str = strsave(aline);
  923:                                          sprintf(tmpS,"acos()'s arg. is not in the range of [-1.0,+1.0].\n");
  924:                                          capa_msg(MESSAGE_ERROR,tmpS);
  925:                                        }
  926:                                        break;
  927:                        case ATAN_F:    resultp->s_real = atan(tmpA);  break;
  928:                        case SINH_F:    resultp->s_real = sinh(tmpA);  break;
  929:                        case COSH_F:    resultp->s_real = cosh(tmpA);  break;
  930:                        case TANH_F:    resultp->s_real = tanh(tmpA);  break;
  931:                        case ASINH_F:   resultp->s_real = asinh(tmpA); break;
  932:                        case ACOSH_F:   resultp->s_real = acosh(tmpA); break;
  933:                        case ATANH_F:   resultp->s_real = atanh(tmpA); break;
  934:                        case J_ZERO_F:  resultp->s_real = j0(tmpA);    break;
  935:                        case J_ONE_F:   resultp->s_real = j1(tmpA);    break;
  936:                        case Y_ZERO_F:  resultp->s_real = y0(tmpA);    break;
  937:                        case Y_ONE_F:   resultp->s_real = y1(tmpA);    break;
  938:                        case LOG_F:     resultp->s_real = log(tmpA);   break;
  939:                        case LOG_TEN_F: resultp->s_real = log10(tmpA); break;
  940:                        case EXP_F:     resultp->s_real = exp(tmpA);   break;
  941:                        case ERF_F:     resultp->s_real = erf(tmpA);   break;
  942:                        case ERFC_F:    resultp->s_real = erfc(tmpA);  break;
  943:                        case ABS_F:     resultp->s_real = fabs(tmpA);  break;
  944:                        case SQRT_F:    if( tmpA >= 0.0) {
  945:                                          resultp->s_real = sqrt(tmpA);
  946:                                        } else {
  947:                                          resultp->s_type = S_CONSTANT;
  948:                                          sprintf(aline,"<<ARG OUT OF BOUND>>");
  949:                                          resultp->s_str = strsave(aline);
  950:                                          sprintf(tmpS, "sqrt()'s arg. is not in the range of [0.0,+Inf].\n");
  951:                                          capa_msg(MESSAGE_ERROR,tmpS);
  952:                                        }
  953:                                        break;
  954:                        case FLOOR_F:   resultp->s_type = I_CONSTANT;
  955:                                        resultp->s_int = (long)floor(tmpA);  break;
  956:                        case CEIL_F:    resultp->s_type = I_CONSTANT;
  957:                                        resultp->s_int = (long)ceil(tmpA);  break;
  958:                        case SGN_F:     resultp->s_type = I_CONSTANT;
  959:                                        resultp->s_int = (int)SGN(tmpA);  break;
  960:                     }
  961:                   }
  962:                 }
  963:                 break;
  964:     case ATANTWO_F:
  965:     case J_N_F:
  966:     case Y_N_F:
  967:     case POW_F: {    noError = 1;
  968:                      switch(FIRST_ARGTYPE(argp)) {
  969:                       case I_VAR:
  970:                       case I_CONSTANT: tmpA = (double)FIRST_ARGINT(argp); break;
  971:                       case R_VAR:
  972:                       case R_CONSTANT: tmpA = FIRST_ARGREAL(argp); break;
  973:                       case S_VAR:
  974:                       case S_CONSTANT: noError = 0;
  975:                                        resultp->s_str = strsave("<<MIS TYPE>>"); 
  976:                                        sprintf(tmpS,"%s()'s second arg. cannot be string.\n",FuncStack[Func_idx].s_name);
  977:                                        capa_msg(MESSAGE_ERROR,tmpS);
  978:                                        break;
  979:                      }
  980:                      switch(SECOND_ARGTYPE(argp)) {
  981:                       case I_VAR:
  982:                       case I_CONSTANT: tmpB = (double)SECOND_ARGINT(argp); break;
  983:                       case R_VAR:
  984:                       case R_CONSTANT: tmpB = SECOND_ARGREAL(argp); break;
  985:                       case S_VAR:
  986:                       case S_CONSTANT: noError = 0;
  987:                                        resultp->s_str = strsave("<<MIS TYPE>>"); 
  988:                                        sprintf(tmpS,"%s()'s first arg. cannot be string.\n",FuncStack[Func_idx].s_name);
  989:                                        capa_msg(MESSAGE_ERROR,tmpS);
  990:                                        break;
  991:                      }
  992: 		     if ( POW_F == func ) {
  993: 		       if ((!(((double)((int)tmpA)) == tmpA)) && (tmpB < 0.0)) {
  994: 			 resultp->s_str = strsave("<<ARG OUT OF BOUND>>"); 
  995: 			 sprintf(tmpS,
  996: 				 "%s()'s arguments would result in a complex number.\n",
  997: 				 FuncStack[Func_idx].s_name);
  998: 			 capa_msg(MESSAGE_ERROR,tmpS);
  999: 			 noError=0;
 1000: 		       }
 1001: 		     }
 1002:                      if(noError) {
 1003:                        resultp->s_type = R_CONSTANT;
 1004:                        switch( func ) {
 1005:                          case J_N_F: resultp->s_real = jn((int)tmpB, tmpA); break;
 1006:                          case Y_N_F: resultp->s_real = yn((int)tmpB, tmpA); break;
 1007:                          case POW_F: resultp->s_real = pow(tmpB, tmpA); break;
 1008:                          case ATANTWO_F: resultp->s_real = atan2(tmpB, tmpA); break;
 1009:                        }
 1010:                      }else {
 1011:                        resultp->s_type = S_CONSTANT;
 1012:                      }
 1013:                      
 1014:                 }
 1015:                 break;
 1016:     case TEX_F: { if (Parsemode_f != TeX_MODE) {
 1017:                      resultp->s_type =  FIRST_ARGTYPE(argp);
 1018:                      switch(FIRST_ARGTYPE(argp)) {
 1019:                       case I_VAR:
 1020:                       case I_CONSTANT: resultp->s_int = FIRST_ARGINT(argp); break;
 1021:                       case R_VAR:
 1022:                       case R_CONSTANT: resultp->s_real = FIRST_ARGREAL(argp); break;
 1023:                       case S_VAR:
 1024:                       case S_CONSTANT: resultp->s_str = strsave(FIRST_ARGSTR(argp)); break;
 1025:                      }
 1026:                   } else {
 1027:                      resultp->s_type =  SECOND_ARGTYPE(argp);
 1028:                      switch(SECOND_ARGTYPE(argp)) {
 1029:                       case I_VAR:
 1030:                       case I_CONSTANT: resultp->s_int = SECOND_ARGINT(argp); break;
 1031:                       case R_VAR:
 1032:                       case R_CONSTANT: resultp->s_real = SECOND_ARGREAL(argp); break;
 1033:                       case S_VAR:
 1034:                       case S_CONSTANT: resultp->s_str = strsave(SECOND_ARGSTR(argp)); break;
 1035:                      }
 1036:                   }
 1037:                 }       break;
 1038:     case VAR_IN_TEX_F:{
 1039:                   
 1040:                   if (Parsemode_f == TeX_MODE) {
 1041:                      resultp->s_type =  FIRST_ARGTYPE(argp);
 1042:                      
 1043:                      switch(FIRST_ARGTYPE(argp)) {
 1044:                       case I_VAR:
 1045:                       case I_CONSTANT: resultp->s_int = FIRST_ARGINT(argp); break;
 1046:                       case R_VAR:
 1047:                       case R_CONSTANT: resultp->s_real = FIRST_ARGREAL(argp); break;
 1048:                       case S_VAR:
 1049:                       case S_CONSTANT: resultp->s_str = strsave(FIRST_ARGSTR(argp)); break;
 1050:                      }
 1051:                   } else {
 1052:                      resultp->s_type =  S_CONSTANT;
 1053:                      resultp->s_str = strsave("");
 1054:                      
 1055:                   }
 1056:                 }  break;
 1057:     case HTML_F: {  if (Parsemode_f == HTML_MODE) {
 1058:                       resultp->s_type =  FIRST_ARGTYPE(argp);
 1059:                       switch(FIRST_ARGTYPE(argp)) {
 1060:                         case I_VAR:
 1061:                         case I_CONSTANT: resultp->s_int = FIRST_ARGINT(argp);   break;
 1062:                         case R_VAR:
 1063:                         case R_CONSTANT: resultp->s_real = FIRST_ARGREAL(argp); break;
 1064:                         case S_VAR:
 1065:                         case S_CONSTANT: resultp->s_str = strsave(FIRST_ARGSTR(argp)); break;
 1066:                       }
 1067:                     } else {
 1068:                       resultp->s_type =  S_CONSTANT;
 1069:                       resultp->s_str = strsave("");
 1070:                     }
 1071:                     /* printf("HTML:%s\n",resultp->s_str); */
 1072:                 }   break;
 1073:     case WEB_F:
 1074:     case FORMAT_F: {  /*   web(ASCII,TeX,HTML)      */
 1075:                     if( argc == 3 ) {
 1076:                       switch(Parsemode_f) {
 1077:                         case HTML_MODE: {
 1078:                           resultp->s_type =  FIRST_ARGTYPE(argp);
 1079:                             switch(FIRST_ARGTYPE(argp)) {
 1080:                               case I_VAR:
 1081:                               case I_CONSTANT: resultp->s_int = FIRST_ARGINT(argp);   break;
 1082:                               case R_VAR:
 1083:                               case R_CONSTANT: resultp->s_real = FIRST_ARGREAL(argp); break;
 1084:                               case S_VAR:
 1085:                               case S_CONSTANT: resultp->s_str = strsave(FIRST_ARGSTR(argp)); break;
 1086:                             }
 1087:                           }  break;
 1088:                         case TeX_MODE: {
 1089:                           resultp->s_type =  SECOND_ARGTYPE(argp);
 1090:                             switch(SECOND_ARGTYPE(argp)) {
 1091:                               case I_VAR:
 1092:                               case I_CONSTANT: resultp->s_int = SECOND_ARGINT(argp); break;
 1093:                               case R_VAR:
 1094:                               case R_CONSTANT: resultp->s_real = SECOND_ARGREAL(argp); break;
 1095:                               case S_VAR:
 1096:                               case S_CONSTANT: resultp->s_str = strsave(SECOND_ARGSTR(argp)); break;
 1097:                             }
 1098:                           }  break;
 1099:                         default:       {
 1100:                           resultp->s_type =  THIRD_ARGTYPE(argp);
 1101:                             switch(THIRD_ARGTYPE(argp)) {
 1102:                               case I_VAR:
 1103:                               case I_CONSTANT: resultp->s_int = THIRD_ARGINT(argp); break;
 1104:                               case R_VAR:
 1105:                               case R_CONSTANT: resultp->s_real = THIRD_ARGREAL(argp); break;
 1106:                               case S_VAR:
 1107:                               case S_CONSTANT: resultp->s_str = strsave(THIRD_ARGSTR(argp)); break;
 1108:                             }
 1109:                           }  break;
 1110:                       }
 1111:                     } else {  /* argc == 2 */
 1112:                       switch(Parsemode_f) {
 1113:                         case TeX_MODE: {
 1114:                           resultp->s_type =  FIRST_ARGTYPE(argp);
 1115:                             switch(FIRST_ARGTYPE(argp)) {
 1116:                               case I_VAR:
 1117:                               case I_CONSTANT: resultp->s_int = FIRST_ARGINT(argp);   break;
 1118:                               case R_VAR:
 1119:                               case R_CONSTANT: resultp->s_real = FIRST_ARGREAL(argp); break;
 1120:                               case S_VAR:
 1121:                               case S_CONSTANT: resultp->s_str = strsave(FIRST_ARGSTR(argp)); break;
 1122:                             }
 1123:                           }  break;
 1124:                         default :      {
 1125:                           resultp->s_type =  SECOND_ARGTYPE(argp);
 1126:                             switch(SECOND_ARGTYPE(argp)) {
 1127:                               case I_VAR:
 1128:                               case I_CONSTANT: resultp->s_int = SECOND_ARGINT(argp); break;
 1129:                               case R_VAR:
 1130:                               case R_CONSTANT: resultp->s_real = SECOND_ARGREAL(argp); break;
 1131:                               case S_VAR:
 1132:                               case S_CONSTANT: resultp->s_str = strsave(SECOND_ARGSTR(argp)); break;
 1133:                             }
 1134:                           }  break;
 1135:                       }
 1136:                     }
 1137:                 }   break;
 1138:     case FACTORIAL_F: { 
 1139:                      int                 ii;
 1140:                      unsigned long long  l_fac;
 1141:                      double              d_fac;
 1142:                      
 1143:                      switch(FIRST_ARGTYPE(argp)) {
 1144:                       case I_VAR:
 1145:                       case I_CONSTANT: {
 1146:                               if( FIRST_ARGINT(argp) < 0 ) {
 1147:                                 sprintf(aline,"<<FACTORIAL ERROR>>");
 1148:                                 resultp->s_type = S_CONSTANT;
 1149:                                 resultp->s_str = strsave(aline);
 1150:                                 sprintf(tmpS,"%s()'s arg. cannot be less than zero.\n",FuncStack[Func_idx].s_name);
 1151:                                 capa_msg(MESSAGE_ERROR,tmpS);
 1152:                               } else {
 1153:                                 if( FIRST_ARGINT(argp) <= 20 ) {
 1154:                                   resultp->s_type =  I_CONSTANT;
 1155:                                   l_fac = 1;
 1156:                                   for(ii=2; ii <= FIRST_ARGINT(argp); ii++) { l_fac *= ii;  }
 1157:                                   resultp->s_int = l_fac;
 1158:                                 } else {
 1159:                                   resultp->s_type =  R_CONSTANT;
 1160:                                   d_fac = 362880.0;
 1161:                                   for(ii=10; ii <= FIRST_ARGINT(argp); ii++) { d_fac *= ii; }
 1162:                                   resultp->s_real = d_fac;
 1163:                                 }
 1164:                               }
 1165:                             }
 1166:                             break;
 1167:                       case R_VAR:
 1168:                       case R_CONSTANT: {
 1169:                               if( FIRST_ARGREAL(argp) < 0.0 ) {
 1170:                                 sprintf(aline,"<<FACTORIAL ERROR>>");
 1171:                                 resultp->s_type = S_CONSTANT;
 1172:                                 resultp->s_str = strsave(aline);
 1173:                                 sprintf(tmpS,"%s()'s arg. cannot be less than zero.\n", FuncStack[Func_idx].s_name);
 1174:                                 capa_msg(MESSAGE_ERROR,tmpS);
 1175:                               } else {
 1176:                                 if( FIRST_ARGREAL(argp) <= 20.0 ) {
 1177:                                   resultp->s_type =  I_CONSTANT;
 1178:                                   l_fac = 1;
 1179:                                   for(ii=2; ii <= FIRST_ARGREAL(argp); ii++)  { l_fac *= ii; }
 1180:                                   resultp->s_int = l_fac;
 1181:                                 } else {
 1182:                                   resultp->s_type =  R_CONSTANT;
 1183:                                   d_fac = 362880.0;
 1184:                                   for(ii=10; ii <= FIRST_ARGREAL(argp); ii++) { d_fac *= ii; }
 1185:                                   resultp->s_real = d_fac;
 1186:                                 }
 1187:                               }
 1188:                             }
 1189:                             break;
 1190:                       case S_VAR:
 1191:                       case S_CONSTANT: {
 1192:                               sprintf(aline,"<<FACTORIAL ERROR>>");
 1193:                               resultp->s_type = S_CONSTANT;
 1194:                               resultp->s_str = strsave(aline);
 1195:                               sprintf(tmpS,"%s()'s arg. cannot be of string type.\n",FuncStack[Func_idx].s_name);
 1196:                               capa_msg(MESSAGE_ERROR,tmpS);
 1197:                             }
 1198:                             break;
 1199:                     }
 1200:                 }       break;
 1201:     case MOD_F:         break;
 1202:     case REMAINDER_F:   break;
 1203:     case MAX_F:
 1204:     case MIN_F: {  int  ii, idx, type;
 1205:     
 1206:                    tmpArgp = argp;
 1207:                    tmpA = ((func == MIN_F)? MAX_DOUBLE : - MAX_DOUBLE);
 1208:                    type = R_CONSTANT; idx = -1;
 1209:                    noError = 1;
 1210:                    for(ii = 0; (ii < argc)&&(noError); ii++) {
 1211:                      switch (FIRST_ARGTYPE(tmpArgp)) {
 1212:                        case I_VAR:
 1213:                        case I_CONSTANT:
 1214:                                if( type == S_CONSTANT) {
 1215:                                  sprintf(aline,"<<ARG TYPE>>");
 1216:                                  resultp->s_type = S_CONSTANT;
 1217:                                  resultp->s_str = strsave(aline);
 1218:                                  sprintf(tmpS,"%s()'s arg. type cannot mix string with int or real.\n",FuncStack[Func_idx].s_name);
 1219:                                  capa_msg(MESSAGE_ERROR,tmpS);
 1220:                                  noError = 0;
 1221:                                } else {
 1222:                                  switch(func) {
 1223:                                    case MIN_F:
 1224:                                     if( tmpA <= FIRST_ARGINT(tmpArgp) ) {
 1225:                                      } else {
 1226:                                       idx = ii; type = I_CONSTANT;
 1227:                                       tmpA = (double)FIRST_ARGINT(tmpArgp);
 1228:                                     }
 1229:                                     break;
 1230:                                    case MAX_F:
 1231:                                     if( tmpA >= FIRST_ARGINT(tmpArgp) ) {
 1232:                                      } else {
 1233:                                       idx = ii; type = I_CONSTANT;
 1234:                                       tmpA = (double)FIRST_ARGINT(tmpArgp);
 1235:                                     }
 1236:                                     break;
 1237:                                  }
 1238:                                }
 1239:                                break;
 1240:                        case R_VAR:
 1241:                        case R_CONSTANT:
 1242:                                if( type == S_CONSTANT ) {
 1243:                                  sprintf(aline,"<<ARG TYPE>>");
 1244:                                  resultp->s_type = S_CONSTANT;
 1245:                                  resultp->s_str = strsave(aline);
 1246:                                  sprintf(tmpS,"%s()'s arg. type cannot mix string with int or real.\n",FuncStack[Func_idx].s_name);
 1247:                                  capa_msg(MESSAGE_ERROR,tmpS);
 1248:                                  noError = 0;
 1249:                                } else {
 1250:                                  switch(func) {
 1251:                                    case MIN_F:
 1252:                                     if( tmpA <= FIRST_ARGREAL(tmpArgp) ) {
 1253:                                     } else {
 1254:                                      idx = ii; type = R_CONSTANT;
 1255:                                      tmpA = FIRST_ARGREAL(tmpArgp);
 1256:                                     }
 1257:                                     break;
 1258:                                    case MAX_F:
 1259:                                     if( tmpA >= FIRST_ARGREAL(tmpArgp) ) {
 1260:                                     } else {
 1261:                                      idx = ii; type = R_CONSTANT;
 1262:                                      tmpA = FIRST_ARGREAL(tmpArgp);
 1263:                                     }
 1264:                                     break;
 1265:                                   }
 1266:                                }
 1267:                                break;
 1268:                        case S_VAR:      
 1269:                        case S_CONSTANT:
 1270:                               if( (ii != 0)&&(type != S_CONSTANT) ) {
 1271:                                  sprintf(aline,"<<ARG TYPE>>");
 1272:                                  resultp->s_type = S_CONSTANT;
 1273:                                  resultp->s_str = strsave(aline);
 1274:                                  sprintf(tmpS," %s()'s arg. type cannot mix string with int or real.\n",FuncStack[Func_idx].s_name);
 1275:                                  capa_msg(MESSAGE_ERROR,tmpS);
 1276:                                  noError = 0;
 1277:                               } else {
 1278:                                 if( ii == 0 )  { idx = 0; strcpy(tmpS, FIRST_ARGSTR(tmpArgp)); }
 1279:                                 type = S_CONSTANT;
 1280:                                 switch( func) {
 1281:                                  case MIN_F:
 1282:                                   if( strcmp(tmpS, FIRST_ARGSTR(tmpArgp)) <= 0 ) {
 1283:                                   } else {
 1284:                                     idx = ii;
 1285:                                     strcpy(tmpS, FIRST_ARGSTR(tmpArgp));
 1286:                                   }
 1287:                                   break;
 1288:                                  case MAX_F:
 1289:                                   if( strcmp(tmpS, FIRST_ARGSTR(tmpArgp)) >= 0 ) {
 1290:                                   } else {
 1291:                                     idx = ii;
 1292:                                     strcpy(tmpS, FIRST_ARGSTR(tmpArgp));
 1293:                                   }
 1294:                                   break;
 1295:                                 }
 1296:                               }
 1297:                               break;
 1298:                      }
 1299:                      tmpArgp = tmpArgp->a_next;
 1300:                    }
 1301:                    if( noError ) {
 1302:                      for(tmpArgp=argp,ii=0; ii<idx; ii++) { tmpArgp=tmpArgp->a_next; }
 1303:                      resultp->s_type = type;
 1304:                      switch(type) {
 1305:                        case I_CONSTANT: resultp->s_int = (tmpArgp->a_sp)->s_int;
 1306:                                       break;
 1307:                        case R_CONSTANT: resultp->s_real = (tmpArgp->a_sp)->s_real;
 1308:                                       break;
 1309:                        case S_CONSTANT: resultp->s_str = strsave((tmpArgp->a_sp)->s_str);
 1310:                                       break;
 1311:                      }
 1312:                    }
 1313:                    
 1314:                 }
 1315:                 break;
 1316:     case ROUNDTO_F: {
 1317:                      noError = 1; hh = 0;  /* reuse integer hh  and mm */
 1318:                      switch(FIRST_ARGTYPE(argp)) {
 1319:                       case I_VAR:
 1320:                       case I_CONSTANT: mm = FIRST_ARGINT(argp);    break;
 1321:                       case R_VAR:
 1322:                       case R_CONSTANT: mm = (int)FIRST_ARGREAL(argp); break;
 1323:                       case S_VAR:
 1324:                       case S_CONSTANT: noError = 0;
 1325:                                        resultp->s_type = S_CONSTANT;
 1326:                                        resultp->s_str = strsave("<<MIS TYPE>>"); 
 1327:                                        sprintf(tmpS, 
 1328:                                            "%s()'s second arg. cannot be string.\n",FuncStack[Func_idx].s_name);
 1329:                                        capa_msg(MESSAGE_ERROR,tmpS);
 1330:                                        break;
 1331:                      }
 1332:                      switch(SECOND_ARGTYPE(argp)) {
 1333:                       case I_VAR:
 1334:                       case I_CONSTANT: hh = SECOND_ARGINT(argp); break;
 1335:                       case R_VAR:
 1336:                       case R_CONSTANT: tmpA = SECOND_ARGREAL(argp); break;
 1337:                       case S_VAR:
 1338:                       case S_CONSTANT: noError = 0;
 1339:                                        resultp->s_type = S_CONSTANT;
 1340:                                        resultp->s_str = strsave("<<MIS TYPE>>"); 
 1341:                                        sprintf(tmpS, 
 1342:                                            "%s()'s first arg. cannot be string.\n",
 1343: 					       FuncStack[Func_idx].s_name);
 1344:                                        capa_msg(MESSAGE_ERROR,tmpS);
 1345:                                        break;
 1346:                      }
 1347:                      if(noError) {
 1348:                        resultp->s_type = R_CONSTANT;
 1349:                        if( hh != 0 ) {
 1350:                          resultp->s_type = I_CONSTANT;
 1351:                          resultp->s_int  = hh;
 1352:                        } else {
 1353:                          if ( mm >= 0 ) {
 1354:                            sprintf(fmt_str,"%%.%df",mm);
 1355:                            sprintf(num_str,fmt_str,tmpA);
 1356:                            tmpB = atof(num_str);
 1357:                            resultp->s_real = tmpB;
 1358:                          } else {
 1359:                            sprintf(tmpS,"%s()'s second arg. cannot be negative (%d).\n",
 1360: 				   FuncStack[Func_idx].s_name,mm);
 1361:                            capa_msg(MESSAGE_ERROR,tmpS);
 1362:                            resultp->s_real = tmpA;  /* not changed */
 1363:                          }
 1364:                        }
 1365:                      }
 1366:                     }    break;
 1367:     case EVALUATE_F: { char    *f_str, *v_str, *pt_str, *out_come;
 1368:                      noError = 1;
 1369:                      switch(FIRST_ARGTYPE(argp)) { /* now only accepts string like "0.0,0.1,0.2,0.3,0.4,0.5"  */
 1370:                       case I_VAR:
 1371:                       case I_CONSTANT: noError = 0;
 1372:                                        resultp->s_type = S_CONSTANT;
 1373:                                        resultp->s_str = strsave("<<Evaulate Formula: Pts TYPE incorrect>>");
 1374:                                        sprintf(tmpS, 
 1375:                                            "%s()'s third arg. cannot be integer.\n",FuncStack[Func_idx].s_name);
 1376:                                        capa_msg(MESSAGE_ERROR,tmpS);
 1377:                                      break;
 1378:                       case R_VAR:
 1379:                       case R_CONSTANT: noError = 0;
 1380:                                        resultp->s_type = S_CONSTANT;
 1381:                                        resultp->s_str = strsave("<<Evaulate Formula: Pts TYPE incorrect>>");
 1382:                                        sprintf(tmpS, 
 1383:                                            "%s()'s third arg. cannot be integer.\n",FuncStack[Func_idx].s_name);
 1384:                                        capa_msg(MESSAGE_ERROR,tmpS);
 1385:                                      break;
 1386:                       case S_VAR:
 1387:                       case S_CONSTANT: 
 1388:                                        pt_str = FIRST_ARGSTR(argp);
 1389:                                      break;
 1390:                      }
 1391:                      switch(SECOND_ARGTYPE(argp)) {
 1392:                       case I_VAR:
 1393:                       case I_CONSTANT: 
 1394:                       case R_VAR:
 1395:                       case R_CONSTANT: noError = 0;
 1396:                                        resultp->s_type = S_CONSTANT;
 1397:                                        resultp->s_str = strsave("<<Evaluate Formula: Var list TYPE incorrect>>");
 1398:                                        sprintf(tmpS, 
 1399:                                            "%s()'s second arg. cannot be number.\n",FuncStack[Func_idx].s_name);
 1400:                                        capa_msg(MESSAGE_ERROR,tmpS);
 1401:                                      break;
 1402: 
 1403:                       case S_VAR:
 1404:                       case S_CONSTANT: v_str = SECOND_ARGSTR(argp);
 1405:                                      break;
 1406:                      }
 1407:                      switch(THIRD_ARGTYPE(argp)) {
 1408:                       case I_VAR:
 1409:                       case I_CONSTANT: 
 1410:                       case R_VAR:
 1411:                       case R_CONSTANT: noError = 0;
 1412:                                        resultp->s_type = S_CONSTANT;
 1413:                                        resultp->s_str = strsave("<<Evaluate Formula: Formula TYPE incorrect>>");
 1414:                                        sprintf(tmpS, 
 1415:                                            "%s()'s first arg. cannot be number.\n",FuncStack[Func_idx].s_name);
 1416:                                        capa_msg(MESSAGE_ERROR,tmpS);
 1417:                                       break;
 1418:                       case S_VAR:
 1419:                       case S_CONSTANT: f_str = THIRD_ARGSTR(argp);
 1420:                                       break;
 1421:                      }
 1422:                      if(noError) {
 1423:                        resultp->s_type = S_CONSTANT;
 1424:                        /* printf("EVALUATE:::%s,%s,%s\n",f_str, v_str, pt_str); */
 1425:                        out_come = eval_formula_range_str(f_str, v_str, pt_str);
 1426:                        if( !out_come ) {
 1427:                          resultp->s_str = strsave("<<Evaluate formula:: NULL>>");
 1428:                          sprintf(tmpS, 
 1429:                            "%s() cannot evaluate the formula correctly.\n",FuncStack[Func_idx].s_name);
 1430:                            capa_msg(MESSAGE_ERROR,tmpS);
 1431:                        } else {
 1432:                          resultp->s_str = out_come;
 1433:                        }
 1434:                      }
 1435:                     }
 1436:                     break;
 1437:     case CAPAID_PLUS:
 1438:                     {
 1439: 		      extern Problem_t* FirstProblem_p;
 1440: 		      extern Problem_t* LexiProblem_p;
 1441: 		      Problem_t* problem; 
 1442: 		      int        num_char,pin;
 1443: 		      errCode = 0;
 1444: 		      if (argc==1) {
 1445: 			switch( FIRST_ARGTYPE(argp) ) {
 1446: 			case I_VAR: case I_CONSTANT: num_char=FIRST_ARGINT(argp); break;
 1447: 			case R_VAR: case R_CONSTANT: errCode = 1; break;
 1448: 			case S_VAR: case S_CONSTANT: errCode = 1; break;
 1449: 			}
 1450: 		      } else {
 1451: 			switch( SECOND_ARGTYPE(argp) ) {
 1452: 			case I_VAR: case I_CONSTANT: num_char=SECOND_ARGINT(argp); break;
 1453: 			case R_VAR: case R_CONSTANT: errCode = 1; break;
 1454: 			case S_VAR: case S_CONSTANT: errCode = 1; break;
 1455: 			}
 1456: 		      }
 1457: 		      
 1458: 		      if( errCode == 0 ) {
 1459: 			if ( FirstProblem_p ) {
 1460: 			  problem=FirstProblem_p;
 1461: 			} else {
 1462: 			  problem=LexiProblem_p;
 1463: 			}
 1464: 			if (!(problem->capaidplus)) capa_mfree(problem->capaidplus);
 1465: 			if (-1==(tmpInt=which_set(argc-1,argp,resultp))) break;
 1466: 			pin=capa_PIN(Parse_student_number,tmpInt,0);
 1467: 			problem->capaidplus = capa_id_plus(Parse_student_number,
 1468: 							   tmpInt,num_char);
 1469: 			resultp->s_type = S_CONSTANT;
 1470: 			resultp->s_str = strsave(problem->capaidplus);
 1471: 		      } else {
 1472: 			resultp->s_type = S_CONSTANT;
 1473: 			resultp->s_str = strsave("<<INCORRECT ARGS TO CAPAID_PLUS>>");
 1474: 		      }
 1475: 		    }
 1476: 		    break;
 1477:     case SEAT_NUMBER:
 1478:                     { 
 1479: 		      int filenum;
 1480: 		      double filedoub;
 1481: 		      char *filename;
 1482: 		      if ( argc == 1 ) {
 1483: 			switch( FIRST_ARGTYPE(argp)) {
 1484: 			case I_VAR: case I_CONSTANT: filenum=FIRST_ARGINT(argp); 
 1485: 			  filename=capa_malloc(TMP_LINE_LENGTH,1);
 1486: 			  sprintf(filename,"%d",filenum);
 1487: 			  break;
 1488: 			case R_VAR: case R_CONSTANT: filedoub=FIRST_ARGREAL(argp); 
 1489: 			  filename=capa_malloc(TMP_LINE_LENGTH,1);
 1490: 			  sprintf(filename,"%f",filedoub);
 1491: 			  break;
 1492: 			case S_VAR: case S_CONSTANT: 
 1493: 			  filename=strsave(FIRST_ARGSTR(argp)); break;
 1494: 			}
 1495: 		      } else {
 1496: 			filename=NULL;
 1497: 		      }
 1498: 		      resultp->s_type = S_CONSTANT;
 1499:                       resultp->s_str = capa_get_seat(Parse_student_number,filename);
 1500: 		      if ( filename != NULL ) capa_mfree(filename);
 1501:                       break;
 1502:                     }
 1503:     case DURATION: { resultp->s_type = I_CONSTANT;
 1504:                      resultp->s_int=capa_get_duration(Parse_student_number,
 1505: 						      Parse_section,Parse_set);
 1506:                    } break;
 1507:     case MANAGERMODE_F: { resultp->s_type = I_CONSTANT;
 1508:                           resultp->s_int=managermode;
 1509:                         }break;
 1510:     case CORRECT_F: {
 1511:       
 1512:                     }break;
 1513: 
 1514:     case TRIES_F: {
 1515:                       
 1516:                   }break;
 1517: 
 1518:     case GRADE_F: {
 1519:                       
 1520:                   }break;
 1521: 
 1522:     case MIS_ARG_COUNT:
 1523:                     { resultp->s_type = S_CONSTANT;
 1524:                       resultp->s_str = strsave("<<ARG COUNT>>");
 1525:                       sprintf(tmpS,"%s()'s arg. count is not correct.\n",
 1526: 			      FuncStack[Func_idx].s_name);
 1527:                       capa_msg(MESSAGE_ERROR,tmpS);
 1528:                     } break;
 1529:     case UNKNOWN_F: 
 1530:     default:        { resultp->s_type = S_CONSTANT;
 1531:                       resultp->s_str = strsave("<<UNKNOWN FUNCTION>>");
 1532:                       sprintf(tmpS,"%s() unknown.\n",FuncStack[Func_idx].s_name);
 1533:                       capa_msg(MESSAGE_ERROR,tmpS);
 1534:                       
 1535:                     } break;
 1536:   }
 1537:   
 1538:   return (resultp);
 1539: }
 1540: 

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