Annotation of capa/capa51/GUITools/quizzer.funct.c, revision 1.4
1.2 albertel 1: /* c interfaces for Quizzer
2: Copyright (C) 1992-2000 Michigan State University
3:
4: The CAPA system is free software; you can redistribute it and/or
1.4 ! albertel 5: modify it under the terms of the GNU General Public License as
1.2 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.4 ! albertel 12: General Public License for more details.
1.2 albertel 13:
1.4 ! albertel 14: You should have received a copy of the GNU General Public
1.2 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,
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: */
24:
1.1 albertel 25: /*
26: * quizzer.funct.c
1.2 albertel 27: * Guy Albertelli II 1996
1.1 albertel 28: */
29: #include <stdio.h>
30: #include <tk.h>
1.3 albertel 31: #include <pProj/capaCommon.h>
1.1 albertel 32: #include <quizzer.h>
33: #include <common.h>
34: #include <ctype.h>
35: #include <time.h>
36: #include <signal.h>
37: #include <sys/types.h>
38: #include <sys/wait.h>
39: #include <errno.h>
40:
41: extern int errno;
42: extern int Parsemode_f;
43: static int capaParsing;
44: static int gCreateDvi;
45: void capaQuizzerStatus();
46:
47: T_header gCapaHeader;
48: static char* gPreviewText;
49: int capaTclParse (ClientData clientdata, Tcl_Interp *interp, int argc,
50: char *argv[])
51: {
52:
53: extern char *EndText_p;
54: extern char *StartText_p;
55: T_student student;
56: Problem_t *headProblem,*currentProblem;
57: int numOfQuestions,numAnswers,problemNumber=0;
58: int result,i=1,j,length;
59: char *buf, *buf2, *temp, *previewText=NULL;
60: char lower[32],upper[32],ans[64], unit[64];
61: double targetAns;
62: #ifdef QUIZZER_UPDATE
63: char *update=";update";
64: #else
65: char *update=" ";
66: #endif
67:
68: capaParsing = 1;
69: switch(argv[0][0])
70: {
71: case 'e':Parsemode_f = ASCII_MODE;break;
72: case 't':Parsemode_f = TeX_MODE;break;
73: case 'w':Parsemode_f = HTML_MODE;break;
74: default:
75: Tcl_ResetResult(interp);
76: Tcl_AppendElement(interp,"Invalid call to capaTclParse\n");
77: capaParsing=0;
78: return TCL_ERROR;
79: break;
80: }
81:
82: if (argc==9) { gCreateDvi=atoi(argv[8]); } else { gCreateDvi=0; }
83:
84: if ( (previewText = Tcl_GetVar(interp,argv[7],
85: TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG)) == NULL)
86: {
87: fprintf(stderr,"Tcl_GetVar error\n");
88: fprintf(stderr,"%s\n",interp->result);
89: capaParsing=0;
90: return TCL_ERROR;
91: }
92: gPreviewText=previewText;
93: switch (argv[3][0])
94: {
95: case 'R':
96: result = capa_pick_student(atoi(argv[4]),&student);
97: if (result == -1)
98: {
99: buf=capa_malloc(BUFFER_SIZE,1);
100: sprintf(buf,"displayError \"There are no students in section %d.\"",
101: atoi(argv[4]));
102: Tcl_Eval(interp,buf);
103: capa_mfree(buf);
104: Tcl_ResetResult(interp);
105: Tcl_AppendElement(interp,"-1");
106: capaParsing = 0;
107: return TCL_ERROR;
108: }
109: result = capa_parse(atoi(argv[2]),&headProblem,student.s_sn,
110: &numOfQuestions,capaQuizzerStatus);
111: break;
112: case 'S':
113: result = capa_get_student(argv[5],&student);
114: if ((result == -1) || (result == 0))
115: {
116: buf=capa_malloc(BUFFER_SIZE,1);
117: sprintf(buf,"displayError \"The student %s does not exist.\"",
118: argv[5]);
119: Tcl_Eval(interp,buf);
120: capa_mfree(buf);
121: Tcl_ResetResult(interp);
122: Tcl_AppendElement(interp,"-1");
123: capaParsing = 0;
124: return TCL_ERROR;
125: }
126: result = capa_parse(atoi(argv[2]),&headProblem,argv[5],&numOfQuestions,
127: capaQuizzerStatus);
128: break;
129: default:
130: Tcl_ResetResult(interp);
131: Tcl_AppendElement(interp,"Invalid 2nd argument to capaTclParse\n");
132: capaParsing = 0;
133: return TCL_ERROR;
134: break;
135: }
136:
137: if (result==-1)
138: {
139: Tcl_ResetResult(interp);
140: Tcl_AppendElement(interp,"-1");
141: capaParsing = 0;
142: return TCL_OK;
143: }
144:
145: currentProblem=headProblem;
146: buf=capa_malloc(BUFFER_SIZE,1);
147: sprintf(buf,"%s del 0.0 end %s",previewText,update);
148: if (Tcl_Eval(interp,buf) != TCL_OK)
149: {
150: fprintf(stderr,"Tcl_Eval error 2a\n");
151: fprintf(stderr,"%s\n",interp->result);
152: capaParsing = 0;
153: return TCL_ERROR;
154: }
155: capa_mfree(buf);
156:
157: /* if in answer only mode or ascii mode put a useful header on top */
158: if(argv[1][0] == Q_ANSWER || Parsemode_f == ASCII_MODE )
159: {
160: buf=capa_malloc(BUFFER_SIZE,1);
161: buf2=capa_malloc(BUFFER_SIZE,1);
162: switch(Parsemode_f)
163: {
164: case ASCII_MODE:
165: sprintf(buf,"Section %d Set %d\n Name: %s CAPAID: %d\n\n",
166: student.s_sec, atoi(argv[2]), student.s_nm,
167: capa_PIN(student.s_sn, atoi(argv[2]),0));
168: break;
169: case TeX_MODE:
170:
171: sprintf(buf,"Section %d {\\Large %s}\\hspace*{1in}{\\large %s}, CAPAID: %d, set%d\n\\begin{enumerate}",
172: student.s_sec, student.s_nm, student.s_sn,
173: capa_PIN(student.s_sn, atoi(argv[2]),0), atoi(argv[2]));
174: break;
175: case HTML_MODE:
176: sprintf(buf,"<H2>Section %d %s, %s, CAPAID:%d set %d</H2>\n<OL>\n",
177: student.s_sec, student.s_nm, student.s_sn,
178: capa_PIN(student.s_sn, atoi(argv[2]),0), atoi(argv[2]));
179: break;
180: }
181: j=capaPrepareBuffer(buf,buf2,0);
182:
183: sprintf(buf,"%s insert end \" %s \" header%s",previewText,buf2,update);
184:
185: if (Tcl_Eval(interp,buf) != TCL_OK)
186: {
187: fprintf(stderr,"Tcl_Eval error 2\n");
188: fprintf(stderr,"%s\n",interp->result);
189: capaParsing = 0;
190: return TCL_ERROR;
191: }
192: capa_mfree(buf);
193: capa_mfree(buf2);
194: }
195:
196: if ( gCapaHeader.weight != NULL ) { capa_mfree(gCapaHeader.weight); }
197: if ( gCapaHeader.partial_credit != NULL ) { capa_mfree(gCapaHeader.partial_credit); }
198: gCapaHeader.weight= capa_malloc(numOfQuestions+1,1);
199: gCapaHeader.partial_credit= capa_malloc(numOfQuestions+1,1);
200:
201: if( ( StartText_p != NULL) )
202: {
203: buf=capa_malloc(BUFFER_SIZE+(2*strlen(StartText_p)),1);
204: buf2=capa_malloc(BUFFER_SIZE+(2*strlen(StartText_p)),1);
205: temp=capa_malloc(BUFFER_SIZE+(2*strlen(StartText_p)),1);
206: sprintf(temp,"%s", StartText_p);
207: j=capaPrepareBuffer(temp,buf2,0);
208:
209: sprintf(buf,"%s insert end \"%s\" answer%s",previewText,buf2,update);
210:
211: if (Tcl_Eval(interp,buf) != TCL_OK)
212: {
213: fprintf(stderr,"Tcl_Eval error 8\n");
214: fprintf(stderr,"%s\n",interp->result);
215: capaParsing = 0;
216: return TCL_ERROR;
217: }
218: capa_mfree(buf);
219: capa_mfree(buf2);
220: capa_mfree(temp);
221: }
222:
223: while (currentProblem!=NULL)
224: {
225: gCapaHeader.weight[problemNumber]=((char)(currentProblem->weight))+'0';
226: gCapaHeader.partial_credit[problemNumber]=
227: ((char)(currentProblem->partial_cdt))+'0';
228: switch (argv[1][0])
229: {
230: case Q_PROBLEM:
231: if (currentProblem->question) {
232: length=strlen(currentProblem->question);
233: } else {
234: length=0;
235: }
236: buf=capa_malloc(BUFFER_SIZE+(2*length),1);
237: buf2=capa_malloc(BUFFER_SIZE+(2*length),1);
238: if(currentProblem->question) {
239: j=capaPrepareBuffer(currentProblem->question,buf2,0);
240: buf2[j-1]='\n';
241: buf2[j]='\0';
242: } else {
243: buf2[0]='\n';buf2[1]='\0';
244: }
245:
246: switch(Parsemode_f)
247: {
248: case ASCII_MODE:
249: sprintf(buf,"%s insert end \"%s \n-----------\n\n\" problem%s",
250: previewText,buf2,update);
251: break;
252: case TeX_MODE:
253: sprintf(buf,"%s insert end \"%s\" problem%s",previewText,buf2,update);
254: break;
255: case HTML_MODE:
256: sprintf(buf,"%s insert end \"%s\" problem%s",previewText,buf2,update);
257: break;
258: }
259: if (Tcl_Eval(interp,buf) != TCL_OK)
260: {
261: fprintf(stderr,"Tcl_Eval error 3\n");
262: fprintf(stderr,"%s\n",interp->result);
263: capaParsing = 0;
264: return TCL_ERROR;
265: }
266: capa_mfree(buf);
267: capa_mfree(buf2);
268: break;
269: case Q_PROBLEM_AND_ANSWER:
270: if (currentProblem->question) {
271: length=strlen(currentProblem->question);
272: } else {
273: length=0;
274: }
275: buf=capa_malloc(BUFFER_SIZE+(2*length),1);
276: buf2=capa_malloc(BUFFER_SIZE+(2*length),1);
277: temp=capa_malloc(BUFFER_SIZE+(2*length),1);
278: if (currentProblem->question)
279: j=capaPrepareBuffer(currentProblem->question,buf2,0);
280: switch(Parsemode_f)
281: {
282: case ASCII_MODE:
283: sprintf(buf,"%s insert end \"%s \n-----------\n\n\" problem%s",
284: previewText,buf2,update);
285: break;
286: case TeX_MODE:
287: sprintf(buf,"%s insert end \"%s\" problem%s",previewText,buf2,update);
288: break;
289: case HTML_MODE:
290: sprintf(buf,"%s insert end \"%s\" problem%s",previewText,buf2,update);
291: break;
292: }
293: if (Tcl_Eval(interp,buf) != TCL_OK)
294: {
295: fprintf(stderr,"Tcl_Eval error 4\n");
296: fprintf(stderr,"%s\n",interp->result);
297: capaParsing = 0;
298: return TCL_ERROR;
299: }
300: capa_mfree(buf);
301: capa_mfree(buf2);
302: capa_mfree(temp);
303: capaInsertAnswer(currentProblem,interp,previewText);
304: break;
305: case Q_ANSWER:
306: print_begin_item(Parsemode_f,interp,previewText,problemNumber+1);
307: capaInsertAnswer(currentProblem,interp,previewText);
308: break;
309: }
310:
311: currentProblem=currentProblem->next;
312: problemNumber++;
313: }
314:
315: if(argv[1][0] == Q_ANSWER && Parsemode_f == TeX_MODE ) {
316: buf=capa_malloc(BUFFER_SIZE,1);
317: buf2=capa_malloc(BUFFER_SIZE,1);
318: sprintf(buf,"\n\\end{enumerate}\n");
319: j=capaPrepareBuffer(buf,buf2,0);
320:
321: sprintf(buf,"%s insert end \" %s \" header%s",previewText,buf2,update);
322:
323: if (Tcl_Eval(interp,buf) != TCL_OK) {
324: fprintf(stderr,"Tcl_Eval error 2\n");
325: fprintf(stderr,"%s\n",interp->result);
326: capaParsing = 0;
327: return TCL_ERROR;
328: }
329: capa_mfree(buf);
330: capa_mfree(buf2);
331: }
332:
333: if( ( EndText_p != NULL) )
334: {
335: buf=capa_malloc(BUFFER_SIZE+(2*strlen(EndText_p)),1);
336: buf2=capa_malloc(BUFFER_SIZE+(2*strlen(EndText_p)),1);
337: temp=capa_malloc(BUFFER_SIZE+(2*strlen(EndText_p)),1);
338: sprintf(temp,"%s", EndText_p);
339: j=capaPrepareBuffer(temp,buf2,0);
340:
341: sprintf(buf,"%s insert end \"%s\" answer%s",previewText,buf2,update);
342:
343: if (Tcl_Eval(interp,buf) != TCL_OK)
344: {
345: fprintf(stderr,"Tcl_Eval error 7\n");
346: fprintf(stderr,"%s\n",interp->result);
347: capaParsing = 0;
348: return TCL_ERROR;
349: }
350: capa_mfree(buf);
351: capa_mfree(buf2);
352: capa_mfree(temp);
353: }
354: free_problems(headProblem);
355: free_units();
356: gCapaHeader.weight[problemNumber]='\0';
357: gCapaHeader.partial_credit[problemNumber]='\0';
358:
359: if (result==0)
360: {
361: Tcl_ResetResult(interp);
362: Tcl_AppendElement(interp,"0");
363: }
364: else
365: {
366: buf=capa_malloc(BUFFER_SIZE,1);
367: sprintf(buf,"%d",result);
368: Tcl_ResetResult(interp);
369: Tcl_AppendElement(interp,buf);
370: capa_mfree(buf);
371: }
372: capaParsing = 0;
373: return TCL_OK;
374: }
375:
376: int capaGetStudent(ClientData clientdata, Tcl_Interp *interp, int argc,
377: char *argv[])
378: {
379: T_student student;
380: int result;
381: char buf[BUFFER_SIZE];
382:
383: result = capa_get_student(argv[1],&student);
384:
385: Tcl_ResetResult(interp);
386:
387: switch (result)
388: {
389: case -1:
390: Tcl_AppendElement(interp,"File path incorrect");
391: break;
392: case 0:
393: Tcl_AppendElement(interp,"No such student");
394: break;
395: default:
396: Tcl_ResetResult(interp);
397: sprintf(buf,"%d",student.s_sec);
398: Tcl_AppendElement(interp,buf);
399: sprintf(buf,"%d",student.s_scores);
400: Tcl_AppendElement(interp,buf);
401: Tcl_AppendElement(interp,student.s_key);
402: Tcl_AppendElement(interp,student.s_sn);
403: Tcl_AppendElement(interp,student.s_nm);
404: break;
405: }
406: return TCL_OK;
407: }
408:
409: int capaRunLatex(ClientData clientdata, Tcl_Interp *interp, int argc,
410: char *argv[])
411: {
412: FILE* output;
413: char *textWindow,buf[BUFFER_SIZE],buf2[BUFFER_SIZE*2],
414: command[BUFFER_SIZE*3],*stopPrinting;
415: char *compString="Output written on quiztemp.dvi";
416: int createdDvi=0,stop=0,i,update=0;
417:
418: if ( (output = popen(argv[1],"r"))==NULL) {
419: fprintf(stderr,"popen failed");
420: }
421:
422: if ( (textWindow = Tcl_GetVar(interp,argv[2],
423: TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG)) == NULL) {
424: fprintf(stderr,"Tcl_GetVar error\n");
425: fprintf(stderr,"%s\n",interp->result);
426: return TCL_ERROR;
427: }
428:
429: while(fgets(buf,BUFFER_SIZE-1,output)) {
430: if (strncmp(compString,buf,strlen(compString))==0) createdDvi=1;
431:
432: capaPrepareBuffer(buf,buf2,0);
433:
434: sprintf(command,"%s insert end \"%s\" answer",textWindow, buf2);
435:
436: if (Tcl_Eval(interp,command) != TCL_OK) {
437: fprintf(stderr,"Tcl_Eval error\n");
438: fprintf(stderr,"%s\n",interp->result);
439: return TCL_ERROR;
440: }
441:
442: if (Tcl_Eval(interp,"update") != TCL_OK) {
443: fprintf(stderr,"Tcl_Eval error\n");
444: fprintf(stderr,"%s\n",interp->result);
445: return TCL_ERROR;
446: }
447:
448: if (update++ > 10) {
449: sprintf(command,"%s see end",textWindow, buf2);
450:
451: if (Tcl_Eval(interp,command) != TCL_OK) {
452: fprintf(stderr,"Tcl_Eval error\n");
453: fprintf(stderr,"%s\n",interp->result);
454: return TCL_ERROR;
455: }
456: update=0;
457: }
458: if ( (stopPrinting = Tcl_GetVar(interp,"gStopPrinting",
459: TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG)) == NULL) {
460: fprintf(stderr,"Tcl_GetVar error\n");
461: fprintf(stderr,"%s\n",interp->result);
462: return TCL_ERROR;
463: }
464: stop=atoi(stopPrinting);
465: if (stop) {
466: for(i=1;i< 32768;i++) {
467: waitpid(i,NULL,WNOHANG);
468: if (errno!=ECHILD) { errno=0;break; }
469: errno=0;
470: }
471: if ( i < 32768 ) { kill(i,SIGKILL); }
472: break;
473: }
474: }
475:
476: sprintf(command,"%s see end",textWindow, buf2);
477:
478: if (Tcl_Eval(interp,command) != TCL_OK) {
479: fprintf(stderr,"Tcl_Eval error\n");
480: fprintf(stderr,"%s\n",interp->result);
481: return TCL_ERROR;
482: }
483: pclose(output);
484:
485: if (stop) {
486: Tcl_ResetResult(interp);
487: Tcl_AppendElement(interp,"2");
488: return TCL_OK;
489: }
490: if (createdDvi) {
491: Tcl_ResetResult(interp);
492: Tcl_AppendElement(interp,"1");
493: } else {
494: Tcl_ResetResult(interp);
495: Tcl_AppendElement(interp,"0");
496: }
497: return TCL_OK;
498: }
499:
500: int capaGetParseErrors(ClientData clientdata, Tcl_Interp *interp,
501: int argc, char *argv[])
502: {
503: extern int ErrorMsg_count;
504: extern char *ErrorMsg_p;
505:
506: if (ErrorMsg_count > 0)
507: {
508: Tcl_ResetResult(interp);
509: Tcl_SetResult(interp,ErrorMsg_p,TCL_VOLATILE);
510: }
511: else
512: {
513: Tcl_ResetResult(interp);
514: }
515: return TCL_OK;
516: }
517:
518: int capaGetHeaderInfo(ClientData clientdata, Tcl_Interp *interp,
519: int argc, char *argv[])
520: {
521: T_header header;
522: T_dates *dates,*current;
523: char * setNumber,buf[BUFFER_SIZE],*buf2;
524: int set,result,i;
525:
526: setNumber=Tcl_GetVar(interp,"gLoadHeaderSet",TCL_GLOBAL_ONLY);
527:
528: if ( setNumber== NULL || setNumber[0] == '\0') {
529: Tcl_ResetResult(interp);
530: Tcl_AppendElement(interp,"called getHeaderInfo with no gLoadHeaderSet value");
531: return TCL_ERROR;
532: }
533:
534: sscanf(setNumber,"%d",&set);
535:
536: result=capa_get_header(&header,set);
537:
538: if (result == -1 ) {
539: Tcl_ResetResult(interp);
540: Tcl_AppendElement(interp,"capa_get_header return a -1");
541: return TCL_ERROR;
542: }
543:
544: Tcl_SetVar(interp,"gWeightsDiffer","0",TCL_GLOBAL_ONLY);
545: if (gCapaHeader.weight!=NULL && header.weight !=NULL) {
546: for(i=0;i<(strlen(header.weight)&&strlen(gCapaHeader.weight));i++) {
547: if (header.weight[i]!=gCapaHeader.weight[i]) {
548: Tcl_SetVar(interp,"gWeightsDiffer","1",TCL_GLOBAL_ONLY);break;
549: }
550: }
551: }
552: capa_mfree(header.weight);
553:
554: if (gCapaHeader.partial_credit!=NULL && header.partial_credit !=NULL) {
555: Tcl_SetVar(interp,"gPartialDiffer","0",TCL_GLOBAL_ONLY);
556: for(i=0;i<(strlen(header.partial_credit)&&strlen(gCapaHeader.partial_credit));i++) {
557: if (header.partial_credit[i]!=gCapaHeader.partial_credit[i]) {
558: Tcl_SetVar(interp,"gPartialDiffer","1",TCL_GLOBAL_ONLY);break;
559: }
560: }
561: }
562: capa_mfree(header.partial_credit);
563:
564: result=capa_get_all_dates(set,&dates);
565: if (result < 0 ) {
566: Tcl_ResetResult(interp);
567: Tcl_AppendElement(interp,"capa_get_header returned a negative number");
568: return TCL_ERROR;
569: }
570:
571: Tcl_SetVar(interp,"gHeaderQCount",header.num_questions,TCL_GLOBAL_ONLY);
572:
573: buf2=capa_malloc(result*QUARTER_K,1);
574: buf2[0]='\0';
575: current=dates;
576: while(current != NULL ) {
577: sprintf(buf,"{%d %d {%s} {%s} {%s} {%s} %d %d} ",current->section_start,
578: current->section_end, current->open_date, current->due_date,
579: current->answer_date, current->duration, current->inhibit_response,
580: current->view_problems_after_due);
581: strcat(buf2,buf);
582: current=current->s_next;
583: }
584: Tcl_SetVar(interp,"gControlDates",buf2,TCL_GLOBAL_ONLY);
585: free_dates(dates);
586: capa_mfree(buf2);
587: return TCL_OK;
588: }
589:
590: int capaCheckDateFormat(char *varName,Tcl_Interp *interp)
591: {
592: char *tempPoint;
593:
594: tempPoint=Tcl_GetVar(interp,varName,TCL_GLOBAL_ONLY);
595:
596: if (strlen(tempPoint)!=8) goto wrong;
597:
598: switch(tempPoint[0])
599: {
600: case '0':
601: if (!isdigit(tempPoint[1])) goto wrong;
602: break;
603: case '1':
604: if (!(
605: (tempPoint[1]=='0') ||
606: (tempPoint[1]=='1') ||
607: (tempPoint[1]=='2')
608: )
609: ) goto wrong;
610: break;
611: case '2':
612: if (!(
613: (tempPoint[1]=='0') ||
614: (tempPoint[1]=='1') ||
615: (tempPoint[1]=='2') ||
616: (tempPoint[1]=='3') ||
617: (tempPoint[1]=='4')
618: )
619: ) goto wrong;
620: break;
621: default:
622: goto wrong;
623: break;
624: }
625: if (tempPoint[2] != '/') goto wrong;
626: switch(tempPoint[3])
627: {
628: case '0':
629: case '1':
630: case '2':
631: if (!isdigit(tempPoint[4])) goto wrong;
632: break;
633: case '3':
634: if (!(
635: (tempPoint[4]=='0') ||
636: (tempPoint[4]=='1')
637: )
638: ) goto wrong;
639: break;
640: default:
641: goto wrong;
642: break;
643: }
644: if (tempPoint[5] != '/') goto wrong;
645: if (!isdigit(tempPoint[6])) goto wrong;
646: if (!isdigit(tempPoint[7])) goto wrong;
647: goto right;
648: wrong:
649: return 0;
650: right:
651: return 1;
652: }
653:
654: int capaCheckTimeFormat(char *varName,Tcl_Interp *interp)
655: {
656: char *tempPoint;
657:
658: tempPoint=Tcl_GetVar(interp,varName,TCL_GLOBAL_ONLY);
659:
660: if (strlen(tempPoint)!=5) goto wrong;
661:
662: switch(tempPoint[0])
663: {
664: case '0':
665: if (!isdigit(tempPoint[1])) goto wrong;
666: break;
667: case '1':
668: if (!(isdigit(tempPoint[1])))
669: goto wrong;
670: break;
671: case '2':
672: switch(tempPoint[1])
673: {
674: case '0':
675: case '1':
676: case '2':
677: case '3':
678: case '4':
679: break;
680: default:
681: goto wrong;
682: break;
683: }
684: break;
685: default:
686: goto wrong;
687: break;
688: }
689: if (tempPoint[2] != ':') goto wrong;
690: switch (tempPoint[3])
691: {
692: case '0':
693: case '1':
694: case '2':
695: case '3':
696: case '4':
697: case '5':
698: break;
699: default:
700: goto wrong;
701: break;
702: }
703: if (!isdigit(tempPoint[4])) goto wrong;
704: goto right;
705:
706: wrong:
707: return 0;
708: right:
709: return 1;
710: }
711:
712: int capaCheckHeader(ClientData clientdata, Tcl_Interp *interp,
713: int argc, char *argv[])
714: {
715: if (!capaCheckDateFormat("gOpenDate",interp))
716: {
717: Tcl_ResetResult(interp);
718: Tcl_AppendElement(interp,"0");
719: return TCL_OK;
720: }
721: if (!capaCheckTimeFormat("gOpenTime",interp))
722: {
723: Tcl_ResetResult(interp);
724: Tcl_AppendElement(interp,"0");
725: return TCL_OK;
726: }
727: if (!capaCheckDateFormat("gDueDate",interp))
728: {
729: Tcl_ResetResult(interp);
730: Tcl_AppendElement(interp,"0");
731: return TCL_OK;
732: }
733: if (!capaCheckTimeFormat("gDueTime",interp))
734: {
735: Tcl_ResetResult(interp);
736: Tcl_AppendElement(interp,"0");
737: return TCL_OK;
738: }
739: if (!capaCheckDateFormat("gAnswerDate",interp))
740: {
741: Tcl_ResetResult(interp);
742: Tcl_AppendElement(interp,"0");
743: return TCL_OK;
744: }
745: if (!capaCheckTimeFormat("gAnswerTime",interp))
746: {
747: Tcl_ResetResult(interp);
748: Tcl_AppendElement(interp,"0");
749: return TCL_OK;
750: }
751: Tcl_ResetResult(interp);
752: Tcl_AppendElement(interp,"1");
753: return TCL_OK;
754: }
755:
756: int capaUpdateHeader(ClientData clientdata, Tcl_Interp *interp,
757: int argc, char *argv[])
758: {
759: char *setNumber,*date,*time,*questions;
760: int set,result,i;
761: T_dates *dates;
762:
763: setNumber=Tcl_GetVar(interp,"gSetNumberText",TCL_GLOBAL_ONLY);
764:
765: if ( setNumber[0] == '\0' ) return TCL_OK;
766:
767: sscanf(setNumber,"%d",&set);
768: questions=Tcl_GetVar(interp,"gNumberParsedText",TCL_GLOBAL_ONLY);
769: sprintf(gCapaHeader.num_questions,"%s",questions);
770:
771: /*weight and partialcredit info is from the parse*/
772:
773: result=capa_set_header(&gCapaHeader,set);
774:
775: if (result == -1)
776: Tcl_Eval(interp,"displayError \"The records directory does not exist or is unwritable.\"");
777: else {
778: T_dates* current;
779: for(i=0;i<argc/8;i++) {
780: if ( i==0 ) {
781: dates=current=(T_dates*)capa_malloc(sizeof(T_dates),1);
782: } else {
783: current->s_next=(T_dates*)capa_malloc(sizeof(T_dates),1);
784: current=current->s_next;
785: }
786: current->section_start=atoi(argv[(i*8)+1]);
787: current->section_end=atoi(argv[(i*8)+2]);
788: strncpy(current->open_date,argv[(i*8)+3],sizeof(current->open_date));
789: strncpy(current->due_date,argv[(i*8)+4],sizeof(current->due_date));
790: strncpy(current->answer_date,argv[(i*8)+5],sizeof(current->answer_date));
791: strncpy(current->duration,argv[(i*8)+6],sizeof(current->duration));
792: current->inhibit_response=atoi(argv[(i*8)+7]);
793: current->view_problems_after_due=atoi(argv[(i*8)+8]);
794: }
795: result=capa_set_all_dates(set,dates);
796: free_dates(dates);
797: if (result == -1)
798: Tcl_Eval(interp,"displayError \"The records directory does not exist or is unwritable.\"");
799: }
800: return TCL_OK;
801: }
802:
803: int capaGetStudentNumbers(ClientData clientdata, Tcl_Interp *interp,
804: int argc, char *argv[])
805: {
806: char buf[BUFFER_SIZE];
807: T_student *first_student,*a_student;
808: int result;
809:
810: result=capa_get_section(&first_student,0);
811:
812: if ( result == 0 ) {
813: Tcl_Eval(interp,"displayError \"There are no students in this class, you can only do random runs\"");
814: Tcl_ResetResult(interp);
815: return TCL_OK;
816: }
817: if ( result == -1 ) {
818: Tcl_Eval(interp,"displayError \"There is no classl file, you can only do random runs.\"");
819: Tcl_ResetResult(interp);
820: return TCL_OK;
821: }
822:
823: a_student=first_student;
824: Tcl_ResetResult(interp);
825: while( a_student ) {
826: Tcl_AppendElement(interp,a_student->s_sn);
827: Tcl_AppendElement(interp,a_student->s_nm);
828: sprintf(buf,"%d",a_student->s_sec);
829: Tcl_AppendElement(interp,buf);
830: a_student=a_student->s_next;
831: }
832: free_students(first_student);
833: return TCL_OK;
834: }
835:
836: void capaShowParseLocation(int sigNum)
837: {
838: extern int Current_line[MAX_OPENED_FILE];
839: extern int Input_idx;
840: extern char Opened_filename[MAX_OPENED_FILE][QUARTER_K];
841: extern Tcl_Interp *gInterp;
842: char buf[BUFFER_SIZE];
843:
844: sprintf(buf,"displayError \"In file %s on Line %d a coding error caused a fatal error in Quizzer.\"",Opened_filename[Input_idx],Current_line[Input_idx]-1);
845: printf(buf);
846: fflush(stdout);
847: Tcl_Eval(gInterp,buf);
848: exit(-1);
849: }
850:
851: void capaGenerateError()
852: {
853: extern Tcl_Interp *gInterp;
854: char buf[BUFFER_SIZE];
855:
856: sprintf(buf, "displayError \"Your last action just caused Quizzer to die. Please let the developers know what action caused this. Thanks.\"");
857: printf(buf);
858: fflush(stdout);
859: Tcl_Eval(gInterp,buf);
860: exit(-1);
861: }
862:
863: /*
864: extern int Input_idx;
865: extern char Opened_filename[MAX_OPENED_FILE][QUARTER_K];
866: extern char Current_line[MAX_OPENED_FILE];
867: extern Tcl_Interp *gInterp;
868: void dynamicStatus()
869: {
870: char *buf,*buf2,small[BUFFER_SIZE];
871: int i,j,totlen=0,len,idx=0;
872:
873: for(i=0;i<=Input_idx;i++) totlen=+strlen(Opened_filename[i])+4;
874: buf=capa_malloc(sizeof(char),totlen);
875: for(i=0;i<=Input_idx;i++) {
876: len=strlen(Opened_filename[i]);
877: for(j=0;j<len;j++) buf[idx++] = Opened_filename[i][j];
878: buf[idx++] = ':';
879: sprintf(small,"%d",Current_line[i]);
880: len=strlen(small);
881: for(j=0;j<len;j++) buf[idx++] = small[j];
882: buf[idx++]=' ';
883: buf[idx]='\0';
884: }
885: buf[idx++]='\n';
886: buf[idx]='\0';
887: buf2=capa_malloc(sizeof(char),strlen(buf)*2);
888: j=capaPrepareBuffer(buf,buf2,0);
889: capa_mfree(buf);
890: buf=capa_malloc(sizeof(char),strlen(buf2)+BUFFER_SIZE);
891: sprintf(buf,"%s insert end %s",gPreviewText,buf2);
892: if (Tcl_Eval(gInterp,buf) != TCL_OK) {
893: fprintf(stderr,"Tcl_Eval error 2a\n");
894: fprintf(stderr,"%s\n",gInterp->result);
895: }
896: capa_mfree(buf);
897: capa_mfree(buf2);
898: }
899: */
900:
901: void capaQuizzerStatus()
902: {
903: static time_t lasttime;
904: time_t thistime=time(NULL);
905: if (thistime > lasttime) {
906: extern Tcl_Interp *gInterp;
907: char *buf=parser_status(),*buf2;
908: int j;
909: buf2=capa_malloc(sizeof(char),strlen(buf)*2);
910: j=capaPrepareBuffer(buf,buf2,0);
911: capa_mfree(buf);
912: buf=capa_malloc(sizeof(char),strlen(buf2)+BUFFER_SIZE);
913: if (gCreateDvi) {
914: sprintf(buf,"global gStopStatus;set gStopStatus \"%s\"",buf2);
915: } else {
916: sprintf(buf,"%s insert end \"%s\n\";%s see end",
917: gPreviewText,buf2,gPreviewText);
918: }
919: capa_mfree(buf2);
920: if (Tcl_Eval(gInterp,buf) != TCL_OK) {
921: fprintf(stderr,"Tcl_Eval error 2a\n");
922: fprintf(stderr,"%s\n",gInterp->result);
923: }
924: capa_mfree(buf);
925: while(Tcl_DoOneEvent(TCL_ALL_EVENTS|TCL_DONT_WAIT));
926: lasttime=time(NULL);
927: } else {
928: if (!gFasterParsing) while(Tcl_DoOneEvent(TCL_ALL_EVENTS|TCL_DONT_WAIT));
929: }
930: }
931:
932: void signalHandler(int sigNum)
933: {
934: if (capaParsing) {
935: capaShowParseLocation(sigNum);
936: } else {
937: capaGenerateError();
938: }
939: }
940:
941: int capaStopParser(ClientData clientdata, Tcl_Interp *interp, int argc, char *argv[])
942: {
943: extern int Stop_Parser;
944: Stop_Parser=1;
945: return TCL_OK;
946: }
947:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>