aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build.c173
1 files changed, 109 insertions, 64 deletions
diff --git a/build.c b/build.c
index 6af16f0..6817b62 100644
--- a/build.c
+++ b/build.c
@@ -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;
+}