File:  [LON-CAPA] / capa / capa51 / GUITools / quizzer.funct.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Sep 28 21:25:36 1999 UTC (24 years, 8 months ago) by albertel
Branches: capa
CVS tags: start
Created directory structure

    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>