Annotation of capa/capa51/GUITools/quizzer.funct.c, revision 1.1.1.1

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>