home *** CD-ROM | disk | FTP | other *** search
- /* File MAKE.C. */
- /* BDS-C Version 1.2 6/14/85 */
- #define VERSION "V1.2 6/14/85"
-
- /* v 1.2 [bmm]
- * compatible with DateStamper v 2.0
- * fixed relative time display in prtree
- * coded alloc() and free() in ASM
- * read entire time&date file on first drive
- * omit script file if no actual commands to execute
- */
-
- #include <bdscio.h>
- #include "make.h"
-
- /*
- * MAKE - Maintain seperate source files
- *
- * SYNOPSIS
- * MAKE [-f file] [-a] [-n] [-d] [name] ...
- * f: use 'file' instead of default makefile
- * a: assume all modules are obsolete (recompile everything)
- * n: don't recompile, just list steps to recompile
- * d: debugging (print tree, file info)
- * name: module name to recompile
- *
- * 'secret' options (not to be used by humans):
- * -ofile 'file' is the script file to write to
- *
- * AUTHOR
- * Landon M. Dyer, Atari Inc.
- *
- * MODIFICATIONS
- * Neil Maron: Converted to CP/M 80 (tm), BDS-C(tm), using
- * DateStamper(tm).
- * v 1.2 Bridger Mitchell (Plu*Perfect Systems)
- */
-
- #define SCRIPTFILE "make$$$$.sub" /* (default) script-listing file */
- #define INIT "~INIT" /* initialization macro */
- #define DEINIT "~DEINIT" /* de-init macro */
- #define BEFORE "~BEFORE" /* the per-root 'startup' method */
- #define AFTER "~AFTER" /* the per-root 'wrapup' method */
- #define BATCH "~BATCH" /* the batch processor to run */
-
-
- /*MACRO *mroot;*/ /* root of macro-list */
- /*FILENODE *froot;*/ /* root of filenode-list */
- FILENODE *firstf; /* the very first filenode */
- char mkfpbuf[BUFSIZ]; /* output file buffer */
- FILE *mkfp; /* script file */
- char *modnames[MAXMODS]; /* module-names mentioned in commandline */
- int modcount; /* #of module-names */
- int debug; /* nonzero: turn on debugging */
- int obsolete; /* nonzero: every file should be recompiled */
- int noscript; /* nonzero: print methods on standard output */
- char *scriptf; /* default script file */
- /*DATE *bigbang;*/ /* a date, the very earliest possible */
- /*DATE *endoftime;*/ /* a date, the very last possible */
-
- main(argc, argv)
- int argc;
- char **argv;
- {
- int arg, i;
- char *mfile;
- DATE *adate();
- char *gdsadate();
- char *m;
-
- /* Inits */
- mfile=NULL;
- mroot=NULL; froot=NULL; firstf=NULL; mkfp=NULL;
- modcount=debug=obsolete=noscript=0;
- scriptf=SCRIPTFILE;
- datesdisk = -1; /* signal initial read to getfdate() */
- havedates = somechanges = FALSE;
- /* End of inits */
-
- bigbang = adate("\000\000\000\000\000"); /* init root dates */
- endoftime = adate("\377\377\377\377\377");
-
- if (bdos(12) != 0x0022) {
- printf("\7Requires CP/M 2.2\nAborting\n");
- exit();
- }
-
- /* Get the date for output of version string.*/
- ascidate=gdsadate();
- if(!ascidate) ascidate="No Date";
-
- printf("MAKE %s on %s\n", VERSION, ascidate);
-
- if(argc < 2) {
- printf("Usage: MAKE [-f file] [-a] [-n] [-d] [name] ...\n");
- printf("\tf: use 'file' instead of default MAKEFILE.\n");
- printf("\ta: assume all modules are obsolete (recompile everything)\n");
- printf("\tn: don't recompile, just list steps to recompile\n");
- printf("\td: debugging (print tree, file info)\n");
- printf("\tname: module name to recompile\n");
- exit();
- }
-
- for(arg = 1; arg < argc; ++arg)
- if(*argv[arg] == '-') switch(tolower(argv[arg][1]))
- {
- case 'f':
- if(++arg >= argc || argv[arg][0]=='-')
- {
- printf("\7-f needs filename argument.\n");
- return;
- }
- mfile = argv[arg];
- break;
-
- case 'a':
- obsolete = 1;
- break;
-
- case 'n':
- noscript = 1;
- break;
-
- case 'd':
- debug = 1;
- break;
-
- case 'o':
- scriptf = argv[arg] + 2;
- break;
-
- default:
- printf("Unknown switch: %c\n", argv[arg][1]);
- break;
- } else if(modcount < MAXMODS)
- modnames[modcount++] = argv[arg];
- else
- {
- printf("Too many module names.\n");
- return;
- }
-
-
- mfilename = (mfile != NULL) ? mfile : "MAKEFILE";
-
- if(fmakesb(mfilename) == -1)
- printf("Cannot open makefile '%s'.\n", mfilename);
-
- if(debug) prtree();
-
- if ((m=gmacro(BATCH)) != NULL && !noscript && somechanges) {
- execl(m, scriptf,0);
- printf("Can't start %s\n", m);
- }
- exit(1);
- }
-
-
- /*
- * Construct dependency tree from the makefile 'fn'.
- * Figure out what has to be recompiled, and write a script file to do that.
- */
- fmakesb(fn)
- char *fn;
- {
- FILE *fp;
- char fpbuf[BUFSIZ];
-
- if((fp = fopen(fn, fpbuf)) == ERROR) return -1;
- fp=&fpbuf; /* BDS-C buffered I/O */
-
- fparse(fp);
- determ();
-
- fclose(fp);
- return 0;
- }
-
-
- /*
- * Parse the input file, defining macros and building the dependency tree.
- */
- fparse(fp)
- FILE *fp;
- {
- char ibuf[STRSIZ], ebuf[STRSIZ];
- char *strp, *tok1, *tok2, *s;
- FILENODE *lastf;
- FILENODE *sf;
-
- lastf=NULL;
- for(;;)
- {
- if(fgets(ibuf, fp) == NULL) break;
- mexpand(ibuf, ebuf, STRSIZ, MACCHAR);
- escape(ebuf, COMCHAR);
-
- /* clobber last newline in string */
- s = ebuf + strlen(ebuf) - 1;
- if(s >= ebuf && *s == '\n') *s = '\0';
-
- if(*ebuf == '\t')
- {
- addmeth(lastf, ebuf+1);
- continue;
- }
-
- strp = ebuf;
- if((tok1 = token(&strp)) == NULL) continue;
- if((tok2 = token(&strp)) != NULL)
- if(strcieq(tok2, DEFMAC))
- {
- if(*strp) defmac(tok1, strp);
- else if(undefmac(tok1) < 0)
- printf(
- "Can't undefine macro '%s'\n", tok1);
- continue;
- }
- else if(strcieq(tok2, DEPEND))
- {
- addmeth(lastf, gmacro(AFTER));
-
- lastf = filenode(tok1);
- if(firstf == NULL) firstf = lastf;
- lastf->fmake = NULL;
-
- addmeth(lastf, gmacro(BEFORE));
-
- lastf->fflag |= ROOTP;
- while((tok1 = token(&strp)) != NULL)
- addfile(lastf, tok1);
- continue;
- }
- else addfile(lastf, tok2);
-
- do {
- addfile(lastf, tok1);
- } while((tok1 = token(&strp)) != NULL);
- }
-
- addmeth(lastf, gmacro(AFTER));
- }
-
- /*
- * Determine sequence of recompiles from the creation dates.
- * If there's anything to recompile, then create a script file of commands.
- */
- determ()
- {
- FILENODE *f;
- int i;
- char *m;
-
- if(firstf == NULL) /* empty tree */
- {
- nochanges();
- somechanges = FALSE;
- return;
- }
-
- if(modcount == 0) examine(firstf, endoftime);
- else for(i = 0; i < modcount; ++i)
- {
- if((f = gfile(modnames[i])) == NULL)
- {
- printf("Can't find root '%s'.\n", modnames[i]);
- continue;
- }
-
- if(f->fflag & ROOTP == 0)
- {
- printf("'%s' is not a root!\n", f->fname);
- continue;
- }
- examine(f, endoftime);
- }
-
- if(mkfp != NULL)
- {
- if((m = gmacro(DEINIT)) != NULL)
- {
- if (mkfp == 1) puts(m);
- else fputs(m, mkfp);
- putc('\r', mkfp);
- putc('\n', mkfp);
- }
- if (mkfp != 1) {
- putc('\032', mkfp); /* CPM e-o-f */
- fflush(mkfp);
- fclose(mkfp);
- if (!somechanges) {
- unlink(scriptf); nochanges();}
- }
- else
- if (!somechanges)
- nochanges();
-
- } else nochanges();
- }
- nochanges()
- {
- printf("No changes.\n");
- }
-
- /*
- * Examine filenode 'fnd' and see if it has to be recompiled.
- * 'date' is the last-touched date of the node's father
- * (or 'endoftime' if its a root file.)
- * Root files with NO dependencies are assumed not to be up to date.
- */
- examine(fnd, date)
- FILENODE *fnd;
- DATE *date;
- {
- int rebuildp;
- NODE *n;
-
- rebuildp=0;
- getdate(fnd);
- if(fnd->fnode == NULL && fnd->fflag & ROOTP)
- rebuildp = 1;
- else for(n = fnd->fnode; n != NULL; n = n->nnext)
- if(examine(n->nfile, fnd->fdate)) rebuildp = 1;
-
- if(rebuildp) recomp(fnd);
- if(obsolete || laterdt(fnd->fdate, date) >= 0)
- rebuildp = 1;
- return rebuildp;
- }
-
-
- /*
- * Make sure a filenode gets recompiled.
- */
- recomp(f)
- FILENODE *f;
- {
- FILENODE *sf;
- char *m;
-
- if(mkfp == NULL) {
- if(noscript) mkfp=1;
- else if((mkfp = fcreat(scriptf, mkfpbuf)) == NULL)
- printf("Cannot create: '%s'\n", scriptf);
- else {
- mkfp=&mkfpbuf;
- /* Install current time as a comment in the file. [nm] */
- fprintf(mkfp,"; script created from %s at %s\r\n",
- mfilename,ascidate);
- }
-
- if((m = gmacro(INIT)) != NULL) {
- if (mkfp == 1) puts(m);
- else fputs(m, mkfp);
- putc('\r', mkfp);
- putc('\n', mkfp);
- }
- }
-
- if(f->fflag & REBUILT) return;
- if(f->fmake != NULL) {
- if (mkfp == 1) puts(f->fmake);
- else {
- fputs(f->fmake, mkfp);
- somechanges = TRUE; }
- }
- f->fflag |= REBUILT;
- }
-
-
- /*
- * Complain about being out of memory, and then die.
- */
- allerr() {
- printf("Can't alloc -- no space left (I give up!)\n");
- exit(1);
- }
-
- /*-- v 1.2 in csm library ---
-
- /* Case independant string equality.
- * Return TRUE is same, FALSE if not.
- */
- strcieq(str1, str2)
- char *str1, *str2;
- {
- char toupper();
- while (*str1 && *str2)
- if (toupper(*str1++) != toupper(*str2++)) return FALSE;
- if (*str1 == *str2) return TRUE;
- return FALSE;
- }
- --- --*/
- Cannot create: '%s'\n", scriptf);
- else {
- mkfp=&mkfpbuf;
- /* Install curren