Subversion Repositories wimsdev

Rev

Rev 10 | Rev 8185 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /*    Copyright (C) 1998-2003 XIAO, Gang of Universite de Nice - Sophia Antipolis
  2.  *
  3.  *  This program is free software; you can redistribute it and/or modify
  4.  *  it under the terms of the GNU General Public License as published by
  5.  *  the Free Software Foundation; either version 2 of the License, or
  6.  *  (at your option) any later version.
  7.  *
  8.  *  This program is distributed in the hope that it will be useful,
  9.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.  *  GNU General Public License for more details.
  12.  *
  13.  *  You should have received a copy of the GNU General Public License
  14.  *  along with this program; if not, write to the Free Software
  15.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16.  */
  17.  
  18. #include <utime.h>
  19.  
  20.         /* Subroutines to process examinations */
  21.  
  22. char eparm[MAX_LINELEN+1];
  23.  
  24. void exam_parm(void)
  25. {
  26.     char *p1, *p2, *p3;
  27.     int v;
  28.     setvar("module_init_parm",eparm);
  29.     for(v=0,p1=eparm; *p1; p1=p2) {
  30.         while(*p1=='&') p1++;
  31.         p2=strchr(p1,'&');
  32.         if(p2==NULL) p2=p1+strlen(p1); else *p2++=0;
  33.         p3=strchr(p1,'='); if(p3==NULL) continue; else *p3++=0;
  34.         p1=find_word_start(p1); *find_word_end(p1)=0;
  35.         p3=find_word_start(p3); strip_trailing_spaces(p3);
  36.         user_variable[v].name=p1; user_variable[v].value=p3;
  37.         v++;
  38.     }
  39.     user_var_no=v;
  40. }
  41.  
  42.         /* prepare examination situation */
  43. void check_exam(void)
  44. {
  45.     char *p, *p2, *e1, *e2, *pc=NULL;
  46.     char ps[64], pb[64], cbuf[64], dbuf[64], vbuf[MAX_FNAME+1];
  47.     int t1, t2;
  48.     int start, duration, remain;
  49.     double prime;
  50.     struct stat st;
  51.  
  52.     p=getvar(ro_name[ro_session]);
  53.     if(p==NULL || (p2=strstr(p,"_exam"))==NULL) return;
  54.     mystrncpy(pb,p,sizeof(pb)); p=pb;
  55.     p2=strstr(p,"_exam"); if(p2==NULL) return; else *p2=0;
  56.  
  57.     if(strchr(p2+1,'t')==NULL) {
  58.         e1=getvar(ro_name[ro_worksheet]);
  59.         if(e1==NULL || *e1==0) {
  60.             bad: user_error("bad_exam"); return;
  61.         }
  62.         e2=strchr(e1,'.'); if(e2==NULL) goto bad;
  63.         e2++; t1=atoi(e1); t2=atoi(e2);
  64.     }
  65.     else {
  66.         char *pt1,*pt2;
  67.         pt1=strchr(p2+1,'t'); pt2=strchr(pt1+1,'t');
  68.         *pt1++=0; *pt2++=0; t1=atoi(pt1); t2=atoi(pt2);
  69.     }
  70.     if(t1<1 || t1>99 || t2<1 || t2>99) goto bad;
  71.     snprintf(ps,sizeof(ps),"%s_examt%dt%d",p,t1,t2);
  72.     isexam=1; setsesdir(ps); force_setvar("wims_isexam","1");
  73.     force_setvar(ro_name[ro_session],ps);
  74.         /* get exam setup data */
  75.     accessfile(cbuf,"r","%s/%s/examdata.%d", session_dir,pb,t1);
  76.     if(cbuf[0]==0) goto bad;
  77.     p=find_word_start(cbuf); p2=find_word_end(p); if(*p2) *p2++=0;
  78.     duration=atoi(p)*60; if(duration==0) goto bad;
  79.     if(*p2) prime=atof(p2); else prime=0;
  80.     if (strstr(ps,parent_dir_string)!=NULL) user_error("wrong_session");
  81.         /* Whether the exercise is already done */
  82.     p=getvar(ro_name[ro_cmd]); if(p!=NULL) {
  83.         if(strcmp(p,"getins")==0 || strcmp(p,"getframe")==0) goto skipped;
  84.     }
  85.     exam_currscore(t1);
  86.     if(exam_scoredata[t2-1]!=-1000) {
  87.         snprintf(dbuf,sizeof(dbuf),"%.1f",exam_scoredata[t2-1]);
  88.         setvar("wims_exo_lastscore",dbuf);
  89.                 /* Do we need to erase subsession? */
  90.         user_error("exam_exo_finished");
  91.     }
  92.     skipped:
  93.     snprintf(session_prefix,sizeof(session_prefix),"%s/%s",session_dir,ps);
  94.     snprintf(vbuf,sizeof(vbuf),"%s/var",session_prefix);
  95.     if(stat(vbuf,&st)==0) {     /* exists */
  96.         unsetvar("module");
  97.         p=getvar(ro_name[ro_cmd]);
  98.         if(p==NULL) {
  99.             recmd:
  100.             force_setvar(ro_name[ro_cmd],commands[cmd_resume]);
  101.             user_var_no=0;
  102.         }
  103.         else {
  104.             int i;
  105.             for(i=0;i<CMD_NO && strcmp(p,commands[i]);i++);
  106.             if(i>=CMD_NO || i==cmd_intro || i==cmd_new || i==cmd_renew || i==cmd_hint)
  107.               goto recmd;
  108.         }
  109.     }
  110.     else {      /* new */
  111.         char *pt, cbuf[MAX_FNAME+1], ebuf[MAX_FNAME+1];
  112.         char buf[2][MAX_LINELEN+1];
  113.         int w1,w2;
  114.        
  115.         force_setvar(ro_name[ro_cmd],commands[cmd_new]);
  116.         get_static_session_var();
  117.        
  118.         pc=getvar("wims_class"); if(pc==NULL) pc="";
  119.         snprintf(cbuf,sizeof(cbuf),"%s/%s",class_base,pc);
  120.         snprintf(ebuf,sizeof(ebuf),"%s/exams/.exam%d",cbuf,t1);
  121.         direct_datafile=1;
  122.         datafile_fnd_record(ebuf,t2,buf[0]);
  123.         direct_datafile=0;
  124.         if(buf[0][0]==0) goto bad;
  125.         fnd_line(buf[0],4,buf[1]); if(buf[1][0]!=0) { /* dependencies */
  126.             if(!exam_depcheck(buf[1],t1)) {
  127.                
  128.                 user_error("exam_dep");
  129.             }
  130.         }
  131.         fnd_line(buf[0],2,buf[1]); if(buf[1][0]==0) goto bad;
  132.         calc_randitem(buf[1]);
  133.         pt=strchr(buf[1],'.'); if(pt==NULL) {
  134.             bad2: module_error("bad_exam_2"); return;
  135.         }
  136.         snprintf(exam_sheetexo,sizeof(exam_sheetexo),"  %s",buf[1]);
  137.         *pt++=0; w1=atoi(buf[1]); w2=atoi(pt);
  138.         if(w1<1 || w1>99 || w2<1 || w2>99) goto bad2;
  139.         snprintf(ebuf,sizeof(ebuf),"%s/sheets/.sheet%d",cbuf,w1);
  140.         direct_datafile=1;
  141.         datafile_fnd_record(ebuf,w2,buf[0]);
  142.         direct_datafile=0;
  143.         if(buf[0][0]==0) goto bad2;
  144.         fnd_line(buf[0],1,buf[1]); if(buf[1][0]==0) goto bad2;
  145.         force_setvar(ro_name[ro_module],buf[1]);
  146.         fnd_line(buf[0],2,eparm); /* if(eparm[0]==0) goto bad2; */
  147.         exam_parm();
  148.     }
  149.                 /* Register start time */
  150.     snprintf(vbuf,sizeof(vbuf),"%s/%s/examreg.%d",
  151.              session_dir,pb,t1);
  152.     if(stat(vbuf,&st)==0) {     /* reg exists */
  153.         char tbuf[MAX_LINELEN+1];
  154.         struct utimbuf ut;
  155.         accessfile(tbuf,"r",vbuf); start=atoi(tbuf);
  156.         if(start<=nowtime-duration) {
  157.             user_error("expired_exam"); return;
  158.         }
  159.         /* refresh session times */
  160.         ut.actime=ut.modtime=nowtime;
  161.         utime(mkfname(NULL,"%s/%s",session_dir,pb),&ut);
  162.     }
  163.     else { /* First time call: register starting time */
  164.         char *pu, *p1, tbuf[MAX_LINELEN+1];
  165.         snprintf(dbuf,sizeof(dbuf),"%u",(unsigned int) nowtime);
  166.         accessfile(dbuf,"w","%s",vbuf); start=nowtime;
  167.         if(pc==NULL) pc=getvar("wims_class"); if(pc==NULL) pc="";
  168.         pu=getvar("wims_user"); if(pu==NULL) pu="";
  169.         snprintf(vbuf,sizeof(vbuf),"%s/%s/.parmreg", class_base, pc);
  170.         mkdirs(vbuf);
  171.         snprintf(vbuf,sizeof(vbuf),"%s/%s/.parmreg/%s.exam",
  172.                  class_base, pc, pu);
  173.         p1=remote_addr;
  174.         snprintf(dbuf,sizeof(dbuf),"%s %s %u %d",
  175.                  p1, pb, (unsigned int) start+duration, t1);
  176.         accessfile(dbuf,"w","%s",vbuf);
  177.         accessfile(tbuf,"r","%s/%s/.E%d",class_base,pc,t1);
  178.         if(strchr(tbuf,'#')==NULL && strcmp(pu,"supervisor")!=0) {  /* not for simulation */
  179.             snprintf(tbuf,sizeof(tbuf),"%d 00 %d %u %s %s %s\n",
  180.                      t1, duration/60, (unsigned int) start,p1,pb,
  181.                      nowstr);
  182.             if(prime!=0) {
  183.                 int n=strlen(tbuf);
  184.                 snprintf(tbuf+n,sizeof(tbuf)-n,"%d %.2f -1 %u %s %s\n",
  185.                          t1,prime,(unsigned int) start,p1,pb);
  186.             }
  187.             accessfile(tbuf,"a","%s/%s/score/%s.exam",
  188.                        class_base,pc,pu);
  189.         }
  190.         else accessfile("yes","w","%s/%s/examsimu.%d",
  191.              session_dir,pb,t1);
  192.     }
  193.     remain=duration+start-nowtime; if(remain<0) remain=0;
  194.     snprintf(dbuf,sizeof(dbuf),"%d",remain);
  195.     setvar("wims_exam_remain",dbuf);    /* remaining time in seconds */
  196.     if(pc==NULL) pc=getvar("wims_class");
  197.     if(pc) getscorestatus(pc,t1);       /* set up wims_scoring */
  198. }
  199.  
  200. double currexamscore(int sh)
  201. {
  202.     char buf[MAX_FNAME+1], sbuf[MAX_LINELEN+1];
  203.     char *p, *p1, *cl;
  204.     int i, excnt;
  205.     double sc, w, ww, prime;
  206.    
  207.     cl=getvar("wims_class"); if(cl==NULL || *cl==0) return 0;
  208.     mystrncpy(sbuf,session_prefix,sizeof(sbuf));
  209.     p=strstr(sbuf,"_exam"); if(p) *p=0;
  210.     accessfile(buf,"r","%s/examdata.%d",sbuf,sh);
  211.     p=find_word_start(find_word_end(find_word_start(buf)));
  212.     if(*p) prime=atof(p); else prime=0;
  213.     exam_currscore(sh);
  214.     snprintf(buf,sizeof(buf),"%s/%s/exams/.exam%d",class_base,cl,sh);
  215.     direct_datafile=1;
  216.     excnt=datafile_recordnum(buf);
  217.     w=sc=0; for(i=0;i<excnt;i++) {
  218.         sbuf[0]=0; datafile_fnd_record(buf,i+1,sbuf);
  219.         p1=find_word_start(sbuf); *find_word_end(p1)=0;
  220.         ww=atof(p1); if(ww<=0) continue;
  221.         w+=ww; if(exam_scoredata[i]>-1000) sc+=exam_scoredata[i]*ww;
  222.     }
  223.     direct_datafile=0; if(sc<0) sc=0;
  224.     if(w==0) return 0; else return (1-prime/10)*sc/w+prime;
  225. }
  226.  
  227. void calc_examdep(char *p)
  228. {
  229.     char *p1, *p2;
  230.     int t;
  231.     if(!trusted_module()) {abt: *p=0; return;}
  232.     p1=find_word_start(p); p2=find_word_end(p1);
  233.     if(*p2==0) goto abt;
  234.     *p2++=0; p2=find_word_start(p2);
  235.     t=atoi(p1);
  236.     snprintf(p,MAX_LINELEN, exam_depcheck(p2,t)? "yes" : "no");
  237. }
  238.  
  239.