home *** CD-ROM | disk | FTP | other *** search
- /*
- * Do the actual making for make
- */
-
- #include <stdio.h>
-
- #ifdef unix
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/errno.h>
- #endif
-
- #include "h.h"
-
- #ifdef MCH_AMIGA
-
- /* test if timestamp is NULL */
-
- null_time(t) TimeStamp *t;
- { return !(t->t[0] || t->t[1] || t->t[2]);
- }
-
- /* cmp_time(t1,t2) - compare two timestamps
-
- returns >0 if (t1 > t2)
- 0 if (t1 = t2)
- <0 if (t1 < t2)
- */
-
- cmp_time(t1,t2) TimeStamp *t1,*t2;
- { long l;
- if (l = t1->t[0] - t2->t[0]) return l;
- if (l = t1->t[1] - t2->t[1]) return l;
- return t1->t[2]-t2->t[2];
- }
-
- TimeStamp time_zero = { 0,0,0 }; /* a null timestamp */
- TimeStamp time_one = { 0,0,1 }; /* a mostly null timestamp */
-
- #endif
-
- /* DJ notes -
- is the idea of alternate shells applicaple here? Do we want this make
- to support things like ARexx?
- Currently there's no support for such in the code...
- */
-
- /*
- * Exec a shell that returns exit status correctly (/bin/esh).
- */
- int
- dosh(string, shell)
- char * string;
- char * shell;
- { return xsystem(string);
- }
-
-
- /*
- * Do commands to make a target
- */
- void
- docmds1(np, lp)
- struct name *np;
- struct line *lp;
- {
- bool ssilent;
- bool signore;
- int estat;
- register char *q;
- register char *p;
- char *shell;
- register struct cmd *cp;
-
- /* shell code is commented out for now */
- #if 0
- if (*(shell = getmacro("SHELL")) == '\0') /* if no shell defined */
- #ifdef unix
- shell = "/bin/sh"; /* use default shell */
- #else
- shell = NULL; /* use normal shell */
- #endif
- #endif
-
- for (cp = lp->l_cmd; cp; cp = cp->c_next) /* for each command in line */
- {
- strcpy(str1, cp->c_cmd); /* get command string */
- expand(str1); /* expand macros */
- q = str1; /* string pointer */
- ssilent = silent; /* get 'silent' flag */
- signore = ignore; /* get 'ignore' flag */
- while ((*q == '@') || (*q == '-'))
- { if (*q == '@') /* Specific silent */
- ssilent = TRUE; /* silence this command */
- else /* Specific ignore */
- signore = TRUE; /* ignore return code */
- q++; /* Not part of the command */
- }
-
- if (!domake) ssilent = 0; /* not silent if no make */
- if (!ssilent) fputs(" ", stdout); /* put out a tab */
-
- for (p=q; *p; p++)
- { if (*p == '\n' && p[1] != '\0') /* if a carriage return */
- { *p = ' '; /* make it a space */
- if (!ssilent) /* and if not silent */
- fputs("\\\n", stdout); /* print a slash */
- }
- else if (!ssilent) /* if not silent */
- putchar(*p); /* print the character */
- }
- if (!ssilent) /* if not silent */
- putchar('\n'); /* print a newline */
-
- if (!domake) return; /* return if pretending */
-
- /* Get the shell to execute it */
- if ((estat = dosh(q, shell)) != 0) /* if an error code */
- {
-
- /* add some more status stuff in here, like 'Interrupted', etc. */
-
- if (estat == -1) /* -1 = couldn't execute */
- fatal("Couldn't execute %s", shell);
- else
- { printf("%s: Error code %d", myname, estat);
- if (signore) /* if ignore command return */
- fputs(" (Ignored)\n", stdout); /* then indicate so */
- else /* otherwise */
- { putchar('\n'); /* newline */
- if (!(np->n_flag & N_PREC)) /* delete target file ?? */
- if (unlink(np->n_name) == 0)
- printf("%s: '%s' removed.\n", myname, np->n_name);
- exit(estat);
- }
- }
- }
- }
- }
-
- docmds(np)
- struct name *np;
- {
- register struct line *lp;
-
- for (lp = np->n_line; lp; lp = lp->l_next) /* for each line in the entry */
- docmds1(np, lp); /* do the command */
- }
-
-
- /*
- * Get the modification time of a file. If the first
- * doesn't exist, it's modtime is set to 0.
- */
- void
- modtime(np)
- struct name * np;
- {
- #ifdef unix
- struct stat info;
- int fd;
-
-
- if (stat(np->n_name, &info) < 0)
- {
- if (errno != ENOENT)
- fatal("Can't open %s; error %d", np->n_name, errno);
-
- np->n_time = 0L;
- }
- else
- np->n_time = info.st_mtime;
- #endif
- #ifdef MCH_AMIGA
- { if (!GetFileDate(np->n_name,&np->n_time))
- { if (IoErr()==205) np->n_time = time_zero;
- else fatal("Can't get date for file %s", np->n_name);
- }
- }
- #endif
- }
-
- /*
- * Update the mod time of a file to now.
- */
- void
- touch(np)
- struct name * np;
- {
- char c;
- int fd;
-
-
- if (!domake || !silent)
- printf(" touch(%s)\n", np->n_name);
-
- if (domake)
- {
- #ifdef unix
- long a[2];
-
- a[0] = a[1] = time(0);
- if (utime(np->n_name, &a[0]) < 0)
- printf("%s: '%s' not touched - non-existant\n",
- myname, np->n_name);
- #endif
- #ifdef MCH_AMIGA
- /* insert a SetFileDate function here */
- #endif
- }
- }
-
- /* from PAMAKE */
-
- #if 0
-
- /*
- * Clear the dynamic dep flag for all deps of this target,
- * in case this dep is used again for another target
- */
-
- void cleardynflag(np)
- struct name *np;
- { register struct depend *dp;
- register struct line *lp;
-
- for (lp = np->n_line; lp; lp = lp->l_next)
- for (dp = lp->l_dep; dp; dp = dp->d_next)
- dp->d_name->n_flag &= ~N_DYND;
- }
-
- /*
- * Display the timestamp
- */
- void dodisp(name,t)
- char *name;
- time_t t; /* fix */
- {
- if (t < 10)
- printf("... %s Timestamp %ld\n",name,t);
- else
- printf("... %s Timestamp %s",name,ctime(&t));
- }
- #endif
-
- /*
- * Recursive routine to make a target.
- */
- int make(np, level)
- struct name *np; /* name pointer */
- int level; /* how many levels down */
- { register struct depend *dp; /* dependancy */
- register struct line *lp;
- register struct depend *qdp;
- TimeStamp dtime;
- bool didsomething = 0;
-
- dtime = time_zero;
-
- #if 0
- /* from PAMAKE */
- if (np->n_flag & N_DONE)
- {
- if ( display ) dodisp(np->n_name,np->n_time);
- return 0;
- }
- #endif
-
- if (np->n_flag & N_DONE) return 0; /* if we already did this... */
-
- if (null_time(&np->n_time)) /* if time == time_zero */
- modtime(np); /* get modtime of this file */
-
- /* if ( display ) dodisp(np->n_name,&np->n_time); */ /* from PAMAKE */
-
- if (rules) /* if using inbuilt rules */
- { for (lp = np->n_line; lp; lp = lp->l_next) /* search line list of entry */
- if (lp->l_cmd) break; /* if line has a command, then do it */
- if (!lp) dyndep(np); /* else look for a dynamic dependancy */
- }
-
- /* if at this point the file doesn't exist, and it's not a target,
- then no way to tell how to make it.
- */
-
- if (!(np->n_flag & N_TARG) && null_time(&np->n_time))
- fatal("Don't know how to make %s", np->n_name);
-
- /* for each entry for the name, for each depndancy in the line */
-
- for (qdp = NULL, lp = np->n_line; lp; lp = lp->l_next)
- {
- for (dp = lp->l_dep; dp; dp = dp->d_next)
- {
- make(dp->d_name, level+1); /* try making it */
-
- /* if the file is earlier than the dependancy, make it a
- dependant (on a temp list) */
-
- if (cmp_time(&np->n_time,&dp->d_name->n_time) < 0)
- qdp = newdep(dp->d_name, qdp);
-
- /* our time is MAX(our time,dependant's time) */
-
- if (cmp_time(&dtime,&dp->d_name->n_time) < 0)
- dtime = dp->d_name->n_time;
- }
-
- if (!quest && (np->n_flag & N_DOUBLE) && cmp_time(&np->n_time,&dtime) < 0)
- { make1(np, lp, qdp); /* free()'s qdp */
- dtime = time_one;
- qdp = (struct depend *)0;
- didsomething++;
- }
- }
-
- np->n_flag |= N_DONE; /* mark as done */
-
- if (quest) /* if 'question up-to-date' */
- { TimeStamp t; /* temp time variable */
-
- t = np->n_time; /* old time of file */
- DateStamp(&np->n_time); /* new time of file = current time */
- /* cleardynflag(np); */ /* from PAMAKE */
- return (cmp_time(&t,&dtime) < 0); /* return comparison */
- }
- else if (makeall || cmp_time(&np->n_time,&dtime) < 0 && !(np->n_flag & N_DOUBLE))
- {
- /* here's the actual part that starts commands executing (normally) */
-
- make1(np, (struct line *)0, qdp); /* free()'s qdp */
- DateStamp(&np->n_time); /* np's time is now current time */
- }
- else if (level == 0 && !didsomething)
- printf("%s: '%s' is up to date\n", myname, np->n_name);
- /* cleardynflag(np); */ /* from PAMAKE */
- return 0;
- }
-
- /* DJ notes:
- Frees all dependancy structures (What good that does, I'm not sure).
- Builds a macro called '?' which is the names of all the dependancies.
- Then executes each command in np.
- */
-
- make1(np, lp, qdp)
- register struct depend *qdp;
- struct line *lp;
- struct name *np;
- { register struct depend *dp;
-
- if (dotouch) /* if 'touch' flag */
- touch(np); /* touch the file */
- else
- { strcpy(str1, ""); /* intialize string var */
- for (dp = qdp; dp; dp = qdp) /* for each dependancy */
- { if (strlen(str1)) /* if not the first name */
- strcat(str1, " "); /* add a space */
- strcat(str1, dp->d_name->n_name); /* concatenate the depndancy name */
- qdp = dp->d_next; /* address of next dependancy */
- free(dp); /* free dependancy */
- }
- setmacro("?", str1); /* set '?' as name of deps */
- setmacro("@", np->n_name); /* and '@' as name of self */
- if (lp) /* lp set if doing a :: rule */
- docmds1(np, lp); /* do a specific line */
- else docmds(np); /* do all lines for that name */
- }
- }
-