-a/--average option implemented.
[timeplan.git] / timeplan.c
index e48910c..7818e43 100644 (file)
@@ -29,11 +29,12 @@ static const char version[]="This is TimePlan, version 1.0\n";
 static const char *pname;
 static char *finame;
 static FILE *fi;
-static int verbose=0,tree=0;
+static int verbose=0,tree=0,doaverage=0;
 static char *formtotal=DEF_FORMTOTAL;
 static char buf[LINE_MAX];
 static int line=0;
 static enum { SORT_NO,SORT_TIMETOT,SORT_STORES } sortby=SORT_TIMETOT;
+static unsigned lifetime_days=0;
 
 static void usage(void)
 {
@@ -50,6 +51,7 @@ Usage: timeplan [-u|--unsort] [-s|--stores] [-T|--timetot]  [-t|--tree]\n\
   -s, --stores\t\tSort the result by stores count\n\
   -T, --timetot\t\tSort the result by total time (default)\n\
   -t, --tree\t\tOrganize data as hierarchy tree\n\
+  -a, --average\t\tDisplay all times as average-per-day value\n\
   -c, --condition\tDefine condition variable\n\
   -f, --formtotal\tFormat \"Total\" column (\"text *val/val:width text\")\n\
   -r, --rule\t\tAdd to the end of .rc file this rule (':'->'\\t')\n\
@@ -65,6 +67,7 @@ static const struct option longopts[]={
 {"stores"   ,0,0,'s'},
 {"timetot"  ,0,0,'T'},
 {"tree"     ,0,0,'t'},
+{"average"  ,0,0,'a'},
 {"condition",1,0,'c'},
 {"formtotal",1,0,'f'},
 {"rule"     ,1,0,'r'},
@@ -87,16 +90,18 @@ static int hashtable_tot=0;
 
 static int dumpaction(const struct action *action)
 {
-int tot FAKEUSE,mins FAKEUSE,hours FAKEUSE,days FAKEUSE,origtot;
+int tot,mins FAKEUSE,hours FAKEUSE,days FAKEUSE,origtot;
 char *s,fmt[]="%?d";
 
        if (action) {
                tot=(action->timetot+30)/60;
+               if (doaverage && lifetime_days)
+                       tot/=lifetime_days;
                mins=tot; hours=mins/60; days=hours/24;
                mins%=60; hours%=24;
-               origtot=tot;
                }
-       else origtot=0;
+       else tot=0;
+       origtot=tot;
        for (s=formtotal;*s;s++)
                switch (*s) {
                        case '*': case '/': {
@@ -131,7 +136,7 @@ dump:
                                else origtot++;
                        }
        if (action)
-               printf("=%02d/%02d:%02d\t%4d\t%s\n",days,hours,mins,
+               printf("=%03d/%02d:%02d %4d\t%s\n",days,hours,mins,
                        action->stores,action->what);
        return(origtot);
 }
@@ -157,7 +162,7 @@ struct action **sorta FAKEUSE,**sorti FAKEUSE;
 int totalwidth=dumpaction(NULL);
 
                while (totalwidth-->5) putchar(' ');
-               puts("Total Da Hr Mi\tStor\tDescription");
+               puts("Total Day Hr Mi Stor\tDescription");
                if (!(sorta=malloc(sizeof(*sorta)*hashtable_tot))) {
                        fprintf(ERRH1"malloc() of %d pointers"ERRNO1,ERRH2,hashtable_tot,ERRNO2);
                        exit(EXIT_FAILURE);
@@ -446,20 +451,20 @@ char *ce;
        storeone(what,length);
 }
 
-static void hit(time_t t)
+static void hit(time_t t,char *bufaction)
 {
 static time_t last=-1;
 static char bufbackup[sizeof(buf)];
 char *acts[ACTS_MAX],*s;
 int timetot,acti,i;
 
-       if (verbose) printf("hit: %ld: %s\n",t,buf+6);
+       if (verbose) printf("hit: %ld: %s\n",t,bufaction);
        if (last!=-1) {
                if (t<last) {
                        fprintf(ERRH1"Time goes backward"WHERE1,ERRH2,WHERE2);
                        t=last;
                        }
-               acts[0]=bufbackup+6;
+               acts[0]=bufbackup;
                acti=1;
                while ((s=strchr(acts[acti-1],'+'))) {
                        *s='\0';
@@ -473,7 +478,7 @@ int timetot,acti,i;
                for (i=0;i<acti;i++)
                        store(acts[i],calctime(timetot,i,acti));
                }
-       strcpy(bufbackup,buf);
+       strcpy(bufbackup,bufaction);
        last=t;
 }
 
@@ -481,10 +486,10 @@ int main(int argc,char **argv)
 {
 int optc;
 time_t basetime=-1,currtime;
-int hour,min;
+int hour,min,sec;
 
        pname=argv[0];
-       while ((optc=getopt_long(argc,argv,"b:pw:qusTtc:f:r:vhV",longopts,NULL))!=EOF) switch (optc) {
+       while ((optc=getopt_long(argc,argv,"b:pw:qusTtac:f:r:vhV",longopts,NULL))!=EOF) switch (optc) {
                
                case 'u':
                        sortby=SORT_NO;
@@ -498,6 +503,9 @@ int hour,min;
                case 't':
                        tree=1;
                        break;
+               case 'a':
+                       doaverage=1;
+                       break;
                case 'c':
                        if (iscondition(optarg))
                                fprintf(ERRH1"Condition \"%s\" already set!\n",ERRH2,optarg);
@@ -596,13 +604,17 @@ const char *days[]={"Ne","Po","Ut","St","Ct","Pa","So"};
 #undef WANTED
                        basetime=t;
                        store(MARK_DAY,0);
+                       lifetime_days++;
                        continue;
                        }
 
-               if (!isdigit(buf[0]) || !isdigit(buf[1]) || buf[2]!=':' || !isdigit(buf[3]) || !isdigit(buf[4]) || buf[5]!='-'
-                || sscanf(buf,"%d:%d-",&hour,&min)!=2
+               if (!(isdigit(buf[0]) && isdigit(buf[1]) && buf[2]==':' && isdigit(buf[3]) && isdigit(buf[4])
+                && (buf[5]=='-' || (buf[5]==':' && isdigit(buf[6]) && isdigit(buf[7]) && buf[8]=='-'))
+                     )
+                || (sec=0,sscanf(buf,(buf[5]=='-'?"%d:%d-":"%d:%d:%d-"),&hour,&min,&sec)!=2+(buf[5]==':'))
                 || hour<0 || hour>23
                 || min <0 || min >59
+                || sec <0 || sec >59
                    ) {
                        fprintf(ERRH1"Incorrect day-time \"%s\""WHERE1,ERRH2,buf,WHERE2);
                        exit(EXIT_FAILURE);
@@ -611,8 +623,8 @@ const char *days[]={"Ne","Po","Ut","St","Ct","Pa","So"};
                        fprintf(ERRH1"Day-time found but no basetime timestamp set"WHERE1,ERRH2,WHERE2);
                        exit(EXIT_FAILURE);
                        }
-               currtime=basetime+(hour*60+min)*60;
-               hit(currtime);
+               currtime=basetime+(hour*60+min)*60+sec;
+               hit(currtime,buf+(buf[5]=='-'?6:9));
                }
 
        if (!feof(fi) || ferror(fi))  {