Rev 3842 | Rev 8185 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
10 | reyssat | 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 | |||
7673 | bpr | 20 | /* Subroutines to process examinations */ |
10 | reyssat | 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) { |
||
7673 | bpr | 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++; |
||
10 | reyssat | 38 | } |
39 | user_var_no=v; |
||
40 | } |
||
41 | |||
7673 | bpr | 42 | /* prepare examination situation */ |
10 | reyssat | 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 | |||
7673 | bpr | 52 | p=getvar(ro_name[ro_session]); |
10 | reyssat | 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) { |
||
7673 | bpr | 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); |
||
10 | reyssat | 64 | } |
65 | else { |
||
7673 | bpr | 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); |
||
10 | reyssat | 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); |
||
7673 | bpr | 74 | /* get exam setup data */ |
10 | reyssat | 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"); |
||
7673 | bpr | 81 | /* Whether the exercise is already done */ |
10 | reyssat | 82 | p=getvar(ro_name[ro_cmd]); if(p!=NULL) { |
7673 | bpr | 83 | if(strcmp(p,"getins")==0 || strcmp(p,"getframe")==0) goto skipped; |
10 | reyssat | 84 | } |
85 | exam_currscore(t1); |
||
86 | if(exam_scoredata[t2-1]!=-1000) { |
||
7673 | bpr | 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"); |
||
10 | reyssat | 91 | } |
92 | skipped: |
||
93 | snprintf(session_prefix,sizeof(session_prefix),"%s/%s",session_dir,ps); |
||
94 | snprintf(vbuf,sizeof(vbuf),"%s/var",session_prefix); |
||
7673 | bpr | 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 | } |
||
10 | reyssat | 109 | } |
7673 | bpr | 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(); |
||
10 | reyssat | 148 | } |
7673 | bpr | 149 | /* Register start time */ |
10 | reyssat | 150 | snprintf(vbuf,sizeof(vbuf),"%s/%s/examreg.%d", |
7673 | bpr | 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); |
||
10 | reyssat | 162 | } |
163 | else { /* First time call: register starting time */ |
||
7673 | bpr | 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); |
||
10 | reyssat | 192 | } |
193 | remain=duration+start-nowtime; if(remain<0) remain=0; |
||
194 | snprintf(dbuf,sizeof(dbuf),"%d",remain); |
||
7673 | bpr | 195 | setvar("wims_exam_remain",dbuf); /* remaining time in seconds */ |
10 | reyssat | 196 | if(pc==NULL) pc=getvar("wims_class"); |
7673 | bpr | 197 | if(pc) getscorestatus(pc,t1); /* set up wims_scoring */ |
10 | reyssat | 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; |
||
7673 | bpr | 206 | |
10 | reyssat | 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++) { |
||
7673 | bpr | 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; |
||
10 | reyssat | 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); |
||
3842 | kbelabas | 236 | snprintf(p,MAX_LINELEN, exam_depcheck(p2,t)? "yes" : "no"); |
10 | reyssat | 237 | } |
238 |