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:
# astat.h
# check.c
# compile.sh
# decl.h
# h.h
# input.c
# link.sh
# lnk
# macro.c
# This archive created: Tue Aug 5 02:46:35 1986
# By: Jwahar R. Bammi ()
export PATH; PATH=/bin:$PATH
echo shar: extracting "'astat.h'" '(512 characters)'
if test -f 'astat.h'
then
echo shar: over-writing existing file "'astat.h'"
fi
sed 's/^X//' << \SHAR_EOF > 'astat.h'
X /************************************************\
X * *
X * astat.h - Retrofit <sys/stat.h> *
X * for the Atari St machines *
X * *
X * J.R. Bammi *
X * *
X \************************************************/
X
X
Xstruct stat
X{
X char st_sp1[21]; /* Junk */
X char st_mode; /* File attributes */
X time_t st_mod; /* Mod time, we use the date & time as 1 long */
X long st_size; /* File size */
X char st_sp2[14]; /* File name */
X};
SHAR_EOF
if test 512 -ne "`wc -c 'astat.h'`"
then
echo shar: error transmitting "'astat.h'" '(should have been 512 characters)'
fi
echo shar: extracting "'check.c'" '(2525 characters)'
if test -f 'check.c'
then
echo shar: over-writing existing file "'check.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'check.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 * Check structures for make.
X */
X
X#include <stdio.h>
X#include "h.h"
X
X
X/*
X * Prints out the structures as defined in memory. Good for check
X * that you make file does what you want (and for debugging make).
X */
Xvoid
Xprt()
X{
X register struct name * np;
X register struct depend * dp;
X register struct line * lp;
X register struct cmd * cp;
X register struct macro * mp;
X
X
X for (mp = macrohead; mp; mp = mp->m_next)
X fprintf(stderr, "%s = %s\n", mp->m_name, mp->m_val);
X
X fputc('\n', stderr);
X
X for (np = namehead.n_next; np; np = np->n_next)
X {
X fprintf(stderr, "%s:\n", np->n_name);
X for (lp = np->n_line; lp; lp = lp->l_next)
X {
X fputc(':', stderr);
X for (dp = lp->l_dep; dp; dp = dp->d_next)
X fprintf(stderr, " %s", dp->d_name->n_name);
X fputc('\n', stderr);
X
X for (cp = lp->l_cmd; cp; cp = cp->c_next)
X fprintf(stderr, "-\t%s\n", cp->c_cmd);
X fputc('\n', stderr);
X }
X fputc('\n', stderr);
X }
X}
X
X
X/*
X * Recursive routine that does the actual checking.
X */
Xvoid
Xcheck(np)
Xstruct name * np;
X{
X register struct depend * dp;
X register struct line * lp;
X
X
X if (np->n_flag & N_MARK)
X fatal("Circular dependency from %s", np->n_name);
X
X np->n_flag |= N_MARK;
X
X for (lp = np->n_line; lp; lp = lp->l_next)
X for (dp = lp->l_dep; dp; dp = dp->d_next)
X check(dp->d_name);
X
X np->n_flag &= ~N_MARK;
X}
X
X
X/*
X * Look for circular dependancies.
X * ie.
X * a: b
X * b: a
X * is a circular dep
X */
Xvoid
Xcirch()
X{
X register struct name * np;
X
X
X for (np = namehead.n_next; np; np = np->n_next)
X check(np);
X}
X
X
X/*
X * Check the target .PRECIOUS, and mark its dependentd as precious
X */
Xvoid
Xprecious()
X{
X register struct depend * dp;
X register struct line * lp;
X register struct name * np;
X
X
X if (!((np = newname(".PRECIOUS"))->n_flag & N_TARG))
X return;
X
X for (lp = np->n_line; lp; lp = lp->l_next)
X for (dp = lp->l_dep; dp; dp = dp->d_next)
X dp->d_name->n_flag |= N_PREC;
X}
SHAR_EOF
if test 2525 -ne "`wc -c 'check.c'`"
then
echo shar: error transmitting "'check.c'" '(should have been 2525 characters)'
fi
echo shar: extracting "'compile.sh'" '(119 characters)'
if test -f 'compile.sh'
then
echo shar: over-writing existing file "'compile.sh'"
fi
sed 's/^X//' << \SHAR_EOF > 'compile.sh'
Xcc -c check.c
Xcc -c input.c
Xcc -c macro.c
Xcc -c main.c
Xcc -c make.c
Xcc -c reader.c
Xcc -c rules.c
Xcc -c ststuff.c
SHAR_EOF
if test 119 -ne "`wc -c 'compile.sh'`"
then
echo shar: error transmitting "'compile.sh'" '(should have been 119 characters)'
fi
echo shar: extracting "'decl.h'" '(1126 characters)'
if test -f 'decl.h'
then
echo shar: over-writing existing file "'decl.h'"
fi
sed 's/^X//' << \SHAR_EOF > 'decl.h'
X /***********************************************\
X * *
X * Decl.h - extern declarations for C libarary *
X * *
X \***********************************************/
X
Xextern FILE *fopen(), *freopen(), *fdopen();
Xextern FILE *fopena(), *freopa();
Xextern FILE *fopenb(), *freopb();
X
X
Xextern char *etoa();
Xextern char *ftoa();
Xextern char *getpass();
Xextern char *index();
Xextern char *mktemp();
Xextern char *rindex();
Xextern char *sprintf();
Xextern char *strcat();
Xextern char *strcpy();
Xextern char *strncat();
Xextern char *strncpy();
Xextern char *calloc(), *malloc(), *realloc(), *sbrk();
Xextern char *gets(), *fgets();
Xextern char *ttyname();
X
Xextern double atan();
Xextern double atof();
Xextern double ceil();
Xextern double cos();
Xextern double exp();
Xextern double fabs();
Xextern double floor();
Xextern double fmod();
Xextern double log();
Xextern double pow();
Xextern double sin();
Xextern double sinh();
Xextern double sqrt();
Xextern double tan();
Xextern double tanh();
X
Xextern int strlen();
Xextern int (*signal())();
X
Xextern long atol();
Xextern long ftell();
Xextern long lseek(), tell();
Xextern long getl();
X
SHAR_EOF
if test 1126 -ne "`wc -c 'decl.h'`"
then
echo shar: error transmitting "'decl.h'" '(should have been 1126 characters)'
fi
echo shar: extracting "'h.h'" '(4053 characters)'
if test -f 'h.h'
then
echo shar: over-writing existing file "'h.h'"
fi
sed 's/^X//' << \SHAR_EOF > 'h.h'
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 * Include header for make
X *
X * -- 7/86 JRB Added Atari ST suport
X */
X#ifdef atarist
X#define ATARIST
X#endif
X
X#ifdef ATARIST
X
X#include <osbind.h>
X#include "decl.h"
X
X/* #define MEGRULES */ /* Define if default .c.o rule is to be
X * genarated to use the Megamax C Compiler
X */
X/* #define MEGAMAX */ /* If using Megamax C to compile Make
X * This symbol has NO relation to the
X * symbol MEGRULES
X */
X
X#ifdef MEGAMAX
X#define void /* Alcyon 4.14 understands void */
X#undef Fdatime /* Megamax has it incorrectly defined */
X#define Fdatime(a,b,c) gemdos(0x57,a,b,c)
X
X#endif /* MEGAMAX */
X
X#ifdef TRUE
X#undef TRUE
X#endif
X
X#ifdef FALSE
X#undef FALSE
X#endif
X
X#ifdef uchar
X#undef uchar
X#endif
X
X#ifdef NULL
X#undef NULL
X#define NULL 0L
X#endif
X
X#ifdef max
X#undef max
X#endif
X
X#ifdef MEGAMAX
X#define uchar char /* For the sake of Megamax and gang who still think
X * that unsigned is a type
X */
X#else
X#define uchar unsigned char
X
X#endif /* MEGAMAX */
X
X#else
X
X#ifndef uchar
X#define uchar unsigned char
X#endif
X
X#endif /* ATARIST */
X
X
X#define bool uchar
X#define time_t long
X#define TRUE (1)
X#define FALSE (0)
X#define max(a,b) ((a)>(b)?(a):(b))
X
X#define DEFN1 "makefile" /* Default names */
X
X#ifndef ATARIST
X#define DEFN2 "Makefile"
X#endif /* ATARIST - TOS is not case sensative */
X
X#ifdef ATARIST
X
X#define LZ 2048 /* BIG Line size */
X
X#else
X
X#define LZ 1024 /* Line Size */
X
X#endif /* ATARIST */
X
X
X/*
X * A name. This represents a file, either to be made, or existant
X */
X
Xstruct name
X{
X struct name * n_next; /* Next in the list of names */
X char * n_name; /* Called */
X struct line * n_line; /* Dependencies */
X time_t n_time; /* Modify time of this name */
X uchar n_flag; /* Info about the name */
X};
X
X#define N_MARK 0x01 /* For cycle check */
X#define N_DONE 0x02 /* Name looked at */
X#define N_TARG 0x04 /* Name is a target */
X#define N_PREC 0x08 /* Target is precious */
X
X/*
X * Definition of a target line.
X */
Xstruct line
X{
X struct line * l_next; /* Next line (for ::) */
X struct depend * l_dep; /* Dependents for this line */
X struct cmd * l_cmd; /* Commands for this line */
X};
X
X
X/*
X * List of dependents for a line
X */
Xstruct depend
X{
X struct depend * d_next; /* Next dependent */
X struct name * d_name; /* Name of dependent */
X};
X
X
X/*
X * Commands for a line
X */
Xstruct cmd
X{
X struct cmd * c_next; /* Next command line */
X char * c_cmd; /* Command line */
X};
X
X
X/*
X * Macro storage
X */
Xstruct macro
X{
X struct macro * m_next; /* Next variable */
X char * m_name; /* Called ... */
X char * m_val; /* Its value */
X uchar m_flag; /* Infinite loop check */
X};
X
Xextern char * myname;
Xextern struct name namehead;
Xextern struct macro * macrohead;
Xextern struct name * firstname;
Xextern bool silent;
Xextern bool ignore;
Xextern bool rules;
Xextern bool dotouch;
Xextern bool quest;
Xextern bool domake;
Xextern char str1[];
Xextern char str2[];
Xextern int lineno;
X
Xextern char * fgets();
Xextern char * index();
Xextern char * rindex();
Xextern char * malloc();
Xextern int errno;
X
Xchar * getmacro();
Xstruct macro * setmacro();
Xvoid input();
Xvoid error();
Xvoid fatal();
Xint make();
Xstruct name * newname();
Xstruct depend * newdep();
Xstruct cmd * newcmd();
Xvoid newline();
Xchar * suffix();
Xvoid touch();
Xvoid makerules();
Xchar * gettok();
Xvoid precious();
X
X#ifdef ATARIST
Xint system();
Xvoid FlipWords();
X#endif /* ATARIST */
SHAR_EOF
if test 4053 -ne "`wc -c 'h.h'`"
then
echo shar: error transmitting "'h.h'" '(should have been 4053 characters)'
fi
echo shar: extracting "'input.c'" '(6224 characters)'
if test -f 'input.c'
then
echo shar: over-writing existing file "'input.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'input.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 * Parse a makefile
X */
X
X
X#include <stdio.h>
X#include <ctype.h>
X
X#include "h.h"
X
X
Xstruct name namehead = {
X (struct name *)NULL,
X (char *)NULL,
X (struct line *)NULL,
X (time_t)0,
X (uchar)0
X };
X
Xstruct name * firstname = (struct name *)NULL;
X
Xchar str1[LZ]; /* General store */
Xchar str2[LZ];
X
X
X/*
X * Intern a name. Return a pointer to the name struct
X */
Xstruct name *
Xnewname(name)
Xchar * name;
X{
X register struct name * rp;
X register struct name * rrp;
X register char * cp;
X
X
X for
X (
X rp = namehead.n_next, rrp = &namehead;
X rp;
X rp = rp->n_next, rrp = rrp->n_next
X )
X if (strcmp(name, rp->n_name) == 0)
X return rp;
X
X if ((rp = (struct name *)malloc(sizeof (struct name)))
X == (struct name *)0)
X fatal("No memory for name");
X rrp->n_next = rp;
X rp->n_next = (struct name *)0;
X if ((cp = malloc(strlen(name)+1)) == (char *)0)
X fatal("No memory for name");
X strcpy(cp, name);
X rp->n_name = cp;
X rp->n_line = (struct line *)0;
X rp->n_time = (time_t)0;
X rp->n_flag = 0;
X
X return rp;
X}
X
X
X/*
X * Add a dependant to the end of the supplied list of dependants.
X * Return the new head pointer for that list.
X */
Xstruct depend *
Xnewdep(np, dp)
Xstruct name * np;
Xstruct depend * dp;
X{
X register struct depend * rp;
X register struct depend * rrp;
X
X
X if ((rp = (struct depend *)malloc(sizeof (struct depend)))
X == (struct depend *)0)
X fatal("No memory for dependant");
X rp->d_next = (struct depend *)0;
X rp->d_name = np;
X
X if (dp == (struct depend *)0)
X return rp;
X
X for (rrp = dp; rrp->d_next; rrp = rrp->d_next)
X ;
X
X rrp->d_next = rp;
X
X return dp;
X}
X
X
X/*
X * Add a command to the end of the supplied list of commands.
X * Return the new head pointer for that list.
X */
Xstruct cmd *
Xnewcmd(str, cp)
Xchar * str;
Xstruct cmd * cp;
X{
X register struct cmd * rp;
X register struct cmd * rrp;
X register char * rcp;
X
X
X if (rcp = rindex(str, '\n'))
X *rcp = '\0'; /* Loose newline */
X
X while (isspace(*str))
X str++;
X
X if (*str == '\0') /* If nothing left, the exit */
X return;
X
X if ((rp = (struct cmd *)malloc(sizeof (struct cmd)))
X == (struct cmd *)0)
X fatal("No memory for command");
X rp->c_next = (struct cmd *)0;
X if ((rcp = malloc(strlen(str)+1)) == (char *)0)
X fatal("No memory for command");
X strcpy(rcp, str);
X rp->c_cmd = rcp;
X
X if (cp == (struct cmd *)0)
X return rp;
X
X for (rrp = cp; rrp->c_next; rrp = rrp->c_next)
X ;
X
X rrp->c_next = rp;
X
X return cp;
X}
X
X
X/*
X * Add a new 'line' of stuff to a target. This check to see
X * if commands already exist for the target.
X */
Xvoid
Xnewline(np, dp, cp)
Xstruct name * np;
Xstruct depend * dp;
Xstruct cmd * cp;
X{
X bool hascmds = FALSE; /* Target has commands */
X register struct line * rp;
X register struct line * rrp;
X
X
X for
X (
X rp = np->n_line, rrp = (struct line *)0;
X rp;
X rrp = rp, rp = rp->l_next
X )
X if (rp->l_cmd)
X hascmds = TRUE;
X
X if (hascmds && cp)
X error("Commands defined twice for target %s", np->n_name);
X
X if ((rp = (struct line *)malloc(sizeof (struct line)))
X == (struct line *)0)
X fatal("No memory for line");
X rp->l_next = (struct line *)0;
X rp->l_dep = dp;
X rp->l_cmd = cp;
X
X if (rrp)
X rrp->l_next = rp;
X else
X np->n_line = rp;
X
X np->n_flag |= N_TARG;
X}
X
X#define Is_special(X) ( \
X (strcmp(X,".SUFFIXES") == 0) || \
X (strcmp(X,".IGNORE") == 0) || \
X (strcmp(X,".SILENT") == 0) || \
X (strcmp(X,".PRECIOUS") == 0) \
X )
X
X/*
X * Parse input from the makefile, and construct a tree structure
X * of it.
X */
Xvoid
Xinput(fd)
XFILE * fd;
X{
X char * p; /* General */
X char * q;
X struct name * np;
X struct depend * dp;
X struct cmd * cp;
X
X
X if (getline(str1, fd)) /* Read the first line */
X return;
X
X for(;;)
X {
X if (*str1 == '\t') /* Rules without targets */
X error("Rules not allowed here");
X
X p = str1;
X
X while (isspace(*p)) /* Find first target */
X p++;
X
X while (((q = index(p, '=')) != (char *)0) &&
X (p != q) && (q[-1] == '\\')) /* Find value */
X {
X register char * a;
X
X a = q - 1; /* Del \ chr; move rest back */
X p = q;
X while(*a++ = *q++)
X ;
X }
X
X if (q != (char *)0)
X {
X register char * a;
X
X *q++ = '\0'; /* Separate name and val */
X while (isspace(*q))
X q++;
X if (p = rindex(q, '\n'))
X *p = '\0';
X
X p = str1;
X if ((a = gettok(&p)) == (char *)0)
X error("No macro name");
X
X setmacro(a, q);
X
X if (getline(str1, fd))
X return;
X continue;
X }
X
X expand(str1);
X p = str1;
X
X while (((q = index(p, ':')) != (char *)0) &&
X (p != q) && (q[-1] == '\\')) /* Find dependents */
X {
X register char * a;
X
X a = q - 1; /* Del \ chr; move rest back */
X p = q;
X while(*a++ = *q++)
X ;
X }
X
X if (q == (char *)0)
X error("No targets provided");
X
X *q++ = '\0'; /* Separate targets and dependents */
X
X for (dp = (struct depend *)0; ((p = gettok(&q)) != (char *)0);)
X /* get list of dep's */
X {
X np = newname(p); /* Intern name */
X dp = newdep(np, dp); /* Add to dep list */
X }
X
X *((char *)((q = str1) + (long)strlen(str1) + 1L)) = '\0';
X /* Need two nulls for gettok (Remember separation) */
X
X cp = (struct cmd *)0;
X if (getline(str2, fd) == FALSE) /* Get commands */
X {
X while (*str2 == '\t')
X {
X cp = newcmd(&str2[0], cp);
X if (getline(str2, fd))
X break;
X }
X }
X
X while ((p = gettok(&q)) != (char *)0) /* Get list of targ's */
X {
X np = newname(p); /* Intern name */
X newline(np, dp, cp);
X if (!firstname)
X {
X if(!Is_special(p))
X firstname = np;
X }
X
X }
X
X if (feof(fd)) /* EOF? */
X return;
X
X strcpy(str1, str2);
X }
X}
SHAR_EOF
if test 6224 -ne "`wc -c 'input.c'`"
then
echo shar: error transmitting "'input.c'" '(should have been 6224 characters)'
fi
echo shar: extracting "'link.sh'" '(43 characters)'
if test -f 'link.sh'
then
echo shar: over-writing existing file "'link.sh'"
fi
sed 's/^X//' << \SHAR_EOF > 'link.sh'
Xlink68 [com[lnk]]
Xrelmod make
Xrm make.68k
X
SHAR_EOF
if test 43 -ne "`wc -c 'link.sh'`"
then
echo shar: error transmitting "'link.sh'" '(should have been 43 characters)'
fi
echo shar: extracting "'lnk'" '(89 characters)'
if test -f 'lnk'
then
echo shar: over-writing existing file "'lnk'"
fi
sed 's/^X//' << \SHAR_EOF > 'lnk'
Xmake.68k=gemstart,check,input,macro,main,make,reader,rules,ststuff, \
Xosbind,gemlib,libf
SHAR_EOF
if test 89 -ne "`wc -c 'lnk'`"
then
echo shar: error transmitting "'lnk'" '(should have been 89 characters)'
fi
echo shar: extracting "'macro.c'" '(3039 characters)'
if test -f 'macro.c'
then
echo shar: over-writing existing file "'macro.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'macro.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 * Macro control for make
X */
X
X#include <stdio.h>
X#include "h.h"
X
X
Xstruct macro * macrohead = (struct macro *)NULL;
X
X
Xstruct macro *
Xgetmp(name)
Xchar * name;
X{
X register struct macro * rp;
X
X for (rp = macrohead; rp; rp = rp->m_next)
X if (strcmp(name, rp->m_name) == 0)
X return rp;
X return (struct macro *)0;
X}
X
X
Xchar *
Xgetmacro(name)
Xchar * name;
X{
X struct macro * mp;
X
X if (mp = getmp(name))
X return mp->m_val;
X else
X return "";
X}
X
X
Xstruct macro *
Xsetmacro(name, val)
Xchar * name;
Xchar * val;
X{
X register struct macro * rp;
X register char * cp;
X
X
X /* Replace macro definition if it exists */
X for (rp = macrohead; rp; rp = rp->m_next)
X if (strcmp(name, rp->m_name) == 0)
X {
X free(rp->m_val); /* Free space from old */
X break;
X }
X
X if (!rp) /* If not defined, allocate space for new */
X {
X if ((rp = (struct macro *)malloc(sizeof (struct macro)))
X == (struct macro *)0)
X fatal("No memory for macro");
X
X rp->m_next = macrohead;
X macrohead = rp;
X rp->m_flag = FALSE;
X
X if ((cp = malloc(strlen(name)+1)) == (char *)0)
X fatal("No memory for macro");
X strcpy(cp, name);
X rp->m_name = cp;
X }
X
X if ((cp = malloc(strlen(val)+1)) == (char *)0)
X fatal("No memory for macro");
X strcpy(cp, val); /* Copy in new value */
X rp->m_val = cp;
X
X return rp;
X}
X
X
X/*
X * Do the dirty work for expand
X */
Xvoid
Xdoexp(to, from, len, buf)
Xchar ** to;
Xchar * from;
Xint * len;
Xchar * buf;
X{
X register char * rp;
X register char * p;
X register char * q;
X register struct macro * mp;
X
X
X rp = from;
X p = *to;
X while (*rp)
X {
X if (*rp != '$')
X {
X *p++ = *rp++;
X (*len)--;
X }
X else
X {
X q = buf;
X if (*++rp == '(')
X while (*++rp && *rp != ')')
X *q++ = *rp;
X else if (*rp == '{')
X while (*++rp && *rp != '}')
X *q++ = *rp;
X else if (!*rp)
X {
X *p++ = '$';
X break;
X }
X else
X *q++ = *rp;
X *q = '\0';
X if (*rp)
X rp++;
X if (!(mp = getmp(buf)))
X mp = setmacro(buf, "");
X if (mp->m_flag)
X fatal("Infinitely recursive macro %s", mp->m_name);
X mp->m_flag = TRUE;
X *to = p;
X doexp(to, mp->m_val, len, buf);
X p = *to;
X mp->m_flag = FALSE;
X }
X if (*len <= 0)
X error("Expanded line too line");
X }
X *p = '\0';
X *to = p;
X}
X
X
X/*
X * Expand any macros in str.
X */
Xvoid
Xexpand(str)
Xchar * str;
X{
X static char a[LZ];
X static char b[LZ];
X char * p = str;
X int len = LZ-1;
X
X strcpy(a, str);
X doexp(&p, a, &len, b);
X}
SHAR_EOF
if test 3039 -ne "`wc -c 'macro.c'`"
then
echo shar: error transmitting "'macro.c'" '(should have been 3039 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