Subversion Repositories wimsdev

Rev

Rev 16704 | 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. #include "wimslogd.h"
  21.  
  22. struct classdata classdata[MAX_CLASSCACHE];
  23.  
  24. struct classcache {
  25.   struct classdata *ptr;
  26. } classcache[MAX_CLASSCACHE];
  27. int classcaches;
  28.  
  29. /* remove old cache items */
  30. void cleancache(void)
  31. {
  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.   }
  43. }
  44.  
  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);
  51.  my_debug("Superclasse: %s\n", cd->sclass);
  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.  
  92. /* Locate the cache number of a class */
  93. struct classdata *getclasscache(char *cl)
  94. {
  95.   int i,j=0,k,l,m,n, oldest, offset;
  96.   struct stat st;
  97.   struct classdata *cd;
  98.   char buf[MAX_LINELEN+1], buf2[MAX_LINELEN+1];
  99.   char spc[MAX_FNAME+1];
  100.   char *p1, *p2, *p3, *q1, *q2;
  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;
  109.     }
  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);
  122.   cd->techs[0]=0; offset=1;
  123.   cd->start=time(NULL); cd->exocnt=0;
  124.   /* get superclass */
  125.   // getdef is defined in wimslogdscore.c
  126.   getdef (".def","class_superclass",spc);
  127.   strcpy(cd->sclass,spc);
  128.   /* Now get the exo data */
  129.   wlogdaccessfile(buf,"r","sheets/.require");
  130.   p1=strchr (buf,':');
  131.   if (p1==NULL) {
  132.     /*old format*/
  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,
  169.     }
  170.     cd->sheetcnt=i; /* number of sheets */
  171.   }
  172.   if(k>=MAX_CLASSEXOS) return NULL;
  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;
  179.   wlogdaccessfile(buf,"r","sheets/.weight");
  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;
  187.         cd->exos[k].weight=atof(q1);
  188.         k++;
  189.       }
  190.     }
  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,':');
  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.         }
  219.       }
  220.     }
  221.     wlogdaccessfile(buf,"r","sheets/.active");
  222.     p1=strchr (buf,':');
  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.           }
  233.         }
  234.       }
  235.     }
  236.   }
  237.   //class_dump(cd);
  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:");
  242.   for(n=m=0,k=cd->exam.indstart; p1 && k<MAX_CLASSEXOS && m<MAX_EXAMS; p1=p2,m++,k++) {
  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);
  254.     cd->ctptr[m]=n; cd->ctbuf[n]=0;
  255.     if(n+strlen(q1)>CTBUFLEN-MAX_EXAMS-16) *q1=0;      /* silent truncation */
  256.     l=strlen(q1)+1; memmove(cd->ctbuf+n,q1,l); n+=l;
  257.   }
  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;
  262.   return cd;
  263. }
  264.