Annotation of capa/capa51/pProj/qzparse.c, revision 1.2
1.1 albertel 1: /* ======================================================================== */
2: /* Feb. 10 1997 Isaac Tsai */
3: /* ======================================================================== */
4:
5: #ifdef NeXT
6: #include <stdlib.h>
7: #include <sys/types.h>
8: #include <sys/stat.h>
9: #include <bsd/curses.h>
10: #else
11: #include <curses.h>
12: #include <malloc.h>
13: double atof();
14: #endif
15:
16: #include <stdio.h>
17: #include <ctype.h>
18: #include <sys/types.h>
19: #include <sys/stat.h>
20: #include <signal.h>
21: #include <time.h>
22: #include <math.h>
23: #include <string.h>
24:
25:
26: #define YES 1
27:
28: #include "capaParser.h"
29: #include "capaCommon.h"
30: #include "ranlib.h"
31:
32: char *progname;
33:
34: void free_header(T_header* header)
35: {
36: capa_mfree(header->weight);
37: capa_mfree(header->partial_credit);
38: }
39:
40: void setdb_error(int set)
41: {
42: fprintf(stderr,"Set #%d has not had it's DB Header set. Please run Quizzer and set the DB Header.\n",set);
43: exit(-1);
44: }
45:
46: void
47: print_header(int mode,FILE *o_fp,int sec,int set,char *stu_nam,char *stu_num)
48: {
49: extern char *StartText_p;
50: int capaid = capa_PIN(stu_num,set,0);
51:
52: if( StartText_p != NULL ) {
53: fprintf(o_fp, "%s", StartText_p);
54: }
55:
1.2 ! albertel 56: switch(mode) {
! 57: case TeX_MODE:
! 58: if (StartText_p == NULL ) {
! 59: fprintf(o_fp, "Section %d {\\Large %s}\\hspace*{1in}",sec,stu_nam);
! 60: fprintf(o_fp, "{\\large %s}, CAPAID: %d, set %d",stu_num, capaid, set);
! 61: }
! 62: fprintf(o_fp, "\n\\begin{enumerate}\n");
! 63: break;
! 64: case ASCII_MODE:
! 65: fprintf(o_fp, "Section %d %s ", sec,stu_nam);
! 66: fprintf(o_fp, "%s, CAPAID: %d set %d\n\n",stu_num, capaid, set);
! 67: break;
! 68: case HTML_MODE:
! 69: fprintf(o_fp, "<H2>Section %d %s, ", sec,stu_nam);
! 70: fprintf(o_fp, "%s, CAPAID:%d set %d</H2>\n", stu_num,capaid,set);
! 71: fprintf(o_fp, "<OL>\n");
! 72: break;
! 73: }
1.1 albertel 74: }
75:
76: void
77: print_begin_item(int mode,FILE *o_fp,int q_idx)
78: {
79:
80: switch(mode) {
81: case TeX_MODE:
82: fprintf(o_fp, "\\item ");
83: break;
84: case ASCII_MODE:
85: fprintf(o_fp, "%d) ", q_idx);
86: break;
87: case HTML_MODE:
88: fprintf(o_fp, "<LI> ");
89: break;
90: }
91: }
92:
93:
94: void
95: unit_toHTML(char *u_str, char *r)
96: {
97: int i;
98: char *ch;
99:
100:
101: while(isspace(*ch)) ch++;
102: while( isalnum(*ch) ) {
103: r[i++] = *ch; ch++;
104: }
105: if( *ch == '^' ) {
106: r[i++] = '<'; r[i++]='s';r[i++]='u';r[i++]='p';r[i++]='>';
107: ch++; while(isspace(*ch)) ch++;
108: while( isalnum(*ch) ) {
109: r[i++] = *ch; ch++;
110: }
111: r[i++] = '<'; r[i++]='/'; r[i++]='s';r[i++]='u';r[i++]='p';r[i++]='>';
112: } else {
113: r[i++] = *ch; ch++;
114: }
115:
116:
117: }
118:
119: void
120: print_footer(int mode,FILE *o_fp)
121: {
122: extern char *EndText_p;
123:
124: switch(mode) {
125: case TeX_MODE:
126: fprintf(o_fp, "\n\\end{enumerate}\n");
127: break;
128: case ASCII_MODE:
129: fprintf(o_fp, "\n");
130: break;
131: case HTML_MODE:
132: fprintf(o_fp, "</OL>\n");
133: break;
134: }
135: if( EndText_p != NULL ) {
136: fprintf(o_fp, "%s", EndText_p);
137: }
138: }
139:
140: /* ============================================================== */
141: /* qz --> tex -Tq */
142: /* qz --> html -Ha */
143: /* qz --> ascii -Ab */
144: /* question only q */
145: /* answer only a */
146: /* both b */
147: /* for entire class -C */
148: /* for a range of sections -Sec 2:6 */
149: /* for a section -Sec 2 */
150: /* for a student -Stu 12345678 */
151: /* output a set -Set 2 */
152: /* output a range of sets -Set 1:6 */
153: /* output blocksize -b 30 */
154: /* ============================================================== */
155:
156: void usage()
157: {
158: printf("USAGE: %s [ -[T|H|A][a|b] ] [-Sec [n|n:m] | -Stu sn [-o filename] ]\n",progname);
159: printf(" [ -Set [n|n:m] ] [-c path_to_class] [-d outputdirectory]\n");
160: printf(" Example 1: %s -Tb -sec 2:3 -set 2:5\n", progname);
161: printf(" will generate tex files with both questions and answers\n");
162: printf(" for sections 2 to 3, sets 2 to 5\n");
163: printf(" Example 2: %s -Ha -stu A12345678 -set 3\n", progname);
164: printf(" will generate html files with answer only \n");
165: printf(" for student A12345678 set 3\n");
166: printf(" -T = tex mode\n");
167: printf(" -H = html mode\n");
168: printf(" -A = ascii mode\n");
169: printf(" = default question only\n");
170: printf(" a = answer only\n");
171: printf(" b = both question and answer\n");
172: printf(" -nopagebreak = don't put a \\clearpage between assignments\n");
173: printf(" -Sec 3 = for section 3\n");
174: printf(" -Sec 3:7 = from section 3 to section 7\n");
175: printf(" -Stu A12345678 = for a specified student\n");
176: printf(" -Set 1 = output set 1\n");
177: printf(" -Set 3:4 = output from set 3 to set 4\n");
178: printf(" -c class_path\n");
179: printf(" -o output_filename_with_absolute_path (only for a student)\n");
180: printf(" -d directory_to_create_files_in (default is class_path/TeX)\n");
181: printf("-------This is version %s @ %s\n",CAPA_VER,COMPILE_DATE);
182: printf("------------------------------------------------------\n");
183: }
184:
185: #define Q_ONLY 1
186: #define A_ONLY 2
187: #define QA_BOTH 3
188: #define F_CLASS 1
189: #define F_SECTIONS 2
190: #define F_STUDENT 3
191:
192:
193:
194: /* filter out the number to be [1:999] */
195: int scan_num(char *num_str,int *first, int *second) {
196: char tmp_str[SMALL_LINE_BUFFER], *ch;
197: int ii=0, a_num, b_num, result=0;
198:
199: ch = num_str;
200: tmp_str[ii] = 0;
201: while( isspace(*ch) ) ch++;
202: while(isdigit(*ch)) { tmp_str[ii++] = *ch; ch++; }
203: tmp_str[ii] = 0;
204: sscanf(tmp_str,"%d",&a_num);
205: if( a_num < 0 || a_num > 999 ) a_num = 1;
206: *first = a_num;
207: result = 1;
208: while( isspace(*ch) ) ch++;
209: if( *ch == ':' ) {
210: ch++;
211: while( isspace(*ch) ) ch++;
212: ii=0; tmp_str[ii] = 0;
213: while( isdigit(*ch) ) { tmp_str[ii++] = *ch; ch++; }
214: tmp_str[ii] = 0;
215: sscanf(tmp_str,"%d",&b_num);
216: if( b_num < 0 || b_num > 999 ) b_num = 1;
217: if( a_num > b_num ) b_num = a_num;
218: *second = b_num;
219: result = 2;
220: }
221: return (result);
222: }
223:
224: int main (int argc, char **argv)
225: {
226: extern int Parsemode_f;
227: extern char *EndText_p;
228: extern char *StartText_p;
229: extern char *ErrorMsg_p;
230: extern int ErrorMsg_count;
231:
232: Problem_t *first_prob,*p;
233: T_student *students_p,*s_p, a_student;
234: int num_students, q_cnt, result, inputNotOK = 1,
235: ii, sectionIdx, setIdx = 1, q_idx, outputFlag = 0;
236: char filename[FILE_NAME_LENGTH], path[FILE_NAME_LENGTH];
237: FILE *dfp;
238: int tmp_num, first_stu, file_specified, directory_specified;
239: int ForWhat = F_SECTIONS, pagebreak=1,
240: StartSec = 1, EndSec = 1, StartSet = 1, EndSet = 1;
241: char StuNum[MAX_STUDENT_NUMBER+1];
242: char out_filename[FILE_NAME_LENGTH],out_directory[FILE_NAME_LENGTH];
243: char cmd[SMALL_LINE_BUFFER], *ans_str;
244:
245: /* qz --> tex -T */
246: /* qz --> html -Ha */
247: /* qz --> ascii -Ab */
248: /* answer only a */
249: /* both b */
250: /* for entire class -C */
251: /* for a range of sections -Sec 2:6 */
252: /* for a section -Sec 2 */
253: /* for a student -Stu 12345678 */
254: /* output a set -Set 2 */
255: /* output a range of sets -Set 1:6 */
256:
257: /* default */
258: Parsemode_f = TeX_MODE; ForWhat = F_SECTIONS; outputFlag=Q_ONLY;
259: file_specified=0;
260: out_filename[0]='\0';
261: directory_specified=0;
262: out_directory[0]='\0';
263: for( progname = *argv++; --argc; argv++) {
264: if ( argv[0][0] == '-' ) {
265: switch(argv[0][1]) {
266: case 'T': Parsemode_f = TeX_MODE;
267: outputFlag=(argv[0][2] == 'a' ? A_ONLY :(argv[0][2] == 'b' ? QA_BOTH : Q_ONLY));
268: break;
269: case 'H': Parsemode_f = HTML_MODE;
270: outputFlag=(argv[0][2] == 'a' ? A_ONLY :(argv[0][2] == 'b' ? QA_BOTH : Q_ONLY));
271: break;
272: case 'A': Parsemode_f = ASCII_MODE;
273: outputFlag=(argv[0][2] == 'a' ? A_ONLY :(argv[0][2] == 'b' ? QA_BOTH : Q_ONLY));
274: break;
275: case 'S':
276: case 's': if( strncasecmp(argv[0],"-sec",4) == 0 ) {
277: tmp_num = scan_num(argv[1],&StartSec,&EndSec);
278: if( tmp_num == 1 ) { EndSec = StartSec; }
279: ForWhat = F_SECTIONS;
280: } else if( strncasecmp(argv[0],"-stu",4) == 0 ) {
281: for(ii=0;ii<MAX_STUDENT_NUMBER;ii++) {
282: StuNum[ii] = argv[1][ii];
283: }
284: StuNum[ii]=0;
285: ForWhat = F_STUDENT;
286: } else if( strncasecmp(argv[0],"-set",4) == 0 ) {
287: tmp_num = scan_num(argv[1],&StartSet,&EndSet);
288: if( tmp_num == 1 ) { EndSet = StartSet; }
289: } else {
290: usage();
291: }
292: break;
293: case 'c': strcpy(path, argv[1]);
294: if(capa_access(path, F_OK) == -1) {
295: inputNotOK = 1;
296: } else {
297: inputNotOK = 0;
298: }
299: break;
300: case 'o':
301: if (argc == 1 || argv[1][0] == '-') {
302: usage(); return 0;
303: } else {
304: strcpy(out_filename, argv[1]); file_specified=1; break;
305: }
306: case 'd':
307: if (argc == 1 || argv[1][0] == '-') {
308: usage(); return 0; break;
309: } else {
310: strcpy(out_directory, argv[1]); directory_specified=1; break;
311: }
312: case 'n':
313: pagebreak=0;break;
314: case 'u': case 'h': default: usage(); return(0); break;
315: }
316: }
317: }
318: printf(" %s running in %s mode, %s for %s, ", progname,
319: (Parsemode_f == TeX_MODE ? "TeX" : (Parsemode_f == ASCII_MODE ? "ASCII" : "HTML")),
320: (outputFlag==A_ONLY ? "answer only" : (outputFlag==QA_BOTH? "question and answer" : "question only")),
321: (ForWhat == F_STUDENT ? "a student" : "section" ) );
322: if( ForWhat == F_STUDENT ) {
323: printf(" for student %s,",StuNum);
324: } else {
325: if(StartSec==EndSec) {
326: printf(" for section %d,", StartSec);
327: }
328: else {
329: printf(" from section %d to %d,",StartSec, EndSec);
330: }
331: }
332: if(StartSet==EndSet) { printf(" set %d\n",StartSet); } else { printf(" from set %d to %d\n", StartSet, EndSet); }
333:
334: while ( inputNotOK ) {
335: puts("Enter the ABSOLUTE path of class");
336: scanf("%s", path);
337: if( capa_access(path, F_OK) == -1 ) {
338: } else {
339: sprintf(filename,"%s/classl",path);
340: if( capa_access(filename, F_OK) == -1 ) {
341: puts("There isn't a classl file in this CLASS directory\nPlease Specify another class");
342: } else {
343: inputNotOK = 0;
344: }
345: }
346: }
347:
348: if( (ForWhat == F_STUDENT) && strlen(StuNum) == 0 ) {
349: inputNotOK = 1;
350: while ( inputNotOK ) {
351: puts("Enter student number"); scanf("%s", StuNum);
352: if( strlen(StuNum) == MAX_STUDENT_NUMBER ) { inputNotOK = 0; }
353: }
354: }
355: if ( file_specified == 0) {
356: if ( directory_specified == 0) {
357: switch( Parsemode_f ) {
358: case TeX_MODE: sprintf(filename,"%s/TeX",path); break;
359: case ASCII_MODE: sprintf(filename,"%s/ASCII",path); break;
360: case HTML_MODE: sprintf(filename,"%s/HTML",path); break;
361: default: sprintf(filename,"%s/TeX",path); Parsemode_f = TeX_MODE; break;
362: }
363: } else {
364: sprintf(filename,"%s",out_directory);
365: }
366: if( capa_access(filename, F_OK) == -1 ) {
367: if ( mkdir(filename, S_IREAD | S_IWRITE | S_IEXEC ) == -1 ) {
368: printf("Unable to write to %s\n",filename);
369: printf("Please check this directory and run %s again.\n",progname);
370: return(-1);
371: }
372: }
373:
374: } else {
375: if ( directory_specified == 0) {
376: } else {
377: sprintf(filename,"%s",out_directory);
378: }
379: }
380: chdir(path);
381:
382: if ( ForWhat == F_SECTIONS ) {
383: T_dates* dates;
384: T_header header;
385: for(ii=StartSet;ii<=EndSet;ii++) {
386: if (capa_get_header(&header,ii)<0) {
387: setdb_error(ii);
388: }
389: free_header(&header);
390: if (capa_get_all_dates(ii,&dates)<0) {
391: setdb_error(ii);
392: }
393: free_dates(dates);
394: }
395: }
396:
397: if( ForWhat == F_STUDENT ) {
398: result = capa_get_student(StuNum, &a_student);
399: if ( result == 0 ) {
400: fprintf(stderr,"Unable to find student %s in %s/classl",StuNum,path);
401: exit(-1);
402: } else {
403: if (result == -1 ) {
404: fprintf(stderr,"Unable to read %s/classl",path);
405: exit(-1);
406: }
407: }
408: if ( file_specified == 0) {
409: if ( directory_specified == 0) {
410: switch( Parsemode_f ) {
411: case TeX_MODE: sprintf(filename,"TeX/%s.tex",StuNum); break;
412: case ASCII_MODE: sprintf(filename,"ASCII/%s.ascii",StuNum); break;
413: case HTML_MODE: sprintf(filename,"HTML/%s.html",StuNum); break;
414: }
415: } else {
416: switch( Parsemode_f ) {
417: case TeX_MODE: sprintf(filename,"%s/%s.tex",out_directory,StuNum); break;
418: case ASCII_MODE: sprintf(filename,"%s/%s.ascii",out_directory,StuNum); break;
419: case HTML_MODE: sprintf(filename,"%s/%s.html",out_directory,StuNum); break;
420: }
421: }
422: } else {
423: if (directory_specified == 0 ) {
424: sprintf(filename,"%s",out_filename);
425: } else {
426: sprintf(filename,"%s/%s",out_directory,out_filename);
427: }
428: }
429: switch ( Parsemode_f ) {
430: case TeX_MODE: sprintf(cmd, "cp TeXheader %s\n",filename); system(cmd); break;
431: default: sprintf(cmd,"rm %s\n",filename);system(cmd); break;
432: }
433: if((dfp=fopen(filename,"a"))==NULL) {
434: fprintf(stdout,"File error! Cannot open [%s].\n",filename);
435: return -1;
436: }
437: for(setIdx=StartSet; setIdx <= EndSet; setIdx++) {
438: result = capa_parse(setIdx, &first_prob, StuNum, &q_cnt, NULL);
439: if ( result != 0 ) { p = first_prob;
440: switch(outputFlag) {
441: case Q_ONLY:
442: if( StartText_p != NULL) {
443: fprintf(dfp, "%s", StartText_p); fflush(dfp);
444: }
445: for( q_idx = 0; q_idx < q_cnt; printf("."),fflush(stdout), q_idx++ ) {
446: fprintf(dfp, "%s", p->question); p = p->next;
447: }
448: if( EndText_p != NULL) {
449: fprintf(dfp, "%s", EndText_p); fflush(dfp);
450: }
451: break;
452: case A_ONLY:
453: print_header(Parsemode_f, dfp,a_student.s_sec,setIdx,a_student.s_nm, StuNum);
454: for( q_idx = 0; q_idx < q_cnt; printf("."),fflush(stdout), q_idx++ ) {
455: print_begin_item(Parsemode_f,dfp,q_idx+1);
456: ans_str = answers_string(Parsemode_f,p);
457: fprintf(dfp, "%s",ans_str); fflush(dfp);
458: capa_mfree((char *)ans_str);
459: p = p->next;
460: }
461: print_footer(Parsemode_f, dfp);
462: break;
463: case QA_BOTH:
464: if( StartText_p != NULL ) {
465: fprintf(dfp, "%s", StartText_p);
466: }
467: for( q_idx = 0; q_idx < q_cnt; printf("."),fflush(stdout), q_idx++ ) {
468: fprintf(dfp, "%s", p->question); fflush(dfp);
469: ans_str = answers_string(Parsemode_f,p);
470: fprintf(dfp, "%s",ans_str); fflush(dfp);
471: capa_mfree((char *)ans_str);
472: p = p->next;
473: }
474: if( EndText_p != NULL ) {
475: fprintf(dfp, "%s", EndText_p);
476: }
477: break;
478: }
479:
480: }
481: free_problems(first_prob);
482: if( setIdx < EndSet ) {
483: if( Parsemode_f == TeX_MODE && pagebreak ) {
484: fprintf(dfp, "\\clearpage\n\\setcounter{page}{1}\n");
485: } else {
486: printf("\n");
487: }
488: }
489: if( ErrorMsg_count > 0 ) {
490: printf("%s",ErrorMsg_p);
491: }
492: }
493: fflush(dfp); fclose(dfp);
494:
495: switch( Parsemode_f ) {
496: case TeX_MODE: sprintf(cmd, "cat TeXfooter >> %s\n", filename); system(cmd); break;
497: }
498: printf("\n DONE Student %s\n",StuNum);
499: } else { /* For section(s) */
500: for(sectionIdx = StartSec; sectionIdx <= EndSec; sectionIdx++ ) {
501: num_students = capa_sorted_section(&students_p, sectionIdx);
502: printf("Section %2d: %d students\n",sectionIdx,num_students);
503: if( num_students > 0 ) {
504: for(setIdx=StartSet; setIdx <= EndSet; setIdx++) {
505:
506: if (directory_specified == 0 ) {
507: switch( Parsemode_f ) {
508: case TeX_MODE: sprintf(cmd, "cp TeXheader TeX/section%d-set%d.tex\n", sectionIdx,setIdx);
509: system(cmd);
510: sprintf(filename,"TeX/section%d-set%d.tex",sectionIdx,setIdx); break;
511: case ASCII_MODE: sprintf(filename,"ASCII/section%d-set%d.ascii",sectionIdx,setIdx); break;
512: case HTML_MODE: sprintf(filename,"HTML/section%d-set%d.text",sectionIdx,setIdx); break;
513: }
514: } else {
515: switch( Parsemode_f ) {
516: case TeX_MODE: sprintf(cmd, "cp TeXheader %s/section%d-set%d.tex\n", out_directory,
517: sectionIdx,setIdx);
518: system(cmd);
519: sprintf(filename,"%s/section%d-set%d.tex",out_directory,
520: sectionIdx,setIdx); break;
521: case ASCII_MODE: sprintf(filename,"%s/section%d-set%d.ascii",out_directory,
522: sectionIdx,setIdx); break;
523: case HTML_MODE: sprintf(filename,"%s/section%d-set%d.text",out_directory,
524: sectionIdx,setIdx); break;
525: }
526: }
527: if((dfp=fopen(filename,"a"))==NULL) { printf("File error\n"); return -1; }
528: for(s_p = students_p,first_stu=1; s_p ; s_p = s_p->s_next ) {
529: s_p->s_sn[MAX_STUDENT_NUMBER]=0;
530: printf(" Student: %s%s set %d",s_p->s_nm,s_p->s_sn,setIdx);
531: result = capa_parse(setIdx, &first_prob, s_p->s_sn, &q_cnt, NULL);
532: if ( result != 0 ) {
533: p = first_prob;
534: switch(outputFlag) {
535: case Q_ONLY:
536: if( StartText_p != NULL ) {
537: fprintf(dfp, "%s", StartText_p); fflush(dfp);
538: }
539: for( q_idx = 0; q_idx < q_cnt; printf("."),fflush(stdout), q_idx++ ) {
540: fprintf(dfp, "%s", p->question); fflush(dfp); p = p->next;
541: }
542: if( EndText_p != NULL ) {
543: fprintf(dfp, "%s", EndText_p); fflush(dfp);
544: }
545: break;
546: case A_ONLY:
547: print_header(Parsemode_f,dfp,s_p->s_sec,setIdx,s_p->s_nm,s_p->s_sn);
548: for( q_idx = 0; q_idx < q_cnt; printf("."),fflush(stdout), q_idx++ ) {
549: print_begin_item(Parsemode_f,dfp,q_idx+1);
550: ans_str = answers_string(Parsemode_f,p);
551: fprintf(dfp, "%s",ans_str); fflush(dfp);
552: capa_mfree((char *)ans_str);
553: p = p->next;
554: }
555: print_footer(Parsemode_f,dfp);
556: break;
557: case QA_BOTH:
558: if( StartText_p != NULL ) {
559: fprintf(dfp, "%s", StartText_p); fflush(dfp);
560: }
561: for( q_idx = 0; q_idx < q_cnt; printf("."),fflush(stdout), q_idx++ ) {
562: fprintf(dfp, "%s", p->question); fflush(dfp);
563: ans_str = answers_string(Parsemode_f,p);
564: fprintf(dfp, "%s",ans_str); fflush(dfp);
565: capa_mfree((char *)ans_str);
566: p = p->next;
567: }
568: if( ( EndText_p != NULL) ) {
569: fprintf(dfp, "%s", EndText_p);
570: }
571: break;
572: }
573: if( s_p->s_next != NULL ) {
574: if(Parsemode_f == TeX_MODE && pagebreak) {
575: fprintf(dfp, "\\clearpage\n\\setcounter{page}{1}\n"); fflush(dfp);
576: }
577: printf("\n");
578: }
579: free_problems(first_prob);
580: }
581: }
582: fflush(dfp); fclose(dfp);
583: if(Parsemode_f == TeX_MODE) {
584: if (directory_specified==0) {
585: sprintf(cmd, "cat TeXfooter >> TeX/section%d-set%d.tex\n", sectionIdx,setIdx); system(cmd);
586: } else {
587: sprintf(cmd, "cat TeXfooter >> %s/section%d-set%d.tex\n", out_directory,
588: sectionIdx,setIdx); system(cmd);
589: }
590: }
591: printf("\n DONE set%2d\n",setIdx);
592: }
593:
594: }
595: printf("\n DONE section%2d\n",sectionIdx);
596: }
597: free_students(students_p);
598: }
599: printf("ALL DONE\n");
600: return (0);
601: }
602:
603:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>