jchvr@ihlpg.UUCP (VanRietschote) (04/29/86)
-- Wanna make your boss happy? Here is a program for him/her that can draw a limited PERT chart form some planning info in UNITY format. See manual page for an example. #-- cut here file=ppert.C /* ppert.c -*-update-version-*- ** HFVR VERSION=Tue Mar 18 13:03:01 1986 */ /* CAVEATS for modifiers: ** ------- --- ---------- ** the program will not work after the year 1994. ** the routines inttoweek,weektoint,incweek,decweek need to be ADAPTED ** ** some years do not have exactly 52 week. In that case ** the routines incweek and decweek need to be adjusted. ** if done the program should still work ok ** ** some work is never done. Suggestions for improvement ** can be found by scanning this text for TBS, feel free ** to add any good features. */ #include <stdio.h> #include <string.h> #include <pwd.h> #include <time.h> typedef enum {FALSE,TRUE} BOOL; /* global switches for command line */ int Aflag = 0 ; /* ALL flag */ int Iflag = 8 ; /* -I flag default=8 */ int Tflag = 12; /* -T flag default=12 */ char oflag[255]=""; /* oflag with name of output file */ int cflag = 1 ; /* increment for printing weeks */ int uflag = 1 ; /* TRUE if need uitloop */ int wflag = 1 ; /* TRUE if need warnings */ int lflag = 0 ; /* TRUE if long listing */ int iflag = 0 ; /* nr of item to print */ char isearch[255]=""; /* id to start printing */ int dflag = 0 ; /* debug TRUE or FALSE */ int sflag = 501; /* start week */ int nflag = 12 ; /* number of weeks to print */ int aflag = 0 ; /* TRUE if all entries should print */ char PERT[255]="pert" ; /* PERT input file */ char READY[] = "ready"; /* ready activity string */ char NAME[]="ppert"; /* program name for printing errors/warnings */ struct DEP { struct DEP *next; /* pointer to next dependor */ int nr; /* number of entry */ } ; #define IDLENGTH 16 #define STATUSLENGTH 6 #define STARTLENGTH 3 #define DURATIONLENGTH 3 #define AFTERLENGTH 255 #define ENDLENGTH 3 #define TITLELENGTH 32 struct ENTRY { /* milestone entry */ int printed; /* 1 if already printed */ int nr ; /* internal number */ char id[IDLENGTH+1] ; /* id of Dpert */ char status[STATUSLENGTH+1]; /* status of Dpert */ char start[STARTLENGTH+1]; /* start of Dpert */ int istart; /* int version of start */ char duration[DURATIONLENGTH+1]; /* duration of Dpert */ int iduration; /* int version of duration */ char after[AFTERLENGTH+1]; /* after of Dpert */ char end[ENDLENGTH+1]; /* end of Dpert */ int iend; /* int version of end */ char title[TITLELENGTH+1]; /* title of Dpert */ struct DEP *dependson; /* pointer to other entries */ } ; /* if an entry depends on items 2 3 and 4 then the pointer chain is ** entries[i].dependson --> @----------@ | nr=4 | |----------| | next-| | @-------|--@ | v @-----------@ | nr=3 | |-----------| | next-| | @-------|---@ | v @-----------@ | nr=2 | |-----------| | next=NULL| @-----------@ */ #define MAXENTRIES 999 struct ENTRY entries[MAXENTRIES]; int c; /* last char read */ int linenr; /* line number */ int nr; /* number of entries */ int totaldep; /* total number of dependencies per id */ FILE *fp; /* input file */ int errors; /* number of errors */ int warnings; /* number of warnings */ #define TAB 9 #define CR 10 #define SP 32 /* prentry: prints a whole entry */ prentry(i) int i; { struct DEP *after; printf("\n--ENTRY--\n"); printf("nr =%d\n",entries[i].nr); printf("id =%s\n",entries[i].id); printf("status =%s\n",entries[i].status); printf("start =%s\n",entries[i].start); printf("istart =%d\n",entries[i].istart); printf("duration =%s\n",entries[i].duration); printf("iduration=%d\n",entries[i].iduration); printf("after =%s\n",entries[i].after); printf("end =%s\n",entries[i].end); printf("iend =%d\n",entries[i].iend); printf("title =%s\n",entries[i].title); /* print dependson pointer chain */ after = entries[i].dependson; printf("after ="); while (after != NULL) { printf("%d ", after->nr); after = after->next; } printf("NULL\n"); }/*prentry*/ /* message: will print error/warning messages ** and keep count of them */ #define ERRSTATE 1 #define WARSTATE 0 message(status,line,string,extra) int status; int line; char string[]; char extra[]; { if (status==ERRSTATE) { errors++; fprintf(stderr,"\007%s: ",NAME); fprintf(stderr,"ERROR: "); fprintf(stderr,"at line %d: ",line); fprintf(stderr,"%s%s.\n",string,extra); } if ((wflag==1) && (status==WARSTATE)) { warnings++; fprintf(stderr,"\007%s: ",NAME); fprintf(stderr,"WARNING: "); fprintf(stderr,"at line %d: ",line); fprintf(stderr,"%s%s.\n",string,extra); } }/*message*/ /* ABORT: will print summary error/warning message and stop */ void ABORT() { fprintf(stderr,"\007%s: ABORTING: after %d errors and %d warnings.\n",NAME,errors,warnings); exit(1); }/*ABORT*/ /* get: will read 1 char and return its value ** EOF is returned if at end of file ** it will increment global var. linenr if CR is read */ int get(f) FILE *f; { int ch; ch=getc(f); if( ch==CR ) { linenr++; } return(ch); }/*get*/ /* usage: will scream usage message to user */ usage() { fprintf(stderr,"\007Usage: %s [-dTIocuwlivsnaA] [-f input]\n",NAME); fprintf(stderr,"Where: -d turns on debug mode\n"); fprintf(stderr," -T <length> to set printing length TITLE\n"); fprintf(stderr," -I <length> to set printing length ID\n"); fprintf(stderr," -o <file> to put updated pert in file\n"); fprintf(stderr," -c <int> sets week increment\n"); fprintf(stderr," -u turns off printing '....'\n"); fprintf(stderr," -w turns off printing of warnings\n"); fprintf(stderr," -l if long listing is needed\n"); fprintf(stderr," -i <item-id> to set item to print\n"); fprintf(stderr," -v prints version number and exit\n"); fprintf(stderr," -s <int> sets start week\n"); fprintf(stderr," -n <int> sets number of weeks to print\n"); fprintf(stderr," -a forces all not ready entries to be printed\n"); fprintf(stderr," -A forces all entries to be printed\n"); fprintf(stderr," -f <file> names input file\n"); }/*usage*/ /* readstring: will read characters in to array ** up til either EOF, CR, or endchar ** then the array is terminated with EOS (end-of-string) ** maxlength is the maximum length of array (counting the EOS) */ readstring(array,maxlength,name,endchar) char array[]; int maxlength; char name[]; int endchar; { int length; /* keeps track of where we are in array */ length = 0; array[length] = '\0'; while ((c != EOF) && (c != endchar) && (c != CR) && (length < maxlength) ) { array[length] = c; length++; array[length] = '\0'; c=get(fp); } /* ABORT if EOF is found after giving error message */ if (c==EOF) { message(ERRSTATE,linenr,"unexpected EOF after field ",name); ABORT(); } /* ABORT if separator was not found */ if (c==CR) { message(ERRSTATE,linenr,"missing separator after field ",name); } /* check if too long */ if ((c!=endchar) && (c!=CR)) { message(WARSTATE,linenr,name," field too long. Truncated"); } /* skip until endchar */ while ((c!=endchar) && (c!=EOF) && (c!=CR)) { c=get(fp); } /*skip past endchar */ c=get(fp); }/*readstring*/ readid(i) int i; { char tmp[IDLENGTH+1]; readstring(tmp,IDLENGTH,"id",TAB); (void)lookup(i,tmp,FALSE); /* must not be found */ strcpy(entries[i].id,tmp); }/*readid*/ readstatus(i) int i; { readstring(entries[i].status,STATUSLENGTH,"status",TAB); }/*readstatus*/ readstart(i) int i; { readstring(entries[i].start,STARTLENGTH,"start",TAB); }/*readstart*/ readduration(i) int i; { readstring(entries[i].duration,DURATIONLENGTH,"duration",TAB); }/*readduration*/ readafter(i) int i; { readstring(entries[i].after,AFTERLENGTH,"after",TAB); entries[i].dependson=NULL; }/*readafter*/ readend(i) int i; { readstring(entries[i].end,ENDLENGTH,"end",TAB); entries[i].iend = -1; }/*readend*/ readtitle(i) int i; { readstring(entries[i].title,TITLELENGTH,"title",TAB); }/*readtitle*/ /* skiptonextentry: skips to begin next line */ skiptonextentry() { while ( (c!=EOF) && (c!=CR) ) { c=get(fp); } if (c!=CR) { message(WARSTATE,linenr,"CR missing at end of file",""); } else { c=get(fp); /* skip past CR */ } }/*skiptonextentry*/ /* readentry: read a full entry from input file */ readentry(i) int i; /* number of entry */ { entries[i].nr=i; readid(i); readstatus(i); readstart(i); readduration(i); readafter(i); readend(i); readtitle(i); skiptonextentry(); }/*readentry*/ /* valstart: start should be either empty or in the range 0-953 ** also will fill in istart field */ valstart(i) int i; { int j; j=0; entries[i].istart=0; while ( (j<=STARTLENGTH) && (entries[i].start[j]!='\0') && (entries[i].start[j]>='0') && (entries[i].start[j]<='9') ) { entries[i].istart=entries[i].istart*10+(entries[i].start[j] - '0'); j++; } /* check if all string was [0-9] */ if (entries[i].start[j]!='\0') { message(ERRSTATE,i+1,"start should be empty or [0-9]{1,3}",""); } /* check range of start */ if ((entries[i].istart < 0) || (entries[i].istart > 953)) { message(ERRSTATE,i+1,"start out of range 0-953",""); } }/*valstart*/ /* valduration: duration should be filled in and > 0 ** also compute iduration */ valduration(i) int i; { int j; j=0; entries[i].iduration=0; /* check to see that duration is not empty */ if (entries[i].duration[0]=='\0') { message(ERRSTATE,i+1,"duration may not be empty",""); } while ( (j<=DURATIONLENGTH) && (entries[i].duration[j]!='\0') && (entries[i].duration[j]>='0') && (entries[i].duration[j]<='9') ) { entries[i].iduration=entries[i].iduration*10 + (entries[i].duration[j] - '0'); j++; } /* check if all string was [0-9] */ if (entries[i].duration[j]!='\0') { message(ERRSTATE,i+1,"duration should be [0-9]+",""); } /* check range of duration */ if ((entries[i].iduration < 0)) { message(ERRSTATE,i+1,"duration must be >= 0",""); } }/*valduration*/ /* valafter: checks that not both start and after are empty */ valafter(i) int i; { /* check that not both after and start or empty */ if ((entries[i].after[0]=='\0') && (entries[i].start[0]=='\0')) { message(ERRSTATE,i+1,"either start of after should be given",""); } }/*valafter*/ /*valend: if status=ready then end should be not empty */ valend(i) int i; { int j; /* check that if status=ready end is filled in */ if ((strcmp("ready",entries[i].status)==0) && (entries[i].end[0]=='\0') ) { message(ERRSTATE,i+1,"if status=ready then end should be filled in",""); return(0); } /* compute iend */ j=0; entries[i].iend=0; while ( (j<=ENDLENGTH) && (entries[i].end[j]!='\0') && (entries[i].end[j]>='0') && (entries[i].end[j]<='9') ) { entries[i].iend=entries[i].iend*10+(entries[i].end[j] - '0'); j++; } /* check if all string was [0-9] */ if (entries[i].end[j]!='\0') { message(ERRSTATE,i+1,"end should be empty or [0-9]{1,3}",""); } /* check range of end */ if ((entries[i].iend < 0) || (entries[i].iend > 953)) { message(ERRSTATE,i+1,"end out of range 0-953",""); } }/*valend*/ /* valid: check that id is unique so far */ valid(i) int i; { /* TBS */ }/*valid*/ /* valentry: validate that certain fields are correct ** and compute int versions */ valentry(i) int i; { valid(i); valstart(i); valduration(i); valafter(i); valend(i); }/*valentry*/ /* convweeks: to convert istart and iend to week numbers */ convweeks(i) int i; /* entry number */ { if (entries[i].istart != 0) entries[i].istart=inttoweek(entries[i].istart); if (entries[i].iend != 0) entries[i].iend =inttoweek(entries[i].iend); }/*convweeks*/ /* readdb: read all entries from the input file ** after checking that file can be read */ readdb() { fp = fopen(PERT, "r"); if (fp == NULL ) { fprintf(stderr,"\007%s: ERROR: cannot open %s. Aborting.\n",NAME,PERT); exit(1); } nr=0; linenr=1; c=get(fp); while ((nr <= MAXENTRIES) && (c != EOF)) { readentry(nr); valentry(nr); convweeks(nr); /* convert to weeknumber */ nr++; }/*while*/ if ( nr > MAXENTRIES ) { message(ERRSTATE,nr,"maximum number of entries reached. Rest is skipped",""); } fclose(fp); }/*readdb*/ /* getsearch: copy after string into search until EOS ~ or SP ** returns position of last char returned */ int getsearch(search,i,k) char search[]; /* for resulting string */ int i; /* index into entries */ int k; /* index into entries[i].after */ { int j; j=0; search[j]='\0'; while ((j<IDLENGTH) && (entries[i].after[k]!='\0') && (entries[i].after[k]!='~') && (entries[i].after[k]!=SP)) { search[j]=entries[i].after[k]; j++; k++; search[j]='\0'; } /* check for too long */ if ( (entries[i].after[k] != '\0') && (entries[i].after[k] != '~' ) && (entries[i].after[k] != SP ) ) { message(WARSTATE,i+1,"id in after field too long",""); /* skip to right separator */ while ((entries[i].after[k] != '\0') && (entries[i].after[k] != '~' ) && (entries[i].after[k] != SP ) ) { k++; }/*while*/ }/*fi*/ return(k); }/*getsearch*/ /* skipseparator: to skip past SP ~ or until EOS ** returns last position scanned */ int skipseparator(i,k) int i; /* index into entries */ int k; /* index into entries[i].after */ { while ((entries[i].after[k]!='\0') && ( (entries[i].after[k]==SP ) || (entries[i].after[k]=='~') ) ) { k++; } return(k); }/*skipseparator*/ /* lookup : returns entrynr where search=id */ int lookup(i,search,mustbefound) int i; /* current entry */ char search[]; /*id to look for */ BOOL mustbefound; /* (TRUE & !found) | (FALSE & found) ->err */ { int j; int found; j=0; found=0; while ((found == 0) && (j < nr)) { if ((strcmp(search,entries[j].id)) == 0) { found = 1; } else { j++; }/*fi*/ }/*while*/ if ( mustbefound && !(found) ) { message(ERRSTATE,i+1,"cannot find entry with id=",search); return(-1); } if ( !(mustbefound) && found ) { message(ERRSTATE,i+1,"double defined entry with id=",search); return(-1); } return(j); }/*lookup*/ /* computeentry: compute dependency for 1 entry */ computeentry(i) int i; /* index into entries */ { char search[IDLENGTH+1]; int k; int p; struct DEP *ptr; extern struct DEP *malloc(); k=0; entries[i].dependson = NULL; /* get all id's */ k=skipseparator(i,k); while (entries[i].after[k]!='\0') { k=getsearch(search,i,k); k=skipseparator(i,k); p=lookup(i,search,TRUE); /* if we found it then add to chain */ if ( p != -1) { ptr = malloc(sizeof(struct DEP)); if ( ptr == NULL ) { message(ERRSTATE,i+1,"Out of memory",""); ABORT(); } ptr->nr = p; ptr->next = entries[i].dependson; entries[i].dependson = ptr; } } }/*computeentry*/ /* compute: the dependency chain for all entries */ compute() { int i; for (i=0 ; i < nr ; i++) { computeentry(i); if (dflag) prentry(i); } }/*compute*/ /* checkerrors: ABORT if errors are present */ checkerrors() { if (errors!=0) { ABORT(); } }/*checkerrors*/ #define OFFSET 8000 /* inttoweek: convert integer to week MUST BE ADAPTED in 1994 */ int inttoweek(j) int j; /* integer > 0 */ { if (j <= 0 ) { message(ERRSTATE,nr,"week number must be > 0",""); return(OFFSET+1); } if (j >= 500) { return(OFFSET+j); /* 8501 8502 .. 8901 8902 .. 8953 */ } return(OFFSET+1000+j); /* 9001 9002 .. 9401 9402 .. 9453 */ }/*inttoweek*/ /* weektoint: convert week to integer MUST BE ADAPTED in 1994 */ int weektoint(week) int week; /* week > 0 */ { if (week <= 0) { message(ERRSTATE,nr,"program error",""); ABORT(); } if (week < OFFSET+1000) { return(week - OFFSET); } return(week - OFFSET - 1000); }/*weektoint*/ /* decweek: decrement week with 1, MUST BE ADAPTED TO YEARS */ int decweek(week) int week; { switch(week) { /* 1985 */ case 8600 : return(8552) ; break; case 8700 : return(8652) ; break; case 8800 : return(8752) ; break; case 8900 : return(8852) ; break; /* 1990 */ case 9000 : return(8952) ; break; case 9100 : return(9052) ; break; case 9200 : return(9152) ; break; case 9300 : return(9252) ; break; case 9400 : return(9352) ; break; case 9500 : return(9452) ; break; } return(week-1); }/*decweek*/ /* incweek: increment week with 1, MUST BE ADAPTED TO YEARS */ int incweek(week) int week; { switch(week) { /* 1985 */ case 8552 : return(8601); break; case 8652 : return(8701); break; case 8752 : return(8801); break; case 8852 : return(8901); break; case 8952 : return(9001); break; /* 1990 */ case 9052 : return(9101); break; case 9152 : return(9201); break; case 9252 : return(9301); break; case 9352 : return(9401); break; case 9452 : return(9501); break; } return(week+1); }/*incweek*/ /* nextweek: incrments week with cflag */ int nextweek(week) int week; { return(addweek(week,cflag)); }/*nextweek*/ /*addweek: adds two weeks, for efficiency make start > weeks */ int addweek(start,weeks) int start; int weeks; { int i; if (weeks < 0) { for ( i = -1 ; i >= weeks ; i--) { start=decweek(start); }/*for*/ return(start); }/*fi*/ for ( i = 1 ; i <= weeks ; i++) { start=incweek(start); } return(start); }/*addweek*/ /*prweeks: print row of weeknumbers */ prweeks(startweek,weeks) int startweek; /* week to start printing */ int weeks; /* number of weeks to print */ { int i; int j; int week; char temp[7]; char temp1[7]; char month[7]; extern int d2d(); /* first print names of months */ for (j=1 ; j <= Iflag+1 ; j++) printf(" "); for (j=1 ; j <= Tflag+1 ; j++) printf(" "); printf(" "); /*STR */ printf(" "); /*END */ week=startweek; strcpy(month,""); for (i=1 ; i <= weeks ; i=i+cflag) { sprintf(temp1,"%3dMon",weektoint(week)); /* temp1 = "week" + "Mon" */ d2d("-%j%a",temp1,"+%h ",temp); if ( (strcmp(temp,month) != 0 )) { strcpy(month,temp); printf("%s",month); } else { printf(" "); }/*fi*/ week=nextweek(week); }/*for*/ printf("\n"); /* print leading spaces with room for id title end */ printf("ID"); for (j=strlen("ID") ; j <= Iflag ; j++) printf(" "); printf("TITLE"); for (j=strlen("TITLE") ; j <= Tflag ; j++) printf(" "); printf("STR "); printf("END "); /* print week numbers */ week=startweek; for (i=1 ; i <= weeks ; i=i+cflag) { printf("%.3d ",weektoint(week)); week=nextweek(week); } printf("\n"); }/*prweeks*/ int max(i,j) int i; int j; { if ( i > j ) return (i); return(j); }/*max*/ /*maxafter: return maximum of end dates all dependencies */ int maxafter(i) int i; { int max1; int max2; struct DEP *ptr; max1 = -1; ptr = entries[i].dependson; while ( ptr != NULL ) { max2=endwk(ptr->nr); max1=max(max1,max2); ptr = ptr->next; } return(max1); }/*maxafter*/ /* startwk: returns start, if start is given then return istart ** else start=maximum of end of all dependencies + 1 */ int startwk(i) int i; { /* check for circular dependency */ totaldep++; if (totaldep > 3*MAXENTRIES) { message(ERRSTATE,i,"entry (indirectly) dependent on itself",""); ABORT(); } if ( entries[i].start[0] != '\0') { return(entries[i].istart); } return(addweek(maxafter(i),1)); }/*start*/ /* endwk: returns end of action which is iend if status=ready ** or end=start+duration-1 */ int endwk(i) int i; { if ( strcmp("ready",entries[i].status)==0) { return(entries[i].iend); } return(addweek(startwk(i),entries[i].iduration - 1)); }/*end*/ /*prid: print id */ prid(i,notbefore,START,WEEKS) int i; /* number of entry to print */ int notbefore; /* week before whicvh we do not need to be ready */ int START; /* week where to start printing */ int WEEKS; /* number of weeks to print */ { struct DEP *after; char format[20]; /* to store printf format */ int endweek; /* week when action is done */ int startweek; /* week when action starts */ int week; /* current week we are working on */ int last; /* last week for which to do printing */ int j; totaldep=0; /* set total number of dependencies */ endweek=endwk(i); startweek=startwk(i); week=START; last=addweek(START,WEEKS-1); /* check to see if need to print */ /* do not print items that have already been printed */ /* unless lflag is set */ /* then set it to printed */ if ( (lflag == 0) && (entries[i].printed)) return(0); entries[i].printed=1; /* Aflag means always print */ if (Aflag == 1) goto ok; /* always print if in window */ if ( !(((endweek < START) || (startweek > last))) ) goto ok; /* now all cases outside window */ /* if aflag set but not ready then print it */ if ((aflag == 1) && (strcmp(READY,entries[i].status) != 0) ) goto ok; /*else do not print */ return(0); ok: /* to print */ /* first print all dependencies */ after=entries[i].dependson; while ( after != NULL ) { prid(after->nr,startweek,START,WEEKS); after = after->next; } /* print id */ sprintf(format,"%%-%d.%ds ",Iflag,Iflag); printf(format,entries[i].id); /* print title */ sprintf(format,"%%-%d.%ds ",Tflag,Tflag); printf(format,entries[i].title); /* print begin except for entries with iduration=0*/ if (entries[i].iduration==0) { printf(" "); } else { printf("%3d ",weektoint(startweek)); } /* print end */ printf("%3d ",weektoint(endweek)); /* print all weeks before startweek */ while ( (week <= last) && ( week < startweek )) { printf(" "); week=nextweek(week); } /* print all working weeks */ while ( (week <= last) && ( week <= endweek )) { printf("----"); week=nextweek(week); } /* print all uitloop weeks if uflag is set */ while ( (week <= last) && ( week < notbefore )) { if (uflag==1) { printf("...."); } else { printf(" "); }/*fi*/ week=nextweek(week); } printf("\n"); }/*prid*/ /*clearprinted: clear all printed fields for entries */ clearprinted() { int i; for (i = 0 ; i < nr ; i++ ) entries[i].printed=0; }/*clearprinted*/ /*prsheet: print pertplan sheet */ prsheet(startweek,weeks) int startweek; /* week to start printing */ int weeks; /* number of weeks to print */ { clearprinted(); prweeks(startweek,weeks); /* if isearch not set then use default */ /* else find item and print it */ if (isearch[0] != '\0') iflag=lookup(nr,isearch); checkerrors(); prid(iflag,0,startweek,weeks); }/*prsheet*/ /* checkoptions: to check legal values for options */ checkoptions() { /* Iflag must be >= 2 (ID) */ if (Iflag < 2) { message(WARSTATE,0,"-I option must be >= 2. Smallest taken",""); Iflag = 2; } /* Tflag must be >=5 (TITLE) */ if (Tflag < 5) { message(WARSTATE,0,"-T option must be >= 5. Smallest taken",""); Tflag = 5; } /* week increment must be > 0 */ if (cflag <= 0) { message(WARSTATE,0,"-c option must be > 0. Default taken",""); cflag=1; } /* start week must be >= 0 */ if (sflag < 0) { message(WARSTATE,0,"-s option must be >= 0. Default taken",""); sflag=501; } sflag=inttoweek(sflag); /* conmver to week number */ /* number of weeks must be > 0 */ if (nflag <= 0 ) { message(WARSTATE,0,"-n option must be > 0. Default taken",""); nflag=12; } }/*checkoptions*/ /*parseswitches: to parse all switches */ parseswitches(argc,argv) int argc; char *argv[]; { int ch; extern char *optarg; extern int optind; int err = 0; while ((ch=getopt(argc,argv,"AT:I:lduwao:c:s:f:n:vVi:")) != EOF) { switch (ch) { case 'A' : Aflag=1; aflag=1 ; break; case 'T' : sscanf(optarg,"%d",&Tflag); break; case 'I' : sscanf(optarg,"%d",&Iflag); break; case 'l' : lflag=1; break; case 'd' : dflag=1; break; case 'u' : uflag=0; break; case 'w' : wflag=0; break; case 'a' : aflag=1; break; case 'o' : sscanf(optarg,"%s",oflag); break; case 'c' : sscanf(optarg,"%d",&cflag); break ; case 's' : sscanf(optarg,"%d",&sflag); break; case 'f' : sscanf(optarg,"%s",PERT); break; case 'n' : sscanf(optarg,"%d",&nflag); break; case 'v' : case 'V' : printf("%s: version 1.01\n",NAME); exit(0); break; case 'i' : sscanf(optarg,"%s",isearch); break; case '?' : err++; break; }/*switch*/ }/*while*/ checkoptions(); if (err) { usage(); exit(1); } if (dflag) printf("Options: I=%d,T=%d,A=%d,o=%s,c=%d,u=%d,w=%d,l=%d,d=%d,a=%d,s=%d,n=%d,f=%s,i=%s\n",Iflag,Tflag,Aflag,oflag,cflag,uflag,wflag,lflag,dflag,aflag,sflag,nflag,PERT,isearch); }/*parseswitches*/ /* setsflag: set sflag to start of item with nr=iflag ** if sflag is still set to default. Do this by finding the ** first week in which an activity leading to iflag is started */ setsflag(id) { /* TBS */ }/*setsflag*/ /*proutput: to print updated unity-format pert if oflag != "" */ proutput() { int i; /* check if we must perform */ if ( oflag[0] == '\0' ) { return(0); } /* open file to be used for output */ fp = fopen(oflag,"w"); if (fp == NULL) { message(ERRSTATE,0,"cannot open output file: ",oflag); ABORT(); } /* print all items */ for ( i=0 ; i < nr ; i++ ) { fprintf(fp,"%s\t",entries[i].id); fprintf(fp,"%d\t",weektoint(startwk(i))); fprintf(fp,"%d\n",weektoint(endwk(i))); } fclose(fp); }/*proutput*/ /* log: to output who uses when the program */ log() { struct passwd *ptr; extern struct passwd *getpwnam(); char name[50]; extern long time(); extern struct tm *localtime(); struct tm *local; long seconds; /* see if me */ if ( strcmp("hvrietsc",getenv("LOGNAME")) == 0 ) return(0); /* get time and date */ seconds = time(0); local = localtime(&seconds); /* open log file */ ptr = getpwnam("hvrietsc"); /* name=~hvrietsc/rje/.PPERT */ if (ptr==NULL) return; strcpy(name,ptr->pw_dir); strcat(name,"/rje/.PPERT"); fp = fopen(name,"a"); if (fp != NULL) { fprintf(fp,"%s\t%.2d%.2d%.2d\t%.2d:%.2d:%.2d\n",getenv("LOGNAME") ,local->tm_year ,local->tm_mon+1 ,local->tm_mday ,local->tm_hour ,local->tm_min ,local->tm_sec); } fclose(fp); }/*log*/ init(argc,argv) int argc; char *argv[]; { errors=0; warnings=0; log(); parseswitches(argc,argv); readdb(); checkerrors(); compute(); checkerrors(); setsflag(iflag); prsheet(sflag,nflag); checkerrors(); proutput(); checkerrors(); }/*init*/ main(argc,argv) int argc; char *argv[]; { init(argc,argv); exit(0); }/*main*/