File:
[LON-CAPA] /
capa /
capa51 /
pProj /
qzparse.c
Revision
1.8:
download - view:
text,
annotated -
select for diffs
Mon Aug 7 20:47:29 2000 UTC (24 years, 2 months ago) by
albertel
Branches:
MAIN
CVS tags:
version_2_9_X,
version_2_9_99_0,
version_2_9_1,
version_2_9_0,
version_2_8_X,
version_2_8_99_1,
version_2_8_99_0,
version_2_8_2,
version_2_8_1,
version_2_8_0,
version_2_7_X,
version_2_7_99_1,
version_2_7_99_0,
version_2_7_1,
version_2_7_0,
version_2_6_X,
version_2_6_99_1,
version_2_6_99_0,
version_2_6_3,
version_2_6_2,
version_2_6_1,
version_2_6_0,
version_2_5_X,
version_2_5_99_1,
version_2_5_99_0,
version_2_5_2,
version_2_5_1,
version_2_5_0,
version_2_4_X,
version_2_4_99_0,
version_2_4_2,
version_2_4_1,
version_2_4_0,
version_2_3_X,
version_2_3_99_0,
version_2_3_2,
version_2_3_1,
version_2_3_0,
version_2_2_X,
version_2_2_99_1,
version_2_2_99_0,
version_2_2_2,
version_2_2_1,
version_2_2_0,
version_2_1_X,
version_2_1_99_3,
version_2_1_99_2,
version_2_1_99_1,
version_2_1_99_0,
version_2_1_3,
version_2_1_2,
version_2_1_1,
version_2_1_0,
version_2_12_X,
version_2_11_X,
version_2_11_5_msu,
version_2_11_5,
version_2_11_4_uiuc,
version_2_11_4_msu,
version_2_11_4,
version_2_11_3_uiuc,
version_2_11_3_msu,
version_2_11_3,
version_2_11_2_uiuc,
version_2_11_2_msu,
version_2_11_2_educog,
version_2_11_2,
version_2_11_1,
version_2_11_0_RC3,
version_2_11_0_RC2,
version_2_11_0_RC1,
version_2_11_0,
version_2_10_X,
version_2_10_1,
version_2_10_0_RC2,
version_2_10_0_RC1,
version_2_10_0,
version_2_0_X,
version_2_0_99_1,
version_2_0_2,
version_2_0_1,
version_2_0_0,
version_1_99_3,
version_1_99_2,
version_1_99_1_tmcc,
version_1_99_1,
version_1_99_0_tmcc,
version_1_99_0,
version_1_3_X,
version_1_3_3,
version_1_3_2,
version_1_3_1,
version_1_3_0,
version_1_2_X,
version_1_2_99_1,
version_1_2_99_0,
version_1_2_1,
version_1_2_0,
version_1_1_X,
version_1_1_99_5,
version_1_1_99_4,
version_1_1_99_3,
version_1_1_99_2,
version_1_1_99_1,
version_1_1_99_0,
version_1_1_3,
version_1_1_2,
version_1_1_1,
version_1_1_0,
version_1_0_99_3,
version_1_0_99_2,
version_1_0_99_1,
version_1_0_99,
version_1_0_3,
version_1_0_2,
version_1_0_1,
version_1_0_0,
version_0_99_5,
version_0_99_4,
version_0_99_3,
version_0_99_2,
version_0_99_1,
version_0_99_0,
version_0_6_2,
version_0_6,
version_0_5_1,
version_0_5,
version_0_4,
stable_2002_spring,
stable_2002_july,
stable_2002_april,
stable_2001_fall,
release_5-1-3,
loncapaMITrelate_1,
language_hyphenation_merge,
language_hyphenation,
conference_2003,
bz6209-base,
bz6209,
STABLE,
HEAD,
GCI_3,
GCI_2,
GCI_1,
CAPA_5-1-6,
CAPA_5-1-5,
CAPA_5-1-4_RC1,
BZ4492-merge,
BZ4492-feature_horizontal_radioresponse,
BZ4492-feature_Support_horizontal_radioresponse,
BZ4492-Support_horizontal_radioresponse
- fixed license notices the reference the GNU GPL rather than the GNU LGPL
/* main program to convert .qz files
Copyright (C) 1992-2000 Michigan State University
The CAPA system is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The CAPA system is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public
License along with the CAPA system; see the file COPYING. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
As a special exception, you have permission to link this program
with the TtH/TtM library and distribute executables, as long as you
follow the requirements of the GNU GPL in regard to all of the
software in the executable aside from TtH/TtM.
*/
/* ======================================================================== */
/* Feb. 10 1997 Isaac Tsai */
/* ======================================================================== */
#ifdef NeXT
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <bsd/curses.h>
#else
#include <curses.h>
#include <malloc.h>
double atof();
#endif
#include <stdio.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
#include <time.h>
#include <math.h>
#include <string.h>
#define YES 1
#include "capaParser.h"
#include "capaCommon.h"
#include "ranlib.h"
#define Q_ONLY 1
#define A_ONLY 2
#define QA_BOTH 3
#define F_CLASS 1
#define F_SECTIONS 2
#define F_STUDENT 3
#define F_ALPHA 4
char *progname;
void free_header(T_header* header)
{
capa_mfree(header->weight);
capa_mfree(header->partial_credit);
}
void setdb_error(int set)
{
fprintf(stderr,"Set #%d has not had it's DB Header set. Please run Quizzer and set the DB Header.\n",set);
exit(-1);
}
void
print_header(int mode,FILE *o_fp,int sec,int set,char *stu_nam,char *stu_num)
{
extern char *StartText_p;
int capaid = capa_PIN(stu_num,set,0);
if( StartText_p != NULL ) {
fprintf(o_fp, "%s", StartText_p);
}
switch(mode) {
case TeX_MODE:
if (StartText_p == NULL ) {
fprintf(o_fp, "Section %d {\\Large %s}\\hspace*{1in}",sec,stu_nam);
fprintf(o_fp, "{\\large %s}, CAPAID: %d, set %d",stu_num, capaid, set);
}
fprintf(o_fp, "\n\\begin{enumerate}\n");
break;
case ASCII_MODE:
fprintf(o_fp, "Section %d %s ", sec,stu_nam);
fprintf(o_fp, "%s, CAPAID: %d set %d\n\n",stu_num, capaid, set);
break;
case HTML_MODE:
fprintf(o_fp, "<H2>Section %d %s, ", sec,stu_nam);
fprintf(o_fp, "%s, CAPAID:%d set %d</H2>\n", stu_num,capaid,set);
fprintf(o_fp, "<OL>\n");
break;
}
}
void
print_begin_item(int mode,FILE *o_fp,int q_idx)
{
switch(mode) {
case TeX_MODE:
fprintf(o_fp, "\\item ");
break;
case ASCII_MODE:
fprintf(o_fp, "%d) ", q_idx);
break;
case HTML_MODE:
fprintf(o_fp, "<LI> ");
break;
}
}
void
unit_toHTML(char *u_str, char *r)
{
int i;
char *ch;
while(isspace(*ch)) ch++;
while( isalnum(*ch) ) {
r[i++] = *ch; ch++;
}
if( *ch == '^' ) {
r[i++] = '<'; r[i++]='s';r[i++]='u';r[i++]='p';r[i++]='>';
ch++; while(isspace(*ch)) ch++;
while( isalnum(*ch) ) {
r[i++] = *ch; ch++;
}
r[i++] = '<'; r[i++]='/'; r[i++]='s';r[i++]='u';r[i++]='p';r[i++]='>';
} else {
r[i++] = *ch; ch++;
}
}
void
print_footer(int mode,FILE *o_fp)
{
extern char *EndText_p;
switch(mode) {
case TeX_MODE:
fprintf(o_fp, "\n\\end{enumerate}\n");
break;
case ASCII_MODE:
fprintf(o_fp, "\n");
break;
case HTML_MODE:
fprintf(o_fp, "</OL>\n");
break;
}
if( EndText_p != NULL ) {
fprintf(o_fp, "%s", EndText_p);
}
}
void output_problems(Problem_t* first_prob,int outputFlag,int q_cnt,FILE* dfp,
T_student* a_student,int setIdx)
{
extern int Parsemode_f;
extern char *EndText_p;
extern char *StartText_p;
Problem_t *p;
int q_idx;
char* ans_str;
p = first_prob;
switch(outputFlag) {
case Q_ONLY:
if( StartText_p != NULL) {
fprintf(dfp, "%s", StartText_p); fflush(dfp);
}
for( q_idx = 0; q_idx < q_cnt; printf("."),fflush(stdout), q_idx++ ) {
fprintf(dfp, "%s", p->question); p = p->next;
}
if( EndText_p != NULL) {
fprintf(dfp, "%s", EndText_p); fflush(dfp);
}
break;
case A_ONLY:
print_header(Parsemode_f, dfp,a_student->s_sec,setIdx,a_student->s_nm,
a_student->s_sn);
for( q_idx = 0; q_idx < q_cnt; printf("."),fflush(stdout), q_idx++ ) {
print_begin_item(Parsemode_f,dfp,q_idx+1);
ans_str = answers_string(Parsemode_f,p);
fprintf(dfp, "%s",ans_str); fflush(dfp);
capa_mfree((char *)ans_str);
p = p->next;
}
print_footer(Parsemode_f, dfp);
break;
case QA_BOTH:
if( StartText_p != NULL ) {
fprintf(dfp, "%s", StartText_p);
}
for( q_idx = 0; q_idx < q_cnt; printf("."),fflush(stdout), q_idx++ ) {
fprintf(dfp, "%s", p->question); fflush(dfp);
ans_str = answers_string(Parsemode_f,p);
fprintf(dfp, "%s",ans_str); fflush(dfp);
capa_mfree((char *)ans_str);
p = p->next;
}
if( EndText_p != NULL ) {
fprintf(dfp, "%s", EndText_p);
}
break;
}
}
/* ============================================================== */
/* qz --> tex -Tq */
/* qz --> html -Ha */
/* qz --> ascii -Ab */
/* question only q */
/* answer only a */
/* both b */
/* for entire class -C */
/* for a range of sections -Sec 2:6 */
/* for a section -Sec 2 */
/* for a student -Stu 12345678 */
/* output a set -Set 2 */
/* output a range of sets -Set 1:6 */
/* output blocksize -b 30 */
/* ============================================================== */
void usage()
{
printf("USAGE: %s [ -[T|H|A][a|b] ] [-Sec [n|n:m] | -Stu sn [-o filename] ]\n",progname);
printf(" [ -Set [n|n:m] ] [-c path_to_class] [-d outputdirectory]\n");
printf(" Example 1: %s -Tb -sec 2:3 -set 2:5\n", progname);
printf(" will generate tex files with both questions and answers\n");
printf(" for sections 2 to 3, sets 2 to 5\n");
printf(" Example 2: %s -Ha -stu A12345678 -set 3\n", progname);
printf(" will generate html files with answer only \n");
printf(" for student A12345678 set 3\n");
printf(" -T = tex mode\n");
printf(" -H = html mode\n");
printf(" -A = ascii mode\n");
printf(" = default question only\n");
printf(" a = answer only\n");
printf(" b = both question and answer\n");
printf(" -nopagebreak = don't put a \\clearpage between assignments\n");
printf(" -Sec 3 = for section 3\n");
printf(" -Sec 3:7 = from section 3 to section 7\n");
printf(" -Stu A12345678 = for a specified student\n");
printf(" -Set 1 = output set 1\n");
printf(" -Set 3:4 = output from set 3 to set 4\n");
printf(" -c class_path\n");
printf(" -o output_filename_with_absolute_path (only for a student)\n");
printf(" -d directory_to_create_files_in (default is class_path/TeX)\n");
printf("-------This is version %s @ %s\n",CAPA_VER,COMPILE_DATE);
printf("------------------------------------------------------\n");
printf("CAPA is released under GNU GPL v2, see COPYING for details.\n");
}
/* filter out the number to be [1:999] */
int scan_num(char *num_str,int *first, int *second) {
char tmp_str[SMALL_LINE_BUFFER], *ch;
int ii=0, a_num, b_num, result=0;
ch = num_str;
tmp_str[ii] = 0;
while( isspace(*ch) ) ch++;
while(isdigit(*ch)) { tmp_str[ii++] = *ch; ch++; }
tmp_str[ii] = 0;
sscanf(tmp_str,"%d",&a_num);
if( a_num < 0 || a_num > 999 ) a_num = 1;
*first = a_num;
result = 1;
while( isspace(*ch) ) ch++;
if( *ch == ':' ) {
ch++;
while( isspace(*ch) ) ch++;
ii=0; tmp_str[ii] = 0;
while( isdigit(*ch) ) { tmp_str[ii++] = *ch; ch++; }
tmp_str[ii] = 0;
sscanf(tmp_str,"%d",&b_num);
if( b_num < 0 || b_num > 999 ) b_num = 1;
if( a_num > b_num ) b_num = a_num;
*second = b_num;
result = 2;
}
return (result);
}
FILE* start_set(int directory_specified,char* out_directory,int file_specified,
char *out_filename,char* filestart,char* filename)
{
extern int Parsemode_f;
char cmd[MAX_BUFFER_SIZE];
FILE* dfp;
if (file_specified == 0) {
if (directory_specified == 0 ) {
switch( Parsemode_f ) {
case TeX_MODE:
sprintf(filename,"TeX/%s.tex",filestart);
break;
case ASCII_MODE:
sprintf(filename,"ASCII/%s.ascii",filestart);
break;
case HTML_MODE:
sprintf(filename,"HTML/%s.text",filestart);
break;
}
} else {
switch( Parsemode_f ) {
case TeX_MODE:
sprintf(filename,"%s/%s.tex",out_directory,filestart);
break;
case ASCII_MODE:
sprintf(filename,"%s/%s.ascii",out_directory,filestart);
break;
case HTML_MODE:
sprintf(filename,"%s/%s.text", out_directory,filestart);
break;
}
}
} else {
if (directory_specified == 0 ) {
sprintf(filename,"%s",out_filename);
} else {
sprintf(filename,"%s/%s",out_directory,out_filename);
}
}
switch ( Parsemode_f ) {
case TeX_MODE: sprintf(cmd, "cp TeXheader %s\n",filename); system(cmd); break;
default: sprintf(cmd,"rm %s\n",filename);system(cmd); break;
}
if((dfp=fopen(filename,"a"))==NULL) { printf("File error\n"); exit(-1); }
return dfp;
}
void end_set(FILE*dfp,char* filename)
{
extern int Parsemode_f;
char cmd[MAX_BUFFER_SIZE];
fflush(dfp);
fclose(dfp);
if(Parsemode_f == TeX_MODE) {
sprintf(cmd, "cat TeXfooter >> %s\n", filename);
system(cmd);
}
}
void end_page(FILE*dfp,int pagebreak)
{
extern int Parsemode_f;
if( Parsemode_f == TeX_MODE && pagebreak ) {
fprintf(dfp, "\\clearpage\n\\setcounter{page}{1}\n"); fflush(dfp);
} else {
printf("\n");
}
}
int main (int argc, char **argv)
{
extern int Parsemode_f;
extern char *EndText_p;
extern char *StartText_p;
extern char *ErrorMsg_p;
extern int ErrorMsg_count;
Problem_t *first_prob,*p;
T_student *students_p,*s_p, a_student;
int num_students, q_cnt, result, inputNotOK = 1,
ii, sectionIdx, setIdx = 1, q_idx, outputFlag = 0;
char filename[FILE_NAME_LENGTH], path[FILE_NAME_LENGTH],
filestart[FILE_NAME_LENGTH];
FILE *dfp;
int tmp_num, first_stu, file_specified, directory_specified;
int ForWhat = F_SECTIONS, pagebreak=1,
StartSec = 1, EndSec = 1, StartSet = 1, EndSet = 1;
char StuNum[MAX_STUDENT_NUMBER+1];
char out_filename[FILE_NAME_LENGTH],out_directory[FILE_NAME_LENGTH];
char cmd[SMALL_LINE_BUFFER], *ans_str;
/* qz --> tex -T */
/* qz --> html -Ha */
/* qz --> ascii -Ab */
/* answer only a */
/* both b */
/* for entire class -C */
/* for a range of sections -Sec 2:6 */
/* for a section -Sec 2 */
/* for a student -Stu 12345678 */
/* output a set -Set 2 */
/* output a range of sets -Set 1:6 */
/* default */
Parsemode_f = TeX_MODE; ForWhat = F_SECTIONS; outputFlag=Q_ONLY;
file_specified=0;
out_filename[0]='\0';
directory_specified=0;
out_directory[0]='\0';
for( progname = *argv++; --argc; argv++) {
if ( argv[0][0] == '-' ) {
switch(argv[0][1]) {
case 'T': Parsemode_f = TeX_MODE;
outputFlag=(argv[0][2] == 'a' ? A_ONLY :(argv[0][2] == 'b' ? QA_BOTH : Q_ONLY));
break;
case 'H': Parsemode_f = HTML_MODE;
outputFlag=(argv[0][2] == 'a' ? A_ONLY :(argv[0][2] == 'b' ? QA_BOTH : Q_ONLY));
break;
case 'A': Parsemode_f = ASCII_MODE;
outputFlag=(argv[0][2] == 'a' ? A_ONLY :(argv[0][2] == 'b' ? QA_BOTH : Q_ONLY));
break;
case 'S':
case 's': if( strncasecmp(argv[0],"-sec",4) == 0 ) {
tmp_num = scan_num(argv[1],&StartSec,&EndSec);
if( tmp_num == 1 ) { EndSec = StartSec; }
ForWhat = F_SECTIONS;
} else if( strncasecmp(argv[0],"-stu",4) == 0 ) {
for(ii=0;ii<MAX_STUDENT_NUMBER;ii++) {
StuNum[ii] = argv[1][ii];
}
StuNum[ii]=0;
ForWhat = F_STUDENT;
} else if( strncasecmp(argv[0],"-set",4) == 0 ) {
tmp_num = scan_num(argv[1],&StartSet,&EndSet);
if( tmp_num == 1 ) { EndSet = StartSet; }
} else {
usage();
}
break;
case 'c': strcpy(path, argv[1]);
if(capa_access(path, F_OK) == -1) {
inputNotOK = 1;
} else {
inputNotOK = 0;
}
break;
case 'o':
if (argc == 1 || argv[1][0] == '-') {
usage(); return 0;
} else {
strcpy(out_filename, argv[1]); file_specified=1; break;
}
case 'd':
if (argc == 1 || argv[1][0] == '-') {
usage(); return 0; break;
} else {
strcpy(out_directory, argv[1]); directory_specified=1; break;
}
case 'n':
pagebreak=0;break;
case 'u': case 'h': default: usage(); return(0); break;
}
}
}
printf(" %s running in %s mode, %s for %s, ", progname,
(Parsemode_f == TeX_MODE ? "TeX" : (Parsemode_f == ASCII_MODE ? "ASCII" : "HTML")),
(outputFlag==A_ONLY ? "answer only" : (outputFlag==QA_BOTH? "question and answer" : "question only")),
(ForWhat == F_STUDENT ? "a student" : "section" ) );
if( ForWhat == F_STUDENT ) {
printf(" for student %s,",StuNum);
} else {
if(StartSec==EndSec) {
printf(" for section %d,", StartSec);
}
else {
printf(" from section %d to %d,",StartSec, EndSec);
}
}
if(StartSet==EndSet) { printf(" set %d\n",StartSet); } else { printf(" from set %d to %d\n", StartSet, EndSet); }
while ( inputNotOK ) {
puts("Enter the ABSOLUTE path of class");
scanf("%s", path);
if( capa_access(path, F_OK) == -1 ) {
} else {
sprintf(filename,"%s/classl",path);
if( capa_access(filename, F_OK) == -1 ) {
puts("There isn't a classl file in this CLASS directory\nPlease Specify another class");
} else {
inputNotOK = 0;
}
}
}
if( (ForWhat == F_STUDENT) && strlen(StuNum) == 0 ) {
inputNotOK = 1;
while ( inputNotOK ) {
puts("Enter student number"); scanf("%s", StuNum);
if( strlen(StuNum) == MAX_STUDENT_NUMBER ) { inputNotOK = 0; }
}
}
if ( file_specified == 0) {
if ( directory_specified == 0) {
switch( Parsemode_f ) {
case TeX_MODE: sprintf(filename,"%s/TeX",path); break;
case ASCII_MODE: sprintf(filename,"%s/ASCII",path); break;
case HTML_MODE: sprintf(filename,"%s/HTML",path); break;
default: sprintf(filename,"%s/TeX",path); Parsemode_f = TeX_MODE; break;
}
} else {
sprintf(filename,"%s",out_directory);
}
if( capa_access(filename, F_OK) == -1 ) {
if ( mkdir(filename, S_IREAD | S_IWRITE | S_IEXEC ) == -1 ) {
printf("Unable to write to %s\n",filename);
printf("Please check this directory and run %s again.\n",progname);
return(-1);
}
}
} else {
if ( directory_specified == 0) {
} else {
sprintf(filename,"%s",out_directory);
}
}
chdir(path);
if ( ForWhat == F_SECTIONS ) {
T_dates* dates;
T_header header;
for(ii=StartSet;ii<=EndSet;ii++) {
if (capa_get_header(&header,ii)<0) setdb_error(ii);
free_header(&header);
if (capa_get_all_dates(ii,&dates)<0) setdb_error(ii);
free_dates(dates);
}
}
switch (ForWhat) {
case F_STUDENT:
result = capa_get_student(StuNum, &a_student);
if ( result == 0 ) {
fprintf(stderr,"Unable to find student %s in %s/classl",StuNum,path);
exit(-1);
} else {
if (result == -1 ) {
fprintf(stderr,"Unable to read %s/classl",path);
exit(-1);
}
}
dfp=start_set(directory_specified,out_directory,file_specified,out_filename,
StuNum,filename);
for(setIdx=StartSet; setIdx <= EndSet; setIdx++) {
result = capa_parse(setIdx, &first_prob, StuNum, &q_cnt, NULL);
if ( result != 0 ) {
output_problems(first_prob,outputFlag,q_cnt,dfp,&a_student,setIdx);
free_problems(first_prob);
}
if( setIdx < EndSet ) { end_page(dfp,pagebreak); }
if( ErrorMsg_count > 0 ) { printf("%s",ErrorMsg_p); }
}
end_set(dfp,filename);
printf("\n DONE Student %s\n",StuNum);
break;
case F_SECTIONS:
for(sectionIdx = StartSec; sectionIdx <= EndSec; sectionIdx++ ) {
num_students = capa_sorted_section(&students_p, sectionIdx);
if( num_students > 0 ) {
printf("Section %2d: %d students\n",sectionIdx,num_students);
for(setIdx=StartSet; setIdx <= EndSet; setIdx++) {
sprintf(filestart,"section%d-set%d",sectionIdx,setIdx);
dfp=start_set(directory_specified,out_directory,file_specified,
out_filename,filestart,filename);
for(s_p = students_p,first_stu=1; s_p ; s_p = s_p->s_next ) {
s_p->s_sn[MAX_STUDENT_NUMBER]=0;
printf(" Student: %s%s set %d\n",s_p->s_nm,s_p->s_sn,setIdx);
result = capa_parse(setIdx, &first_prob, s_p->s_sn, &q_cnt, NULL);
if ( result != 0 ) {
output_problems(first_prob,outputFlag,q_cnt,dfp,s_p,setIdx);
free_problems(first_prob);
if( s_p->s_next != NULL ) { end_page(dfp,pagebreak); }
}
}
end_set(dfp,filename);
printf("\n DONE set%2d\n",setIdx);
}
}
printf("\n DONE section%2d\n",sectionIdx);
}
free_students(students_p);
break;
case F_ALPHA:
break;
}
printf("ALL DONE\n");
return (0);
}
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>