Better ANSI C compatibility and portability:
+ Addition of function prototypes and include files. + Change function definitions to ANSI C style. + Initial support for CMake
This commit is contained in:
parent
10717cc791
commit
910643ccbb
23
util/make/CMakeLists.txt
Normal file
23
util/make/CMakeLists.txt
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
cmake_minimum_required (VERSION 2.6)
|
||||||
|
project (ack-make)
|
||||||
|
|
||||||
|
set(SRC
|
||||||
|
check.c
|
||||||
|
input.c
|
||||||
|
macro.c
|
||||||
|
make.c
|
||||||
|
main.c
|
||||||
|
reader.c
|
||||||
|
rules.c
|
||||||
|
h.h
|
||||||
|
)
|
||||||
|
|
||||||
|
# The following should be added if utime.h and unistd.h are
|
||||||
|
# available.
|
||||||
|
|
||||||
|
# add_definitions(-Dunix)
|
||||||
|
|
||||||
|
add_executable(${PROJECT_NAME} ${SRC})
|
||||||
|
|
||||||
|
install(TARGETS ${PROJECT_NAME} DESTINATION bin)
|
||||||
|
|
|
@ -1,42 +1,45 @@
|
||||||
Following is a repost of the public domain 'make' that I posted
|
Following is a repost of the public domain 'make' that I posted
|
||||||
to net.sources a couple of months ago. I have fixed a few bugs, and
|
to net.sources a couple of months ago. I have fixed a few bugs, and
|
||||||
added some more features, and the resulting changes amounted to
|
added some more features, and the resulting changes amounted to
|
||||||
about as much text as the whole program (hence the repost).
|
about as much text as the whole program (hence the repost).
|
||||||
|
|
||||||
For those that missed the net.sources posting, this is a public domain
|
For those that missed the net.sources posting, this is a public domain
|
||||||
re-implementation of the UNIX make program. There is no manual included;
|
re-implementation of the UNIX make program. There is no manual included;
|
||||||
for documentation, refer to a UNIX manual, or the source.
|
for documentation, refer to a UNIX manual, or the source.
|
||||||
|
|
||||||
Here is a list of the changes made:
|
Here is a list of the changes made:
|
||||||
|
|
||||||
i) If '-' (ignore) or '@' (silent) where used at the start
|
i) If '-' (ignore) or '@' (silent) where used at the start
|
||||||
of a command, their effect was not turned off for the following
|
of a command, their effect was not turned off for the following
|
||||||
commands.
|
commands.
|
||||||
ii) A special target (.SUFFIXES, .PRECIOUS) or a rule (.c.o, .a.o),
|
ii) A special target (.SUFFIXES, .PRECIOUS) or a rule (.c.o, .a.o),
|
||||||
if first in the file would be taken as the default target.
|
if first in the file would be taken as the default target.
|
||||||
This resulted in error messages like "Don't know how to
|
This resulted in error messages like "Don't know how to
|
||||||
make .c", because things like .SUFFIXES were being made.
|
make .c", because things like .SUFFIXES were being made.
|
||||||
This was further complicated by ---
|
This was further complicated by ---
|
||||||
iii) Special target lines with no dependents (ie. .SUFFIXES:\n)
|
iii) Special target lines with no dependents (ie. .SUFFIXES:\n)
|
||||||
were not clearing out the existing dependents like
|
were not clearing out the existing dependents like
|
||||||
they should.
|
they should.
|
||||||
iv) Default rules could not be redefined because of the error
|
iv) Default rules could not be redefined because of the error
|
||||||
checking for commands being defined twice. Now you are
|
checking for commands being defined twice. Now you are
|
||||||
allowed to define a target beinging with '.', having
|
allowed to define a target beinging with '.', having
|
||||||
no dependents with commands.
|
no dependents with commands.
|
||||||
v) The -q option didn't do the time comparison correctly,
|
v) The -q option didn't do the time comparison correctly,
|
||||||
or clear the variable used to keep track of this. Thus
|
or clear the variable used to keep track of this. Thus
|
||||||
it didn't work very well.
|
it didn't work very well.
|
||||||
vi) The syntax ${..} for macro's supported by UNIX make was
|
vi) The syntax ${..} for macro's supported by UNIX make was
|
||||||
not supported.
|
not supported.
|
||||||
vii) There wuz a couple of spelling errors.
|
vii) There wuz a couple of spelling errors.
|
||||||
viii) When make checked for implicit rules on targets without
|
viii) When make checked for implicit rules on targets without
|
||||||
a suffix, there were problems. (Note: The ~ feature of
|
a suffix, there were problems. (Note: The ~ feature of
|
||||||
UNIX make wasn't and still isn't supported)
|
UNIX make wasn't and still isn't supported)
|
||||||
ix) The -n option did not print @ lines like it was supposed to.
|
ix) The -n option did not print @ lines like it was supposed to.
|
||||||
x) :: added. (See UNIX manual)
|
x) :: added. (See UNIX manual)
|
||||||
xi) $? added. (see UNIX manual)
|
xi) $? added. (see UNIX manual)
|
||||||
|
|
||||||
Hacked further by Ceriel Jacobs to make it work better. Use this "make" to
|
Hacked further by Ceriel Jacobs to make it work better. Use this "make" to
|
||||||
install ACK under Microsoft Xenix V3.2. Some of the makefiles are just too
|
install ACK under Microsoft Xenix V3.2. Some of the makefiles are just too
|
||||||
big for the Xenix "make". Strange, they work on a PDP-11 ...
|
big for the Xenix "make". Strange, they work on a PDP-11 ...
|
||||||
|
|
||||||
|
Made it almost ISO C90 and POSIX portable by Carl Eric Codere, and
|
||||||
|
also made it safer by using correct datatypes on some library calls.
|
||||||
|
|
|
@ -7,64 +7,13 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "h.h"
|
#include "h.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Prints out the structures as defined in memory. Good for check
|
|
||||||
* that you make file does what you want (and for debugging make).
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
prt()
|
|
||||||
{
|
|
||||||
register struct name * np;
|
|
||||||
register struct depend * dp;
|
|
||||||
register struct line * lp;
|
|
||||||
register struct cmd * cp;
|
|
||||||
register struct macro * mp;
|
|
||||||
|
|
||||||
|
|
||||||
for (mp = macrohead; mp; mp = mp->m_next)
|
|
||||||
fprintf(stderr, "%s = %s\n", mp->m_name, mp->m_val);
|
|
||||||
|
|
||||||
fputc('\n', stderr);
|
|
||||||
|
|
||||||
for (np = namehead.n_next; np; np = np->n_next)
|
|
||||||
{
|
|
||||||
if (np->n_flag & N_DOUBLE)
|
|
||||||
fprintf(stderr, "%s::\n", np->n_name);
|
|
||||||
else
|
|
||||||
fprintf(stderr, "%s:\n", np->n_name);
|
|
||||||
if (np == firstname)
|
|
||||||
fprintf(stderr, "(MAIN NAME)\n");
|
|
||||||
for (lp = np->n_line; lp; lp = lp->l_next)
|
|
||||||
{
|
|
||||||
fputc(':', stderr);
|
|
||||||
for (dp = lp->l_dep; dp; dp = dp->d_next)
|
|
||||||
fprintf(stderr, " %s", dp->d_name->n_name);
|
|
||||||
fputc('\n', stderr);
|
|
||||||
|
|
||||||
for (cp = lp->l_cmd; cp; cp = cp->c_next)
|
|
||||||
#ifdef os9
|
|
||||||
fprintf(stderr, "- %s\n", cp->c_cmd);
|
|
||||||
#else
|
|
||||||
fprintf(stderr, "-\t%s\n", cp->c_cmd);
|
|
||||||
#endif
|
|
||||||
fputc('\n', stderr);
|
|
||||||
}
|
|
||||||
fputc('\n', stderr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Recursive routine that does the actual checking.
|
* Recursive routine that does the actual checking.
|
||||||
*/
|
*/
|
||||||
void
|
static void check(struct name *np)
|
||||||
check(np)
|
|
||||||
struct name * np;
|
|
||||||
{
|
{
|
||||||
register struct depend * dp;
|
register struct depend * dp;
|
||||||
register struct line * lp;
|
register struct line * lp;
|
||||||
|
|
||||||
|
|
||||||
if (np->n_flag & N_MARK)
|
if (np->n_flag & N_MARK)
|
||||||
fatal("Circular dependency from %s", np->n_name);
|
fatal("Circular dependency from %s", np->n_name);
|
||||||
|
@ -75,10 +24,51 @@ struct name * np;
|
||||||
for (dp = lp->l_dep; dp; dp = dp->d_next)
|
for (dp = lp->l_dep; dp; dp = dp->d_next)
|
||||||
check(dp->d_name);
|
check(dp->d_name);
|
||||||
|
|
||||||
np->n_flag &= ~N_MARK;
|
np->n_flag &= (uchar)~N_MARK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prints out the structures as defined in memory. Good for check
|
||||||
|
* that you make file does what you want (and for debugging make).
|
||||||
|
*/
|
||||||
|
void prt(void)
|
||||||
|
{
|
||||||
|
register struct name * np;
|
||||||
|
register struct depend * dp;
|
||||||
|
register struct line * lp;
|
||||||
|
register struct cmd * cp;
|
||||||
|
register struct macro * mp;
|
||||||
|
|
||||||
|
for (mp = macrohead; mp; mp = mp->m_next)
|
||||||
|
fprintf(stderr, "%s = %s\n", mp->m_name, mp->m_val);
|
||||||
|
|
||||||
|
fputc('\n', stderr);
|
||||||
|
|
||||||
|
for (np = namehead.n_next; np; np = np->n_next)
|
||||||
|
{
|
||||||
|
if (np->n_flag & N_DOUBLE)
|
||||||
|
fprintf(stderr, "%s::\n", np->n_name);
|
||||||
|
else
|
||||||
|
fprintf(stderr, "%s:\n", np->n_name);
|
||||||
|
if (np == firstname)
|
||||||
|
fprintf(stderr, "(MAIN NAME)\n");
|
||||||
|
for (lp = np->n_line; lp; lp = lp->l_next)
|
||||||
|
{
|
||||||
|
fputc(':', stderr);
|
||||||
|
for (dp = lp->l_dep; dp; dp = dp->d_next)
|
||||||
|
fprintf(stderr, " %s", dp->d_name->n_name);
|
||||||
|
fputc('\n', stderr);
|
||||||
|
|
||||||
|
for (cp = lp->l_cmd; cp; cp = cp->c_next)
|
||||||
|
fprintf(stderr, "-\t%s\n", cp->c_cmd);
|
||||||
|
fputc('\n', stderr);
|
||||||
|
}
|
||||||
|
fputc('\n', stderr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Look for circular dependancies.
|
* Look for circular dependancies.
|
||||||
* ie.
|
* ie.
|
||||||
|
@ -86,27 +76,22 @@ struct name * np;
|
||||||
* b: a
|
* b: a
|
||||||
* is a circular dep
|
* is a circular dep
|
||||||
*/
|
*/
|
||||||
void
|
void circh(void)
|
||||||
circh()
|
|
||||||
{
|
{
|
||||||
register struct name * np;
|
register struct name * np;
|
||||||
|
|
||||||
|
|
||||||
for (np = namehead.n_next; np; np = np->n_next)
|
for (np = namehead.n_next; np; np = np->n_next)
|
||||||
check(np);
|
check(np);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check the target .PRECIOUS, and mark its dependentd as precious
|
* Check the target .PRECIOUS, and mark its dependentd as precious
|
||||||
*/
|
*/
|
||||||
void
|
void precious(void)
|
||||||
precious()
|
|
||||||
{
|
{
|
||||||
register struct depend * dp;
|
register struct depend * dp;
|
||||||
register struct line * lp;
|
register struct line * lp;
|
||||||
register struct name * np;
|
register struct name * np;
|
||||||
|
|
||||||
|
|
||||||
if (!((np = newname(".PRECIOUS"))->n_flag & N_TARG))
|
if (!((np = newname(".PRECIOUS"))->n_flag & N_TARG))
|
||||||
return;
|
return;
|
||||||
|
|
182
util/make/h.h
182
util/make/h.h
|
@ -1,145 +1,127 @@
|
||||||
/*
|
/*
|
||||||
* Include header for make
|
* Include header for make
|
||||||
*
|
*
|
||||||
* $Header$
|
* $Header$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef uchar
|
#ifndef uchar
|
||||||
#ifdef os9
|
#define uchar unsigned char
|
||||||
#define uchar char
|
|
||||||
#define void int
|
|
||||||
#define fputc putc
|
|
||||||
#else
|
|
||||||
#define uchar unsigned char
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define bool int
|
#include <time.h>
|
||||||
#define time_t long
|
|
||||||
#define TRUE (1)
|
|
||||||
#define FALSE (0)
|
|
||||||
#define max(a,b) ((a)>(b)?(a):(b))
|
|
||||||
|
|
||||||
#define DEFN1 "makefile" /* Default names */
|
#define bool int
|
||||||
#ifdef unix
|
#define TRUE (1)
|
||||||
#define DEFN2 "Makefile"
|
#define FALSE (0)
|
||||||
#endif
|
|
||||||
#ifdef eon
|
|
||||||
#define DEFN2 "Makefile"
|
|
||||||
#endif
|
|
||||||
/* os9 is case insensitive */
|
|
||||||
|
|
||||||
#define LZ (2048) /* Line size */
|
#define DEFN1 "makefile" /* Default names */
|
||||||
|
#define DEFN2 "Makefile"
|
||||||
|
|
||||||
|
#define LZ (2048) /* Line size */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A name. This represents a file, either to be made, or existant
|
* A name. This represents a file, either to be made, or existant
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct name
|
struct name
|
||||||
{
|
{
|
||||||
struct name * n_next; /* Next in the list of names */
|
struct name * n_next; /* Next in the list of names */
|
||||||
char * n_name; /* Called */
|
char * n_name; /* Called */
|
||||||
struct line * n_line; /* Dependencies */
|
struct line * n_line; /* Dependencies */
|
||||||
time_t n_time; /* Modify time of this name */
|
time_t n_time; /* Modify time of this name */
|
||||||
uchar n_flag; /* Info about the name */
|
uchar n_flag; /* Info about the name */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define N_MARK 0x01 /* For cycle check */
|
#define N_MARK 0x01 /* For cycle check */
|
||||||
#define N_DONE 0x02 /* Name looked at */
|
#define N_DONE 0x02 /* Name looked at */
|
||||||
#define N_TARG 0x04 /* Name is a target */
|
#define N_TARG 0x04 /* Name is a target */
|
||||||
#define N_PREC 0x08 /* Target is precious */
|
#define N_PREC 0x08 /* Target is precious */
|
||||||
#define N_DOUBLE 0x10 /* Double colon target */
|
#define N_DOUBLE 0x10 /* Double colon target */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Definition of a target line.
|
* Definition of a target line.
|
||||||
*/
|
*/
|
||||||
struct line
|
struct line
|
||||||
{
|
{
|
||||||
struct line * l_next; /* Next line (for ::) */
|
struct line * l_next; /* Next line (for ::) */
|
||||||
struct depend * l_dep; /* Dependents for this line */
|
struct depend * l_dep; /* Dependents for this line */
|
||||||
struct cmd * l_cmd; /* Commands for this line */
|
struct cmd * l_cmd; /* Commands for this line */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* List of dependents for a line
|
* List of dependents for a line
|
||||||
*/
|
*/
|
||||||
struct depend
|
struct depend
|
||||||
{
|
{
|
||||||
struct depend * d_next; /* Next dependent */
|
struct depend * d_next; /* Next dependent */
|
||||||
struct name * d_name; /* Name of dependent */
|
struct name * d_name; /* Name of dependent */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Commands for a line
|
* Commands for a line
|
||||||
*/
|
*/
|
||||||
struct cmd
|
struct cmd
|
||||||
{
|
{
|
||||||
struct cmd * c_next; /* Next command line */
|
struct cmd * c_next; /* Next command line */
|
||||||
char * c_cmd; /* Command line */
|
char * c_cmd; /* Command line */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Macro storage
|
* Macro storage
|
||||||
*/
|
*/
|
||||||
struct macro
|
struct macro
|
||||||
{
|
{
|
||||||
struct macro * m_next; /* Next variable */
|
struct macro * m_next; /* Next variable */
|
||||||
char * m_name; /* Called ... */
|
char * m_name; /* Called ... */
|
||||||
char * m_val; /* Its value */
|
char * m_val; /* Its value */
|
||||||
uchar m_flag; /* Infinite loop check */
|
uchar m_flag; /* Infinite loop check */
|
||||||
uchar m_prio; /* 5 levels:
|
uchar m_prio; /* 5 levels:
|
||||||
- 0 for internal ($(CC), etc)
|
- 0 for internal ($(CC), etc)
|
||||||
- 1 (reserved for environment)
|
- 1 (reserved for environment)
|
||||||
- 2 for makefile
|
- 2 for makefile
|
||||||
- 3 for command line
|
- 3 for command line
|
||||||
- 4 for special ($*,$<, etc)
|
- 4 for special ($*,$<, etc)
|
||||||
*/
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
extern char * myname;
|
extern char * myname;
|
||||||
extern struct name namehead;
|
extern struct name namehead;
|
||||||
extern struct macro * macrohead;
|
extern struct macro * macrohead;
|
||||||
extern struct name * firstname;
|
extern struct name * firstname;
|
||||||
extern bool silent;
|
extern bool silent;
|
||||||
extern bool ignore;
|
extern bool ignore;
|
||||||
extern bool rules;
|
extern bool rules;
|
||||||
extern bool dotouch;
|
extern bool dotouch;
|
||||||
extern bool quest;
|
extern bool quest;
|
||||||
extern bool domake;
|
extern bool domake;
|
||||||
extern char str1[];
|
extern char str1[];
|
||||||
extern char str2[];
|
extern char str2[];
|
||||||
extern int lineno;
|
extern int lineno;
|
||||||
|
|
||||||
char * fgets();
|
void circh(void);
|
||||||
char * index();
|
char * getmacro(char* name);
|
||||||
char * rindex();
|
struct macro * setmacro(char* name, char* val, int prio);
|
||||||
char * malloc();
|
void input(FILE *fd);
|
||||||
char * strcpy();
|
void error(char *msg, char* a1);
|
||||||
char * strcat();
|
void expand(char *str);
|
||||||
extern int errno;
|
void fatal(char* msg, char* value);
|
||||||
|
bool dyndep(struct name *np);
|
||||||
void circh();
|
int make(struct name *np, int level);
|
||||||
char * getmacro();
|
void modtime(struct name *np);
|
||||||
struct macro * setmacro();
|
struct name *newname(char *name);
|
||||||
void input();
|
struct depend *newdep(struct name *np, struct depend *dp);
|
||||||
void error();
|
struct cmd *newcmd(char *str, struct cmd *cp);
|
||||||
void expand();
|
void newline(struct name *np, struct depend *dp, struct cmd *cp, int flag);
|
||||||
void fatal();
|
void prt(void);
|
||||||
int make();
|
char *suffix(char *name);
|
||||||
void modtime();
|
void touch(struct name *np);
|
||||||
struct name * newname();
|
void makerules(void);
|
||||||
struct depend * newdep();
|
char *gettok(char **ptr);
|
||||||
struct cmd * newcmd();
|
void precious(void);
|
||||||
void newline();
|
bool mgetline(char* str, FILE* fd);
|
||||||
void prt();
|
|
||||||
char * suffix();
|
|
||||||
void touch();
|
|
||||||
void makerules();
|
|
||||||
char * gettok();
|
|
||||||
void precious();
|
|
||||||
|
|
|
@ -1,80 +1,67 @@
|
||||||
/*
|
/*
|
||||||
* Parse a makefile
|
* Parse a makefile
|
||||||
*
|
*
|
||||||
* $Header$
|
* $Header$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include "h.h"
|
#include "h.h"
|
||||||
|
|
||||||
|
struct name namehead;
|
||||||
|
struct name * firstname;
|
||||||
|
|
||||||
struct name namehead;
|
char str1[LZ]; /* General store */
|
||||||
struct name * firstname;
|
char str2[LZ];
|
||||||
|
|
||||||
char str1[LZ]; /* General store */
|
|
||||||
char str2[LZ];
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Intern a name. Return a pointer to the name struct
|
* Intern a name. Return a pointer to the name struct
|
||||||
*/
|
*/
|
||||||
struct name *
|
struct name *newname(char *name)
|
||||||
newname(name)
|
|
||||||
char * name;
|
|
||||||
{
|
{
|
||||||
register struct name * rp;
|
|
||||||
register struct name * rrp;
|
|
||||||
register char * cp;
|
|
||||||
|
|
||||||
|
register struct name * rp;
|
||||||
|
register struct name * rrp;
|
||||||
|
register char * cp;
|
||||||
|
|
||||||
for
|
for (rp = namehead.n_next, rrp = &namehead; rp;
|
||||||
(
|
rp = rp->n_next, rrp = rrp->n_next)
|
||||||
rp = namehead.n_next, rrp = &namehead;
|
|
||||||
rp;
|
|
||||||
rp = rp->n_next, rrp = rrp->n_next
|
|
||||||
)
|
|
||||||
if (strcmp(name, rp->n_name) == 0)
|
if (strcmp(name, rp->n_name) == 0)
|
||||||
return rp;
|
return rp;
|
||||||
|
|
||||||
if ((rp = (struct name *)malloc(sizeof (struct name)))
|
if ((rp = (struct name *) malloc(sizeof(struct name))) == (struct name *) 0)
|
||||||
== (struct name *)0)
|
fatal("No memory for name",NULL);
|
||||||
fatal("No memory for name");
|
|
||||||
rrp->n_next = rp;
|
rrp->n_next = rp;
|
||||||
rp->n_next = (struct name *)0;
|
rp->n_next = (struct name *) 0;
|
||||||
if ((cp = malloc((unsigned)(strlen(name)+1))) == (char *)0)
|
if ((cp = malloc((unsigned) (strlen(name) + 1))) == (char *) 0)
|
||||||
fatal("No memory for name");
|
fatal("No memory for name",NULL);
|
||||||
strcpy(cp, name);
|
strcpy(cp, name);
|
||||||
rp->n_name = cp;
|
rp->n_name = cp;
|
||||||
rp->n_line = (struct line *)0;
|
rp->n_line = (struct line *) 0;
|
||||||
rp->n_time = (time_t)0;
|
rp->n_time = (time_t) 0;
|
||||||
rp->n_flag = 0;
|
rp->n_flag = 0;
|
||||||
|
|
||||||
return rp;
|
return rp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add a dependant to the end of the supplied list of dependants.
|
* Add a dependant to the end of the supplied list of dependants.
|
||||||
* Return the new head pointer for that list.
|
* Return the new head pointer for that list.
|
||||||
*/
|
*/
|
||||||
struct depend *
|
struct depend *newdep(struct name *np, struct depend *dp)
|
||||||
newdep(np, dp)
|
|
||||||
struct name * np;
|
|
||||||
struct depend * dp;
|
|
||||||
{
|
{
|
||||||
register struct depend * rp;
|
register struct depend * rp;
|
||||||
register struct depend * rrp;
|
register struct depend * rrp;
|
||||||
|
|
||||||
|
if ((rp = (struct depend *) malloc(sizeof(struct depend)))
|
||||||
if ((rp = (struct depend *)malloc(sizeof (struct depend)))
|
== (struct depend *) 0)
|
||||||
== (struct depend *)0)
|
fatal("No memory for dependant",NULL);
|
||||||
fatal("No memory for dependant");
|
rp->d_next = (struct depend *) 0;
|
||||||
rp->d_next = (struct depend *)0;
|
|
||||||
rp->d_name = np;
|
rp->d_name = np;
|
||||||
|
|
||||||
if (dp == (struct depend *)0)
|
if (dp == (struct depend *) 0)
|
||||||
return rp;
|
return rp;
|
||||||
|
|
||||||
for (rrp = dp; rrp->d_next; rrp = rrp->d_next)
|
for (rrp = dp; rrp->d_next; rrp = rrp->d_next)
|
||||||
|
@ -85,40 +72,34 @@ struct depend * dp;
|
||||||
return dp;
|
return dp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add a command to the end of the supplied list of commands.
|
* Add a command to the end of the supplied list of commands.
|
||||||
* Return the new head pointer for that list.
|
* Return the new head pointer for that list.
|
||||||
*/
|
*/
|
||||||
struct cmd *
|
struct cmd *newcmd(char *str, struct cmd *cp)
|
||||||
newcmd(str, cp)
|
|
||||||
char * str;
|
|
||||||
struct cmd * cp;
|
|
||||||
{
|
{
|
||||||
register struct cmd * rp;
|
register struct cmd * rp;
|
||||||
register struct cmd * rrp;
|
register struct cmd * rrp;
|
||||||
register char * rcp;
|
register char * rcp;
|
||||||
|
|
||||||
|
if ((rcp = strrchr(str, '\n')))
|
||||||
if (rcp = rindex(str, '\n'))
|
*rcp = '\0'; /* Loose newline */
|
||||||
*rcp = '\0'; /* Loose newline */
|
|
||||||
|
|
||||||
while (isspace(*str))
|
while (isspace(*str))
|
||||||
str++;
|
str++;
|
||||||
|
|
||||||
if (*str == '\0') /* If nothing left, the exit */
|
if (*str == '\0') /* If nothing left, the exit */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if ((rp = (struct cmd *)malloc(sizeof (struct cmd)))
|
if ((rp = (struct cmd *) malloc(sizeof(struct cmd))) == (struct cmd *) 0)
|
||||||
== (struct cmd *)0)
|
fatal("No memory for command",NULL);
|
||||||
fatal("No memory for command");
|
rp->c_next = (struct cmd *) 0;
|
||||||
rp->c_next = (struct cmd *)0;
|
if ((rcp = malloc((unsigned) (strlen(str) + 1))) == (char *) 0)
|
||||||
if ((rcp = malloc((unsigned)(strlen(str)+1))) == (char *)0)
|
fatal("No memory for command",NULL);
|
||||||
fatal("No memory for command");
|
|
||||||
strcpy(rcp, str);
|
strcpy(rcp, str);
|
||||||
rp->c_cmd = rcp;
|
rp->c_cmd = rcp;
|
||||||
|
|
||||||
if (cp == (struct cmd *)0)
|
if (cp == (struct cmd *) 0)
|
||||||
return rp;
|
return rp;
|
||||||
|
|
||||||
for (rrp = cp; rrp->c_next; rrp = rrp->c_next)
|
for (rrp = cp; rrp->c_next; rrp = rrp->c_next)
|
||||||
|
@ -129,58 +110,48 @@ struct cmd * cp;
|
||||||
return cp;
|
return cp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add a new 'line' of stuff to a target. This check to see
|
* Add a new 'line' of stuff to a target. This check to see
|
||||||
* if commands already exist for the target. If flag is set,
|
* if commands already exist for the target. If flag is set,
|
||||||
* the line is a double colon target.
|
* the line is a double colon target.
|
||||||
*
|
*
|
||||||
* Kludges:
|
* Kludges:
|
||||||
* i) If the new name begins with a '.', and there are no dependents,
|
* i) If the new name begins with a '.', and there are no dependents,
|
||||||
* then the target must cease to be a target. This is for .SUFFIXES.
|
* then the target must cease to be a target. This is for .SUFFIXES.
|
||||||
* ii) If the new name begins with a '.', with no dependents and has
|
* ii) If the new name begins with a '.', with no dependents and has
|
||||||
* commands, then replace the current commands. This is for
|
* commands, then replace the current commands. This is for
|
||||||
* redefining commands for a default rule.
|
* redefining commands for a default rule.
|
||||||
* Neither of these free the space used by dependents or commands,
|
* Neither of these free the space used by dependents or commands,
|
||||||
* since they could be used by another target.
|
* since they could be used by another target.
|
||||||
*/
|
*/
|
||||||
void
|
void newline(struct name *np, struct depend *dp, struct cmd *cp, int flag)
|
||||||
newline(np, dp, cp, flag)
|
|
||||||
struct name * np;
|
|
||||||
struct depend * dp;
|
|
||||||
struct cmd * cp;
|
|
||||||
{
|
{
|
||||||
bool hascmds = FALSE; /* Target has commands */
|
bool hascmds = FALSE; /* Target has commands */
|
||||||
register struct line * rp;
|
register struct line * rp;
|
||||||
register struct line * rrp;
|
register struct line * rrp;
|
||||||
|
|
||||||
|
|
||||||
/* Handle the .SUFFIXES case */
|
/* Handle the .SUFFIXES case */
|
||||||
if (! strcmp(np->n_name, ".SUFFIXES") && !dp && !cp)
|
if (!strcmp(np->n_name, ".SUFFIXES") && !dp && !cp)
|
||||||
{
|
{
|
||||||
for (rp = np->n_line; rp; rp = rrp)
|
for (rp = np->n_line; rp; rp = rrp)
|
||||||
{
|
{
|
||||||
rrp = rp->l_next;
|
rrp = rp->l_next;
|
||||||
free((char *)rp);
|
free((char *) rp);
|
||||||
}
|
}
|
||||||
np->n_line = (struct line *)0;
|
np->n_line = (struct line *) 0;
|
||||||
np->n_flag &= ~N_TARG;
|
np->n_flag &= (uchar)~N_TARG;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This loop must happen since rrp is used later. */
|
/* This loop must happen since rrp is used later. */
|
||||||
for
|
for (rp = np->n_line, rrp = (struct line *) 0; rp;
|
||||||
(
|
rrp = rp, rp = rp->l_next)
|
||||||
rp = np->n_line, rrp = (struct line *)0;
|
|
||||||
rp;
|
|
||||||
rrp = rp, rp = rp->l_next
|
|
||||||
)
|
|
||||||
if (rp->l_cmd)
|
if (rp->l_cmd)
|
||||||
hascmds = TRUE;
|
hascmds = TRUE;
|
||||||
|
|
||||||
if (hascmds && cp && !(np->n_flag & N_DOUBLE))
|
if (hascmds && cp && !(np->n_flag & N_DOUBLE))
|
||||||
/* Handle the implicit rules redefinition case */
|
/* Handle the implicit rules redefinition case */
|
||||||
if (np->n_name[0] == '.' && dp == (struct depend *)0)
|
if (np->n_name[0] == '.' && dp == (struct depend *) 0)
|
||||||
{
|
{
|
||||||
np->n_line->l_cmd = cp;
|
np->n_line->l_cmd = cp;
|
||||||
return;
|
return;
|
||||||
|
@ -188,13 +159,12 @@ struct cmd * cp;
|
||||||
else
|
else
|
||||||
error("Commands defined twice for target %s", np->n_name);
|
error("Commands defined twice for target %s", np->n_name);
|
||||||
if (np->n_flag & N_TARG)
|
if (np->n_flag & N_TARG)
|
||||||
if (!(np->n_flag & N_DOUBLE) != !flag) /* like xor */
|
if (!(np->n_flag & N_DOUBLE) != !flag) /* like xor */
|
||||||
error("Inconsistent rules for target %s", np->n_name);
|
error("Inconsistent rules for target %s", np->n_name);
|
||||||
|
|
||||||
if ((rp = (struct line *)malloc(sizeof (struct line)))
|
if ((rp = (struct line *) malloc(sizeof(struct line))) == (struct line *) 0)
|
||||||
== (struct line *)0)
|
fatal("No memory for line",NULL);
|
||||||
fatal("No memory for line");
|
rp->l_next = (struct line *) 0;
|
||||||
rp->l_next = (struct line *)0;
|
|
||||||
rp->l_dep = dp;
|
rp->l_dep = dp;
|
||||||
rp->l_cmd = cp;
|
rp->l_cmd = cp;
|
||||||
|
|
||||||
|
@ -208,68 +178,60 @@ struct cmd * cp;
|
||||||
np->n_flag |= N_DOUBLE;
|
np->n_flag |= N_DOUBLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse input from the makefile, and construct a tree structure
|
* Parse input from the makefile, and construct a tree structure
|
||||||
* of it.
|
* of it.
|
||||||
*/
|
*/
|
||||||
void
|
void input(FILE *fd)
|
||||||
input(fd)
|
|
||||||
FILE * fd;
|
|
||||||
{
|
{
|
||||||
char * p; /* General */
|
char * p; /* General */
|
||||||
char * q;
|
char * q;
|
||||||
struct name * np;
|
struct name * np;
|
||||||
struct depend * dp;
|
struct depend * dp;
|
||||||
struct cmd * cp;
|
struct cmd * cp;
|
||||||
bool dbl;
|
bool dbl;
|
||||||
|
|
||||||
|
if (mgetline(str1, fd)) /* Read the first line */
|
||||||
if (getline(str1, fd)) /* Read the first line */
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for(;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
#ifdef os9
|
if (*str1 == '\t') /* Rules without targets */
|
||||||
if (*str1 == ' ') /* Rules without targets */
|
error("Rules not allowed here", NULL );
|
||||||
#else
|
|
||||||
if (*str1 == '\t') /* Rules without targets */
|
|
||||||
#endif
|
|
||||||
error("Rules not allowed here");
|
|
||||||
|
|
||||||
p = str1;
|
p = str1;
|
||||||
|
|
||||||
while (isspace(*p)) /* Find first target */
|
while (isspace(*p)) /* Find first target */
|
||||||
p++;
|
p++;
|
||||||
|
|
||||||
while (((q = index(p, '=')) != (char *)0) &&
|
while (((q = strchr(p, '=')) != (char *) 0) && (p != q)
|
||||||
(p != q) && (q[-1] == '\\')) /* Find value */
|
&& (q[-1] == '\\')) /* Find value */
|
||||||
{
|
{
|
||||||
register char * a;
|
register char * a;
|
||||||
|
|
||||||
a = q - 1; /* Del \ chr; move rest back */
|
a = q - 1; /* Del \ chr; move rest back */
|
||||||
p = q;
|
p = q;
|
||||||
while(*a++ = *q++)
|
while ((*a++ = *q++))
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (q != (char *)0)
|
if (q != (char *) 0)
|
||||||
{
|
{
|
||||||
register char * a;
|
register char * a;
|
||||||
|
|
||||||
*q++ = '\0'; /* Separate name and val */
|
*q++ = '\0'; /* Separate name and val */
|
||||||
while (isspace(*q))
|
while (isspace(*q))
|
||||||
q++;
|
q++;
|
||||||
if (p = rindex(q, '\n'))
|
if ((p = strrchr(q, '\n')))
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
|
|
||||||
p = str1;
|
p = str1;
|
||||||
if ((a = gettok(&p)) == (char *)0)
|
if ((a = gettok(&p)) == (char *) 0)
|
||||||
error("No macro name");
|
error("No macro name", NULL );
|
||||||
|
|
||||||
setmacro(a, q, 2);
|
setmacro(a, q, 2);
|
||||||
|
|
||||||
if (getline(str1, fd))
|
if (mgetline(str1, fd))
|
||||||
return;
|
return;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -277,23 +239,23 @@ FILE * fd;
|
||||||
expand(str1);
|
expand(str1);
|
||||||
p = str1;
|
p = str1;
|
||||||
|
|
||||||
while (((q = index(p, ':')) != (char *)0) &&
|
while (((q = strchr(p, ':')) != (char *) 0) && (p != q)
|
||||||
(p != q) && (q[-1] == '\\')) /* Find dependents */
|
&& (q[-1] == '\\')) /* Find dependents */
|
||||||
{
|
{
|
||||||
register char * a;
|
register char * a;
|
||||||
|
|
||||||
a = q - 1; /* Del \ chr; move rest back */
|
a = q - 1; /* Del \ chr; move rest back */
|
||||||
p = q;
|
p = q;
|
||||||
while(*a++ = *q++)
|
while ((*a++ = *q++))
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (q == (char *)0)
|
if (q == (char *) 0)
|
||||||
error("No targets provided");
|
error("No targets provided", NULL );
|
||||||
|
|
||||||
*q++ = '\0'; /* Separate targets and dependents */
|
*q++ = '\0'; /* Separate targets and dependents */
|
||||||
|
|
||||||
if (*q == ':') /* Double colon */
|
if (*q == ':') /* Double colon */
|
||||||
{
|
{
|
||||||
dbl = 1;
|
dbl = 1;
|
||||||
q++;
|
q++;
|
||||||
|
@ -301,40 +263,36 @@ FILE * fd;
|
||||||
else
|
else
|
||||||
dbl = 0;
|
dbl = 0;
|
||||||
|
|
||||||
for (dp = (struct depend *)0; ((p = gettok(&q)) != (char *)0);)
|
for (dp = (struct depend *) 0; ((p = gettok(&q)) != (char *) 0);)
|
||||||
/* get list of dep's */
|
/* get list of dep's */
|
||||||
{
|
{
|
||||||
np = newname(p); /* Intern name */
|
np = newname(p); /* Intern name */
|
||||||
dp = newdep(np, dp); /* Add to dep list */
|
dp = newdep(np, dp); /* Add to dep list */
|
||||||
}
|
}
|
||||||
|
|
||||||
*((q = str1) + strlen(str1) + 1) = '\0';
|
*((q = str1) + strlen(str1) + 1) = '\0';
|
||||||
/* Need two nulls for gettok (Remember separation) */
|
/* Need two nulls for gettok (Remember separation) */
|
||||||
|
|
||||||
cp = (struct cmd *)0;
|
cp = (struct cmd *) 0;
|
||||||
if (getline(str2, fd) == FALSE) /* Get commands */
|
if (mgetline(str2, fd) == FALSE) /* Get commands */
|
||||||
{
|
{
|
||||||
#ifdef os9
|
|
||||||
while (*str2 == ' ')
|
|
||||||
#else
|
|
||||||
while (*str2 == '\t')
|
while (*str2 == '\t')
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
cp = newcmd(&str2[0], cp);
|
cp = newcmd(&str2[0], cp);
|
||||||
if (getline(str2, fd))
|
if (mgetline(str2, fd))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((p = gettok(&q)) != (char *)0) /* Get list of targ's */
|
while ((p = gettok(&q)) != (char *) 0) /* Get list of targ's */
|
||||||
{
|
{
|
||||||
np = newname(p); /* Intern name */
|
np = newname(p); /* Intern name */
|
||||||
newline(np, dp, cp, dbl);
|
newline(np, dp, cp, dbl);
|
||||||
if (!firstname && p[0] != '.')
|
if (!firstname && p[0] != '.')
|
||||||
firstname = np;
|
firstname = np;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (feof(fd)) /* EOF? */
|
if (feof(fd)) /* EOF? */
|
||||||
return;
|
return;
|
||||||
|
|
||||||
strcpy(str1, str2);
|
strcpy(str1, str2);
|
||||||
|
|
|
@ -1,167 +1,156 @@
|
||||||
/*
|
/*
|
||||||
* Macro control for make
|
* Macro control for make
|
||||||
*
|
*
|
||||||
* $Header$
|
* $Header$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
#include "h.h"
|
#include "h.h"
|
||||||
|
|
||||||
|
|
||||||
struct macro * macrohead;
|
struct macro * macrohead;
|
||||||
|
|
||||||
|
|
||||||
struct macro *
|
static struct macro *getmp(char *name)
|
||||||
getmp(name)
|
|
||||||
char * name;
|
|
||||||
{
|
{
|
||||||
register struct macro * rp;
|
register struct macro * rp;
|
||||||
|
|
||||||
for (rp = macrohead; rp; rp = rp->m_next)
|
for (rp = macrohead; rp; rp = rp->m_next)
|
||||||
if (strcmp(name, rp->m_name) == 0)
|
if (strcmp(name, rp->m_name) == 0)
|
||||||
return rp;
|
return rp;
|
||||||
return (struct macro *)0;
|
return (struct macro *)0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
char *
|
char * getmacro(char* name)
|
||||||
getmacro(name)
|
|
||||||
char * name;
|
|
||||||
{
|
{
|
||||||
struct macro * mp;
|
struct macro * mp;
|
||||||
|
|
||||||
if (mp = getmp(name))
|
if ((mp = getmp(name)))
|
||||||
return mp->m_val;
|
return mp->m_val;
|
||||||
else
|
else
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct macro *
|
struct macro * setmacro(char* name, char* val, int prio)
|
||||||
setmacro(name, val, prio)
|
|
||||||
char * name;
|
|
||||||
char * val;
|
|
||||||
{
|
{
|
||||||
register struct macro * rp;
|
register struct macro * rp;
|
||||||
register char * cp;
|
register char * cp;
|
||||||
|
|
||||||
|
|
||||||
/* Replace macro definition if it exists */
|
/* Replace macro definition if it exists */
|
||||||
for (rp = macrohead; rp; rp = rp->m_next)
|
for (rp = macrohead; rp; rp = rp->m_next)
|
||||||
if (strcmp(name, rp->m_name) == 0)
|
if (strcmp(name, rp->m_name) == 0)
|
||||||
{
|
{
|
||||||
if (prio < rp->m_prio)
|
if (prio < rp->m_prio)
|
||||||
return rp;
|
return rp;
|
||||||
free(rp->m_val); /* Free space from old */
|
free(rp->m_val); /* Free space from old */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!rp) /* If not defined, allocate space for new */
|
if (!rp) /* If not defined, allocate space for new */
|
||||||
{
|
{
|
||||||
if ((rp = (struct macro *)malloc(sizeof (struct macro)))
|
if ((rp = (struct macro *)malloc(sizeof (struct macro)))
|
||||||
== (struct macro *)0)
|
== (struct macro *)0)
|
||||||
fatal("No memory for macro");
|
fatal("No memory for macro",NULL);
|
||||||
|
|
||||||
rp->m_next = macrohead;
|
rp->m_next = macrohead;
|
||||||
macrohead = rp;
|
macrohead = rp;
|
||||||
rp->m_flag = FALSE;
|
rp->m_flag = FALSE;
|
||||||
|
|
||||||
if ((cp = malloc((unsigned)(strlen(name)+1))) == (char *)0)
|
if ((cp = malloc((unsigned)(strlen(name)+1))) == (char *)0)
|
||||||
fatal("No memory for macro");
|
fatal("No memory for macro",NULL);
|
||||||
strcpy(cp, name);
|
strcpy(cp, name);
|
||||||
rp->m_name = cp;
|
rp->m_name = cp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((cp = malloc((unsigned)(strlen(val)+1))) == (char *)0)
|
if ((cp = malloc((unsigned)(strlen(val)+1))) == (char *)0)
|
||||||
fatal("No memory for macro");
|
fatal("No memory for macro",NULL);
|
||||||
strcpy(cp, val); /* Copy in new value */
|
strcpy(cp, val); /* Copy in new value */
|
||||||
rp->m_val = cp;
|
rp->m_val = cp;
|
||||||
rp->m_prio = prio;
|
rp->m_prio = (uchar)prio;
|
||||||
|
|
||||||
return rp;
|
return rp;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MBUFSIZ 128
|
#define MBUFSIZ 128
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do the dirty work for expand
|
* Do the dirty work for expand
|
||||||
*/
|
*/
|
||||||
void
|
static void doexp(char **to, char* from, int* len, char* buf)
|
||||||
doexp(to, from, len, buf)
|
|
||||||
char ** to;
|
|
||||||
char * from;
|
|
||||||
int * len;
|
|
||||||
char * buf;
|
|
||||||
{
|
{
|
||||||
register char * rp;
|
register char * rp;
|
||||||
register char * p;
|
register char * p;
|
||||||
register char * q;
|
register char * q;
|
||||||
register struct macro * mp;
|
register struct macro * mp;
|
||||||
|
|
||||||
|
|
||||||
rp = from;
|
rp = from;
|
||||||
p = *to;
|
p = *to;
|
||||||
while (*rp)
|
while (*rp)
|
||||||
{
|
{
|
||||||
if (*rp != '$')
|
if (*rp != '$')
|
||||||
{
|
{
|
||||||
*p++ = *rp++;
|
*p++ = *rp++;
|
||||||
(*len)--;
|
(*len)--;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
q = buf;
|
q = buf;
|
||||||
if (*++rp == '{')
|
if (*++rp == '{')
|
||||||
while (*++rp && *rp != '}') {
|
while (*++rp && *rp != '}') {
|
||||||
if (q < &buf[MBUFSIZ-1]) *q++ = *rp;
|
if (q < &buf[MBUFSIZ-1]) *q++ = *rp;
|
||||||
}
|
}
|
||||||
else if (*rp == '(')
|
else if (*rp == '(')
|
||||||
while (*++rp && *rp != ')') {
|
while (*++rp && *rp != ')') {
|
||||||
if (q < &buf[MBUFSIZ-1]) *q++ = *rp;
|
if (q < &buf[MBUFSIZ-1]) *q++ = *rp;
|
||||||
}
|
}
|
||||||
else if (!*rp)
|
else if (!*rp)
|
||||||
{
|
{
|
||||||
*p++ = '$';
|
*p++ = '$';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
*q++ = *rp;
|
*q++ = *rp;
|
||||||
*q = '\0';
|
*q = '\0';
|
||||||
if (*rp)
|
if (*rp)
|
||||||
rp++;
|
rp++;
|
||||||
if (!(mp = getmp(buf)))
|
if (!(mp = getmp(buf)))
|
||||||
mp = setmacro(buf, "", 2);
|
mp = setmacro(buf, "", 2);
|
||||||
if (mp->m_flag)
|
if (mp->m_flag)
|
||||||
fatal("Infinitely recursive macro %s", mp->m_name);
|
fatal("Infinitely recursive macro %s", mp->m_name);
|
||||||
mp->m_flag = TRUE;
|
mp->m_flag = TRUE;
|
||||||
*to = p;
|
*to = p;
|
||||||
doexp(to, mp->m_val, len, buf);
|
doexp(to, mp->m_val, len, buf);
|
||||||
p = *to;
|
p = *to;
|
||||||
mp->m_flag = FALSE;
|
mp->m_flag = FALSE;
|
||||||
}
|
}
|
||||||
if (*len <= 0)
|
if (*len <= 0)
|
||||||
error("Expanded line too line");
|
error("Expanded line too line", NULL);
|
||||||
}
|
}
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
*to = p;
|
*to = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Expand any macros in str.
|
* Expand any macros in str.
|
||||||
*/
|
*/
|
||||||
void
|
void expand(char *str)
|
||||||
expand(str)
|
|
||||||
char * str;
|
|
||||||
{
|
{
|
||||||
char *a;
|
char *a;
|
||||||
static char b[MBUFSIZ]; /* temp storage for macroname */
|
static char b[MBUFSIZ]; /* temp storage for macroname */
|
||||||
char * p = str;
|
char * p = str;
|
||||||
int len = LZ-1;
|
int len = LZ-1;
|
||||||
|
|
||||||
a = malloc((unsigned)(strlen(str)+1));
|
a = malloc((unsigned)(strlen(str)+1));
|
||||||
if (!a) fatal("No memory for expand");
|
if (!a) fatal("No memory for expand",NULL);
|
||||||
strcpy(a, str);
|
strcpy(a, str);
|
||||||
doexp(&p, a, &len, b);
|
doexp(&p, a, &len, b);
|
||||||
free(a);
|
free(a);
|
||||||
}
|
}
|
||||||
|
|
371
util/make/main.c
371
util/make/main.c
|
@ -1,261 +1,204 @@
|
||||||
/*
|
/*
|
||||||
* make [-f makefile] [-ins] [target(s) ...]
|
* make [-f makefile] [-ins] [target(s) ...]
|
||||||
*
|
*
|
||||||
* (Better than EON mk but not quite as good as UNIX make)
|
* (Better than EON mk but not quite as good as UNIX make)
|
||||||
*
|
*
|
||||||
* -f makefile name
|
* -f makefile name
|
||||||
* -i ignore exit status
|
* -i ignore exit status
|
||||||
* -n Pretend to make
|
* -n Pretend to make
|
||||||
* -p Print all macros & targets
|
* -p Print all macros & targets
|
||||||
* -q Question up-to-dateness of target. Return exit status 1 if not
|
* -q Question up-to-dateness of target. Return exit status 1 if not
|
||||||
* -r Don't not use inbuilt rules
|
* -r Don't not use inbuilt rules
|
||||||
* -s Make silently
|
* -s Make silently
|
||||||
* -t Touch files instead of making them
|
* -t Touch files instead of making them
|
||||||
* -m Change memory requirements (EON only)
|
* -m Change memory requirements (EON only)
|
||||||
* -k For the time being: accept but ignore
|
* -k For the time being: accept but ignore
|
||||||
*
|
*
|
||||||
* $Header$
|
* $Header$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include "h.h"
|
#include "h.h"
|
||||||
|
|
||||||
#ifdef unix
|
char * myname;
|
||||||
#include <errno.h>
|
char * makefile; /* The make file */
|
||||||
#endif
|
|
||||||
#ifdef eon
|
#ifdef eon
|
||||||
#include <sys/err.h>
|
unsigned memspace = MEMSPACE;
|
||||||
#endif
|
|
||||||
#ifdef os9
|
|
||||||
#include <errno.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
FILE * ifd; /* Input file desciptor */
|
||||||
|
bool domake = TRUE; /* Go through the motions option */
|
||||||
|
bool ignore = FALSE; /* 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 */
|
||||||
|
|
||||||
#ifdef eon
|
static void usage(void);
|
||||||
#define MEMSPACE (16384)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
char * myname;
|
int main(int argc, char** argv)
|
||||||
char * makefile; /* The make file */
|
|
||||||
#ifdef eon
|
|
||||||
unsigned memspace = MEMSPACE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
FILE * ifd; /* Input file desciptor */
|
|
||||||
bool domake = TRUE; /* Go through the motions option */
|
|
||||||
bool ignore = FALSE; /* 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)
|
|
||||||
int argc;
|
|
||||||
char ** argv;
|
|
||||||
{
|
{
|
||||||
register char * p; /* For argument processing */
|
register char * p; /* For argument processing */
|
||||||
int estat = 0; /* For question */
|
int estat = 0; /* For question */
|
||||||
register struct name * np;
|
register struct name * np;
|
||||||
int nargc = 0;
|
int nargc = 0;
|
||||||
char **nargv;
|
char **nargv;
|
||||||
int fflag = 0;
|
int fflag = 0;
|
||||||
|
|
||||||
|
|
||||||
myname = (argc-- < 1) ? "make" : *argv++;
|
myname = (argc-- < 1) ? "make" : *argv++;
|
||||||
nargv = argv;
|
nargv = argv;
|
||||||
|
|
||||||
while (argc > 0)
|
while (argc > 0)
|
||||||
{
|
{
|
||||||
argc--; /* One less to process */
|
argc--; /* One less to process */
|
||||||
p = *argv++; /* Now processing this one */
|
p = *argv++; /* Now processing this one */
|
||||||
|
|
||||||
if (*p == '-') while (*++p != '\0')
|
if (*p == '-') while (*++p != '\0')
|
||||||
{
|
{
|
||||||
switch(*p)
|
switch(*p)
|
||||||
{
|
{
|
||||||
case 'f': /* Alternate file name */
|
case 'f': /* Alternate file name */
|
||||||
fflag = 1;
|
fflag = 1;
|
||||||
break;
|
break;
|
||||||
#ifdef eon
|
case 'n': /* Pretend mode */
|
||||||
case 'm': /* Change space requirements */
|
domake = FALSE;
|
||||||
if (*++p == '\0')
|
break;
|
||||||
{
|
case 'i': /* Ignore fault mode */
|
||||||
if (argc-- <= 0)
|
ignore = TRUE;
|
||||||
usage();
|
break;
|
||||||
p = *argv++;
|
case 's': /* Silent about commands */
|
||||||
}
|
silent = TRUE;
|
||||||
memspace = atoi(p);
|
break;
|
||||||
goto end_of_args;
|
case 'p':
|
||||||
#endif
|
print = TRUE;
|
||||||
case 'n': /* Pretend mode */
|
break;
|
||||||
domake = FALSE;
|
case 'r':
|
||||||
break;
|
rules = FALSE;
|
||||||
case 'i': /* Ignore fault mode */
|
break;
|
||||||
ignore = TRUE;
|
case 't':
|
||||||
break;
|
dotouch = TRUE;
|
||||||
case 's': /* Silent about commands */
|
break;
|
||||||
silent = TRUE;
|
case 'q':
|
||||||
break;
|
quest = TRUE;
|
||||||
case 'p':
|
break;
|
||||||
print = TRUE;
|
case 'k':
|
||||||
break;
|
break;
|
||||||
case 'r':
|
default: /* Wrong option */
|
||||||
rules = FALSE;
|
usage();
|
||||||
break;
|
}
|
||||||
case 't':
|
}
|
||||||
dotouch = TRUE;
|
else {
|
||||||
break;
|
if (fflag) {
|
||||||
case 'q':
|
if (argc <= 0) usage();
|
||||||
quest = TRUE;
|
makefile = p;
|
||||||
break;
|
fflag = 0;
|
||||||
case 'k':
|
}
|
||||||
break;
|
else {
|
||||||
default: /* Wrong option */
|
nargc++;
|
||||||
usage();
|
*nargv++ = p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
end_of_args:;
|
||||||
if (fflag) {
|
}
|
||||||
if (argc <= 0) usage();
|
argv = nargv - nargc;
|
||||||
makefile = p;
|
argc = nargc;
|
||||||
fflag = 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
nargc++;
|
|
||||||
*nargv++ = p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
end_of_args:;
|
|
||||||
}
|
|
||||||
argv = nargv - nargc;
|
|
||||||
argc = nargc;
|
|
||||||
|
|
||||||
#ifdef eon
|
|
||||||
if (initalloc(memspace) == 0xffff) /* Must get memory for alloc */
|
|
||||||
fatal("Cannot initalloc memory");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (makefile && strcmp(makefile, "-") == 0) /* Can use stdin as makefile */
|
if (makefile && strcmp(makefile, "-") == 0) /* Can use stdin as makefile */
|
||||||
ifd = stdin;
|
ifd = stdin;
|
||||||
else
|
else
|
||||||
if (!makefile) /* If no file, then use default */
|
if (!makefile) /* If no file, then use default */
|
||||||
{
|
{
|
||||||
if ((ifd = fopen(DEFN1, "r")) == (FILE *)0)
|
if ((ifd = fopen(DEFN1, "r")) == NULL)
|
||||||
#ifdef eon
|
if ((ifd == NULL)
|
||||||
if (errno != ER_NOTF)
|
&& ((ifd = fopen(DEFN2, "r")) == NULL))
|
||||||
fatal("Can't open %s; error %02x", DEFN1, errno);
|
fatal("Can't open %s", DEFN2);
|
||||||
#endif
|
}
|
||||||
#ifdef unix
|
else
|
||||||
if (errno != ENOENT)
|
if ((ifd = fopen(makefile, "r")) == NULL)
|
||||||
fatal("Can't open %s; error %02x", DEFN1, errno);
|
fatal("Can't open %s", makefile);
|
||||||
#endif
|
|
||||||
#ifndef os9
|
|
||||||
if ((ifd == (FILE *)0)
|
|
||||||
&& ((ifd = fopen(DEFN2, "r")) == (FILE *)0))
|
|
||||||
fatal("Can't open %s", DEFN2);
|
|
||||||
#else
|
|
||||||
fatal("Can't open %s", DEFN1);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if ((ifd = fopen(makefile, "r")) == (FILE *)0)
|
|
||||||
fatal("Can't open %s", makefile);
|
|
||||||
|
|
||||||
makerules();
|
makerules();
|
||||||
|
|
||||||
setmacro("$", "$", 4);
|
setmacro("$", "$", 4);
|
||||||
|
|
||||||
while (argc && (p = index(*argv, '=')))
|
while (argc && (p = strchr(*argv, '=')))
|
||||||
{
|
{
|
||||||
char c;
|
char c;
|
||||||
|
|
||||||
c = *p;
|
c = *p;
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
setmacro(*argv, p+1, 3);
|
setmacro(*argv, p+1, 3);
|
||||||
*p = c;
|
*p = c;
|
||||||
|
|
||||||
argv++;
|
argv++;
|
||||||
argc--;
|
argc--;
|
||||||
}
|
}
|
||||||
|
|
||||||
input(ifd); /* Input all the gunga */
|
input(ifd); /* Input all the gunga */
|
||||||
fclose(ifd); /* Finished with makefile */
|
fclose(ifd); /* Finished with makefile */
|
||||||
lineno = 0; /* Any calls to error now print no line number */
|
lineno = 0; /* Any calls to error now print no line number */
|
||||||
|
|
||||||
if (print)
|
if (print)
|
||||||
prt(); /* Print out structures */
|
prt(); /* Print out structures */
|
||||||
|
|
||||||
np = newname(".SILENT");
|
np = newname(".SILENT");
|
||||||
if (np->n_flag & N_TARG)
|
if (np->n_flag & N_TARG)
|
||||||
silent = TRUE;
|
silent = TRUE;
|
||||||
|
|
||||||
np = newname(".IGNORE");
|
np = newname(".IGNORE");
|
||||||
if (np->n_flag & N_TARG)
|
if (np->n_flag & N_TARG)
|
||||||
ignore = TRUE;
|
ignore = TRUE;
|
||||||
|
|
||||||
precious();
|
precious();
|
||||||
|
|
||||||
if (!firstname)
|
if (!firstname)
|
||||||
fatal("No targets defined");
|
fatal("No targets defined",NULL);
|
||||||
|
|
||||||
circh(); /* Check circles in target definitions */
|
circh(); /* Check circles in target definitions */
|
||||||
|
|
||||||
if (!argc)
|
if (!argc)
|
||||||
estat = make(firstname, 0);
|
estat = make(firstname, 0);
|
||||||
else while (argc--)
|
else while (argc--)
|
||||||
{
|
{
|
||||||
if (!print && !silent && strcmp(*argv, "love") == 0)
|
if (!print && !silent && strcmp(*argv, "love") == 0)
|
||||||
printf("Not war!\n");
|
printf("Not war!\n");
|
||||||
estat |= make(newname(*argv++), 0);
|
estat |= make(newname(*argv++), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (quest)
|
if (quest)
|
||||||
exit(estat);
|
exit(estat);
|
||||||
else
|
else
|
||||||
exit(0);
|
exit(0);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
usage()
|
static void usage(void)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Usage: %s [-f makefile] [-inpqrst] [macro=val ...] [target(s) ...]\n", myname);
|
fprintf(stderr, "Usage: %s [-f makefile] [-inpqrst] [macro=val ...] [target(s) ...]\n", myname);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*VARARGS1*/
|
/*VARARGS1*/
|
||||||
void
|
void fatal(char *msg, char* value)
|
||||||
fatal(msg, a1, a2, a3, a4, a5, a6)
|
|
||||||
char *msg;
|
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s: ", myname);
|
if (value != NULL)
|
||||||
fprintf(stderr, msg, a1, a2, a3, a4, a5, a6);
|
{
|
||||||
fputc('\n', stderr);
|
fprintf(stderr, "%s: ", myname);
|
||||||
exit(1);
|
fprintf(stderr, msg, value);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s: ", myname);
|
||||||
|
fprintf(stderr, msg);
|
||||||
|
}
|
||||||
|
fputc('\n', stderr);
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
|
||||||
index(s, c)
|
|
||||||
register char *s, c;
|
|
||||||
{
|
|
||||||
while (*s)
|
|
||||||
if (*s++ == c)
|
|
||||||
return --s;
|
|
||||||
return (char *)0;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *
|
|
||||||
rindex(str, chr)
|
|
||||||
register char *str, chr;
|
|
||||||
{
|
|
||||||
register char *retptr = 0;
|
|
||||||
|
|
||||||
while (*str)
|
|
||||||
if (*str++ == chr)
|
|
||||||
retptr = &str[-1];
|
|
||||||
return retptr;
|
|
||||||
}
|
|
||||||
|
|
678
util/make/make.c
678
util/make/make.c
|
@ -1,482 +1,308 @@
|
||||||
/*
|
/*
|
||||||
* Do the actual making for make
|
* Do the actual making for make
|
||||||
*
|
*
|
||||||
* $Header$
|
* $Header$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#ifdef unix
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
/* UNIX specific */
|
||||||
|
#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))
|
||||||
|
#ifndef unix
|
||||||
|
#define unix
|
||||||
#endif
|
#endif
|
||||||
#ifdef eon
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/err.h>
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef os9
|
|
||||||
#include <time.h>
|
#if defined(__MINGW32__) || defined(__MINGW64__)
|
||||||
#include <os9.h>
|
#ifndef unix
|
||||||
#include <modes.h>
|
#define unix
|
||||||
#include <direct.h>
|
#endif
|
||||||
#include <errno.h>
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef unix
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <utime.h>
|
||||||
#endif
|
#endif
|
||||||
#include "h.h"
|
#include "h.h"
|
||||||
|
|
||||||
|
void docmds(struct name *np);
|
||||||
|
|
||||||
|
#ifndef max
|
||||||
|
#define max(a,b) ((a)>(b)?(a):(b))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Exec a shell that returns exit status correctly (/bin/esh).
|
* Exec a shell that returns exit status correctly (/bin/esh).
|
||||||
* The standard EON shell returns the process number of the last
|
* The standard EON shell returns the process number of the last
|
||||||
* async command, used by the debugger (ugg).
|
* async command, used by the debugger (ugg).
|
||||||
* [exec on eon is like a fork+exec on unix]
|
* [exec on eon is like a fork+exec on unix]
|
||||||
*/
|
*/
|
||||||
int
|
static int dosh(char *string, char *shell)
|
||||||
dosh(string, shell)
|
|
||||||
char * string;
|
|
||||||
char * shell;
|
|
||||||
{
|
{
|
||||||
int number;
|
return system(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do commands to make a target
|
||||||
|
*/
|
||||||
|
static void docmds1(struct name *np, struct line *lp)
|
||||||
|
{
|
||||||
|
bool ssilent;
|
||||||
|
bool signore;
|
||||||
|
int estat;
|
||||||
|
register char * q;
|
||||||
|
register char * p;
|
||||||
|
char * shell;
|
||||||
|
register struct cmd * cp;
|
||||||
|
|
||||||
|
|
||||||
|
if (*(shell = getmacro("SHELL")) == '\0')
|
||||||
#ifdef unix
|
#ifdef unix
|
||||||
return system(string);
|
shell = "/bin/sh";
|
||||||
#endif
|
#endif
|
||||||
#ifdef eon
|
for (cp = lp->l_cmd; cp; cp = cp->c_next)
|
||||||
return ((number = execl(shell, shell,"-c", string, 0)) == -1) ?
|
{
|
||||||
-1: /* couldn't start the shell */
|
strcpy(str1, cp->c_cmd);
|
||||||
wait(number); /* return its exit status */
|
expand(str1);
|
||||||
#endif
|
q = str1;
|
||||||
#ifdef os9
|
ssilent = silent;
|
||||||
int status, pid;
|
signore = ignore;
|
||||||
|
while ((*q == '@') || (*q == '-'))
|
||||||
|
{
|
||||||
|
if (*q == '@') /* Specific silent */
|
||||||
|
ssilent = TRUE;
|
||||||
|
else /* Specific ignore */
|
||||||
|
signore = TRUE;
|
||||||
|
q++; /* Not part of the command */
|
||||||
|
}
|
||||||
|
|
||||||
strcat(string, "\n");
|
if (!domake)
|
||||||
if ((number = os9fork(shell, strlen(string), string, 0, 0, 0)) == -1)
|
ssilent = 0;
|
||||||
return -1; /* Couldn't start a shell */
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if ((pid = wait(&status)) == -1)
|
|
||||||
return -1; /* child already died!?!? */
|
|
||||||
} while (pid != number);
|
|
||||||
|
|
||||||
return status;
|
if (!ssilent)
|
||||||
#endif
|
fputs(" ", stdout);
|
||||||
|
|
||||||
|
for (p=q; *p; p++)
|
||||||
|
{
|
||||||
|
if (*p == '\n' && p[1] != '\0')
|
||||||
|
{
|
||||||
|
*p = ' ';
|
||||||
|
if (!ssilent)
|
||||||
|
fputs("\\\n", stdout);
|
||||||
|
}
|
||||||
|
else if (!ssilent)
|
||||||
|
putchar(*p);
|
||||||
|
}
|
||||||
|
if (!ssilent) {
|
||||||
|
putchar('\n');
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (domake)
|
||||||
|
{ /* Get the shell to execute it */
|
||||||
|
if ((estat = dosh(q, shell)) != 0)
|
||||||
|
{
|
||||||
|
if (estat == -1)
|
||||||
|
fatal("Couldn't execute %s", shell);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("%s: Error code %d", myname, estat);
|
||||||
|
if (signore)
|
||||||
|
fputs(" (Ignored)\n", stdout);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
putchar('\n');
|
||||||
|
if (!(np->n_flag & N_PREC))
|
||||||
|
if (remove(np->n_name) == 0)
|
||||||
|
printf("%s: '%s' removed.\n", myname, np->n_name);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void docmds(struct name *np)
|
||||||
|
{
|
||||||
|
register struct line * lp;
|
||||||
|
|
||||||
|
|
||||||
|
for (lp = np->n_line; lp; lp = lp->l_next)
|
||||||
|
docmds1(np, lp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do commands to make a target
|
* Get the modification time of a file. If the first
|
||||||
|
* doesn't exist, it's modtime is set to 0.
|
||||||
*/
|
*/
|
||||||
void
|
void modtime(struct name *np)
|
||||||
docmds1(np, lp)
|
|
||||||
struct name * np;
|
|
||||||
struct line * lp;
|
|
||||||
{
|
{
|
||||||
bool ssilent;
|
struct stat info;
|
||||||
bool signore;
|
|
||||||
int estat;
|
|
||||||
register char * q;
|
|
||||||
register char * p;
|
|
||||||
char * shell;
|
|
||||||
register struct cmd * cp;
|
|
||||||
|
|
||||||
|
if (stat(np->n_name, &info) < 0)
|
||||||
|
{
|
||||||
|
if (errno != ENOENT)
|
||||||
|
fatal("Can't open %s", np->n_name);
|
||||||
|
|
||||||
if (*(shell = getmacro("SHELL")) == '\0')
|
np->n_time = 0L;
|
||||||
#ifdef eon
|
}
|
||||||
shell = ":bin/esh";
|
else
|
||||||
#endif
|
np->n_time = info.st_mtime;
|
||||||
#ifdef unix
|
|
||||||
shell = "/bin/sh";
|
|
||||||
#endif
|
|
||||||
#ifdef os9
|
|
||||||
shell = "shell";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (cp = lp->l_cmd; cp; cp = cp->c_next)
|
|
||||||
{
|
|
||||||
strcpy(str1, cp->c_cmd);
|
|
||||||
expand(str1);
|
|
||||||
q = str1;
|
|
||||||
ssilent = silent;
|
|
||||||
signore = ignore;
|
|
||||||
while ((*q == '@') || (*q == '-'))
|
|
||||||
{
|
|
||||||
if (*q == '@') /* Specific silent */
|
|
||||||
ssilent = TRUE;
|
|
||||||
else /* Specific ignore */
|
|
||||||
signore = TRUE;
|
|
||||||
q++; /* Not part of the command */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!domake)
|
|
||||||
ssilent = 0;
|
|
||||||
|
|
||||||
if (!ssilent)
|
|
||||||
fputs(" ", stdout);
|
|
||||||
|
|
||||||
for (p=q; *p; p++)
|
|
||||||
{
|
|
||||||
if (*p == '\n' && p[1] != '\0')
|
|
||||||
{
|
|
||||||
*p = ' ';
|
|
||||||
if (!ssilent)
|
|
||||||
fputs("\\\n", stdout);
|
|
||||||
}
|
|
||||||
else if (!ssilent)
|
|
||||||
putchar(*p);
|
|
||||||
}
|
|
||||||
if (!ssilent) {
|
|
||||||
putchar('\n');
|
|
||||||
fflush(stdout);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (domake)
|
|
||||||
{ /* Get the shell to execute it */
|
|
||||||
if ((estat = dosh(q, shell)) != 0)
|
|
||||||
{
|
|
||||||
if (estat == -1)
|
|
||||||
fatal("Couldn't execute %s", shell);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("%s: Error code %d", myname, estat);
|
|
||||||
if (signore)
|
|
||||||
fputs(" (Ignored)\n", stdout);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
putchar('\n');
|
|
||||||
if (!(np->n_flag & N_PREC))
|
|
||||||
if (unlink(np->n_name) == 0)
|
|
||||||
printf("%s: '%s' removed.\n", myname, np->n_name);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fflush(stdout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
docmds(np)
|
|
||||||
struct name * np;
|
|
||||||
{
|
|
||||||
register struct line * lp;
|
|
||||||
|
|
||||||
|
|
||||||
for (lp = np->n_line; lp; lp = lp->l_next)
|
|
||||||
docmds1(np, lp);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef os9
|
|
||||||
/*
|
|
||||||
* Some stuffing around to get the modified time of a file
|
|
||||||
* in an os9 file system
|
|
||||||
*/
|
|
||||||
getmdate(fd, tbp)
|
|
||||||
struct sgtbuf * tbp;
|
|
||||||
{
|
|
||||||
struct registers regs;
|
|
||||||
static struct fildes fdbuf;
|
|
||||||
|
|
||||||
|
|
||||||
regs.rg_a = fd;
|
|
||||||
regs.rg_b = SS_FD;
|
|
||||||
regs.rg_x = &fdbuf;
|
|
||||||
regs.rg_y = sizeof (fdbuf);
|
|
||||||
|
|
||||||
if (_os9(I_GETSTT, ®s) == -1)
|
|
||||||
{
|
|
||||||
errno = regs.rg_b & 0xff;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (tbp)
|
|
||||||
{
|
|
||||||
_strass(tbp, fdbuf.fd_date, sizeof (fdbuf.fd_date));
|
|
||||||
tbp->t_second = 0; /* Files are only acurate to mins */
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Kludge routine to return an aproximation of how many
|
* Update the mod time of a file to now.
|
||||||
* seconds since 1980. Dates will be in order, but will not
|
|
||||||
* be lineer
|
|
||||||
*/
|
*/
|
||||||
time_t
|
void touch(struct name *np)
|
||||||
cnvtime(tbp)
|
|
||||||
struct sgtbuf *tbp;
|
|
||||||
{
|
|
||||||
long acc;
|
|
||||||
|
|
||||||
|
|
||||||
acc = tbp->t_year - 80; /* Baseyear is 1980 */
|
|
||||||
acc = acc * 12 + tbp->t_month;
|
|
||||||
acc = acc * 31 + tbp->t_day;
|
|
||||||
acc = acc * 24 + tbp->t_hour;
|
|
||||||
acc = acc * 60 + tbp->t_minute;
|
|
||||||
acc = acc * 60 + tbp->t_second;
|
|
||||||
|
|
||||||
return acc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Get the current time in the internal format
|
|
||||||
*/
|
|
||||||
time(tp)
|
|
||||||
time_t * tp;
|
|
||||||
{
|
|
||||||
struct sgtbuf tbuf;
|
|
||||||
|
|
||||||
|
|
||||||
if (getime(&tbuf) < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (tp)
|
|
||||||
*tp = cnvtime(&tbuf);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Get the modification time of a file. If the first
|
|
||||||
* doesn't exist, it's modtime is set to 0.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
modtime(np)
|
|
||||||
struct name * np;
|
|
||||||
{
|
{
|
||||||
#ifdef unix
|
#ifdef unix
|
||||||
struct stat info;
|
if (!domake || !silent)
|
||||||
|
printf(" touch(%s)\n", np->n_name);
|
||||||
|
|
||||||
|
if (domake)
|
||||||
|
{
|
||||||
|
struct utimbuf a;
|
||||||
|
time_t timeval;
|
||||||
|
|
||||||
if (stat(np->n_name, &info) < 0)
|
a.actime = a.modtime = time(&timeval);
|
||||||
{
|
if (utime(np->n_name, &a) < 0)
|
||||||
if (errno != ENOENT)
|
printf("%s: '%s' not touched - non-existant\n",
|
||||||
fatal("Can't open %s; error %d", np->n_name, errno);
|
myname, np->n_name);
|
||||||
|
}
|
||||||
np->n_time = 0L;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
np->n_time = info.st_mtime;
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef eon
|
}
|
||||||
struct stat info;
|
|
||||||
int fd;
|
|
||||||
|
|
||||||
|
static void make1(struct name *np, struct line *lp, struct depend *qdp)
|
||||||
|
{
|
||||||
|
register struct depend * dp;
|
||||||
|
register char *p;
|
||||||
|
|
||||||
if ((fd = open(np->n_name, 0)) < 0)
|
if (dotouch)
|
||||||
{
|
touch(np);
|
||||||
if (errno != ER_NOTF)
|
else
|
||||||
fatal("Can't open %s; error %02x", np->n_name, errno);
|
{
|
||||||
|
strcpy(str1, "");
|
||||||
np->n_time = 0L;
|
for (dp = qdp; dp; dp = qdp)
|
||||||
}
|
{
|
||||||
else if (getstat(fd, &info) < 0)
|
if (strlen(str1))
|
||||||
fatal("Can't getstat %s; error %02x", np->n_name, errno);
|
strcat(str1, " ");
|
||||||
else
|
strcat(str1, dp->d_name->n_name);
|
||||||
np->n_time = info.st_mod;
|
qdp = dp->d_next;
|
||||||
|
free((char *)dp);
|
||||||
close(fd);
|
}
|
||||||
#endif
|
setmacro("?", str1, 4);
|
||||||
#ifdef os9
|
setmacro("@", np->n_name, 4);
|
||||||
struct sgtbuf info;
|
p = strrchr(np->n_name, '.');
|
||||||
int fd;
|
if (p) *p = 0;
|
||||||
|
setmacro("*", np->n_name, 4);
|
||||||
|
if (p) *p = '.';
|
||||||
if ((fd = open(np->n_name, 0)) < 0)
|
if (lp) /* lp set if doing a :: rule */
|
||||||
{
|
docmds1(np, lp);
|
||||||
if (errno != E_PNNF)
|
else
|
||||||
fatal("Can't open %s; error %02x", np->n_name, errno);
|
docmds(np);
|
||||||
|
}
|
||||||
np->n_time = 0L;
|
|
||||||
}
|
|
||||||
else if (getmdate(fd, &info) < 0)
|
|
||||||
fatal("Can't getstat %s; error %02x", np->n_name, errno);
|
|
||||||
else
|
|
||||||
np->n_time = cnvtime(&info);
|
|
||||||
|
|
||||||
close(fd);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Update the mod time of a file to now.
|
* Recursive routine to make a target.
|
||||||
*/
|
*/
|
||||||
void
|
int make(struct name *np, int level)
|
||||||
touch(np)
|
|
||||||
struct name * np;
|
|
||||||
{
|
{
|
||||||
char c;
|
register struct depend * dp;
|
||||||
int fd;
|
register struct line * lp;
|
||||||
|
register struct depend * qdp;
|
||||||
|
time_t dtime = 1;
|
||||||
|
bool didsomething = 0;
|
||||||
|
int dynamic = 0;
|
||||||
|
|
||||||
|
|
||||||
if (!domake || !silent)
|
if (np->n_flag & N_DONE)
|
||||||
printf(" touch(%s)\n", np->n_name);
|
return 0;
|
||||||
|
|
||||||
if (domake)
|
if (!np->n_time)
|
||||||
{
|
modtime(np); /* Gets modtime of this file */
|
||||||
#ifdef unix
|
|
||||||
long a[2];
|
|
||||||
long time();
|
|
||||||
|
|
||||||
a[0] = a[1] = time((long *)0);
|
if (rules)
|
||||||
if (utime(np->n_name, &a[0]) < 0)
|
{
|
||||||
printf("%s: '%s' not touched - non-existant\n",
|
for (lp = np->n_line; lp; lp = lp->l_next)
|
||||||
myname, np->n_name);
|
if (lp->l_cmd)
|
||||||
#endif
|
break;
|
||||||
#ifdef eon
|
if (!lp) {
|
||||||
if ((fd = open(np->n_name, 0)) < 0)
|
dyndep(np);
|
||||||
printf("%s: '%s' not touched - non-existant\n",
|
dynamic = 1;
|
||||||
myname, np->n_name);
|
}
|
||||||
else
|
}
|
||||||
{
|
|
||||||
uread(fd, &c, 1, 0);
|
if (!(np->n_flag & N_TARG) && np->n_time == 0L)
|
||||||
uwrite(fd, &c, 1);
|
fatal("Don't know how to make %s", np->n_name);
|
||||||
}
|
|
||||||
close(fd);
|
for (qdp = (struct depend *)0, lp = np->n_line; lp; lp = lp->l_next)
|
||||||
#endif
|
{
|
||||||
#ifdef os9
|
for (dp = lp->l_dep; dp; dp = dp->d_next)
|
||||||
/*
|
{
|
||||||
* Strange that something almost as totally useless
|
char *sv = 0;
|
||||||
* as this is easy to do in os9!
|
if (dynamic) {
|
||||||
*/
|
char *s = getmacro("<");
|
||||||
if ((fd = open(np->n_name, S_IWRITE)) < 0)
|
|
||||||
printf("%s: '%s' not touched - non-existant\n",
|
if (s) {
|
||||||
myname, np->n_name);
|
sv = malloc((unsigned)(strlen(s)+1));
|
||||||
close(fd);
|
if (!sv) {
|
||||||
#endif
|
fatal("no space for saved $<",NULL);
|
||||||
}
|
}
|
||||||
|
strcpy(sv, s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
make(dp->d_name, level+1);
|
||||||
|
if (dynamic && sv) {
|
||||||
|
setmacro("<", sv, 4);
|
||||||
|
free(sv);
|
||||||
|
}
|
||||||
|
if (np->n_time < dp->d_name->n_time)
|
||||||
|
qdp = newdep(dp->d_name, qdp);
|
||||||
|
dtime = max(dtime, dp->d_name->n_time);
|
||||||
|
}
|
||||||
|
if (!quest && (np->n_flag & N_DOUBLE) && (np->n_time < dtime))
|
||||||
|
{
|
||||||
|
make1(np, lp, qdp); /* free()'s qdp */
|
||||||
|
dtime = 1;
|
||||||
|
qdp = (struct depend *)0;
|
||||||
|
didsomething++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
np->n_flag |= N_DONE;
|
||||||
|
|
||||||
|
if (quest)
|
||||||
|
{
|
||||||
|
long t;
|
||||||
|
|
||||||
|
t = np->n_time;
|
||||||
|
time(&np->n_time);
|
||||||
|
return t < dtime;
|
||||||
|
}
|
||||||
|
else if (np->n_time < dtime && !(np->n_flag & N_DOUBLE))
|
||||||
|
{
|
||||||
|
make1(np, (struct line *)0, qdp); /* free()'s qdp */
|
||||||
|
time(&np->n_time);
|
||||||
|
}
|
||||||
|
else if (level == 0 && !didsomething)
|
||||||
|
printf("%s: '%s' is up to date\n", myname, np->n_name);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Recursive routine to make a target.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
make(np, level)
|
|
||||||
struct name * np;
|
|
||||||
int level;
|
|
||||||
{
|
|
||||||
register struct depend * dp;
|
|
||||||
register struct line * lp;
|
|
||||||
register struct depend * qdp;
|
|
||||||
time_t dtime = 1;
|
|
||||||
bool didsomething = 0;
|
|
||||||
int dynamic = 0;
|
|
||||||
|
|
||||||
|
|
||||||
if (np->n_flag & N_DONE)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (!np->n_time)
|
|
||||||
modtime(np); /* Gets modtime of this file */
|
|
||||||
|
|
||||||
if (rules)
|
|
||||||
{
|
|
||||||
for (lp = np->n_line; lp; lp = lp->l_next)
|
|
||||||
if (lp->l_cmd)
|
|
||||||
break;
|
|
||||||
if (!lp) {
|
|
||||||
dyndep(np);
|
|
||||||
dynamic = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(np->n_flag & N_TARG) && np->n_time == 0L)
|
|
||||||
fatal("Don't know how to make %s", np->n_name);
|
|
||||||
|
|
||||||
for (qdp = (struct depend *)0, lp = np->n_line; lp; lp = lp->l_next)
|
|
||||||
{
|
|
||||||
for (dp = lp->l_dep; dp; dp = dp->d_next)
|
|
||||||
{
|
|
||||||
char *sv = 0;
|
|
||||||
if (dynamic) {
|
|
||||||
char *s = getmacro("<");
|
|
||||||
|
|
||||||
if (s) {
|
|
||||||
sv = malloc((unsigned)(strlen(s)+1));
|
|
||||||
if (!sv) {
|
|
||||||
fatal("no space for saved $<");
|
|
||||||
}
|
|
||||||
strcpy(sv, s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
make(dp->d_name, level+1);
|
|
||||||
if (dynamic && sv) {
|
|
||||||
setmacro("<", sv, 4);
|
|
||||||
free(sv);
|
|
||||||
}
|
|
||||||
if (np->n_time < dp->d_name->n_time)
|
|
||||||
qdp = newdep(dp->d_name, qdp);
|
|
||||||
dtime = max(dtime, dp->d_name->n_time);
|
|
||||||
}
|
|
||||||
if (!quest && (np->n_flag & N_DOUBLE) && (np->n_time < dtime))
|
|
||||||
{
|
|
||||||
make1(np, lp, qdp); /* free()'s qdp */
|
|
||||||
dtime = 1;
|
|
||||||
qdp = (struct depend *)0;
|
|
||||||
didsomething++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
np->n_flag |= N_DONE;
|
|
||||||
|
|
||||||
if (quest)
|
|
||||||
{
|
|
||||||
long t;
|
|
||||||
|
|
||||||
t = np->n_time;
|
|
||||||
time(&np->n_time);
|
|
||||||
return t < dtime;
|
|
||||||
}
|
|
||||||
else if (np->n_time < dtime && !(np->n_flag & N_DOUBLE))
|
|
||||||
{
|
|
||||||
make1(np, (struct line *)0, qdp); /* free()'s qdp */
|
|
||||||
time(&np->n_time);
|
|
||||||
}
|
|
||||||
else if (level == 0 && !didsomething)
|
|
||||||
printf("%s: '%s' is up to date\n", myname, np->n_name);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
make1(np, lp, qdp)
|
|
||||||
register struct depend * qdp;
|
|
||||||
struct line * lp;
|
|
||||||
struct name * np;
|
|
||||||
{
|
|
||||||
register struct depend * dp;
|
|
||||||
register char *p;
|
|
||||||
char *rindex();
|
|
||||||
|
|
||||||
|
|
||||||
if (dotouch)
|
|
||||||
touch(np);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
strcpy(str1, "");
|
|
||||||
for (dp = qdp; dp; dp = qdp)
|
|
||||||
{
|
|
||||||
if (strlen(str1))
|
|
||||||
strcat(str1, " ");
|
|
||||||
strcat(str1, dp->d_name->n_name);
|
|
||||||
qdp = dp->d_next;
|
|
||||||
free((char *)dp);
|
|
||||||
}
|
|
||||||
setmacro("?", str1, 4);
|
|
||||||
setmacro("@", np->n_name, 4);
|
|
||||||
p = rindex(np->n_name, '.');
|
|
||||||
if (p) *p = 0;
|
|
||||||
setmacro("*", np->n_name, 4);
|
|
||||||
if (p) *p = '.';
|
|
||||||
if (lp) /* lp set if doing a :: rule */
|
|
||||||
docmds1(np, lp);
|
|
||||||
else
|
|
||||||
docmds(np);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,119 +1,121 @@
|
||||||
/*
|
/*
|
||||||
* Read in makefile
|
* Read in makefile
|
||||||
*
|
*
|
||||||
* $Header$
|
* $Header$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include "h.h"
|
#include "h.h"
|
||||||
|
|
||||||
|
|
||||||
int lineno;
|
int lineno;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Syntax error handler. Print message, with line number, and exits.
|
* Syntax error handler. Print message, with line number, and exits.
|
||||||
*/
|
*/
|
||||||
/*VARARGS1*/
|
/*VARARGS1*/
|
||||||
void
|
void error(char *msg, char* a1)
|
||||||
error(msg, a1, a2, a3)
|
|
||||||
char * msg;
|
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s: ", myname);
|
fprintf(stderr, "%s: ", myname);
|
||||||
fprintf(stderr, msg, a1, a2, a3);
|
if (a1 != NULL)
|
||||||
if (lineno)
|
{
|
||||||
fprintf(stderr, " near line %d", lineno);
|
fprintf(stderr, msg, a1);
|
||||||
fputc('\n', stderr);
|
} else
|
||||||
exit(1);
|
{
|
||||||
|
fprintf(stderr, "%s",msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lineno)
|
||||||
|
fprintf(stderr, " near line %d", lineno);
|
||||||
|
fputc('\n', stderr);
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read a line into the supplied string of length LZ. Remove
|
* Read a line into the supplied string of length LZ. Remove
|
||||||
* comments, ignore blank lines. Deal with quoted (\) #, and
|
* comments, ignore blank lines. Deal with quoted (\) #, and
|
||||||
* quoted newlines. If EOF return TRUE.
|
* quoted newlines. If EOF return TRUE.
|
||||||
*/
|
*/
|
||||||
bool
|
bool mgetline(char* str, FILE* fd)
|
||||||
getline(str, fd)
|
|
||||||
char * str;
|
|
||||||
FILE * fd;
|
|
||||||
{
|
{
|
||||||
register char * p;
|
register char * p;
|
||||||
char * q;
|
char * q;
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
if (fgets(str+pos, LZ-pos, fd) == (char *)0)
|
if (fgets(str+pos, LZ-pos, fd) == (char *)0)
|
||||||
return TRUE; /* EOF */
|
return TRUE; /* EOF */
|
||||||
|
|
||||||
lineno++;
|
lineno++;
|
||||||
|
|
||||||
if ((p = index(str+pos, '\n')) == (char *)0)
|
if ((p = strchr(str+pos, '\n')) == (char *)0)
|
||||||
error("Line too long");
|
error("Line too long", NULL);
|
||||||
|
|
||||||
if (p[-1] == '\\')
|
if (p[-1] == '\\')
|
||||||
{
|
{
|
||||||
p[-1] = '\n';
|
p[-1] = '\n';
|
||||||
pos = p - str;
|
pos = p - str;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
p = str;
|
p = str;
|
||||||
while (((q = index(p, '#')) != (char *)0) &&
|
while (((q = strchr(p, '#')) != (char *)0) &&
|
||||||
(p != q) && (q[-1] == '\\'))
|
(p != q) && (q[-1] == '\\'))
|
||||||
{
|
{
|
||||||
char *a;
|
char *a;
|
||||||
|
|
||||||
a = q - 1; /* Del \ chr; move rest back */
|
a = q - 1; /* Del \ chr; move rest back */
|
||||||
p = q;
|
p = q;
|
||||||
while (*a++ = *q++)
|
while ((*a++ = *q++))
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
if (q != (char *)0)
|
if (q != (char *)0)
|
||||||
{
|
{
|
||||||
q[0] = '\n';
|
q[0] = '\n';
|
||||||
q[1] = '\0';
|
q[1] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
p = str;
|
p = str;
|
||||||
while (isspace(*p)) /* Checking for blank */
|
while (isspace(*p)) /* Checking for blank */
|
||||||
p++;
|
p++;
|
||||||
|
|
||||||
if (*p != '\0')
|
if (*p != '\0')
|
||||||
return FALSE;
|
return FALSE;
|
||||||
pos = 0;
|
pos = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get a word from the current line, surounded by white space.
|
* Get a word from the current line, surounded by white space.
|
||||||
* return a pointer to it. String returned has no white spaces
|
* return a pointer to it. String returned has no white spaces
|
||||||
* in it.
|
* in it.
|
||||||
*/
|
*/
|
||||||
char *
|
char *gettok(char **ptr)
|
||||||
gettok(ptr)
|
|
||||||
char **ptr;
|
|
||||||
{
|
{
|
||||||
register char * p;
|
register char * p;
|
||||||
|
|
||||||
|
|
||||||
while (isspace(**ptr)) /* Skip spaces */
|
while (isspace(**ptr)) /* Skip spaces */
|
||||||
(*ptr)++;
|
(*ptr)++;
|
||||||
|
|
||||||
if (**ptr == '\0') /* Nothing after spaces */
|
if (**ptr == '\0') /* Nothing after spaces */
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
p = *ptr; /* word starts here */
|
p = *ptr; /* word starts here */
|
||||||
|
|
||||||
while ((**ptr != '\0') && (!isspace(**ptr)))
|
while ((**ptr != '\0') && (!isspace(**ptr)))
|
||||||
(*ptr)++; /* Find end of word */
|
(*ptr)++; /* Find end of word */
|
||||||
|
|
||||||
*(*ptr)++ = '\0'; /* Terminate it */
|
*(*ptr)++ = '\0'; /* Terminate it */
|
||||||
|
|
||||||
return(p);
|
return(p);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,257 +1,253 @@
|
||||||
/*
|
/*
|
||||||
* Control of the implicit suffix rules
|
* Control of the implicit suffix rules
|
||||||
*
|
*
|
||||||
* $Header$
|
* $Header$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include "h.h"
|
#include "h.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return a pointer to the suffix of a name
|
* Return a pointer to the suffix of a name
|
||||||
*/
|
*/
|
||||||
char *
|
char *suffix(char *name)
|
||||||
suffix(name)
|
|
||||||
char * name;
|
|
||||||
{
|
{
|
||||||
return rindex(name, '.');
|
return strrchr(name, '.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Dynamic dependency. This routine applies the suffis rules
|
* Dynamic dependency. This routine applies the suffis rules
|
||||||
* to try and find a source and a set of rules for a missing
|
* to try and find a source and a set of rules for a missing
|
||||||
* target. If found, np is made into a target with the implicit
|
* target. If found, np is made into a target with the implicit
|
||||||
* source name, and rules. Returns TRUE if np was made into
|
* source name, and rules. Returns TRUE if np was made into
|
||||||
* a target.
|
* a target.
|
||||||
*/
|
*/
|
||||||
bool
|
bool dyndep(struct name *np)
|
||||||
dyndep(np)
|
|
||||||
struct name * np;
|
|
||||||
{
|
{
|
||||||
register char * p;
|
register char * p;
|
||||||
register char * q;
|
register char * q;
|
||||||
register char * suff; /* Old suffix */
|
register char * suff; /* Old suffix */
|
||||||
register char * basename; /* Name without suffix */
|
register char * basename; /* Name without suffix */
|
||||||
struct name * op; /* New dependent */
|
struct name * op; /* New dependent */
|
||||||
struct name * sp; /* Suffix */
|
struct name * sp; /* Suffix */
|
||||||
struct line * lp;
|
struct line * lp;
|
||||||
struct depend * dp;
|
struct depend * dp;
|
||||||
char * newsuff;
|
char * newsuff;
|
||||||
|
|
||||||
|
|
||||||
p = str1;
|
p = str1;
|
||||||
q = np->n_name;
|
q = np->n_name;
|
||||||
if (!(suff = suffix(q)))
|
if (!(suff = suffix(q)))
|
||||||
return FALSE; /* No suffix */
|
return FALSE; /* No suffix */
|
||||||
while (q < suff)
|
while (q < suff)
|
||||||
*p++ = *q++;
|
*p++ = *q++;
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
basename = setmacro("*", str1, 4)->m_val;
|
basename = setmacro("*", str1, 4)->m_val;
|
||||||
|
|
||||||
if (!((sp = newname(".SUFFIXES"))->n_flag & N_TARG))
|
if (!((sp = newname(".SUFFIXES"))->n_flag & N_TARG))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
for (lp = sp->n_line; lp; lp = lp->l_next)
|
for (lp = sp->n_line; lp; lp = lp->l_next)
|
||||||
for (dp = lp->l_dep; dp; dp = dp->d_next)
|
for (dp = lp->l_dep; dp; dp = dp->d_next)
|
||||||
{
|
{
|
||||||
newsuff = dp->d_name->n_name;
|
newsuff = dp->d_name->n_name;
|
||||||
if (strlen(suff)+strlen(newsuff)+1 >= LZ)
|
if (strlen(suff)+strlen(newsuff)+1 >= LZ)
|
||||||
fatal("Suffix rule too long");
|
fatal("Suffix rule too long",NULL);
|
||||||
p = str1;
|
p = str1;
|
||||||
q = newsuff;
|
q = newsuff;
|
||||||
while (*p++ = *q++)
|
while ((*p++ = *q++))
|
||||||
;
|
;
|
||||||
p--;
|
p--;
|
||||||
q = suff;
|
q = suff;
|
||||||
while (*p++ = *q++)
|
while ((*p++ = *q++))
|
||||||
;
|
;
|
||||||
sp = newname(str1);
|
sp = newname(str1);
|
||||||
if (sp->n_flag & N_TARG)
|
if (sp->n_flag & N_TARG)
|
||||||
{
|
{
|
||||||
p = str1;
|
p = str1;
|
||||||
q = basename;
|
q = basename;
|
||||||
if (strlen(basename) + strlen(newsuff)+1 >= LZ)
|
if (strlen(basename) + strlen(newsuff)+1 >= LZ)
|
||||||
fatal("Implicit name too long");
|
fatal("Implicit name too long",NULL);
|
||||||
while (*p++ = *q++)
|
while ((*p++ = *q++))
|
||||||
;
|
;
|
||||||
p--;
|
p--;
|
||||||
q = newsuff;
|
q = newsuff;
|
||||||
while (*p++ = *q++)
|
while ((*p++ = *q++))
|
||||||
;
|
;
|
||||||
op = newname(str1);
|
op = newname(str1);
|
||||||
if (!op->n_time)
|
if (!op->n_time)
|
||||||
modtime(op);
|
modtime(op);
|
||||||
if (op->n_time || (op->n_flag & N_TARG))
|
if (op->n_time || (op->n_flag & N_TARG))
|
||||||
{
|
{
|
||||||
dp = newdep(op, (struct depend *)0);
|
dp = newdep(op, (struct depend *)0);
|
||||||
newline(np, dp, sp->n_line->l_cmd, 0);
|
newline(np, dp, sp->n_line->l_cmd, 0);
|
||||||
setmacro("<", op->n_name, 4);
|
setmacro("<", op->n_name, 4);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make the default rules
|
* Make the default rules
|
||||||
*/
|
*/
|
||||||
void
|
void makerules(void)
|
||||||
makerules()
|
|
||||||
{
|
{
|
||||||
struct cmd * cp;
|
struct cmd * cp;
|
||||||
struct name * np;
|
struct name * np;
|
||||||
struct depend * dp;
|
struct depend * dp;
|
||||||
|
|
||||||
|
|
||||||
#ifdef eon
|
#ifdef eon
|
||||||
setmacro("BDSCC", "asm", 0);
|
setmacro("BDSCC", "asm", 0);
|
||||||
/* setmacro("BDSCFLAGS", "", 0); */
|
/* setmacro("BDSCFLAGS", "", 0); */
|
||||||
cp = newcmd("$(BDSCC) $(BDSCFLAGS) -n $<", (struct cmd *)0);
|
cp = newcmd("$(BDSCC) $(BDSCFLAGS) -n $<", (struct cmd *)0);
|
||||||
np = newname(".c.o");
|
np = newname(".c.o");
|
||||||
newline(np, (struct depend *)0, cp, 0);
|
newline(np, (struct depend *)0, cp, 0);
|
||||||
|
|
||||||
setmacro("CC", "c", 0);
|
setmacro("CC", "c", 0);
|
||||||
setmacro("CFLAGS", "-O", 0);
|
setmacro("CFLAGS", "-O", 0);
|
||||||
cp = newcmd("$(CC) $(CFLAGS) -c $<", (struct cmd *)0);
|
cp = newcmd("$(CC) $(CFLAGS) -c $<", (struct cmd *)0);
|
||||||
np = newname(".c.obj");
|
np = newname(".c.obj");
|
||||||
newline(np, (struct depend *)0, cp, 0);
|
newline(np, (struct depend *)0, cp, 0);
|
||||||
|
|
||||||
setmacro("M80", "asm -n", 0);
|
setmacro("M80", "asm -n", 0);
|
||||||
/* setmacro("M80FLAGS", "", 0); */
|
/* setmacro("M80FLAGS", "", 0); */
|
||||||
cp = newcmd("$(M80) $(M80FLAGS) $<", (struct cmd *)0);
|
cp = newcmd("$(M80) $(M80FLAGS) $<", (struct cmd *)0);
|
||||||
np = newname(".mac.o");
|
np = newname(".mac.o");
|
||||||
newline(np, (struct depend *)0, cp, 0);
|
newline(np, (struct depend *)0, cp, 0);
|
||||||
|
|
||||||
setmacro("AS", "zas", 0);
|
setmacro("AS", "zas", 0);
|
||||||
/* setmacro("ASFLAGS", "", 0); */
|
/* setmacro("ASFLAGS", "", 0); */
|
||||||
cp = newcmd("$(ZAS) $(ASFLAGS) -o $@ $<", (struct cmd *)0);
|
cp = newcmd("$(ZAS) $(ASFLAGS) -o $@ $<", (struct cmd *)0);
|
||||||
np = newname(".as.obj");
|
np = newname(".as.obj");
|
||||||
newline(np, (struct depend *)0, cp, 0);
|
newline(np, (struct depend *)0, cp, 0);
|
||||||
|
|
||||||
np = newname(".as");
|
np = newname(".as");
|
||||||
dp = newdep(np, (struct depend *)0);
|
dp = newdep(np, (struct depend *)0);
|
||||||
np = newname(".obj");
|
np = newname(".obj");
|
||||||
dp = newdep(np, dp);
|
dp = newdep(np, dp);
|
||||||
np = newname(".c");
|
np = newname(".c");
|
||||||
dp = newdep(np, dp);
|
dp = newdep(np, dp);
|
||||||
np = newname(".o");
|
np = newname(".o");
|
||||||
dp = newdep(np, dp);
|
dp = newdep(np, dp);
|
||||||
np = newname(".mac");
|
np = newname(".mac");
|
||||||
dp = newdep(np, dp);
|
dp = newdep(np, dp);
|
||||||
np = newname(".SUFFIXES");
|
np = newname(".SUFFIXES");
|
||||||
newline(np, dp, (struct cmd *)0, 0);
|
newline(np, dp, (struct cmd *)0, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Some of the UNIX implicit rules
|
* Some of the UNIX implicit rules
|
||||||
*/
|
*/
|
||||||
#ifdef unix
|
#ifdef unix
|
||||||
setmacro("CC", "cc", 0);
|
setmacro("CC", "cc", 0);
|
||||||
setmacro("CFLAGS", "-O", 0);
|
setmacro("CFLAGS", "-O", 0);
|
||||||
#ifdef MINIX
|
#ifdef MINIX
|
||||||
cp = newcmd("$(CC) $(CFLAGS) -S $<", (struct cmd *)0);
|
cp = newcmd("$(CC) $(CFLAGS) -S $<", (struct cmd *)0);
|
||||||
np = newname(".c.s");
|
np = newname(".c.s");
|
||||||
#else
|
#else
|
||||||
cp = newcmd("$(CC) $(CFLAGS) -c $<", (struct cmd *)0);
|
cp = newcmd("$(CC) $(CFLAGS) -c $<", (struct cmd *)0);
|
||||||
np = newname(".c.o");
|
np = newname(".c.o");
|
||||||
#endif MINIX
|
#endif /* MINIX */
|
||||||
newline(np, (struct depend *)0, cp, 0);
|
newline(np, (struct depend *)0, cp, 0);
|
||||||
|
|
||||||
setmacro("AS", "as", 0);
|
setmacro("AS", "as", 0);
|
||||||
cp = newcmd("$(AS) -o $@ $<", (struct cmd *)0);
|
cp = newcmd("$(AS) -o $@ $<", (struct cmd *)0);
|
||||||
np = newname(".s.o");
|
np = newname(".s.o");
|
||||||
newline(np, (struct depend *)0, cp, 0);
|
newline(np, (struct depend *)0, cp, 0);
|
||||||
|
|
||||||
setmacro("YACC", "yacc", 0);
|
setmacro("YACC", "yacc", 0);
|
||||||
/* setmacro("YFLAGS", "", 0); */
|
/* setmacro("YFLAGS", "", 0); */
|
||||||
cp = newcmd("$(YACC) $(YFLAGS) $<", (struct cmd *)0);
|
cp = newcmd("$(YACC) $(YFLAGS) $<", (struct cmd *)0);
|
||||||
cp = newcmd("mv y.tab.c $@", cp);
|
cp = newcmd("mv y.tab.c $@", cp);
|
||||||
np = newname(".y.c");
|
np = newname(".y.c");
|
||||||
newline(np, (struct depend *)0, cp, 0);
|
newline(np, (struct depend *)0, cp, 0);
|
||||||
|
|
||||||
cp = newcmd("$(YACC) $(YFLAGS) $<", (struct cmd *)0);
|
cp = newcmd("$(YACC) $(YFLAGS) $<", (struct cmd *)0);
|
||||||
cp = newcmd("$(CC) $(CFLAGS) -c y.tab.c", cp);
|
cp = newcmd("$(CC) $(CFLAGS) -c y.tab.c", cp);
|
||||||
cp = newcmd("rm y.tab.c", cp);
|
cp = newcmd("rm y.tab.c", cp);
|
||||||
cp = newcmd("mv y.tab.o $@", cp);
|
cp = newcmd("mv y.tab.o $@", cp);
|
||||||
np = newname(".y.o");
|
np = newname(".y.o");
|
||||||
newline(np, (struct depend *)0, cp, 0);
|
newline(np, (struct depend *)0, cp, 0);
|
||||||
|
|
||||||
setmacro("LEX", "lex", 0);
|
setmacro("LEX", "lex", 0);
|
||||||
/* setmacro("LFLAGS", "", 0); */
|
/* setmacro("LFLAGS", "", 0); */
|
||||||
cp = newcmd("$(LEX) $(LFLAGS) $<", (struct cmd *)0);
|
cp = newcmd("$(LEX) $(LFLAGS) $<", (struct cmd *)0);
|
||||||
cp = newcmd("mv lex.yy.c $@", cp);
|
cp = newcmd("mv lex.yy.c $@", cp);
|
||||||
np = newname(".l.c");
|
np = newname(".l.c");
|
||||||
newline(np, (struct depend *)0, cp, 0);
|
newline(np, (struct depend *)0, cp, 0);
|
||||||
|
|
||||||
cp = newcmd("$(LEX) $(LFLAGS) $<", (struct cmd *)0);
|
cp = newcmd("$(LEX) $(LFLAGS) $<", (struct cmd *)0);
|
||||||
cp = newcmd("$(CC) $(CFLAGS) -c lex.yy.c", cp);
|
cp = newcmd("$(CC) $(CFLAGS) -c lex.yy.c", cp);
|
||||||
cp = newcmd("rm lex.yy.c", cp);
|
cp = newcmd("rm lex.yy.c", cp);
|
||||||
cp = newcmd("mv lex.yy.o $@", cp);
|
cp = newcmd("mv lex.yy.o $@", cp);
|
||||||
np = newname(".l.o");
|
np = newname(".l.o");
|
||||||
newline(np, (struct depend *)0, cp, 0);
|
newline(np, (struct depend *)0, cp, 0);
|
||||||
|
|
||||||
np = newname(".s");
|
np = newname(".s");
|
||||||
dp = newdep(np, (struct depend *)0);
|
dp = newdep(np, (struct depend *)0);
|
||||||
np = newname(".o");
|
np = newname(".o");
|
||||||
dp = newdep(np, dp);
|
dp = newdep(np, dp);
|
||||||
np = newname(".c");
|
np = newname(".c");
|
||||||
dp = newdep(np, dp);
|
dp = newdep(np, dp);
|
||||||
np = newname(".y");
|
np = newname(".y");
|
||||||
dp = newdep(np, dp);
|
dp = newdep(np, dp);
|
||||||
np = newname(".l");
|
np = newname(".l");
|
||||||
dp = newdep(np, dp);
|
dp = newdep(np, dp);
|
||||||
np = newname(".SUFFIXES");
|
np = newname(".SUFFIXES");
|
||||||
newline(np, dp, (struct cmd *)0, 0);
|
newline(np, dp, (struct cmd *)0, 0);
|
||||||
#endif
|
#endif
|
||||||
#ifdef os9
|
#ifdef os9
|
||||||
/*
|
/*
|
||||||
* Fairlight use an enhanced version of the C sub-system.
|
* Fairlight use an enhanced version of the C sub-system.
|
||||||
* They have a specialised macro pre-processor.
|
* They have a specialised macro pre-processor.
|
||||||
*/
|
*/
|
||||||
setmacro("CC", "cc", 0);
|
setmacro("CC", "cc", 0);
|
||||||
setmacro("CFLAGS", "-z", 0);
|
setmacro("CFLAGS", "-z", 0);
|
||||||
cp = newcmd("$(CC) $(CFLAGS) -r $<", (struct cmd *)0);
|
cp = newcmd("$(CC) $(CFLAGS) -r $<", (struct cmd *)0);
|
||||||
|
|
||||||
np = newname(".c.r");
|
np = newname(".c.r");
|
||||||
newline(np, (struct depend *)0, cp, 0);
|
newline(np, (struct depend *)0, cp, 0);
|
||||||
np = newname(".ca.r");
|
np = newname(".ca.r");
|
||||||
newline(np, (struct depend *)0, cp, 0);
|
newline(np, (struct depend *)0, cp, 0);
|
||||||
np = newname(".a.r");
|
np = newname(".a.r");
|
||||||
newline(np, (struct depend *)0, cp, 0);
|
newline(np, (struct depend *)0, cp, 0);
|
||||||
np = newname(".o.r");
|
np = newname(".o.r");
|
||||||
newline(np, (struct depend *)0, cp, 0);
|
newline(np, (struct depend *)0, cp, 0);
|
||||||
np = newname(".mc.r");
|
np = newname(".mc.r");
|
||||||
newline(np, (struct depend *)0, cp, 0);
|
newline(np, (struct depend *)0, cp, 0);
|
||||||
np = newname(".mca.r");
|
np = newname(".mca.r");
|
||||||
newline(np, (struct depend *)0, cp, 0);
|
newline(np, (struct depend *)0, cp, 0);
|
||||||
np = newname(".ma.r");
|
np = newname(".ma.r");
|
||||||
newline(np, (struct depend *)0, cp, 0);
|
newline(np, (struct depend *)0, cp, 0);
|
||||||
np = newname(".mo.r");
|
np = newname(".mo.r");
|
||||||
newline(np, (struct depend *)0, cp, 0);
|
newline(np, (struct depend *)0, cp, 0);
|
||||||
|
|
||||||
np = newname(".r");
|
np = newname(".r");
|
||||||
dp = newdep(np, (struct depend *)0);
|
dp = newdep(np, (struct depend *)0);
|
||||||
np = newname(".mc");
|
np = newname(".mc");
|
||||||
dp = newdep(np, dp);
|
dp = newdep(np, dp);
|
||||||
np = newname(".mca");
|
np = newname(".mca");
|
||||||
dp = newdep(np, dp);
|
dp = newdep(np, dp);
|
||||||
np = newname(".c");
|
np = newname(".c");
|
||||||
dp = newdep(np, dp);
|
dp = newdep(np, dp);
|
||||||
np = newname(".ca");
|
np = newname(".ca");
|
||||||
dp = newdep(np, dp);
|
dp = newdep(np, dp);
|
||||||
np = newname(".ma");
|
np = newname(".ma");
|
||||||
dp = newdep(np, dp);
|
dp = newdep(np, dp);
|
||||||
np = newname(".mo");
|
np = newname(".mo");
|
||||||
dp = newdep(np, dp);
|
dp = newdep(np, dp);
|
||||||
np = newname(".o");
|
np = newname(".o");
|
||||||
dp = newdep(np, dp);
|
dp = newdep(np, dp);
|
||||||
np = newname(".a");
|
np = newname(".a");
|
||||||
dp = newdep(np, dp);
|
dp = newdep(np, dp);
|
||||||
np = newname(".SUFFIXES");
|
np = newname(".SUFFIXES");
|
||||||
newline(np, dp, (struct cmd *)0, 0);
|
newline(np, dp, (struct cmd *)0, 0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue