1 static char *sccsid = "@(#)main.c 4.2 (Berkeley) 82/04/20"; 2 # include "defs" 3 /* 4 command make to update programs. 5 Flags: 'd' print out debugging comments 6 'p' print out a version of the input graph 7 's' silent mode--don't print out commands 8 'f' the next argument is the name of the description file; 9 "makefile" is the default 10 'i' ignore error codes from the shell 11 'S' stop after any command fails (normally do parallel work) 12 'n' don't issue, just print, commands 13 't' touch (update time of) files but don't issue command 14 'q' don't do anything, but check if object is up to date; 15 returns exit code 0 if up to date, -1 if not 16 */ 17 18 struct nameblock *mainname = NULL; 19 struct nameblock *firstname = NULL; 20 struct lineblock *sufflist = NULL; 21 struct varblock *firstvar = NULL; 22 struct pattern *firstpat = NULL; 23 struct dirhdr *firstod = NULL; 24 25 #include <signal.h> 26 int sigivalue = 0; 27 int sigqvalue = 0; 28 int waitpid = 0; 29 30 int dbgflag = NO; 31 int prtrflag = NO; 32 int silflag = NO; 33 int noexflag = NO; 34 int keepgoing = NO; 35 int noruleflag = NO; 36 int touchflag = NO; 37 int questflag = NO; 38 int ndocoms = NO; 39 int ignerr = NO; /* default is to stop on error */ 40 int okdel = YES; 41 int inarglist; 42 #ifdef pwb 43 char *prompt = ">"; /* other systems -- pick what you want */ 44 #else 45 char *prompt = ""; /* other systems -- pick what you want */ 46 #endif 47 int nopdir = 0; 48 char junkname[20]; 49 char funny[128]; 50 51 main(argc,argv) 52 int argc; 53 char *argv[]; 54 { 55 register struct nameblock *p; 56 int i, j; 57 int descset, nfargs; 58 TIMETYPE tjunk; 59 char c, *s; 60 static char onechar[2] = "X"; 61 #ifdef unix 62 int intrupt(); 63 64 65 66 #endif 67 68 #ifdef METERFILE 69 meter(METERFILE); 70 #endif 71 72 descset = 0; 73 74 funny['\0'] = (META | TERMINAL); 75 for(s = "=|^();&<>*?[]:$`'\"\\\n" ; *s ; ++s) 76 funny[*s] |= META; 77 for(s = "\n\t :;&>|" ; *s ; ++s) 78 funny[*s] |= TERMINAL; 79 80 81 inarglist = 1; 82 for(i=1; i<argc; ++i) 83 if(argv[i]!=0 && argv[i][0]!='-' && eqsign(argv[i])) 84 argv[i] = 0; 85 86 setvar("$","$"); 87 inarglist = 0; 88 89 for(i=1; i<argc; ++i) 90 if(argv[i]!=0 && argv[i][0]=='-') 91 { 92 for(j=1 ; (c=argv[i][j])!='\0' ; ++j) switch(c) 93 { 94 case 'd': 95 dbgflag = YES; 96 break; 97 98 case 'p': 99 prtrflag = YES; 100 break; 101 102 case 's': 103 silflag = YES; 104 break; 105 106 case 'i': 107 ignerr = YES; 108 break; 109 110 case 'S': 111 keepgoing = NO; 112 break; 113 114 case 'k': 115 keepgoing = YES; 116 break; 117 118 case 'n': 119 noexflag = YES; 120 break; 121 122 case 'r': 123 noruleflag = YES; 124 break; 125 126 case 't': 127 touchflag = YES; 128 break; 129 130 case 'q': 131 questflag = YES; 132 break; 133 134 case 'f': 135 if(i >= argc-1) 136 fatal("No description argument after -f flag"); 137 if( rddescf(argv[i+1]) ) 138 fatal1("Cannot open %s", argv[i+1]); 139 argv[i+1] = 0; 140 ++descset; 141 break; 142 143 default: 144 onechar[0] = c; /* to make lint happy */ 145 fatal1("Unknown flag argument %s", onechar); 146 } 147 148 argv[i] = 0; 149 } 150 151 if( !descset ) 152 #ifdef unix 153 if( rddescf("makefile") ) rddescf("Makefile"); 154 #endif 155 #ifdef gcos 156 rddescf("makefile"); 157 #endif 158 159 if(prtrflag) printdesc(NO); 160 161 if( srchname(".IGNORE") ) ++ignerr; 162 if( srchname(".SILENT") ) silflag = 1; 163 if(p=srchname(".SUFFIXES")) sufflist = p->linep; 164 if( !sufflist ) fprintf(stderr,"No suffix list.\n"); 165 166 #ifdef unix 167 sigivalue = (int) signal(SIGINT, SIG_IGN) & 01; 168 sigqvalue = (int) signal(SIGQUIT, SIG_IGN) & 01; 169 enbint(intrupt); 170 #endif 171 172 nfargs = 0; 173 174 for(i=1; i<argc; ++i) 175 if((s=argv[i]) != 0) 176 { 177 if((p=srchname(s)) == 0) 178 { 179 p = makename(s); 180 } 181 ++nfargs; 182 doname(p, 0, &tjunk); 183 if(dbgflag) printdesc(YES); 184 } 185 186 /* 187 If no file arguments have been encountered, make the first 188 name encountered that doesn't start with a dot 189 */ 190 191 if(nfargs == 0) 192 if(mainname == 0) 193 fatal("No arguments or description file"); 194 else { 195 doname(mainname, 0, &tjunk); 196 if(dbgflag) printdesc(YES); 197 } 198 199 exit(0); 200 } 201 202 203 204 #ifdef unix 205 intrupt() 206 { 207 struct varblock *varptr(); 208 char *p; 209 TIMETYPE exists(); 210 211 if(okdel && !noexflag && !touchflag && 212 (p = varptr("@")->varval) && exists(p)>0 && !isprecious(p) ) 213 { 214 fprintf(stderr, "\n*** %s removed.", p); 215 unlink(p); 216 } 217 218 if(junkname[0]) 219 unlink(junkname); 220 fprintf(stderr, "\n"); 221 exit(2); 222 } 223 224 225 226 227 isprecious(p) 228 char *p; 229 { 230 register struct lineblock *lp; 231 register struct depblock *dp; 232 register struct nameblock *np; 233 234 if(np = srchname(".PRECIOUS")) 235 for(lp = np->linep ; lp ; lp = lp->nxtlineblock) 236 for(dp = lp->depp ; dp ; dp = dp->nxtdepblock) 237 if(! unequal(p, dp->depname->namep)) 238 return(YES); 239 240 return(NO); 241 } 242 243 244 enbint(k) 245 int (*k)(); 246 { 247 if(sigivalue == 0) 248 signal(SIGINT,k); 249 if(sigqvalue == 0) 250 signal(SIGQUIT,k); 251 } 252 #endif 253 254 extern char *builtin[]; 255 256 char **linesptr = builtin; 257 258 FILE * fin; 259 int firstrd = 0; 260 261 262 rddescf(descfile) 263 char *descfile; 264 { 265 FILE * k; 266 267 /* read and parse description */ 268 269 if( !firstrd++ ) 270 { 271 if( !noruleflag ) 272 rdd1( (FILE *) NULL); 273 274 #ifdef pwb 275 { 276 char *nlog, s[100]; 277 nlog = logdir(); 278 if ( (k=fopen( concat(nlog,"/makecomm",s), "r")) != NULL) 279 rdd1(k); 280 else if ( (k=fopen( concat(nlog,"/Makecomm",s), "r")) != NULL) 281 rdd1(k); 282 283 if ( (k=fopen("makecomm", "r")) != NULL) 284 rdd1(k); 285 else if ( (k=fopen("Makecomm", "r")) != NULL) 286 rdd1(k); 287 } 288 #endif 289 290 } 291 if(! unequal(descfile, "-")) 292 return( rdd1(stdin) ); 293 294 if( (k = fopen(descfile,"r")) != NULL) 295 return( rdd1(k) ); 296 297 return(1); 298 } 299 300 301 302 303 rdd1(k) 304 FILE * k; 305 { 306 extern int yylineno; 307 extern char *zznextc; 308 309 fin = k; 310 yylineno = 0; 311 zznextc = 0; 312 313 if( yyparse() ) 314 fatal("Description file error"); 315 316 if(fin != NULL) 317 fclose(fin); 318 319 return(0); 320 } 321 322 printdesc(prntflag) 323 int prntflag; 324 { 325 struct nameblock *p; 326 struct depblock *dp; 327 struct varblock *vp; 328 struct dirhdr *od; 329 struct shblock *sp; 330 struct lineblock *lp; 331 332 #ifdef unix 333 if(prntflag) 334 { 335 printf("Open directories:\n"); 336 for (od = firstod; od; od = od->nxtopendir) 337 printf("\t%d: %s\n", od->dirfc->dd_fd, od->dirn); 338 } 339 #endif 340 341 if(firstvar != 0) printf("Macros:\n"); 342 for(vp = firstvar; vp ; vp = vp->nxtvarblock) 343 printf("\t%s = %s\n" , vp->varname , vp->varval); 344 345 for(p = firstname; p; p = p->nxtnameblock) 346 { 347 printf("\n\n%s",p->namep); 348 if(p->linep != 0) printf(":"); 349 if(prntflag) printf(" done=%d",p->done); 350 if(p==mainname) printf(" (MAIN NAME)"); 351 for(lp = p->linep ; lp ; lp = lp->nxtlineblock) 352 { 353 if( dp = lp->depp ) 354 { 355 printf("\n depends on:"); 356 for(; dp ; dp = dp->nxtdepblock) 357 if(dp->depname != 0) 358 printf(" %s ", dp->depname->namep); 359 } 360 361 if(sp = lp->shp) 362 { 363 printf("\n commands:\n"); 364 for( ; sp!=0 ; sp = sp->nxtshblock) 365 printf("\t%s\n", sp->shbp); 366 } 367 } 368 } 369 printf("\n"); 370 fflush(stdout); 371 } 372