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
- #ifdef eon
- #include <sys/stat.h>
- #include <sys/err.h>
- #endif
- #ifdef os9
- #include <time.h>
- #include <os9.h>
- #include <modes.h>
- #include <direct.h>
- #include <errno.h>
- #endif
- #ifdef amiga
- #include <ctype.h>
- #include <errno.h>
- #include <libraries/dosextens.h>
- #include <exec/memory.h>
- #include <exec/io.h>
- #include <exec/ports.h>
- #include <functions.h>
- #undef TRUE /*OIS*0.80*/
- #undef FALSE /*OIS*0.80*/
- /*#define ACTION_SET_DATE 34L /*OIS*0.80*/
- #endif
- #include "h.h"
-
-
-
- /*
- * Exec a shell that returns exit status correctly (/bin/esh).
- * The standard EON shell returns the process number of the last
- * async command, used by the debugger (ugg).
- * [exec on eon is like a fork+exec on unix]
- */
- int
- dosh(string, shell)
- char *string;
- char *shell;
- {
- int number;
-
- #ifdef amiga
- char *av[3], *s, *p;
- int i;
-
- fflush(stdout); /*OIS*0.80*/
- if ((p = s = malloc((unsigned) strlen(string) + 1)) == NULL)
- fatal("No memory for command '%s'", string);
- strcpy(p, string); /* make a copy of the string */
- i = 0;
- av[0] = gettok(&p); /* get first argument */
- av[1] = p; /* get rest of command line */
- av[2] = NULL;
- if (fexecv(av[0], av) == -1)
- fatal("couldn't execute command '%s', error return %02x\n",
- av[0], errno);
- number = wait();
- free(s);
- return number;
- #endif
-
- #ifdef unix
- return system(string);
- #endif
- #ifdef eon
- return ((number = execl(shell, shell, "-c", string, 0)) == -1) ?
- -1 : /* couldn't start the shell */
- wait(number); /* return its exit status */
- #endif
- #ifdef os9
- int status, pid;
-
- strcat(string, "\n");
- if ((number = os9fork(shell, strlen(string), string, 0, 0, 0)) == -1)
- return -1; /* Couldn't start a shell */
- do {
- if ((pid = wait(&status)) == -1)
- return -1; /* child already died!?!? */
- } while (pid != number);
-
- return status;
- #endif
- }
-
-
- /*
- * 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;
- #ifdef amiga
- long SetSignal();
- #endif
-
- #ifndef amiga
- if (*(shell = getmacro("SHELL")) == '\0')
- #ifdef eon
- shell = ":bin/esh";
- #endif
- #ifdef unix
- shell = "/bin/sh";
- #endif
- #ifdef os9
- shell = "shell";
- #endif
- #else /* for amiga */
- shell = NULL;
- #endif
-
- for (cp = lp->l_cmd; cp; cp = cp->c_next) {
- strcpy(str1, cp->c_cmd);
- expand(str1);
- q = str1;
- ssilent = silent;
- signore = ignore;
- while ((*q == '@') || (*q == '-')) {
- if (*q == '@') /* Specific silent */
- ssilent = TRUE;
- else /* Specific ignore */
- signore = TRUE;
- q++; /* Not part of the command */
- }
-
- if (!domake)
- ssilent = 0;
-
- if (!ssilent)
- fputs(" ", stdout);
-
- for (p = q; *p; p++) {
- if (*p == '\n' && p[1] != '\0') {
- *p = ' ';
- if (!ssilent)
- fputs("\\\n", stdout);
- } else if (!ssilent)
- putchar(*p);
- }
- if (!ssilent)
- putchar('\n');
-
- if (domake) { /* Get the shell to execute it */
- if ((estat = dosh(q, shell)) != 0) {
- if (estat == -1)
- fatal("Couldn't execute %s", shell);
- else {
- printf("%s: Error code %d", myname, estat);
- if (signore)
- fputs(" (Ignored)\n", stdout);
- else {
- putchar('\n');
- if (!(np->n_flag & N_PREC))
- if (unlink(np->n_name) == 0)
- printf("%s: '%s' removed.\n", myname, np->n_name);
- exit(estat);
- }
- }
- }
- #ifdef amiga
- if ((SetSignal(0L, SIGBREAKF_CTRL_D) & SIGBREAKF_CTRL_D) != 0) {
- fatal("Abort due to ^D"); /*OIS*0.80*/
- }
- #endif
- }
- }
- }
-
-
- docmds(np)
- struct name *np;
- {
- register struct line *lp;
-
-
- for (lp = np->n_line; lp; lp = lp->l_next)
- docmds1(np, lp);
- }
-
-
- #ifdef os9
- /*
- * Some stuffing around to get the modified time of a file
- * in an os9 file system
- */
- getmdate(fd, tbp)
- struct sgtbuf *tbp;
- {
- struct registers regs;
- static struct fildes fdbuf;
-
-
- regs.rg_a = fd;
- regs.rg_b = SS_FD;
- regs.rg_x = &fdbuf;
- regs.rg_y = sizeof(fdbuf);
-
- if (_os9(I_GETSTT, ®s) == -1) {
- errno = regs.rg_b & 0xff;
- return -1;
- }
- if (tbp) {
- _strass(tbp, fdbuf.fd_date, sizeof(fdbuf.fd_date));
- tbp->t_second = 0; /* Files are only acurate to mins */
- }
- return 0;
- }
-
-
- /*
- * Kludge routine to return an aproximation of how many
- * seconds since 1980. Dates will be in order, but will not
- * be lineer
- */
- time_t
- cnvtime(tbp)
- struct sgtbuf *tbp;
- {
- long acc;
-
-
- acc = tbp->t_year - 80; /* Baseyear is 1980 */
- acc = acc * 12 + tbp->t_month;
- acc = acc * 31 + tbp->t_day;
- acc = acc * 24 + tbp->t_hour;
- acc = acc * 60 + tbp->t_minute;
- acc = acc * 60 + tbp->t_second;
-
- return acc;
- }
-
-
- /*
- * Get the current time in the internal format
- */
- time(tp)
- time_t *tp;
- {
- struct sgtbuf tbuf;
-
-
- if (getime(&tbuf) < 0)
- return -1;
-
- if (tp)
- *tp = cnvtime(&tbuf);
-
- return 0;
- }
- #endif
-
-
- /*
- * 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 eon
- struct stat info;
- int fd;
-
-
- if ((fd = open(np->n_name, 0)) < 0) {
- if (errno != ER_NOTF)
- fatal("Can't open %s; error %02x", np->n_name, errno);
-
- np->n_time = 0L;
- } else if (getstat(fd, &info) < 0)
- fatal("Can't getstat %s; error %02x", np->n_name, errno);
- else
- np->n_time = info.st_mod;
-
- close(fd);
- #endif
- #ifdef os9
- struct sgtbuf info;
- int fd;
-
-
- if ((fd = open(np->n_name, 0)) < 0) {
- if (errno != E_PNNF)
- fatal("Can't open %s; error %02x", np->n_name, errno);
-
- np->n_time = 0L;
- } else if (getmdate(fd, &info) < 0)
- fatal("Can't getstat %s; error %02x", np->n_name, errno);
- else
- np->n_time = cnvtime(&info);
-
- close(fd);
- #endif
- #ifdef amiga
- struct FileInfoBlock *fib;
- struct FileLock *myLock;
- long ioErr;
-
- fib = (struct FileInfoBlock *) malloc((unsigned) sizeof(struct FileInfoBlock));
- if ((myLock = Lock(np->n_name, ACCESS_READ)) == NULL) {
- if ((ioErr = IoErr()) != ERROR_OBJECT_NOT_FOUND)
- fatal("Can't Lock '%s'; error %3ld", np->n_name, ioErr);
- np->n_time = 0L;
- } else if (!Examine(myLock, fib)) {
- UnLock(myLock);
- fatal("Can't Examine '%s'; error %3ld", np->n_name, IoErr());
- } else {
- np->n_time = fib->fib_Date.ds_Tick/TICKS_PER_SECOND +
- 60*fib->fib_Date.ds_Minute + 86400*fib->fib_Date.ds_Days;
- UnLock(myLock);
- }
- free((char *) fib);
- #endif
-
- }
-
- #ifdef amiga
- char *
- nametail(name)
- register char *name;
- {
- register char *tail;
-
- if ((tail = index(name, ':')) == NULL) /* strip device name */
- tail = name;
- if ((name = rindex(tail, '/')) == NULL) /* strip directories */
- name = tail;
-
- return 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 eon
- if ((fd = open(np->n_name, 0)) < 0)
- printf("%s: '%s' not touched - non-existant\n",
- myname, np->n_name);
- else {
- uread(fd, &c, 1, 0);
- uwrite(fd, &c, 1);
- }
- close(fd);
- #endif
- #ifdef os9
- /*
- * Strange that something almost as totally useless as this is easy
- * to do in os9!
- */
- if ((fd = open(np->n_name, S_IWRITE)) < 0)
- printf("%s: '%s' not touched - non-existant\n",
- myname, np->n_name);
- close(fd);
- #endif
- #ifdef amiga
- struct MsgPort *task;
- ULONG dateStamp[3];
- struct FileLock *lock, *plock;
- UBYTE *bcplstring;
-
- if(!(bcplstring = (UBYTE *)AllocMem(64L, MEMF_PUBLIC)))
- fatal("Can't get 64 bytes for bcplstring");
- if(!(task=(struct MsgPort *)DeviceProc(np->n_name))) {
- printf("%s: can't get MsgPort for '%s'\n", myname, np->n_name);
- goto abort;
- }
- if(!(lock = Lock(np->n_name, SHARED_LOCK))) {
- printf("%s: '%s' not touched - non-existant\n",
- myname, np->n_name);
- goto abort;
- }
- plock = ParentDir(lock);
- UnLock(lock);
-
- /* Strip pathnames first */
- strcpy((bcplstring + 1), nametail(np->n_name));
- *bcplstring = strlen(bcplstring + 1);
-
- dos_packet(task, ACTION_SET_DATE, NULL, plock, (ULONG)bcplstring >> 2,
- (ULONG) DateStamp(dateStamp), 0L, 0L, 0L);
-
- UnLock(plock);
- abort:
- FreeMem((void *) bcplstring, 64L);
- #endif
- }
- }
-
- /*
- * Recursive routine to make a target.
- */
- int
- make(np, level)
- struct name *np;
- int level;
- {
- register struct depend *dp;
- register struct line *lp;
- register struct depend *qdp;
- time_t dtime = 1, time();
- bool didsomething = 0;
- char * basename = (char *) 0;
- char * inputname = (char *) 0;
-
-
- if (np->n_flag & N_DONE)
- return 0;
-
- if (!np->n_time)
- modtime(np); /* Gets modtime of this file */
-
- if (rules) {
- for (lp = np->n_line; lp; lp = lp->l_next)
- if (lp->l_cmd)
- break;
- if (!lp)
- dyndep(np, &basename, &inputname);
- }
- if (!(np->n_flag & N_TARG) && np->n_time == 0L)
- fatal("Don't know how to make %s", np->n_name);
-
- for (qdp = (struct depend *) 0, 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);
- if (np->n_time < dp->d_name->n_time)
- qdp = newdep(dp->d_name, qdp);
- dtime = max(dtime, dp->d_name->n_time);
- }
- if (!quest && (np->n_flag & N_DOUBLE) && (np->n_time < dtime)) {
- make1(np, lp, qdp, basename, inputname); /* free()'s qdp */
- dtime = 1;
- qdp = (struct depend *) 0;
- didsomething++;
- }
- }
-
- np->n_flag |= N_DONE;
-
- if (quest) {
- long t;
-
- t = np->n_time;
- time(&np->n_time);
- if (basename)
- free(basename);
-
- return t < dtime;
- } else if (np->n_time < dtime && !(np->n_flag & N_DOUBLE)) {
- make1(np, (struct line *)0, qdp, basename, inputname); /* free()'s qdp */
- time(&np->n_time);
- } else if (level == 0 && !didsomething)
- printf("%s: '%s' is up to date\n", myname, np->n_name);
-
- if (basename)
- free(basename);
-
- return 0;
- }
-
-
- make1(np, lp, qdp, basename, inputname)
- register struct depend *qdp;
- struct line *lp;
- struct name *np;
- char *basename;
- char *inputname;
- {
- register struct depend *dp;
-
-
- if (dotouch)
- touch(np);
- else {
- strcpy(str1, "");
- if (!basename)
- basename = str1;
- setmacro("*", basename); /* $* = file */
- if (!inputname)
- inputname = str1;
- setmacro("<", inputname); /* $< = path/file.c or file.c */
- for (dp = qdp; dp; dp = qdp) {
- if (strlen(str1))
- strcat(str1, " ");
- strcat(str1, dp->d_name->n_name);
- qdp = dp->d_next;
- free(dp);
- }
- setmacro("?", str1); /* $? = file.c file1.h file2.h */
- setmacro("@", np->n_name); /* $@ = file.o */
- if (lp) /* lp set if doing a :: rule */
- docmds1(np, lp);
- else
- docmds(np);
- }
- }
- #ifdef amiga
- /*
- * Replace the Aztec-provided time function with one which returns something
- * easy to find and compare, namely the number of seconds since the Amiga's
- * reference date. This is the same thing returned by modtime() above.
- */
- time_t
- time(v)
- time_t *v;
- {
- long t[3];
-
- DateStamp(t);
- t[0] = t[2]/TICKS_PER_SECOND + 60*t[1] + 86400*t[0];
- if (v)
- *v = t[0];
- return t[0];
- }
- #endif
-