home *** CD-ROM | disk | FTP | other *** search
- /*
- * Make.c Un*x like program builder for MS-DOS
- *
- * (C) Copyright 1985 Aspen Scientific
- *
- */
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <ctype.h>
-
- #ifdef BUFSIZ
- # undef BUFSIZ
- # define BUFSIZ 2048
- #endif
-
- #define reg register
- #define INSTR 8
- #define iscomment(c) (c == '#')
- #define nodisplay(c) (c == '@')
- #define MAXARG 64
- #define strbck1(str) strcpy(str, &str[1]) /* back up one char */
-
- #ifndef UNIX
- # include <process.h> /* defines P_WAIT for spawnvp() */
- #endif
-
- /* compare command request to internal dos commands */
- static char *idos[] = {
- "break", "cd", "chdir", "cls", "copy", "ctty", "date", "del",
- "dir", "echo", "erase", "exit", "exist", "if", "md", "mkdir",
- "pause", "rd", "rem", "ren", "rename", "rmdir", "time", "type",
- "ver", "verify", "vol",
- (char *)0
- };
-
- char *m_argv[MAXARG];
- char work[BUFSIZ], temp[BUFSIZ], buff[BUFSIZ];
-
- typedef struct deplist {
- char *depf;
- struct deplist *next;
- } DEP;
-
- typedef struct mklist {
- DEP *dep;
- char *targ;
- int echoi[INSTR]; /* should we echo the cmd ? */
- char *instr[INSTR];
- struct mklist *next;
- } MK;
-
- MK *mk = (MK *)0; /* tree root */
- MK *get_targ();
- #ifdef DEBUG
- MK *ddtmp;
- DEP *dddtmp;
- #endif
- FILE *mk_fp, *script_fp;
-
- char *malloc();
- int madeit = 0, mk_script = 0; /* build shell script */
-
- main(argc, argv)
- int argc;
- char **argv;
- {
- reg int i;
-
- fprintf(stderr,"AS_Make v1.3 Copyright 1985,1989 Aspen Scientific ");
- fprintf(stderr,"with mods for C++\n");
- if((mk_fp = fopen("makefile", "r")) == (FILE *)0) {
- fprintf(stderr,"\nMake: cannot open makefile.\n");
- exit(2);
- }
- if(argc > 1 && argv[1][0] == '-') {
- if(argv[1][1] != 'B' && argv[1][1] != 'b')
- eusage();
- if((script_fp = fopen("mk.bat","w"))==(FILE *)0) {
- fprintf(stderr,"\nMake: cannot open MK.BAT.\n");
- exit(2);
- }
- fprintf(script_fp,"echo off\ncls\n");
- mk_script = 1;
- }
- set_mk();
- #ifdef DEBUG
- for(ddtmp = mk; ddtmp; ddtmp = ddtmp->next)
- for(dddtmp = ddtmp->dep; dddtmp; dddtmp = dddtmp->next)
- printf("\ntarg->%s : dep->%s",
- ddtmp->targ,dddtmp->depf);
- #endif
- fclose(mk_fp);
- for(i = 0; i < MAXARG; m_argv[i++] = (char *)0);
- if(mk == (MK *)0) {
- fprintf(stderr,"\nMake: No arguments or description file. Stop.");
- exit(2);
- }
- if(argc < (2 + mk_script)) {
- if(!mkit(mk->targ))
- fprintf(stdout,"\n'%s' is up to date.", mk->targ);
- else
- ++madeit;
- }
- else {
- for(i = (1+mk_script); i < argc; i++)
- if(!mkit(argv[i]))
- fprintf(stdout,"\n'%s' is up to date.",argv[i]);
- else
- ++madeit;
- }
- if(mk_script) {
- fprintf(stdout,"\nMake: run command from MK.BAT");
- fprintf(script_fp,"echo remove MK.BAT\ngoto end\n");
- fprintf(script_fp,":stop\necho Make: errors detected. Stop.\n:end\n");
- fclose(script_fp);
- if(!madeit)
- unlink("mk.bat");
- }
- exit(0);
- }
- eusage()
- {
- fprintf(stderr,"\nUsage: make [-B | -b] [target_name(s)]");
- fprintf(stderr,"\n -B : build Dos Batch script.\n");
- exit(2);
- }
- set_mk()
- {
- int line;
-
- for(line = 1;;line++) {
- if(!fgets(work, BUFSIZ, mk_fp))
- break;
- if(*work == '\n' || comment())
- continue;
- if(!scantarg(work, temp)) {
- fprintf(stderr,"\nMake: bad target on line %d. Stop.\n", line);
- exit(2);
- }
- fill_dep(temp, &work[strlen(temp)]);
- fill_inst(&line);
- }
- }
- scantarg(src, targ)
- char *src, *targ;
- {
- reg int i, j;
-
- for(i = 0, j = 0; src[i]; i++) {
- if(isspace(src[i]))
- continue;
- if(src[i] == ':')
- break;
- targ[j++] = (isupper(src[i]) ? tolower(src[i]):src[i]);
- }
- targ[j] = '\0';
- return(src[i]);
- }
- fill_dep(targ, dep)
- char *targ, *dep;
- {
- reg int i, j, k;
- reg MK *tmp;
- reg DEP *dtmp;
-
- if(mk == (MK *)0) {
- if((mk = (MK *)malloc(sizeof(MK))) == (MK *)0)
- mem_err();
- tmp = mk;
- }
- else {
- for(tmp = mk; ; tmp = tmp->next)
- if(!tmp->next)
- break;
- if((tmp->next = (MK *)malloc(sizeof(MK))) == (MK *)0)
- mem_err();
- tmp = tmp->next;
- }
- tmp->next = (MK *)0;
- tmp->dep = (DEP *)0;
- for(i = 0; i < INSTR; tmp->instr[i++] = (char *)0);
- if((tmp->targ = malloc((strlen(targ)+1))) == (char *)0)
- mem_err();
- strcpy(tmp->targ, targ);
- for(i = 0; dep[i]; i++)
- if(!isspace(dep[i]) && dep[i] != ':')
- break;
- if(!dep[i])
- return(0); /* no dependancies */
- for(;;) {
- if(tmp->dep == (DEP *)0) {
- if((tmp->dep = (DEP *)malloc(sizeof(DEP)))==(DEP *)0)
- mem_err();
- dtmp = tmp->dep;
- }
- else {
- if((dtmp->next = (DEP *)malloc(sizeof(DEP)))==(DEP *)0)
- mem_err();
- dtmp = dtmp->next;
- }
- dtmp->depf = (char *)0;
- dtmp->next = (DEP *)0;
- for(k = 0, j = i; dep[j] && !isspace(dep[j]); j++)
- buff[k++] = tolower(dep[j]);
- buff[k] = '\0';
- if((dtmp->depf = malloc((strlen(buff)+1)))==(char *)0)
- mem_err();
- strcpy(dtmp->depf, buff);
- #ifdef DEBUG
- printf("\ndep arg=%s", buff);
- #endif
- if(!dep[j])
- break;
- for(; ; j++) {
- if(!dep[j])
- return;
- if(isalnum(dep[j]))
- break;
- }
- i = j;
- }
- }
- fill_inst(line)
- int *line;
- {
- reg MK *tmp;
- reg int i, len;
-
- for(tmp = mk; ; tmp = tmp->next)
- if(tmp->next == (MK *)0)
- break;
-
- for(i = 0; i < INSTR; i++) {
- if(!fgets(work, BUFSIZ, mk_fp))
- break;
- (*line)++;
- if(*work == '\n')
- break;
- if(comment())
- continue;
- for(len = 0; work[len] && isspace(work[len]); len++);
- if(!work[len] || work[len] == '\n')
- continue;
- if(work[((len = strlen(work) - 1))] == '\n')
- work[len] = '\0';
- if((tmp->instr[i] = malloc((len + 1))) == (char *)0)
- mem_err();
- strcpy(tmp->instr[i], work);
- }
- }
- comment()
- {
- int i, flag;
-
- for(i = 0, flag = 0; work[i]; i++)
- if(iscomment(work[i])) {
- work[i] = '\0';
- break;
- }
- else if(!isspace(work[i]))
- ++flag;
- return( (flag ? 0:1) ); /* only comment or only at end of line ? */
- }
- mem_err()
- {
- fprintf(stderr,"\nMake: Out of memory. Stop.\n");
- exit(2);
- }
- mkit(targ)
- char *targ;
- {
- MK *tmp;
- DEP *dtmp;
-
- int i, j, len, made, go, display;
-
- made = go = 0;
- if((tmp = get_targ(targ)) == (MK *)0) {
- len = (strlen(targ) - 2);
- if(strcmp(&targ[len], ".c") && strcmp(&targ[len], ".h")) {
-
- len -= 2;
- if (strcmp(&targ[len], ".cpp") &&
- strcmp(&targ[len], ".hpp") &&
- strcmp(&targ[len], ".cxx") &&
- strcmp(&targ[len], ".hxx"))
- mk_err(targ);
- }
- return(0);
- }
- if(tmp->dep == (DEP *)0)
- ++go; /* no dependencies - do command */
- else {
- for(dtmp = tmp->dep ; ; ) {
- #ifdef DEBUG
- printf("\ntarg->%s : arg->%s ",
- tmp->targ, dtmp->depf);
- #endif
- mkit(dtmp->depf);
- if(time_stamp(targ, dtmp->depf) != 0)
- ++go;
- if(dtmp->next == (DEP *)0)
- break;
- dtmp = dtmp->next;
- }
- }
- if(go) {
- for(i = 0; i < INSTR; i++)
- if(tmp->instr[i]) {
- if(!bld_arg(tmp->instr[i]))
- continue;
- if(!nodisplay(m_argv[0][0]))
- display = 1;
- else {
- display = 0;
- strbck1(m_argv[0]);
- }
- for(j = 0; idos[j] && strcmp(idos[j],m_argv[0]); j++);
- if(mk_script) {
- strcpy(work, tmp->instr[i]);
- batch_it(work, display,
- (idos[j] != (char *)0));
- continue;
- }
- if(display)
- fprintf(stdout,"\n%s\n",tmp->instr[i]);
- #ifdef UNIX
- if(fork() != (-1)) {
- if(execvp(m_argv[0], m_argv) == (-1))
- instr_err();
- }
- else {
- wait(&go);
- if( (go &= 0xff00) )
- proc_err(go);
- }
- #else
- if(idos[j] != (char *)0) {
- strcpy(buff, tmp->instr[i]);
- zaplead(buff);
- if(system(buff) == (-1))
- instr_err();
- }
- else {
- go = spawnvp(P_WAIT, m_argv[0], m_argv);
- if(go == (-1))
- instr_err();
- if(go != 0)
- proc_err(go);
- }
- #endif
- }
- made++;
- }
- return(made);
- }
- batch_it(cmd, echo, isdos)
- char *cmd;
- int echo, isdos;
- {
- if(echo)
- fprintf(script_fp, "echo %s\n", cmd);
- zaplead(cmd);
- fprintf(script_fp, "%s\n", cmd);
- /* cannot check for dos function exit code */
- if(!isdos)
- fprintf(script_fp, "if errorlevel == 1 goto stop\n");
- }
- MK *get_targ(targ)
- char *targ;
- {
- reg MK *tmp;
-
- for(tmp = mk; tmp; tmp = tmp->next)
- if(!strcmp(tmp->targ, targ))
- return(tmp);
- return(NULL);
- }
- time_stamp(targ, dep)
- char *targ, *dep;
- {
- struct stat t, d;
-
- if(stat(targ, &t) == (-1) || stat(dep, &d) == (-1))
- return(1); /* fake or non-existant target */
- /* ***
- if(stat(dep, &d) == (-1)) {
- fprintf(stderr,"\nMake: file '%s' does not exist. Stop.\n",
- dep);
- - exit(2);
- }
- *** */
-
- if(t.st_mtime < d.st_mtime)
- return(1);
- return(0);
- }
- bld_arg(instr)
- char *instr;
- {
- int found;
- reg int i;
- reg char *p;
-
- strcpy(buff, instr);
- for(i = 0; i < MAXARG; m_argv[i++] = (char *)0)
- if(m_argv[i] == (char *)0)
- break;
- for(i = 0, p = buff; *p && i < MAXARG;)
- if(isspace(*p))
- for(; *p && isspace(*p); *p++ = '\0');
- else {
- ++found;
- m_argv[i++] = p;
- for(; *p && !isspace(*p); p++);
- }
- return(found);
- }
- zaplead(str)
- reg char *str;
- {
- reg int i;
-
- for(i = 0; str[i]; i++)
- if(!isspace(str[i]) && !nodisplay(str[i]))
- break;
- strcpy(str, &str[i]);
- }
- mk_err(targ)
- char *targ;
- {
- fprintf(stderr,"\nMake: don't know how to make '%s'\n",targ);
- exit(2);
- }
- instr_err()
- {
- fprintf(stderr,"\nMake: error bad instruction. Stop.\n");
- exit(2);
- }
- proc_err(err)
- int err;
- {
- fprintf(stderr,"\nMake: errors detected.\n*** Error code %d.\nStop.\n",
- err);
- exit(err);
- }
-