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