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>