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