Rev 11125 | Rev 15847 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 11125 | Rev 12474 | ||
---|---|---|---|
Line 20... | Line 20... | ||
20 | #include "wimslogd.h" |
20 | #include "wimslogd.h" |
21 | 21 | ||
22 | struct classdata classdata[MAX_CLASSCACHE]; |
22 | struct classdata classdata[MAX_CLASSCACHE]; |
23 | 23 | ||
24 | struct classcache { |
24 | struct classcache { |
25 |
|
25 | struct classdata *ptr; |
26 | } classcache[MAX_CLASSCACHE]; |
26 | } classcache[MAX_CLASSCACHE]; |
27 | int classcaches; |
27 | int classcaches; |
28 | 28 | ||
29 | struct sheetdata { |
29 | struct sheetdata { |
30 |
|
30 | char buffer[SHEETBUFLEN]; |
31 |
|
31 | int name,header,status,exocnt,exo[MAX_EXOS]; |
32 |
|
32 | time_t start, last; |
33 |
|
33 | int access; |
34 | } sheetdata[MAX_SHEETCACHE]; |
34 | } sheetdata[MAX_SHEETCACHE]; |
35 | 35 | ||
36 | struct sheetcache { |
36 | struct sheetcache { |
37 |
|
37 | struct sheetdata *ptr; |
38 | } sheetcache[MAX_SHEETCACHE]; |
38 | } sheetcache[MAX_SHEETCACHE]; |
39 | int sheetcaches; |
39 | int sheetcaches; |
40 | 40 | ||
41 | /* searches a list. Returns index if found, -1 if nomatch. |
41 | /* searches a list. Returns index if found, -1 if nomatch. |
42 | * Uses binary search, list must be sorted. |
42 | * Uses binary search, list must be sorted. |
43 | */ |
43 | */ |
44 | int search_data(void *list, int items, size_t item_size, unsigned short int t) |
44 | int search_data(void *list, int items, size_t item_size, unsigned short int t) |
45 | { |
45 | { |
46 |
|
46 | int i1,i2,j,k; |
47 |
|
47 | unsigned short int *p; |
48 | 48 | ||
49 |
|
49 | if(items<=0) return -1; |
50 |
|
50 | j=0; p=list; k=*p-t; |
51 |
|
51 | if(k==0) return k; |
52 |
|
52 | if(k>0) return -1; |
53 |
|
53 | p=list+(items-1)*item_size; |
54 |
|
54 | k=*p-t; if(k==0) return items-1; if(k<0) return ~items; |
55 |
|
55 | for(i1=0,i2=items-1;i2>i1+1;) { |
56 |
|
56 | j=(i2+i1)/2; |
57 |
|
57 | p=list+(j*item_size); |
58 |
|
58 | k=*p-t; |
59 |
|
59 | if(k==0) return j; |
60 |
|
60 | if(k>0) {i2=j; continue;} |
61 |
|
61 | if(k<0) {i1=j; continue;} |
62 |
|
62 | } |
63 |
|
63 | return ~i2; |
64 | } |
64 | } |
65 | 65 | ||
66 | /* remove old cache items */ |
66 | /* remove old cache items */ |
67 | void cleancache(void) |
67 | void cleancache(void) |
68 | { |
68 | { |
69 |
|
69 | int i; |
70 |
|
70 | time_t now; |
71 |
|
71 | struct classdata *cd; |
72 |
|
72 | struct sheetdata *sd; |
73 |
|
73 | now=time(NULL); |
74 |
|
74 | for(i=0;i<classcaches;i++) { |
75 |
|
75 | cd=classcache[i].ptr; |
76 |
|
76 | if(now<cd->start+CLASSCACHE_DELAY) continue; |
77 |
|
77 | cd->access=0; |
78 |
|
78 | memmove(classcache+i,classcache+i+1,(classcaches-i-1)*sizeof(classcache[0])); |
79 |
|
79 | classcaches--; |
80 |
|
80 | } |
81 |
|
81 | for(i=0;i<sheetcaches;i++) { |
82 |
|
82 | sd=sheetcache[i].ptr; |
83 |
|
83 | if(now<sd->start+SHEETCACHE_DELAY) continue; |
84 |
|
84 | sd->access=0; |
85 |
|
85 | memmove(sheetcache+i,sheetcache+i+1,(sheetcaches-i-1)*sizeof(sheetcache[0])); |
86 |
|
86 | sheetcaches--; |
87 |
|
87 | } |
88 | } |
88 | } |
89 | 89 | ||
90 | /* Locate the cache number of a class */ |
90 | /* Locate the cache number of a class */ |
91 | struct classdata *getclasscache(char *cl) |
91 | struct classdata *getclasscache(char *cl) |
92 | { |
92 | { |
93 |
|
93 | int i,j,k,l,m,n, oldest; |
94 |
|
94 | struct stat st; |
95 |
|
95 | struct classdata *cd; |
96 |
|
96 | char buf[MAX_LINELEN+1], buf2[MAX_LINELEN+1]; |
97 |
|
97 | char *p1, *p2, *q1, *q2; |
98 |
|
98 | time_t tt; |
99 |
|
99 | tt=0, oldest=0; |
100 |
|
100 | for(i=0;i<classcaches;i++) { |
101 |
|
101 | cd=classcache[i].ptr; |
102 |
|
102 | if(tt>cd->start) {tt=cd->start; oldest=i;} |
103 |
|
103 | if(strcmp(cd->name,cl)==0) { |
104 |
|
104 | cd->access++; |
105 |
|
105 | return cd; |
106 |
|
106 | } |
107 |
|
107 | } |
108 |
|
108 | if(classcaches>=MAX_CLASSCACHE) { |
109 |
|
109 | i=oldest;cd=classcache[i].ptr; |
110 |
|
110 | cd->access=0; |
111 |
|
111 | memmove(classcache+i,classcache+i+1,(classcaches-i-1)*sizeof(classcache[0])); |
112 |
|
112 | classcaches--; |
113 |
|
113 | } |
114 |
|
114 | for(i=0;i<MAX_CLASSCACHE && classdata[i].access>0; i++); |
115 |
|
115 | if(i>classcaches) return NULL; |
116 |
|
116 | cd=classdata+i; cd->access=1; |
117 |
|
117 | classcache[classcaches++].ptr=cd; |
118 |
|
118 | snprintf(cd->name,sizeof(cd->name),"%s",cl); |
119 |
|
119 | cd->start=time(NULL); cd->exocnt=0; |
120 | /* Now get the exo data */ |
120 | /* Now get the exo data */ |
121 |
|
121 | wlogdaccessfile(buf,"r","sheets/.require"); |
122 |
|
122 | for(i=k=0,p1=buf; *p1; i++,p1=p2) { |
123 |
|
123 | p2=strchr(p1,'\n'); if(p2) *p2++=0; else p2=p1+strlen(p1); |
124 |
|
124 | for(j=0,q1=find_word_start(p1); *q1 && k<MAX_CLASSEXOS; j++,q1=find_word_start(q2)) { |
125 |
|
125 | q2=find_word_end(q1); if(*q2) *q2++=0; |
126 |
|
126 | cd->exos[k].num=(i<<8)+j;cd->exos[k].require=atof(q1); |
127 |
|
127 | cd->exos[k].weight=0; |
128 | k++; |
- | |
129 | } |
- | |
130 | - | ||
131 | } |
- | |
132 | if(k>=MAX_CLASSEXOS) return NULL; |
- | |
133 | cd->exocnt=k; cd->examstart=k; cd->modif=0; |
- | |
134 | wlogdaccessfile(buf,"r","sheets/.weight"); |
- | |
135 | for(i=k=0,p1=buf; *p1; i++,p1=p2) { |
- | |
136 | p2=strchr(p1,'\n'); if(p2) *p2++=0; else p2=p1+strlen(p1); |
- | |
137 | for(j=0,q1=find_word_start(p1); *q1 && k<MAX_CLASSEXOS; j++,q1=find_word_start(q2)) { |
- | |
138 | q2=find_word_end(q1); if(*q2) *q2++=0; |
- | |
139 | if(cd->exos[k].num==(i<<8)+j) { |
- | |
140 | cd->exos[k].weight=atof(q1); |
- | |
141 | k++; |
- | |
142 | } |
- | |
143 | else while(k<cd->exocnt && cd->exos[k].num<(i<<8)+j) k++; |
- | |
144 | } |
- | |
145 | } |
- | |
146 | if(stat("exams/.exams",&st)==0) cd->modif=st.st_mtime; else return cd; |
- | |
147 | wlogdaccessfile(buf,"r","exams/.exams"); |
- | |
148 | if(buf[0]==0) return cd; |
- | |
149 | if(buf[0]==':') p1=buf-1; else p1=strstr(buf,"\n:"); |
- | |
150 | for(n=m=0,k=cd->exocnt; p1 && k<MAX_CLASSEXOS && m<MAX_EXOS; p1=p2,m++) { |
- | |
151 | p1+=2; |
- | |
152 | p2=strstr(p1,"\n:"); if(p2) *p2=0; |
- | |
153 | // if(*find_word_start(p1)<'1') continue; /* status */ |
- | |
154 | fnd_line(p1,3,buf2); if(buf2[0]==0) continue; |
- | |
155 | q1=find_word_start(buf2); q2=find_word_end(q1); |
- | |
156 | if(*q2) *q2++=0; |
- | |
157 | q2=find_word_start(q2); *find_word_end(q2)=0; |
- | |
158 | i=atoi(q1); j=atoi(q2); if(i<=0 || j<=0) continue; |
- | |
159 | cd->exos[k].num=0xFF00+m; |
- | |
160 | cd->exos[k].weight=i; cd->exos[k].require=j; /* weight: duration. require: retries */ |
- | |
161 | fnd_line(p1,6,buf2); q1=find_word_start(buf2); |
- | |
162 | singlespace(q1); strip_trailing_spaces(q1); |
- | |
163 | cd->ctptr[k-cd->exocnt]=n; cd->ctbuf[n]=0; |
- | |
164 | if(n+strlen(q1)>CTBUFLEN-MAX_EXOS-16) *q1=0; /* silent truncation */ |
- | |
165 | l=strlen(q1)+1; memmove(cd->ctbuf+n,q1,l); n+=l; |
- | |
166 | k++; |
128 | k++; |
167 | } |
129 | } |
- | 130 | } |
|
- | 131 | if(k>=MAX_CLASSEXOS) return NULL; |
|
- | 132 | cd->exocnt=k; cd->examstart=k; cd->modif=0; |
|
- | 133 | wlogdaccessfile(buf,"r","sheets/.weight"); |
|
- | 134 | for(i=k=0,p1=buf; *p1; i++,p1=p2) { |
|
- | 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 | if(cd->exos[k].num==(i<<8)+j) { |
|
- | 139 | cd->exos[k].weight=atof(q1); |
|
- | 140 | k++; |
|
- | 141 | } |
|
- | 142 | else while(k<cd->exocnt && cd->exos[k].num<(i<<8)+j) k++; |
|
- | 143 | } |
|
- | 144 | } |
|
- | 145 | if(stat("exams/.exams",&st)==0) cd->modif=st.st_mtime; else return cd; |
|
- | 146 | wlogdaccessfile(buf,"r","exams/.exams"); |
|
- | 147 | if(buf[0]==0) return cd; |
|
- | 148 | if(buf[0]==':') p1=buf-1; else p1=strstr(buf,"\n:"); |
|
- | 149 | for(n=m=0,k=cd->exocnt; p1 && k<MAX_CLASSEXOS && m<MAX_EXOS; p1=p2,m++) { |
|
- | 150 | p1+=2; |
|
- | 151 | p2=strstr(p1,"\n:"); if(p2) *p2=0; |
|
- | 152 | // if(*find_word_start(p1)<'1') continue; /* status */ |
|
- | 153 | fnd_line(p1,3,buf2); if(buf2[0]==0) continue; |
|
- | 154 | q1=find_word_start(buf2); q2=find_word_end(q1); |
|
- | 155 | if(*q2) *q2++=0; |
|
- | 156 | q2=find_word_start(q2); *find_word_end(q2)=0; |
|
- | 157 | i=atoi(q1); j=atoi(q2); if(i<=0 || j<=0) continue; |
|
- | 158 | cd->exos[k].num=0xFF00+m; |
|
- | 159 | cd->exos[k].weight=i; cd->exos[k].require=j; /* weight: duration. require: retries */ |
|
- | 160 | fnd_line(p1,6,buf2); q1=find_word_start(buf2); |
|
- | 161 | singlespace(q1); strip_trailing_spaces(q1); |
|
- | 162 | cd->ctptr[k-cd->exocnt]=n; cd->ctbuf[n]=0; |
|
- | 163 | if(n+strlen(q1)>CTBUFLEN-MAX_EXOS-16) *q1=0; /* silent truncation */ |
|
- | 164 | l=strlen(q1)+1; memmove(cd->ctbuf+n,q1,l); n+=l; |
|
- | 165 | k++; |
|
- | 166 | } |
|
168 |
|
167 | cd->examcnt=k-cd->exocnt; cd->exocnt=k; |
169 |
|
168 | return cd; |
170 | } |
169 | } |
171 | // misprint ?? sheetdata ?? does not seem to be used. |
170 | // misprint ?? sheetdata ?? does not seem to be used. |
172 | /* prepare cache for a sheet */ |
171 | /* prepare cache for a sheet */ |
173 | struct sheetata *getsheetcache(char *cl, char *sh) |
172 | struct sheetata *getsheetcache(char *cl, char *sh) |
174 | { |
173 | { |
175 | - | ||
176 | - | ||
177 | - | ||
178 |
|
174 | return NULL; |
179 | } |
175 | } |
180 | - |