diff options
-rw-r--r-- | build.c | 173 |
1 files changed, 109 insertions, 64 deletions
@@ -6,22 +6,49 @@ #include <sys/stat.h> #include <unistd.h> -#define USAGE "usage: %s file [...]\n", argv[0] +#define USAGE "usage: %s file [...]\n", name +#define d(...) do { if (dflag > 0) \ + fprintf(stderr, __VA_ARGS__); } while (0); +#define dd(...) do { if (dflag > 1) \ + fprintf(stderr, __VA_ARGS__); } while (0); +#define ddd(...) do { if (dflag > 2) \ + fprintf(stderr, __VA_ARGS__); } while (0); + +#define MAXBUF 1024 +#define MAXCMDS 32 +#define MAXCMD 1024 +#define MAXDEP 1024 +#define MAXTGT 64 extern char *optarg; extern int optind; +void cleandep(char **); +void cleantgt(char **); +char *nextdep(char **); + int main(int argc, char *argv[]) { - char *b, *bb, *bbb, buf[1024], *cmd[32], dep[1024], *t, *tt, tgt[64]; + char *b, buf[MAXBUF], *cmd[MAXCMDS], *d, *dep, *name, *tgt; FILE *fp; - int c, dflag, i, icmd, j, max; + int c, dflag, i, icmd, j; struct stat sb, ssb; + /* allocate memory */ + for (i = 0; i < MAXCMDS; i++) { + cmd[i] = malloc(MAXCMD*sizeof(char)); + if (!cmd[i]) err(1, "malloc"); + } + dep = malloc(MAXDEP*sizeof(char)); + if (!dep) err(1, "malloc"); + tgt = malloc(MAXTGT*sizeof(char)); + if (!dep) err(1, "malloc"); + tgt[0] = dep[0] = 0; /* process arguments */ + name = argv[0]; dflag = 0; while ((c = getopt(argc, argv, "d")) != -1) switch (c) { @@ -39,52 +66,41 @@ main(int argc, char *argv[]) return 1; } - /* allocate memory */ - for (i = 0; i < 32; i++) { - cmd[i] = malloc(1024*sizeof(char)); - if (!cmd[i]) err(1, "malloc"); - } - /* process each file */ for (i = icmd = 0; i < argc; i++, icmd = 0) { fp = fopen(argv[i], "r"); if (!fp) err(1, "fopen"); /* read line by line */ - for (j = 0; j < 20 && fgets(buf, sizeof(buf), fp); j++) { + for (j = 0; j < 20 && fgets(buf, MAXBUF, fp); j++) { buf[strcspn(buf, "\n")] = 0; /* parse line */ b = buf; for (b++; *b; b++) { - if (!(*(b+1) && *(b+2) && *(b+3))) continue; - if (!(*b == ' ' || *b == ' ')) continue; - /* command line */ - if (*(b+1) == '$' && *(b+2) == ' ') { - strncpy(cmd[icmd++],b+3,sizeof(buf)-1); + if (strncmp(b, " $ ", 3) == 0 + || strncmp(b, " $ ", 3) == 0) { + strncpy(cmd[icmd++],b+3,MAXBUF-1); /* find target */ for (b = b+3; *b; b++) { if (!(*b+1)) continue; if (*b != '>') continue; - strncpy(tgt,b+1,sizeof(tgt)-1); + strncpy(tgt,b+1,MAXTGT-1); } - if (dflag < 3) continue; - fprintf(stderr, - "%s: command line '%s'\n", + ddd("%s: command line '%s'\n", argv[i], buf); continue; } - /* depends line */ - if (*(b+1) == '%' && *(b+2) == ' ') { - strncpy(dep, b+3, sizeof(dep)-1); - if (dflag < 3) continue; - fprintf(stderr, - "%s: depends line '%s'\n", + /* dependency line */ + if (strncmp(b, " % ", 3) == 0 + || strncmp(b, " % ", 3) == 0) { + strncpy(dep, b+3, MAXDEP-1); + ddd("%s: dependency line '%s'\n", argv[i], buf); continue; } @@ -100,18 +116,15 @@ main(int argc, char *argv[]) goto build; /* compare source > target */ - for (t = tgt; *t; t++) - if (!isspace(*t)) break; - for (tt = t; *tt; tt++) - if (isspace(*tt)) { *tt = 0; break; } + cleantgt(&tgt); + dd("%s: target '%s'\n", argv[i], tgt); if (stat(argv[i], &sb)) err(1, argv[i]); - if (stat(t, &ssb)) - err(1, t); + if (stat(tgt, &ssb)) + err(1, tgt); if (sb.st_mtime > ssb.st_mtime) { - if (dflag) - fprintf(stderr, "%s: building because " - "%s is modified\n", argv[i], argv[i]); + d("%s: %s is modified, building\n", + argv[i], argv[i]); goto build; } @@ -119,33 +132,18 @@ main(int argc, char *argv[]) goto uptodate; /* compare dependencies > target */ - for (t = dep; *t; t++) - if (!isspace(*t)) break; - for (j = 0; t[j]; j++) { - if (isspace(t[j]) || t[j+1] == 0) { - tt = strdup(t); - tt[j+(t[j+1]==0)] = 0; - - if (dflag > 1) - fprintf(stderr, "%s: depend '%s'\n", - argv[i], tt); - - if (stat(tt, &sb)) - err(1, tt); - free(tt); - if (sb.st_mtime > ssb.st_mtime) { - if (dflag) - fprintf(stderr, - "%s: building because " - "%s is modified\n", - argv[i], tt); - goto build; - } - - for (; t[j]; j++) - if (!isspace(t[j])) break; - t += j; - j = 0; + cleandep(&dep); + while (d = nextdep(&dep)) { + dd("%s: depend '%s'\n", + argv[i], d); + + if (stat(d, &sb)) + err(1, d); + free(d); + if (sb.st_mtime > ssb.st_mtime) { + d("%s: %s is modified, building\n", + argv[i], d); + goto build; } } @@ -157,9 +155,9 @@ build: /* run commands */ buf[0] = 0; for (j = 0; j < icmd; j++) { - fprintf(stderr, "%s: %s\n", argv[i], cmd[j]); - strncat(buf, cmd[j], sizeof(buf)-1); - strncat(buf, "\n", sizeof(buf)-1); + fprintf(stderr, "$ %s\n", cmd[j]); + strncat(buf, cmd[j], MAXBUF-1); + strncat(buf, "\n", MAXBUF-1); } system(buf); @@ -167,3 +165,50 @@ done: fclose(fp); } } + +void +cleandep(char **dep) +{ + for (; **dep; (*dep)++) + if (!isspace(**dep)) break; +} + +void +cleantgt(char **tgt) +{ + char *t; + + for (; **tgt; (*tgt)++) + if (!isspace(**tgt)) break; + + for (t = *tgt; *t; t++) + if (isspace(*t) + || *t == '|' + || *t == '&' + || *t == ';' + || *t == ')') { + *t = 0; break; + } +} + +char * +nextdep(char **dep) +{ + char *d; + int i; + + for (i = 0; (*dep)[i]; i++) { + if (isspace((*dep)[i]) || (*dep)[i+1] == 0) { + d = strdup(*dep); + d[i+((*dep)[i+1]==0)] = 0; + + for (; (*dep)[i]; i++) + if (!isspace((*dep)[i])) break; + + (*dep) += i + ((*dep)[i+1]==0); + break; + } + } + + return d; +} |