Rev 16704 | 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 | |||
8155 | bpr | 18 | /* Caches and its management */ |
10 | reyssat | 19 | |
8185 | bpr | 20 | #include "wimslogd.h" |
10 | reyssat | 21 | |
8185 | bpr | 22 | struct classdata classdata[MAX_CLASSCACHE]; |
10 | reyssat | 23 | |
24 | struct classcache { |
||
12474 | bpr | 25 | struct classdata *ptr; |
10 | reyssat | 26 | } classcache[MAX_CLASSCACHE]; |
27 | int classcaches; |
||
28 | |||
8155 | bpr | 29 | /* remove old cache items */ |
10 | reyssat | 30 | void cleancache(void) |
31 | { |
||
12474 | bpr | 32 | int i; |
33 | time_t now; |
||
34 | struct classdata *cd; |
||
35 | now=time(NULL); |
||
36 | for(i=0;i<classcaches;i++) { |
||
37 | cd=classcache[i].ptr; |
||
38 | if(now<cd->start+CLASSCACHE_DELAY) continue; |
||
39 | cd->access=0; |
||
40 | memmove(classcache+i,classcache+i+1,(classcaches-i-1)*sizeof(classcache[0])); |
||
41 | classcaches--; |
||
42 | } |
||
10 | reyssat | 43 | } |
44 | |||
15847 | bpr | 45 | void class_dump(struct classdata *cd) |
46 | { |
||
47 | int i, j, k, nb; |
||
48 | char *s; |
||
49 | exodata *ed; |
||
50 | my_debug("Classe: %s\n", cd->name); |
||
18421 | czzmrn | 51 | my_debug("Superclasse: %s\n", cd->sclass); |
15847 | bpr | 52 | my_debug("Feuilles: %i, Exercices: %i\n", cd->sheetcnt, cd->exocnt); |
53 | for (i=0;i<cd->sheetcnt;i++) |
||
54 | { |
||
55 | my_debug("Feuille %i: %i exercices\n",i+1,cd->sheets[i].exocnt); |
||
56 | nb=cd->sheets[i].techcnt; |
||
57 | if (nb==1) |
||
58 | my_debug("Pas de variable technique\n"); |
||
59 | else |
||
60 | { |
||
61 | s = cd->techs+cd->sheets[i].techoffset; |
||
62 | my_debug("Variable technique: %s, %i valeurs (actuel: %i)\n",s,nb,cd->sheets[i].techval); |
||
63 | s += strlen(s); s++; |
||
64 | for (j = 0; j < nb;j++) |
||
65 | { |
||
66 | my_debug("%s ",s); s += strlen(s); s++; |
||
67 | } |
||
68 | my_debug("\n"); |
||
69 | } |
||
70 | |||
71 | ed = cd->exos + cd->sheets[i].indstart; |
||
72 | for (j = 0; j < nb; j++) |
||
73 | { |
||
74 | for (k = 0; k < cd->sheets[i].exocnt; k++, ed++) |
||
75 | my_debug("[a: %i r: %f w:%f] ", ed->active, ed->require, ed->weight); |
||
76 | my_debug("\n"); |
||
77 | } |
||
78 | } |
||
79 | if (cd->exam.exocnt>0) |
||
80 | { |
||
81 | ed = cd->exos + cd->exam.indstart; |
||
82 | my_debug("Examen: %i exercices\n", cd->exam.exocnt); |
||
83 | for (k = 0; k < cd->exam.exocnt; k++, ed++) |
||
84 | my_debug("[a: %i r: %f w:%f] ", ed->active, ed->require, ed->weight); |
||
85 | my_debug("\n"); |
||
86 | } |
||
87 | else |
||
88 | my_debug("Pas d'examen\n"); |
||
89 | my_debug("Fin de la classe\n"); |
||
90 | } |
||
91 | |||
8155 | bpr | 92 | /* Locate the cache number of a class */ |
10 | reyssat | 93 | struct classdata *getclasscache(char *cl) |
94 | { |
||
16081 | bpr | 95 | int i,j=0,k,l,m,n, oldest, offset; |
12474 | bpr | 96 | struct stat st; |
97 | struct classdata *cd; |
||
98 | char buf[MAX_LINELEN+1], buf2[MAX_LINELEN+1]; |
||
18421 | czzmrn | 99 | char spc[MAX_FNAME+1]; |
15847 | bpr | 100 | char *p1, *p2, *p3, *q1, *q2; |
12474 | bpr | 101 | time_t tt; |
102 | tt=0, oldest=0; |
||
103 | for(i=0;i<classcaches;i++) { |
||
104 | cd=classcache[i].ptr; |
||
105 | if(tt>cd->start) {tt=cd->start; oldest=i;} |
||
106 | if(strcmp(cd->name,cl)==0) { |
||
107 | cd->access++; |
||
108 | return cd; |
||
10 | reyssat | 109 | } |
12474 | bpr | 110 | } |
111 | if(classcaches>=MAX_CLASSCACHE) { |
||
112 | i=oldest;cd=classcache[i].ptr; |
||
113 | cd->access=0; |
||
114 | memmove(classcache+i,classcache+i+1,(classcaches-i-1)*sizeof(classcache[0])); |
||
115 | classcaches--; |
||
116 | } |
||
117 | for(i=0;i<MAX_CLASSCACHE && classdata[i].access>0; i++); |
||
118 | if(i>classcaches) return NULL; |
||
119 | cd=classdata+i; cd->access=1; |
||
120 | classcache[classcaches++].ptr=cd; |
||
121 | snprintf(cd->name,sizeof(cd->name),"%s",cl); |
||
15847 | bpr | 122 | cd->techs[0]=0; offset=1; |
12474 | bpr | 123 | cd->start=time(NULL); cd->exocnt=0; |
18421 | czzmrn | 124 | /* get superclass */ |
125 | // getdef is defined in wimslogdscore.c |
||
126 | getdef (".def","class_superclass",spc); |
||
127 | strcpy(cd->sclass,spc); |
||
12474 | bpr | 128 | /* Now get the exo data */ |
129 | wlogdaccessfile(buf,"r","sheets/.require"); |
||
15847 | bpr | 130 | p1=strchr (buf,':'); |
131 | if (p1==NULL) { |
||
16391 | bpr | 132 | /*old format*/ |
15847 | bpr | 133 | for(i=k=0,p1=buf; *p1; i++,p1=p2) { |
134 | cd->sheets[i].start=cd->sheets[i].indstart=k; |
||
135 | p2=strchr(p1,'\n'); if(p2) *p2++=0; else p2=p1+strlen(p1); |
||
136 | for(j=0,q1=find_word_start(p1); *q1 && k<MAX_CLASSEXOS; j++,q1=find_word_start(q2)) { |
||
137 | q2=find_word_end(q1); if(*q2) *q2++=0; |
||
138 | cd->exos[k].require=atof(q1); |
||
139 | cd->exos[k].weight=0; |
||
140 | cd->exos[k].active=1; |
||
141 | k++; |
||
142 | } |
||
143 | cd->sheets[i].exocnt=j; |
||
144 | cd->exocnt +=j; |
||
145 | cd->sheets[i].techcnt=1; |
||
146 | } |
||
147 | cd->sheetcnt=i; |
||
148 | } |
||
149 | else { |
||
150 | /* i: sheet, k: exo numero counted with multiplicity, l: tech version*/ |
||
151 | for (i=k=0,p1++; *p1; i++,p1=p2) { |
||
152 | cd->sheets[i].indstart=k; /* numero of the first exo of the i sheet with multiplicity */ |
||
153 | cd->sheets[i].start=cd->exocnt; |
||
154 | p2=strchr(p1,':'); if(p2) *p2++=0; else p2=p1+strlen(p1); |
||
155 | for (l=0; *p1; l++,p1=p3) { |
||
156 | p3=strchr(p1,'\n'); if(p3) *p3++=0; else p3=p1+strlen(p1); |
||
157 | for(j=0,q1=find_word_start(p1); *q1 && k<MAX_CLASSEXOS; j++,q1=find_word_start(q2)) { |
||
158 | q2=find_word_end(q1); if(*q2) *q2++=0; |
||
159 | cd->exos[k].require=atof(q1); |
||
160 | /* default values, will be changed after reading the appropriate file */ |
||
161 | cd->exos[k].weight=0; |
||
162 | cd->exos[k].active=1; |
||
163 | k++; |
||
164 | } |
||
165 | } |
||
166 | cd->sheets[i].exocnt=j; /* number of exos in the sheet i */ |
||
167 | cd->exocnt+=j; /* total number of exos sans multiplicité */ |
||
168 | cd->sheets[i].techcnt=l; //nombre de lignes=nombre de variables techniques, |
||
10 | reyssat | 169 | } |
15847 | bpr | 170 | cd->sheetcnt=i; /* number of sheets */ |
12474 | bpr | 171 | } |
172 | if(k>=MAX_CLASSEXOS) return NULL; |
||
15847 | bpr | 173 | cd->examstart=cd->exocnt; // nb exos sans multipl. dans les feuilles précédant l'examen |
174 | cd->examcnt=0; |
||
175 | cd->exam.indstart=k; |
||
176 | cd->exam.start=cd->exocnt; |
||
177 | cd->exam.exocnt=0; |
||
178 | cd->modif=0; |
||
12474 | bpr | 179 | wlogdaccessfile(buf,"r","sheets/.weight"); |
15847 | bpr | 180 | p1=strchr (buf,':'); |
181 | /*old format*/ |
||
182 | if (p1==NULL) |
||
183 | for(i=k=0,p1=buf; *p1; i++,p1=p2) { |
||
184 | p2=strchr(p1,'\n'); if(p2) *p2++=0; else p2=p1+strlen(p1); |
||
185 | for(j=0,q1=find_word_start(p1); *q1 && k<MAX_CLASSEXOS; j++,q1=find_word_start(q2)) { |
||
186 | q2=find_word_end(q1); if(*q2) *q2++=0; |
||
12474 | bpr | 187 | cd->exos[k].weight=atof(q1); |
188 | k++; |
||
8849 | bpr | 189 | } |
10 | reyssat | 190 | } |
15847 | bpr | 191 | else |
192 | for (i=k=0,p1++; *p1; i++,p1=p2) { |
||
193 | p2=strchr(p1,':'); if(p2) *p2++=0; else p2=p1+strlen(p1); |
||
194 | for (; *p1; p1=p3) { |
||
195 | p3=strchr(p1,'\n'); if(p3) *p3++=0; else p3=p1+strlen(p1); |
||
196 | for(q1=find_word_start(p1); *q1 && k<MAX_CLASSEXOS;q1=find_word_start(q2)) { |
||
197 | q2=find_word_end(q1); if(*q2) *q2++=0; |
||
198 | cd->exos[k].weight=atof(q1); |
||
199 | k++; |
||
200 | } |
||
201 | } |
||
202 | } |
||
203 | if(stat("sheets/.vars",&st)==0) { |
||
204 | wlogdaccessfile(buf,"r","sheets/.vars"); |
||
205 | p1=strchr (buf,':'); |
||
16391 | bpr | 206 | if (p1!=NULL) { |
207 | for (i=0; i < cd->sheetcnt; i++, p1=p2){ |
||
208 | p1++; |
||
209 | cd->sheets[i].techoffset=0; |
||
210 | p2=strchr(p1,'\n'); if(p2) *p2++=0; else p2=p1+strlen(p1); |
||
211 | if (cd->sheets[i].techcnt == 0) continue; |
||
212 | cd->sheets[i].techoffset=offset; |
||
213 | for(l=0; l <= cd->sheets[i].techcnt;l++,p1=q2) { |
||
214 | p1=find_word_start(p1); |
||
215 | q2=find_word_end(p1); if(*q2) *q2++=0; |
||
216 | strcpy(cd->techs+offset,p1); |
||
217 | offset+=strlen(p1); offset++; |
||
218 | } |
||
15847 | bpr | 219 | } |
220 | } |
||
221 | wlogdaccessfile(buf,"r","sheets/.active"); |
||
222 | p1=strchr (buf,':'); |
||
16391 | bpr | 223 | if (p1!=NULL) { |
224 | for (i=k=0,p1++; *p1; i++,p1=p2) { |
||
225 | p2=strchr(p1,':'); if(p2) *p2++=0; else p2=p1+strlen(p1); |
||
226 | for (; *p1; p1=p3) { |
||
227 | p3=strchr(p1,'\n'); if(p3) *p3++=0; else p3=p1+strlen(p1); |
||
228 | for(q1=find_word_start(p1); *q1 && k<MAX_CLASSEXOS;q1=find_word_start(q2)) { |
||
229 | q2=find_word_end(q1); if(*q2) *q2++=0; |
||
230 | cd->exos[k].active=strcmp(q1,"0"); |
||
231 | k++; |
||
232 | } |
||
15847 | bpr | 233 | } |
234 | } |
||
235 | } |
||
12474 | bpr | 236 | } |
15847 | bpr | 237 | //class_dump(cd); |
12474 | bpr | 238 | if(stat("exams/.exams",&st)==0) cd->modif=st.st_mtime; else return cd; |
239 | wlogdaccessfile(buf,"r","exams/.exams"); |
||
240 | if(buf[0]==0) return cd; |
||
241 | if(buf[0]==':') p1=buf-1; else p1=strstr(buf,"\n:"); |
||
16704 | guerimand | 242 | for(n=m=0,k=cd->exam.indstart; p1 && k<MAX_CLASSEXOS && m<MAX_EXAMS; p1=p2,m++,k++) { |
12474 | bpr | 243 | p1+=2; |
244 | p2=strstr(p1,"\n:"); if(p2) *p2=0; |
||
245 | // if(*find_word_start(p1)<'1') continue; /* status */ |
||
246 | fnd_line(p1,3,buf2); if(buf2[0]==0) continue; |
||
247 | q1=find_word_start(buf2); q2=find_word_end(q1); |
||
248 | if(*q2) *q2++=0; |
||
249 | q2=find_word_start(q2); *find_word_end(q2)=0; |
||
250 | i=atoi(q1); j=atoi(q2); if(i<=0 || j<=0) continue; |
||
251 | cd->exos[k].weight=i; cd->exos[k].require=j; /* weight: duration. require: retries */ |
||
252 | fnd_line(p1,6,buf2); q1=find_word_start(buf2); |
||
253 | singlespace(q1); strip_trailing_spaces(q1); |
||
15847 | bpr | 254 | cd->ctptr[m]=n; cd->ctbuf[n]=0; |
16704 | guerimand | 255 | if(n+strlen(q1)>CTBUFLEN-MAX_EXAMS-16) *q1=0; /* silent truncation */ |
12474 | bpr | 256 | l=strlen(q1)+1; memmove(cd->ctbuf+n,q1,l); n+=l; |
257 | } |
||
15847 | bpr | 258 | cd->examcnt=m; // number of exos in all exams |
259 | cd->exocnt+=m; // number of all exos without multiplicity |
||
260 | cd->exam.exocnt=m; |
||
261 | cd->sheets[cd->sheetcnt]=cd->exam; |
||
12474 | bpr | 262 | return cd; |
10 | reyssat | 263 | } |