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