Subversion Repositories wimsdev

Rev

Rev 7363 | Rev 8185 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

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