// analyse des statistiques d'emploi du temps. cf fichier ~/temps.txt // CC temps.c -o temps #include #include #include #define error(msg) { printf("%s::%d : %s \n",name,lin,msg); exit(1); } int analyse(char* file); void display(); #define NB_MAX 1000 char* label[NB_MAX]; int label_t[NB_MAX]; int alias[NB_MAX]; int nb_label=0; int show_alias=0, show_tot=0, show_res=1, show_nul=0, show_missions=0, heures=0, strict=0, range[2]={0,0x7fffffff}; // prefs int t=0,tp=0,tm=0,tv=0,dm=0,dM=0,j=0,jp=0,jm=0; int lin=0; char*name = NULL; // globs int inc_label(char* nom, int t) { // retrouve ou definit un label int i; for (i=0; i=NB_MAX) error("trop de labels; augmenter NB_MAX"); label[i] = strdup(nom); label_t[i]=0; alias[i]=0; if ((nom[0]=='+')&&strcmp(nom,"+mission")) alias[i]=-1; // sous-totaux nb_label++; } label_t[i] += t; return i; } int date(char* s) { // converti une date en chiffre int j,m,a,n,p; n=sscanf(s,"%d/%d%n",&j,&m,&p); if (n!=2) return -1; n=sscanf(s+p,"/%d",&a); if (n!=1) { a=m; m=j; j=0; } return j+32*(m+12*a); } char* strdate(int d) { // converti une date en chaine static char sdate[256]; sprintf(sdate,"%02d/%02d/%02d",d%32,(d/32)%12,d/384); return sdate; } void read_duree(char* ptr,int* dt, int* dtm) { // lit une duree ou deux int h=0,m=0,hm=0,mm=0,n=0; n=sscanf(ptr,"%dh%d (%dh%d)",&h,&m,&hm,&mm); if ((n<2)||(n==3)) error("erreur NhNN"); *dt = h*60+m; *dtm = hm*60+mm; } void help(){ printf(" +d [JJ/]MM/AA : a partir de la date indiquee \n" " -d [JJ/]MM/AA : avant la date indiquee \n" " +t -t : avec/sans resultats detailles \n" " +s -s : avec/sans resultats par categorie \n" " +h : avec le nombre d'heures \n" " +f -f : ne compte que les h de bureau \n" " -p (1st param) : ne consulte pas le fichier de prefs .temps\n" " +z : force display of zero values \n" " +m : include mission days into +mission (1j=8h) \n" "\ncontenu du fichier de relevés:\n" " show ( label | \"label\") : declare label pour ordre affichage\n" " show ( +titre | \"+titre\") : affiche un sous-total\n" " alias label1 label2 : label1 est inclu dans categ label2\n" "\n entrée journalière:\n" " --- J JJ/MM/AA [commentaire] (ou: +++ si congé)\n" " bloc-note \n" " === \n" " label1: NN' [commentaire]\n" " labelN: NN' [commentaire]\n" " [+mission: NN'[commentaire]]\n" " j: NhNN (ou: si congé: +j NhNN si mission: Nj)\n" ); } int main(int argc, char** argv) { int file=0, cas; int i; char** ptr; printf("%s [-p][-h][+h][-t][+t][-s][+s][-f][+f][+z][+d date][-d date] [files] \n" "( default: -t +s +f -z .temps|temps.txt )\n\n",argv[0]); for (i=argc-1,ptr=argv+1; i; i--,ptr++) // parse ligne de commande (prefs) if (((*ptr)[0]=='-')||((*ptr)[0]=='+')) { cas = ((*ptr)[0]=='+'); switch((*ptr)[1]) { case 'h': if (!cas) {help(); exit(0);} else heures=1; break; case 't': show_tot = cas; break; case 's': show_res = cas; break; case 'd': if (!*(ptr+1)) error("date absente"); range[1-cas] = date(*(ptr+1)); i--;ptr++; break; case 'f': strict = 1-cas; break; case 'z': show_nul = cas; break; case 'm': show_missions = cas; break; } } if ((argc<=1) || (strcmp(argv[1],"-p")!=0)) if (analyse(".temps")) file++; for (i=argc-1,ptr=argv+1; i; i--,ptr++) // parse ligne de commande (files) if (((*ptr)[0]=='-')||((*ptr)[0]=='+')) { if ((*ptr)[1]=='d') { i--;ptr++; } } else if (analyse(*ptr)) file++; else error("fichier inexistant"); if (!file) if (!analyse("temps.txt")) error("fichier inexistant"); display(); return 1; } int analyse(char* file) { // --------- analyse des donnees ------------- char buff[256],str1[256],str2[256], *ptr, c,tj; int state=0, m,h,n,dt,dtm, i,i1,i2, ok,_d; static int d=-1; FILE* f = fopen(name=file,"r"); lin=0; if (!f) return 0; inc_label("vide",0); // car duree journee > somme taches ! while (1) { // -------------- on parse tout le fichier if (fgets(buff,256,f)==NULL) break; // fin du fichier ! lin++; // numero de ligne *str1=0;if ((buff[0]=='#')||(sscanf(buff,"%s",str1)==0)||(!strlen(str1))) continue; // commentaire if (state==0) { // #### on est dans la partie commandes (hors blocs dates) if (strncmp(buff,"echo",4)==0) { puts(buff+5); } else if (strncmp(buff,"include",7)==0) { // cf autre fichier sscanf(buff,"%*s%s",str1); int _lin=lin; analyse(str1); name=file; lin=_lin; } else if (strncmp(buff,"alias",5)==0) { // def d'aliases n=sscanf(buff,"%*s%*0c%n%s%*0c%n%s",&i1,str1,&i2,str2); if (n!=2) error("erreur alias"); if (str1[0]=='"') { // cas d'un 1er label contenant des espaces ptr = strchr(buff+i1+1,'"'); if (!ptr) error("manque \" "); *ptr=0; strcpy(str1,buff+i1+1); ptr++; n=sscanf(ptr,"%*0c%n%s",&i2,str2); if (n!=1) error("erreur alias"); i2 += (ptr-buff); } if (str2[0]=='"') { // cas d'un 2nd label contenant des espaces ptr = strchr(buff+i2+1,'"'); if (!ptr) error("manque \" "); *ptr=0; strcpy(str2,buff+i2+1); ptr++; } i1 = inc_label(str1,0); i2 = inc_label(str2,0); alias[i1]=i2+1; show_alias=1; // lie les 2 labels. ATTENTION: N+1 } else if (strncmp(buff,"show",4)==0) { // def ordre de presentation n=sscanf(buff,"%*s%*0c%n%s",&i1,str1); if (n!=1) error("erreur show"); if (str1[0]=='"') { // cas d'un label contenant des espaces ptr = strchr(buff+i1+1,'"'); if (!ptr) error("manque \" "); *ptr=0; strcpy(str1,buff+i1+1); } inc_label(str1,0); // on declare le label dans l'ordre } else if (strncmp(buff,"===",3)==0) error("manque '---'") else if ((strncmp(buff,"---",3)==0)||(strncmp(buff,"+++",3)==0)){ // date state=1; tj = buff[0]; // memo le type de jour pour verif if (strict&&(tj=='+')) { ok=0; continue; } // si que j ouvrables _d=d; d = date(buff+6); if (d<0) error("date erronnee"); if (d<_d) error("date non chronologique"); ok = (d>=range[0])&&(d=0)&&label_t[i]) print_ligne(label[i],label_t[i]); } if (show_alias && show_res) { printf("\n*** CATEGORIES ***\n\n"); for (i=0; i<><> if (i1!=i) { label_t[i1]+=label_t[i]; label_t[i]=0; } } for (i=0; i