Rev 11125 | Rev 12287 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 11125 | Rev 12245 | ||
---|---|---|---|
Line 22... | Line 22... | ||
22 | 22 | ||
23 | char eparm[MAX_LINELEN+1]; |
23 | char eparm[MAX_LINELEN+1]; |
24 | 24 | ||
25 | void exam_parm(void) |
25 | void exam_parm(void) |
26 | { |
26 | { |
27 |
|
27 | char *p1, *p2, *p3; |
28 |
|
28 | int v; |
29 |
|
29 | setvar("module_init_parm",eparm); |
30 |
|
30 | for(v=0,p1=eparm; *p1; p1=p2) { |
31 |
|
31 | while(*p1=='&') p1++; |
32 |
|
32 | p2=strchr(p1,'&'); |
33 |
|
33 | if(p2==NULL) p2=p1+strlen(p1); else *p2++=0; |
34 |
|
34 | p3=strchr(p1,'='); if(p3==NULL) continue; else *p3++=0; |
35 |
|
35 | p1=find_word_start(p1); *find_word_end(p1)=0; |
36 |
|
36 | p3=find_word_start(p3); strip_trailing_spaces(p3); |
37 |
|
37 | user_variable[v].name=p1; user_variable[v].value=p3; |
38 |
|
38 | v++; |
39 |
|
39 | } |
40 |
|
40 | user_var_no=v; |
41 | } |
41 | } |
42 | 42 | ||
43 | /* prepare examination situation */ |
43 | /* prepare examination situation */ |
44 | void check_exam(void) |
44 | void check_exam(void) |
45 | { |
45 | { |
46 |
|
46 | char *p, *p2, *e1, *e2, *pc=NULL; |
47 |
|
47 | char ps[64], pb[64], cbuf[64], dbuf[64], vbuf[MAX_FNAME+1]; |
48 |
|
48 | int t1, t2; |
49 |
|
49 | int start, duration, remain; |
50 |
|
50 | double prime; |
51 |
|
51 | struct stat st; |
- | 52 | ||
- | 53 | p=getvar(ro_name[ro_session]); |
|
- | 54 | if(p==NULL || (p2=strstr(p,"_exam"))==NULL) return; |
|
- | 55 | mystrncpy(pb,p,sizeof(pb)); p=pb; |
|
- | 56 | p2=strstr(p,"_exam"); if(p2==NULL) return; else *p2=0; |
|
52 | 57 | ||
53 | p=getvar(ro_name[ro_session]); |
- | |
54 | if(p==NULL || (p2=strstr(p,"_exam"))==NULL) return; |
- | |
55 | mystrncpy(pb,p,sizeof(pb)); p=pb; |
- | |
56 | p2=strstr(p,"_exam"); if(p2==NULL) return; else *p2=0; |
- | |
57 | - | ||
58 |
|
58 | if(strchr(p2+1,'t')==NULL) { |
59 |
|
59 | e1=getvar(ro_name[ro_worksheet]); |
60 |
|
60 | if(e1==NULL || *e1==0) { |
61 |
|
61 | bad: user_error("bad_exam"); return; |
62 | } |
- | |
63 | e2=strchr(e1,'.'); if(e2==NULL) goto bad; |
- | |
64 | e2++; t1=atoi(e1); t2=atoi(e2); |
- | |
65 | } |
- | |
66 | else { |
- | |
67 | char *pt1,*pt2; |
- | |
68 | pt1=strchr(p2+1,'t'); pt2=strchr(pt1+1,'t'); |
- | |
69 | *pt1++=0; *pt2++=0; t1=atoi(pt1); t2=atoi(pt2); |
- | |
70 | } |
62 | } |
- | 63 | e2=strchr(e1,'.'); if(e2==NULL) goto bad; |
|
- | 64 | e2++; t1=atoi(e1); t2=atoi(e2); |
|
- | 65 | } |
|
- | 66 | else { |
|
- | 67 | char *pt1,*pt2; |
|
- | 68 | pt1=strchr(p2+1,'t'); pt2=strchr(pt1+1,'t'); |
|
- | 69 | *pt1++=0; *pt2++=0; t1=atoi(pt1); t2=atoi(pt2); |
|
- | 70 | } |
|
71 |
|
71 | if(t1<1 || t1>99 || t2<1 || t2>99) goto bad; |
72 |
|
72 | snprintf(ps,sizeof(ps),"%s_examt%dt%d",p,t1,t2); |
73 |
|
73 | isexam=1; setsesdir(ps); force_setvar("wims_isexam","1"); |
74 |
|
74 | force_setvar(ro_name[ro_session],ps); |
75 | /* get exam setup data */ |
75 | /* get exam setup data */ |
76 |
|
76 | accessfile(cbuf,"r","%s/%s/examdata.%d", session_dir,pb,t1); |
77 |
|
77 | if(cbuf[0]==0) goto bad; |
78 |
|
78 | p=find_word_start(cbuf); p2=find_word_end(p); if(*p2) *p2++=0; |
79 |
|
79 | duration=atoi(p)*60; if(duration==0) goto bad; |
80 |
|
80 | if(*p2) prime=atof(p2); else prime=0; |
81 |
|
81 | if (strstr(ps,parent_dir_string)!=NULL) user_error("wrong_session"); |
82 | /* Whether the exercise is already done */ |
82 | /* Whether the exercise is already done */ |
83 |
|
83 | p=getvar(ro_name[ro_cmd]); if(p!=NULL) { |
84 |
|
84 | if(strcmp(p,"getins")==0 || strcmp(p,"getframe")==0) goto skipped; |
85 |
|
85 | } |
86 |
|
86 | exam_currscore(t1); |
87 |
|
87 | if(exam_scoredata[t2-1]!=-1000) { |
88 |
|
88 | snprintf(dbuf,sizeof(dbuf),"%.1f",exam_scoredata[t2-1]); |
89 |
|
89 | setvar("wims_exo_lastscore",dbuf); |
90 | /* Do we need to erase subsession? */ |
90 | /* Do we need to erase subsession? */ |
91 |
|
91 | user_error("exam_exo_finished"); |
92 |
|
92 | } |
93 |
|
93 | skipped: |
94 |
|
94 | snprintf(session_prefix,sizeof(session_prefix),"%s/%s",session_dir,ps); |
95 |
|
95 | snprintf(vbuf,sizeof(vbuf),"%s/var",session_prefix); |
96 |
|
96 | if(stat(vbuf,&st)==0) { /* exists */ |
97 |
|
97 | unsetvar("module"); |
98 |
|
98 | p=getvar(ro_name[ro_cmd]); |
99 |
|
99 | if(p==NULL) { |
100 |
|
100 | recmd: |
101 |
|
101 | force_setvar(ro_name[ro_cmd],commands[cmd_resume]); |
102 |
|
102 | user_var_no=0; |
103 |
|
103 | } |
104 |
|
104 | else { |
105 |
|
105 | int i; |
106 |
|
106 | for(i=0;i<CMD_NO && strcmp(p,commands[i]);i++); |
107 |
|
107 | if(i>=CMD_NO || i==cmd_intro || i==cmd_new || i==cmd_renew || i==cmd_hint) |
108 |
|
108 | goto recmd; |
109 |
|
109 | } |
110 |
|
110 | } |
111 |
|
111 | else { /* new */ |
112 |
|
112 | char *pt, cbuf[MAX_FNAME+1], ebuf[MAX_FNAME+1]; |
113 |
|
113 | char buf[2][MAX_LINELEN+1]; |
114 |
|
114 | int w1,w2; |
115 | 115 | ||
116 |
|
116 | force_setvar(ro_name[ro_cmd],commands[cmd_new]); |
117 |
|
117 | get_static_session_var(); |
118 | 118 | ||
119 |
|
119 | pc=getvar("wims_class"); if(pc==NULL) pc=""; |
120 |
|
120 | snprintf(cbuf,sizeof(cbuf),"%s/%s",class_base,pc); |
121 |
|
121 | snprintf(ebuf,sizeof(ebuf),"%s/exams/.exam%d",cbuf,t1); |
122 |
|
122 | direct_datafile=1; |
123 |
|
123 | datafile_fnd_record(ebuf,t2,buf[0]); |
124 |
|
124 | direct_datafile=0; |
125 |
|
125 | if(buf[0][0]==0) goto bad; |
- | 126 | fnd_line(buf[0],4,buf[1]); |
|
126 |
|
127 | if(buf[1][0]!=0) { /* dependencies */ |
127 |
|
128 | if(!exam_depcheck(buf[1],t1)) { |
128 | 129 | ||
129 |
|
130 | user_error("exam_dep"); |
130 | } |
- | |
131 | } |
- | |
132 | fnd_line(buf[0],2,buf[1]); if(buf[1][0]==0) goto bad; |
- | |
133 | calc_randitem(buf[1]); |
- | |
134 | pt=strchr(buf[1],'.'); if(pt==NULL) { |
- | |
135 | bad2: module_error("bad_exam_2"); return; |
- | |
136 | } |
131 | } |
137 | snprintf(exam_sheetexo,sizeof(exam_sheetexo)," %s",buf[1]); |
- | |
138 | *pt++=0; w1=atoi(buf[1]); w2=atoi(pt); |
- | |
139 | if(w1<1 || w1>99 || w2<1 || w2>99) goto bad2; |
- | |
140 | snprintf(ebuf,sizeof(ebuf),"%s/sheets/.sheet%d",cbuf,w1); |
- | |
141 | direct_datafile=1; |
- | |
142 | datafile_fnd_record(ebuf,w2,buf[0]); |
- | |
143 | direct_datafile=0; |
- | |
144 | if(buf[0][0]==0) goto bad2; |
- | |
145 | fnd_line(buf[0],1,buf[1]); if(buf[1][0]==0) goto bad2; |
- | |
146 | force_setvar(ro_name[ro_module],buf[1]); |
- | |
147 | fnd_line(buf[0],2,eparm); /* if(eparm[0]==0) goto bad2; */ |
- | |
148 | exam_parm(); |
- | |
149 | } |
132 | } |
- | 133 | fnd_line(buf[0],2,buf[1]); if(buf[1][0]==0) goto bad; |
|
- | 134 | calc_randitem(buf[1]); |
|
- | 135 | pt=strchr(buf[1],'.'); |
|
- | 136 | if(pt==NULL) { |
|
- | 137 | bad2: module_error("bad_exam_2"); return; |
|
- | 138 | } |
|
- | 139 | snprintf(exam_sheetexo,sizeof(exam_sheetexo)," %s",buf[1]); |
|
- | 140 | *pt++=0; w1=atoi(buf[1]); w2=atoi(pt); |
|
- | 141 | if(w1<1 || w1>99 || w2<1 || w2>99) goto bad2; |
|
- | 142 | snprintf(ebuf,sizeof(ebuf),"%s/sheets/.sheet%d",cbuf,w1); |
|
- | 143 | direct_datafile=1; |
|
- | 144 | datafile_fnd_record(ebuf,w2,buf[0]); |
|
- | 145 | direct_datafile=0; |
|
- | 146 | if(buf[0][0]==0) goto bad2; |
|
- | 147 | fnd_line(buf[0],1,buf[1]); if(buf[1][0]==0) goto bad2; |
|
- | 148 | force_setvar(ro_name[ro_module],buf[1]); |
|
- | 149 | fnd_line(buf[0],2,eparm); /* if(eparm[0]==0) goto bad2; */ |
|
- | 150 | exam_parm(); |
|
- | 151 | } |
|
150 | /* Register start time */ |
152 | /* Register start time */ |
151 |
|
153 | snprintf(vbuf,sizeof(vbuf),"%s/%s/examreg.%d", |
152 |
|
154 | session_dir,pb,t1); |
153 |
|
155 | if(stat(vbuf,&st)==0) { /* reg exists */ |
154 |
|
156 | char tbuf[MAX_LINELEN+1]; |
155 |
|
157 | struct utimbuf ut; |
156 |
|
158 | accessfile(tbuf,"r",vbuf); start=atoi(tbuf); |
157 |
|
159 | if(start<=nowtime-duration) { |
158 |
|
160 | user_error("expired_exam"); return; |
159 |
|
161 | } |
160 | /* refresh session times */ |
162 | /* refresh session times */ |
161 | ut.actime=ut.modtime=nowtime; |
163 | ut.actime=ut.modtime=nowtime; |
162 | utime(mkfname(NULL,"%s/%s",session_dir,pb),&ut); |
164 | utime(mkfname(NULL,"%s/%s",session_dir,pb),&ut); |
163 |
|
165 | } |
164 |
|
166 | else { /* First time call: register starting time */ |
165 |
|
167 | char *pu, *p1, tbuf[MAX_LINELEN+1]; |
166 |
|
168 | snprintf(dbuf,sizeof(dbuf),"%u",(unsigned int) nowtime); |
167 |
|
169 | accessfile(dbuf,"w","%s",vbuf); start=nowtime; |
168 |
|
170 | if(pc==NULL) pc=getvar("wims_class"); |
169 |
|
171 | if(pc==NULL) pc=""; |
170 |
|
172 | pu=getvar("wims_user"); if(pu==NULL) pu=""; |
171 |
|
173 | snprintf(vbuf,sizeof(vbuf),"%s/%s/.parmreg", class_base, pc); |
172 |
|
174 | mkdirs(vbuf); |
173 |
|
175 | snprintf(vbuf,sizeof(vbuf),"%s/%s/.parmreg/%s.exam", |
174 |
|
176 | class_base, pc, pu); |
175 |
|
177 | p1=remote_addr; |
176 |
|
178 | snprintf(dbuf,sizeof(dbuf),"%s %s %u %d", |
177 |
|
179 | p1, pb, (unsigned int) start+duration, t1); |
178 |
|
180 | accessfile(dbuf,"w","%s",vbuf); |
179 |
|
181 | accessfile(tbuf,"r","%s/%s/.E%d",class_base,pc,t1); |
180 |
|
182 | if(strchr(tbuf,'#')==NULL && strcmp(pu,"supervisor")!=0) { /* not for simulation */ |
181 |
|
183 | snprintf(tbuf,sizeof(tbuf),"%d 00 %d %u %s %s %s\n", |
182 |
|
184 | t1, duration/60, (unsigned int) start,p1,pb, |
183 |
|
185 | nowstr); |
184 |
|
186 | if(prime!=0) { |
185 |
|
187 | int n=strlen(tbuf); |
186 | snprintf(tbuf+n,sizeof(tbuf)-n,"%d %.2f -1 %u %s %s\n", |
188 | snprintf(tbuf+n,sizeof(tbuf)-n,"%d %.2f -1 %u %s %s\n", |
187 | t1,prime,(unsigned int) start,p1,pb); |
189 | t1,prime,(unsigned int) start,p1,pb); |
188 |
|
190 | } |
189 |
|
191 | accessfile(tbuf,"a","%s/%s/score/%s.exam", |
190 | class_base,pc,pu); |
192 | class_base,pc,pu); |
191 |
|
193 | } |
192 |
|
194 | else accessfile("yes","w","%s/%s/examsimu.%d", |
193 | session_dir,pb,t1); |
195 | session_dir,pb,t1); |
194 |
|
196 | } |
195 |
|
197 | remain=duration+start-nowtime; if(remain<0) remain=0; |
196 |
|
198 | snprintf(dbuf,sizeof(dbuf),"%d",remain); |
197 |
|
199 | setvar("wims_exam_remain",dbuf); /* remaining time in seconds */ |
198 |
|
200 | if(pc==NULL) pc=getvar("wims_class"); |
199 |
|
201 | if(pc) getscorestatus(pc,t1); /* set up wims_scoring */ |
200 | } |
202 | } |
201 | 203 | ||
202 | double currexamscore(int sh) |
204 | double currexamscore(int sh) |
203 | { |
205 | { |
204 |
|
206 | char buf[MAX_FNAME+1], sbuf[MAX_LINELEN+1]; |
205 |
|
207 | char *p, *p1, *cl; |
206 |
|
208 | int i, excnt; |
207 |
|
209 | double sc, w, ww, prime; |
208 | 210 | ||
209 |
|
211 | cl=getvar("wims_class"); if(cl==NULL || *cl==0) return 0; |
210 |
|
212 | mystrncpy(sbuf,session_prefix,sizeof(sbuf)); |
211 |
|
213 | p=strstr(sbuf,"_exam"); if(p) *p=0; |
212 |
|
214 | accessfile(buf,"r","%s/examdata.%d",sbuf,sh); |
213 |
|
215 | p=find_word_start(find_word_end(find_word_start(buf))); |
214 |
|
216 | if(*p) prime=atof(p); else prime=0; |
215 |
|
217 | exam_currscore(sh); |
216 |
|
218 | snprintf(buf,sizeof(buf),"%s/%s/exams/.exam%d",class_base,cl,sh); |
217 |
|
219 | direct_datafile=1; |
218 |
|
220 | excnt=datafile_recordnum(buf); |
219 |
|
221 | w=sc=0; for(i=0;i<excnt;i++) { |
220 |
|
222 | sbuf[0]=0; datafile_fnd_record(buf,i+1,sbuf); |
221 |
|
223 | p1=find_word_start(sbuf); *find_word_end(p1)=0; |
222 |
|
224 | ww=atof(p1); if(ww<=0) continue; |
223 |
|
225 | w+=ww; if(exam_scoredata[i]>-1000) sc+=exam_scoredata[i]*ww; |
224 |
|
226 | } |
225 |
|
227 | direct_datafile=0; if(sc<0) sc=0; |
226 |
|
228 | if(w==0) return 0; else return (1-prime/10)*sc/w+prime; |
227 | } |
229 | } |
228 | 230 | ||
229 | void calc_examdep(char *p) |
231 | void calc_examdep(char *p) |
230 | { |
232 | { |
231 |
|
233 | char *p1, *p2; |
232 |
|
234 | int t; |
233 |
|
235 | if(!trusted_module()) {abt: *p=0; return;} |
234 |
|
236 | p1=find_word_start(p); p2=find_word_end(p1); |
235 |
|
237 | if(*p2==0) goto abt; |
236 |
|
238 | *p2++=0; p2=find_word_start(p2); |
237 |
|
239 | t=atoi(p1); |
238 |
|
240 | snprintf(p,MAX_LINELEN, exam_depcheck(p2,t)? "yes" : "no"); |
239 | } |
241 | } |
240 | 242 |