home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 September
/
Simtel20_Sept92.cdr
/
msdos
/
progjorn
/
pj_7_5.arc
/
MAKE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1989-05-05
|
10KB
|
448 lines
/*
* 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);
}