bammi@cwruecmp.UUCP (08/05/86)
#!/bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #!/bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # main.c # make.c # makefile # makefile.mmc # mmcomp.sh # mmlink.sh # read.mee # reader.c # This archive created: Tue Aug 5 02:46:37 1986 # By: Jwahar R. Bammi () export PATH; PATH=/bin:$PATH echo shar: extracting "'main.c'" '(6212 characters)' if test -f 'main.c' then echo shar: over-writing existing file "'main.c'" fi sed 's/^X//' << \SHAR_EOF > 'main.c' X#define ATARIST X X /*******************************************************\ X * * X * A full featured MAKE Clone * X * * X * Origional Author: (Thank You) * X * Neil Russell * X * ACSnet: caret@tictoc.oz * X * UUCP: ...!seismo!munnari!tictoc.oz!caret * X * ARPA: caret%tictoc.oz@seismo.arpa * X * * X * Atari St Port & C code cleanup: * X * Jwahar R. Bammi * X * UUCP: .....!decvax!cwruecmp!bammi * X * CSNET: bammi@case * X * ARPA: bammi%case@csnet-relay * X * CompuServe: 71515,155 * X * * X \*******************************************************/ X X X/* X * make [-f makefile] [-ins] [target(s) ...] X * X * (Better than EON mk but not quite as good as UNIX make) X * X * -f makefile name X * -i ignore exit status X * -n Pretend to make X * -p Print all macros & targets X * -q Question up-to-dateness of target. Return exit status 1 if not X * -r Don't not use inbuilt rules X * -s Make silently X * -t Touch files instead of making them X * -m Change memory requirements -- NOT in the Atari St version X * X * >>>>> net.sources posting by: X * X * Neil Russell X * ACSnet: caret@tictoc.oz X * UUCP: ...!seismo!munnari!tictoc.oz!caret X * ARPA: caret%tictoc.oz@seismo.arpa X * X * >>>>> 7/86 Jwahar R. Bammi Added support for Atari ST X * report any Atari ST related complaints/suggestions to X * decvax!cwruecmp!bammi X * bammi@case.CSNET X * bammi%case@csnet-relay.ARPA X * 71515,155 X */ X X#include <stdio.h> X#include "h.h" X X#ifndef ATARIST X#include <sys/stat.h> X#include <sys/err.h> X X#else X#include "astat.h" X X#endif /* ATARIST */ X X X#ifndef ATARIST X#define MEMSPACE (16384) X#endif /* ATARIST */ X X Xchar * myname; Xchar * makefile = ""; /* The make file */ X X#ifndef ATARIST Xunsigned int memspace = MEMSPACE; X#endif /* ATARIST */ X XFILE * ifd; /* Input file desciptor */ Xbool domake = TRUE; /* Go through the motions option */ Xbool ignore = FALSE; /* Ignore exit status option */ Xbool silent = FALSE; /* Silent option */ Xbool print = FALSE; /* Print debuging information */ Xbool rules = TRUE; /* Use inbuilt rules */ Xbool dotouch = FALSE;/* Touch files instead of making */ Xbool quest = FALSE; /* Question up-to-dateness of file */ X X Xvoid Xmain(argc, argv) Xint argc; Xchar ** argv; X{ X register char * p; /* For argument processing */ X int estat = 0; /* For question */ X register struct name * np; X extern FILE *fopen(); X extern int atoi(); X extern char *index(); X X#ifndef ATARIST X myname = (argc-- < 1) ? "make" : *argv++; X#else X myname = "make"; X argc--; argv++; X#endif /* ATARIST - TOS does not pass the prog. name in argv[0] */ X X while ((argc > 0) && (**argv == '-')) X { X argc--; /* One less to process */ X p = *argv++; /* Now processing this one */ X X while (*++p != '\0') X { X switch(*p) X { X case 'F': /* Goddamned MSDOS style shells pass caps */ X case 'f': /* Alternate file name */ X if (*++p == '\0') X { X if (argc-- <= 0) X usage(); X p = *argv++; X } X makefile = p; X goto end_of_args; X#ifndef ATARIST X case 'm': /* Change space requirements */ X if (*++p == '\0') X { X if (argc-- <= 0) X usage(); X p = *argv++; X } X memspace = atoi(p); X goto end_of_args; X#endif /* ATARIST */ X case 'N': X case 'n': /* Pretend mode */ X domake = FALSE; X break; X X case 'I': X case 'i': /* Ignore fault mode */ X ignore = TRUE; X break; X X case 'S': X case 's': /* Silent about commands */ X silent = TRUE; X break; X case 'P': X case 'p': X print = TRUE; X break; X case 'R': X case 'r': X rules = FALSE; X break; X case 'T': X case 't': X dotouch = TRUE; X break; X case 'Q': X case 'q': X quest = TRUE; X break; X default: /* Wrong option */ X usage(); X } X } X end_of_args:; X } X X#ifndef ATARIST X if (initalloc(memspace) == 0xffff) /* Must get memory for alloc */ X fatal("Cannot initalloc memory"); X#endif /* ATARIST */ X X if (strcmp(makefile, "-") == 0) /* Can use stdin as makefile */ X ifd = stdin; /* Will create havoc with Alcyons libs! */ X else X if (*makefile == '\0') /* If no file, then use default */ X { X if ((ifd = fopen(DEFN1, "r")) == (FILE *)0) X#ifndef ATARIST X if (errno != ER_NOTF) X fatal("Can't open %s; error %02x", DEFN1, errno); X#else X fatal("Can't open %s",DEFN1); X else X makefile = DEFN1; X#endif /* ATARIST */ X X#ifndef ATARIST X if ((ifd == (FILE *)0) X && ((ifd = fopen(DEFN2, "r")) == (FILE *)0)) X fatal("Can't open %s", DEFN2); X#endif /* ATARIST */ X } X else X if ((ifd = fopen(makefile, "r")) == (FILE *)0) X fatal("Can't open %s", makefile); X X makerules(); X X setmacro("$", "$"); X X while (argc && ((p = index(*argv, '=')) != (char *)NULL)) X { X char c; X X c = *p; X *p = '\0'; X setmacro(*argv, p+1); X *p = c; X X argv++; X argc--; X } X X X input(ifd); /* Input all the gunga */ X fclose(ifd); /* Finished with makefile */ X lineno = 0; /* Any calls to error now print no line number */ X X X if (print) X prt(); /* Print out structures */ X X np = newname(".SILENT"); X if (np->n_flag & N_TARG) X silent = TRUE; X X np = newname(".IGNORE"); X if (np->n_flag & N_TARG) X ignore = TRUE; X X precious(); X X if (!domake) X silent = FALSE; X X if (!firstname) X fatal("No targets defined"); X X circh(); /* Check circles in target definitions */ X X X if (!argc) X estat = make(firstname, 0); X else while (argc--) X { X if (!print && !silent && strcmp(*argv, "love") == 0) X printf("Not war!\n"); X estat |= make(newname(*argv++), 0); X } X X if (quest) X exit(estat); X else X exit(0); X} X X Xusage() X{ X#ifndef ATARIST X fprintf(stderr, "Usage: %s [-f makefile] [-inpqrst] [macro=val ...] [target(s) ...]\n", myname); X#else X fprintf(stderr, "Usage: make [-f makefile] [-inpqrst] [macro=val ...] [target(s) ...]\n"); X#endif /* ATARIST - argv[0] not passed by TOS - is Atari EVER going to fix this?? */ X exit(1); X} X X Xvoid Xfatal(msg, a1, a2, a3) Xchar *msg; X#ifdef ATARIST Xchar *a1; /* Better be else you will get junk for a2 */ Xint a2, a3; X#endif /* ATARIST - When will people learn that sizeof(int *) != sizeof(int) */ X{ X fprintf(stderr, "%s: ", myname); X fprintf(stderr, msg, a1, a2, a3); X fputc('\n', stderr); X exit(1); X} SHAR_EOF if test 6212 -ne "`wc -c 'main.c'`" then echo shar: error transmitting "'main.c'" '(should have been 6212 characters)' fi echo shar: extracting "'make.c'" '(5900 characters)' if test -f 'make.c' then echo shar: over-writing existing file "'make.c'" fi sed 's/^X//' << \SHAR_EOF > 'make.c' X#define ATARIST X X /*******************************************************\ X * * X * A full featured MAKE Clone * X * * X * Origional Author: (Thank You) * X * Neil Russell * X * ACSnet: caret@tictoc.oz * X * UUCP: ...!seismo!munnari!tictoc.oz!caret * X * ARPA: caret%tictoc.oz@seismo.arpa * X * * X * Atari St Port & C code cleanup: * X * Jwahar R. Bammi * X * UUCP: .....!decvax!cwruecmp!bammi * X * CSNET: bammi@case * X * ARPA: bammi%case@csnet-relay * X * CompuServe: 71515,155 * X * * X \*******************************************************/ X X X/* X * Do the actual making for make X */ X X#include <stdio.h> X#include "h.h" X X#ifndef ATARIST X#include <sys/stat.h> X#include <sys/err.h> X#else X#include "astat.h" X#endif /* ATARIST */ X X X#ifndef ATARIST X/* X * Exec a shell that returns exit status correctly (/bin/esh). X * The standard EON shell returns the process number of the last X * async command, used by the debugger (ugg). X * [exec on eon is like a fork+exec on unix] X */ Xint Xdosh(string, shell) Xchar * string; Xchar * shell; X{ X int number; X X return ((number = execl(shell, shell,"-c", string, 0)) == -1) ? X -1: /* couldn't start the shell */ X wait(number); /* return its exit status */ X} X X#else X /* Atari St will use the system() function defined in ststuff.c */ X X#define dosh(X,Y) system(X) X X#endif /* ATARIST */ X X/* X * Do commands to make a target X */ Xvoid Xdocmds(np) Xstruct name * np; X{ X bool ssilent = silent; X bool signore = ignore; X int estat; X register char * q; X register char * p; X char * shell; X register struct line * lp; X register struct cmd * cp; X X X#ifndef ATARIST X if (*(shell = getmacro("SHELL")) == '\0') X shell = ":bin/esh"; X#endif /* ATARIST - does not have any standard shell */ X X for (lp = np->n_line; lp; lp = lp->l_next) X for (cp = lp->l_cmd; cp; cp = cp->c_next) X { X strcpy(str1, cp->c_cmd); X expand(str1); X q = str1; X ssilent = silent; X signore = ignore; X while ((*q == '@') || (*q == '-')) X { X if (*q == '@') /* Specific silent */ X ssilent = TRUE; X else /* Specific ignore */ X signore = TRUE; X q++; /* Not part of the command */ X } X X if (!ssilent) X putchar('\t'); X X for (p=q; *p; p++) X { X if (*p == '\n' && p[1] != '\0') X { X *p = ' '; X if (!ssilent) X fputs("\\\n", stdout); X } X else if (!ssilent) X putchar(*p); X } X if (!ssilent) X putchar('\n'); X X if (domake) X { /* Get the shell to execute it */ X if ((estat = dosh(q, shell)) != 0) X { X if (estat == -1) X#ifndef ATARIST X fatal("Couldn't execute %s", shell); X#else X fatal("Couldn't execute %s", q); X#endif /* ATARIST */ X else X { X printf("%s: Error code %d", myname, estat); X if (signore) X fputs(" (Ignored)\n", stdout); X else X { X putchar('\n'); X if (!(np->n_flag & N_PREC)) X if (unlink(np->n_name) == 0) X printf("%s: '%s' removed.\n", myname, np->n_name); X exit(estat); X } X } X } X } X } X} X X X/* X * Get the modification time of a file. If the first X * doesn't exist, it's modtime is set to 0. X */ X#ifndef ATARIST Xvoid Xmodtime(np) Xstruct name * np; X{ X struct stat info; X int fd; X X X if ((fd = open(np->n_name, 0)) < 0) X { X if (errno != ER_NOTF) X fatal("Can't open %s; error %02x", np->n_name, errno); X np->n_time = 0L; X } X else if (getstat(fd, &info) < 0) X fatal("Can't getstat %s; error %02x", np->n_name, errno); X else X np->n_time = info.st_mod; X X close(fd); X} X X#else X /* Atari St version of modtime() using getstat() X * see ststuff.c for Atari st version of getstat() X */ Xvoid Xmodtime(np) Xstruct name * np; X{ X struct stat info; X extern int getstat(); X X if (getstat(np->n_name, &info) < 0) X np->n_time = 0L; X else X { X FlipWords(&info.st_mod); X np->n_time = info.st_mod; X } X} X#endif /* ATARIST */ X X#ifndef ATARIST X/* X * Update the mod time of a file to now. X */ Xvoid Xtouch(np) Xstruct name * np; X{ X char c; X int fd; X X X if (!domake || !silent) X printf(" touch %s\n", np->n_name); X X if (domake) X { X if ((fd = open(np->n_name, 0)) < 0) X printf("%s: '%s' not touched - non-existant\n", X myname, np->n_name); X else X { X uread(fd, &c, 1, 0); X uwrite(fd, &c, 1); X } X close(fd); X } X} X X# else X/* X * Update the mod time of a file to now -- Atari St style X */ X Xvoid Xtouch(np) Xstruct name *np; X{ X register int fd; X X X if (!domake || !silent) X printf("\ttouch %s\n", np->n_name); X X if (domake) X { X if ((fd = Fopen(np->n_name, 0)) < 0) X printf("%s: '%s' not touched - non-existant\n", X myname, np->n_name); X else X { X long tim; X X Fseek(0L, fd, 2); /* Seek to EOF */ X tim = Gettime(); X FlipWords(&tim); X Fdatime( &tim, fd, 1); /* This time the Hitch Hikers X * guide is wrong X */ X Fclose(fd); X } X } X} X X#endif /* ATARIST */ X X/* X * Recursive routine to make a target. X */ Xint Xmake(np, level) Xstruct name * np; Xint level; X{ X register struct depend * dp; X register struct line * lp; X time_t dtime = 1L; X X X if (np->n_flag & N_DONE) X return 0; X X if (!np->n_time) X modtime(np); /* Gets modtime of this file */ X X if (rules) X { X for (lp = np->n_line; lp; lp = lp->l_next) X if (lp->l_cmd) X break; X if (!lp) X dyndep(np); X } X X if (!(np->n_flag & N_TARG) && np->n_time == 0L) X fatal("Don't know how to make %s", np->n_name); X X for (lp = np->n_line; lp; lp = lp->l_next) X for (dp = lp->l_dep; dp; dp = dp->d_next) X { X make(dp->d_name, level+1); X dtime = max(dtime, dp->d_name->n_time); X } X X np->n_flag |= N_DONE; X X if (quest) X { X rtime(&np->n_time); X return np->n_time < dtime; X } X else if (np->n_time < dtime) X { X if (dotouch) X touch(np); X else X { X setmacro("@", np->n_name); X docmds(np); X } X rtime(&np->n_time); X } X else if (level == 0) X printf("%s: '%s' is up to date\n", myname, np->n_name); X return 0; X} SHAR_EOF if test 5900 -ne "`wc -c 'make.c'`" then echo shar: error transmitting "'make.c'" '(should have been 5900 characters)' fi echo shar: extracting "'makefile'" '(561 characters)' if test -f 'makefile' then echo shar: over-writing existing file "'makefile'" fi sed 's/^X//' << \SHAR_EOF > 'makefile' X# Makefile for make X XBINDIR = d:\bin X XCPFLAGS = -i c:\include\ -DATARIST -DDECL X XOBJS1 = check.o input.o macro.o \ Xreader.o rules.o X XOBJS2 = main.o make.o ststuff.o X Xmake.prg : $(OBJS1) $(OBJS2) lnk X $(LINKER) [com[lnk]] X $(RELMOD) make X ${ECHO} Break out the Champainge X Xtouch.prg: touch.o X $(LINKER) touch.68k=gemstart,touch,osbind,gemlib X $(RELMOD) touch X $(ECHO) touch made X X X# Dependencies X X$(OBJS1) : h.h X$(OBJS2) : h.h astat.h X Xclean: X $(RM) *.o *.68k X Xinstall: make.prg touch.prg X $(CP) make.prg $(BINDIR)\make.prg X $(CP) touch.prg $(BINDIR)\touch.prg X SHAR_EOF if test 561 -ne "`wc -c 'makefile'`" then echo shar: error transmitting "'makefile'" '(should have been 561 characters)' fi echo shar: extracting "'makefile.mmc'" '(475 characters)' if test -f 'makefile.mmc' then echo shar: over-writing existing file "'makefile.mmc'" fi sed 's/^X//' << \SHAR_EOF > 'makefile.mmc' X# Makefile for make X XBINDIR = d:\bin X X XOBJS1 = check.o input.o macro.o \ Xreader.o rules.o X XOBJS2 = main.o make.o ststuff.o X Xmake.prg : $(OBJS1) $(OBJS2) X $(LINKER) $(OBJS1) $(OBJS2) -o make.prg X ${ECHO} Break out the Champainge X Xtouch.prg: touch.o X $(LINKER) touch.o -o touch.prg X $(ECHO) touch made X X# Dependencies X X$(OBJS1) : h.h X$(OBJS2) : h.h astat.h X Xclean: X $(RM) *.o X Xinstall: make.prg touch.prg X $(CP) make.prg $(BINDIR)\make.prg X $(CP) touch.prg $(BINDIR)\touch.prg SHAR_EOF if test 475 -ne "`wc -c 'makefile.mmc'`" then echo shar: error transmitting "'makefile.mmc'" '(should have been 475 characters)' fi echo shar: extracting "'mmcomp.sh'" '(84 characters)' if test -f 'mmcomp.sh' then echo shar: over-writing existing file "'mmcomp.sh'" fi sed 's/^X//' << \SHAR_EOF > 'mmcomp.sh' Xmmlink check.o input.o macro.o main.o make.o reader.o rules.o ststuff.o -o make.prg SHAR_EOF if test 84 -ne "`wc -c 'mmcomp.sh'`" then echo shar: error transmitting "'mmcomp.sh'" '(should have been 84 characters)' fi echo shar: extracting "'mmlink.sh'" '(84 characters)' if test -f 'mmlink.sh' then echo shar: over-writing existing file "'mmlink.sh'" fi sed 's/^X//' << \SHAR_EOF > 'mmlink.sh' Xmmlink check.o input.o macro.o main.o make.o reader.o rules.o ststuff.o -o make.prg SHAR_EOF if test 84 -ne "`wc -c 'mmlink.sh'`" then echo shar: error transmitting "'mmlink.sh'" '(should have been 84 characters)' fi echo shar: extracting "'read.mee'" '(757 characters)' if test -f 'read.mee' then echo shar: over-writing existing file "'read.mee'" fi sed 's/^X//' << \SHAR_EOF > 'read.mee' Xmake.c: X * Fix dosh() for your system. X * Call to getstat() in modtime() is like a fstat() on unix, X so it needs fixing. Xmain.c: X * You can have fun in main(). That call to initalloc() is X really special to EON. Xrules.c: X * Fix makerules() to suit you compilers for the auto suffix X stuff. X XIt supports most features of the UNIX make, the notable exceptions Xbeing libraries, and some subtleties with quoting. I will support Xproblems with it to a degree. Good luck. X XP.S. I never actually got around to writing a manual entry for X it, so the best course of action is to refer to the UNIX X manual entry, or the source. X X XNeil Russell XACSnet: caret@tictoc.oz XUUCP: ...!seismo!munnari!tictoc.oz!caret XARPA: caret%tictoc.oz@seismo.arpa X X X SHAR_EOF if test 757 -ne "`wc -c 'read.mee'`" then echo shar: error transmitting "'read.mee'" '(should have been 757 characters)' fi echo shar: extracting "'reader.c'" '(2569 characters)' if test -f 'reader.c' then echo shar: over-writing existing file "'reader.c'" fi sed 's/^X//' << \SHAR_EOF > 'reader.c' X#define ATARIST X X /*******************************************************\ X * * X * A full featured MAKE Clone * X * * X * Origional Author: (Thank You) * X * Neil Russell * X * ACSnet: caret@tictoc.oz * X * UUCP: ...!seismo!munnari!tictoc.oz!caret * X * ARPA: caret%tictoc.oz@seismo.arpa * X * * X * Atari St Port & C code cleanup: * X * Jwahar R. Bammi * X * UUCP: .....!decvax!cwruecmp!bammi * X * CSNET: bammi@case * X * ARPA: bammi%case@csnet-relay * X * CompuServe: 71515,155 * X * * X \*******************************************************/ X X X/* X * Read in makefile X */ X X X#include <stdio.h> X#include <ctype.h> X X#include "h.h" X X Xint lineno = 0; X X X/* X * Syntax error handler. Print message, with line number, and exits. X */ Xvoid Xerror(msg, a1, a2, a3) Xchar * msg; Xchar *a1; Xint a2, a3; X{ X fprintf(stderr, "%s: ", myname); X fprintf(stderr, msg, a1, a2, a3); X if (lineno) X fprintf(stderr, " on line %d", lineno); X fputc('\n', stderr); X exit(1); X} X X X/* X * Read a line into the supplied string of length LZ. Remove X * comments, ignore blank lines. Deal with quoted (\) #, and X * quoted newlines. If EOF return TRUE. X */ Xbool Xgetline(str, fd) Xchar * str; XFILE * fd; X{ X register char * p; X char * q; X int pos = 0; X extern char * fgets(); X X for (;;) X { X if(fgets((char *)((long)str + (long)pos), (int)(LZ-pos), fd) == X (char *)0) X return TRUE; /* EOF */ X X lineno++; X X if ((p = index((char *)((long)str+(long)pos), '\n')) == X (char *)0) X error("Line too long"); X X if (p[-1] == '\\') X { X p[-1] = '\n'; X pos = (int)((long)p - (long)str); X continue; X } X X p = str; X while (((q = index(p, '#')) != (char *)0) && X (p != q) && (q[-1] == '\\')) X { X char *a; X X a = q - 1; /* Del \ chr; move rest back */ X p = q; X while (*a++ = *q++) X ; X } X if (q != (char *)0) X { X q[0] = '\n'; X q[1] = '\0'; X } X X p = str; X while (isspace(*p)) /* Checking for blank */ X p++; X X if (*p != '\0') X return FALSE; X pos = 0; X } X} X X X/* X * Get a word from the current line, surounded by white space. X * return a pointer to it. String returned has no white spaces X * in it. X */ Xchar * Xgettok(ptr) Xchar **ptr; X{ X register char * p; X X X while (isspace(**ptr)) /* Skip spaces */ X (*ptr)++; X X if (**ptr == '\0') /* Nothing after spaces */ X return NULL; X X p = *ptr; /* word starts here */ X X while ((**ptr != '\0') && (!isspace(**ptr))) X (*ptr)++; /* Find end of word */ X X *(*ptr)++ = '\0'; /* Terminate it */ X X return(p); X} SHAR_EOF if test 2569 -ne "`wc -c 'reader.c'`" then echo shar: error transmitting "'reader.c'" '(should have been 2569 characters)' fi # End of shell archive exit 0 -- Jwahar R. Bammi Usenet: .....!decvax!cwruecmp!bammi CSnet: bammi@case Arpa: bammi%case@csnet-relay CompuServe: 71515,155