Annotation of capa/capa51/pProj/capaFunction.c, revision 1.3
1.1 albertel 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;
1.3 ! albertel 24: int managermode;
1.1 albertel 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));
1.3 ! albertel 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));
1.1 albertel 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"};
1.2 albertel 188: char *month[14] = { "UNKNOWN", "Jan", "Feb", "Mar", "Apr", "May", "Jun",
189: "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "\0"};
1.1 albertel 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;
1.3 ! albertel 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:
1.1 albertel 1522: case MIS_ARG_COUNT:
1523: { resultp->s_type = S_CONSTANT;
1524: resultp->s_str = strsave("<<ARG COUNT>>");
1.3 ! albertel 1525: sprintf(tmpS,"%s()'s arg. count is not correct.\n",
! 1526: FuncStack[Func_idx].s_name);
1.1 albertel 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>