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