Back to index

wims  3.65+svn20090927
exam.c
Go to the documentation of this file.
00001 /*    Copyright (C) 1998-2003 XIAO, Gang of Universite de Nice - Sophia Antipolis
00002  *
00003  *  This program is free software; you can redistribute it and/or modify
00004  *  it under the terms of the GNU General Public License as published by
00005  *  the Free Software Foundation; either version 2 of the License, or
00006  *  (at your option) any later version.
00007  *
00008  *  This program is distributed in the hope that it will be useful,
00009  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00010  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011  *  GNU General Public License for more details.
00012  *
00013  *  You should have received a copy of the GNU General Public License
00014  *  along with this program; if not, write to the Free Software
00015  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00016  */
00017 
00018 #include <utime.h>
00019 
00020        /* Subroutines to process examinations */
00021 
00022 char eparm[MAX_LINELEN+1];
00023 
00024 void exam_parm(void)
00025 {
00026     char *p1, *p2, *p3;
00027     int v;
00028     setvar("module_init_parm",eparm);
00029     for(v=0,p1=eparm; *p1; p1=p2) {
00030        while(*p1=='&') p1++;
00031        p2=strchr(p1,'&');
00032        if(p2==NULL) p2=p1+strlen(p1); else *p2++=0;
00033        p3=strchr(p1,'='); if(p3==NULL) continue; else *p3++=0;
00034        p1=find_word_start(p1); *find_word_end(p1)=0;
00035        p3=find_word_start(p3); strip_trailing_spaces(p3);
00036        user_variable[v].name=p1; user_variable[v].value=p3;
00037        v++;
00038     }
00039     user_var_no=v;
00040 }
00041 
00042        /* prepare examination situation */
00043 void check_exam(void)
00044 {
00045     char *p, *p2, *e1, *e2, *pc=NULL;
00046     char ps[64], pb[64], cbuf[64], dbuf[64], vbuf[MAX_FNAME+1];
00047     int t1, t2;
00048     int start, duration, remain;
00049     double prime;
00050     struct stat st;
00051 
00052     p=getvar(ro_name[ro_session]); 
00053     if(p==NULL || (p2=strstr(p,"_exam"))==NULL) return;
00054     mystrncpy(pb,p,sizeof(pb)); p=pb;
00055     p2=strstr(p,"_exam"); if(p2==NULL) return; else *p2=0;
00056 
00057     if(strchr(p2+1,'t')==NULL) {
00058        e1=getvar(ro_name[ro_worksheet]);
00059        if(e1==NULL || *e1==0) {
00060            bad: user_error("bad_exam"); return;
00061        }
00062        e2=strchr(e1,'.'); if(e2==NULL) goto bad;
00063        e2++; t1=atoi(e1); t2=atoi(e2);
00064     }
00065     else {
00066        char *pt1,*pt2;
00067        pt1=strchr(p2+1,'t'); pt2=strchr(pt1+1,'t');
00068        *pt1++=0; *pt2++=0; t1=atoi(pt1); t2=atoi(pt2);
00069     }
00070     if(t1<1 || t1>99 || t2<1 || t2>99) goto bad;
00071     snprintf(ps,sizeof(ps),"%s_examt%dt%d",p,t1,t2);
00072     isexam=1; setsesdir(ps); force_setvar("wims_isexam","1");
00073     force_setvar(ro_name[ro_session],ps);
00074        /* get exam setup data */
00075     accessfile(cbuf,"r","%s/%s/examdata.%d", session_dir,pb,t1);
00076     if(cbuf[0]==0) goto bad;
00077     p=find_word_start(cbuf); p2=find_word_end(p); if(*p2) *p2++=0;
00078     duration=atoi(p)*60; if(duration==0) goto bad;
00079     if(*p2) prime=atof(p2); else prime=0;
00080     if (strstr(ps,parent_dir_string)!=NULL) user_error("wrong_session");
00081        /* Whether the exercise is already done */
00082     p=getvar(ro_name[ro_cmd]); if(p!=NULL) {
00083        if(strcmp(p,"getins")==0 || strcmp(p,"getframe")==0) goto skipped;
00084     }
00085     exam_currscore(t1);
00086     if(exam_scoredata[t2-1]!=-1000) {
00087        snprintf(dbuf,sizeof(dbuf),"%.1f",exam_scoredata[t2-1]);
00088        setvar("wims_exo_lastscore",dbuf);
00089               /* Do we need to erase subsession? */
00090        user_error("exam_exo_finished");
00091     }
00092     skipped:
00093     snprintf(session_prefix,sizeof(session_prefix),"%s/%s",session_dir,ps);
00094     snprintf(vbuf,sizeof(vbuf),"%s/var",session_prefix);
00095     if(stat(vbuf,&st)==0) { /* exists */
00096        unsetvar("module");
00097        p=getvar(ro_name[ro_cmd]);
00098        if(p==NULL) {
00099            recmd:
00100            force_setvar(ro_name[ro_cmd],commands[cmd_resume]);
00101            user_var_no=0;
00102        }
00103        else {
00104            int i;
00105            for(i=0;i<CMD_NO && strcmp(p,commands[i]);i++);
00106            if(i>=CMD_NO || i==cmd_intro || i==cmd_new || i==cmd_renew || i==cmd_hint)
00107              goto recmd;
00108        }
00109     }
00110     else {    /* new */
00111        char *pt, cbuf[MAX_FNAME+1], ebuf[MAX_FNAME+1];
00112        char buf[2][MAX_LINELEN+1];
00113        int w1,w2;
00114        
00115        force_setvar(ro_name[ro_cmd],commands[cmd_new]);
00116        get_static_session_var();
00117        
00118        pc=getvar("wims_class"); if(pc==NULL) pc="";
00119        snprintf(cbuf,sizeof(cbuf),"%s/%s",class_base,pc);
00120        snprintf(ebuf,sizeof(ebuf),"%s/exams/.exam%d",cbuf,t1);
00121        direct_datafile=1;
00122        datafile_fnd_record(ebuf,t2,buf[0]);
00123        direct_datafile=0;
00124        if(buf[0][0]==0) goto bad;
00125        fnd_line(buf[0],4,buf[1]); if(buf[1][0]!=0) { /* dependencies */
00126            if(!exam_depcheck(buf[1],t1)) {
00127               
00128               user_error("exam_dep");
00129            }
00130        }
00131        fnd_line(buf[0],2,buf[1]); if(buf[1][0]==0) goto bad;
00132        calc_randitem(buf[1]);
00133        pt=strchr(buf[1],'.'); if(pt==NULL) {
00134            bad2: module_error("bad_exam_2"); return;
00135        }
00136        snprintf(exam_sheetexo,sizeof(exam_sheetexo),"   %s",buf[1]);
00137        *pt++=0; w1=atoi(buf[1]); w2=atoi(pt);
00138        if(w1<1 || w1>99 || w2<1 || w2>99) goto bad2;
00139        snprintf(ebuf,sizeof(ebuf),"%s/sheets/.sheet%d",cbuf,w1);
00140        direct_datafile=1;
00141        datafile_fnd_record(ebuf,w2,buf[0]);
00142        direct_datafile=0;
00143        if(buf[0][0]==0) goto bad2;
00144        fnd_line(buf[0],1,buf[1]); if(buf[1][0]==0) goto bad2;
00145        force_setvar(ro_name[ro_module],buf[1]);
00146        fnd_line(buf[0],2,eparm); /* if(eparm[0]==0) goto bad2; */
00147        exam_parm();
00148     }
00149               /* Register start time */
00150     snprintf(vbuf,sizeof(vbuf),"%s/%s/examreg.%d",
00151             session_dir,pb,t1);
00152     if(stat(vbuf,&st)==0) { /* reg exists */
00153        char tbuf[MAX_LINELEN+1];
00154        struct utimbuf ut;
00155        accessfile(tbuf,"r",vbuf); start=atoi(tbuf);
00156        if(start<=nowtime-duration) {
00157            user_error("expired_exam"); return;
00158        }
00159        /* refresh session times */
00160        ut.actime=ut.modtime=nowtime;
00161        utime(mkfname(NULL,"%s/%s",session_dir,pb),&ut);
00162     }
00163     else { /* First time call: register starting time */
00164        char *pu, *p1, tbuf[MAX_LINELEN+1];
00165        snprintf(dbuf,sizeof(dbuf),"%u",(unsigned int) nowtime);
00166        accessfile(dbuf,"w","%s",vbuf); start=nowtime;
00167        if(pc==NULL) pc=getvar("wims_class"); if(pc==NULL) pc="";
00168        pu=getvar("wims_user"); if(pu==NULL) pu="";
00169        snprintf(vbuf,sizeof(vbuf),"%s/%s/.parmreg", class_base, pc);
00170        mkdirs(vbuf);
00171        snprintf(vbuf,sizeof(vbuf),"%s/%s/.parmreg/%s.exam",
00172                class_base, pc, pu);
00173        p1=remote_addr;
00174        snprintf(dbuf,sizeof(dbuf),"%s %s %u %d",
00175                p1, pb, (unsigned int) start+duration, t1);
00176        accessfile(dbuf,"w","%s",vbuf);
00177        accessfile(tbuf,"r","%s/%s/.E%d",class_base,pc,t1);
00178        if(strchr(tbuf,'#')==NULL && strcmp(pu,"supervisor")!=0) {  /* not for simulation */
00179            snprintf(tbuf,sizeof(tbuf),"%d 00 %d %u %s %s %s\n",
00180                    t1, duration/60, (unsigned int) start,p1,pb,
00181                    nowstr);
00182            if(prime!=0) {
00183                int n=strlen(tbuf);
00184               snprintf(tbuf+n,sizeof(tbuf)-n,"%d %.2f -1 %u %s %s\n",
00185                       t1,prime,(unsigned int) start,p1,pb);
00186            }
00187            accessfile(tbuf,"a","%s/%s/score/%s.exam",
00188                      class_base,pc,pu);
00189        }
00190        else accessfile("yes","w","%s/%s/examsimu.%d",
00191             session_dir,pb,t1);
00192     }
00193     remain=duration+start-nowtime; if(remain<0) remain=0;
00194     snprintf(dbuf,sizeof(dbuf),"%d",remain);
00195     setvar("wims_exam_remain",dbuf);      /* remaining time in seconds */
00196     if(pc==NULL) pc=getvar("wims_class");
00197     if(pc) getscorestatus(pc,t1);  /* set up wims_scoring */
00198 }
00199 
00200 double currexamscore(int sh)
00201 {
00202     char buf[MAX_FNAME+1], sbuf[MAX_LINELEN+1];
00203     char *p, *p1, *cl;
00204     int i, excnt;
00205     double sc, w, ww, prime;
00206     
00207     cl=getvar("wims_class"); if(cl==NULL || *cl==0) return 0;
00208     mystrncpy(sbuf,session_prefix,sizeof(sbuf));
00209     p=strstr(sbuf,"_exam"); if(p) *p=0;
00210     accessfile(buf,"r","%s/examdata.%d",sbuf,sh);
00211     p=find_word_start(find_word_end(find_word_start(buf)));
00212     if(*p) prime=atof(p); else prime=0;
00213     exam_currscore(sh);
00214     snprintf(buf,sizeof(buf),"%s/%s/exams/.exam%d",class_base,cl,sh);
00215     direct_datafile=1;
00216     excnt=datafile_recordnum(buf);
00217     w=sc=0; for(i=0;i<excnt;i++) {
00218        sbuf[0]=0; datafile_fnd_record(buf,i+1,sbuf);
00219        p1=find_word_start(sbuf); *find_word_end(p1)=0;
00220        ww=atof(p1); if(ww<=0) continue;
00221        w+=ww; if(exam_scoredata[i]>-1000) sc+=exam_scoredata[i]*ww;
00222     }
00223     direct_datafile=0; if(sc<0) sc=0;
00224     if(w==0) return 0; else return (1-prime/10)*sc/w+prime;
00225 }
00226 
00227 void calc_examdep(char *p)
00228 {
00229     char *p1, *p2;
00230     int t;
00231     if(!trusted_module()) {abt: *p=0; return;}
00232     p1=find_word_start(p); p2=find_word_end(p1);
00233     if(*p2==0) goto abt;
00234     *p2++=0; p2=find_word_start(p2);
00235     t=atoi(p1);
00236     if(exam_depcheck(p2,t)) p1="yes";
00237     else p1="no";
00238     snprintf(p,MAX_LINELEN,p1);
00239 }
00240