Annotation of capa/capa51/Historic/bubbler.c, revision 1.1

1.1     ! albertel    1: #include <stdio.h>
        !             2: #include <sgtty.h>
        !             3: #include <libc.h>
        !             4: #include <sys/types.h>
        !             5: #include <sys/uio.h>
        !             6: #include <ctype.h>
        !             7: #include "Capa/capaCommon.h"
        !             8: #include "bubbler.h"
        !             9: 
        !            10: int serportfd;
        !            11: int readportfd;
        !            12: FILE * readport;
        !            13: int CheckPIN;
        !            14: int CompareClassName;
        !            15: int Anon;
        !            16: int CheckSpaces;
        !            17: int SurveyMode;
        !            18: int SurveyHeader;
        !            19: int formNumber;
        !            20: 
        !            21: int GetProblems(Question questions[MAXQUEST],char * class,int * setId)
        !            22: {
        !            23:   int i,q,length;
        !            24:   char clear[100];
        !            25: 
        !            26:   printf("What is the class name?");
        !            27:   scanf("%s",class);
        !            28:   
        !            29:   printf("What is the SetId?");
        !            30:   scanf("%d",setId);
        !            31: 
        !            32:   printf("Is this a survey or exam/quiz?(s or e)");
        !            33:   scanf("%s",clear);
        !            34:   if (clear[0]=='s' || clear[0]=='S')
        !            35:     {
        !            36:       SurveyMode=1;
        !            37:       printf("Does the form include a Header?(y or n)");
        !            38:       scanf("%s",clear);
        !            39:       if (clear[0]=='n' || clear[0]=='N')
        !            40: 	{
        !            41: 	  SurveyHeader=0;
        !            42: 	}
        !            43:       else
        !            44: 	{
        !            45: 	  SurveyHeader=1;
        !            46: 	}
        !            47:       printf("How many Questions are on the form?");
        !            48:       scanf("%d",&q);
        !            49:       
        !            50:       for (i=0;i<q;i++)
        !            51: 	{
        !            52: 	  questions[i].type='d';
        !            53: 	  questions[i].leafs=questions[i].points=9;
        !            54: 	}
        !            55:     }
        !            56:   else
        !            57:     {
        !            58:       SurveyMode=0;
        !            59: 
        !            60:       printf("Should bubbler compare the entered class name and SetId with \n");
        !            61:       printf("the encoded information on each paper?(y or n)");
        !            62:       scanf("%s",clear);
        !            63:       if (clear[0]=='N' || clear[0]=='n')
        !            64: 	CompareClassName=0;
        !            65:       else
        !            66: 	CompareClassName=1;
        !            67:       
        !            68:       printf("Should the student coded CAPA ID be checked for correctness?\n");
        !            69:       printf("(y or n)");
        !            70:       scanf("%s",clear);
        !            71:       if (clear[0]=='N' || clear[0]=='n')
        !            72: 	CheckPIN=0;
        !            73:       else
        !            74: 	{
        !            75: 	  CheckPIN=1;
        !            76: 	  
        !            77: 	  printf("Should bubbler run in Anonymous mode (search for correct \n");
        !            78: 	  printf("Student Number based on the CAPA ID)? (y or n)");
        !            79: 	  scanf("%s",clear);
        !            80: 	  
        !            81: 	  if (clear[0]=='N' || clear[0]=='n')
        !            82: 	    Anon=0;
        !            83: 	  else
        !            84: 	    Anon=1;
        !            85: 	}
        !            86:       
        !            87:       printf("Should bubbler check for blank answers and issue a warning when \n");
        !            88:       printf("one is encountered? (y or n)");
        !            89:       scanf("%s",clear);
        !            90:       if (clear[0]=='N' || clear[0]=='n')
        !            91: 	CheckSpaces=0;
        !            92:       else
        !            93: 	CheckSpaces=1;
        !            94:       
        !            95:       length=strlen(class);
        !            96:       if (length < 8)
        !            97: 	{
        !            98: 	  for(;length<8;length++)
        !            99: 	    {
        !           100: 	      class[length]=' ';
        !           101: 	    }
        !           102: 	  class[length]='\0';
        !           103: 	}
        !           104:       printf("How many Questions are on the form?");
        !           105:       scanf("%d",&q);
        !           106:       
        !           107:       printf("For Each Question enter \"a\" for a one out of 8\n");
        !           108:       printf("                        \"b\" for a GLE type\n");
        !           109:       printf("                        \"c\" for a TF type.\n");
        !           110:       printf("                        \"d\" for an assigned score.\n");
        !           111:       printf("                        \"e\" for a multiple out of 8.\n");
        !           112:       printf("                        \"f\" for single digit string matching.\n");
        !           113:       printf("                        \"g\" for exact string matching/\n");
        !           114:       
        !           115:       for (i=0;i<q;i++)
        !           116: 	{
        !           117: 	  printf("Question#%2d: ",i+1);
        !           118: 	  scanf("%1s",&questions[i].type);
        !           119: 	  fflush(stdin);
        !           120: 	  switch(questions[i].type)
        !           121: 	    {
        !           122: 	    case 'a':
        !           123: 	    case 'd':
        !           124: 	    case 'g':
        !           125: 	    case 'f':
        !           126: 	      printf("How many Points are possible?");
        !           127: 	      scanf("%d",&questions[i].points);
        !           128: 	      questions[i].leafs=questions[i].points;
        !           129: 	      break;
        !           130: 	    case 'b':
        !           131: 	    case 'c':
        !           132: 	      printf("How many parts to the problem?");
        !           133: 	      scanf("%d",&questions[i].points);
        !           134: 	      questions[i].leafs=questions[i].points;
        !           135: 	      break;
        !           136: 	    case 'e':
        !           137: 	      printf("How many possible answers are there?");
        !           138: 	      scanf("%d",&questions[i].points);
        !           139: 	      questions[i].leafs=questions[i].points;
        !           140: 	      break;
        !           141: 	    default:
        !           142: 	      printf("Unknown choice.\n");
        !           143: 	      break;
        !           144: 	    }
        !           145: 	  fflush(stdin);
        !           146: 	}
        !           147:     }
        !           148:   return q;
        !           149: }
        !           150:  
        !           151: void serial_open(FILE ** streamserport,char * device)
        !           152: {
        !           153:   struct sgttyb one;
        !           154:   
        !           155:   if ((serportfd=open(device,O_WRONLY,O_CREAT))==-1)
        !           156:     {
        !           157:       fprintf(stderr,"Unable to open serial port.\n");
        !           158:       exit(-1);
        !           159:     }
        !           160: 
        !           161:   if ((readportfd=open(device,O_RDONLY,O_CREAT))==-1)
        !           162:     {
        !           163:       fprintf(stderr,"Unable to open serial port for reading.\n");
        !           164:       exit(-1);
        !           165:     }
        !           166:   
        !           167:   one.sg_ispeed='\015';
        !           168:   one.sg_ospeed='\015';
        !           169:   one.sg_erase='\177';
        !           170:   one.sg_kill='\024';
        !           171:   one.sg_flags= (short) 3;
        !           172: 
        !           173: #ifdef DEBUG  
        !           174:   ioctl(serportfd,TIOCGETP,&two);
        !           175:   printf("%d %d %d %d %d\n",two.sg_ispeed,two.sg_ospeed,
        !           176: 	 two.sg_erase,two.sg_kill,two.sg_flags);
        !           177: #endif
        !           178:   
        !           179:   ioctl(serportfd,TIOCSETN,&one);
        !           180:   ioctl(readportfd,TIOCSETN,&one);
        !           181: 
        !           182: #ifdef DEBUG
        !           183:   ioctl(serportfd,TIOCGETP,&two);
        !           184:   printf("%d %d %d %d %d\n",two.sg_ispeed,two.sg_ospeed,
        !           185: 	 two.sg_erase,two.sg_kill,two.sg_flags);
        !           186:   printf("%d %d %d %d %d\n",one.sg_ispeed,one.sg_ospeed,
        !           187: 	 one.sg_erase,one.sg_kill,one.sg_flags);
        !           188: #endif
        !           189:   *streamserport=fdopen(serportfd,"w");
        !           190:   readport=fdopen(readportfd,"r");
        !           191: }
        !           192: 
        !           193: 
        !           194: void print(FILE** serport,char * out,int shouldread)
        !           195: {
        !           196:   int readamount;
        !           197:   char buf[100];
        !           198: 
        !           199: #ifdef DEBUG
        !           200:   printf("%s\n",out);
        !           201: #endif /*DEBUG*/
        !           202: 
        !           203:   write(serportfd,out,strlen(out));
        !           204:   if (shouldread)
        !           205:     {
        !           206:       readamount=read(readportfd,buf,1);
        !           207: #ifdef DEBUG
        !           208:       printf("%d %d\n",readamount,buf[0]);
        !           209: #endif
        !           210:     }
        !           211: }
        !           212: 
        !           213: void send_initform_strings(FILE ** serport,int numQuestions,
        !           214: 			   Question questions[MAXQUEST])
        !           215: {
        !           216:   int i, scan,j,Points;
        !           217:   /* this sets up kermit and then sends the correct strings to the scantron 
        !           218:      to define what the sheet looks like 
        !           219:      */
        !           220:   char buffer[1024],answerString[1024];
        !           221:   
        !           222:   for(i=0;i<1000;i++) 
        !           223:     {
        !           224:       buffer[i]='\0';
        !           225:     }
        !           226:   
        !           227:   scan=11+numQuestions;
        !           228:   
        !           229:   /* resets the scantron*/
        !           230:   sprintf(buffer,".srst\015");
        !           231:   print(serport,buffer, 1);
        !           232:   
        !           233:   /* sets the error character to be the '"' character */
        !           234:   sprintf(buffer,".err=34\015");
        !           235:   print(serport,buffer, 1);
        !           236:  
        !           237:   /* tell scantron how many scanlines there are*/
        !           238:   sprintf(buffer,".frm=fs %d 0 48 n n n\015",scan);
        !           239:   print(serport,buffer, 1);
        !           240:  
        !           241:   /* encoded class info*/
        !           242:   sprintf(buffer,".frm=pa 1 2 44 11 32 l 10 7\015");
        !           243:   print(serport,buffer, 1);
        !           244:  
        !           245:   /* the first letter of the student number*/
        !           246:   sprintf(buffer,".frm=mc n n 1 1 3 4 4 4 c 1 2 ab\015");
        !           247:   print(serport,buffer, 1);
        !           248:  
        !           249:   /* the remaining digits of the student number*/
        !           250:   sprintf(buffer,".frm=mc n n 1 1 2 6 11 20 c 8 10 0123456789\015");
        !           251:   print(serport,buffer, 1);
        !           252:  
        !           253:   /* the PIN number*/
        !           254:   sprintf(buffer,".frm=mc n n 1 1 2 24 11 30 c 4 10 0123456789\015");
        !           255:   print(serport,buffer, 1);
        !           256: 
        !           257: #ifdef DEBUG
        !           258:   printf("%d\n",numQuestions);
        !           259: #endif /*DEBUG*/
        !           260: 
        !           261:   /*sets each question line*/
        !           262:   for (i=0;i<numQuestions;i++)
        !           263:     {
        !           264: 
        !           265: #ifdef DEBUG
        !           266:       printf("%c\n",questions[i].type);
        !           267: #endif /*DEBUG*/
        !           268: 
        !           269:       switch (questions[i].type)
        !           270: 	{
        !           271: 	case 'a':
        !           272: 	  sprintf(buffer,".frm=mc n m 1 1 %d 6 %d 20 l 1 8 ABCDEFGH\015",
        !           273: 		  i+12,i+12);
        !           274: 	  print(serport,buffer,1);
        !           275: 	  break;
        !           276: 	case 'b':
        !           277: 	  for(j=0;j<questions[i].points;j++)
        !           278: 	    {
        !           279: 	      sprintf(buffer,
        !           280: 		      ".frm=mc n m 1 1 %d %d %d %d l 1 3 GLE\015",
        !           281: 		      i+12,(j*8)+6,i+12,(j*8)+10);
        !           282: 	      print(serport,buffer,1);
        !           283: 	    }
        !           284: 	  break;
        !           285: 	case 'c':
        !           286: 	  for(j=0;j<questions[i].points;j++)
        !           287: 	    {
        !           288: 	      sprintf(buffer,
        !           289: 		      ".frm=mc n m 1 1 %d %d %d %d l 1 2 TF\015",
        !           290: 		      i+12,(j*6)+6,i+12,(j*6)+8);
        !           291: 	      print(serport,buffer,1);
        !           292: 	    }
        !           293: 	  break;
        !           294: 	case 'd':
        !           295: 	  answerString[0]='\0';
        !           296: 	  Points=questions[i].points;
        !           297: 	  for(j=0;j<=Points;j++)
        !           298: 	    {
        !           299: 	      sprintf(buffer,"%d",j);
        !           300: 	      strcat(answerString,buffer);
        !           301: 	    }
        !           302: 	  sprintf(buffer,".frm=mc n m 1 1 %d 6 %d %d l 1 %d %s\015",
        !           303: 		  i+12,i+12,(Points*2)+6,Points+1,answerString);
        !           304: 	  print(serport,buffer,1);
        !           305: 	  break;
        !           306: 	case 'e':
        !           307: 	case 'g':
        !           308: 	  sprintf(buffer,".frm=mc y n 1 1 %d 6 %d 20 l 1 8 ABCDEFGH\015",
        !           309: 		  i+12,i+12);
        !           310: 	  print(serport,buffer,1);
        !           311: 	  break;
        !           312: 	case 'f':
        !           313: 	  sprintf(buffer,".frm=mc n m 1 1 %d 6 %d 24 l 1 10 0123456789\015",
        !           314: 		  i+12,i+12);
        !           315: 	  print(serport,buffer,1);
        !           316: 	  break;
        !           317: 	default:
        !           318: 	  fprintf(stderr,"Booga Booga, couldn't find that question type to");
        !           319: 	  fprintf(stderr," tell Scantron about\n %c \n",questions[i].type);
        !           320: 	  break;
        !           321: 	}
        !           322:     }
        !           323: 
        !           324:   /* end of the form*/
        !           325:   sprintf(buffer,".frm=ls\015");
        !           326:   print(serport,buffer, 1);
        !           327: #ifdef DEBUG
        !           328:   fprintf(stderr,"We have sent the data\n");
        !           329: #endif /*DEBUG*/
        !           330: }
        !           331: 
        !           332: void SetupScantron(FILE ** serport,int problems,
        !           333: 		   Question questions[MAXQUEST])
        !           334: {
        !           335:   serial_open(serport,"/dev/ttyfb");
        !           336:   send_initform_strings(serport,problems,questions);
        !           337: }
        !           338: 
        !           339: /* stolen from allpin.c and modified by Guy Albertelli*/
        !           340: int buildPIDandPINlist(int setId, PIDPINlist PIDandPINlist[MAX_SECTION_SIZE] )
        !           341: {
        !           342:   int i=0,j=0,count=0,numStudents;
        !           343:   int SecCntArry[MAX_SECTION_COUNT], sectionIdx;
        !           344:   student_t Students[2048];
        !           345: 
        !           346:   if (count = capa_get_section_count(SecCntArry) != 0)
        !           347:     {
        !           348:       for (sectionIdx=1; sectionIdx <= SecCntArry[0]; sectionIdx++)
        !           349: 	{
        !           350: 	  numStudents=0;
        !           351: 	  get_section(Students, &numStudents, sectionIdx);
        !           352: 	  for(i=0;i<numStudents;i++,j++)
        !           353: 	    {
        !           354: 	      strcpy(PIDandPINlist[j].PID,Students[i].student_number);
        !           355: 	      PIDandPINlist[j].PIN=
        !           356: 		capa_PIN(Students[i].student_number,setId,0);
        !           357: 	    }
        !           358: 	}
        !           359:     }
        !           360:   return j;
        !           361: }
        !           362: 
        !           363: /*searches all the possible PIN's for all matches and then asks for 
        !           364:   confirmation of which PID to use*/
        !           365: int findPID(Student* student,PIDPINlist PIDandPINlist[MAX_SECTION_SIZE],
        !           366: 	    int numOfStudents)
        !           367: {
        !           368:   int i,j=0,matches[30],selection,error=ENONE;
        !           369:   
        !           370:   for(i=0;i<numOfStudents;i++)
        !           371:     {
        !           372:       if (atoi(student->PIN)==PIDandPINlist[i].PIN)
        !           373: 	{
        !           374: 	  matches[j]=i;
        !           375: 	  j++;
        !           376: 	}
        !           377:     }
        !           378:   matches[j]=-1;
        !           379:   switch(j)
        !           380:     {
        !           381:     case 0:
        !           382:       printf("No match for PIN %s\n",student->PIN);
        !           383:       error=ENOONE;
        !           384:       break;
        !           385:     case 1:
        !           386:       printf("Only one match assuming PID %s\n",PIDandPINlist[matches[0]].PID);
        !           387:       strcpy(student->questionPID,PIDandPINlist[matches[0]].PID);
        !           388:       break;
        !           389:     default:
        !           390:       printf("Please press\n");
        !           391:       for(i=0;i<30;i++)
        !           392: 	{
        !           393: 	  if (matches[i]!=-1)
        !           394: 	    {
        !           395: 	      printf("%d) for student number %s\n",i,
        !           396: 		     PIDandPINlist[matches[i]].PID);
        !           397: 	    }
        !           398: 	  else
        !           399: 	    {
        !           400: 	      i=30;
        !           401: 	    }
        !           402: 	}
        !           403:       scanf("%d",&selection);
        !           404:       if ((selection < j) && (selection > 0))
        !           405: 	{
        !           406: 	  strcpy(student->questionPID,PIDandPINlist[matches[selection]].PID);
        !           407: 	}
        !           408:       break;
        !           409:     }
        !           410:   return error;
        !           411: }
        !           412: 
        !           413: Student * getForm(int * status,FILE ** serport,
        !           414: 		  Question questions[MAXQUEST])
        !           415: {
        !           416:   Student *newStudent;
        !           417:   char buffer[1024],buf[1024],buf2[1024];
        !           418:   int readamount=0,done=0,i=0,j=0,h=0,q=0,space=0;
        !           419: 
        !           420:   sprintf(buffer,".read 2\015");
        !           421:   print(serport,buffer,1);
        !           422:   while(!done)
        !           423:     {
        !           424:       readamount=read(readportfd,buf,100);
        !           425:       buf[readamount]='\0';
        !           426:       for(i=0;i<readamount;i++,j++)
        !           427: 	{
        !           428: 	  if (buf[i]==13)
        !           429: 	    {
        !           430: 	      done=1;
        !           431: 	      break;
        !           432: 	    }
        !           433: 	  buf2[j]=buf[i];
        !           434: 	}
        !           435:       buf2[j]='\0';
        !           436:     }
        !           437: 
        !           438:   printf("%s\n",buf2);
        !           439: 
        !           440:   switch(buf2[0])
        !           441:     {
        !           442:     case '\"':
        !           443:       *status=GFFAILED;
        !           444:       return NULL;
        !           445:       break;
        !           446:     default:
        !           447:       newStudent=(Student *)malloc(sizeof(Student));
        !           448:       if (SurveyMode) 
        !           449: 	sprintf(newStudent->answerPID,"a%08d",formNumber++);
        !           450:       else
        !           451: 	strncpy(newStudent->answerPID,&buf2[10],9);
        !           452:       newStudent->answerPID[9]='\0';
        !           453:       strncpy(newStudent->class,&buf2[2],8);
        !           454:       newStudent->class[8]='\0';
        !           455:       strncpy(newStudent->SetId,&buf2[0],2);
        !           456:       newStudent->SetId[2]='\0';
        !           457:       strncpy(newStudent->PIN,&buf2[19],4);
        !           458:       newStudent->PIN[4]='\0';
        !           459:       i=23;h=0;
        !           460:       while(buf2[i]!='\0')
        !           461: 	{
        !           462: 	  switch(questions[h].type)
        !           463: 	    {
        !           464: 	    case 'a':
        !           465: 	    case 'd':
        !           466: 	    case 'f':
        !           467: 	      newStudent->Answers[h][0]=buf2[i];
        !           468: 	      newStudent->Answers[h][1]='\0';
        !           469: 	      if (isspace(buf2[i])) space++;
        !           470: 	      i++;
        !           471: 	      break;
        !           472: 	    case 'b':
        !           473: 	      /*loop through each leaf*/
        !           474: 	      for(j=0;j<questions[h].points;j++)
        !           475: 		{
        !           476: 		  newStudent->Answers[h][j]=buf2[i];
        !           477: 		  if (isspace(buf2[i])) space++;
        !           478: 		  i++;
        !           479: 		}
        !           480: 	      newStudent->Answers[h][j]='\0';
        !           481: 	      break;
        !           482: 	    case 'c':
        !           483: 	      /*loop through each leaf*/
        !           484: 	      for(j=0;j<questions[h].points;j++)
        !           485: 		{
        !           486: 		  newStudent->Answers[h][j]=buf2[i];
        !           487: 		  if (isspace(buf2[i])) space++;
        !           488: 		  i++;
        !           489: 		}
        !           490: 	      newStudent->Answers[h][j]='\0';
        !           491: 	      break;
        !           492: 	    case 'e':
        !           493: 	    case 'g':
        !           494: 	      for (j=0,q=0;j<8;j++)
        !           495: 		{
        !           496: 		  if (buf2[i]!=' ')
        !           497: 		    {
        !           498: 		      newStudent->Answers[h][q]=buf2[i];
        !           499: 		      q++;
        !           500: 		    }
        !           501: 		  i++;
        !           502: 		}
        !           503: 	      if (isspace(buf2[i])) space++;
        !           504: 	      newStudent->Answers[h][q]='\0';
        !           505: 	      break;
        !           506: 	    default:
        !           507: 	      fprintf(stderr,"Wha? %c",questions[h].type);
        !           508: 	      i++;
        !           509: 	      break;
        !           510: 	    }
        !           511: 	  h++;
        !           512: 	}
        !           513:       *status=GFSUCCESS;
        !           514:       break;
        !           515:     }
        !           516:   if (space!=0) *status=GFSPACES;
        !           517:   return newStudent;
        !           518: }
        !           519: 
        !           520: int checkForm(Student * student,int numQuestions,char *class,int setId)
        !           521: {
        !           522:   int error,pin;
        !           523:   student_t capaStudent;
        !           524: 
        !           525: #ifdef DEBUG
        !           526:   printf("PID:\t%s\nclass:\t%s\nSetId:\t%s\nPIN:\t%s\n",
        !           527: 	 student->answerPID,student->class,student->SetId,student->PIN);
        !           528: 
        !           529:   for(i=0,j=0;i<numQuestions;i++)
        !           530:     {
        !           531:       printf("Answer %d: %s\n",i,student->Answers[i]);
        !           532:     }
        !           533: #endif /*DEBUG*/
        !           534: 
        !           535:   if (CompareClassName)
        !           536:     {
        !           537:       if (strncasecmp(student->class,class,8))
        !           538: 	{
        !           539: 	  printf("Class: The Scantron reported:%s, You typed in:%s\n",
        !           540: 		 student->class,class);
        !           541: 	  return ECLASS;
        !           542: 	}
        !           543:     }
        !           544:   else
        !           545:     {
        !           546:       strcpy(student->class,class);
        !           547:       sprintf(student->SetId,"%2d",setId);
        !           548:     }
        !           549: 
        !           550:   error=capa_get_student_info(student->answerPID, &capaStudent);
        !           551:   switch(error)
        !           552:     {
        !           553:     case 1:
        !           554:       printf("%s %d\n\n",capaStudent.name,capaStudent.section);
        !           555:       break;
        !           556:     case 0:
        !           557:       printf("PID: The Scantron reported:%s\n",student->answerPID);
        !           558:       return ESTID;
        !           559:       break;
        !           560:     case -1:
        !           561:       return ECLASSL;
        !           562:       break;
        !           563:     default:
        !           564:       fprintf(stderr,"capa_get_student returned an invalid result ");
        !           565:       fprintf(stderr,"in CheckForm.\n");
        !           566:       break;
        !           567:     }
        !           568:   
        !           569:   if (CheckPIN && !Anon)
        !           570:     {
        !           571:       pin=capa_PIN(student->answerPID,atoi(student->SetId),0);
        !           572:       if (pin!=atoi(student->PIN))
        !           573: 	{
        !           574: 	  printf("PIN: The Scantron reported:%s, The Classl file has:%d\n",
        !           575: 		 student->PIN,pin);
        !           576: 	  return EPIN;
        !           577: 	}
        !           578:     }
        !           579:   return 0;
        !           580: }
        !           581: 
        !           582: long getBubblerEntry(FILE ** outputFile,char *PID)
        !           583: {
        !           584:   char oneline[512],fmtbuf[16],a_sn[32];
        !           585:   int done=0,found=0,offset=0,len=0,next_r=0;
        !           586: 
        !           587:   rewind(*outputFile);
        !           588:   sprintf(fmtbuf,"%%%dc",MAX_STUDENT_NUMBER);
        !           589:   while(!done)
        !           590:     {
        !           591:       done=!fgets(oneline,511,*outputFile);
        !           592:       len=strlen(oneline);
        !           593:       if (!done)
        !           594: 	{
        !           595: 	  sscanf(oneline,fmtbuf,a_sn);
        !           596: 	  if (!strncasecmp(a_sn,PID,MAX_STUDENT_NUMBER))
        !           597: 	    {
        !           598: 	      next_r=ftell(*outputFile);
        !           599: 	      offset = next_r-len;
        !           600: 	      done=1;
        !           601: 	      found=1;
        !           602: 	    }
        !           603: 	  else
        !           604: 	    {
        !           605: 	    }
        !           606: 	}
        !           607:       else
        !           608: 	{
        !           609: 	  fseek(*outputFile,0L,SEEK_END);
        !           610: 	  offset=ftell(*outputFile);
        !           611: 	  fseek(*outputFile,-1L,SEEK_END);
        !           612: 	  while (fgetc(*outputFile)=='\n')
        !           613: 	    {
        !           614: 	      offset--;
        !           615: 	      fseek(*outputFile,offset,SEEK_SET);
        !           616: 	    }
        !           617: 	  offset= offset+2;
        !           618: 	  found=0;
        !           619: 	  done=1;
        !           620: 	}
        !           621:     }
        !           622:   if(!found)
        !           623:     {
        !           624:       offset=-offset;
        !           625:     }
        !           626:   return offset;
        !           627: }
        !           628: 	  
        !           629: 
        !           630: void setBubblerEntry(FILE ** outputFile,char* answerPID,char* name,
        !           631: 		     char* answers,int score, int section, 
        !           632: 		     char* answerstring,char* questionPID, int offset)
        !           633: {
        !           634:   int len=0;
        !           635:   char buf[1024];
        !           636:   
        !           637:   rewind(*outputFile);
        !           638:   sprintf(buf,"%s %s %s %3d %2d %s %s\n",answerPID,name,answers,score,section,
        !           639: 	  answerstring,questionPID);
        !           640:   len=strlen(buf);
        !           641:   fseek(*outputFile,abs(offset),0);
        !           642:   if(!fwrite(buf,len,1,*outputFile))
        !           643:     {
        !           644:       fprintf(stderr,"Failed write.\n");
        !           645:     }
        !           646: }
        !           647:      
        !           648: 
        !           649: /* Checks if answers are right and gives a point for each right.*/
        !           650: void writeForm(Student * student,FILE ** outputFile,
        !           651: 	       Question questions[MAXQUEST],int numQuestions)
        !           652: {
        !           653:   int result,capaQuestions,questionIndex,leafs,numRight,error,total=0;
        !           654:   int offset2;
        !           655:   char one=1,zero=0;
        !           656:   char *ansOn[20],*stuOn[20];
        !           657:   Problem_t *problems,*oldproblem;
        !           658:   char answerstring[1024],grade[1024];
        !           659:   student_t capaStudent;
        !           660: 
        !           661:   if (!SurveyMode)
        !           662:     {
        !           663:       error=capa_get_student_info(student->answerPID, &capaStudent);
        !           664:       result=capa_parse(atoi(student->SetId),&problems,student->questionPID,
        !           665: 			&capaQuestions);
        !           666:       oldproblem=problems;
        !           667:       if (result==0)
        !           668: 	{
        !           669: 	  fprintf(stderr,"Parse failed: %d\n",result);
        !           670: 	  return;
        !           671: 	}
        !           672:     }
        !           673:   else
        !           674:     {
        !           675:       strcpy(capaStudent.name,"Unknown                       ");
        !           676:       capaStudent.section=0;
        !           677:       oldproblem=problems=NULL;      
        !           678:     }
        !           679:   offset2=getBubblerEntry(outputFile,student->answerPID);
        !           680:   for(questionIndex=0;questionIndex<numQuestions;questionIndex++)
        !           681:     {
        !           682:       switch(questions[questionIndex].type)
        !           683: 	{
        !           684: 	case 'a':
        !           685: 	case 'b':
        !           686: 	case 'c':
        !           687: 	case 'f':
        !           688: 	  numRight=0;
        !           689: 	  printf("%s %s\n",problems->answer,student->Answers[questionIndex]);
        !           690: 	  for(leafs=0;problems->answer[leafs]!='\0';leafs++)
        !           691: 	    {
        !           692: 	      if (problems->answer[leafs]==
        !           693: 		  student->Answers[questionIndex][leafs])
        !           694: 		{
        !           695: 		  numRight++;
        !           696: 		}
        !           697: 	    }
        !           698: 	  total+=numRight;
        !           699: 	  grade[questionIndex]='0'+(char)numRight;
        !           700: 	  break;
        !           701: 	case 'd':
        !           702: 	  printf("%s\n",student->Answers[questionIndex]);
        !           703: 	  grade[questionIndex]=student->Answers[questionIndex][0];
        !           704: 	  if (isspace(student->Answers[questionIndex][0]))
        !           705: 	    total+=0;
        !           706: 	  else
        !           707: 	    total+=(int)(student->Answers[questionIndex][0]-'0');
        !           708: 	  break;
        !           709: 	case 'e':
        !           710: 	  printf("%s %s\n",problems->answer,student->Answers[questionIndex]);
        !           711: 	  numRight=0;
        !           712: 	  for(leafs=0;questions[questionIndex].leafs>leafs;leafs++)
        !           713: 	    {
        !           714: 	      ansOn[leafs]=strchr(problems->answer,('A'+(char)leafs));
        !           715: 	    }
        !           716: 	  for(leafs=0;questions[questionIndex].leafs>leafs;leafs++)
        !           717: 	    {
        !           718: 	      if (ansOn[leafs] != NULL ) { ansOn[leafs]=&one;} 
        !           719: 	      else { ansOn[leafs]=&zero;}
        !           720: 	    }
        !           721: 	  for(leafs=0;questions[questionIndex].leafs>leafs;leafs++)
        !           722: 	    {
        !           723: 	      stuOn[leafs]=strchr(student->Answers[questionIndex],
        !           724: 				  ('A'+(char)leafs));
        !           725: 	    }
        !           726: 	  for(leafs=0;questions[questionIndex].leafs>leafs;leafs++)
        !           727: 	    {
        !           728: 	      if (stuOn[leafs] != NULL) {stuOn[leafs]=&one;} 
        !           729: 	      else {stuOn[leafs]=&zero;}
        !           730: 	    }
        !           731: 	  for(leafs=0;questions[questionIndex].leafs>leafs;leafs++)
        !           732: 	    {
        !           733: 	      if (ansOn[leafs] == stuOn[leafs]) numRight++;
        !           734: 	    }
        !           735: 	  fprintf(stderr,"%d\n",numRight);
        !           736: 	  total+=numRight;
        !           737: 	  grade[questionIndex]='0'+(char)numRight;
        !           738: 	  break;
        !           739: 	case 'g':
        !           740: 	  printf("%s %s\n",problems->answer,student->Answers[questionIndex]);
        !           741: 	  if (!(strcasecmp(problems->answer,student->Answers[questionIndex])))
        !           742: 	    {
        !           743: 	      total+=questions[questionIndex].points;
        !           744: 	      grade[questionIndex]='0'+questions[questionIndex].points;
        !           745: 	    }
        !           746: 	  else
        !           747: 	    {
        !           748: 	      grade[questionIndex]='0';
        !           749: 	    }
        !           750: 	  break;
        !           751: 	default:
        !           752: 	  printf("No points since don't know question type.\n");
        !           753: 	  break;
        !           754: 	}
        !           755:       if (!SurveyMode) problems=problems->next;
        !           756:     }
        !           757: 
        !           758:   answerstring[0]='\0';
        !           759: 
        !           760:   for(questionIndex=0;questionIndex<numQuestions;questionIndex++)
        !           761:     {
        !           762:       strcat(answerstring,student->Answers[questionIndex]);
        !           763:     }
        !           764:      
        !           765:   setBubblerEntry(outputFile,student->answerPID,capaStudent.name,grade,
        !           766: 		  total,capaStudent.section,answerstring,student->questionPID,
        !           767: 		  offset2);
        !           768: 
        !           769:   if (!SurveyMode)
        !           770:     {
        !           771:       problems=oldproblem;
        !           772:       for(questionIndex=0;problems!=NULL;questionIndex++)
        !           773: 	{
        !           774: 	  oldproblem=problems;
        !           775: 	  problems=problems->next;
        !           776: 	  free(oldproblem);
        !           777: 	}
        !           778: #ifdef DEBUG
        !           779:       fprintf(stderr,"Freed: %d\n",questionIndex);
        !           780: #endif /*DEBUG*/
        !           781:     }
        !           782: }
        !           783: 
        !           784: void processForms(FILE ** serport,int numQuestions,
        !           785: 		  Question questions[MAXQUEST],char* class,int setId)
        !           786: {
        !           787: 
        !           788:   int done=0,error,i,numOfStudents=0;
        !           789:   int status;
        !           790:   char buf[128],filename[128];
        !           791:   Student * student;
        !           792:   FILE * outputFile;
        !           793:   PIDPINlist PIDandPINlist[MAX_SECTION_SIZE];
        !           794: 
        !           795:   sprintf(filename,"bubbler.output.%d",setId);
        !           796:   outputFile=fopen(filename,"r+");
        !           797:   if (outputFile != NULL)
        !           798:     {
        !           799:       rewind(outputFile);
        !           800:       fscanf(outputFile,"%s",buf);
        !           801:     }
        !           802:   if (outputFile==NULL || buf[0]=='\0')
        !           803:     {
        !           804:       outputFile=fopen(filename,"w+");
        !           805:       fprintf(outputFile,"%s %d ",class,setId);
        !           806:       for(i=0;i<numQuestions;i++)
        !           807: 	{
        !           808: 	  fprintf(outputFile,"%c%d",questions[i].type,questions[i].points);
        !           809: 	}
        !           810:       fprintf(outputFile,"\n");
        !           811:     }
        !           812:   if (Anon)
        !           813:     {
        !           814:       numOfStudents=buildPIDandPINlist(setId,PIDandPINlist);
        !           815:       if (numOfStudents==0)
        !           816: 	{
        !           817: 	  fprintf(stderr,"buildPIDandPINlists returned 0 students.");
        !           818: 	  exit(-2);
        !           819: 	}
        !           820:     }
        !           821:   
        !           822:   while(!done)
        !           823:     {
        !           824:       student=getForm(&status,serport,questions);
        !           825:       switch (status)
        !           826: 	{
        !           827: 	case GFSPACES:
        !           828: 	  if (CheckSpaces)
        !           829: 	    {
        !           830: 	      printf("The current form appears to have some questions left\n");
        !           831: 	      printf("blank. Please enter yes if you wish to continue \n");
        !           832: 	      printf("grading of this form.\n");
        !           833: 	      scanf("%s",buf);
        !           834: 	      if (buf[0]=='y' || buf[0]=='Y') ;
        !           835: 	      else break;
        !           836: 	    }
        !           837: 	case GFSUCCESS:
        !           838: 	  if ((!SurveyMode) && 
        !           839: 	      (error=checkForm(student,numQuestions,class,setId))) 
        !           840: 	    {
        !           841: 	      switch(error)
        !           842: 		{
        !           843: 		case ECLASS:
        !           844: 		  printf("The current form has a class string that is \n");
        !           845: 		  printf("different from the one entered at the start.\n");
        !           846: 		  printf("Please place that form to the side and type ");
        !           847: 		  printf("start to continue.\n");
        !           848: 		  scanf("%s",buf);
        !           849: 		  break;
        !           850: 		case ESTID:
        !           851: 		  printf("The current form's Student Id is incorrect.\n");
        !           852: 		  printf("Please set the form aside and type start to ");
        !           853: 		  printf("continue.\n");
        !           854: 		  scanf("%s",buf);
        !           855: 		  break;
        !           856: 		case ECLASSL:
        !           857: 		  fprintf(stderr,"The classl file was not found in the");
        !           858: 		  fprintf(stderr," current directory.\n");
        !           859: 		  fprintf(stderr,"Please try again.\n");
        !           860: 		  done=1;
        !           861: 		  break;
        !           862: 		case EPIN:
        !           863: 		  fprintf(stderr,"The current form's PIN is incorrect.\n");
        !           864: 		  fprintf(stderr,"Please set the form aside and type ");
        !           865: 		  fprintf(stderr,"start to continue.\n");
        !           866: 		  scanf("%s",buf);
        !           867: 		  break;
        !           868: 		default:
        !           869: 		  fprintf(stderr,"Unimplemented error in checkForm %d\n",
        !           870: 			  error);
        !           871: 		  break;
        !           872: 		}
        !           873: 	    }
        !           874: 	  else
        !           875: 	    {
        !           876: 	      if (Anon)
        !           877: 		{
        !           878: 		  error=findPID(student,PIDandPINlist,numOfStudents);
        !           879: 		}
        !           880: 	      else
        !           881: 		{
        !           882: 		  error=ENONE;
        !           883: 		  strcpy(student->questionPID,student->answerPID);
        !           884: 		}
        !           885: 	      switch(error)
        !           886: 		{
        !           887: 		case ENONE:
        !           888: 		  writeForm(student,&outputFile,questions,numQuestions);
        !           889: 		  break;
        !           890: 		case ENOONE:
        !           891: 		  break;
        !           892: 		default:
        !           893: 		  fprintf(stderr,"Unimplemented error in findPID %d\n",
        !           894: 			  error);
        !           895: 		  break;
        !           896: 		}
        !           897: 	    }
        !           898: 	  break;
        !           899: 	case GFFAILED:
        !           900: 	  printf("The Scantron has returned an error.\n");
        !           901: 	  printf("Are there still more forms to process?");
        !           902: 	  scanf("%s",buf);
        !           903: 	  if (buf[0]=='n')
        !           904: 	    {
        !           905: 	      done=1;
        !           906: 	    }
        !           907: 	  else
        !           908: 	    {
        !           909: 	      printf("Please put that last read form to the side.\n");
        !           910: 	      printf("Enter start to continue\n");
        !           911: 	      scanf("%s",buf);
        !           912: 	    }
        !           913: 	  break;
        !           914: 	case GFEOF:
        !           915: 	  done=1;
        !           916: 	  break;
        !           917: 	default:
        !           918: 	  printf("Unimplened return code in GetForm %d\n",status);
        !           919: 	  break;
        !           920: 	}
        !           921:       if (student != NULL)
        !           922: 	{
        !           923: 	  free(student);
        !           924: 	}
        !           925:     }
        !           926: }
        !           927: 
        !           928: void CloseScantron(FILE ** serport)
        !           929: {
        !           930:   fprintf(*serport,".srst\r");
        !           931:   fclose(*serport);
        !           932: }
        !           933: 
        !           934: int main(int argc, char *argv[])
        !           935: {
        !           936:   FILE * serport;
        !           937:   Question questions[MAXQUEST];
        !           938:   char class[10];
        !           939:   int numQuestions,setId;
        !           940: 
        !           941:   printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
        !           942:   printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
        !           943:   printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
        !           944:   printf("Welcome to Bubbler, the Automated CAPA grader.\n");
        !           945:   printf("Version 0.05.02\n\n\n");
        !           946:   numQuestions=GetProblems(questions,class,&setId);
        !           947:   SetupScantron(&serport,numQuestions,questions);
        !           948:   processForms(&serport,numQuestions,questions,class,setId);
        !           949:   CloseScantron(&serport);
        !           950:   return 0;
        !           951: }
        !           952: 

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