1 static char *sccsid = "@(#)main.c 4.4 (Berkeley) 82/10/11"; 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 212 213 #ifdef unix 214 intrupt() 215 { 216 struct varblock *varptr(); 217 char *p; 218 TIMETYPE exists(); 219 220 if(okdel && !noexflag && !touchflag && 221 (p = varptr("@")->varval) && exists(p)>0 && !isprecious(p) ) 222 { 223 fprintf(stderr, "\n*** %s removed.", p); 224 unlink(p); 225 } 226 227 if(junkname[0]) 228 unlink(junkname); 229 fprintf(stderr, "\n"); 230 exit(2); 231 } 232 233 234 235 236 isprecious(p) 237 char *p; 238 { 239 register struct lineblock *lp; 240 register struct depblock *dp; 241 register struct nameblock *np; 242 243 if(np = srchname(".PRECIOUS")) 244 for(lp = np->linep ; lp ; lp = lp->nxtlineblock) 245 for(dp = lp->depp ; dp ; dp = dp->nxtdepblock) 246 if(! unequal(p, dp->depname->namep)) 247 return(YES); 248 249 return(NO); 250 } 251 252 253 enbint(k) 254 int (*k)(); 255 { 256 if(sigivalue == 0) 257 signal(SIGINT,k); 258 if(sigqvalue == 0) 259 signal(SIGQUIT,k); 260 } 261 #endif 262 263 extern char *builtin[]; 264 265 char **linesptr = builtin; 266 267 FILE * fin; 268 int firstrd = 0; 269 270 271 rddescf(descfile) 272 char *descfile; 273 { 274 FILE * k; 275 276 /* read and parse description */ 277 278 if( !firstrd++ ) 279 { 280 if( !noruleflag ) 281 rdd1( (FILE *) NULL); 282 283 #ifdef pwb 284 { 285 char *nlog, s[100]; 286 nlog = logdir(); 287 if ( (k=fopen( concat(nlog,"/makecomm",s), "r")) != NULL) 288 rdd1(k); 289 else if ( (k=fopen( concat(nlog,"/Makecomm",s), "r")) != NULL) 290 rdd1(k); 291 292 if ( (k=fopen("makecomm", "r")) != NULL) 293 rdd1(k); 294 else if ( (k=fopen("Makecomm", "r")) != NULL) 295 rdd1(k); 296 } 297 #endif 298 299 } 300 if(! unequal(descfile, "-")) 301 return( rdd1(stdin) ); 302 303 if( (k = fopen(descfile,"r")) != NULL) 304 return( rdd1(k) ); 305 306 return(1); 307 } 308 309 310 311 312 rdd1(k) 313 FILE * k; 314 { 315 extern int yylineno; 316 extern char *zznextc; 317 318 fin = k; 319 yylineno = 0; 320 zznextc = 0; 321 322 if( yyparse() ) 323 fatal("Description file error"); 324 325 if(fin != NULL) 326 fclose(fin); 327 328 return(0); 329 } 330 331 printdesc(prntflag) 332 int prntflag; 333 { 334 struct nameblock *p; 335 struct depblock *dp; 336 struct varblock *vp; 337 struct dirhdr *od; 338 struct shblock *sp; 339 struct lineblock *lp; 340 341 #ifdef unix 342 if(prntflag) 343 { 344 printf("Open directories:\n"); 345 for (od = firstod; od; od = od->nxtopendir) 346 printf("\t%d: %s\n", od->dirfc->dd_fd, od->dirn); 347 } 348 #endif 349 350 if(firstvar != 0) printf("Macros:\n"); 351 for(vp = firstvar; vp ; vp = vp->nxtvarblock) 352 printf("\t%s = %s\n" , vp->varname , vp->varval); 353 354 for(p = firstname; p; p = p->nxtnameblock) 355 { 356 printf("\n\n%s",p->namep); 357 if(p->linep != 0) printf(":"); 358 if(prntflag) printf(" done=%d",p->done); 359 if(p==mainname) printf(" (MAIN NAME)"); 360 for(lp = p->linep ; lp ; lp = lp->nxtlineblock) 361 { 362 if( dp = lp->depp ) 363 { 364 printf("\n depends on:"); 365 for(; dp ; dp = dp->nxtdepblock) 366 if(dp->depname != 0) 367 printf(" %s ", dp->depname->namep); 368 } 369 370 if(sp = lp->shp) 371 { 372 printf("\n commands:\n"); 373 for( ; sp!=0 ; sp = sp->nxtshblock) 374 printf("\t%s\n", sp->shbp); 375 } 376 } 377 } 378 printf("\n"); 379 fflush(stdout); 380 } 381