home *** CD-ROM | disk | FTP | other *** search
- /*
- * make [-f makefile] [-nprst] [macro=val ...] [target(s) ...]
- *
- * (Better than EON mk & old CPM make but not quite as good as UNIX make)
- *
- * -f makefile name
- * -i don't ignore exit status
- * -n Pretend to make
- * -p Print all macros & targets
- * -q Question up-to-dateness of target. Return exit status 1 if not
- * -r Don't not use inbuilt rules
- * -s Make silently
- * -t Touch files instead of making them
- * -m Change memory requirements - N/A under CP/M
- */
-
- #include "c:stdio.h" /* c: is my ramdisk */
- #include "c:fcntl.h"
- #include "h.h"
-
- char Usage1[]=" -f makefile name\n\
- -i don't ignore exit status\n\
- -n Pretend to make\n\
- -p Print all macros & targets\n\
- -r Do not use inbuilt rules\n\
- -s Make silently\n\
- -t Touch files instead of making them\n";
-
-
- #define MEMSPACE (16384) /* superfluous under cp/m */
-
-
- char * myname;
- char * makefile; /* The make file */
- unsigned memspace = MEMSPACE;
-
- extern FILE *execfile;
-
- FILE * ifd; /* Input file desciptor */
- bool domake = TRUE; /* Go through the motions option */
- bool ignore = TRUE; /* Ignore exit status option */
- bool silent = FALSE; /* Silent option */
- bool print = FALSE; /* Print debuging information */
- bool rules = TRUE; /* Use inbuilt rules */
- bool dotouch = FALSE;/* Touch files instead of making */
- bool quest = FALSE; /* Question up-to-dateness of file */
-
-
- void
- main(argc, argv)
- char ** argv;
- int argc;
- {
- register char * p; /* For argument processing */
- int estat; /* For question */
- register struct name * np;
-
-
- /*
- * CP/M makes all command line junque upper case. All things
- * being equal, I'd rather they be all forced lower. So I will.
- *
- * I have also forced everything in the makefile to lower case,
- * so everything should be case insensitive.
- */
- for (estat = argc ; --estat > 0 ;) {
- strlower(argv[estat]);
- }
-
- unlink(MAKERUN); /* delete possible existing make-submit file */
-
- myname = (argc-- < 1) ? "make" : *argv++;
- /*
- * CP/M can't do argv[0] (OS limitation), so we don't know who we are.
- */
- myname = "make";
-
- while ((argc > 0) && (**argv == '-'))
- {
- argc--; /* One less to process */
- p = *argv++; /* Now processing this one */
-
- while (*++p != '\0')
- {
- /*
- * Elaborate switch not really needed, but I
- * hacked this in before I made all argv parameters
- * lower case (for cp/m).
- */
- switch( isupper(*p) ? tolower (*p) : *p )
- {
- case 'f': /* Alternate file name */
- if (*++p == '\0')
- {
- if (argc-- <= 0)
- usage();
- p = *argv++;
- }
- makefile = p;
- goto end_of_args;
- case 'm': /* Change space requirements */
- if (*++p == '\0')
- {
- if (argc-- <= 0)
- usage();
- p = *argv++;
- }
- memspace = atoi(p);
- goto end_of_args;
- case 'n': /* Pretend mode */
- domake = FALSE;
- break;
- case 'i': /* Ignore fault mode */
- ignore = FALSE;
- break;
- case 's': /* Silent about commands */
- silent = TRUE;
- break;
- case 'p':
- print = TRUE;
- break;
- case 'r':
- rules = FALSE;
- break;
- case 't':
- dotouch = TRUE;
- break;
- case 'q':
- quest = TRUE;
- break;
- default: /* Wrong option */
- usage();
- }
- }
- end_of_args:;
- }
-
- /* if (initalloc(memspace) == 0xffff) Must get memory for alloc
- fatal("Cannot initalloc memory");
- */
- if (strcmp(makefile, "-") == 0) /* Can use stdin as makefile */
- ifd = stdin;
- else
- if (!makefile) /* If no file, then use default */
- {
- if ((ifd = fopen(DEFN1, "r")) == (FILE *)0
- && ((ifd = fopen(DEFN2, "r")) == (FILE *)0)) {
- fatal("Can't open %s or %s; error %02x",
- DEFN1,DEFN2, errno);
- }
-
- }
- else
- if ((ifd = fopen(makefile, "r")) == (FILE *)0)
- fatal("Can't open %s", makefile);
-
- if (rules)
- makerules();
-
- setmacro("$", "$");
-
- while (argc && (p = index(*argv, '=')))
- {
- char c;
-
- c = *p;
- *p = '\0';
- setmacro(*argv, p+1);
- *p = c;
-
- argv++;
- argc--;
- }
-
- input(ifd); /* Input all the gunga */
- fclose(ifd); /* Finished with makefile */
- lineno = 0; /* Any calls to error now print no line number */
-
- if (print)
- prt(); /* Print out structures */
-
- np = newname(".SILENT");
- if (np->n_flag & N_TARG)
- silent = TRUE;
-
- np = newname(".IGNORE");
- if (np->n_flag & N_TARG)
- ignore = TRUE;
-
- precious();
-
- if (!domake)
- silent = FALSE;
-
- if (!firstname)
- fatal("No targets defined");
-
- circh(); /* Check circles in target definitions */
-
- if (!argc)
- estat = make(firstname, 0);
- else while (argc--)
- {
- if (!print && !silent && strcmp(*argv, "love") == 0)
- printf("Not war!\n");
- estat |= make(newname(*argv++), 0);
- }
-
-
- if (execfile == NULL) {
- exit(0); /* no file made, must be up to date! */
- }
-
- /*
- * The "trick" algorithm used for CP/M (which can't execute
- * commands while "make" is running) is that dosh() really
- * puts commands into a submit file MAKERUN, then after
- * the make is "done", that submit file is chained-to (below).
- * The first code-line below enters the submit file's last command
- * to delete itself (so this chaining trick is mostly transparent.
- *
- * -mdk
- */
-
- dosh("era ",MAKERUN); /* have the submit file delete itself */
- dosh("\n","");
- fclose(execfile); /* close the writing to this file */
-
- bdos(108,0); /* Reset CP/M Program return code */
-
- strcpy((char *)0x80,MAKERUN); /* load submit file name into DMA buf*/
- bdos(47,0xff); /* chain to the generated submit file */
-
-
- /* if (quest)
- exit(estat);
- else
- exit(0);
- */
-
- }
-
-
- usage()
- {
- fprintf(stderr, "Usage: %s [-f makefile] [-nprst] [macro=val ...] [target(s) ...]\n%s", myname,Usage1);
- exit(1);
- }
-
-
- void
- fatal(msg, a1, a2, a3)
- char *msg;
- {
- fprintf(stderr, "%s: ", myname);
- fprintf(stderr, msg, a1, a2, a3);
- fputc('\n', stderr);
- exit(1);
- }
-
-
-
- strlower(string)
- char *string;
- {
- register char *pointer;
- char c;
- for (pointer = string ; (c=*pointer) != '\0' ; pointer++ ) {
- if (isupper(c))
- *pointer = tolower(c);
- }
- }
-