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