diff options
494 files changed, 52571 insertions, 0 deletions
diff --git a/dmake/alloc.h b/dmake/alloc.h new file mode 100644 index 000000000000..876284de06a8 --- /dev/null +++ b/dmake/alloc.h @@ -0,0 +1,59 @@ +/* RCS $Id: alloc.h,v 1.1.1.1 2000-09-22 15:33:25 hr Exp $ +-- +-- SYNOPSIS +-- Macros for allocating memory. +-- +-- DESCRIPTION +-- A somewhat nicer interface to malloc and calloc. +-- Here we standardise the calling convention with a common macro +-- interface. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef ALLOC_h +#define ALLOC_h + +/* DO NOT CHANGE these! These are the definitions that the make source + * uses for allocating memory. They must be defined for make to compile + * properly. + */ + +/* This is the only place that we define size_t now. This should be more + * than enough! */ +#if __STDC__ +#else +# if !defined(_TYPES_) && !defined(M_XENIX) && !defined(atarist) && !defined(_MPW) && !defined(_SIZE_T) && !defined(_SIZE_T_) && !defined(__size_t) && !defined(_WIN32) +# if defined(MSDOS) || defined(__MSDOS__) +# undef size_t + typedef unsigned size_t; +# else + typedef long size_t; +# endif +# endif +#endif + +#define usizeof(t) (size_t)sizeof(t) + +#define FREE(p) free((char*)(p)) +#define MALLOC(n, t) (t*) malloc((unsigned int)(n)*usizeof(t)) +#define CALLOC(n, t) (t*) calloc((unsigned int)(n), usizeof(t)) + +#define TALLOC(p, n, t) if ((p = CALLOC(n, t)) == (t*)0) {No_ram();} + +#endif + diff --git a/dmake/dag.c b/dmake/dag.c new file mode 100644 index 000000000000..09efcb510c99 --- /dev/null +++ b/dmake/dag.c @@ -0,0 +1,577 @@ +/* RCS $Id: dag.c,v 1.1.1.1 2000-09-22 15:33:25 hr Exp $ +-- +-- SYNOPSIS +-- Routines to construct the internal dag. +-- +-- DESCRIPTION +-- This file contains all the routines that are responsible for +-- defining and manipulating all objects used by the make facility. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include "extern.h" + +static void +set_macro_value(hp) +HASHPTR hp; +{ + switch( hp->ht_flag & M_VAR_MASK ) /* only one var type per var */ + { + case M_VAR_STRING: + *hp->MV_SVAR = hp->ht_value; + break; + + case M_VAR_CHAR: + *hp->MV_CVAR = (hp->ht_value == NIL(char)) ? '\0':*hp->ht_value; + break; + + case M_VAR_INT: { + int tvalue; + if( hp->MV_IVAR == NIL(int) ) break; /* first time */ + + tvalue = atoi(hp->ht_value); + if( hp->MV_IVAR == &Buffer_size ) { + /* If Buffer_size is modified then make sure you change the + * size of the real buffer as well. */ + tvalue = (tvalue < (BUFSIZ-2)) ? BUFSIZ : tvalue+2; + if( Buffer_size == tvalue ) break; + if( Buffer ) FREE(Buffer); + if((Buffer=MALLOC(tvalue, char)) == NIL(char)) No_ram(); + *Buffer = '\0'; + } + *hp->MV_IVAR = tvalue; + + if( hp->MV_IVAR == &Max_proc || hp->MV_IVAR == &Max_proclmt ) { + if( tvalue < 1 ) + Fatal( "Process limit value must be > 1" ); + + if( Max_proc > Max_proclmt ) + Fatal( "Specified # of processes exceeds limit of [%d]", + Max_proclmt ); + } + } break; + + case M_VAR_BIT: + /* Bit variables are set to 1 if ht_value is not NULL and 0 + * otherwise */ + + if( hp->ht_value == NIL(char) ) + *hp->MV_BVAR &= ~hp->MV_MASK; + else + *hp->MV_BVAR |= hp->MV_MASK; + break; + } +} + + +PUBLIC HASHPTR +Get_name( name, tab, define )/* +=============================== + Look to see if the name is defined, if it is then return + a pointer to its node, if not return NIL(HASH). + If define is TRUE and the name is not found it will be added. */ + +char *name; /* name we are looking for */ +HASHPTR *tab; /* the hash table to look in */ +int define; /* TRUE => add to table */ +{ + register HASHPTR hp; + register char *p; + uint16 hv; + uint32 hash_key; + + DB_ENTER( "Get_name" ); + DB_PRINT( "name", ("Looking for %s", name) ); + + hp = Search_table( tab, name, &hv, &hash_key ); + + if( hp == NIL(HASH) && define ) { + /* Check to make sure that CELL name contains only printable chars */ + for( p=name; *p; p++ ) + if( !isprint(*p) && !iswhite(*p) && *p != '\n' ) + Fatal( "Name contains non-printable character [0x%02x]", *p ); + + TALLOC( hp, 1, HASH ); /* allocate a cell and add it in */ + + hp->ht_name = DmStrDup( name ); + hp->ht_hash = hash_key; + hp->ht_next = tab[ hv ]; + tab[ hv ] = hp; + + DB_PRINT( "name", ("Adding %s", name) ); + } + + DB_PRINT( "name",("Returning: [%s,%lu]", + (hp == NIL(HASH)) ? "":hp->ht_name, hv) ); + DB_RETURN( hp ); +} + + +PUBLIC HASHPTR +Search_table( tab, name, phv, phkey ) +HASHPTR *tab; +char *name; +uint16 *phv; +uint32 *phkey; +{ + HASHPTR hp; + + *phv = Hash( name, phkey ); + + for( hp = tab[ *phv ]; hp != NIL(HASH); hp = hp->ht_next ) + if( hp->ht_hash == *phkey + && !strcmp(hp->ht_name, name) ) + break; + + return( hp ); +} + + +PUBLIC HASHPTR +Push_macro(hp) +HASHPTR hp; +{ + HASHPTR cur,prev; + uint16 hv; + uint32 key; + + hv = Hash(hp->ht_name, &key); + + for(prev=NIL(HASH),cur=Macs[hv]; cur!=NIL(HASH); prev=cur,cur=cur->ht_next) + if( cur->ht_hash == key + && !strcmp(cur->ht_name, hp->ht_name) ) + break; + + if (cur == NIL(HASH) || prev == NIL(HASH)) { + hp->ht_next = Macs[hv]; + Macs[hv] = hp; + } + else { + hp->ht_next = prev->ht_next; + prev->ht_next = hp; + } + + if (cur) { + memcpy((void *)&hp->var, (void *)&cur->var, sizeof(hp->var)); + hp->ht_flag |= ((M_VAR_MASK|M_PRECIOUS) & cur->ht_flag); + } + + return(hp); +} + + +PUBLIC HASHPTR +Pop_macro(hp) +HASHPTR hp; +{ + HASHPTR cur,prev; + uint16 hv; + uint32 key; + + hv = Hash(hp->ht_name, &key); + + for(prev=NIL(HASH),cur=Macs[hv]; cur != NIL(HASH);prev=cur,cur=cur->ht_next) + if (cur == hp) + break; + + if (cur == NIL(HASH)) + return(NIL(HASH)); + + if (prev) + prev->ht_next = cur->ht_next; + else + Macs[hv] = cur->ht_next; + + for(cur=cur->ht_next; cur != NIL(HASH); cur=cur->ht_next) + if( cur->ht_hash == key + && !strcmp(cur->ht_name, hp->ht_name) ) + break; + + if (cur) + set_macro_value(cur); + + hp->ht_next = NIL(HASH); + return(hp); +} + + + +PUBLIC HASHPTR +Def_macro( name, value, flags )/* +================================= + This routine is used to define a macro, and it's value. + The flags indicates if it is a permanent macro or if it's value + can be redefined. A flags of M_PRECIOUS means it is a precious + macro and cannot be further redefined. If the flags flag also + contains the M_MULTI bit it means that the macro can be redefined + multiple times and no warning of the redefinitions should be issued. + Once a macro's VAR flags are set they are preserved through all future + macro definitions. + + Macro definitions that have one of the variable bits set are treated + specially. In each case the hash table entry var field points at the + global variable that can be set by assigning to the macro. + + bit valued global vars must be computed when the macro value is changed. + char valued global vars must have the first char of ht_value copied to + them. string valued global vars have the same value as ht_value and should + just have the new value of ht_value copied to them. */ + +char *name; /* macro name to define */ +char *value; /* macro value to set */ +int flags; /* initial ht_flags */ +{ + register HASHPTR hp; + register char *p, *q; + + DB_ENTER( "Def_macro" ); + DB_PRINT( "mac", ("Defining macro %s = %s, %x", name, value, flags) ); + + /* check to see if name is in the table, if so then just overwrite + the previous definition. Otherwise allocate a new node, and + stuff it in the hash table, at the front of any linked list */ + + if( Readenv ) flags |= M_LITERAL|M_EXPANDED; + + hp = Get_name( name, Macs, TRUE ); + + if ((flags & M_PUSH) && hp->ht_name != NIL(char)) { + HASHPTR thp=hp; + TALLOC(hp,1,HASH); + hp->ht_name = DmStrDup(thp->ht_name); + hp->ht_hash = thp->ht_hash; + Push_macro(hp); + flags |= hp->ht_flag; + } + flags &= ~M_PUSH; + + if( (hp->ht_flag & M_PRECIOUS) && !(flags & M_FORCE) ) { + if (Verbose & V_WARNALL) + Warning( "Macro `%s' cannot be redefined", name ); + DB_RETURN( hp ); + } + + /* Make sure we don't export macros whose names contain legal macro + * assignment operators, since we can't do proper quoting in the + * environment. */ + if( *DmStrPbrk(name, "*+:=") != '\0' ) flags |= M_NOEXPORT; + + if( hp->ht_value != NIL(char) ) FREE( hp->ht_value ); + + if( (hp->ht_flag & M_USED) && !((flags | hp->ht_flag) & M_MULTI) ) + Warning( "Macro `%s' redefined after use", name ); + + if( (value != NIL(char)) && (*value) ) { + /* strip out any \<nl> combinations where \ is the current CONTINUATION + * char */ + + for( p = value; (p = strchr(p, CONTINUATION_CHAR)) != NIL(char); ) + if( p[1] == '\n' ) + strcpy( p, p+2 ); + else + p++; + + if( !(flags & M_LITERAL) ) { + p = DmStrDup( DmStrSpn(value," \t")); /* strip white space before */ + /* ... and after value */ + if( *p ) { + for(q=p+strlen(p)-1; ((*q == ' ')||(*q == '\t')); q--); + *++q = '\0'; + } + flags &= ~M_LITERAL; + } + else + p = DmStrDup( value ); /* take string literally */ + + if( !*p ) { /* check if result is "" */ + FREE( p ); + p = NIL(char); + flags |= M_EXPANDED; + } + else if( *DmStrPbrk( p, "${}" ) == '\0' ) + flags |= M_EXPANDED; + + hp->ht_value = p; + } + else + hp->ht_value = NIL(char); + + /* Assign the hash table flag less the M_MULTI flag, it is used only + * to silence the warning. But carry it over if it was previously + * defined in ht_flag, as this is a permanent M_MULTI variable. */ + + hp->ht_flag = (((flags & ~(M_MULTI|M_FORCE)) | + (hp->ht_flag & (M_VAR_MASK | M_MULTI)))) & ~M_INIT; + + /* Check for macro variables and make the necessary adjustment in the + * corresponding global variables */ + + if( hp->ht_flag & M_VAR_MASK ) + if( !(flags & M_EXPANDED) ) + Error( "Macro variable '%s' must be assigned with :=", name ); + else + set_macro_value(hp); + + DB_RETURN( hp ); +} + + + +PUBLIC CELLPTR +Def_cell( name )/* +================== + Take a string passed in and define it as a cell + If the cell exists then return a pointer to it. */ +char *name; +{ + register HASHPTR hp; + register CELLPTR cp; + register CELLPTR lib; + char *member; + char *end; + + DB_ENTER( "Def_cell" ); + + /* Check to see if the cell is a member of the form lib(member) or + * lib((symbol)) and handle the cases appropriately. + * What we do is we look at the target, if it is of the above two + * forms we get the lib, and add the member/symbol to the list of + * prerequisites for the library. If this is a symbol name def'n + * we additionally add the attribute A_SYMBOL, so that stat can + * try to do the right thing. */ + + if( ((member = strchr(name, '(')) != NIL(char)) && + ((end = strrchr(member, ')')) != NIL(char)) && + (member > name) && (member[-1] != '$') && + (end > member+1) && (end[1] == '\0') ) + { + *member++ = *end = '\0'; + + if( (*member == '(') && (member[strlen(member)-1] == ')') ) { + member[ strlen(member)-1 ] = '\0'; + cp = Def_cell( member+1 ); + cp->ce_attr |= A_SYMBOL; + } + else + cp = Def_cell( member ); + + lib = Def_cell( name ); + + Add_prerequisite( lib, cp, FALSE, FALSE ); + lib->ce_attr |= A_LIBRARY | A_COMPOSITE; + + if( !Def_targets ) cp = lib; + } + else { + hp = Get_name( name, Defs, TRUE );/* get the name from hash table */ + + if( hp->CP_OWNR == NIL(CELL) ) /* was it previously defined */ + { /* NO, so define a new cell */ + DB_PRINT( "cell", ("Defining cell [%s]", name) ); + + TALLOC( cp, 1, CELL ); + hp->CP_OWNR = cp; + cp->ce_name = hp; + cp->ce_fname = hp->ht_name; + cp->ce_all.cl_prq = cp; + } + else /* YES, so return the old cell */ + { + DB_PRINT( "cell", ("Getting cell [%s]", hp->ht_name) ); + cp = hp->CP_OWNR; + } + } + + DB_RETURN( cp ); +} + + + + +PUBLIC LINKPTR +Add_prerequisite( cell, prq, head, force )/* +============================================ + Add a dependency node to the dag. It adds it to the prerequisites, + if any, of the cell and makes certain they are in linear order. + If head == 1, then add to head of the prerequisite list, else + add to tail. */ +CELLPTR cell; +CELLPTR prq; +int head; +int force; +{ + register LINKPTR lp, tlp; + + DB_ENTER( "Add_prerequisite" ); + DB_PRINT( "cell", ("Defining prerequisite %s", prq->CE_NAME) ); + + if( (prq->ce_flag & (F_MAGIC | F_PERCENT)) && !force ) + Fatal( "Special target [%s] cannot be a prerequisite", + prq->CE_NAME ); + + if( cell->ce_prq == NIL(LINK) ) { /* it's the first one */ + TALLOC( lp, 1, LINK ); + lp->cl_prq = prq; + cell->ce_prq = lp; + } + else { /* search the list, checking for duplicates */ + for( lp = cell->ce_prq; + (lp->cl_next != NIL(LINK)) && (lp->cl_prq != prq); + lp = lp->cl_next ); + + /* If the prq is not found and we are at the last prq in the list, + * allocate a new prq and place it into the list, insert it at the + * head if head == 1, else we add it to the end. */ + + if( lp->cl_prq != prq ) { + TALLOC( tlp, 1, LINK ); + tlp->cl_prq = prq; + + if( head ) { + tlp->cl_next = cell->ce_prq; + cell->ce_prq = tlp; + } + else + lp->cl_next = tlp; + + lp = tlp; + } + } + + DB_RETURN( lp ); +} + + + +PUBLIC void +Clear_prerequisites( cell )/* +============================= + Clear out the list of prerequisites, freeing all of the LINK nodes, + and setting the list to NULL */ +CELLPTR cell; +{ + LINKPTR lp, tlp; + + DB_ENTER( "Clear_prerequisites" ); + DB_PRINT( "cell", ("Nuking prerequisites") ); + + if( cell == NIL(CELL) ) { DB_VOID_RETURN; } + + for( lp=cell->ce_prq; lp != NIL(LINK); lp=tlp ) { + tlp=lp->cl_next; + FREE( lp ); + } + + cell->ce_prq = NIL(LINK); + + DB_VOID_RETURN; +} + + +PUBLIC int +Test_circle( cp, fail )/* +========================= + Actually run through the graph */ +CELLPTR cp; +int fail; +{ + register LINKPTR lp; + int res = 0; + + DB_ENTER( "Test_circle" ); + DB_PRINT( "tc", ("checking [%s]", cp->CE_NAME) ); + + if( cp->ce_flag & F_MARK ) + if( fail ) + Fatal("Detected circular dependency in graph at [%s]", cp->CE_NAME); + else + DB_RETURN( 1 ); + + cp->ce_flag |= F_MARK; + for( lp = cp->ce_prq; !res && lp != NIL(LINK); lp = lp->cl_next ) + res = Test_circle( lp->cl_prq, fail ); + cp->ce_flag ^= F_MARK; + + DB_RETURN( res ); +} + + + +PUBLIC STRINGPTR +Def_recipe( rcp, sp, white_too, no_check )/* +============================================= + Take the recipe and add it to the list of recipes + pointed to by sp. sp points to the last element. + return a pointer to the new recipe. If white_too == TRUE add the + recipe even if it contains only white space. + If no_check is true then don't look for -@ at the start of the + recipe line. */ +char *rcp; +STRINGPTR sp; +int white_too; +int no_check; +{ + register STRINGPTR nsp; + register char *rp; + + DB_ENTER( "Def_recipe" ); + DB_PRINT( "rul", ("Defining recipe %s", rcp) ); + + if( !white_too ) rcp = DmStrSpn( rcp, " \t" ); + if( (rcp == NIL(char)) || (*rcp == 0 && !white_too) ) + DB_RETURN( sp ); /* return last recipe when new recipe not added */ + + rp = no_check ? rcp : DmStrSpn( rcp, " \t@-+%" ); + + TALLOC(nsp, 1, STRING); + nsp->st_string = DmStrDup( rp ); + + if( sp != NIL(STRING) ) sp->st_next = nsp; + nsp->st_next = NIL(STRING); + + if( !no_check ) nsp->st_attr |= Rcp_attribute( rcp ); + + DB_RETURN( nsp ); +} + + +PUBLIC t_attr +Rcp_attribute( rp )/* +====================== + Look at the recipe and return the set of attributes that it defines. */ +char *rp; +{ + t_attr flag = A_DEFAULT; + int done = FALSE; + + while( !done ) + switch( *rp++ ) + { + case '@' : flag |= A_SILENT; break; + case '-' : flag |= A_IGNORE; break; + case '+' : flag |= A_SHELL; break; + case '%' : flag |= A_SWAP; break; + + case ' ' : + case '\t': break; + + default: done = TRUE; break; + } + + return(flag); +} diff --git a/dmake/db.h b/dmake/db.h new file mode 100644 index 000000000000..a640dfaee7a4 --- /dev/null +++ b/dmake/db.h @@ -0,0 +1,66 @@ +/* RCS $Id: db.h,v 1.1.1.1 2000-09-22 15:33:25 hr Exp $ +-- +-- SYNOPSIS +-- Front end to DBUG macros. +-- +-- DESCRIPTION +-- This is a front end to Fred Fish's DBUG macros. The intent was +-- to provide an interface so that if you don't have the DBUG code +-- you can still compile dmake, by undefining DBUG, if you do have +-- the code then you can use Fred Fish's DBUG package. Originally +-- the DBUG stuff was copyrighted, it is now in the public domain +-- so the need for this is not as apparent. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef DB_h +#define DB_h + +#ifdef DBUG + +# include "dbug.h" + +# define DB_ENTER(a1) DBUG_ENTER(a1) +# define DB_RETURN(a1) DBUG_RETURN(a1) +# define DB_VOID_RETURN DBUG_VOID_RETURN +# define DB_EXECUTE(keyword, a1) DBUG_EXECUTE(keyword,a1) +# define DB_PRINT(keyword,arglist) DBUG_PRINT(keyword,arglist) +# define DB_PUSH(a1) DBUG_PUSH(a1) +# define DB_POP() DBUG_POP() +# define DB_PROCESS(a1) DBUG_PROCESS(a1) +# define DB_FILE(file) DBUG_FILE(file) +# define DB_SETJMP DBUG_SETJMP +# define DB_LONGJMP DBUG_LONGJMP + +#else + +# define DB_ENTER(a1) +# define DB_RETURN(a1) return (a1) +# define DB_VOID_RETURN return +# define DB_EXECUTE(keyword, a1) +# define DB_PRINT(keyword,arglist) +# define DB_PUSH(a1) +# define DB_POP() +# define DB_PROCESS(a1) +# define DB_FILE(file) +# define DB_SETJMP setjmp +# define DB_LONGJMP longjmp + +#endif +#endif + diff --git a/dmake/dbug/dbug.mk b/dmake/dbug/dbug.mk new file mode 100644 index 000000000000..09aa82d7f37d --- /dev/null +++ b/dmake/dbug/dbug.mk @@ -0,0 +1,66 @@ +# Set the proper macros based on whether we are making the debugging version +# or not. The valid parameters to this file are: +# +# DEBUG=1 ==> enable the making of the DBUG version +# DBMALLOC=1 ==> enable DBUG version with extensive MALLOC checking +# +# DB_CFLAGS ==> CFLAGS is set to this value at the end if DEBUG=1 +# DB_LDFLAGS ==> LDFLAGS is set to this at the end if DEBUG=1 +# DB_LDLIBS ==> LDLIBS is set to this at end if DEBUG=1 +# +# The non debug versions of the above three macros are: +# +# NDB_CFLAGS +# NDB_LDFLAGS +# NDB_LDLIBS +# +# One of the set of three should have values set appropriately prior to +# sourcing this file. + +.IF $(DEBUG) + DBUG_SRC += dbug.c + DB_CFLAGS += -Idbug/dbug + + .SETDIR=dbug/dbug : $(DBUG_SRC) + + # If DBMALLOC is requested (ie non-NULL) then include the sources for + # compilation. BSD 4.3 needs the getwd.c source compiled in due to a bug + # in the clib getwd routine. + .IF $(DBMALLOC) + # Serious bug in bsd43 getwd.c would free a string and then use its + # value. The DBMALLOC code clears a string when it is free'd so the + # value was no longer valid and the returned path for the current + # directory was now completely wrong. + .IF $(OSRELEASE) == bsd43 + GETWD_SRC += getwd.c + .SETDIR=dbug : $(GETWD_SRC) + .END + + MLC_SRC += malloc.c free.c realloc.c calloc.c string.c\ + mlc_chk.c mlc_chn.c memory.c tostring.c m_perror.c\ + m_init.c mallopt.c dump.c + + .SETDIR=dbug/malloc : $(MLC_SRC) + + DB_CFLAGS += -Idbug/malloc + .END + + SRC += $(DBUG_SRC) $(MLC_SRC) $(GETWD_SRC) + HDR += db.h + + LDFLAGS += $(DB_LDFLAGS) + LDLIBS += $(DB_LDLIBS) + + __.SILENT !:= $(.SILENT) + .SILENT !:= yes + TARGET := db$(TARGET) + OBJDIR := $(OBJDIR).dbg + .SILENT !:= $(__.SILENT) + + CFLAGS += $(DB_CFLAGS) + .KEEP_STATE := _dbstate.mk +.ELSE + CFLAGS += $(NDB_CFLAGS) + LDFLAGS += $(NDB_LDFLAGS) + LDLIBS += $(NDB_LDLIBS) +.END diff --git a/dmake/dbug/dbug/dbug.c b/dmake/dbug/dbug/dbug.c new file mode 100644 index 000000000000..c20db79315b6 --- /dev/null +++ b/dmake/dbug/dbug/dbug.c @@ -0,0 +1,1834 @@ +/****************************************************************************** + * * + * N O T I C E * + * * + * Copyright Abandoned, 1987, Fred Fish * + * * + * * + * This previously copyrighted work has been placed into the public * + * domain by the author and may be freely used for any purpose, * + * private or commercial. * + * * + * Because of the number of inquiries I was receiving about the use * + * of this product in commercially developed works I have decided to * + * simply make it public domain to further its unrestricted use. I * + * specifically would be most happy to see this material become a * + * part of the standard Unix distributions by AT&T and the Berkeley * + * Computer Science Research Group, and a standard part of the GNU * + * system from the Free Software Foundation. * + * * + * I would appreciate it, as a courtesy, if this notice is left in * + * all copies and derivative works. Thank you. * + * * + * The author makes no warranty of any kind with respect to this * + * product and explicitly disclaims any implied warranties of mer- * + * chantability or fitness for any particular purpose. * + * * + ****************************************************************************** + */ + + +/* + * FILE + * + * dbug.c runtime support routines for dbug package + * + * SCCS + * + * @(#)dbug.c 1.19 9/5/87 + * + * DESCRIPTION + * + * These are the runtime support routines for the dbug package. + * The dbug package has two main components; the user include + * file containing various macro definitions, and the runtime + * support routines which are called from the macro expansions. + * + * Externally visible functions in the runtime support module + * use the naming convention pattern "_db_xx...xx_", thus + * they are unlikely to collide with user defined function names. + * + * AUTHOR(S) + * + * Fred Fish (base code) + * (Currently at Motorola Computer Division, Tempe, Az.) + * hao!noao!mcdsun!fnf + * (602) 438-3614 + * + * Binayak Banerjee (profiling enhancements) + * seismo!bpa!sjuvax!bbanerje + */ + + +#include <stdio.h> +#ifdef amiga +#define AMIGA +#endif + +#ifdef AMIGA +#define HZ (50) /* Probably in some header somewhere */ +#endif + +/* + * Manifest constants that should not require any changes. + */ + +#define FALSE 0 /* Boolean FALSE */ +#define TRUE 1 /* Boolean TRUE */ +#define EOS '\000' /* End Of String marker */ + +/* + * Manifest constants which may be "tuned" if desired. + */ + +#define PRINTBUF 1024 /* Print buffer size */ +#define INDENT 4 /* Indentation per trace level */ +#define MAXDEPTH 200 /* Maximum trace depth default */ + +/* + * The following flags are used to determine which + * capabilities the user has enabled with the state + * push macro. + */ + +#define TRACE_ON 000001 /* Trace enabled */ +#define DEBUG_ON 000002 /* Debug enabled */ +#define FILE_ON 000004 /* File name print enabled */ +#define LINE_ON 000010 /* Line number print enabled */ +#define DEPTH_ON 000020 /* Function nest level print enabled */ +#define PROCESS_ON 000040 /* Process name print enabled */ +#define NUMBER_ON 000100 /* Number each line of output */ +#define PROFILE_ON 000200 /* Print out profiling code */ + +#define TRACING (stack -> flags & TRACE_ON) +#define DEBUGGING (stack -> flags & DEBUG_ON) +#define PROFILING (stack -> flags & PROFILE_ON) +#define STREQ(a,b) (strcmp(a,b) == 0) + +/* + * Typedefs to make things more obvious. + */ + +#define VOID void /* Can't use typedef for most compilers */ +typedef int BOOLEAN; + +/* + * Make it easy to change storage classes if necessary. + */ + +#define LOCAL static /* Names not needed by outside world */ +#define IMPORT extern /* Names defined externally */ +#define EXPORT /* Allocated here, available globally */ +#define AUTO auto /* Names to be allocated on stack */ +#define REGISTER register /* Names to be placed in registers */ + +/* + * The following define is for the variable arguments kluge, see + * the comments in _db_doprnt_(). + * + * Also note that the longer this list, the less prone to failing + * on long argument lists, but the more stuff that must be moved + * around for each call to the runtime support routines. The + * length may really be critical if the machine convention is + * to pass arguments in registers. + * + * Note that the default define allows up to 16 integral arguments, + * or 8 floating point arguments (doubles), on most machines. + * + * Someday this may be replaced with true varargs support, when + * ANSI C has had time to take root. + */ + +#define ARGLIST a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15 + +/* + * The default file for profiling. Could also add another flag + * (G?) which allowed the user to specify this. + */ + +#define PROF_FILE "dbugmon.out" + +/* + * Variables which are available externally but should only + * be accessed via the macro package facilities. + */ + +EXPORT FILE *_db_fp_ = stderr; /* Output stream, default stderr */ +EXPORT FILE *_db_pfp_ = (FILE *)0; /* Profile stream, 'dbugmon.out' */ +EXPORT char *_db_process_ = "dbug"; /* Pointer to process name; argv[0] */ +EXPORT BOOLEAN _db_on_ = FALSE; /* TRUE if debugging currently on */ +EXPORT BOOLEAN _db_pon_ = FALSE; /* TRUE if debugging currently on */ + +/* + * Externally supplied functions. + */ + +#ifdef unix /* Only needed for unix */ +IMPORT VOID perror (); /* Print system/library error */ +IMPORT int chown (); /* Change owner of a file */ +IMPORT int getgid (); /* Get real group id */ +IMPORT int getuid (); /* Get real user id */ +IMPORT int access (); /* Test file for access */ +#else +#if !(AMIGA || LATTICE || __TURBOC__) +LOCAL VOID perror (); /* Fake system/library error print routine */ +#endif +#endif + +# if BSD4_3 || sun +IMPORT int getrusage (); +#endif + +IMPORT int atoi (); /* Convert ascii to integer */ +IMPORT VOID exit (); /* Terminate execution */ +IMPORT int fclose (); /* Close a stream */ +IMPORT FILE *fopen (); /* Open a stream */ +#if !defined(__BORLANDC__) +IMPORT int fprintf (); /* Formatted print on file */ +#endif +IMPORT VOID free (); +IMPORT char *malloc (); /* Allocate memory */ +IMPORT int strcmp (); /* Compare strings */ +IMPORT char *strcpy (); /* Copy strings around */ +IMPORT int strlen (); /* Find length of string */ + +#ifndef fflush /* This is sometimes a macro */ +IMPORT int fflush (); /* Flush output for stream */ +#endif + + +/* + * The user may specify a list of functions to trace or + * debug. These lists are kept in a linear linked list, + * a very simple implementation. + */ + +struct link { + char *string; /* Pointer to link's contents */ + struct link *next_link; /* Pointer to the next link */ +}; + + +/* + * Debugging states can be pushed or popped off of a + * stack which is implemented as a linked list. Note + * that the head of the list is the current state and the + * stack is pushed by adding a new state to the head of the + * list or popped by removing the first link. + */ + +struct state { + int flags; /* Current state flags */ + int maxdepth; /* Current maximum trace depth */ + unsigned int delay; /* Delay after each output line */ + int level; /* Current function nesting level */ + FILE *out_file; /* Current output stream */ + FILE *prof_file; /* Current profiling stream */ + struct link *functions; /* List of functions */ + struct link *p_functions; /* List of profiled functions */ + struct link *keywords; /* List of debug keywords */ + struct link *processes; /* List of process names */ + struct state *next_state; /* Next state in the list */ +}; + +LOCAL struct state *stack = NULL; /* Linked list of stacked states */ + +/* + * Local variables not seen by user. + */ + +LOCAL int lineno = 0; /* Current debugger output line number */ +LOCAL char *func = "?func"; /* Name of current user function */ +LOCAL char *file = "?file"; /* Name of current user file */ +LOCAL BOOLEAN init_done = FALSE;/* Set to TRUE when initialization done */ + +/*#if unix || AMIGA || M_I86*/ +LOCAL int jmplevel; /* Remember nesting level at setjmp () */ +LOCAL char *jmpfunc; /* Remember current function for setjmp */ +LOCAL char *jmpfile; /* Remember current file for setjmp */ +/*#endif*/ + +LOCAL struct link *ListParse ();/* Parse a debug command string */ +LOCAL char *StrDup (); /* Make a fresh copy of a string */ +LOCAL VOID OpenFile (); /* Open debug output stream */ +LOCAL VOID OpenProfile (); /* Open profile output stream */ +LOCAL VOID CloseFile (); /* Close debug output stream */ +LOCAL VOID PushState (); /* Push current debug state */ +LOCAL VOID ChangeOwner (); /* Change file owner and group */ +LOCAL BOOLEAN DoTrace (); /* Test for tracing enabled */ +LOCAL BOOLEAN Writable (); /* Test to see if file is writable */ +LOCAL unsigned long Clock (); /* Return current user time (ms) */ +LOCAL char *DbugMalloc (); /* Allocate memory for runtime support */ +LOCAL char *BaseName (); /* Remove leading pathname components */ +LOCAL VOID DoPrefix (); /* Print debugger line prefix */ +LOCAL VOID FreeList (); /* Free memory from linked list */ +LOCAL VOID Indent (); /* Indent line to specified indent */ + + /* Supplied in Sys V runtime environ */ +LOCAL char *strtok (); /* Break string into tokens */ +LOCAL char *strrchr (); /* Find last occurance of char */ + +/* + * The following local variables are used to hold the state information + * between the call to _db_pargs_() and _db_doprnt_(), during + * expansion of the DBUG_PRINT macro. This is the only macro + * that currently uses these variables. The DBUG_PRINT macro + * and the new _db_doprnt_() routine replace the older DBUG_N macros + * and their corresponding runtime support routine _db_printf_(). + * + * These variables are currently used only by _db_pargs_() and + * _db_doprnt_(). + */ + +LOCAL int u_line = 0; /* User source code line number */ +LOCAL char *u_keyword = "?"; /* Keyword for current macro */ + +/* + * Miscellaneous printf format strings. + */ + +#define ERR_MISSING_RETURN "%s: missing DBUG_RETURN or DBUG_VOID_RETURN macro in function \"%s\"\n" +#define ERR_OPEN "%s: can't open debug output stream \"%s\": " +#define ERR_CLOSE "%s: can't close debug file: " +#define ERR_ABORT "%s: debugger aborting because %s\n" +#define ERR_CHOWN "%s: can't change owner/group of \"%s\": " +#define ERR_PRINTF "%s: obsolete object file for '%s', please recompile!\n" + +/* + * Macros and defines for testing file accessibility under UNIX. + */ + +#ifdef unix +# define A_EXISTS 00 /* Test for file existance */ +# define A_EXECUTE 01 /* Test for execute permission */ +# define A_WRITE 02 /* Test for write access */ +# define A_READ 03 /* Test for read access */ +# define EXISTS(pathname) (access (pathname, A_EXISTS) == 0) +# define WRITABLE(pathname) (access (pathname, A_WRITE) == 0) +#else +# define EXISTS(pathname) (FALSE) /* Assume no existance */ +#endif + +/* + * Translate some calls among different systems. + */ + +#ifdef unix +# define XDelay sleep +IMPORT unsigned int sleep (); /* Pause for given number of seconds */ +#endif + +#ifdef AMIGA +IMPORT int XDelay (); /* Pause for given number of ticks */ +#endif + + +/* + * FUNCTION + * + * _db_push_ push current debugger state and set up new one + * + * SYNOPSIS + * + * VOID _db_push_ (control) + * char *control; + * + * DESCRIPTION + * + * Given pointer to a debug control string in "control", pushes + * the current debug state, parses the control string, and sets + * up a new debug state. + * + * The only attribute of the new state inherited from the previous + * state is the current function nesting level. This can be + * overridden by using the "r" flag in the control string. + * + * The debug control string is a sequence of colon separated fields + * as follows: + * + * <field_1>:<field_2>:...:<field_N> + * + * Each field consists of a mandatory flag character followed by + * an optional "," and comma separated list of modifiers: + * + * flag[,modifier,modifier,...,modifier] + * + * The currently recognized flag characters are: + * + * d Enable output from DBUG_<N> macros for + * for the current state. May be followed + * by a list of keywords which selects output + * only for the DBUG macros with that keyword. + * A null list of keywords implies output for + * all macros. + * + * D Delay after each debugger output line. + * The argument is the number of tenths of seconds + * to delay, subject to machine capabilities. + * I.E. -#D,20 is delay two seconds. + * + * f Limit debugging and/or tracing, and profiling to the + * list of named functions. Note that a null list will + * disable all functions. The appropriate "d" or "t" + * flags must still be given, this flag only limits their + * actions if they are enabled. + * + * F Identify the source file name for each + * line of debug or trace output. + * + * g Enable profiling. Create a file called 'dbugmon.out' + * containing information that can be used to profile + * the program. May be followed by a list of keywords + * that select profiling only for the functions in that + * list. A null list implies that all functions are + * considered. + * + * L Identify the source file line number for + * each line of debug or trace output. + * + * n Print the current function nesting depth for + * each line of debug or trace output. + * + * N Number each line of dbug output. + * + * p Limit debugger actions to specified processes. + * A process must be identified with the + * DBUG_PROCESS macro and match one in the list + * for debugger actions to occur. + * + * P Print the current process name for each + * line of debug or trace output. + * + * r When pushing a new state, do not inherit + * the previous state's function nesting level. + * Useful when the output is to start at the + * left margin. + * + * t Enable function call/exit trace lines. + * May be followed by a list (containing only + * one modifier) giving a numeric maximum + * trace level, beyond which no output will + * occur for either debugging or tracing + * macros. The default is a compile time + * option. + * + * Some examples of debug control strings which might appear + * on a shell command line (the "-#" is typically used to + * introduce a control string to an application program) are: + * + * -#d:t + * -#d:f,main,subr1:F:L:t,20 + * -#d,input,output,files:n + * + * For convenience, any leading "-#" is stripped off. + * + */ + + +VOID _db_push_ (control) +char *control; +{ + REGISTER char *scan; + REGISTER struct link *temp; + + if (control && *control == '-') { + if (*++control == '#') { + control++; + } + } + control = StrDup (control); + PushState (); + scan = strtok (control, ":"); + for (; scan != NULL; scan = strtok ((char *)NULL, ":")) { + switch (*scan++) { + case 'd': + _db_on_ = TRUE; + stack -> flags |= DEBUG_ON; + if (*scan++ == ',') { + stack -> keywords = ListParse (scan); + } + break; + case 'D': + stack -> delay = 0; + if (*scan++ == ',') { + temp = ListParse (scan); + stack -> delay = DelayArg (atoi (temp -> string)); + FreeList (temp); + } + break; + case 'f': + if (*scan++ == ',') { + stack -> functions = ListParse (scan); + } + break; + case 'F': + stack -> flags |= FILE_ON; + break; + case 'g': + _db_pon_ = TRUE; + OpenProfile(PROF_FILE); + stack -> flags |= PROFILE_ON; + if (*scan++ == ',') { + stack -> p_functions = ListParse (scan); + } + break; + case 'L': + stack -> flags |= LINE_ON; + break; + case 'n': + stack -> flags |= DEPTH_ON; + break; + case 'N': + stack -> flags |= NUMBER_ON; + break; + case 'o': + if (*scan++ == ',') { + temp = ListParse (scan); + OpenFile (temp -> string); + FreeList (temp); + } else { + OpenFile ("-"); + } + break; + case 'p': + if (*scan++ == ',') { + stack -> processes = ListParse (scan); + } + break; + case 'P': + stack -> flags |= PROCESS_ON; + break; + case 'r': + stack -> level = 0; + break; + case 't': + stack -> flags |= TRACE_ON; + if (*scan++ == ',') { + temp = ListParse (scan); + stack -> maxdepth = atoi (temp -> string); + FreeList (temp); + } + break; + } + } + free (control); +} + + + +/* + * FUNCTION + * + * _db_pop_ pop the debug stack + * + * DESCRIPTION + * + * Pops the debug stack, returning the debug state to its + * condition prior to the most recent _db_push_ invocation. + * Note that the pop will fail if it would remove the last + * valid state from the stack. This prevents user errors + * in the push/pop sequence from screwing up the debugger. + * Maybe there should be some kind of warning printed if the + * user tries to pop too many states. + * + */ + +VOID _db_pop_ () +{ + REGISTER struct state *discard; + + discard = stack; + if (discard != NULL && discard -> next_state != NULL) { + stack = discard -> next_state; + _db_fp_ = stack -> out_file; + _db_pfp_ = stack -> prof_file; + if (discard -> keywords != NULL) { + FreeList (discard -> keywords); + } + if (discard -> functions != NULL) { + FreeList (discard -> functions); + } + if (discard -> processes != NULL) { + FreeList (discard -> processes); + } + if (discard -> p_functions != NULL) { + FreeList (discard -> p_functions); + } + CloseFile (discard -> out_file); + CloseFile (discard -> prof_file); + free ((char *) discard); + } +} + + +/* + * FUNCTION + * + * _db_enter_ process entry point to user function + * + * SYNOPSIS + * + * VOID _db_enter_ (_func_, _file_, _line_, _sfunc_, _sfile_, _slevel_) + * char *_func_; points to current function name + * char *_file_; points to current file name + * int _line_; called from source line number + * char **_sfunc_; save previous _func_ + * char **_sfile_; save previous _file_ + * int *_slevel_; save previous nesting level + * + * DESCRIPTION + * + * Called at the beginning of each user function to tell + * the debugger that a new function has been entered. + * Note that the pointers to the previous user function + * name and previous user file name are stored on the + * caller's stack (this is why the ENTER macro must be + * the first "executable" code in a function, since it + * allocates these storage locations). The previous nesting + * level is also stored on the callers stack for internal + * self consistency checks. + * + * Also prints a trace line if tracing is enabled and + * increments the current function nesting depth. + * + * Note that this mechanism allows the debugger to know + * what the current user function is at all times, without + * maintaining an internal stack for the function names. + * + */ + +VOID _db_enter_ (_func_, _file_, _line_, _sfunc_, _sfile_, _slevel_) +char *_func_; +char *_file_; +int _line_; +char **_sfunc_; +char **_sfile_; +int *_slevel_; +{ + if (!init_done) { + _db_push_ (""); + } + *_sfunc_ = func; + *_sfile_ = file; + func = _func_; + file = BaseName (_file_); + stack -> level++; + *_slevel_ = stack -> level; + if (DoProfile ()) { + (VOID) fprintf (_db_pfp_, "%s\tE\t%ld\n",func, Clock()); + (VOID) fflush (_db_pfp_); + } + if (DoTrace ()) { + DoPrefix (_line_); + Indent (stack -> level); + (VOID) fprintf (_db_fp_, ">%s\n", func); + (VOID) fflush (_db_fp_); + (VOID) XDelay (stack -> delay); + } +} + + +/* + * FUNCTION + * + * _db_return_ process exit from user function + * + * SYNOPSIS + * + * VOID _db_return_ (_line_, _sfunc_, _sfile_, _slevel_) + * int _line_; current source line number + * char **_sfunc_; where previous _func_ is to be retrieved + * char **_sfile_; where previous _file_ is to be retrieved + * int *_slevel_; where previous level was stashed + * + * DESCRIPTION + * + * Called just before user function executes an explicit or implicit + * return. Prints a trace line if trace is enabled, decrements + * the current nesting level, and restores the current function and + * file names from the defunct function's stack. + * + */ + +VOID _db_return_ (_line_, _sfunc_, _sfile_, _slevel_) +int _line_; +char **_sfunc_; +char **_sfile_; +int *_slevel_; +{ + if (!init_done) { + _db_push_ (""); + } + if (stack -> level != *_slevel_ && (TRACING || DEBUGGING || PROFILING)) { + (VOID) fprintf (_db_fp_, ERR_MISSING_RETURN, _db_process_, func); + (VOID) XDelay (stack -> delay); + } else if (DoProfile ()) { + (VOID) fprintf (_db_pfp_, "%s\tX\t%ld\n", func, Clock()); + (VOID) XDelay (stack -> delay); + } else if (DoTrace ()) { + DoPrefix (_line_); + Indent (stack -> level); + (VOID) fprintf (_db_fp_, "<%s\n", func); + (VOID) XDelay (stack -> delay); + } + (VOID) fflush (_db_fp_); + stack -> level = *_slevel_ - 1; + func = *_sfunc_; + file = *_sfile_; +} + + +/* + * FUNCTION + * + * _db_pargs_ log arguments for subsequent use by _db_doprnt_() + * + * SYNOPSIS + * + * VOID _db_pargs_ (_line_, keyword) + * int _line_; + * char *keyword; + * + * DESCRIPTION + * + * The new universal printing macro DBUG_PRINT, which replaces + * all forms of the DBUG_N macros, needs two calls to runtime + * support routines. The first, this function, remembers arguments + * that are used by the subsequent call to _db_doprnt_(). +* + */ + +VOID _db_pargs_ (_line_, keyword) +int _line_; +char *keyword; +{ + u_line = _line_; + u_keyword = keyword; +} + + +/* + * FUNCTION + * + * _db_doprnt_ handle print of debug lines + * + * SYNOPSIS + * + * VOID _db_doprnt_ (format, ARGLIST) + * char *format; + * long ARGLIST; + * + * DESCRIPTION + * + * When invoked via one of the DBUG macros, tests the current keyword + * set by calling _db_pargs_() to see if that macro has been selected + * for processing via the debugger control string, and if so, handles + * printing of the arguments via the format string. The line number + * of the DBUG macro in the source is found in u_line. + * + * Note that the format string SHOULD NOT include a terminating + * newline, this is supplied automatically. + * + * NOTES + * + * This runtime support routine replaces the older _db_printf_() + * routine which is temporarily kept around for compatibility. + * + * The rather ugly argument declaration is to handle some + * magic with respect to the number of arguments passed + * via the DBUG macros. The current maximum is 3 arguments + * (not including the keyword and format strings). + * + * The new <varargs.h> facility is not yet common enough to + * convert to it quite yet... + * + */ + +/*VARARGS1*/ +VOID _db_doprnt_ (format, ARGLIST) +char *format; +long ARGLIST; +{ + if (_db_keyword_ (u_keyword)) { + DoPrefix (u_line); + if (TRACING) { + Indent (stack -> level + 1); + } else { + (VOID) fprintf (_db_fp_, "%s: ", func); + } + (VOID) fprintf (_db_fp_, "%s: ", u_keyword); + (VOID) fprintf (_db_fp_, format, ARGLIST); + (VOID) fprintf (_db_fp_, "\n"); + (VOID) fflush (_db_fp_); + (VOID) XDelay (stack -> delay); + } +} + +/* + * The following routine is kept around temporarily for compatibility + * with older objects that were compiled with the DBUG_N macro form + * of the print routine. It will print a warning message on first + * usage. It will go away in subsequent releases... + */ + +/*VARARGS3*/ +VOID _db_printf_ (_line_, keyword, format, ARGLIST) +int _line_; +char *keyword, *format; +long ARGLIST; +{ + static BOOLEAN firsttime = TRUE; + + if (firsttime) { + (VOID) fprintf (stderr, ERR_PRINTF, _db_process_, file); + firsttime = FALSE; + } + _db_pargs_ (_line_, keyword); + _db_doprnt_ (format, ARGLIST); +} + + +/* + * FUNCTION + * + * ListParse parse list of modifiers in debug control string + * + * SYNOPSIS + * + * LOCAL struct link *ListParse (ctlp) + * char *ctlp; + * + * DESCRIPTION + * + * Given pointer to a comma separated list of strings in "cltp", + * parses the list, building a list and returning a pointer to it. + * The original comma separated list is destroyed in the process of + * building the linked list, thus it had better be a duplicate + * if it is important. + * + * Note that since each link is added at the head of the list, + * the final list will be in "reverse order", which is not + * significant for our usage here. + * + */ + +LOCAL struct link *ListParse (ctlp) +char *ctlp; +{ + REGISTER char *start; + REGISTER struct link *new; + REGISTER struct link *head; + + head = NULL; + while (*ctlp != EOS) { + start = ctlp; + while (*ctlp != EOS && *ctlp != ',') { + ctlp++; + } + if (*ctlp == ',') { + *ctlp++ = EOS; + } + new = (struct link *) DbugMalloc (sizeof (struct link)); + new -> string = StrDup (start); + new -> next_link = head; + head = new; + } + return (head); +} + + +/* + * FUNCTION + * + * InList test a given string for member of a given list + * + * SYNOPSIS + * + * LOCAL BOOLEAN InList (linkp, cp) + * struct link *linkp; + * char *cp; + * + * DESCRIPTION + * + * Tests the string pointed to by "cp" to determine if it is in + * the list pointed to by "linkp". Linkp points to the first + * link in the list. If linkp is NULL then the string is treated + * as if it is in the list (I.E all strings are in the null list). + * This may seem rather strange at first but leads to the desired + * operation if no list is given. The net effect is that all + * strings will be accepted when there is no list, and when there + * is a list, only those strings in the list will be accepted. + * + */ + +LOCAL BOOLEAN InList (linkp, cp) +struct link *linkp; +char *cp; +{ + REGISTER struct link *scan; + REGISTER BOOLEAN accept; + + if (linkp == NULL) { + accept = TRUE; + } else { + accept = FALSE; + for (scan = linkp; scan != NULL; scan = scan -> next_link) { + if (STREQ (scan -> string, cp)) { + accept = TRUE; + break; + } + } + } + return (accept); +} + + +/* + * FUNCTION + * + * PushState push current state onto stack and set up new one + * + * SYNOPSIS + * + * LOCAL VOID PushState () + * + * DESCRIPTION + * + * Pushes the current state on the state stack, and initializes + * a new state. The only parameter inherited from the previous + * state is the function nesting level. This action can be + * inhibited if desired, via the "r" flag. + * + * The state stack is a linked list of states, with the new + * state added at the head. This allows the stack to grow + * to the limits of memory if necessary. + * + */ + +LOCAL VOID PushState () +{ + REGISTER struct state *new; + + new = (struct state *) DbugMalloc (sizeof (struct state)); + new -> flags = 0; + new -> delay = 0; + new -> maxdepth = MAXDEPTH; + if (stack != NULL) { + new -> level = stack -> level; + } else { + new -> level = 0; + } + new -> out_file = stderr; + new -> functions = NULL; + new -> p_functions = NULL; + new -> keywords = NULL; + new -> processes = NULL; + new -> next_state = stack; + stack = new; + init_done = TRUE; +} + + +/* + * FUNCTION + * + * DoTrace check to see if tracing is current enabled + * + * SYNOPSIS + * + * LOCAL BOOLEAN DoTrace () + * + * DESCRIPTION + * + * Checks to see if tracing is enabled based on whether the + * user has specified tracing, the maximum trace depth has + * not yet been reached, the current function is selected, + * and the current process is selected. Returns TRUE if + * tracing is enabled, FALSE otherwise. + * + */ + +LOCAL BOOLEAN DoTrace () +{ + REGISTER BOOLEAN trace; + + trace = FALSE; + if (TRACING) { + if (stack -> level <= stack -> maxdepth) { + if (InList (stack -> functions, func)) { + if (InList (stack -> processes, _db_process_)) { + trace = TRUE; + } + } + } + } + return (trace); +} + + +/* + * FUNCTION + * + * DoProfile check to see if profiling is current enabled + * + * SYNOPSIS + * + * LOCAL BOOLEAN DoProfile () + * + * DESCRIPTION + * + * Checks to see if profiling is enabled based on whether the + * user has specified profiling, the maximum trace depth has + * not yet been reached, the current function is selected, + * and the current process is selected. Returns TRUE if + * profiling is enabled, FALSE otherwise. + * + */ + +LOCAL BOOLEAN DoProfile () +{ + REGISTER BOOLEAN profile; + + profile = FALSE; + if (PROFILING) { + if (stack -> level <= stack -> maxdepth) { + if (InList (stack -> p_functions, func)) { + if (InList (stack -> processes, _db_process_)) { + profile = TRUE; + } + } + } + } + return (profile); +} + + +/* + * FUNCTION + * + * _db_keyword_ test keyword for member of keyword list + * + * SYNOPSIS + * + * BOOLEAN _db_keyword_ (keyword) + * char *keyword; + * + * DESCRIPTION + * + * Test a keyword to determine if it is in the currently active + * keyword list. As with the function list, a keyword is accepted + * if the list is null, otherwise it must match one of the list + * members. When debugging is not on, no keywords are accepted. + * After the maximum trace level is exceeded, no keywords are + * accepted (this behavior subject to change). Additionally, + * the current function and process must be accepted based on + * their respective lists. + * + * Returns TRUE if keyword accepted, FALSE otherwise. + * + */ + +BOOLEAN _db_keyword_ (keyword) +char *keyword; +{ + REGISTER BOOLEAN accept; + + if (!init_done) { + _db_push_ (""); + } + accept = FALSE; + if (DEBUGGING) { + if (stack -> level <= stack -> maxdepth) { + if (InList (stack -> functions, func)) { + if (InList (stack -> keywords, keyword)) { + if (InList (stack -> processes, _db_process_)) { + accept = TRUE; + } + } + } + } + } + return (accept); +} + + +/* + * FUNCTION + * + * Indent indent a line to the given indentation level + * + * SYNOPSIS + * + * LOCAL VOID Indent (indent) + * int indent; + * + * DESCRIPTION + * + * Indent a line to the given level. Note that this is + * a simple minded but portable implementation. + * There are better ways. + * + * Also, the indent must be scaled by the compile time option + * of character positions per nesting level. + * + */ + +LOCAL VOID Indent (indent) +int indent; +{ + REGISTER int count; + AUTO char buffer[PRINTBUF]; + + indent *= INDENT; + for (count = 0; (count < (indent - INDENT)) && (count < (PRINTBUF - 1)); count++) { + if ((count % INDENT) == 0) { + buffer[count] = '|'; + } else { + buffer[count] = ' '; + } + } + buffer[count] = EOS; + (VOID) fprintf (_db_fp_, buffer); + (VOID) fflush (_db_fp_); +} + + +/* + * FUNCTION + * + * FreeList free all memory associated with a linked list + * + * SYNOPSIS + * + * LOCAL VOID FreeList (linkp) + * struct link *linkp; + * + * DESCRIPTION + * + * Given pointer to the head of a linked list, frees all + * memory held by the list and the members of the list. + * + */ + +LOCAL VOID FreeList (linkp) +struct link *linkp; +{ + REGISTER struct link *old; + + while (linkp != NULL) { + old = linkp; + linkp = linkp -> next_link; + if (old -> string != NULL) { + free (old -> string); + } + free ((char *) old); + } +} + + +/* + * FUNCTION + * + * StrDup make a duplicate of a string in new memory + * + * SYNOPSIS + * + * LOCAL char *StrDup (string) + * char *string; + * + * DESCRIPTION + * + * Given pointer to a string, allocates sufficient memory to make + * a duplicate copy, and copies the string to the newly allocated + * memory. Failure to allocated sufficient memory is immediately + * fatal. + * + */ + + +LOCAL char *StrDup (string) +char *string; +{ + REGISTER char *new; + + new = DbugMalloc (strlen (string) + 1); + (VOID) strcpy (new, string); + return (new); +} + + +/* + * FUNCTION + * + * DoPrefix print debugger line prefix prior to indentation + * + * SYNOPSIS + * + * LOCAL VOID DoPrefix (_line_) + * int _line_; + * + * DESCRIPTION + * + * Print prefix common to all debugger output lines, prior to + * doing indentation if necessary. Print such information as + * current process name, current source file name and line number, + * and current function nesting depth. + * + */ + + +LOCAL VOID DoPrefix (_line_) +int _line_; +{ + lineno++; + if (stack -> flags & NUMBER_ON) { + (VOID) fprintf (_db_fp_, "%5d: ", lineno); + } + if (stack -> flags & PROCESS_ON) { + (VOID) fprintf (_db_fp_, "%s: ", _db_process_); + } + if (stack -> flags & FILE_ON) { + (VOID) fprintf (_db_fp_, "%14s: ", file); + } + if (stack -> flags & LINE_ON) { + (VOID) fprintf (_db_fp_, "%5d: ", _line_); + } + if (stack -> flags & DEPTH_ON) { + (VOID) fprintf (_db_fp_, "%4d: ", stack -> level); + } + (VOID) fflush (_db_fp_); +} + + +/* + * FUNCTION + * + * OpenFile open new output stream for debugger output + * + * SYNOPSIS + * + * LOCAL VOID OpenFile (name) + * char *name; + * + * DESCRIPTION + * + * Given name of a new file (or "-" for stdout) opens the file + * and sets the output stream to the new file. + * + */ + +LOCAL VOID OpenFile (name) +char *name; +{ + REGISTER FILE *fp; + REGISTER BOOLEAN newfile; + + if (name != NULL) { + if (strcmp (name, "-") == 0) { + _db_fp_ = stdout; + stack -> out_file = _db_fp_; + } else { + if (!Writable (name)) { + (VOID) fprintf (_db_fp_, ERR_OPEN, _db_process_, name); + perror (""); + (VOID) fflush (_db_fp_); + (VOID) XDelay (stack -> delay); + } else { + if (EXISTS (name)) { + newfile = FALSE; + } else { + newfile = TRUE; + } + fp = fopen (name, "a"); + if (fp == NULL) { + (VOID) fprintf (_db_fp_, ERR_OPEN, _db_process_, name); + perror (""); + (VOID) fflush (_db_fp_); + (VOID) XDelay (stack -> delay); + } else { + _db_fp_ = fp; + stack -> out_file = fp; + if (newfile) { + ChangeOwner (name); + } + } + } + } + } +} + + +/* + * FUNCTION + * + * OpenProfile open new output stream for profiler output + * + * SYNOPSIS + * + * LOCAL VOID OpenProfile (name) + * char *name; + * + * DESCRIPTION + * + * Given name of a new file, opens the file + * and sets the profiler output stream to the new file. + * + * It is currently unclear whether the prefered behavior is + * to truncate any existing file, or simply append to it. + * The latter behavior would be desirable for collecting + * accumulated runtime history over a number of separate + * runs. It might take some changes to the analyzer program + * though, and the notes that Binayak sent with the profiling + * diffs indicated that append was the normal mode, but this + * does not appear to agree with the actual code. I haven't + * investigated at this time [fnf; 24-Jul-87]. + */ + +LOCAL VOID OpenProfile (name) +char *name; +{ + REGISTER FILE *fp; + REGISTER BOOLEAN newfile; + + if (name != NULL) { + if (!Writable (name)) { + (VOID) fprintf (_db_fp_, ERR_OPEN, _db_process_, name); + perror (""); + (VOID) fflush (_db_fp_); + (VOID) XDelay (stack -> delay); + } else { + if (EXISTS (name)) { + newfile = FALSE; + } else { + newfile = TRUE; + } + fp = fopen (name, "w"); + if (fp == NULL) { + (VOID) fprintf (_db_fp_, ERR_OPEN, _db_process_, name); + perror (""); + (VOID) fflush (_db_fp_); + (VOID) XDelay (stack -> delay); + } else { + _db_pfp_ = fp; + stack -> prof_file = fp; + if (newfile) { + ChangeOwner (name); + } + } + } + } +} + + +/* + * FUNCTION + * + * CloseFile close the debug output stream + * + * SYNOPSIS + * + * LOCAL VOID CloseFile (fp) + * FILE *fp; + * + * DESCRIPTION + * + * Closes the debug output stream unless it is standard output + * or standard error. + * + */ + +LOCAL VOID CloseFile (fp) +FILE *fp; +{ + if (fp != stderr && fp != stdout) { + if (fclose (fp) == EOF) { + (VOID) fprintf (stderr, ERR_CLOSE, _db_process_); + perror (""); + (VOID) fflush (stderr); + (VOID) XDelay (stack -> delay); + } + } +} + + +/* + * FUNCTION + * + * DbugExit print error message and exit + * + * SYNOPSIS + * + * LOCAL VOID DbugExit (why) + * char *why; + * + * DESCRIPTION + * + * Prints error message using current process name, the reason for + * aborting (typically out of memory), and exits with status 1. + * This should probably be changed to use a status code + * defined in the user's debugger include file. + * + */ + +LOCAL VOID DbugExit (why) +char *why; +{ + (VOID) fprintf (stderr, ERR_ABORT, _db_process_, why); + (VOID) fflush (stderr); + (VOID) XDelay (stack -> delay); + exit (1); +} + + +/* + * FUNCTION + * + * DbugMalloc allocate memory for debugger runtime support + * + * SYNOPSIS + * + * LOCAL char *DbugMalloc (size) + * int size; + * + * DESCRIPTION + * + * Allocate more memory for debugger runtime support functions. + * Failure to to allocate the requested number of bytes is + * immediately fatal to the current process. This may be + * rather unfriendly behavior. It might be better to simply + * print a warning message, freeze the current debugger state, + * and continue execution. + * + */ + +LOCAL char *DbugMalloc (size) +int size; +{ + register char *new; + + new = malloc ( size ); + if (new == NULL) { + DbugExit ("out of memory"); + } + return (new); +} + + +/* + * This function may be eliminated when strtok is available + * in the runtime environment (missing from BSD4.1). + */ + +LOCAL char *strtok (s1, s2) +char *s1, *s2; +{ + static char *end = NULL; + REGISTER char *rtnval; + + rtnval = NULL; + if (s2 != NULL) { + if (s1 != NULL) { + end = s1; + rtnval = strtok ((char *) NULL, s2); + } else if (end != NULL) { + if (*end != EOS) { + rtnval = end; + while (*end != *s2 && *end != EOS) {end++;} + if (*end != EOS) { + *end++ = EOS; + } + } + } + } + return (rtnval); +} + + +/* + * FUNCTION + * + * BaseName strip leading pathname components from name + * + * SYNOPSIS + * + * LOCAL char *BaseName (pathname) + * char *pathname; + * + * DESCRIPTION + * + * Given pointer to a complete pathname, locates the base file + * name at the end of the pathname and returns a pointer to + * it. + * + */ + +LOCAL char *BaseName (pathname) +char *pathname; +{ + register char *base; + + base = strrchr (pathname, '/'); + if (base++ == NULL) { + base = pathname; + } + return (base); +} + + +/* + * FUNCTION + * + * Writable test to see if a pathname is writable/creatable + * + * SYNOPSIS + * + * LOCAL BOOLEAN Writable (pathname) + * char *pathname; + * + * DESCRIPTION + * + * Because the debugger might be linked in with a program that + * runs with the set-uid-bit (suid) set, we have to be careful + * about opening a user named file for debug output. This consists + * of checking the file for write access with the real user id, + * or checking the directory where the file will be created. + * + * Returns TRUE if the user would normally be allowed write or + * create access to the named file. Returns FALSE otherwise. + * + */ + +LOCAL BOOLEAN Writable (pathname) +char *pathname; +{ + REGISTER BOOLEAN granted; +#ifdef unix + REGISTER char *lastslash; +#endif + +#ifndef unix + granted = TRUE; +#else + granted = FALSE; + if (EXISTS (pathname)) { + if (WRITABLE (pathname)) { + granted = TRUE; + } + } else { + lastslash = strrchr (pathname, '/'); + if (lastslash != NULL) { + *lastslash = EOS; + } else { + pathname = "."; + } + if (WRITABLE (pathname)) { + granted = TRUE; + } + if (lastslash != NULL) { + *lastslash = '/'; + } + } +#endif + return (granted); +} + + +/* + * This function may be eliminated when strrchr is available + * in the runtime environment (missing from BSD4.1). + * Alternately, you can use rindex() on BSD systems. + */ + +LOCAL char *strrchr (s, c) +char *s; +char c; +{ + REGISTER char *scan; + + for (scan = s; *scan != EOS; scan++) {;} + while (scan > s && *--scan != c) {;} + if (*scan != c) { + scan = NULL; + } + return (scan); +} + + +/* + * FUNCTION + * + * ChangeOwner change owner to real user for suid programs + * + * SYNOPSIS + * + * LOCAL VOID ChangeOwner (pathname) + * + * DESCRIPTION + * + * For unix systems, change the owner of the newly created debug + * file to the real owner. This is strictly for the benefit of + * programs that are running with the set-user-id bit set. + * + * Note that at this point, the fact that pathname represents + * a newly created file has already been established. If the + * program that the debugger is linked to is not running with + * the suid bit set, then this operation is redundant (but + * harmless). + * + */ + +LOCAL VOID ChangeOwner (pathname) +char *pathname; +{ +#ifdef unix + if (chown (pathname, getuid (), getgid ()) == -1) { + (VOID) fprintf (stderr, ERR_CHOWN, _db_process_, pathname); + perror (""); + (VOID) fflush (stderr); + (VOID) XDelay (stack -> delay); + } +#endif +} + + +/* + * FUNCTION + * + * _db_setjmp_ save debugger environment + * + * SYNOPSIS + * + * VOID _db_setjmp_ () + * + * DESCRIPTION + * + * Invoked as part of the user's DBUG_SETJMP macro to save + * the debugger environment in parallel with saving the user's + * environment. + * + */ + +VOID _db_setjmp_ () +{ + jmplevel = stack -> level; + jmpfunc = func; + jmpfile = file; +} + + +/* + * FUNCTION + * + * _db_longjmp_ restore previously saved debugger environment + * + * SYNOPSIS + * + * VOID _db_longjmp_ () + * + * DESCRIPTION + * + * Invoked as part of the user's DBUG_LONGJMP macro to restore + * the debugger environment in parallel with restoring the user's + * previously saved environment. + * + */ + +VOID _db_longjmp_ () +{ + stack -> level = jmplevel; + if (jmpfunc) { + func = jmpfunc; + } + if (jmpfile) { + file = jmpfile; + } +} + + +/* + * FUNCTION + * + * DelayArg convert D flag argument to appropriate value + * + * SYNOPSIS + * + * LOCAL int DelayArg (value) + * int value; + * + * DESCRIPTION + * + * Converts delay argument, given in tenths of a second, to the + * appropriate numerical argument used by the system to delay + * that that many tenths of a second. For example, on the + * AMIGA, there is a system call "Delay()" which takes an + * argument in ticks (50 per second). On unix, the sleep + * command takes seconds. Thus a value of "10", for one + * second of delay, gets converted to 50 on the amiga, and 1 + * on unix. Other systems will need to use a timing loop. + * + */ + +LOCAL int DelayArg (value) +int value; +{ + int delayarg = 0; + +#ifdef unix + delayarg = value / 10; /* Delay is in seconds for sleep () */ +#endif +#ifdef AMIGA + delayarg = (HZ * value) / 10; /* Delay in ticks for XDelay () */ +#endif + return (delayarg); +} + + +/* + * A dummy delay stub for systems that do not support delays. + * With a little work, this can be turned into a timing loop. + */ + +#ifndef unix +#ifndef AMIGA +XDelay () +{ +} +#endif +#endif + + +/* + * FUNCTION + * + * perror perror simulation for systems that don't have it + * + * SYNOPSIS + * + * LOCAL VOID perror (s) + * char *s; + * + * DESCRIPTION + * + * Perror produces a message on the standard error stream which + * provides more information about the library or system error + * just encountered. The argument string s is printed, followed + * by a ':', a blank, and then a message and a newline. + * + * An undocumented feature of the unix perror is that if the string + * 's' is a null string (NOT a NULL pointer!), then the ':' and + * blank are not printed. + * + * This version just complains about an "unknown system error". + * + */ + +#if !unix && !(AMIGA || LATTICE || __TURBOC__ ) +LOCAL VOID perror (s) +#if __STDC__ +const char *s; +#else +char *s; +#endif +{ + if (s && *s != EOS) { + (VOID) fprintf (stderr, "%s: ", s); + } + (VOID) fprintf (stderr, "<unknown system error>\n"); +} +#endif /* !unix && !(AMIGA && LATTICE) */ + +/* + * Here we need the definitions of the clock routine. Add your + * own for whatever system that you have. + */ + +#if unix + +# include <sys/param.h> +# if !defined(Solaris) && (BSD4_3 || sun) + +/* + * Definition of the Clock() routine for 4.3 BSD. + */ + +#include <sys/time.h> +#include <sys/resource.h> + + +/* + * Returns the user time in milliseconds used by this process so + * far. + */ + +LOCAL unsigned long Clock () +{ + struct rusage ru; + + (VOID) getrusage (RUSAGE_SELF, &ru); + return ((ru.ru_utime.tv_sec * 1000) + (ru.ru_utime.tv_usec / 1000)); +} + +#else + +LOCAL unsigned long Clock () +{ + return (0); +} + +# endif + +#else + +#if AMIGA + +struct DateStamp { /* Yes, this is a hack, but doing it right */ + long ds_Days; /* is incredibly ugly without splitting this */ + long ds_Minute; /* off into a separate file */ + long ds_Tick; +}; + +static int first_clock = TRUE; +static struct DateStamp begin; +static struct DateStamp elapsed; + +LOCAL unsigned long Clock () +{ + register struct DateStamp *now; + register unsigned long millisec = 0; + extern VOID *AllocMem (); + + now = (struct DateStamp *) AllocMem ((long) sizeof (struct DateStamp), 0L); + if (now != NULL) { + if (first_clock == TRUE) { + first_clock = FALSE; + (VOID) DateStamp (now); + begin = *now; + } + (VOID) DateStamp (now); + millisec = 24 * 3600 * (1000 / HZ) * (now -> ds_Days - begin.ds_Days); + millisec += 60 * (1000 / HZ) * (now -> ds_Minute - begin.ds_Minute); + millisec += (1000 / HZ) * (now -> ds_Tick - begin.ds_Tick); + (VOID) FreeMem (now, (long) sizeof (struct DateStamp)); + } + return (millisec); +} + +#else + +LOCAL unsigned long Clock () +{ + return (0); +} + +#endif /* AMIGA */ + +#endif /* unix */ + +#ifdef AMIGA +XDelay(x) +int x; +{ + if (x) Delay(x); /* fix Delay bug in AmigaDOS */ +} +#endif + diff --git a/dmake/dbug/dbug/dbug.h b/dmake/dbug/dbug/dbug.h new file mode 100644 index 000000000000..0f171e0d349f --- /dev/null +++ b/dmake/dbug/dbug/dbug.h @@ -0,0 +1,164 @@ +/****************************************************************************** + * * + * N O T I C E * + * * + * Copyright Abandoned, 1987, Fred Fish * + * * + * * + * This previously copyrighted work has been placed into the public * + * domain by the author and may be freely used for any purpose, * + * private or commercial. * + * * + * Because of the number of inquiries I was receiving about the use * + * of this product in commercially developed works I have decided to * + * simply make it public domain to further its unrestricted use. I * + * specifically would be most happy to see this material become a * + * part of the standard Unix distributions by AT&T and the Berkeley * + * Computer Science Research Group, and a standard part of the GNU * + * system from the Free Software Foundation. * + * * + * I would appreciate it, as a courtesy, if this notice is left in * + * all copies and derivative works. Thank you. * + * * + * The author makes no warranty of any kind with respect to this * + * product and explicitly disclaims any implied warranties of mer- * + * chantability or fitness for any particular purpose. * + * * + ****************************************************************************** + */ + + +/* + * FILE + * + * dbug.h user include file for programs using the dbug package + * + * SYNOPSIS + * + * #include <local/dbug.h> + * + * SCCS ID + * + * @(#)dbug.h 1.11 9/5/87 + * + * DESCRIPTION + * + * Programs which use the dbug package must include this file. + * It contains the appropriate macros to call support routines + * in the dbug runtime library. + * + * To disable compilation of the macro expansions define the + * preprocessor symbol "DBUG_OFF". This will result in null + * macros expansions so that the resulting code will be smaller + * and faster. (The difference may be smaller than you think + * so this step is recommended only when absolutely necessary). + * In general, tradeoffs between space and efficiency are + * decided in favor of efficiency since space is seldom a + * problem on the new machines). + * + * All externally visible symbol names follow the pattern + * "_db_xxx..xx_" to minimize the possibility of a dbug package + * symbol colliding with a user defined symbol. + * + * The DBUG_<N> style macros are obsolete and should not be used + * in new code. Macros to map them to instances of DBUG_PRINT + * are provided for compatibility with older code. They may go + * away completely in subsequent releases. + * + * AUTHOR + * + * Fred Fish + * (Currently employed by Motorola Computer Division, Tempe, Az.) + * hao!noao!mcdsun!fnf + * (602) 438-3614 + * + */ + + +/* + * Internally used dbug variables which must be global. + */ + +#ifndef DBUG_OFF + extern int _db_on_; /* TRUE if debug currently enabled */ + extern FILE *_db_fp_; /* Current debug output stream */ + extern char *_db_process_; /* Name of current process */ + extern int _db_keyword_ (); /* Accept/reject keyword */ + extern void _db_push_ (); /* Push state, set up new state */ + extern void _db_pop_ (); /* Pop previous debug state */ + extern void _db_enter_ (); /* New user function entered */ + extern void _db_return_ (); /* User function return */ + extern void _db_pargs_ (); /* Remember args for line */ + extern void _db_doprnt_ (); /* Print debug output */ + extern void _db_setjmp_ (); /* Save debugger environment */ + extern void _db_longjmp_ (); /* Restore debugger environment */ +# endif + + +/* + * These macros provide a user interface into functions in the + * dbug runtime support library. They isolate users from changes + * in the MACROS and/or runtime support. + * + * The symbols "__LINE__" and "__FILE__" are expanded by the + * preprocessor to the current source file line number and file + * name respectively. + * + * WARNING --- Because the DBUG_ENTER macro allocates space on + * the user function's stack, it must precede any executable + * statements in the user function. + * + */ + +# ifdef DBUG_OFF +# define DBUG_ENTER(a1) +# define DBUG_MALLOC(a1) +# define DBUG_RETURN(a1) return(a1) +# define DBUG_VOID_RETURN return +# define DBUG_EXECUTE(keyword,a1) +# define DBUG_PRINT(keyword,arglist) +# define DBUG_2(keyword,format) /* Obsolete */ +# define DBUG_3(keyword,format,a1) /* Obsolete */ +# define DBUG_4(keyword,format,a1,a2) /* Obsolete */ +# define DBUG_5(keyword,format,a1,a2,a3) /* Obsolete */ +# define DBUG_PUSH(a1) +# define DBUG_POP() +# define DBUG_PROCESS(a1) +# define DBUG_FILE (stderr) +# define DBUG_SETJMP setjmp +# define DBUG_LONGJMP longjmp +# else +# define DBUG_ENTER(a) \ + auto char *_db_func_, *_db_file_; \ + int _db_level_; \ + _db_enter_ (a,__FILE__,__LINE__,&_db_func_,&_db_file_,&_db_level_) +# define DBUG_MALLOC(a) \ + auto char *_db_func_, *_db_file_; \ + int _db_level_; \ + malloc_init();\ + _db_enter_ (a,__FILE__,__LINE__,&_db_func_,&_db_file_,&_db_level_) +# define DBUG_LEAVE \ + (_db_return_ (__LINE__, &_db_func_, &_db_file_, &_db_level_)) +# define DBUG_RETURN(a1) return (DBUG_LEAVE, (a1)) +/* define DBUG_RETURN(a1) {DBUG_LEAVE; return(a1);} Alternate form */ +# define DBUG_VOID_RETURN DBUG_LEAVE; return +# define DBUG_EXECUTE(keyword,a1) \ + {if (_db_on_) {if (_db_keyword_ (keyword)) { a1 }}} +# define DBUG_PRINT(keyword,arglist) \ + {if (_db_on_) {_db_pargs_(__LINE__,keyword); _db_doprnt_ arglist;}} +# define DBUG_2(keyword,format) \ + DBUG_PRINT(keyword,(format)) /* Obsolete */ +# define DBUG_3(keyword,format,a1) \ + DBUG_PRINT(keyword,(format,a1)) /* Obsolete */ +# define DBUG_4(keyword,format,a1,a2) \ + DBUG_PRINT(keyword,(format,a1,a2)) /* Obsolete */ +# define DBUG_5(keyword,format,a1,a2,a3) \ + DBUG_PRINT(keyword,(format,a1,a2,a3)) /* Obsolete */ +# define DBUG_PUSH(a1) _db_push_ (a1) +# define DBUG_POP() _db_pop_ () +# define DBUG_PROCESS(a1) (_db_process_ = a1) +# define DBUG_FILE (_db_fp_) +# define DBUG_SETJMP(a1) (_db_setjmp_ (), setjmp (a1)) +# define DBUG_LONGJMP(a1,a2) (_db_longjmp_ (), longjmp (a1, a2)) +# endif + diff --git a/dmake/dbug/dbug/dbug.uue b/dmake/dbug/dbug/dbug.uue new file mode 100644 index 000000000000..da8743b7e128 --- /dev/null +++ b/dmake/dbug/dbug/dbug.uue @@ -0,0 +1,368 @@ +begin 650 dbug.Z +M'YV,"@*"&$BPH,&#" T2 2$$1!401P0FG&AP" @H<MZ<D1.F#0@B9<34.7,F +MC9LS%\.,61/F3!F)%&/*!"$F#\R9. <:D5.&# @C:>:@"4@481($1Y,Z0;"T +M*14$3Z-*03"UZA,$5[,20;"U:Q4$7\,.03"V;%2H4),B19H5*]:F3)D6C1F$ +M39LW<^B *&.GC)P\(.!DW-@1!!F^9=B\@=.FC!N]CNVDR>BF\6,0=][(H8,& +M,(@W9A0@Y%QFH)N.I06_D7QX#H@Y;QJ_UJP7M.&0(TN>!&%&91HV:>CD<3&P +MRIPZ8=BPL3D:35 0=,*L*>.:]$ SFCU^-C,PS$#5A+7?<3X&S<#G(,:$@1-& +M#)O2VT4?'//F<4;E)E'NQ5-F3!TZ:=0WD&V?D29'8(-QU(9K8;CA4QEX=&12 +M?M"A\1)")M'AUVELO!:=AML5:.&!$/;W'X7@*3@'<2!08>$<I0D'!W4#AH90 +MBAVY=L=O'8I1&D]F^,633W2\ 4(8KD&HH1P<WB8227ZY-H=)8\1HH7P&'?:D +M2P<^Y\8;>K&W68C6E>@?@+OAV :+1438!ASON19?<^C)"!^!6N;FUWENC,%& +M'8<-9%T8"!!J*!D((*JH& @PZNB1#KZ&P!R33JIHHHDZVFBC3NHIQQQ8%J0: +M:SUA%IQYUH4%%EAP-:564E@@$.NL&^ 0 P*WYKI!#I_-R!&:*,V11UYEK#D7 +M14^X49IMUJGF7K$,S@';&&F$H:%/.W)V6U^*P8%B@CF&2I!)W;DQ4&23U6>9 +M7J9J"\(9;[SATWY+-MDIE)^"\!QGUHH[T&'<+E:JFG)J&"ET1H* 1AA]#00< +M'72\-^"!('S)9[W)^:NO&WG)4<>ZU@;H!HLM.B<G>G4<E]QRIH'9'8)O/.L1 +M=@>2IC' B0E\X)1]EF:AOG.P\-F!UCI<!I+L"O5&'6S,ZZ/0&P/8AK6),7=0 +M;VW\5BW%V9I7(7P9;IC<T&<TF(8>(=<G-!G6>M=Q'6/040=/06O<H$_TV?=& +MAV8H=@>9/ZM)4QD4WNL2&20GP2YZ86@,HQP!IDR0L^]IQYMF TT=]FD]?P=N +M&XU]"O5X"8?!D\9UN '<="P7J3##I1U7'F\2 F=Z<)YU+>C/,(<WD(_Y::SY +M8V&8U!/4=Y&1AAEI'#]T8+25ZGJ#8(ZXEQN24;8NBXIK_%QRL!T)L\Q"(V8N +MS5]OF[.O0H_G6/J]*^B]G'?U-:_KD%Z?O;J.Z:6[=X))0]8 U##,I0YK6C/= +MS7"#+Z%ASGP5,U*>\.6"8TTD6>FKWIX6YB"A?2%1'Q3#!^OP091\SUP0Z@B< +M[L2=_$5-;&Q8X);\PB(A]"<,*2M-<$# DSC483(T"AN3QF:2MX$,0 *R3>-N +M]#FAW4U?=)!3REH"'S*\@4819-=A9G0P 4'*,W.8$;4RAA#UL$<,6@,0%@ED +MG?V8"(GFTE^Z*M,_J.WP>VRX0QB&93<[%(\-[9'8$W>DG'/QYTQ@BV.#/(,N +M[?5O=T7[FL8$!T48L8$[A.R0F?ZCPY$-) GF"@,9E ='H?&L2E $VI$T1I\W +MO0=$@5$)2UPR$-V)[S5B7%X:QC"0'%),B+VI$M2.I)Q)?DY.F"&/UW)X'G9E +M\G?P&54:#C,O6TXI:X"4@PQS0R$SMB>-S5O10%STG'*:2RBF@T-ZZD,'CN0% +M80,RD 4)\H5ZVO.>-RE(#(A3!2<D 0NJ]$X[15DLTZTA1$&@@@FHP)#$=(@) +M[=&,M303S@H216,YD4D+0! #$+3@HA=%"!&$4(4C..1Q(&A"@Y#3H8S&Y EQ +MB]F>9) #H<4@!SBP04BOEAW7V$:(32IB.S_6O[29RWT\V8M*O(:S;NWI=:!J +M#N$H]H8[N$%H*6,IR^+D&F\^2V@T\\A/'P-#P]%08Z!\S<>F]A>A^4@]S/P@ +M&4(XPA(&U%Q '=L$N91*:;:&E?69$K'Z!!B59$1:O?)+R';32/X])FB0\LE; +M<0BC5 :ECW\,9(R,M#+U.35?._0K%O,F6(.-P3.&Q4M4#])9@FTL?7- C1P= +M^1B+8K0@+BJ-7.F* !(B "7L60D5]?4FO-"H/BQS&W#.@ :]A+$, W-,<H3S +M&3=H;)/ BE^.A":C7:X,,&V FWFX6J$&<10&@?%+E1[C1 ?9#03)HXYSSY8: +MZ;)!.%#KKGJ4XYD8H!>>()#!?WVU7CJ03 A6RU(9F.>&PKDME\SCI44$4P;5 +M5$E:F!-6&\2P-YI4#W#4*8UZK(L0'_&P)W"3GI'TX!<CZ<YBY6F02US3PQ\. +M25 ):R-LYE8EP![&MC+)[77VYK?" >>=JKRE#W=YT($<!W2F\TR(=G>A^:SG +MFP\+9XVH/)#=-JJNOXVE<%W"IJ6FY\IH?!A@1CPX[SDH#:S1*F"D^RR?8$YY +ML:WSD?1B':G!QSO:U<YE,82]-TQG7C21\G.I988\% Y^1X*#:@)(M8&T<FH' +M XZR[":',Q#UL1;-B9':]$:108<CJ'P-&JI:.#.D+FZF!L%[N&5I=M[GM@GI +M6U4+0JZ7.;E8:6@!8>! GN\2!-/*HA@(4A8\EYKD,,2#(SR?[5T0*2LO%-HB +M9T*-$R,]X3]P^$_Z_/BGXW)G90XDFAO 6 <QP(A=H(':=!*,D[QVR(^0T^R* +M\DD1(S%!@#L\$JP#BV-?+UJ7O/PUNZ9<,=20 =<(<76?X+AOB!?$WP#7B\0' +M;JZ!HG)ZN.R/+DMU[>QJ&PW<GHF_VY,8I<YN:70(MUXT71K=[5@.J&2>Q!HN +MF\A:W" TK]C'?"2'E,MDY3YJZ=%F]QEPBUO6QJOEJ4PCVRG[1PX\><S/1961 +M"U=<U!=)F7DP!X?%7*RLABM<7BH-X)55=>L$P:ZI=2>2W^B%7'O-]H)Q>-^O +M=QL$4N@)$./&Y7L-R.E):^?1M(._M3O(= ]W*<QE/A 4Y,6*_TG!Q'Q]FL;, +M2^=E8)&0#],;IM$![H>/N;@[MO@D.YYM<IB7D# ' LO3X3!83P')<HOZ$RN/ +M)QR';W\X&!2//*>5*]00RYY=8<= NS8VRNB7Y#"U#EWZB4$?TN"EW78[O&&: +MJ9=Y[_/6MUU&T;;S=*E& ^Q1D*;_(R0UJ7'VI%(WL%3]R(HIT0-<4X[B5*?O +M!P4((( $6!54016O@A1-@ +V( )F 1G$14/: 4(0($66 0(@($:^!%<T8%$ +MH($9F(%"@ C6(*J$A9'@ IN((KJ((J^("MPA0MN((M@A91 8(:6!9D019( +M@ ]^(,QZ$]KD111@ !%>(0G"!8XF(%3@ !-^(3O9Q"@A#$=(E0><T2FAD<\ +M(4J%13O8M#6UUC-P<'JC821W\4YJ$CJ0=4HZ='>ND57&9AW,\REZD7<GH3$: +M4AX-YD/P\1ZFHRR(@UMYX"W[M1S#) (!=!EKIR'K,@<B0!"F4V4&441^<2U\ +M EM+@W,B)B^E431")%\H\GV/Q5T_0Q^',3\GAGR_42I/A%W.$UF%1S>F5SB3 +M]W2#=A IE#6 ^%KF92V,.(;P=!A+HHLU-R)6DAH9(3- 8W0$(606AF))54Y+ +M$C)],3I3YW)>$QR*Q7V.EAC*<X<(<1=)!8OPI1EW@GA0\T0*(S"NQE^%=W.H +MQ"Q7PD0Q4SFJA&?TT1<WYB,T<XQ-IWIZ\5:Q02-%8B391$M%LD!CTRY>0WL4 +M)AE+,P<LLS&/8XD>0C6-:!K0121&XB,:PQ/UTQ,L A2>EE0==4+[H4(2(X_[ +M,H@LY#D9!V>26!!VB!)YB 9[6 >AMU,Y,0)4\B>!P@.7%R N@ 8^P&\Q,3RU +M9SIG, 9.U&EVD *]ER%'TFECL /CMS 'H@),:0=;T 58Z5)[T'M<ER'<@0(B +MT)5; -= (] (E0 9<X 8B\)1GX)5LF0)AB7\@\ (J0)8%H0(#$7CO9!MJ +M I@$H0(O@)@(8I:U)P(]\)96I"QNV0-S*0)ZV7M]$(5\B1 D.3>E$0.,61 8 +M$9,- Q);0B%4,'PY^1(@)1-%T!>/(6?I>#!PZ(Y'8@9+ HD+YX=(]AJ(P1$Q +MA"'32''YQ3N44RQ25TB#<SFIXQ-/1!]8UQ_7PB)!0(8'P1G/47890HJEH2QW +M,)&4N!FETIB7<9&,V#_TDS+LXI$(<1C3)77;1A#)LBQB )&2 QM_(FW[8B37 +M!"> <1BO=(QM8#?*44-EH!O)]H8JXXY65"'?PQME\#=^]H:/\1M?XQD+TQ=X +MF# \,2.15"87FE3/B%C!"1A^)C[@21,C 3UP\(9P4$$((60PDC<^<8:U<9^1 +M(R5[<R("TI^ST1BK]C>&$12:164:4XMT #6$8R"[DQ$CX34ZEHFH9(J;"#J/ +M%$QIE <LP$I;*&U*9'CX5BW/ D\F-@?94AZEDD0' AIFD&Z)ACH\HQ]M9!$( +M4F%=1QVP470$\9E))0-WE9*NM"SG5DS-P1,QPIIIP(<5AY2=>1 ;-0/MYWX: +M,U(E=5+TMU(+^:@% 5-%LG\T95/_YWXNY9-] I2E(92W1Y1&Z:@30943Y)8@ +M -8V7M*B0),Z915>9=2Z6R7D:M[F1,QMI5J"9:]-Y:=Z9?F20=GF990*:LE +M@ >7:9=1"0**R9C+4WL3I'F)R*R/J99L":UR29?4NI9=D)G)^I>/*IB )U\A +M<ICKNIBENCRD]Q%%$'^,V:W-&IF&41^E$9F7B:X9-0+.MSR:R9F<VJ=I4)*E +M(0.CJ1 ,]!%&6J:KJ8>+JI.@\IHQ401F=I.M"57-)">BY$?$,V/E,B]X-K(- +M$ATSIC&V1#=BQ"[X0P9YT'F[! )V("4?<K,J04!&94I4NHFGB!"KX1<6(DI" +M WRQX2V )&TU!D2-6#Y(0JB]!"-0 Z\'L85LDV:XPZ1T, 8D\P3ZR$Q3UD84 +M5J)[.AO[*3(:LV0KL55'0P;5823)N2 ,.1L\)K3PH;58ACLG*SS%0SPFT;?4 +ME4SO U^SN$(#,0((P+B.FP8( +F2:P8(0+F6>RF*4@8(H+F<:[F56[E.E@<; +MMC<B.XZNXYX'07K&8V<4\YP+MKJ_,[7SXD4'%V&"XI)R@B<,M$!3,B2B]S/P +MJ+=G9BXF-C6!(I$+VUPL(XX_$K>:I3$UH5;!<:3,%VVF)H^EX;B-V[B2&[F1 +MZ[F7BRF9N[GDNV"?:[F[^FE1!$]3\[6H,H\'4;T[ZT5L5(J<Z%;B]B5ZT5D3 +M]J%YBF'YXG9W@(<FLWN\@UR>\;0@^4B70S$Z%AV/%WO%L2IA$80/."NR(BL$ +M,03&A*=OX'68\QSH8QTG, (GD!Y:V;-[,CV2=C1=TG$_,X=Y 5A_T@97]3M/ +M!T$0*B<P BT.DP;3 8EQ5)5H-%!_(<21=Q"ILX6P<1IE>F(=8WXB0S)^"A^2 +MBI*YJ+@LN5H&,45D1JD:F[ )L5$T,*FD>A"6*G\H57_W)\8#X:DR=2"AZG\Y +M=<8]^9. DJI#^09%>92V&KA+:974VJL9197 FI6F8ZW%&JPX@:P#.RYF4*\? +MB*^=J:_?"I7F*J[3NJMX>:Z,/!,C$'=O%GWXYY>CR:Z$"7V!=LKR^LCG$<D+ +M9J^4S)>6C);\.IG_:IET*; ]*<K*0\HXL9FNZL95# (S\+!-8([M*DI'BA$> +M#,('8AQ4!,;47,UV[,8&L5$U8,9A7!!IC*D'PL:;*L9P#*K]=U-U_'Y&@ #K +MW,Y)V$]QT10Z:!8VF!9#R!9ND15!6(,1:(!5$00( - "/<]DL81% (&C<&S +M(M !'= -R( ,2( #.(!,@ 5?=$&C; #<04UQR,7.29N*FLNW&"[$5%/UT9> +M!4YK!,P$T49>)D*]95=B-DOP$;W+-J<O\Y\2HXO4%&C)M$M#449+RTG5$<,] +M2U%C$Z9"MV$T1!!I-32X5W"# S%^L4!WP3$#!4MMM''<YW&ET1@QUF!ST :D +MN)V? S3>,ZCK4BK -S=3PBW#H1,+"YH@4,;[\C-*R=6Q1C,$+,)'G6\=HB;H +M-Z^GFL<@H*K*P\>MZE+*.G\'XEI*PS0^P4P\H!C[]0)D\"1];*VM?,>%'2@B +MD-DC490B,,SA",BX*LB<3,@Y8<A6^<DR,:R*C,G&*I:,R1,E02POK!>R>%]" +MDP9X -LYH20;$C6T$U. 77LIX$1%D@;*7:N=F<9?4 1.0 5%( 6/.3R8*=PX +M(=U0( 5/, 1%, 53$,AW::Z\K'[H@P+ +:LQL /Z@@>'O:N\9 (FP,E; -Q= +MD,G\>@(M< +P#=PKL *:Y\B<BJ;!,3NI?=[ZO04Q<*X@8.!NK!Z55<(GH ,/ +M2Q'>7053@ 2U9P(+[I4-+@/GFM[8_#M;N ;<[5*;V9DMSI?K'>#RS0/T+>,# +M7N 9#G\E]07?G035?<EGX(A"@Y9J&9=M^98E(.3Q7:[ZG0(FSI>]K1=O&4Q% +MDMRXVMSF+>)X4.(KGE&U+ )QN<E1_N0Y\>+X)]U24 144 52X 2U!P-D3A'" +MG.,44<PT0.=&\-?5TB$8H1$*DE*!2W/7G!!"U@8(8.B(;BB%4BC=*[EN@ "/ +M'NF\\6K\*2<P&UAI\,3H S->YV#K!EA0=C!01YF]PGU,J;XB>S"D$4?(=R*[ +MX7-,E"$4(H=ZGM3<L73F\25NT *+(6VGOCT\>>($L5$VP,W!3A#?[-B ;G_C +MG+#E/%/G/*H:_1.349B%R@9"H[^[9"5%TUG8:U8'HM>!Q6E@H];]4YZ2 6AG +M^[]I"U^I)4[C9#+]2B/ZNT >IW$9X1'6P;=<2UW?;J6P.#73X1HIZQ[-QEJ% +M%*NJV+2FUDYPMN=+^1KY(3'K_L%ZFF&BRV'87JD>R!4E2((D^,XSJ((?5/(( +M\ 5MD17MS,[LO/+M#%::<6'I,S5CD!'[P1X<(S)SVYSVIQRZ9]H@4!?AH^T? +M]S-X/"5)U$)M=+11S1NK^"_BFRF;XBAUT%M6/Q*_E?5GX ((P/5>CP8( /9B +MKS%FD._I8]ECP_1[ GI%"GQ5'M>U)V3ZB/1X]=D]H3'&J$I]YJYSGX5QU$:B +MK1_!^R]!X? B 4<WLWV:D0>ZUXSRSO9Y$QU%1$P=8AVJVV 4U\"2])X,Q%<T +M?UCMHTR4_SH-(X?9P8%=X?$@;X(4#!8C?P0F7_(*+2NSCP5>W_5=?_M>K_M= +M7_NU#V0Q(62IWQ4?S_HG^/JQ?_(&'801"!4&[<]4X>XU;R0F$59%731[M<(+ +MXS\^ SO7158WEC[B;BZ=5RJ(?NB'KNB&TNB1&^F0#NG<HQ?A]4XF9AWZ"!@R +MC)T&(0+8I5F/&'3DXAWC[T2ZN2>==1A^8CI&E>I);!#\J,R+)")[TO]E2G._ +M6QK#K_K%+_(NN(+)S^,378 ':!7YC!4$+=XAJ(%/Z(1.^(1.Z(32;_.W:! N +MD6S&ED-VICJ 41^HY"L^[3K5?_J W_E5C1#C433EGSZ"HT>N81+>=V@,^;NE +M,?RJ7_PB[X(KF/P\/M$$^,Y/Z(1.^(,^Z(/2GQ'"(R\C5]0B-C=95X>=OR>+ +M6!K1&UN2\>IFRQ/XR<4%L8A_=C#OEETJ.J'H61IB(+O5E3Z1?Q\> CG@>!#L +M(2VLZ!K!P2"=IKZ_6QK#K_K%+_(NN(+)S^,378 '6!4P&,],T?P,)?TVGV0Y +M=#]O8$Q4"3_DAK$A@NOINRZ:/QY +3Y4CM15R,4%<;I7*G,B&>^E,?RJ7_PB +M[X(KF/Q? /UI'H(:V/QKWOIL?H!5L<^?GV,.53"\D_W:U!PARCO.MV76<759 +MIW&4;FH+XQH^\CY;J*;0Z5X(P1-RPR0,@K/)H9, AM(KTVJ4/L4$41<M5;\A +M!KC3KR,>;6+MR#(0 B>!6RKD<ASN5@9\J(C4J?/,.*-&PDR6W_E^X9W'7>40 +M3TGH81+>=V@N.W7><7V1$G3?'E883N=4CM0=T@(C0 8ZH!<=!:C'K#%"!E_H +MG^B+OO[>Z^CO+^F3/G&QIK1GT& L5C"\(P(M, )DH -T\(@> CFOCB3=L4WX +M$H;MU&$> CDGT5X^P1[20I _D_U$TVFHKC%H208Z0 >8*=4N#4)?%M-AQD.I +MDZ)J)6FT,1!0BB98E.Y(*E(=/U*K'_*M7U(NN(+)S^,338#O_(1.Z(0_Z(,^ +M*/T9\;O;:3H XA_9Y"&0PUA.'"?_2'EE'QL$7!K#K_K%+_(NN(+)S^,378 ' +M6!4P&,],T?P,]?DN-G4D3 8GW#<M 8MT%B?70>EL.QJH5CBV1,)T<,)]TQ*_ +M6QI4CM1\0^E96-2.P4HK(SUH@*C0(4#4T3Y3-RB=ANH@( (Q4)<#(0(R4)<G +M.Q B, ,B(*,'X01@ A_\(K,_X]U2X.,,%1T#GY)QTSH(0 <(0 <(0 =W@ !W +M@ !W@ "9@0!O@ !O@ "<U6FHWCZG0L"QTQ_U 9V=IKX1'U9%$\4E'2E'!F\M +MU*W/BQ#DAK&:YQA^8EP^02YBTC\O$A3,*%(1&_GWX2&0<Q)=A>G6?DMJ+P?' +M"1\BT (C4)=D3V1559XV#6CTH1CG5&&F0S4^<62JG/U$TVFH+J,'P;&SD_U$ +MTVGJ&U 2?Q(2,ZPJ3#%]TQ)#IAQ5=?<E5ECFTNLB,S;7!YQB0C4^<62J_.OJ +M&7*,=K,)*57O(I/G TA;/Q!3,)""ND(,PA,8WLW"[E$@< /&_G[)OL::VE)N +M_.QR'.WI#/0XT0(C0 8Z0 <Z\ 9TW@(C0 8L8!(L ',Z\*;#HP-&H -,@)1. +M ";PP2_L\I [.I%T]AXHV_E/U;,Z;VGF!4V)GV?O(5DH:K]ZTR%1O!LBT (C +M( + 3Q&C][J8?[W<0>O(#?'C;TH9OS?T!9U<7! BX 0A4)>J5!*RF6@8GN-. +M$ *RZN:"Z00MT%&"Z0(N0!R *IBBJ3'%O,UW71I4CM0M-?ZU)/K$M4(9N<,& +M"B^0PQG:T=:?(I/+03). ";PP2]\)N]>XC+*XG6WLQP$7!H^\DYZA*()\Z#' +M7>5[GNJRAW6T9Z/!H?/=<3H8<@;35RK(-Z#+,=@#B\=!N<=]W'N-C5*0O6J2 +M?=.IBO9L@-F:;92<W7NFZB>&'=J:C0:E/9670>5(W2$H0&XZR=HX@=N%OR=4 +M26XZV>4((>$N)=W4;=W8C994CM1LL-V,Z=U2X.,,A98,1@9U^9@,YA-Q>=Q5 +MON=UB;/)H9-.WN4QD:TH0&XZ"0(^P%$X+L;DII/6.N6UWB$H0&XZZ5$<%><S +M8>;JY]U2X.,,A9917I>/&>6J%)=UB;/)H9-.WN4Q@>9JSN9NC@+DII-Q/A%S +M+NP'4<PU0.<%D>?(#?%&0.ELV\T)49]'0@8DR[*E87D#Z>Z H;_KE/-1'7"P +MH7D QFS@F)V\\])@IA_!1=/G43#;WTQ.UD[U<083Z1CT,3=4Y!KMN!R.,U1Q +M YIX(R\4HCL(7%VET3]'_$3^NA^A)8J+0V*X:&:3/G%3/!!-D+@2 R&A)8I1 +M9$KB=21)8CHLPQ-RPR1<7!"N0QUFU(FR%B]P(#13 Q@FED-D@+^086:R8Q[< +M>9X*3!T$#!]D2R"]*&D906D@,ORJ7_PB[X(KF/Q? /UI'H(:V/QKWOIL?H!5 +ML<^8,_RJ7_PB[X(KF/Q?8($56($ICQ4/./Q<D?Q? /UI'H(:V/QKWOIL?H!5 +M$82 ._WH1^=C# (X8.SOE^QKK*DMY<;/+L?1GLY 3P4=^4--4WA4CM0M14E> +M!&CO;,'W_$\9/"NA2RQD#>I,VXF1HFD'I3O6<7T.@N&H-P:\Q.O'7>40/SPN +MP$M4CM1LX *\U )-\R1(*60BT )-\R2/^.L,K'QL4#"\HQ@$Y< )HVE-UFLV +M@Q ><Z&R<1R21AOE2 9,0R,C_#,O#6; )4M4Q":'Y.HV";\&0>5('=AG_3_K +M%.IVQAVF3WT83N?'7>40WU& *JEE7 -(Z1+)1C5%O2R(IVI55?=.S[ @8 .# +MG5&BZ5(.ZU(ZY5(R<.<N%0,"-NV<6LPZ)>S'7>40WU& *JEE7 .#[IF4'FNS +MUG*GYANOCAYT]AY.XQGL(2V%8S.</T,U\S,G0 <GW#<M\5J6'[&1?Q\> CDG +M,9)SG50W@(KPHZ0#$>6M9O;P<WT'(P)4CM0=\E$(,0)TH -&(JDR( +H9\V4 +M*NS9# *\\E&4*E+Q!\[+WL9N_.QR'.WI?.PRP0<$X0-4CM3#F5%\0!!\0! ^ +M0.5(/9P9Q0<$P0<$P0-4CM3#F5%\0! \0.5(/9P9Y; NQ0<$X0-4CM3#F5%\ +M0!!\0! ^0.5(/9P9Q0<$P0<$P0<$X0-4CM3#F5%\0!!\0!!\0! \0.5(/9P9 +MQ0<$P0<$P0-4CM3#F5%\0! \0.5(/9P9I5,NQ0/#,^V<6LPW0.<%0>5(W2$M +M, )TH -&(JD.V\T)P;&STS]'[#J8PQ-RPR2\8?;>,?ZJ1&WJ88DUH3$GX ,G +MK/GPTS]'##U428XGP ,GK/GP R&A)8I+"EANH"QQ4RK1JX\ LE\T83H[+\#N +M[KZ%PYV/)=6H:Q!',R4L@QW/:;CG5&&F0S62!1@'61IX!L$7!OP404[5@6K+ +M@G@;HSSJH2'7SV=YKT>ISB?!L>>LU%D 1N5(S3=F?ZNNT^H@(@,AL-R7HQQ5 +M52K1NT0',:<2T]:?(I-G5DBN0^5(7?E&TNH@$@,A\+OP,3S&Y.>%\35QI*2Q +M2!VF-V04(P,A<+*6MC+2 [\&0>5(W5+CWQUETVNVI&/]41_S\NMU-! S(*,' +MD>?(#?%GIASE&1R6U$)M_2DRV3I&TNH@(@,A (LQ$ )=*E7FPA-RPR2E$OGW +MP;Z!&_I _8^49__)H9.:/P,A8#>1 B':B#C3[@1@PNU\EO=>8H;64AX4TC]' +MS)V7(0+#XP./V, $O+=E(#=, CU4*0(\H-V# U>5531])D#^./RJ7_PB[X(K +MF/S3'8(:R/SU;-TAJ('0+P6 ._V8@20GME2E0B[#PUVH1B%ZY!KZ>SV:Y1-Y +M4 8&YM3Z7Q!ZE+NJ@UJZ^51M]/D),_RJ7_PB[X(KF/P\/M$$^,Y/Z(1.^(,^ +MZ(.UA"2&5&J[P2_Z7Q >1R&3)1MT]AZ!6#+EY$I:QB]\]C.__DA'IO\%$=E- +M TV>8_'24IY(<BZF,Y%( CW2DND2PX:C;Z4=7"7?2*>\D_^6UED -ORJ7_PB +M[X(KF/P\/M$$^,Y/Z(1.^(,^Z(/G@4QZVC][OAQN)AE3\L2N@[E2KRDB<?6] +M=09:'V8HH)U=95XFEAER<&A5N321$KWCF5U+E)W%4G8<<<0#,?RJ7_PB[X(K +MF/P\/M$$^,Y/Z(1.^(,^Z(,H@ H@ H@ "XNNB&(@<(( <(( <(T&E:_UMV +M@ !V@ !V@ !>B0!;@ !;@ .CBNX@BM=@ !=@ !=@ #GB@ I@ I@ ":=QY8 +MJCQ4,Y'=H9M/A:0BU?$CM?HAW_HEY8(KF/S3'8(:R/SU;-TAJ('0+P4H@ H +M@ H@ !HB0 B@ B@ B</Z)ONCK[[V._OZ1+@((( ((( ((@)D(D ((D (( +MH'F?S\?=+.P>=5[&_G[)OL::VE)N_.QR'.WI#/3U*6M(DT5EX)VGIA++@G@1 +M1'W&UDIK]'3U0<#P\7J0MQ=8IQDL,@54XH]4CM2!?=;=ZAK!P<4%$>75!5L0 +M#'MVAHY?$XU%'4VJE>E;6B,$?(X .2!_SSO#.+@M!3RO/@<UWQ%ZIB_<T6>9 +MX3B*ER-5^9TN(RQ]@@:405^!6#*28_F=OR?]V30XYK*0 R+!X5.(5UVP!<&P +M9V>(1Y$:@K0X6RWI<P)O< )D#T@H,:PJS*<#X01@ A_\PBX6 P(G\ 8G3%QP +MHF7P0WI\I_\%87MW WGG@G6:L=R^=@)O<,)W:S&_KI["UR Z>S>0EZ3H"(O> +M<0)O<,+_HTB=IKZ9<S0<4[7EV4;EG\0& 7J)XP)% #4B0.5(W2$M, )TH -O +MP **<09L+ZDR\(B8L31-@QF0 R(V,QJHMBR(]UHBH!AG 'HB@*!P55D$\LX6 +M?,__E,&S<A[F;KWU8>]_!%F!QJ!RQD.I0SNZ;;A'!3G9Y3J7!W,?:2W6PR_G +M='M"0HI+PUP[K$KZ*SX!)!ND-4W;R+:$ML."ND+H9\W6;,W'+NP;%0,=]5&4 +M*E+Q!\[+WL9N_.QR'.WIC)3O_(1.Z(0�(ICQ4NS\ZH[X'%'_*M7U(NN(+) +MS^,378 '6!4P&,],T?P,]= -R- #O8-E ?W@G<]8,>V%/GQF,]8WK6(P0P8I +M!@*("#F/80:/F!=YL)*(=QY<7!#6,?RJ7_PB[X(KF/P\/M$%>(!5 8/QS!3- +MSU"?S\?33@6<I1R[9DG4>;W<H:2\8?:U>[.?CQ?'.9,$D?_=T6GJ"T\GBOH> +M6/PAW_HEY8(KF/P\/M$%>(!5 8/QS!3-SU"?3_T, @(O#68H,6^9$7LR>A!7 +M8"$P_!SSEAD2O!X@"EHPW(F=IKY0AV3U"Q\G0 8G0/: I!^7"(DT&;$$$?GW +M01!1?!+#A"3C,L0B\%$(,0)DP +SEAFQ%P,L,&^9$7LRP (NX (NH -T4)?_ +M2'EE'QN%)YV7_F;@>!"?GS#/06?O$8@E4QJDQW?^8R$P[!<ZY!H6<P)D<,)] +MTQ(;0\";J#<=$L6[ :1TMI*(QQMF/_JH[X'%'_*M7U(NN(+)S^,378 '6!4P +M&,],T?Q4 +C3WZA!-HC>Q5].Y-//9&(>8R[U(4QW:S'SEAFQQ\4%4;O-0P;Y +ME3#"Z!?$6$O;#P+SEAFQQR!)-25GT& 1MK(-3, B-C=9%R;):(\H8!WSEAFQ +MQR D"CEDY1.]UD:?_P9)BG@_K"R-7S+OTRQG_4PFYC&A5#8FT3Y39S.<W[OE +M.6^9$7N0!6"Y&'75-9&U>[/=P<0$ 1INMB3R!?P40:/]41_0V6GJ"T_>,?RJ +M7_PB[X(KF/P\/M$%>(!5 8/QS!3-SU"?3_T,<I$1G,0&8<D>D@<[%U:1%,6O +MKH[^^CS,F[X9F9"QSEZC[QA^8EP^02YBTC\O\ASAPR]\9B%K1F34*9/+ ;W] +M,9 &-_'P\?FETVGJ:\#H@1Y#BK.W\[P(87],G2^&"3F/<6Z=ANI5&3MU(&G1 +M$XA!SP;ADT7PP2_Z7Q 6<_/ 02WL IY!EV0*S(I\]C/.!V(-W+Z.X_ G89T, +MXNY4W:;<D1=Y\![<E1G/PQF(^AK5UR'#K_K%+_(NN(+)S^,378 '6!4P&,], +MT?Q4 +C37[K1!"2*5:8@-Z<[G5IWZQUH,!*E$5;]@A!1?!(C.==)A0.J5E5% +MO2R(I_FDQW<RBVJ>GL0*IMG63,W"GLT<!:@?1:DB%7_@O.QM[,;/+L?1GL[' +M+A-\ (F=-@<Z@-\D+JO'[%)\0! ^0.5(/9P9Q0<$P0<$P6!DH -.'RF22N5( +M/9P9Q0<$P0<$X0-4CM3#F5%\0!!\0!!\0! ,1@8ZX/21 JA4CM3#F5%\0!!\ +M0!!\0! ^0.5(/9P9Q0<$P0<$P0<$P0<$P6!DH -.'RD=1>5(/9P9Q0<$P0<$ +MP0<$P0<$$>4Z ,6FITJBZ5)\0!!\0!!\0! \0.5(/9P9Q0<$P0<$P0<$$>4Z +M ,6FITH.ZU)\0!!\0! \0.5(/9P9Q0<$P0<$$>4Z ,6FITHZY5)\0! \0.5( +M/9P9I5,NQ0/#,^V<6LPX0.<%0>5(W2$M, )DH -TH -&<LS=3.@_HZ2\8?;6 +M,?RJ7_PB[X(KF/P\/M$%>(!5 8/QS!3-SU#2;_-))K_EF9"G[;Z%Y]7_2'DC +M',.4[O<_/3O6\?EOD*1C<'7P?@468BXU>1YR0F?O0090<_@M([.H5@;'.9,$ +MH:0?O;Y%8QWOH9ONWFDFT3ZG G,;\WQ&!?P400425"R!E=6QDQC4>;W<4;LW +M^_EXH?E*VJ41-]?CR"NJ5E4%PSM17DL6 L.E0>5('=AG?8N36&B'=K>6'[&1 +M?Q\> CF[(0(M, )DP )1K@-O( *#G5%4CM1LH -0;'HZ ,6FITJBZ5)4CM1L +MH -0;'HZ ,6FITH.ZU)4CM1LH -0;'HZ ,6FITHZY5)4CM1LH -0;'HZ ,6F +MITHR<.<N)0-W#O2<6LPY0.?'7>40WP(C0 8L$.4Z8"1W3JG"GLT<):D?1:DB +M%7_@O.QM[,;/+L?1GLY KSBJ!!N-4:&WT;M'"F!TX_"$EW:O?C=XB&I_QG$% +MPUDAQV@W._[/<V2J//[[-J/R_CUC@'Q'9B'8,G5M= )F<,*\ 4CZ,:PJ_$M_ +M#[\*]B1AV$X=YB&0<Q)4/-?CZ%_G43 'C'@@1O:U'MAG;;AQY#%Q9$LH;6L= +MYB&0\^HB\%$(,0)DH -O2N5(S08Z8 0ZP 0Z\ 8B\+NE<0)&<,)]TQ+7HV_+ +M2B'8ZSA!Z_024_ZP2,),<,)]TQ+7HV\P>:&O7K\S21"#S_9!9W],773'GA-4 +MCM1LX )CH ,&D0,Z<-Q5ON<ZX/0.H@-.'RF22N5(/9SX1^5(S08N, 8Z8! Y +MH /'7>5[K@-.[R ZX/21 JA4CM3#B7]4CM1LX )CH ,&D0,Z<-Q5ON<ZX/0. +MH@-.'RD=1>5(/9SX1^5(S08N, 8ZH$\SH /'7>5[K@-0;'HZ ,6FITJB">.U +MS@8N, 8ZH$\SH /'7>5[K@-0;'HZ ,6FITH."^.US@8N, 8ZH$\SH /'7>5[ +MK@-0;'HZ ,6FITHZY5( 2.<34<S^];!4CM0=T@(C0 8Z\*94CM1LH -&H -, +MH -&<LS=3.@_HZ2OQ3P,>UZJ5E77SV<_(P(,1@:/^/D)<XN3&$=L#P(B0.5( +MS08N, :/N&=.%K0_3)DX (O6(0)17MJG/?VJ1"[6$5NRP?9%,_A!%P,R@'[6 +M7,W"GLT<5<8?1:DB%7_@O.QM[,;/+L?1GLY(^81.Z(3O_- -^- -R- "#?U2 +MD 4(D 4(D 4(D 4@D/)8X?+LG%(0W8 ,/= [6!;0#][YC!5/Z(1...WD)"74 +M:6I/QE;T53"\X\4O.?KI,3=9%S'T1A"77YZ?CQ>O91TO#6; )4M4]+M?_>ZW +MP6#!H?/D[IR10B[6X4L;XR>&S?:8*_6:(A)7WUMGH/6_Q?M%&?9A'_:\8?8/ +M?#>0YV9^8MB_1YV+/]C='7_37=W771PPPI'0X5#IXS$7*AO'(6FTD3GRPC0S +MR:EM5/X@-ND39VK PUC@+Y)T7C*=V&GJB[CT3[5V @*(*(J[F9#8/*PJ+ <B +M8,#P(=W4;=W8_?EFR)YT?J=5$BBC[T9G<J2CCD6]9C/8//X#H0;L>2[@_XKJ +M./]ZT4HSR:EAH)M/U5FR]L$+>1A^8CI&!>\#P;'E0><Z#OO4;=W8+?TVC[A( +MMJ&=Z.[N>_!BC.9JSN9NCCG2;05/D 1$\ 5ION9M+OTVWR_8O-64'FL0$G#< +M"6H#(=W4;=U20.?2?U@$D4.(UC4P5Q" ECG64AX'+\9HKN9L[N;/H^.P;P5/ +MD 1$\ 5ION9MGCFI1>>F4DAP55F8\8>%TQC20D5R4O:Q@:38_-)@!ERR-%P> +M<Z&R<1R21AOE2 9,LY-TCM!8H ,Z#OO4;=W8C9;:G9E;A^9JSN9NCJG0"1EF +M!B&A)8KPUD* -OYTODZ"2]+Z 6C23=W6C=W2;_-[MOENW#]'S)VU%>^=V&GJ +MJ_>\0VXZ2>< QA-RPR143.DZ7TNBSQ-RPR011.<XFQPZ61 HX'W3I'D$$=E- +M4Q!DV]+P*\;2;05/D 1$\ 5ION9MGCFI%?^!.GO:A,WX0Q ;"A^0J!#Q]P5I +MON9M;A":0><Z#OM6\ 1)0 1?D.9KWN:9DUJ7>$OC3^<_/3L+XQH6T[[E02'2 +M3=W6C=W2GQ%=BLWJB-)+NXI<X]'(!TCDDJTV@\V?CQ=5V8EQ(V<W72HH "$X +M3TT_3^<(C04ZH..PG^9KWN:U1VXZ&>?X5P18H ,Z#OM6\ 1)0 1?D.9KWN;0 +M+1/>#=[B3=[% 2,<R7/^>'59QRYH"TT'+\:N&(@#$02W2XAC\^M9BCG:R<4) +M^_G4[QK.>MYL69<5LC3,U4S+V5*H*\:^$B1QPS(+(VF \3_K)B)[$L4GP8R/ +M6@18H ,Z#OO?'=[C7=XACM[0G1,;WN$#,05EL+[>L:+9OS,?4AK1&VY",>OP +M*\97EW5:%/69/?6-4O557_58?P9:[V0?<B>/43IQ9&_'+NP;%0/;_%&4*E+Q +M!\[+WL9N_.QR'.WI#/0YL78K 8OOEEUUH$[6L:*+6!K,!HYN#/@1NTYZTR%1 +MG"9( B/06=0SR:F?SUF=IKZ_^]5XP2Z7YD5>/).<"J3O!EL?$CL0UCR2U843 +M1.?KI#<M%<6O?F(.CQB(5O:QT=+P*\:_SL!'9F $X01@ A_\PF<_XX??> 9T +M#@(BT (C\(CDXAT*;VL=%L6[4;O-D\1BC"2^=GV1$G2__DCSKQ?N'^EO@ !O +M@ !O@ !@@@!T@ !T@ !.9.<RA[2PHJN(2:J##^?7SJ=IKXRZL;.F!&^<M/# +M!:3L@5@ )(J[F9#8O-75SB[#JL(4H_Z% KZ52P<(0 <(0 <(H"'EN[ER@ !R +M@ !R@ .S#L@( (M, *EC<U1?!+,^*A%@ 4ZH..P#P4<[N$H$.+YO=\D[N1= +M[E)%@ 4ZH..P#P4<[N%H208Z0 ?;3><(C04ZH..P#P4<[N%HN=U KQ#QQ^-/ +M 6#*5_F6-3(R!<["N[H6=/TQJEE)VF%8QV+&#O1L1+62=5ODET)B<UEIT[, +MZV0?@D7\$D?A)A3E^4QMALT+.WWEJ8X6@QE_2"'/9&(E(9LRZL;"'W\\_@10 +M(/TVOS"N83&_KI[,^*A%@ 4ZH..P#P5/ 7/#?3>'']?8 1)P 0'73+P(=U& +MD 1,<-#2;_-)ED/WDS#]2N<W#QS4HA=)\ )/4%WI$ZM*ZB%;:"S8K#BJE$,^ +M02XZ5G7(]E1(@J38K&$:+R<B<'DP]XCD* *7)R2/^%HV@\VO!WD@D 0O\ 0S +M347,^*A%@ 4ZP!NU+-U&D 1,4 1"(P)$((KZT0925E4DYL9)\ )/$ )P#MTR +M(=U%@ 5%, 158-WQ#A_270184 1#4 76G3FI=1[(E$.(EI#8[(I?1,3!P1%' +M;!%6^KNED?]TGK[KHO<_$ZOSEAFQ!S4Y=#]O0.>GMK!\Y49G<KW<81T 7[O- +MD\1BC"2PU1_U 9V=IKZ_^QR?;X;L2>?->=/E"5=(E#(3.5DY!#6K<XQTKN.P +MW^,__OEO8$>+([+_$1LA4XCT=N")09WE:=.DQW?.9"'*HH]<=@)D< )TSAN +MA!(+XQH6\^N/=&3L@@))X )%X +I.! B\%'8/ )DH -T\(B1?Q\> CDG\?-T +MCM!8H ,Z#OM%@ 5%, 158-W?RF&;49='PF%C@@).#MWJ)]UN7C(A)OV@;[A) +MY>;HT6MMQ!$G,9.<*@,M4 /IF%17EW41 Q@QHY]E "*#Y-&H*\8@6;0^02[> +MX6IR,XX\X9NA1Q#SAZ38O*+>+04^SE"?S\?'+NP;%0/%_E&4*E+Q!\[+WL9N +M_.QR'.WI#/3('G\\+@4^SE"8RI']NJR%D^Z%)P)FH*^EC<W (08<<<23/G&Q +MYD76<7595X>[B\VLUQ%"(]U&D 1,4 2_"Q_YWQV=IKYTGF2 %JL@,&^9$7O' +M"1\U6A\^\3UTWL#MZV0._^KJV$;K-)UA5!_?> 9TGK[K\L-Y03). ";PP2\R +M&\/9T2_8',4E'2F_SL!'QBZ1V!W,Z:]T+OTVG[[K<K+PA?Z(7O557_4I4RF4 +MDA<(0 <(0 <($)"EX1A^8EP^81)T'DM91QJ"Q8R/6@18H ,Z#OL]_N-H60:@ +M49>/Z7PAPO;8\9R8&>?X5P18H ,Z#OL]_N-H:2=U^9AVHDK16I=T#ATNZ>1= +M[E)%@ 4ZH..PW^,_CI9Y 0=U^9C1ZE$^ )=*GA=PT*78G!?JU (^P'-EX.30 +M/1/2/05JK@1- 7% 2,^02YPHA)4JV-E0 =J\"8HH'F3/G%LB\VND_^O 3OI +M<W595X>=OR>+.).<^D2K;DAO!!\/?#>0IW!J\"9T?F8'ZOB,HQQ553!&8OF= +MO\)O0.=07.5M> (Z6VGN \.E(=U,\ 1.< 1*T 100.?2;_-)ED/WDS FX7U! +M;!VO!WET+FOU<09J\"8HH'F%R")#,#=9%S&%54A"U2 71N=3)MU3H.9*T 10 +MD#GL.2!C<'7RZ1PP/),'+EOC#XM%HV-5-_YT7C&@N!NSEAC,^*A%@ 4ZH..P +M/P5JK@1- 6U%QF9^7/2S01/X 1'H 1- 7% 2,^02YPHA)4:QV*<1)J\"8H +MH'F3/G%LB\WXD_\#03=5[H\/N:/@3N?H^6<+UT;0(4#PP7!M)&M(0^<Z#OM3 +MH.9*T 10@,0M;2%#[(HM#;]B_'J0YS#U<09J\"8HH'EG=J $X01@ A_EI?\) +M>W59%S%2-OH#(=U,\ 1.< 1*T 10<&SO3N=07.7^N(B=*+.\DZ)E"[]B#$A( +M)MU3H.9*T 10$/^8L31-TYQE)RV9_AYT#F##(_EQ!"-BPG;2/05JK@1- 5_ +MB\W2S01/X 1'H 1- 634SSY\CM2MJ&/9C/8G/T'XC$7*AO'(6FT48YDP#2E +M0;8V@\WY#XF=IKY2_<M!DG4 PG8V@\WL4>W,^*A%@ 4ZH..PSP1/X 1'H 1- +M 6U%QDL0&Z96<W"GLT<=0/&_G[)OL::VE)N_.QR'.WIC)3#SQ4&7?PAW_HE +MY8(T2-!#D/)O$<],T?Q4 /W@G<]8<=$6;=$@\(1.Z(3-3P70+P4P&,\RZ((K +M..VC%[&1?Q\> CF[\1PYQ)' *;.\LX@L1,#P >X$D>Z%-_RJ7_PB[X(KF/P\ +M/M$$^,Y/Z(1.^(,^Z(.9DUH&C!XUBO@(\61L15]%+6)SDW414UA^]!M'FOUM +M.H8Z3XXV$W& I!_#JL+Y\M-,1V<[1WL%+S&DL28#$02=IKX:<V3KZQA^8EP^ +M02XGL 4G_$0GT 4G'(FE+C+) ?PX009;P +SEAFQ-P=M601.O'/_2'G78?:9 +M\^X$T35T3A"UVSSS,F^9$7OP'O2FP30=<F301^<$,6^9$7NN(4!PHF7\LK^% +M-&^9$7L,<CK";DG4*9) GQ!$L 4LX&=M"1* A/\9!F'-<S\"]&>Z^52X3N<$ +MH:0_K"SYE3"O%'Y/1P8<81(R>N)4($ ZY!HE(9NO93"<D;LM!&@U6A])C,TH +M0&XZN67^I4K^"IPVVO@?L7>F1^?CXAHLEA',2!%FL 4L,/YST);_-D $D?W* +MUK,ZW]()@Z3"7KO-,R]'!F_<,?[P'@1"9Z@G?F2J/.D3I_/GX4I:5E[LLC)T +M3A#CSR!)94G4*9) GQ-& .AR<%"X#N[A]W1!QY!TWM(_4_X@AK>:Z/02$_F! +M>_#8;!V?;R1PA=/6H:3,^*A, .AR<%"X#N[A]W1!QY!TWM*\,_A.OW-!M]3[ +MA[UT?FRI=6;,MAO6H:3,^*CFHE)R<%"X#N[A]W1!QY!TWM*E.#=9IW&4;FHE +MIW=CB') GQ-N/@5EP(<7:FQ+O7_G8F;_TOE5+>Q*^L.DOG:;X6!ZL4_Q7DY< +M[,8YU(Y#1C% XA>.D6KA)@=E!R-RXCXD=N+93U6(=QZN(43/]2FETC5T/CEG +MK:3,*&I;P *@UY:!]WO4F3[9WZ:(YR%;J.]O0.<MS3LAQVC-@VB@9\!5M'>F +M1^<$H:1.IGB%X7JW)R0D$P0$T?/#>>*_SL!'QBYP!2.YBWA2C;K8K'UNKV(> +M@GD&!O23LP4L@+;4T9;_-D $D?W*UK,ZW]()@Z3"7KO-@VAH2QTD$P2FP30M +M=62G-^V/NE$Q@ /&_G[)OL::VE)N_.QR'.WI#/3.YDI:UEKL3AV_6TX,NF!, +M0^<$L>F>8_'2@D4_S70\E#H$41Z_D<38C+;4P2). ";PP2_L@NO_TOE5+>Q* +M^L.DSF;-Z>YR<&AW:S/"7OX@EAYSDW7L@K8#D>Y(*NPG 4GW#<M\;O(:/&( +M5?Z(^T[M6QYTWM*\TQV=IKZB@B0P@F@ AJ3"/ORJ7_PB[X(KF/P\/M$%>(!6 +MD<]80=#B'8(:^(1.Z(1/Z(1.*/T9P8R/"@6 +@<'A>O@'GY/%W0,2><M_3/E +M#V+I,3=9%R;LSB+)/,/"GD/M:+CFDD/8,G4 Q.ZUI$QT3A >PS&6YAQ-XSD6 +M+RU8Q"_L$HG$!!MT3A# LQO9'X@@X 1@PNU\AIR1J'7"CK:9PYY5R1$G41HC +M_#/9KTW"'OGWX2&0LQOX8V*Q)"WEB3\V(^SE\1L^@;;4P8R/<PXA/DDC=J +M0.ES-W76,?RJ7_PB[X(KF/P\/M$$^,Y/Z(1.^(,^Z(-T?FRI!4]T4P9\5HIS +MDW5WYR!%A?C"/FLM)P:R!$\LEA$LDLSOE$/M*)]!?>+#K_K%+_(NN(+)S^,3 +M38#O_(1.Z(0_Z(,^F#GO7K4J!AW%4G8< 3G+0>>0>%_:7QK9OS,?LI,/2P=; +MP ).T)9%X,02,_[KI#=\XS>"@FKY(:,G7NAA@ <"]#$5 XJ[<7*J5+O-D\38 +M'+U.T%X^07I\M[ZN(V P@'[6;,U _Z@;=5/&_G[)OL::VE)N_.QR'.WIC)0_ +MZ(,^"(/QS!3-3P5/Z(1.&/0-+=!!./Q<D5(0[8#WG 1/Z(1.2-#B'8(:>-$6 +M;=$7;=$6S= "'80&G?)8\<Y/Z(1...WU"6+E^$XYU(YG=D8J[5/<81TO#6; +M)4O3C"$%DS#(%XF%)W<$-V7>41*RZ=/D0@>9D?AF$"19!QG8,T>-^+OE5!V# +MZ%T.ZJ^)YD9G<O &T2QG32XBNC]T=!E(U8:#LZ$T,FE^D5SNA1"Q)1F[8?F= +MOR=*RHLG%B19EW.K^+O(Z.<=@8I?$T<><U13-TW]XUU5Z 8RYQKD(J+[0T>7 +M@50S.2[LDC5SX",;BD7JV$9*>AXB6S:]9D9R$_Z]MD19NV!^X1BI!GH&#!]T +MD!D# 21^X1BI!GIRPF9?$T>HFR7+$R19!R#&AGR1R)&W,8Q1ET)QPS)(51IR +M5Q])RAU]EAF<KJ<THCSZ.&/ 3Q%!,! \T;3EZ<5@8^D)2C=T+RB@^.I(!1^; +MCXN'Y*-#3""WE!YSDW7LTO=>A![(%XGSTA*!.\,((7<$9Y@\@9^NT?>!];OE +MY!HX6K4+QC2U9"$DEIUY'XG5M;PF@3EA/6/ 3Q&*HTKZ6Z1F$&&FQ[[RLCR% +MA4)X4/B%L_!/E9 88N[G"1L]5[_P,?[)X;<@!@(O#6; )4O3C! X5"3MZUW\ +MU3ZG G-XJXGK%"AA;;( 9K:? [V$LQO9'X@@D%94;DKBA<(R1B-WX!<Z9.YD +MY1/DLD0'T?=)GSY00!M':A%#L+2K>" VW48XQ!FTUVM<1<#F=4ML _<@@ 15 +M%9QVY(8>0AEGP#*.01]S0T5$LOV4KS'@R3)-)3!XPXGK=*'VMUDW[8_9?R"? +MCQ<-3,#P 3V;0;A2QL0$ET7EZ<+ T=3Q#A_),W));! +OR>1W33-F4-VICKX +MCSD:@FV,A0>%_RU^GB/H9\W5+.S9'&#H]5&4*E+Q!\[+WL9N_.QR'.WIC)0$ +M/00,+= 66($5:- ,+=#-3P5/Z(1...U"]M)@!ERR-%R9(0=KX!H^\DZVY%H_ +MS70;.I,$(0)!1U'G3@:/^(\R!S6RXS5((BA*PND7+SKOXAB*-9P'$6YR4':5 +M=2)91AWE\[7Q/[S-^4)R$$SE:4TU#UTD=A 4=>[SXEIJ-3M(@K-!<7^"5^6N +M$;U#\KHD;9/P:Q#K,6GY!B*?CQ?P5(@A-T9\0^DZK_E%&D: Y&C@F)V\D_T4 +M$^7P#@)/T$+TX=9E<)SHH1Y]$4GH4>\(L1YPXEUEFJV6W_E[HJ2JI-.>008? +M,R/SDB&E0_9/CSYEEQ<M('<"DHN#"T? 3Q%]'AXZ(OK,U!CBB%K*\<%&=1V4 +MKO/Q-"($;%[PA?Z)ONB&P@8(P 8(P 8(H!P(P 8(P 8(H!@(\ 8(\ 8(\,$( +M, 8(, 8(D'#/=--R1OK(6(\^S&R[81VO!WD:\])@!ERR1$6_^]5XH1>7)B!U +6JTKA=5]I *"4_\%4D\0&T1CB.!Q$ 1VO + +end diff --git a/dmake/dbug/dbug/readme b/dmake/dbug/dbug/readme new file mode 100644 index 000000000000..a69f34682276 --- /dev/null +++ b/dmake/dbug/dbug/readme @@ -0,0 +1,6 @@ +To unpack the DBUG manual page please issue the following sequence of +commands: + + uudecode dbug.uue + uncompress dbug.Z + mv dbug dbug.p diff --git a/dmake/dbug/getwd.c b/dmake/dbug/getwd.c new file mode 100644 index 000000000000..56e1a03ab7ca --- /dev/null +++ b/dmake/dbug/getwd.c @@ -0,0 +1,6 @@ +char * +getwd(pathname) +char *pathname; +{ + return("delete this code if your getwd.c works correctly"); +} diff --git a/dmake/dbug/malloc/_changes b/dmake/dbug/malloc/_changes new file mode 100644 index 000000000000..888a47a8dfb5 --- /dev/null +++ b/dmake/dbug/malloc/_changes @@ -0,0 +1,9 @@ +I made the following changes to the malloc package as found in +comp.sources.unix: + + 1. created this file _changes. + 2. moved README to _readme (facilitates transfer to DOS and back to + unix) + 3. renamed testmalloc.c, malloc_chk.c, and malloc_chn.c to testmlc.c, + mlc_chk.c, and mlc_chn.c respectively. Again DOS has trouble with + long basenames in filenames. diff --git a/dmake/dbug/malloc/_readme b/dmake/dbug/malloc/_readme new file mode 100644 index 000000000000..b78b1fd6bbcd --- /dev/null +++ b/dmake/dbug/malloc/_readme @@ -0,0 +1,133 @@ +# (c) Copyright 1990 Conor P. Cahill. (uunet!virtech!cpcahil) +# You may copy, distribute, and use this software as long as this +# copyright statement is not removed. + +This package is a collection of routines which are a drop-in replacement +for the malloc(3), memory(3), string(3), and bstring(3) library functions. + +The purpose of these programs is to aid the development and/or debugging +of programs using these functions by providing a high level of consistancy +checking whenever a malloc pointer is used. Due to this increased +level of consistancy checking, these functions have a considerably larger +overhead than the standard functions, but the extra checking should be +well worth it in a development environment. + +To use these functions all you need to do is compile the library and +include it on your loader command line. You do not need to recompile +your code, only a relink is necessary. + +Features of this library: + + 1. The malloced area returned from each call to malloc is filled with + non-null bytes. This should catch any use of uninitialized malloc + area. The fill pattern for malloced area is 0x01. + + 2. When free is called numerous validity checks are made on the + pointer it is passed. In addition, the data in the malloc block + beyound the size requested on the initial malloc is checked to + verify that it is still filled with the original fill characters. + + This is usefull for catching things like: + + ptr = malloc(5); + ptr[5] = '\0'; + + /* + * You should not that this will be caught when it is + * freed not when it is done + */ + + And finally, the freed block is filled with a different fill pattern + so that you can easily determine if you are still using free'd space. + The fill pattern for free'd areas is 0x02. + + This is usefull for catching things like: + + ptr = malloc(20); + + bptr = ptr+10; + + /* do something usefule with bptr */ + + free(ptr); + + /* + * now try to do something useful with bptr, it should + * be trashed enough that it would cause real problems + * and when you went to debug the problem it would be + * filled with 0x02's and you would then know to look + * for something free'ing what bptr points to. + */ + + + 3. Whenever a bstring(3)/string(3)/memory(3) function is called, it's + parameters are checked as follows: + + If they point somewhere in the malloc arena + If the operation goes beyond requested malloc space + call malloc_warning() + + This is usefull for catching things like: + + ptr = malloc(5); + strcpy(ptr,"abcde"); + + + 4. Malloc_warning() and malloc_fatal() are used when an error condition + is detected. If the error is severe, malloc_fatal is called. + Malloc_warning is used otherwise. The decision about what is fatal + and what is a warning was made somewhat arbitrarily. + + Warning messages include: + + Calling free with a bad pointer + Calling a bstring/string/memory (3) function which will go beyond + the end of a malloc block (Note that the library function is + not modified to refuse the operation. If malloc warnings are + in the default IGNORE case, the operation will continue and + at some point cause a real problem). + + Fatal errors are: + + Detectable corruption to the malloc chain. + + + 5. The operations to perform when an error is detected are specified at + run time by the use of environment variables. + + MALLOC_WARN - specifies the warning error message handling + MALLOC_FATAL - specifies the fatal error handling + + + When one of these error conditions occur you will get an error + message and the handler will execute based upon what setting + is in the environment variables. Currently understood settings + are as follows: + + 0 - continue operations + 1 - drop core and exit + 2 - just exit + 3 - drop core, but continue executing. Core files will + be placed into core.[PID].[counter] i.e: core.00123.001 + 128 - dump malloc chain and continue + 129 - dump malloc chain, dump core, and exit + 130 - dump malloc chain, exit + 131 - dump malloc chain, dump core, continue processing + + + There is an additional environment variable MALLOC_ERRFILE which + is used to indicate the name of the file for error message output. + + For example, to set up the session to generate a core file for + every malloc warning, to drop core and exit on a malloc fatal, and + to log all messages to the file "malloc_log" do the following: + + MALLOC_WARN=131 + MALLOC_FATAL=1 + MALLOC_ERRFILE=malloc_log + + export MALLOC_WARN MALLOC_FATAL MALLOC_ERRFILE + + 6. The function malloc_dump() is available to dump the malloc chain whenever + you might want. It's only argument is a file descriptor to use to write + the data. Review the code if you need to know what data is printed. diff --git a/dmake/dbug/malloc/calloc.c b/dmake/dbug/malloc/calloc.c new file mode 100644 index 000000000000..6d1e0f84b626 --- /dev/null +++ b/dmake/dbug/malloc/calloc.c @@ -0,0 +1,91 @@ +/* + * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil). + * You may copy, distribute, and use this software as long as this + * copyright statement is not removed. + */ +#include <stdio.h> + +/* + * Function: calloc() + * + * Purpose: to allocate and nullify a data area + * + * Arguments: nelem - number of elements + * elsize - size of each element + * + * Returns: NULL - if malloc fails + * or pointer to allocated space + * + * Narrative: determine size of area to malloc + * malloc area. + * if malloc succeeds + * fill area with nulls + * return ptr to malloc'd region + */ +#ifndef lint +static char rcs_header[] = "$Id: calloc.c,v 1.1.1.1 2000-09-22 15:33:26 hr Exp $"; +#endif + +char * +calloc(nelem,elsize) + unsigned int nelem; + unsigned int elsize; +{ + char * malloc(); + char * memset(); + char * ptr; + unsigned int size; + + size = elsize * nelem; + + if( (ptr = malloc(size)) != NULL) + { + (void) memset(ptr,'\0',(int)size); + } + + return(ptr); +} + + +/* + * $Log: not supported by cvs2svn $ + * Revision 1.1.1.1 1997/09/22 14:51:10 hjs + * dmake 4.1 orginal sourcen + * + * Revision 1.1.1.1 1997/07/15 16:02:26 dvadura + * dmake gold 4.1.00 initial import + * + * Revision 1.1.1.1 1996/10/27 07:30:14 dvadura + * Dmake 4.1 Initial Import + * + * Revision 1.1.1.1 1996/10/24 05:33:14 dvadura + * Initial import for final release of dmake 4.1 + * + * Revision 1.1 1994/10/06 17:43:08 dvadura + * dmake Release Version 4.0, Initial revision + * + * Revision 1.1 1994/10/06 03:45:17 dvadura + * dmake Release Version 4.0, Initial revision + * + * Revision 1.1 1992/01/24 03:28:58 dvadura + * dmake Version 3.8, Initial revision + * + * Revision 1.6 90/05/11 00:13:07 cpcahil + * added copyright statment + * + * Revision 1.5 90/02/24 20:41:57 cpcahil + * lint changes. + * + * Revision 1.4 90/02/24 17:25:47 cpcahil + * changed $header to $id so full path isn't included. + * + * Revision 1.3 90/02/24 13:32:24 cpcahil + * added function header. moved log to end of file. + * + * Revision 1.2 90/02/22 23:08:26 cpcahil + * fixed rcs_header line + * + * Revision 1.1 90/02/22 23:07:38 cpcahil + * Initial revision + * + */ diff --git a/dmake/dbug/malloc/debug.h b/dmake/dbug/malloc/debug.h new file mode 100644 index 000000000000..1a206d242936 --- /dev/null +++ b/dmake/dbug/malloc/debug.h @@ -0,0 +1,129 @@ +/* + * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil). + * You may copy, distribute, and use this software as long as this + * copyright statement is not removed. + */ +/************************************************************************/ +/* */ +/* this include sets up some macro functions which can be used while */ +/* debugging the program, and then left in the code, but turned of by */ +/* just not defining "DEBUG". This way your production version of */ +/* the program will not be filled with bunches of debugging junk */ +/* */ +/************************************************************************/ +/* + * $Id: debug.h,v 1.1.1.1 2000-09-22 15:33:26 hr Exp $ + */ + +#ifdef DEBUG + +#if DEBUG == 1 /* if default level */ +#undef DEBUG +#define DEBUG 100 /* use level 100 */ +#endif + +#include <stdio.h> + +#define DEBUG0(val,str)\ + {\ + if( DEBUG > val ) \ + fprintf(stderr,"%s(%d): %s\n",\ + __FILE__,__LINE__,str);\ + } +#define DEBUG1(val,str,a1)\ + {\ + char _debugbuf[100];\ + if( DEBUG > val )\ + {\ + sprintf(_debugbuf,str,a1);\ + fprintf(stderr,"%s(%d): %s\n",\ + __FILE__,__LINE__,_debugbuf);\ + }\ + } + +#define DEBUG2(val,str,a1,a2)\ + {\ + char _debugbuf[100];\ + if( DEBUG > val )\ + {\ + sprintf(_debugbuf,str,a1,a2);\ + fprintf(stderr,"%s(%d): %s\n",\ + __FILE__,__LINE__,_debugbuf);\ + }\ + } + +#define DEBUG3(val,str,a1,a2,a3)\ + {\ + char _debugbuf[100];\ + if( DEBUG > val )\ + {\ + sprintf(_debugbuf,str,a1,a2,a3);\ + fprintf(stderr,"%s(%d): %s\n",\ + __FILE__,__LINE__,_debugbuf);\ + }\ + } + +#define DEBUG4(val,str,a1,a2,a3,a4)\ + {\ + char _debugbuf[100];\ + if( DEBUG > val )\ + {\ + sprintf(_debugbuf,str,a1,a2,a3,a4);\ + fprintf(stderr,"%s(%d): %s\n",\ + __FILE__,__LINE__,_debugbuf);\ + }\ + } + +#define DEBUG5(val,str,a1,a2,a3,a4,a5)\ + {\ + char _debugbuf[100];\ + if( DEBUG > val )\ + {\ + sprintf(_debugbuf,str,a1,a2,a3,a4,a5);\ + fprintf(stderr,"%s(%d): %s\n",\ + __FILE__,__LINE__,_debugbuf);\ + }\ + } + +#else + +#define DEBUG0(val,s) +#define DEBUG1(val,s,a1) +#define DEBUG2(val,s,a1,a2) +#define DEBUG3(val,s,a1,a2,a3) +#define DEBUG4(val,s,a1,a2,a3,a4) +#define DEBUG5(val,s,a1,a2,a3,a4,a5) + +#endif /* DEBUG */ + + +/* + * $Log: not supported by cvs2svn $ + * Revision 1.1.1.1 1997/09/22 14:51:11 hjs + * dmake 4.1 orginal sourcen + * + * Revision 1.1.1.1 1997/07/15 16:02:26 dvadura + * dmake gold 4.1.00 initial import + * + * Revision 1.1.1.1 1996/10/27 07:30:14 dvadura + * Dmake 4.1 Initial Import + * + * Revision 1.1.1.1 1996/10/24 05:33:14 dvadura + * Initial import for final release of dmake 4.1 + * + * Revision 1.1 1994/10/06 17:43:09 dvadura + * dmake Release Version 4.0, Initial revision + * + * Revision 1.1 1994/10/06 03:45:18 dvadura + * dmake Release Version 4.0, Initial revision + * + * Revision 1.1 1992/01/24 03:28:59 dvadura + * dmake Version 3.8, Initial revision + * + * Revision 1.2 90/05/11 00:13:08 cpcahil + * added copyright statment + * + * Revision 1.1 90/02/23 07:09:01 cpcahil + * Initial revision + * + */ diff --git a/dmake/dbug/malloc/dump.c b/dmake/dbug/malloc/dump.c new file mode 100644 index 000000000000..7ac79ccc884f --- /dev/null +++ b/dmake/dbug/malloc/dump.c @@ -0,0 +1,142 @@ +/* + * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil). + * You may copy, distribute, and use this software as long as this + * copyright statement is not removed. + */ +#include <stdio.h> +#include "malloc.h" +#include "tostring.h" + +/* + * Function: malloc_dump() + * + * Purpose: to dump a printed copy of the malloc chain and + * associated data elements + * + * Arguments: fd - file descriptor to write data to + * + * Returns: nothing of any use + * + * Narrative: Just print out all the junk + * + * Notes: This function is implemented using low level calls because + * of the likelyhood that the malloc tree is damaged when it + * is called. (Lots of things in the c library use malloc and + * we don't want to get into a catch-22). + * + */ + +#ifndef lint +static +char rcs_hdr[] = "$Id: dump.c,v 1.1.1.1 2000-09-22 15:33:26 hr Exp $"; +#endif + + +#define ERRSTR "I/O Error on malloc dump file descriptor\n" + +#define WRITEOUT(fd,str,len) if( write(fd,str,(unsigned)len) != len ) \ + { \ + (void) write(2,ERRSTR,\ + (unsigned)strlen(ERRSTR));\ + exit(120); \ + } + +void +malloc_dump(fd) + int fd; +{ + char buffer[512]; + void exit(); + int i; + extern char * malloc_data_end; + extern char * malloc_data_start; + extern struct mlist * malloc_end; + extern struct mlist malloc_start; + struct mlist * ptr; + + WRITEOUT(fd,"MALLOC CHAIN:\n",14); + WRITEOUT(fd,"-------------------- START ----------------\n",44); + + for(i=0; i < 80; i++) + { + buffer[i] = ' '; + } + + for(ptr = &malloc_start; ptr; ptr = ptr->next) + { + (void) tostring(buffer, (int)ptr, 8, B_HEX, '0'); + (void) tostring(buffer+9, (int)ptr->next, 8, B_HEX, '0'); + (void) tostring(buffer+18, (int)ptr->prev, 8, B_HEX, '0'); + (void) tostring(buffer+27, (int)ptr->flag, 10, B_HEX, '0'); + (void) tostring(buffer+38, (int)ptr->s.size, 8, B_DEC, ' '); + (void) tostring(buffer+47, (int)ptr->s.size, 8, B_HEX, '0'); + (void) tostring(buffer+57, (int)ptr->data, 8, B_HEX, '0'); + buffer[46] = '('; + buffer[55] = ')'; + buffer[65] = '\n'; + WRITEOUT(fd,buffer,66); + } + WRITEOUT(fd,"-------------------- DONE -----------------\n",44); + + WRITEOUT(fd,"Malloc start: ",19); + (void) tostring(buffer, (int) &malloc_start, 8, B_HEX, '0'); + buffer[8] = '\n'; + WRITEOUT(fd,buffer,9); + + WRITEOUT(fd,"Malloc end: ", 19); + (void) tostring(buffer, (int) malloc_end, 8, B_HEX, '0'); + buffer[8] = '\n'; + WRITEOUT(fd,buffer,9); + + WRITEOUT(fd,"Malloc data start: ", 19); + (void) tostring(buffer, (int) malloc_data_start, 8, B_HEX, '0'); + buffer[8] = '\n'; + WRITEOUT(fd,buffer,9); + + WRITEOUT(fd,"Malloc data end: ", 19); + (void) tostring(buffer, (int) malloc_data_end, 8, B_HEX, '0'); + buffer[8] = '\n'; + WRITEOUT(fd,buffer,9); + +} /* malloc_dump(... */ + + +/* + * $Log: not supported by cvs2svn $ + * Revision 1.1.1.1 1997/09/22 14:51:11 hjs + * dmake 4.1 orginal sourcen + * + * Revision 1.1.1.1 1997/07/15 16:02:26 dvadura + * dmake gold 4.1.00 initial import + * + * Revision 1.1.1.1 1996/10/27 07:30:14 dvadura + * Dmake 4.1 Initial Import + * + * Revision 1.1.1.1 1996/10/24 05:33:14 dvadura + * Initial import for final release of dmake 4.1 + * + * Revision 1.1 1994/10/06 17:43:09 dvadura + * dmake Release Version 4.0, Initial revision + * + * Revision 1.1 1994/10/06 03:45:19 dvadura + * dmake Release Version 4.0, Initial revision + * + * Revision 1.1 1992/01/24 03:29:01 dvadura + * dmake Version 3.8, Initial revision + * + * Revision 1.5 90/08/29 21:22:37 cpcahil + * miscellaneous lint fixes + * + * Revision 1.4 90/05/11 00:13:08 cpcahil + * added copyright statment + * + * Revision 1.3 90/02/24 21:50:07 cpcahil + * lots of lint fixes + * + * Revision 1.2 90/02/24 17:27:48 cpcahil + * changed $header to $Id to remove full path from rcs id string + * + * Revision 1.1 90/02/22 23:17:43 cpcahil + * Initial revision + * + */ diff --git a/dmake/dbug/malloc/free.c b/dmake/dbug/malloc/free.c new file mode 100644 index 000000000000..5eb139d6fcb8 --- /dev/null +++ b/dmake/dbug/malloc/free.c @@ -0,0 +1,206 @@ +/* + * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil). + * You may copy, distribute, and use this software as long as this + * copyright statement is not removed. + */ +#include <stdio.h> +#include "malloc.h" +#include "debug.h" + +/* + * Function: free() + * + * Purpose: to deallocate malloced data + * + * Arguments: ptr - pointer to data area to deallocate + * + * Returns: nothing of any value + * + * Narrative: + * verify pointer is within malloc region + * get mlist pointer from passed address + * verify magic number + * verify inuse flag + * verify pointer connections with surrounding segments + * turn off inuse flag + * verify no data overrun into non-malloced area at end of segment + * IF possible join segment with next segment + * IF possible join segment with previous segment + * Clear all data in segment (to make sure it isn't reused) + * + */ +#ifndef lint +static +char rcs_hdr[] = "$Id: free.c,v 1.1.1.1 2000-09-22 15:33:26 hr Exp $"; +#endif + +void +free(cptr) + char * cptr; +{ + char * func = "free"; + int i; + extern int malloc_checking; + extern struct mlist * malloc_end; + extern int malloc_errno; + extern char * malloc_data_end; + extern char * malloc_data_start; + void malloc_join(); + void malloc_memset(); + struct mlist * oldptr; + struct mlist * ptr; + + /* + * IF malloc chain checking is on, go do it. + */ + if( malloc_checking ) + { + (void) malloc_chain_check(1); + } + + /* + * verify that cptr is within the malloc region... + */ + if( cptr < malloc_data_start || cptr > malloc_data_end ) + { + malloc_errno = M_CODE_BAD_PTR; + malloc_warning(func); + return; + } + + /* + * convert pointer to mlist struct pointer. To do this we must + * move the pointer backwards the correct number of bytes... + */ + + ptr = (struct mlist *) (cptr - M_SIZE); + + if( (ptr->flag&M_MAGIC) != M_MAGIC ) + { + malloc_errno = M_CODE_BAD_MAGIC; + malloc_warning(func); + return; + } + + if( ! (ptr->flag & M_INUSE) ) + { + malloc_errno = M_CODE_NOT_INUSE; + malloc_warning(func); + return; + } + + if( (ptr->prev && (ptr->prev->next != ptr) ) || + (ptr->next && (ptr->next->prev != ptr) ) || + ((ptr->next == NULL) && (ptr->prev == NULL)) ) + { + malloc_errno = M_CODE_BAD_CONNECT; + malloc_warning(func); + return; + } + + ptr->flag &= ~M_INUSE; + + /* + * verify that the user did not overrun the requested number of bytes. + */ + for(i=ptr->r_size; i < ptr->s.size; i++) + { + if( ptr->data[i] != M_FILL ) + { + malloc_errno = M_CODE_OVERRUN; + malloc_warning(func); + break; + } + } + + DEBUG3(10,"pointers: prev: 0x%.7x, ptr: 0x%.7x, next: 0x%.7x", + ptr->prev, ptr, ptr->next); + + DEBUG3(10,"size: prev: %9d, ptr: %9d, next: %9d", + ptr->prev->s.size, ptr->s.size, ptr->next->s.size); + + DEBUG3(10,"flags: prev: 0x%.7x, ptr: 0x%.7x, next: 0x%.7x", + ptr->prev->flag, ptr->flag, ptr->next->flag); + + /* + * check to see if this block can be combined with the next and/or + * previous block. Since it may be joined with the previous block + * we will save a pointer to the previous block and test to verify + * if it is joined (it's next ptr will no longer point to ptr). + */ + malloc_join(ptr,ptr->next,0,0); + + oldptr = ptr->prev; + + malloc_join(ptr->prev, ptr,0,0); + + if( oldptr->next != ptr ) + { + DEBUG0(10,"Oldptr was changed"); + ptr = oldptr; + } + + /* + * fill this block with '\02's to ensure that nobody is using a + * pointer to already freed data... + */ + malloc_memset(ptr->data,M_FREE_FILL,(int)ptr->s.size); + +} + +/* + * $Log: not supported by cvs2svn $ + * Revision 1.1.1.1 1997/09/22 14:51:11 hjs + * dmake 4.1 orginal sourcen + * + * Revision 1.1.1.1 1997/07/15 16:02:26 dvadura + * dmake gold 4.1.00 initial import + * + * Revision 1.1.1.1 1996/10/27 07:30:14 dvadura + * Dmake 4.1 Initial Import + * + * Revision 1.1.1.1 1996/10/24 05:33:14 dvadura + * Initial import for final release of dmake 4.1 + * + * Revision 1.1 1994/10/06 17:43:10 dvadura + * dmake Release Version 4.0, Initial revision + * + * Revision 1.1 1994/10/06 03:45:19 dvadura + * dmake Release Version 4.0, Initial revision + * + * Revision 1.1 1992/01/24 03:29:02 dvadura + * dmake Version 3.8, Initial revision + * + * Revision 1.9 90/08/29 21:22:48 cpcahil + * miscellaneous lint fixes + * + * Revision 1.8 90/05/11 00:13:08 cpcahil + * added copyright statment + * + * Revision 1.7 90/02/25 11:00:18 cpcahil + * added support for malloc chain checking. + * + * Revision 1.6 90/02/24 21:50:18 cpcahil + * lots of lint fixes + * + * Revision 1.5 90/02/24 17:29:13 cpcahil + * changed $Header to $Id so full path wouldnt be included as part of rcs + * id string + * + * Revision 1.4 90/02/24 15:15:32 cpcahil + * 1. changed ALREADY_FREE errno to NOT_INUSE so that the same errno could + * be used by both free and realloc (since it was the same error). + * 2. fixed coding bug + * + * Revision 1.3 90/02/24 14:23:45 cpcahil + * fixed malloc_warning calls + * + * Revision 1.2 90/02/24 13:59:10 cpcahil + * added function header. + * Modified calls to malloc_warning/malloc_fatal to use new code error messages + * Added support for malloc_errno setting of error codes. + * + * Revision 1.1 90/02/22 23:17:43 cpcahil + * Initial revision + * + */ diff --git a/dmake/dbug/malloc/m_init.c b/dmake/dbug/malloc/m_init.c new file mode 100644 index 000000000000..cef558319340 --- /dev/null +++ b/dmake/dbug/malloc/m_init.c @@ -0,0 +1,121 @@ +/* + * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil). + * You may copy, distribute, and use this software as long as this + * copyright statement is not removed. + */ +#include <stdio.h> +#include "malloc.h" + +/* + * Function: malloc_init() + * + * Purpose: to initialize the pointers and variables use by the + * malloc() debugging library + * + * Arguments: none + * + * Returns: nothing of any value + * + * Narrative: Just initialize all the needed variables. Use mallopt + * to set options taken from the environment. + * + */ +#ifndef lint +static +char rcs_hdr[] = "$Id: m_init.c,v 1.1.1.1 2000-09-22 15:33:26 hr Exp $"; +#endif + +void +malloc_init() +{ + char * cptr; + char * getenv(); + union malloptarg m; + extern char * malloc_data_end; + extern char * malloc_data_start; + extern struct mlist * malloc_end; + extern struct mlist malloc_start; + char * sbrk(); + + /* + * If already initialized... + */ + if( malloc_data_start != (char *) 0) + { + return; + } + + + malloc_data_start = sbrk(0); + malloc_data_end = malloc_data_start; + malloc_start.s.size = 0; + malloc_end = &malloc_start; + + if( (cptr=getenv("MALLOC_WARN")) != NULL ) + { + m.i = atoi(cptr); + (void) mallopt(MALLOC_WARN,m); + } + + if( (cptr=getenv("MALLOC_FATAL")) != NULL) + { + m.i = atoi(cptr); + (void) mallopt(MALLOC_FATAL,m); + } + + if( (cptr=getenv("MALLOC_CKCHAIN")) != NULL) + { + m.i = atoi(cptr); + (void) mallopt(MALLOC_CKCHAIN,m); + } + + if( (cptr=getenv("MALLOC_ERRFILE")) != NULL) + { + m.str = cptr; + (void) mallopt(MALLOC_ERRFILE,m); + } + +} + +/* + * $Log: not supported by cvs2svn $ + * Revision 1.1.1.1 1997/09/22 14:51:11 hjs + * dmake 4.1 orginal sourcen + * + * Revision 1.1.1.1 1997/07/15 16:02:26 dvadura + * dmake gold 4.1.00 initial import + * + * Revision 1.1.1.1 1996/10/27 07:30:14 dvadura + * Dmake 4.1 Initial Import + * + * Revision 1.1.1.1 1996/10/24 05:33:14 dvadura + * Initial import for final release of dmake 4.1 + * + * Revision 1.1 1994/10/06 17:43:11 dvadura + * dmake Release Version 4.0, Initial revision + * + * Revision 1.1 1994/10/06 03:45:20 dvadura + * dmake Release Version 4.0, Initial revision + * + * Revision 1.1 1992/01/24 03:29:03 dvadura + * dmake Version 3.8, Initial revision + * + * Revision 1.6 90/08/29 22:23:21 cpcahil + * fixed mallopt to use a union as an argument. + * + * Revision 1.5 90/08/29 21:22:50 cpcahil + * miscellaneous lint fixes + * + * Revision 1.4 90/05/11 15:53:35 cpcahil + * fixed bug in initialization code. + * + * Revision 1.3 90/05/11 00:13:08 cpcahil + * added copyright statment + * + * Revision 1.2 90/02/24 21:50:20 cpcahil + * lots of lint fixes + * + * Revision 1.1 90/02/24 17:10:53 cpcahil + * Initial revision + * + */ diff --git a/dmake/dbug/malloc/m_perror.c b/dmake/dbug/malloc/m_perror.c new file mode 100644 index 000000000000..ad582acea37c --- /dev/null +++ b/dmake/dbug/malloc/m_perror.c @@ -0,0 +1,111 @@ +/* + * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil). + * You may copy, distribute, and use this software as long as this + * copyright statement is not removed. + */ + +#ifndef lint +static +char rcsid[] = "$Id: m_perror.c,v 1.1.1.1 2000-09-22 15:33:26 hr Exp $"; +#endif + +/* + * malloc errno error strings... + */ + +char *malloc_err_strings[] = +{ + "No errors", + "Malloc chain is corrupted, pointers out of order", + "Malloc chain is corrupted, end before end pointer", + "Pointer is not within malloc area", + "Malloc region does not have valid magic number in header", + "Pointers between this segment and ajoining segments are invalid", + "Data has overrun beyond requested number of bytes", + "Data in free'd area has been modified", + "Data are is not in use (can't be freed or realloced)", + "Unable to get additional memory from the system", + "Pointer within malloc region, but outside of malloc data bounds", + (char *) 0 +}; + +/* + * Function: malloc_perror() + * + * Purpose: to print malloc_errno error message + * + * Arguments: str - string to print with error message + * + * Returns: nothing of any value + * + * Narrative: + */ +void +malloc_perror(str) + char * str; +{ + extern int malloc_errno; + register char * s; + register char * t; + + if( str && *str) + { + for(s=str; *s; s++) + { + /* do nothing */; + } + + (void) write(2,str,(unsigned)(s-str)); + (void) write(2,": ",(unsigned)2); + } + + t = malloc_err_strings[malloc_errno]; + + for(s=t; *s; s++) + { + /* do nothing */; + } + + (void) write(2,t,(unsigned)(s-t)); + + (void) write(2,"\n",(unsigned)1); +} + +/* + * $Log: not supported by cvs2svn $ + * Revision 1.1.1.1 1997/09/22 14:51:11 hjs + * dmake 4.1 orginal sourcen + * + * Revision 1.1.1.1 1997/07/15 16:02:26 dvadura + * dmake gold 4.1.00 initial import + * + * Revision 1.1.1.1 1996/10/27 07:30:14 dvadura + * Dmake 4.1 Initial Import + * + * Revision 1.1.1.1 1996/10/24 05:33:14 dvadura + * Initial import for final release of dmake 4.1 + * + * Revision 1.1 1994/10/06 17:43:12 dvadura + * dmake Release Version 4.0, Initial revision + * + * Revision 1.1 1994/10/06 03:45:21 dvadura + * dmake Release Version 4.0, Initial revision + * + * Revision 1.1 1992/01/24 03:29:04 dvadura + * dmake Version 3.8, Initial revision + * + * Revision 1.5 90/08/29 21:25:08 cpcahil + * added additional error message that was missing (and + * caused a core dump) + * + * Revision 1.4 90/05/11 00:13:08 cpcahil + * added copyright statment + * + * Revision 1.3 90/02/24 21:50:21 cpcahil + * lots of lint fixes + * + * Revision 1.2 90/02/24 17:39:55 cpcahil + * 1. added function header + * 2. added rcs id and log strings. + * + */ diff --git a/dmake/dbug/malloc/makefile b/dmake/dbug/malloc/makefile new file mode 100644 index 000000000000..88395c7b8f6c --- /dev/null +++ b/dmake/dbug/malloc/makefile @@ -0,0 +1,77 @@ +# +# (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil). +# You may copy, distribute, and use this software as long as this +# copyright statement is not removed. +# +# +# This is the Makefile for the malloc debugging library +# +# $Id: makefile,v 1.1.1.1 2000-09-22 15:33:26 hr Exp $ +# +CC=cc +# for System V systems use this CFLAGS +#CFLAGS=-g -DSYS5 +# else for BSD use: +#CFLAGS=-g +LINT=lint +SHARCMD=shar -o mallocshar -l50 -x -a -n Malloclib +SHELL=/bin/sh + +LIB=libmalloc.a + +SRCS= malloc.c \ + free.c \ + realloc.c \ + calloc.c \ + string.c \ + mlc_chk.c \ + mlc_chn.c \ + memory.c \ + tostring.c \ + m_perror.c \ + m_init.c \ + mallopt.c \ + dump.c + +OBJS= malloc.o \ + free.o \ + realloc.o \ + calloc.o \ + string.o \ + mlc_chk.o \ + mlc_chn.o \ + memory.o \ + tostring.o \ + m_perror.o \ + m_init.o \ + mallopt.o \ + dump.o + +TESTS=testmlc testmem + +all: $(LIB) $(TESTS) + +clean: + rm -f $(TESTS) pgm $(LIB) *.o *.ln + +sharfile: + $(SHARCMD) Makefile README patchlevel *.[ch3] + +$(LIB): $(OBJS) + ar ru $(LIB) $(OBJS) + -if test -s /bin/ranlib; then /bin/ranlib $(LIB); else exit 0; fi + -if test -s /usr/bin/ranlib; then /usr/bin/ranlib $(LIB); else exit 0; fi + +testmlc: $(LIB) testmlc.o + $(CC) -o $@ testmlc.o $(LIB) + +testmem: $(LIB) testmem.o + $(CC) -o $@ testmem.o $(LIB) + +lint: + $(LINT) $(CFLAGS) $(SRCS) testmlc.c testmem.c + + +$(OBJS): malloc.h + +tostring.o malloc.o dump.o: tostring.h diff --git a/dmake/dbug/malloc/malloc.3 b/dmake/dbug/malloc/malloc.3 new file mode 100644 index 000000000000..f5e1d2dc0dab --- /dev/null +++ b/dmake/dbug/malloc/malloc.3 @@ -0,0 +1,223 @@ +.TH MALLOC 3 "" "" "1.0" +.ds ]T +.\"/* +.\" * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil). +.\" * You may copy, distribute, and use this software as long as this +.\" * copyright statement is not removed. +.\" */ +.\" $Id: malloc.3,v 1.1.1.1 2000-09-22 15:33:26 hr Exp $ +.SH NAME +malloc \t- debugging malloc library +.SH SYNOPSIS +.ft B +.nf +#include <malloc.h> + +char * calloc(nelem,elsize); +void free(ptr); +char * malloc(size); +int malloc_chain_check(flag); +void malloc_dump(fd); +int mallopt(cmd,val) +char * realloc(ptr,size); + +int cmd,fd,flag; +unsigned elsize,nelem,size; +char * ptr; +union malloptarg val; + +.fi +.ft R +.SH DESCRIPTION +This malloc library is a replacement for the standard library to be used +during software development/debugging. See the standard malloc(3) pages +for more information on the use of the following functions: +.nf +.in +.5i +calloc(), free(), malloc(), realloc() +.in -.5i +.fi +.sp +This library differs from the standard malloc library in the +following ways: +.P +1. Each malloc segment contains a magic number so that free can +verify that the pointer passed points to a valid malloc segment. +.P +2. Each malloc segment is filled with a non-zero pattern so that code that +depends upon malloc segments being null will fail. +.P +3. The size of each segment will be at least 1 byte larger than requested +and the extra bytes will be filled with a non-zero pattern. When free is +called, it will verify that you did not go beyond the number of bytes +you asked for. +.P +4. When a segment is freed, it will be filled with a different non-zero pattern +to ensure that the program doesn't depend upon the use of already freed data. +.P +5. Whenever any of the string or memory functions (str*, b*, mem*) are +called with a pointer that is within the malloc arena, the operation is +checked to verify that it does not overrun the malloced segment. A failure +of this check is considered a "warning level error" (described later) and +is handled accordingly. +.P +7. Run time checking can include verification of the malloc chain at each +and every call to one of the malloc functions or manually by calling the +malloc_chain_check function. +.P +6. When a problem is found, the action taken is specified at runtime by +environment variables or at compile time by the use of the mallopt() +function. +.P +There are two arbitrary levels of errors, warning and fatal, that this +library will detect. They are broken down as follows: +.P +.nf +.in +.25i +Warning messages include: +.sp +.in +.5i +.ti -.25i +Calling free with a bad pointer +.br +.ti -.25i +Calling a bstring/string/memory (3) function which will go beyond +the end of a malloc block. Note that the library function is +not modified to refuse the operation. +.sp +.in -.5i +Fatal errors are: +.in +.5i +.ti -.25i +Detectable corruption to the malloc chain. +.in -.5i +.in -.25i +.P +The error handling for each level (warning or fatal) are specified using +environment variables or mallopt(). The coding for the error handling is +as follows: +.sp +.nf +.in +.5i +.ti -.25i + 0 - continue operations +.ti -.25i + 1 - drop core and exit +.ti -.25i + 2 - just exit +.ti -.25i + 3 - drop core, but continue executing. Core files will +be placed into core.[PID].[counter] i.e: core.00123.001 +.ti -.25i +128 - dump malloc chain and continue +.ti -.25i +129 - dump malloc chain, dump core, and exit +.ti -.25i +130 - dump malloc chain, exit +.ti -.25i +131 - dump malloc chain, dump core, continue processing +.in -.5i +.P +In addition error messages can be placed into an error file. +.P +\fBmalloc_opt\fP() is used to set the malloc debugging options. The +following options can be set: +.br +.sp +.in +.5i +MALLOC_WARN - set the error handling for warning level errors. \fBval.i\fP is +an integer that can contain any one of the following values: +.sp +.in +.5i +M_HANDLE_IGNORE - ignore error +.br +M_HANDLE_ABORT - drop core and exit +.br +M_HANDLE_EXIT - just exit (no core drop) +.br +M_HANDLE_CORE - drop core, but keep on going +.br +.in -.5i +.sp +In addition, M_HANDLE_DUMP may be or'd in to cause a dump of the current +malloc chain. +.br +.sp +MALLOC_FATAL - set the error handling for fatal level errors. \fBval.i\fP is +equivalent to \fBval.i\fP for MALLOC_WARN. +.br +.sp +MALLOC_ERRFILE - set the destination for malloc error messages. \fBval.str\fP +is a pointer to a character string containing the name of the file to be used +for error messages. +.br +.sp +MALLOC_CKCHAIN - set the malloc chain checking flag. If \fBval.i\fP is +non-zero, chain checking at every call to malloc is turned on. +.br +.sp +For example, to set up the session to generate a core file for +every malloc warning, to drop core and exit on a malloc fatal, and +to log all messages to the file "malloc_log" do the following: +.sp +.nf +.in +.5i +#include <malloc.h> +malloc_opt(MALLOC_WARN,131); +malloc_opt(MALLOC_FATAL,1); +malloc_opt(MALLOC_ERRFILE,"malloc_log"); +.in -.5i +.fi +.in -.5i +.sp +\fBmalloc_opt\fP() can be used to set/alter the debugging options at any +time. +.P +\fBmalloc_dump\fP() will dump a table of the malloc arena showing all +allocated/freed segments and the first few bytes of data in each segment. +\fBfd\fP is the file descriptor to write the data to. +.P +\fBmalloc_chain_check\fP() will check the status of the malloc arena. +If \fBflag\fP is non-zero, an error found in the chain will cause a +fatal error. \fBmalloc_chain_check\fP() returns zero when there are no +problems found in the malloc chain, non-zero otherwise. +.SH "ENVIRONMENT VARIABLES" +Environment variables can be used to control error handling, error logging +and malloc chain checking at run time. The following environment variables +are used: +.P +MALLOC_WARN - specifies the error handling for warning errors +.br +MALLOC_FATAL - specifies the error handling for fatal errors +.br +MALLOC_ERRFILE - specifies the error log file for error messages. +.br +MALLOC_CKCHAIN - if 1, turns on malloc chain checking at every call to any +of the malloc functions. +.P +For example, to set up the session to generate a core file for +every malloc warning, to drop core and exit on a malloc fatal, and +to log all messages to the file "malloc_log" do the following: +.sp +.nf +.in +.5i +MALLOC_WARN=131 +MALLOC_FATAL=1 +MALLOC_ERRFILE=malloc_log + +export MALLOC_WARN MALLOC_FATAL MALLOC_ERRFILE +.in -.5i +.fi +.SH WARNINGS +This malloc library and it's associated string and memory functions are +much less efficient than the standard functions due in part to the extra +error checking. You do not want to use this library when generating a +production (i.e. releasable) version of your software. It should only +be used during development and testing. +.SH SEE ALSO +stat(2) +.SH AUTHOR +Conor P. Cahill +Virtual Technologies Incorporated +.sp +uunet!virtech!cpcahil diff --git a/dmake/dbug/malloc/malloc.c b/dmake/dbug/malloc/malloc.c new file mode 100644 index 000000000000..e2f060f1d0ac --- /dev/null +++ b/dmake/dbug/malloc/malloc.c @@ -0,0 +1,672 @@ +/* + * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil). + * You may copy, distribute, and use this software as long as this + * copyright statement is not removed. + */ +#include <stdio.h> +#include <fcntl.h> +#include "malloc.h" +#include "tostring.h" + +/* + * Function: malloc() + * + * Purpose: memory allocator + * + * Arguments: size - size of data area needed + * + * Returns: pointer to allocated area, or NULL if unable + * to allocate addtional data. + * + * Narrative: + * + */ +#ifndef lint +static +char rcs_hdr[] = "$Id: malloc.c,v 1.1.1.1 2000-09-22 15:33:26 hr Exp $"; +#endif + +extern int malloc_checking; +char * malloc_data_start; +char * malloc_data_end; +struct mlist * malloc_end; +int malloc_errfd = 2; +int malloc_errno; +int malloc_fatal_level = M_HANDLE_CORE; +struct mlist malloc_start; +int malloc_warn_level; +void malloc_memset(); + +char * +malloc(size) + unsigned int size; +{ + char * func = "malloc"; + char * getenv(); + void malloc_fatal(); + void malloc_init(); + void malloc_split(); + void malloc_warning(); + unsigned int need; + struct mlist * oldptr; + struct mlist * ptr; + char * sbrk(); + + /* + * If this is the first call to malloc... + */ + if( malloc_data_start == (char *) 0 ) + { + malloc_init(); + } + + /* + * If malloc chain checking is on, go do it. + */ + if( malloc_checking ) + { + (void) malloc_chain_check(1); + } + + /* + * always make sure there is at least on extra byte in the malloc + * area so that we can verify that the user does not overrun the + * data area. + */ + size++; + + /* + * Now look for a free area of memory of size bytes... + */ + oldptr = NULL; + for(ptr = &malloc_start; ; ptr = ptr->next) + { + /* + * Since the malloc chain is a forward only chain, any + * pointer that we get should always be positioned in + * memory following the previous pointer. If this is not + * so, we must have a corrupted chain. + */ + if( ptr ) + { + if( ptr<oldptr ) + { + malloc_errno = M_CODE_CHAIN_BROKE; + malloc_fatal(func); + return(NULL); + } + oldptr = ptr; + } + else if( oldptr != malloc_end ) + { + /* + * This should never happen. If it does, then + * we got a real problem. + */ + malloc_errno = M_CODE_NO_END; + malloc_fatal(func); + return(NULL); + } + + + /* + * if this element is already in use... + */ + if( ptr && ((ptr->flag & M_INUSE) != 0) ) + { + continue; + } + + /* + * if there isn't room for this block.. + */ + if( ptr && (ptr->s.size < size) ) + { + continue; + } + + /* + * If ptr is null, we have run out of memory and must sbrk more + */ + if( ptr == NULL ) + { + need = (size + M_SIZE) * (size > 10*1024 ? 1:2); + if( need < M_BLOCKSIZE ) + { + need = M_BLOCKSIZE; + } + else if( need & (M_BLOCKSIZE-1) ) + { + need &= ~(M_BLOCKSIZE-1); + need += M_BLOCKSIZE; + } + ptr = (struct mlist *) sbrk((int)need); + if( ptr == (struct mlist *) -1 ) + { + malloc_errno = M_CODE_NOMORE_MEM; + malloc_fatal(func); + } + malloc_data_end = sbrk((int)0); + + ptr->prev = oldptr; + ptr->next = (struct mlist *) 0; + ptr->s.size = need - M_SIZE; + ptr->flag = M_MAGIC; + + oldptr->next = ptr; + malloc_end = ptr; + + + } /* if( ptr ==... */ + + /* + * Now ptr points to a memory location that can store + * this data, so lets go to work. + */ + + ptr->r_size = size; /* save requested size */ + ptr->flag |= M_INUSE; + + /* + * split off unneeded data area in this block, if possible... + */ + malloc_split(ptr); + + /* + * re-adjust the requested size so that it is what the user + * actually requested... + */ + + ptr->r_size--; + + /* + * just to make sure that noone is misusing malloced + * memory without initializing it, lets set it to + * all '\01's. We call local_memset() because memset() + * may be checking for malloc'd ptrs and this isn't + * a malloc'd ptr yet. + */ + malloc_memset(ptr->data,M_FILL,(int)ptr->s.size); + + return( ptr->data); + + } /* for(... */ + +} /* malloc(... */ + +/* + * Function: malloc_split() + * + * Purpose: to split a malloc segment if there is enough room at the + * end of the segment that isn't being used + * + * Arguments: ptr - pointer to segment to split + * + * Returns: nothing of any use. + * + * Narrative: + * get the needed size of the module + * round the size up to appropriat boundry + * calculate amount of left over space + * if there is enough left over space + * create new malloc block out of remainder + * if next block is free + * join the two blocks together + * fill new empty block with free space filler + * re-adjust pointers and size of current malloc block + * + * + * + * Mod History: + * 90/01/27 cpcahil Initial revision. + */ +void +malloc_split(ptr) + struct mlist * ptr; +{ + extern struct mlist * malloc_end; + void malloc_join(); + int rest; + int size; + struct mlist * tptr; + + size = ptr->r_size; + + /* + * roundup size to the appropriate boundry + */ + + M_ROUNDUP(size); + + /* + * figure out how much room is left in the array. + * if there is enough room, create a new mlist + * structure there. + */ + + if( ptr->s.size > size ) + { + rest = ptr->s.size - size; + } + else + { + rest = 0; + } + + if( rest > (M_SIZE+M_RND) ) + { + tptr = (struct mlist *) (ptr->data+size); + tptr->prev = ptr; + tptr->next = ptr->next; + tptr->flag = M_MAGIC; + tptr->s.size = rest - M_SIZE; + + /* + * If possible, join this segment with the next one + */ + + malloc_join(tptr, tptr->next,0,0); + + if( tptr->next ) + { + tptr->next->prev = tptr; + } + + malloc_memset(tptr->data,M_FREE_FILL, (int)tptr->s.size); + + ptr->next = tptr; + ptr->s.size = size; + + if( malloc_end == ptr ) + { + malloc_end = tptr; + } + } + +} /* malloc_split(... */ + +/* + * Function: malloc_join() + * + * Purpose: to join two malloc segments together (if possible) + * + * Arguments: ptr - pointer to segment to join to. + * nextptr - pointer to next segment to join to ptr. + * + * Returns: nothing of any values. + * + * Narrative: + * + * Mod History: + * 90/01/27 cpcahil Initial revision. + */ +void +malloc_join(ptr,nextptr, inuse_override, fill_flag) + struct mlist * ptr; + struct mlist * nextptr; + int inuse_override; + int fill_flag; +{ + unsigned int newsize; + + if( ptr && ! (inuse_override || (ptr->flag & M_INUSE)) && + nextptr && ! (nextptr->flag & M_INUSE) && + ((ptr->data+ptr->s.size) == (char *) nextptr) ) + { + if( malloc_end == nextptr ) + { + malloc_end = ptr; + } + ptr->next = nextptr->next; + newsize = nextptr->s.size + M_SIZE; + + /* + * if we are to fill and this segment is in use, + * fill in with M_FILL newly added space... + */ + + if(fill_flag && (ptr->flag & M_INUSE) ) + { + malloc_memset(ptr->data+ptr->s.size, + M_FILL, (int)(nextptr->s.size + M_SIZE)); + } + + ptr->s.size += newsize; + if( ptr->next ) + { + ptr->next->prev = ptr; + } + } + +} /* malloc_join(... */ + + +/* + * The following mess is just to ensure that the versions of these functions in + * the current library are included (to make sure that we don't accidentaly get + * the libc versions. (This is the lazy man's -u ld directive) + */ + +void free(); +int strcmp(); +int memcmp(); +char * realloc(); + +void (*malloc_void_funcs[])() = +{ + free, +}; + +int (*malloc_int_funcs[])() = +{ + strcmp, + memcmp, +}; + +char * (*malloc_char_star_funcs[])() = +{ + realloc, +}; + +/* + * This is malloc's own memset which is used without checking the parameters. + */ + +void +malloc_memset(ptr,byte,len) + char * ptr; + char byte; + int len; +{ + + while(len-- > 0) + { + *ptr++ = byte; + } + +} /* malloc_memset(... */ + +/* + * Function: malloc_fatal() + * + * Purpose: to display fatal error message and take approrpriate action + * + * Arguments: funcname - name of function calling this routine + * + * Returns: nothing of any value + * + * Narrative: + * + * Notes: This routine does not make use of any libc functions to build + * and/or disply the error message. This is due to the fact that + * we are probably at a point where malloc is having a real problem + * and we don't want to call any function that may use malloc. + */ +void +malloc_fatal(funcname) + char * funcname; +{ + char errbuf[128]; + void exit(); + void malloc_err_handler(); + extern char * malloc_err_strings[]; + extern int malloc_errno; + extern int malloc_fatal_level; + char * s; + char * t; + + s = errbuf; + t = "Fatal error: "; + while( *s = *t++) + { + s++; + } + t = funcname; + while( *s = *t++) + { + s++; + } + + t = "(): "; + while( *s = *t++) + { + s++; + } + + t = malloc_err_strings[malloc_errno]; + while( *s = *t++) + { + s++; + } + + *(s++) = '\n'; + + if( write(malloc_errfd,errbuf,(unsigned)(s-errbuf)) != (s-errbuf)) + { + (void) write(2,"I/O error to error file\n",(unsigned)24); + exit(110); + } + malloc_err_handler(malloc_fatal_level); + +} /* malloc_fatal(... */ + +/* + * Function: malloc_warning() + * + * Purpose: to display warning error message and take approrpriate action + * + * Arguments: funcname - name of function calling this routine + * + * Returns: nothing of any value + * + * Narrative: + * + * Notes: This routine does not make use of any libc functions to build + * and/or disply the error message. This is due to the fact that + * we are probably at a point where malloc is having a real problem + * and we don't want to call any function that may use malloc. + */ +void +malloc_warning(funcname) + char * funcname; +{ + char errbuf[128]; + void exit(); + void malloc_err_handler(); + extern char * malloc_err_strings[]; + extern int malloc_errno; + extern int malloc_warn_level; + char * s; + char * t; + + s = errbuf; + t = "Warning: "; + while( *s = *t++) + { + s++; + } + t = funcname; + while( *s = *t++) + { + s++; + } + + t = "(): "; + while( *s = *t++) + { + s++; + } + + t = malloc_err_strings[malloc_errno]; + while( *s = *t++) + { + s++; + } + + *(s++) = '\n'; + + if( write(malloc_errfd,errbuf,(unsigned)(s-errbuf)) != (s-errbuf)) + { + (void) write(2,"I/O error to error file\n",(unsigned)24); + exit(110); + } + + malloc_err_handler(malloc_warn_level); + +} /* malloc_warning(... */ + +/* + * Function: malloc_err_handler() + * + * Purpose: to take the appropriate action for warning and/or fatal + * error conditions. + * + * Arguments: level - error handling level + * + * Returns: nothing of any value + * + * Narrative: + * + * Notes: This routine does not make use of any libc functions to build + * and/or disply the error message. This is due to the fact that + * we are probably at a point where malloc is having a real problem + * and we don't want to call any function that may use malloc. + */ +void +malloc_err_handler(level) +{ + void exit(); + void malloc_dump(); + extern int malloc_errfd; + + if( level & M_HANDLE_DUMP ) + { + malloc_dump(malloc_errfd); + } + + switch( level & ~M_HANDLE_DUMP ) + { + /* + * If we are to drop a core file and exit + */ + case M_HANDLE_ABORT: + (void) abort(); + break; + + /* + * If we are to exit.. + */ + case M_HANDLE_EXIT: + exit(200); + break; + +#ifndef __MSDOS__ + /* + * If we are to dump a core, but keep going on our merry way + */ + case M_HANDLE_CORE: + { + int pid; + + /* + * fork so child can abort (and dump core) + */ + if( (pid = fork()) == 0 ) + { + (void) write(2,"Child dumping core\n", + (unsigned)9); + (void) abort(); + } + + /* + * wait for child to finish dumping core + */ + while( wait((int *)0) != pid) + { + } + + /* + * Move core file to core.pid.cnt so + * multiple cores don't overwrite each + * other. + */ + if( access("core",0) == 0 ) + { + static int corecnt; + char filenam[32]; + filenam[0] = 'c'; + filenam[1] = 'o'; + filenam[2] = 'r'; + filenam[3] = 'e'; + filenam[4] = '.'; + (void)tostring(filenam+5,getpid(), + 5, B_DEC, '0'); + filenam[10] = '.'; + (void)tostring(filenam+11,corecnt++, + 3, B_DEC, '0'); + filenam[14] = '\0'; + (void) unlink(filenam); + if( link("core",filenam) == 0) + { + (void) unlink("core"); + } + } + } +#endif + + + /* + * If we are to just ignore the error and keep on processing + */ + case M_HANDLE_IGNORE: + break; + + } /* switch(... */ + +} /* malloc_err_handler(... */ + +/* + * $Log: not supported by cvs2svn $ + * Revision 1.1.1.1 1997/09/22 14:51:11 hjs + * dmake 4.1 orginal sourcen + * + * Revision 1.1.1.1 1997/07/15 16:02:26 dvadura + * dmake gold 4.1.00 initial import + * + * Revision 1.1.1.1 1996/10/27 07:30:14 dvadura + * Dmake 4.1 Initial Import + * + * Revision 1.1.1.1 1996/10/24 05:33:14 dvadura + * Initial import for final release of dmake 4.1 + * + * Revision 1.1 1994/10/06 17:43:12 dvadura + * dmake Release Version 4.0, Initial revision + * + * Revision 1.1 1994/10/06 03:45:22 dvadura + * dmake Release Version 4.0, Initial revision + * + * Revision 1.1 1992/01/24 03:29:05 dvadura + * dmake Version 3.8, Initial revision + * + * Revision 1.6 90/05/11 00:13:09 cpcahil + * added copyright statment + * + * Revision 1.5 90/02/25 11:01:18 cpcahil + * added support for malloc chain checking. + * + * Revision 1.4 90/02/24 21:50:21 cpcahil + * lots of lint fixes + * + * Revision 1.3 90/02/24 14:51:18 cpcahil + * 1. changed malloc_fatal and malloc_warn to use malloc_errno and be passed + * the function name as a parameter. + * 2. Added several function headers. + * 3. Changed uses of malloc_fatal/warning to conform to new usage. + * + * Revision 1.2 90/02/23 18:05:23 cpcahil + * fixed open of error log to use append mode. + * + * Revision 1.1 90/02/22 23:17:43 cpcahil + * Initial revision + * + */ diff --git a/dmake/dbug/malloc/malloc.h b/dmake/dbug/malloc/malloc.h new file mode 100644 index 000000000000..0f34d49e1b72 --- /dev/null +++ b/dmake/dbug/malloc/malloc.h @@ -0,0 +1,121 @@ +/* + * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil). + * You may copy, distribute, and use this software as long as this + * copyright statement is not removed. + */ +/* + * $Id: malloc.h,v 1.1.1.1 2000-09-22 15:33:26 hr Exp $ + */ +struct mlist +{ + struct mlist * next; /* next entry in chain */ + struct mlist * prev; /* prev entry in chain */ + int flag; /* inuse flag */ + unsigned int r_size; /* requested size */ + union + { + unsigned int size; /* actual size */ + double unused_just_for_alignment; + } s; + char data[4]; +}; + +#define M_SIZE ((int)(char *)((struct mlist *)0)->data) +#define M_RND 0x08 + +#define M_INUSE 0x01 +#define M_MAGIC 0x03156100 + +#define M_BLOCKSIZE (1024*8) + +#define M_FILL '\01' +#define M_FREE_FILL '\02' + +#define M_ROUNDUP(size) {\ + if( size & (M_RND-1) ) \ + { \ + size &= ~(M_RND-1); \ + size += M_RND; \ + } \ + } + +/* + * Malloc warning/fatal error handler defines... + */ +#define M_HANDLE_DUMP 0x80 /* 128 */ +#define M_HANDLE_IGNORE 0 +#define M_HANDLE_ABORT 1 +#define M_HANDLE_EXIT 2 +#define M_HANDLE_CORE 3 + +/* + * Mallopt commands and defaults + */ + +#define MALLOC_WARN 1 /* set malloc warning handling */ +#define MALLOC_FATAL 2 /* set malloc fatal handling */ +#define MALLOC_ERRFILE 3 /* specify malloc error file */ +#define MALLOC_CKCHAIN 4 /* turn on chain checking */ +union malloptarg +{ + int i; + char * str; +}; + +/* + * Malloc warning/fatal error codes + */ + +#define M_CODE_CHAIN_BROKE 1 /* malloc chain is broken */ +#define M_CODE_NO_END 2 /* chain end != endptr */ +#define M_CODE_BAD_PTR 3 /* pointer not in malloc area */ +#define M_CODE_BAD_MAGIC 4 /* bad magic number in header */ +#define M_CODE_BAD_CONNECT 5 /* chain poingers corrupt */ +#define M_CODE_OVERRUN 6 /* data overrun in malloc seg */ +#define M_CODE_REUSE 7 /* reuse of freed area */ +#define M_CODE_NOT_INUSE 8 /* pointer is not in use */ +#define M_CODE_NOMORE_MEM 9 /* no more memory available */ +#define M_CODE_OUTOF_BOUNDS 10 /* gone beyound bounds */ + +void malloc_warning(); +void malloc_fatal(); +void malloc_check_data(); +void malloc_check_str(); +void malloc_verify(); + +/* + * $Log: not supported by cvs2svn $ + * Revision 1.1.1.1 1997/09/22 14:51:11 hjs + * dmake 4.1 orginal sourcen + * + * Revision 1.1.1.1 1997/07/15 16:02:26 dvadura + * dmake gold 4.1.00 initial import + * + * Revision 1.1.1.1 1996/10/27 07:30:14 dvadura + * Dmake 4.1 Initial Import + * + * Revision 1.1.1.1 1996/10/24 05:33:14 dvadura + * Initial import for final release of dmake 4.1 + * + * Revision 1.1 1994/10/06 17:43:13 dvadura + * dmake Release Version 4.0, Initial revision + * + * Revision 1.1 1994/10/06 03:45:22 dvadura + * dmake Release Version 4.0, Initial revision + * + * Revision 1.1 1992/01/24 03:29:06 dvadura + * dmake Version 3.8, Initial revision + * + * Revision 1.4 90/08/29 22:23:38 cpcahil + * fixed mallopt to use a union as an argument. + * + * Revision 1.3 90/05/11 11:04:10 cpcahil + * took out some extraneous lines + * + * Revision 1.2 90/05/11 00:13:09 cpcahil + * added copyright statment + * + * Revision 1.1 90/02/23 07:09:03 cpcahil + * Initial revision + * + */ diff --git a/dmake/dbug/malloc/mallopt.c b/dmake/dbug/malloc/mallopt.c new file mode 100644 index 000000000000..a3151d4730ac --- /dev/null +++ b/dmake/dbug/malloc/mallopt.c @@ -0,0 +1,143 @@ +/* + * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil). + * You may copy, distribute, and use this software as long as this + * copyright statement is not removed. + */ +#include <stdio.h> +#include <fcntl.h> +#include "malloc.h" + +/* + * Function: mallopt() + * + * Purpose: to set options for the malloc debugging library + * + * Arguments: none + * + * Returns: nothing of any value + * + * Narrative: + * + */ + +#ifndef lint +static +char rcs_hdr[] = "$Id: mallopt.c,v 1.1.1.1 2000-09-22 15:33:26 hr Exp $"; +#endif + +int +mallopt(cmd,value) + int cmd; + union malloptarg value; +{ + int i; + extern int malloc_checking; + extern char * malloc_data_start; + extern int malloc_errfd; + extern int malloc_fatal_level; + void malloc_init(); + extern int malloc_warn_level; + register char * s; + + /* + * If not initialized... + */ + if( malloc_data_start == (char *) 0) + { + malloc_init(); + } + + + switch(cmd) + { + case MALLOC_WARN: + malloc_warn_level = value.i; + break; + + case MALLOC_FATAL: + malloc_fatal_level = value.i; + break; + + case MALLOC_CKCHAIN: + malloc_checking = value.i; + break; + + case MALLOC_ERRFILE: + + i = open(value.str,O_CREAT|O_APPEND|O_WRONLY,0666); + if( i == -1 ) + { + (void) write(2, + "Unable to open malloc error file: ", + (unsigned) 34); + for(s=value.str; *s; s++) + { + /* do nothing */; + } + (void) write(2,value.str, + (unsigned)(s-value.str)); + (void) write(2,"\n",(unsigned)1); + } + else + { + if( malloc_errfd != 2 ) + { + (void) close(malloc_errfd); + } + malloc_errfd = i; + } + + break; + + default: + return(1); + } + + return(0); +} + +/* + * $Log: not supported by cvs2svn $ + * Revision 1.1.1.1 1997/09/22 14:51:11 hjs + * dmake 4.1 orginal sourcen + * + * Revision 1.1.1.1 1997/07/15 16:02:26 dvadura + * dmake gold 4.1.00 initial import + * + * Revision 1.1.1.1 1996/10/27 07:30:14 dvadura + * Dmake 4.1 Initial Import + * + * Revision 1.1.1.1 1996/10/24 05:33:14 dvadura + * Initial import for final release of dmake 4.1 + * + * Revision 1.1 1994/10/06 17:43:14 dvadura + * dmake Release Version 4.0, Initial revision + * + * Revision 1.1 1994/10/06 03:45:23 dvadura + * dmake Release Version 4.0, Initial revision + * + * Revision 1.1 1992/01/24 03:29:07 dvadura + * dmake Version 3.8, Initial revision + * + * Revision 1.6 90/08/29 22:23:36 cpcahil + * fixed mallopt to use a union as an argument. + * + * Revision 1.5 90/08/29 21:22:51 cpcahil + * miscellaneous lint fixes + * + * Revision 1.4 90/05/11 00:13:10 cpcahil + * added copyright statment + * + * Revision 1.3 90/02/25 11:03:26 cpcahil + * changed to return int so that it agrees with l libmalloc.a's mallopt() + * + * Revision 1.2 90/02/25 11:01:21 cpcahil + * added support for malloc chain checking. + * + * Revision 1.1 90/02/24 21:50:24 cpcahil + * Initial revision + * + * Revision 1.1 90/02/24 17:10:53 cpcahil + * Initial revision + * + */ diff --git a/dmake/dbug/malloc/memory.c b/dmake/dbug/malloc/memory.c new file mode 100644 index 000000000000..986007b1b77f --- /dev/null +++ b/dmake/dbug/malloc/memory.c @@ -0,0 +1,243 @@ +/* + * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil). + * You may copy, distribute, and use this software as long as this + * copyright statement is not removed. + */ + +#ifndef lint +static +char rcs_hdr[] = "$Id: memory.c,v 1.1.1.1 2000-09-22 15:33:26 hr Exp $"; +#endif + +void malloc_check_data(); + +char * +memccpy(ptr1, ptr2, ch, len) + register char * ptr1; + register char * ptr2; + int len; + int ch; +{ + int check; + register int i; + char * rtn; + + /* + * I know that the assignment could be done in the following, but + * I wanted to perform a check before any assignment, so first I + * determine the length, check the pointers and then do the assignment. + */ + for( i=0; (i < len) && (ptr2[i] != ch); i++) + { + } + if( ptr2[i] == ch ) + { + check = i+1; + } + else + { + check = len; + } + + malloc_check_data("memccpy", ptr1, check); + malloc_check_data("memccpy", ptr2, check); + + /* + * if we found the character... + */ + + if( i < len ) + { + rtn = ptr1+i+1; + i++; + } + else + { + rtn = (char *) 0; + } + + while( i-- ) + { + *(ptr1++) = *(ptr2++); + } + + return(rtn); +} + +char * +memchr(ptr1,ch,len) + register char * ptr1; + register int ch; + int len; +{ + int i; + + for( i=0; (i < len) && (ptr1[i] != (char) ch); i++) + { + } + + malloc_check_data("memchr", ptr1, i); + + if( i < len ) + { + return( ptr1+i ); + } + else + { + return( (char *) 0); + } +} + +char * +memcpy(ptr1, ptr2, len) + register char * ptr1; + register char * ptr2; + register int len; +{ + char * rtn = ptr1; + + malloc_check_data("memcpy", ptr1, len); + malloc_check_data("memcpy", ptr2, len); + + /* + * while the normal memcpy does not guarrantee that it will + * handle overlapping memory correctly, we will try... + */ + if( ptr1 > ptr2 && ptr1 < (ptr2+len)) + { + ptr1 += (len-1); + ptr2 += (len-1); + while( len-- > 0 ) + { + *(ptr1--) = *(ptr2--); + } + } + else + { + while( len-- > 0 ) + { + *(ptr1++) = *(ptr2++); + } + } + + return(rtn); +} + +int +memcmp(ptr1, ptr2, len) + register char * ptr1; + register char * ptr2; + register int len; +{ + malloc_check_data("memcpy", ptr1, len); + malloc_check_data("memcpy", ptr2, len); + + while( --len >= 0 && (*ptr1 == *ptr2) ) + { + ptr1++; + ptr2++; + } + + /* + * If stopped by len, return zero + */ + if( len < 0 ) + { + return(0); + } + + return( *ptr1 - *ptr2 ); +} + +char * +memset(ptr1, ch, len) + register char * ptr1; + register int ch; + register int len; +{ + char * rtn = ptr1; + + malloc_check_data("memcpy", ptr1, len); + + while( len-- ) + { + *(ptr1++) = ch; + } + + return(rtn); +} + +char * +bcopy(ptr2,ptr1,len) + char * ptr2; + char * ptr1; + int len; +{ + return(memcpy(ptr1,ptr2,len)); +} + +char * +bzero(ptr1,len) + char * ptr1; + int len; +{ + return(memset(ptr1,'\0',len)); +} + +int +bcmp(ptr2, ptr1, len) + char * ptr1; + char * ptr2; + int len; +{ + return( memcmp(ptr1,ptr2,len) ); +} + +/* + * $Log: not supported by cvs2svn $ + * Revision 1.1.1.1 1997/09/22 14:51:11 hjs + * dmake 4.1 orginal sourcen + * + * Revision 1.1.1.1 1997/07/15 16:02:26 dvadura + * dmake gold 4.1.00 initial import + * + * Revision 1.1.1.1 1996/10/27 07:30:14 dvadura + * Dmake 4.1 Initial Import + * + * Revision 1.1.1.1 1996/10/24 05:33:14 dvadura + * Initial import for final release of dmake 4.1 + * + * Revision 1.1 1994/10/06 17:43:14 dvadura + * dmake Release Version 4.0, Initial revision + * + * Revision 1.1 1994/10/06 03:45:23 dvadura + * dmake Release Version 4.0, Initial revision + * + * Revision 1.1 1992/01/24 03:29:08 dvadura + * dmake Version 3.8, Initial revision + * + * Revision 1.7 90/08/29 21:27:58 cpcahil + * fixed value of check in memccpy when character was not found. + * + * Revision 1.6 90/07/16 20:06:26 cpcahil + * fixed several minor bugs found with Henry Spencer's string/mem tester + * program. + * + * + * Revision 1.5 90/05/11 15:39:36 cpcahil + * fixed bug in memccpy(). + * + * Revision 1.4 90/05/11 00:13:10 cpcahil + * added copyright statment + * + * Revision 1.3 90/02/24 21:50:29 cpcahil + * lots of lint fixes + * + * Revision 1.2 90/02/24 17:29:41 cpcahil + * changed $Header to $Id so full path wouldnt be included as part of rcs + * id string + * + * Revision 1.1 90/02/22 23:17:43 cpcahil + * Initial revision + * + */ diff --git a/dmake/dbug/malloc/mlc_chk.c b/dmake/dbug/malloc/mlc_chk.c new file mode 100644 index 000000000000..077e675240bf --- /dev/null +++ b/dmake/dbug/malloc/mlc_chk.c @@ -0,0 +1,297 @@ +/* + * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil). + * You may copy, distribute, and use this software as long as this + * copyright statement is not removed. + */ + +#include <stdio.h> +#include "malloc.h" +#include "debug.h" + +#ifndef lint +static +char rcs_hdr[] = "$Id: mlc_chk.c,v 1.1.1.1 2000-09-22 15:33:26 hr Exp $"; +#endif + +extern struct mlist malloc_start; +extern struct mlist * malloc_end; +extern char * malloc_data_start; +extern char * malloc_data_end; + +/* + * Function: malloc_in_arena() + * + * Purpose: to verify address is within malloc arena. + * + * Arguments: ptr - pointer to verify + * + * Returns: TRUE - if pointer is within malloc area + * FALSE - otherwise + * + * Narrative: + * IF pointer is >= malloc area start AND <= malloc area end + * return TRUE + * ELSE + * return FALSE + * + * Mod History: + * 90/01/24 cpcahil Initial revision. + */ +int +malloc_in_arena(ptr) + char * ptr; +{ + extern char * malloc_data_start; + extern char * malloc_data_end; + int rtn = 0; + + if( ptr >= malloc_data_start && ptr <= malloc_data_end ) + { + rtn = 1; + } + + return(rtn); +} + +/* + * Function: malloc_check_str() + * + * Arguments: func - name of function calling this routine + * str - pointer to area to check + * + * Purpose: to verify that if str is within the malloc arena, the data + * it points to does not extend beyond the applicable region. + * + * Returns: Nothing of any use (function is void). + * + * Narrative: + * IF pointer is within malloc arena + * determin length of string + * call malloc_verify() to verify data is withing applicable region + * return + * + * Mod History: + * 90/01/24 cpcahil Initial revision. + * 90/01/29 cpcahil Added code to ignore recursive calls. + */ +void +malloc_check_str(func,str) + char * func; + char * str; +{ + static int layers; + register char * s; + + if( (layers++ == 0) && malloc_in_arena(str) ) + { + for( s=str; *s; s++) + { + } + + malloc_verify(func,str,s-str+1); + } + + layers--; +} + +/* + * Function: malloc_check_strn() + * + * Arguments: func - name of function calling this routine + * str - pointer to area to check + * len - max length of string + * + * Purpose: to verify that if str is within the malloc arena, the data + * it points to does not extend beyond the applicable region. + * + * Returns: Nothing of any use (function is void). + * + * Narrative: + * IF pointer is within malloc arena + * determin length of string + * call malloc_verify() to verify data is withing applicable region + * return + * + * Mod History: + * 90/01/24 cpcahil Initial revision. + * 90/01/29 cpcahil Added code to ignore recursive calls. + * 90/08/29 cpcahil added length (for strn* functions) + */ +void +malloc_check_strn(func,str,len) + char * func; + char * str; + int len; +{ + register int i; + static int layers; + register char * s; + + if( (layers++ == 0) && malloc_in_arena(str) ) + { + for( s=str,i=0; (i < len) && *s; s++) + { + } + + malloc_verify(func,str,s-str+1); + } + + layers--; +} + +/* + * Function: malloc_check_data() + * + * Arguments: func - name of function calling this routine + * ptr - pointer to area to check + * len - length to verify + * + * Purpose: to verify that if ptr is within the malloc arena, the data + * it points to does not extend beyond the applicable region. + * + * Returns: Nothing of any use (function is void). + * + * Narrative: + * IF pointer is within malloc arena + * call malloc_verify() to verify data is withing applicable region + * return + * + * Mod History: + * 90/01/24 cpcahil Initial revision. + * 90/01/29 cpcahil Added code to ignore recursive calls. + */ +void +malloc_check_data(func,ptr,len) + char * func; + char * ptr; + int len; +{ + static int layers; + + if( layers++ == 0 ) + { + DEBUG3(40,"malloc_check_data(%s,0x%x,%d) called...", + func,ptr,len); + if( malloc_in_arena(ptr) ) + { + DEBUG0(10,"pointer in malloc arena, verifying..."); + malloc_verify(func,ptr,len); + } + } + + layers--; +} + +/* + * Function: malloc_verify() + * + * Arguments: func - name of function calling the malloc check routines + * ptr - pointer to area to check + * len - length to verify + * + * Purpose: to verify that the data ptr points to does not extend beyond + * the applicable malloc region. This function is only called + * if it has been determined that ptr points into the malloc arena. + * + * Returns: Nothing of any use (function is void). + * + * Narrative: + * + * Mod History: + * 90/01/24 cpcahil Initial revision. + */ +void +malloc_verify(func,ptr,len) + char * func; + char * ptr; + int len; +{ + extern struct mlist * malloc_end; + extern int malloc_errno; + extern struct mlist malloc_start; + struct mlist * mptr; + + DEBUG3(40,"malloc_verify(%s,0x%x,%d) called...", func,ptr,len); + /* + * Find the malloc block that includes this pointer + */ + mptr = &malloc_start; + while( mptr && + ! (((char *)mptr < ptr) && ((mptr->data+mptr->s.size) > ptr) ) ) + { + mptr = mptr->next; + } + + /* + * if ptr was not in a malloc block, it must be part of + * some direct sbrk() stuff, so just return. + */ + if( ! mptr ) + { + DEBUG1(10,"ptr (0x%x) not found in malloc search", ptr); + return; + } + + /* + * Now we have a valid malloc block that contains the indicated + * pointer. We must verify that it is withing the requested block + * size (as opposed to the real block size which is rounded up to + * allow for correct alignment). + */ + + DEBUG4(60,"Checking 0x%x-0x%x, 0x%x-0x%x", + ptr, ptr+len, mptr->data, mptr->data+mptr->r_size); + + if( (ptr < mptr->data) || ((ptr+len) > (mptr->data+mptr->r_size)) ) + { + DEBUG4(0,"pointer not within region 0x%x-0x%x, 0x%x-0x%x", + ptr, ptr+len, mptr->data, mptr->data+mptr->r_size); + + malloc_errno = M_CODE_OUTOF_BOUNDS; + malloc_warning(func); + } + + return; +} + +/* + * $Log: not supported by cvs2svn $ + * Revision 1.1.1.1 1997/09/22 14:51:11 hjs + * dmake 4.1 orginal sourcen + * + * Revision 1.1.1.1 1997/07/15 16:02:26 dvadura + * dmake gold 4.1.00 initial import + * + * Revision 1.1.1.1 1996/10/27 07:30:14 dvadura + * Dmake 4.1 Initial Import + * + * Revision 1.1.1.1 1996/10/24 05:33:14 dvadura + * Initial import for final release of dmake 4.1 + * + * Revision 1.1 1994/10/06 17:43:15 dvadura + * dmake Release Version 4.0, Initial revision + * + * Revision 1.1 1994/10/06 03:45:24 dvadura + * dmake Release Version 4.0, Initial revision + * + * Revision 1.1 1992/01/24 03:29:09 dvadura + * dmake Version 3.8, Initial revision + * + * Revision 1.5 90/08/29 22:23:48 cpcahil + * added new function to check on strings up to a specified length + * and used it within several strn* functions. + * + * Revision 1.4 90/05/11 00:13:09 cpcahil + * added copyright statment + * + * Revision 1.3 90/02/24 21:50:22 cpcahil + * lots of lint fixes + * + * Revision 1.2 90/02/24 17:29:38 cpcahil + * changed $Header to $Id so full path wouldnt be included as part of rcs + * id string + * + * Revision 1.1 90/02/24 14:57:03 cpcahil + * Initial revision + * + */ diff --git a/dmake/dbug/malloc/mlc_chn.c b/dmake/dbug/malloc/mlc_chn.c new file mode 100644 index 000000000000..3f24333611f9 --- /dev/null +++ b/dmake/dbug/malloc/mlc_chn.c @@ -0,0 +1,188 @@ +/* + * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil). + * You may copy, distribute, and use this software as long as this + * copyright statement is not removed. + */ +#include <stdio.h> +#include <fcntl.h> +#include "malloc.h" + +/* + * Function: malloc_chain_check() + * + * Purpose: to verify malloc chain is intact + * + * Arguments: todo - 0 - just check and return status + * 1 - call malloc_warn if error detected + * + * Returns: 0 - malloc chain intact & no overflows + * other - problems detected in malloc chain + * + * Narrative: + * + * Notes: If todo is non-zero the malloc_warn function, when called + * may not return (i.e. it may exit) + * + */ +#ifndef lint +static +char rcs_hdr[] = "$Id: mlc_chn.c,v 1.1.1.1 2000-09-22 15:33:26 hr Exp $"; +#endif + + +int +malloc_chain_check(todo) + int todo; +{ + char * func = "malloc_chain_check"; + int i; + extern char * malloc_data_start; + extern char * malloc_data_end; + extern struct mlist * malloc_end; + extern int malloc_errno; + extern struct mlist malloc_start; + struct mlist * oldptr; + struct mlist * ptr; + int rtn = 0; + + oldptr = &malloc_start; + for(ptr = malloc_start.next; ; ptr = ptr->next) + { + /* + * Since the malloc chain is a forward only chain, any + * pointer that we get should always be positioned in + * memory following the previous pointer. If this is not + * so, we must have a corrupted chain. + */ + if( ptr ) + { + if(ptr < oldptr ) + { + malloc_errno = M_CODE_CHAIN_BROKE; + if( todo ) + { + malloc_fatal(func); + } + rtn++; + break; + } + oldptr = ptr; + } + else + { + if( oldptr != malloc_end ) + { + /* + * This should never happen. If it does, then + * we got a real problem. + */ + malloc_errno = M_CODE_NO_END; + if( todo ) + { + malloc_fatal(func); + } + rtn++; + } + break; + } + + /* + * verify that ptr is within the malloc region... + * since we started within the malloc chain this should never + * happen. + */ + + if( ((char *)ptr < malloc_data_start) || + ((char *)ptr > malloc_data_end) ) + { + malloc_errno = M_CODE_BAD_PTR; + if( todo ) + { + malloc_fatal(func); + } + rtn++; + break; + } + + /* + * verify magic flag is set + */ + + if( (ptr->flag&M_MAGIC) != M_MAGIC ) + { + malloc_errno = M_CODE_BAD_MAGIC; + if( todo ) + { + malloc_warning(func); + } + rtn++; + continue; + } + + /* + * verify segments are correctly linked together + */ + + if( (ptr->prev && (ptr->prev->next != ptr) ) || + (ptr->next && (ptr->next->prev != ptr) ) || + ((ptr->next == NULL) && (ptr->prev == NULL)) ) + { + malloc_errno = M_CODE_BAD_CONNECT; + if( todo ) + { + malloc_warning(func); + } + rtn++; + continue; + } + + /* + * If this segment is allocated + */ + + if( (ptr->flag & M_INUSE) != 0 ) + { + /* + * verify no overflow of data area + */ + + for(i=ptr->r_size; i < ptr->s.size; i++) + { + if( ptr->data[i] != M_FILL ) + { + malloc_errno = M_CODE_OVERRUN; + if( todo ) + { + malloc_warning(func); + } + rtn++; + break; + } + } + } + else /* it's not allocated so */ + { + /* + * verify no reuse of freed data blocks + */ + + for(i=0; i < ptr->s.size; i++) + { + if( ptr->data[i] != M_FREE_FILL ) + { + malloc_errno = M_CODE_REUSE; + if( todo ) + { + malloc_warning(func); + } + rtn++; + break; + } + } + } + + } /* for(... */ + + return(rtn); + +} /* malloc_chain_check(... */ diff --git a/dmake/dbug/malloc/patchlev b/dmake/dbug/malloc/patchlev new file mode 100644 index 000000000000..00750edc07d6 --- /dev/null +++ b/dmake/dbug/malloc/patchlev @@ -0,0 +1 @@ +3 diff --git a/dmake/dbug/malloc/realloc.c b/dmake/dbug/malloc/realloc.c new file mode 100644 index 000000000000..43bc20fa7841 --- /dev/null +++ b/dmake/dbug/malloc/realloc.c @@ -0,0 +1,233 @@ +/* + * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil). + * You may copy, distribute, and use this software as long as this + * copyright statement is not removed. + */ +#include <stdio.h> +#include "malloc.h" + +/* + * Function: realloc() + * + * Purpose: to re-allocate a data area. + * + * Arguments: cptr - pointer to area to reallocate + * size - size to change area to + * + * Returns: pointer to new area (may be same area) + * + * Narrative: verify pointer is within malloc region + * obtain mlist pointer from cptr + * verify magic number is correct + * verify inuse flag is set + * verify connection to adjoining segments is correct + * save requested size + * round-up size to appropriate boundry + * IF size is bigger than what is in this segment + * try to join next segment to this segment + * IF size is less than what is is this segment + * determine leftover amount of space + * ELSE + * allocate new segment of size bites + * IF allocation failed + * return NULL + * copy previous data to new segment + * free previous segment + * return new pointer + * split of extra space in this segment (if any) + * clear bytes beyound what they had before + * return pointer to data + */ +#ifndef lint +static +char rcs_hdr[] = "$Id: realloc.c,v 1.1.1.1 2000-09-22 15:33:26 hr Exp $"; +#endif + +char * +realloc(cptr,size) + char * cptr; + unsigned int size; +{ + void free(); + char * func = "realloc"; + int i; + char * malloc(); + extern int malloc_checking; + extern struct mlist * malloc_end; + extern int malloc_errno; + extern char * malloc_data_end; + extern char * malloc_data_start; + void malloc_join(); + void malloc_memset(); + void malloc_split(); + char * memcpy(); + char * new_cptr; + struct mlist * ptr; + int r_size; + + /* + * IF malloc chain checking is on, go do it. + */ + if( malloc_checking ) + { + (void) malloc_chain_check(1); + } + + /* + * verify that cptr is within the malloc region... + */ + if( cptr < malloc_data_start || cptr > malloc_data_end ) + { + malloc_errno = M_CODE_BAD_PTR; + malloc_warning(func); + return (NULL); + } + + /* + * convert pointer to mlist struct pointer. To do this we must + * move the pointer backwards the correct number of bytes... + */ + + ptr = (struct mlist *) (cptr - M_SIZE); + + if( (ptr->flag&M_MAGIC) != M_MAGIC ) + { + malloc_errno = M_CODE_BAD_MAGIC; + malloc_warning(func); + return(NULL); + } + + if( ! (ptr->flag & M_INUSE) ) + { + malloc_errno = M_CODE_NOT_INUSE ; + malloc_warning(func); + return(NULL); + } + + if( (ptr->prev && (ptr->prev->next != ptr) ) || + (ptr->next && (ptr->next->prev != ptr) ) || + ((ptr->next == NULL) && (ptr->prev == NULL)) ) + { + malloc_errno = M_CODE_BAD_CONNECT; + malloc_warning(func); + return(NULL); + } + + r_size = ++size; + + M_ROUNDUP(size); + + if( size > ptr->s.size ) + { + malloc_join(ptr,ptr->next,1,1); + } + + if( size > ptr->s.size ) + { + /* + * else we can't combine it, so lets allocate a new chunk, + * copy the data and free the old chunk... + */ + new_cptr = malloc(size); + + if( new_cptr == (char *) 0) + { + return(new_cptr); + } + + if( r_size < ptr->r_size ) + { + i = r_size; + } + else + { + i = ptr->r_size; + } + (void)memcpy(new_cptr,ptr->data,i); + free(cptr); + return(new_cptr); + + } /* else... */ + + /* + * save amount of real data in new segment (this will be used in the + * memset later) and then save requested size of this segment. + */ + + if( ptr->r_size < r_size ) + { + i = ptr->r_size; + } + else + { + i = r_size; + } + + ptr->r_size = r_size; + + /* + * split off extra free space at end of this segment, if possible... + */ + + malloc_split(ptr); + + malloc_memset( ptr->data+i, M_FILL, (int) (ptr->s.size - i)); + + return(ptr->data); + +} /* realloc(... */ + + +/* + * $Log: not supported by cvs2svn $ + * Revision 1.1.1.1 1997/09/22 14:51:11 hjs + * dmake 4.1 orginal sourcen + * + * Revision 1.1.1.1 1997/07/15 16:02:26 dvadura + * dmake gold 4.1.00 initial import + * + * Revision 1.1.1.1 1996/10/27 07:30:14 dvadura + * Dmake 4.1 Initial Import + * + * Revision 1.1.1.1 1996/10/24 05:33:14 dvadura + * Initial import for final release of dmake 4.1 + * + * Revision 1.1 1994/10/06 17:43:17 dvadura + * dmake Release Version 4.0, Initial revision + * + * Revision 1.1 1994/10/06 03:45:26 dvadura + * dmake Release Version 4.0, Initial revision + * + * Revision 1.1 1992/01/24 03:29:11 dvadura + * dmake Version 3.8, Initial revision + * + * Revision 1.8 90/08/29 21:22:52 cpcahil + * miscellaneous lint fixes + * + * Revision 1.7 90/05/11 00:13:10 cpcahil + * added copyright statment + * + * Revision 1.6 90/02/25 11:01:20 cpcahil + * added support for malloc chain checking. + * + * Revision 1.5 90/02/24 21:50:31 cpcahil + * lots of lint fixes + * + * Revision 1.4 90/02/24 17:29:39 cpcahil + * changed $Header to $Id so full path wouldnt be included as part of rcs + * id string + * + * Revision 1.3 90/02/24 17:20:00 cpcahil + * attempt to get rid of full path in rcs header. + * + * Revision 1.2 90/02/24 15:14:20 cpcahil + * 1. added function header + * 2. changed calls to malloc_warning to conform to new usage + * 3. added setting of malloc_errno + * 4. broke up bad pointer determination so that errno's would be more + * descriptive + * + * Revision 1.1 90/02/22 23:17:43 cpcahil + * Initial revision + * + */ diff --git a/dmake/dbug/malloc/string.c b/dmake/dbug/malloc/string.c new file mode 100644 index 000000000000..8ca3a1eee167 --- /dev/null +++ b/dmake/dbug/malloc/string.c @@ -0,0 +1,581 @@ +/* + * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil). + * You may copy, distribute, and use this software as long as this + * copyright statement is not removed. + */ + +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include "malloc.h" + +#ifndef lint +static +char rcs_hdr[] = "$Id: string.c,v 1.1.1.1 2000-09-22 15:33:26 hr Exp $"; +#endif + +int malloc_checking = 0; + +char * +strcat(str1,str2) + register char * str1; + register char * str2; +{ + char * rtn; + int len; + + /* + * check pointers agains malloc region. The malloc* functions + * will properly handle the case where a pointer does not + * point into malloc space. + */ + malloc_checking = 1; + + len = strlen(str2); + malloc_check_str("strcat", str2); + + len += strlen(str1) + 1; + malloc_checking = 0; + + malloc_check_data("strcat", str1, len); + + rtn = str1; + + while( *str1 ) + { + str1++; + } + + while( (*str1 = *str2) != '\0' ) + { + str1++; + str2++; + } + + return(rtn); +} + +char * +strdup(str1) + register char * str1; +{ + char * malloc(); + char * rtn; + register char * str2; + + malloc_check_str("strdup", str1); + + rtn = str2 = malloc((unsigned)strlen(str1)+1); + + if( rtn != (char *) 0) + { + while( (*str2 = *str1) != '\0' ) + { + str1++; + str2++; + } + } + + return(rtn); +} + +char * +strncat(str1,str2,len) + register char * str1; + register char * str2; + register int len; +{ + int len1; + int len2; + char * rtn; + + malloc_check_strn("strncat", str2, len); + + malloc_checking = 1; + + len2 = strlen(str2) + 1; + len1 = strlen(str1); + + malloc_checking = 0; + + + if( (len+1) < len2 ) + { + len1 += len + 1; + } + else + { + len1 += len2; + } + malloc_check_data("strncat", str1, len1); + + rtn = str1; + + while( *str1 ) + { + str1++; + } + + while( len-- && ((*str1++ = *str2++) != '\0') ) + { + } + + if( ! len ) + { + *str1 = '\0'; + } + + return(rtn); +} + +int +strcmp(str1,str2) + register char * str1; + register char * str2; +{ + malloc_check_str("strcmp", str1); + malloc_check_str("strcmp", str2); + + while( *str1 && (*str1 == *str2) ) + { + str1++; + str2++; + } + + + /* + * in order to deal with the case of a negative last char of either + * string when the other string has a null + */ + if( (*str2 == '\0') && (*str1 == '\0') ) + { + return(0); + } + else if( *str2 == '\0' ) + { + return(1); + } + else if( *str1 == '\0' ) + { + return(-1); + } + + return( *str1 - *str2 ); +} + +int +strncmp(str1,str2,len) + register char * str1; + register char * str2; + register int len; +{ + malloc_check_strn("strncmp", str1, len); + malloc_check_strn("strncmp", str2, len); + + while( --len >= 0 && *str1 && (*str1 == *str2) ) + { + str1++; + str2++; + } + + if( len < 0 ) + { + return(0); + } + /* + * in order to deal with the case of a negative last char of either + * string when the other string has a null + */ + if( (*str2 == '\0') && (*str1 == '\0') ) + { + return(0); + } + else if( *str2 == '\0' ) + { + return(1); + } + else if( *str1 == '\0' ) + { + return(-1); + } + + return( *str1 - *str2 ); +} + +char * +strcpy(str1,str2) + register char * str1; + register char * str2; +{ + char * rtn; + int len; + + malloc_checking = 1; + len = strlen(str2) + 1; + malloc_checking = 0; + + malloc_check_data("strcpy", str1, len); + malloc_check_data("strcpy", str2, len); + + rtn = str1; + + while( (*str1++ = *str2++) != '\0') + { + } + + return(rtn); +} + +char * +strncpy(str1,str2,len) + register char * str1; + register char * str2; + register int len; +{ + extern int malloc_checking; + char * rtn; + + malloc_check_data("strncpy", str1, len); + malloc_check_strn("strncpy", str2, len); + + rtn = str1; + + while((len-- > 0) && (*str1++ = *str2++) != '\0') + { + } + while( (len-- > 0) ) + { + *str1++ = '\0'; + } + + return(rtn); +} + +int +strlen(str1) + register char * str1; +{ + register char * s; + + if(! malloc_checking ) + { + malloc_check_str("strlen", str1); + } + + for( s = str1; *s; s++) + { + } + + return( s - str1 ); +} + +char * +strchr(str1,c) + register char * str1; + register int c; +{ + malloc_check_str("strchr", str1); + + while( *str1 && (*str1 != (char) c) ) + { + str1++; + } + + if(*str1 != (char) c) + { + str1 = (char *) 0; + } + + return(str1); +} + +char * +strrchr(str1,c) + register char * str1; + register int c; +{ + register char * rtn = (char *) 0; + + malloc_check_str("strrchr", str1); + + while( *str1 ) + { + if(*str1 == (char) c ) + { + rtn = str1; + } + str1++; + } + + if( *str1 == (char) c) + { + rtn = str1; + } + + return(rtn); +} + +char * +index(str1,c) + char * str1; + char c; +{ + return( strchr(str1,c) ); +} + +char * +rindex(str1,c) + char * str1; + char c; +{ + return( strrchr(str1,c) ); +} + +char * +strpbrk(str1,str2) + register char * str1; + register char * str2; +{ + register char * tmp; + + malloc_check_str("strpbrk", str1); + malloc_check_str("strpbrk", str2); + + while(*str1) + { + for( tmp=str2; *tmp && *tmp != *str1; tmp++) + { + } + if( *tmp ) + { + break; + } + str1++; + } + + if( ! *str1 ) + { + str1 = (char *) 0; + } + + return(str1); +} + +int +strspn(str1,str2) + register char * str1; + register char * str2; +{ + register char * tmp; + char * orig = str1; + + malloc_check_str("strspn", str1); + malloc_check_str("strspn", str2); + + while(*str1) + { + for( tmp=str2; *tmp && *tmp != *str1; tmp++) + { + } + if(! *tmp ) + { + break; + } + str1++; + } + + return( (int) (str1 - orig) ); +} + +int +strcspn(str1,str2) + register char * str1; + register char * str2; +{ + register char * tmp; + char * orig = str1; + + malloc_check_str("strcspn", str1); + malloc_check_str("strcspn", str2); + + while(*str1) + { + for( tmp=str2; *tmp && *tmp != *str1; tmp++) + { + } + if( *tmp ) + { + break; + } + str1++; + } + + return( (int) (str1 - orig) ); +} + +/* + * strtok() source taken from that posted to comp.lang.c by Chris Torek + * in Jan 1990. + */ + +/* + * Copyright (c) 1989 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +/* + * Get next token from string s (NULL on 2nd, 3rd, etc. calls), + * where tokens are nonempty strings separated by runs of + * chars from delim. Writes NULs into s to end tokens. delim need not + * remain constant from call to call. + * + * Modified by cpc: changed variable names to conform with naming + * conventions used in rest of code. Added malloc pointer + * check calls. + */ +char * +strtok(str1, str2) + char * str1; + char * str2; +{ + static char * last; + char * strtoken(); + + if( str1 ) + { + malloc_check_str("strtok", str1); + last = str1; + } + malloc_check_str("strtok", str2); + + return (strtoken(&last, str2, 1)); +} + + +/* + * Get next token from string *stringp, where tokens are (possibly empty) + * strings separated by characters from delim. Tokens are separated + * by exactly one delimiter iff the skip parameter is false; otherwise + * they are separated by runs of characters from delim, because we + * skip over any initial `delim' characters. + * + * Writes NULs into the string at *stringp to end tokens. + * delim will usually, but need not, remain constant from call to call. + * On return, *stringp points past the last NUL written (if there might + * be further tokens), or is NULL (if there are definitely no more tokens). + * + * If *stringp is NULL, strtoken returns NULL. + */ +char * +strtoken(stringp, delim, skip) + register char **stringp; + register char *delim; + int skip; +{ + register char *s; + register char *spanp; + register int c, sc; + char *tok; + + if ((s = *stringp) == NULL) + return (NULL); + + if (skip) { + /* + * Skip (span) leading delimiters (s += strspn(s, delim)). + */ + cont: + c = *s; + for (spanp = delim; (sc = *spanp++) != 0;) { + if (c == sc) { + s++; + goto cont; + } + } + if (c == 0) { /* no token found */ + *stringp = NULL; + return (NULL); + } + } + + /* + * Scan token (scan for delimiters: s += strcspn(s, delim), sort of). + * Note that delim must have one NUL; we stop if we see that, too. + */ + for (tok = s;;) { + c = *s++; + spanp = delim; + do { + if ((sc = *spanp++) == c) { + if (c == 0) + s = NULL; + else + s[-1] = 0; + *stringp = s; + return (tok); + } + } while (sc != 0); + } + /* NOTREACHED */ +} + +/* + * $Log: not supported by cvs2svn $ + * Revision 1.1.1.1 1997/09/22 14:51:11 hjs + * dmake 4.1 orginal sourcen + * + * Revision 1.1.1.1 1997/07/15 16:02:26 dvadura + * dmake gold 4.1.00 initial import + * + * Revision 1.1.1.1 1996/10/27 07:30:14 dvadura + * Dmake 4.1 Initial Import + * + * Revision 1.1.1.1 1996/10/24 05:33:14 dvadura + * Initial import for final release of dmake 4.1 + * + * Revision 1.1 1994/10/06 17:43:17 dvadura + * dmake Release Version 4.0, Initial revision + * + * Revision 1.1 1994/10/06 03:45:27 dvadura + * dmake Release Version 4.0, Initial revision + * + * Revision 1.1 1992/01/24 03:29:13 dvadura + * dmake Version 3.8, Initial revision + * + * Revision 1.7 90/08/29 22:24:19 cpcahil + * added new function to check on strings up to a specified length + * and used it within several strn* functions. + * + * Revision 1.6 90/07/16 20:06:56 cpcahil + * fixed several minor bugs found with Henry Spencer's string/mem function + * tester program. + * + * Revision 1.5 90/06/10 14:59:49 cpcahil + * Fixed a couple of bugs in strncpy & strdup + * + * Revision 1.4 90/05/11 00:13:10 cpcahil + * added copyright statment + * + * Revision 1.3 90/02/24 21:50:32 cpcahil + * lots of lint fixes + * + * Revision 1.2 90/02/24 17:29:40 cpcahil + * changed $Header to $Id so full path wouldnt be included as part of rcs + * id string + * + * Revision 1.1 90/02/22 23:17:44 cpcahil + * Initial revision + * + */ diff --git a/dmake/dbug/malloc/testmem.c b/dmake/dbug/malloc/testmem.c new file mode 100644 index 000000000000..46fba912f8c0 --- /dev/null +++ b/dmake/dbug/malloc/testmem.c @@ -0,0 +1,646 @@ +/* + * This stuff is all stolen (with permission, since it was in the public + * domain) from Henry Spencer's string and memory library. Thanks Henry. + */ + +/* + * Test program for string(3) routines. + * + * Note that at least one Bell Labs implementation of the string + * routines flunks a couple of these tests -- the ones which test + * behavior on "negative" characters. + */ + +#include <stdio.h> +#include <string.h> + +char * index(); +char * rindex(); + +#define STREQ(a, b) (strcmp((a), (b)) == 0) + +char *it = "<UNSET>"; /* Routine name for message routines. */ +int waserror = 0; /* For exit status. */ + +char uctest[] = "\004\203"; /* For testing signedness of chars. */ +int charsigned; /* Result. */ + +/* + - check - complain if condition is not true + */ +void +check(thing, number) +int thing; +int number; /* Test number for error message. */ +{ + if (!thing) { + printf("%s flunked test %d\n", it, number); + waserror = 1; + } +} + +/* + - equal - complain if first two args don't strcmp as equal + */ +void +equal(a, b, number) +char *a; +char *b; +int number; /* Test number for error message. */ +{ + check(a != NULL && b != NULL && STREQ(a, b), number); +} + +char one[50]; +char two[50]; + +#ifdef UNIXERR +#define ERR 1 +#endif +#ifdef BERKERR +#define ERR 1 +#endif +#ifdef ERR +int f; +extern char *sys_errlist[]; +extern int sys_nerr; +extern int errno; +#endif + +/* ARGSUSED */ +main(argc, argv) +int argc; +char *argv[]; +{ + /* + * First, establish whether chars are signed. + */ + if (uctest[0] < uctest[1]) + charsigned = 0; + else + charsigned = 1; + + /* + * Then, do the rest of the work. Split into two functions because + * some compilers get unhappy about a single immense function. + */ + first(); + second(); + + exit((waserror) ? 1 : 0); +} + +first() +{ + /* + * Test strcmp first because we use it to test other things. + */ + it = "strcmp"; + check(strcmp("", "") == 0, 1); /* Trivial case. */ + check(strcmp("a", "a") == 0, 2); /* Identity. */ + check(strcmp("abc", "abc") == 0, 3); /* Multicharacter. */ + check(strcmp("abc", "abcd") < 0, 4); /* Length mismatches. */ + check(strcmp("abcd", "abc") > 0, 5); + check(strcmp("abcd", "abce") < 0, 6); /* Honest miscompares. */ + check(strcmp("abce", "abcd") > 0, 7); + check(strcmp("a\203", "a") > 0, 8); /* Tricky if char signed. */ + if (charsigned) /* Sign-bit comparison. */ + check(strcmp("a\203", "a\003") < 0, 9); + else + check(strcmp("a\203", "a\003") > 0, 9); + check(strcmp("a", "a\203") < 0, 10); /* Tricky if char signed. */ + + /* + * Test strcpy next because we need it to set up other tests. + */ + it = "strcpy"; + check(strcpy(one, "abcd") == one, 1); /* Returned value. */ + equal(one, "abcd", 2); /* Basic test. */ + + (void) strcpy(one, "x"); + equal(one, "x", 3); /* Writeover. */ + equal(one+2, "cd", 4); /* Wrote too much? */ + + (void) strcpy(two, "hi there"); + (void) strcpy(one, two); + equal(one, "hi there", 5); /* Basic test encore. */ + equal(two, "hi there", 6); /* Stomped on source? */ + + (void) strcpy(one, ""); + equal(one, "", 7); /* Boundary condition. */ + + /* + * strcat + */ + it = "strcat"; + (void) strcpy(one, "ijk"); + check(strcat(one, "lmn") == one, 1); /* Returned value. */ + equal(one, "ijklmn", 2); /* Basic test. */ + + (void) strcpy(one, "x"); + (void) strcat(one, "yz"); + equal(one, "xyz", 3); /* Writeover. */ + equal(one+4, "mn", 4); /* Wrote too much? */ + + (void) strcpy(one, "gh"); + (void) strcpy(two, "ef"); + (void) strcat(one, two); + equal(one, "ghef", 5); /* Basic test encore. */ + equal(two, "ef", 6); /* Stomped on source? */ + + (void) strcpy(one, ""); + (void) strcat(one, ""); + equal(one, "", 7); /* Boundary conditions. */ + (void) strcpy(one, "ab"); + (void) strcat(one, ""); + equal(one, "ab", 8); + (void) strcpy(one, ""); + (void) strcat(one, "cd"); + equal(one, "cd", 9); + + /* + * strncat - first test it as strcat, with big counts, then + * test the count mechanism. + */ + it = "strncat"; + (void) strcpy(one, "ijk"); + check(strncat(one, "lmn", 99) == one, 1); /* Returned value. */ + equal(one, "ijklmn", 2); /* Basic test. */ + + (void) strcpy(one, "x"); + (void) strncat(one, "yz", 99); + equal(one, "xyz", 3); /* Writeover. */ + equal(one+4, "mn", 4); /* Wrote too much? */ + + (void) strcpy(one, "gh"); + (void) strcpy(two, "ef"); + (void) strncat(one, two, 99); + equal(one, "ghef", 5); /* Basic test encore. */ + equal(two, "ef", 6); /* Stomped on source? */ + + (void) strcpy(one, ""); + (void) strncat(one, "", 99); + equal(one, "", 7); /* Boundary conditions. */ + (void) strcpy(one, "ab"); + (void) strncat(one, "", 99); + equal(one, "ab", 8); + (void) strcpy(one, ""); + (void) strncat(one, "cd", 99); + equal(one, "cd", 9); + + (void) strcpy(one, "ab"); + (void) strncat(one, "cdef", 2); + equal(one, "abcd", 10); /* Count-limited. */ + + (void) strncat(one, "gh", 0); + equal(one, "abcd", 11); /* Zero count. */ + + (void) strncat(one, "gh", 2); + equal(one, "abcdgh", 12); /* Count and length equal. */ + + /* + * strncmp - first test as strcmp with big counts, then test + * count code. + */ + it = "strncmp"; + check(strncmp("", "", 99) == 0, 1); /* Trivial case. */ + check(strncmp("a", "a", 99) == 0, 2); /* Identity. */ + check(strncmp("abc", "abc", 99) == 0, 3); /* Multicharacter. */ + check(strncmp("abc", "abcd", 99) < 0, 4); /* Length unequal. */ + check(strncmp("abcd", "abc", 99) > 0, 5); + check(strncmp("abcd", "abce", 99) < 0, 6); /* Honestly unequal. */ + check(strncmp("abce", "abcd", 99) > 0, 7); + check(strncmp("a\203", "a", 2) > 0, 8); /* Tricky if '\203' < 0 */ + if (charsigned) /* Sign-bit comparison. */ + check(strncmp("a\203", "a\003", 2) < 0, 9); + else + check(strncmp("a\203", "a\003", 2) > 0, 9); + check(strncmp("abce", "abcd", 3) == 0, 10); /* Count limited. */ + check(strncmp("abce", "abc", 3) == 0, 11); /* Count == length. */ + check(strncmp("abcd", "abce", 4) < 0, 12); /* Nudging limit. */ + check(strncmp("abc", "def", 0) == 0, 13); /* Zero count. */ + + /* + * strncpy - testing is a bit different because of odd semantics + */ + it = "strncpy"; + check(strncpy(one, "abc", 4) == one, 1); /* Returned value. */ + equal(one, "abc", 2); /* Did the copy go right? */ + + (void) strcpy(one, "abcdefgh"); + (void) strncpy(one, "xyz", 2); + equal(one, "xycdefgh", 3); /* Copy cut by count. */ + + (void) strcpy(one, "abcdefgh"); + (void) strncpy(one, "xyz", 3); /* Copy cut just before NUL. */ + equal(one, "xyzdefgh", 4); + + (void) strcpy(one, "abcdefgh"); + (void) strncpy(one, "xyz", 4); /* Copy just includes NUL. */ + equal(one, "xyz", 5); + equal(one+4, "efgh", 6); /* Wrote too much? */ + + (void) strcpy(one, "abcdefgh"); + (void) strncpy(one, "xyz", 5); /* Copy includes padding. */ + equal(one, "xyz", 7); + equal(one+4, "", 8); + equal(one+5, "fgh", 9); + + (void) strcpy(one, "abc"); + (void) strncpy(one, "xyz", 0); /* Zero-length copy. */ + equal(one, "abc", 10); + + (void) strncpy(one, "", 2); /* Zero-length source. */ + equal(one, "", 11); + equal(one+1, "", 12); + equal(one+2, "c", 13); + + (void) strcpy(one, "hi there"); + (void) strncpy(two, one, 9); + equal(two, "hi there", 14); /* Just paranoia. */ + equal(one, "hi there", 15); /* Stomped on source? */ + + /* + * strlen + */ + it = "strlen"; + check(strlen("") == 0, 1); /* Empty. */ + check(strlen("a") == 1, 2); /* Single char. */ + check(strlen("abcd") == 4, 3); /* Multiple chars. */ + + /* + * strchr + */ + it = "strchr"; + check(strchr("abcd", 'z') == NULL, 1); /* Not found. */ + (void) strcpy(one, "abcd"); + check(strchr(one, 'c') == one+2, 2); /* Basic test. */ + check(strchr(one, 'd') == one+3, 3); /* End of string. */ + check(strchr(one, 'a') == one, 4); /* Beginning. */ + check(strchr(one, '\0') == one+4, 5); /* Finding NUL. */ + (void) strcpy(one, "ababa"); + check(strchr(one, 'b') == one+1, 6); /* Finding first. */ + (void) strcpy(one, ""); + check(strchr(one, 'b') == NULL, 7); /* Empty string. */ + check(strchr(one, '\0') == one, 8); /* NUL in empty string. */ + + /* + * index - just like strchr + */ + it = "index"; + check(index("abcd", 'z') == NULL, 1); /* Not found. */ + (void) strcpy(one, "abcd"); + check(index(one, 'c') == one+2, 2); /* Basic test. */ + check(index(one, 'd') == one+3, 3); /* End of string. */ + check(index(one, 'a') == one, 4); /* Beginning. */ + check(index(one, '\0') == one+4, 5); /* Finding NUL. */ + (void) strcpy(one, "ababa"); + check(index(one, 'b') == one+1, 6); /* Finding first. */ + (void) strcpy(one, ""); + check(index(one, 'b') == NULL, 7); /* Empty string. */ + check(index(one, '\0') == one, 8); /* NUL in empty string. */ + + /* + * strrchr + */ + it = "strrchr"; + check(strrchr("abcd", 'z') == NULL, 1); /* Not found. */ + (void) strcpy(one, "abcd"); + check(strrchr(one, 'c') == one+2, 2); /* Basic test. */ + check(strrchr(one, 'd') == one+3, 3); /* End of string. */ + check(strrchr(one, 'a') == one, 4); /* Beginning. */ + check(strrchr(one, '\0') == one+4, 5); /* Finding NUL. */ + (void) strcpy(one, "ababa"); + check(strrchr(one, 'b') == one+3, 6); /* Finding last. */ + (void) strcpy(one, ""); + check(strrchr(one, 'b') == NULL, 7); /* Empty string. */ + check(strrchr(one, '\0') == one, 8); /* NUL in empty string. */ + + /* + * rindex - just like strrchr + */ + it = "rindex"; + check(rindex("abcd", 'z') == NULL, 1); /* Not found. */ + (void) strcpy(one, "abcd"); + check(rindex(one, 'c') == one+2, 2); /* Basic test. */ + check(rindex(one, 'd') == one+3, 3); /* End of string. */ + check(rindex(one, 'a') == one, 4); /* Beginning. */ + check(rindex(one, '\0') == one+4, 5); /* Finding NUL. */ + (void) strcpy(one, "ababa"); + check(rindex(one, 'b') == one+3, 6); /* Finding last. */ + (void) strcpy(one, ""); + check(rindex(one, 'b') == NULL, 7); /* Empty string. */ + check(rindex(one, '\0') == one, 8); /* NUL in empty string. */ +} + +second() +{ + /* + * strpbrk - somewhat like strchr + */ + it = "strpbrk"; + check(strpbrk("abcd", "z") == NULL, 1); /* Not found. */ + (void) strcpy(one, "abcd"); + check(strpbrk(one, "c") == one+2, 2); /* Basic test. */ + check(strpbrk(one, "d") == one+3, 3); /* End of string. */ + check(strpbrk(one, "a") == one, 4); /* Beginning. */ + check(strpbrk(one, "") == NULL, 5); /* Empty search list. */ + check(strpbrk(one, "cb") == one+1, 6); /* Multiple search. */ + (void) strcpy(one, "abcabdea"); + check(strpbrk(one, "b") == one+1, 7); /* Finding first. */ + check(strpbrk(one, "cb") == one+1, 8); /* With multiple search. */ + check(strpbrk(one, "db") == one+1, 9); /* Another variant. */ + (void) strcpy(one, ""); + check(strpbrk(one, "bc") == NULL, 10); /* Empty string. */ + check(strpbrk(one, "") == NULL, 11); /* Both strings empty. */ + +#if 0 + /* + * strstr - somewhat like strchr + */ + it = "strstr"; + check(strstr("abcd", "z") == NULL, 1); /* Not found. */ + check(strstr("abcd", "abx") == NULL, 2); /* Dead end. */ + (void) strcpy(one, "abcd"); + check(strstr(one, "c") == one+2, 3); /* Basic test. */ + check(strstr(one, "bc") == one+1, 4); /* Multichar. */ + check(strstr(one, "d") == one+3, 5); /* End of string. */ + check(strstr(one, "cd") == one+2, 6); /* Tail of string. */ + check(strstr(one, "abc") == one, 7); /* Beginning. */ + check(strstr(one, "abcd") == one, 8); /* Exact match. */ + check(strstr(one, "abcde") == NULL, 9); /* Too long. */ + check(strstr(one, "de") == NULL, 10); /* Past end. */ + check(strstr(one, "") == one+4, 11); /* Finding empty. */ + (void) strcpy(one, "ababa"); + check(strstr(one, "ba") == one+1, 12); /* Finding first. */ + (void) strcpy(one, ""); + check(strstr(one, "b") == NULL, 13); /* Empty string. */ + check(strstr(one, "") == one, 14); /* Empty in empty string. */ + (void) strcpy(one, "bcbca"); + check(strstr(one, "bca") == one+2, 15); /* False start. */ + (void) strcpy(one, "bbbcabbca"); + check(strstr(one, "bbca") == one+1, 16); /* With overlap. */ +#endif + + /* + * strspn + */ + it = "strspn"; + check(strspn("abcba", "abc") == 5, 1); /* Whole string. */ + check(strspn("abcba", "ab") == 2, 2); /* Partial. */ + check(strspn("abc", "qx") == 0, 3); /* None. */ + check(strspn("", "ab") == 0, 4); /* Null string. */ + check(strspn("abc", "") == 0, 5); /* Null search list. */ + + /* + * strcspn + */ + it = "strcspn"; + check(strcspn("abcba", "qx") == 5, 1); /* Whole string. */ + check(strcspn("abcba", "cx") == 2, 2); /* Partial. */ + check(strcspn("abc", "abc") == 0, 3); /* None. */ + check(strcspn("", "ab") == 0, 4); /* Null string. */ + check(strcspn("abc", "") == 3, 5); /* Null search list. */ + + /* + * strtok - the hard one + */ + it = "strtok"; + (void) strcpy(one, "first, second, third"); + equal(strtok(one, ", "), "first", 1); /* Basic test. */ + equal(one, "first", 2); + equal(strtok((char *)NULL, ", "), "second", 3); + equal(strtok((char *)NULL, ", "), "third", 4); + check(strtok((char *)NULL, ", ") == NULL, 5); + (void) strcpy(one, ", first, "); + equal(strtok(one, ", "), "first", 6); /* Extra delims, 1 tok. */ + check(strtok((char *)NULL, ", ") == NULL, 7); + (void) strcpy(one, "1a, 1b; 2a, 2b"); + equal(strtok(one, ", "), "1a", 8); /* Changing delim lists. */ + equal(strtok((char *)NULL, "; "), "1b", 9); + equal(strtok((char *)NULL, ", "), "2a", 10); + (void) strcpy(two, "x-y"); + equal(strtok(two, "-"), "x", 11); /* New string before done. */ + equal(strtok((char *)NULL, "-"), "y", 12); + check(strtok((char *)NULL, "-") == NULL, 13); + (void) strcpy(one, "a,b, c,, ,d"); + equal(strtok(one, ", "), "a", 14); /* Different separators. */ + equal(strtok((char *)NULL, ", "), "b", 15); + equal(strtok((char *)NULL, " ,"), "c", 16); /* Permute list too. */ + equal(strtok((char *)NULL, " ,"), "d", 17); + check(strtok((char *)NULL, ", ") == NULL, 18); + check(strtok((char *)NULL, ", ") == NULL, 19); /* Persistence. */ + (void) strcpy(one, ", "); + check(strtok(one, ", ") == NULL, 20); /* No tokens. */ + (void) strcpy(one, ""); + check(strtok(one, ", ") == NULL, 21); /* Empty string. */ + (void) strcpy(one, "abc"); + equal(strtok(one, ", "), "abc", 22); /* No delimiters. */ + check(strtok((char *)NULL, ", ") == NULL, 23); + (void) strcpy(one, "abc"); + equal(strtok(one, ""), "abc", 24); /* Empty delimiter list. */ + check(strtok((char *)NULL, "") == NULL, 25); + (void) strcpy(one, "abcdefgh"); + (void) strcpy(one, "a,b,c"); + equal(strtok(one, ","), "a", 26); /* Basics again... */ + equal(strtok((char *)NULL, ","), "b", 27); + equal(strtok((char *)NULL, ","), "c", 28); + check(strtok((char *)NULL, ",") == NULL, 29); + equal(one+6, "gh", 30); /* Stomped past end? */ + equal(one, "a", 31); /* Stomped old tokens? */ + equal(one+2, "b", 32); + equal(one+4, "c", 33); + + /* + * memcmp + */ + it = "memcmp"; + check(memcmp("a", "a", 1) == 0, 1); /* Identity. */ + check(memcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */ + check(memcmp("abcd", "abce", 4) < 0, 3); /* Honestly unequal. */ + check(memcmp("abce", "abcd", 4) > 0, 4); + check(memcmp("alph", "beta", 4) < 0, 5); + if (charsigned) /* Sign-bit comparison. */ + check(memcmp("a\203", "a\003", 2) < 0, 6); + else + check(memcmp("a\203", "a\003", 2) > 0, 6); + check(memcmp("abce", "abcd", 3) == 0, 7); /* Count limited. */ + check(memcmp("abc", "def", 0) == 0, 8); /* Zero count. */ + + /* + * memchr + */ + it = "memchr"; + check(memchr("abcd", 'z', 4) == NULL, 1); /* Not found. */ + (void) strcpy(one, "abcd"); + check(memchr(one, 'c', 4) == one+2, 2); /* Basic test. */ + check(memchr(one, 'd', 4) == one+3, 3); /* End of string. */ + check(memchr(one, 'a', 4) == one, 4); /* Beginning. */ + check(memchr(one, '\0', 5) == one+4, 5); /* Finding NUL. */ + (void) strcpy(one, "ababa"); + check(memchr(one, 'b', 5) == one+1, 6); /* Finding first. */ + check(memchr(one, 'b', 0) == NULL, 7); /* Zero count. */ + check(memchr(one, 'a', 1) == one, 8); /* Singleton case. */ + (void) strcpy(one, "a\203b"); + check(memchr(one, 0203, 3) == one+1, 9); /* Unsignedness. */ + + /* + * memcpy + * + * Note that X3J11 says memcpy must work regardless of overlap. + * The SVID says it might fail. + */ + it = "memcpy"; + check(memcpy(one, "abc", 4) == one, 1); /* Returned value. */ + equal(one, "abc", 2); /* Did the copy go right? */ + + (void) strcpy(one, "abcdefgh"); + (void) memcpy(one+1, "xyz", 2); + equal(one, "axydefgh", 3); /* Basic test. */ + + (void) strcpy(one, "abc"); + (void) memcpy(one, "xyz", 0); + equal(one, "abc", 4); /* Zero-length copy. */ + + (void) strcpy(one, "hi there"); + (void) strcpy(two, "foo"); + (void) memcpy(two, one, 9); + equal(two, "hi there", 5); /* Just paranoia. */ + equal(one, "hi there", 6); /* Stomped on source? */ + + (void) strcpy(one, "abcdefgh"); + (void) memcpy(one+1, one, 9); + equal(one, "aabcdefgh", 7); /* Overlap, right-to-left. */ + + (void) strcpy(one, "abcdefgh"); + (void) memcpy(one+1, one+2, 7); + equal(one, "acdefgh", 8); /* Overlap, left-to-right. */ + + (void) strcpy(one, "abcdefgh"); + (void) memcpy(one, one, 9); + equal(one, "abcdefgh", 9); /* 100% overlap. */ + + /* + * memccpy - first test like memcpy, then the search part + * + * The SVID, the only place where memccpy is mentioned, says + * overlap might fail, so we don't try it. Besides, it's hard + * to see the rationale for a non-left-to-right memccpy. + */ + it = "memccpy"; + check(memccpy(one, "abc", 'q', 4) == NULL, 1); /* Returned value. */ + equal(one, "abc", 2); /* Did the copy go right? */ + + (void) strcpy(one, "abcdefgh"); + (void) memccpy(one+1, "xyz", 'q', 2); + equal(one, "axydefgh", 3); /* Basic test. */ + + (void) strcpy(one, "abc"); + (void) memccpy(one, "xyz", 'q', 0); + equal(one, "abc", 4); /* Zero-length copy. */ + + (void) strcpy(one, "hi there"); + (void) strcpy(two, "foo"); + (void) memccpy(two, one, 'q', 9); + equal(two, "hi there", 5); /* Just paranoia. */ + equal(one, "hi there", 6); /* Stomped on source? */ + + (void) strcpy(one, "abcdefgh"); + (void) strcpy(two, "horsefeathers"); + check(memccpy(two, one, 'f', 9) == two+6, 7); /* Returned value. */ + equal(one, "abcdefgh", 8); /* Source intact? */ + equal(two, "abcdefeathers", 9); /* Copy correct? */ + + (void) strcpy(one, "abcd"); + (void) strcpy(two, "bumblebee"); + check(memccpy(two, one, 'a', 4) == two+1, 10); /* First char. */ + equal(two, "aumblebee", 11); + check(memccpy(two, one, 'd', 4) == two+4, 12); /* Last char. */ + equal(two, "abcdlebee", 13); + (void) strcpy(one, "xyz"); + check(memccpy(two, one, 'x', 1) == two+1, 14); /* Singleton. */ + equal(two, "xbcdlebee", 15); + + /* + * memset + */ + it = "memset"; + (void) strcpy(one, "abcdefgh"); + check(memset(one+1, 'x', 3) == one+1, 1); /* Return value. */ + equal(one, "axxxefgh", 2); /* Basic test. */ + + (void) memset(one+2, 'y', 0); + equal(one, "axxxefgh", 3); /* Zero-length set. */ + + (void) memset(one+5, 0, 1); + equal(one, "axxxe", 4); /* Zero fill. */ + equal(one+6, "gh", 5); /* And the leftover. */ + + (void) memset(one+2, 010045, 1); + equal(one, "ax\045xe", 6); /* Unsigned char convert. */ + + /* + * bcopy - much like memcpy + * + * Berklix manual is silent about overlap, so don't test it. + */ + it = "bcopy"; + (void) bcopy("abc", one, 4); + equal(one, "abc", 1); /* Simple copy. */ + + (void) strcpy(one, "abcdefgh"); + (void) bcopy("xyz", one+1, 2); + equal(one, "axydefgh", 2); /* Basic test. */ + + (void) strcpy(one, "abc"); + (void) bcopy("xyz", one, 0); + equal(one, "abc", 3); /* Zero-length copy. */ + + (void) strcpy(one, "hi there"); + (void) strcpy(two, "foo"); + (void) bcopy(one, two, 9); + equal(two, "hi there", 4); /* Just paranoia. */ + equal(one, "hi there", 5); /* Stomped on source? */ + + /* + * bzero + */ + it = "bzero"; + (void) strcpy(one, "abcdef"); + bzero(one+2, 2); + equal(one, "ab", 1); /* Basic test. */ + equal(one+3, "", 2); + equal(one+4, "ef", 3); + + (void) strcpy(one, "abcdef"); + bzero(one+2, 0); + equal(one, "abcdef", 4); /* Zero-length copy. */ + + /* + * bcmp - somewhat like memcmp + */ + it = "bcmp"; + check(bcmp("a", "a", 1) == 0, 1); /* Identity. */ + check(bcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */ + check(bcmp("abcd", "abce", 4) != 0, 3); /* Honestly unequal. */ + check(bcmp("abce", "abcd", 4) != 0, 4); + check(bcmp("alph", "beta", 4) != 0, 5); + check(bcmp("abce", "abcd", 3) == 0, 6); /* Count limited. */ + check(bcmp("abc", "def", 0) == 0, 8); /* Zero count. */ + +#ifdef ERR + /* + * strerror - VERY system-dependent + */ + it = "strerror"; + f = open("/", 1); /* Should always fail. */ + check(f < 0 && errno > 0 && errno < sys_nerr, 1); + equal(strerror(errno), sys_errlist[errno], 2); +#ifdef UNIXERR + equal(strerror(errno), "Is a directory", 3); +#endif +#ifdef BERKERR + equal(strerror(errno), "Permission denied", 3); +#endif +#endif +} diff --git a/dmake/dbug/malloc/testmlc.c b/dmake/dbug/malloc/testmlc.c new file mode 100644 index 000000000000..16e11736cc18 --- /dev/null +++ b/dmake/dbug/malloc/testmlc.c @@ -0,0 +1,176 @@ +/* NOT copyright by SoftQuad Inc. -- msb, 1988 */ +#ifndef lint +static char *SQ_SccsId = "@(#)mtest3.c 1.2 88/08/25"; +#endif +#include <stdio.h> +/* +** looptest.c -- intensive allocator tester +** +** Usage: looptest +** +** History: +** 4-Feb-1987 rtech!daveb +*/ + +# ifdef SYS5 +# define random rand +# else +# include <sys/vadvise.h> +# endif + +# include <stdio.h> +# include <signal.h> +# include <setjmp.h> + +# define MAXITER 1000000 /* main loop iterations */ +# define MAXOBJS 1000 /* objects in pool */ +# define BIGOBJ 90000 /* max size of a big object */ +# define TINYOBJ 80 /* max size of a small object */ +# define BIGMOD 100 /* 1 in BIGMOD is a BIGOBJ */ +# define STATMOD 10000 /* interation interval for status */ + +main( argc, argv ) +int argc; +char **argv; +{ + register int **objs; /* array of objects */ + register int *sizes; /* array of object sizes */ + register int n; /* iteration counter */ + register int i; /* object index */ + register int size; /* object size */ + register int r; /* random number */ + + int objmax; /* max size this iteration */ + int cnt; /* number of allocated objects */ + int nm = 0; /* number of mallocs */ + int nre = 0; /* number of reallocs */ + int nal; /* number of allocated objects */ + int nfre; /* number of free list objects */ + long alm; /* memory in allocated objects */ + long frem; /* memory in free list */ + long startsize; /* size at loop start */ + long endsize; /* size at loop exit */ + long maxiter = 0; /* real max # iterations */ + + extern char end; /* memory before heap */ + char *calloc(); + char *malloc(); + char *sbrk(); + long atol(); + +# ifndef SYS5 + /* your milage may vary... */ + vadvise( VA_ANOM ); +# endif + + if (argc > 1) + maxiter = atol (argv[1]); + if (maxiter <= 0) + maxiter = MAXITER; + + printf("MAXITER %d MAXOBJS %d ", maxiter, MAXOBJS ); + printf("BIGOBJ %d, TINYOBJ %d, nbig/ntiny 1/%d\n", + BIGOBJ, TINYOBJ, BIGMOD ); + fflush( stdout ); + + if( NULL == (objs = (int **)calloc( MAXOBJS, sizeof( *objs ) ) ) ) + { + fprintf(stderr, "Can't allocate memory for objs array\n"); + exit(1); + } + + if( NULL == ( sizes = (int *)calloc( MAXOBJS, sizeof( *sizes ) ) ) ) + { + fprintf(stderr, "Can't allocate memory for sizes array\n"); + exit(1); + } + + /* as per recent discussion on net.lang.c, calloc does not + ** necessarily fill in NULL pointers... + */ + for( i = 0; i < MAXOBJS; i++ ) + objs[ i ] = NULL; + + startsize = sbrk(0) - &end; + printf( "Memory use at start: %d bytes\n", startsize ); + fflush(stdout); + + printf("Starting the test...\n"); + fflush(stdout); + for( n = 0; n < maxiter ; n++ ) + { + if( !(n % STATMOD) ) + { + printf("%d iterations\n", n); + fflush(stdout); + } + + /* determine object of interst and it's size */ + + r = random(); + objmax = ( r % BIGMOD ) ? TINYOBJ : BIGOBJ; + size = r % objmax; + i = r % (MAXOBJS - 1); + + /* either replace the object of get a new one */ + + if( objs[ i ] == NULL ) + { + objs[ i ] = (int *)malloc( size ); + nm++; + } + else + { + /* don't keep bigger objects around */ + if( size > sizes[ i ] ) + { + objs[ i ] = (int *)realloc( objs[ i ], size ); + nre++; + } + else + { + free( objs[ i ] ); + objs[ i ] = (int *)malloc( size ); + nm++; + } + } + + sizes[ i ] = size; + if( objs[ i ] == NULL ) + { + printf("\nCouldn't allocate %d byte object!\n", + size ); + break; + } + } /* for() */ + + printf( "\n" ); + cnt = 0; + for( i = 0; i < MAXOBJS; i++ ) + if( objs[ i ] ) + cnt++; + + printf( "Did %d iterations, %d objects, %d mallocs, %d reallocs\n", + n, cnt, nm, nre ); + printf( "Memory use at end: %d bytes\n", sbrk(0) - &end ); + fflush( stdout ); + + /* free all the objects */ + for( i = 0; i < MAXOBJS; i++ ) + if( objs[ i ] != NULL ) + free( objs[ i ] ); + + endsize = sbrk(0) - &end; + printf( "Memory use after free: %d bytes\n", endsize ); + fflush( stdout ); + + if( startsize != endsize ) + printf("startsize %d != endsize %d\n", startsize, endsize ); + + free( objs ); + free( sizes ); + + malloc_dump(2); + exit( 0 ); +} + diff --git a/dmake/dbug/malloc/tostring.c b/dmake/dbug/malloc/tostring.c new file mode 100644 index 000000000000..5d04a1e7e282 --- /dev/null +++ b/dmake/dbug/malloc/tostring.c @@ -0,0 +1,169 @@ +/* + * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil). + * You may copy, distribute, and use this software as long as this + * copyright statement is not removed. + */ +#include "tostring.h" + +/* + * Function: tostring() + * + * Purpose: to convert an integer to an ascii display string + * + * Arguments: buf - place to put the + * val - integer to convert + * len - length of output field (0 if just enough to hold data) + * base - base for number conversion (only works for base <= 16) + * fill - fill char when len > # digits + * + * Returns: length of string + * + * Narrative: IF fill character is non-blank + * Determine base + * If base is HEX + * add "0x" to begining of string + * IF base is OCTAL + * add "0" to begining of string + * + * While value is greater than zero + * use val % base as index into xlation str to get cur char + * divide val by base + * + * Determine fill-in length + * + * Fill in fill chars + * + * Copy in number + * + * + * Mod History: + * 90/01/24 cpcahil Initial revision. + */ + +#ifndef lint +static +char rcs_hdr[] = "$Id: tostring.c,v 1.1.1.1 2000-09-22 15:33:26 hr Exp $"; +#endif + +#define T_LEN 10 + +int +tostring(buf,val,len,base,fill) + int base; + char * buf; + char fill; + int len; + int val; + +{ + char * bufstart = buf; + int i = T_LEN; + char * xbuf = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + char tbuf[T_LEN]; + + /* + * if we are filling with non-blanks, make sure the + * proper start string is added + */ + if( fill != ' ' ) + { + switch(base) + { + case B_HEX: + *(buf++) = '0'; + *(buf++) = 'x'; + if( len ) + { + len -= 2; + } + break; + case B_OCTAL: + *(buf++) = fill; + if( len ) + { + len--; + } + break; + default: + break; + } + } + + while( val > 0 ) + { + tbuf[--i] = xbuf[val % base]; + val = val / base; + } + + if( len ) + { + len -= (T_LEN - i); + + if( len > 0 ) + { + while(len-- > 0) + { + *(buf++) = fill; + } + } + else + { + /* + * string is too long so we must truncate + * off some characters. We do this the easiest + * way by just incrementing i. This means the + * most significant digits are lost. + */ + while( len++ < 0 ) + { + i++; + } + } + } + + while( i < T_LEN ) + { + *(buf++) = tbuf[i++]; + } + + return( (int) (buf - bufstart) ); + +} /* tostring(... */ + +/* + * $Log: not supported by cvs2svn $ + * Revision 1.1.1.1 1997/09/22 14:51:11 hjs + * dmake 4.1 orginal sourcen + * + * Revision 1.1.1.1 1997/07/15 16:02:26 dvadura + * dmake gold 4.1.00 initial import + * + * Revision 1.1.1.1 1996/10/27 07:30:15 dvadura + * Dmake 4.1 Initial Import + * + * Revision 1.1.1.1 1996/10/24 05:33:14 dvadura + * Initial import for final release of dmake 4.1 + * + * Revision 1.1 1994/10/06 17:43:20 dvadura + * dmake Release Version 4.0, Initial revision + * + * Revision 1.1 1994/10/06 03:45:29 dvadura + * dmake Release Version 4.0, Initial revision + * + * Revision 1.1 1992/01/24 03:29:16 dvadura + * dmake Version 3.8, Initial revision + * + * Revision 1.4 90/05/11 00:13:11 cpcahil + * added copyright statment + * + * Revision 1.3 90/02/24 21:50:33 cpcahil + * lots of lint fixes + * + * Revision 1.2 90/02/24 17:29:42 cpcahil + * changed $Header to $Id so full path wouldnt be included as part of rcs + * id string + * + * Revision 1.1 90/02/22 23:17:44 cpcahil + * Initial revision + * + */ diff --git a/dmake/dbug/malloc/tostring.h b/dmake/dbug/malloc/tostring.h new file mode 100644 index 000000000000..566ae2bedf77 --- /dev/null +++ b/dmake/dbug/malloc/tostring.h @@ -0,0 +1,43 @@ +/* + * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil). + * You may copy, distribute, and use this software as long as this + * copyright statement is not removed. + */ +/* + * $Id: tostring.h,v 1.1.1.1 2000-09-22 15:33:26 hr Exp $ + */ +#define B_BIN 2 +#define B_DEC 10 +#define B_HEX 16 +#define B_OCTAL 8 + +/* + * $Log: not supported by cvs2svn $ + * Revision 1.1.1.1 1997/09/22 14:51:11 hjs + * dmake 4.1 orginal sourcen + * + * Revision 1.1.1.1 1997/07/15 16:02:26 dvadura + * dmake gold 4.1.00 initial import + * + * Revision 1.1.1.1 1996/10/27 07:30:15 dvadura + * Dmake 4.1 Initial Import + * + * Revision 1.1.1.1 1996/10/24 05:33:14 dvadura + * Initial import for final release of dmake 4.1 + * + * Revision 1.1 1994/10/06 17:43:20 dvadura + * dmake Release Version 4.0, Initial revision + * + * Revision 1.1 1994/10/06 03:45:30 dvadura + * dmake Release Version 4.0, Initial revision + * + * Revision 1.1 1992/01/24 03:29:17 dvadura + * dmake Version 3.8, Initial revision + * + * Revision 1.2 90/05/11 00:13:11 cpcahil + * added copyright statment + * + * Revision 1.1 90/02/23 07:09:05 cpcahil + * Initial revision + * + */ diff --git a/dmake/dbug/readme b/dmake/dbug/readme new file mode 100644 index 000000000000..15efc00a7edc --- /dev/null +++ b/dmake/dbug/readme @@ -0,0 +1,13 @@ +This directory contains two public domain debugging packages. + + 1. Fred Fishes DEBUG macros. + 2. Connor P. Cahills malloc library. + +Descriptions of both can be found in their respective sub-directories. dbug +for the DEBUG macros and malloc for the malloc library. I have left the +malloc distribution intact as it comes from the net except for the changes +noted in the _changes file. + +I thank the authors for making them available for others to use. + +-dennis diff --git a/dmake/dmake.c b/dmake/dmake.c new file mode 100644 index 000000000000..941c8a203c23 --- /dev/null +++ b/dmake/dmake.c @@ -0,0 +1,843 @@ +/* RCS $Id: dmake.c,v 1.1.1.1 2000-09-22 15:33:25 hr Exp $ +-- +-- SYNOPSIS +-- The main program. +-- +-- DESCRIPTION +-- +-- dmake [-#dbug_string] [ options ] +-- [ macro definitions ] [ target ... ] +-- +-- This file contains the main command line parser for the +-- make utility. The valid flags recognized are as follows: +-- +-- -f file - use file as the makefile +-- -C file - duplicate console output to file (MSDOS only) +-- -K file - .KEEP_STATE file +-- -#dbug_string - dump out debugging info, see below +-- -v{dfimt} - verbose, print what we are doing, as we do it. +-- +-- options: (can be catenated, ie -irn == -i -r -n) +-- +-- -A - enable AUGMAKE special target mapping +-- -B - enable non-use of TABS to start recipe lines +-- -c - use non-standard comment scanning +-- -d - do not use directory cache +-- -i - ignore errors +-- -n - trace and print, do not execute commands +-- -t - touch, update dates without executing commands +-- -T - do not apply transitive closure on inference rules +-- -r - don't use internal rules +-- -s - do your work silently +-- -S - force Sequential make, overrides -P +-- -q - check if target is up to date. Does not +-- do anything. Returns 0 if up to date, -1 +-- otherwise. +-- -p - print out a version of the makefile +-- -P# - set value of MAXPROCESS +-- -E - define environment strings as macros +-- -e - as -E but done after parsing makefile +-- -u - force unconditional update of target +-- -k - make all independent targets even if errors +-- -V - print out this make version number +-- -M - Microsoft make compatibility, (* disabled *) +-- -h - print out usage info +-- -x - export macro defs to environment +-- -X - ignore #! lines found in makefile +-- +-- NOTE: - #ddbug_string is only availabe for versions of dmake that +-- have been compiled with -DDBUG switch on. Not the case for +-- distributed versions. Any such versions must be linked +-- together with a version of Fred Fish's debug code. +-- +-- NOTE: - in order to compile the code the include file stddef.h +-- must be shipped with the bundled code. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +/* Set this flag to one, and the global variables in vextern.h will not + * be defined as 'extern', instead they will be defined as global vars + * when this module is compiled. */ +#define _DEFINE_GLOBALS_ 1 + +#include "extern.h" +#include "sysintf.h" +#include "patchlvl.h" +#include "version.h" + +#ifndef MSDOS +#define USAGE \ +"Usage:\n%s [-P#] [-{f|K} file] [-{w|W} target ...] [macro[!][[*][+][:]]=value ...]\n" +#define USAGE2 \ +"%s [-v{cdfimtw}] [-ABcdeEghiknpqrsStTuVxX] [target ...]\n" +#else +#define USAGE \ +"Usage:\n%s [-P#] [-{f|C|K} file] [-{w|W} target ...] [macro[!][[*][+][:]]=value ...]\n" +#define USAGE2 \ +"%s [-v{cdfimtw}] [-ABcdeEghiknpqrsStTuVxX] [target ...]\n" +#endif + +/* We don't use va_end at all, so define it out so that it doesn't produce + * lots of "Value not used" warnings. */ +#ifdef va_end +#undef va_end +#endif +#define va_end(expand_to_null) + +/* Make certain that ARG macro is correctly defined. */ +#ifdef ARG +#undef ARG +#endif +#define ARG(a,b) a b + +static char *sccid = "Copyright (c) 1990,...,1997 by WTI Corp."; +static char _warn = TRUE; /* warnings on by default */ + +static void _do_VPATH(); +static void _do_ReadEnvironment(); +#if !defined(__GNUC__) && !defined(__IBMC__) +static void _do_f_flag ANSI((char, char *, char **)); +#else +static void _do_f_flag ANSI((int, char *, char **)); +#endif + +PUBLIC void +main(argc, argv) +int argc; +char **argv; +{ +#ifdef MSDOS + char* std_fil_name = NIL(char); +#endif + + char* fil_name = NIL(char); + char* state_name = NIL(char); + char* whatif = NIL(char); + char* cmdmacs; + char* targets; + FILE* mkfil; + int ex_val; + int m_export; + + DB_ENTER("main"); + + /* Initialize Global variables to their default values */ + Prolog(argc, argv); + Create_macro_vars(); + Catch_signals(Quit); + + Def_macro( "MAKECMD", Pname, M_PRECIOUS|M_NOEXPORT ); + Pname = Basename(Pname); + + DB_PROCESS(Pname); + (void) setvbuf(stdout, NULL, _IOLBF, BUFSIZ); /* stdout line buffered */ + + Continue = FALSE; + Comment = FALSE; + Get_env = FALSE; + Force = FALSE; + Target = FALSE; + If_expand = FALSE; + Listing = FALSE; + Readenv = FALSE; + Rules = TRUE; + Trace = FALSE; + Touch = FALSE; + Check = FALSE; + Microsoft = FALSE; + Makemkf = FALSE; + No_exec = FALSE; + m_export = FALSE; + cmdmacs = NIL(char); + targets = NIL(char); + + Verbose = V_NONE; + Transitive = TRUE; + Nest_level = 0; + Line_number = 0; + Suppress_temp_file = FALSE; + Skip_to_eof = FALSE; + + while( --argc > 0 ) { + register char *p; + char *q; + + if( *(p = *++argv) == '-' ) { + if( p[1] == '\0' ) Fatal("Missing option letter"); + + /* copy options to Buffer for $(MFLAGS), strip 'f' and 'C'*/ + q = strchr(Buffer, '\0'); + while (*p != '\0') { + char c = (*q++ = *p++); + if( c == 'f' || c == 'C' ) q--; + } + + if( *(q-1) == '-' ) + q--; + else + *q++ = ' '; + + *q = '\0'; + + for( p = *argv+1; *p; p++) switch (*p) { + case 'f': + _do_f_flag( 'f', *++argv, &fil_name ); argc--; + break; + +#if defined(MSDOS) && !defined(OS2) + case 'C': + _do_f_flag( 'C', *++argv, &std_fil_name ); argc--; + Hook_std_writes( std_fil_name ); + break; +#endif + + case 'K': + _do_f_flag( 'K', *++argv, &state_name ); argc--; + Def_macro(".KEEP_STATE", state_name, M_EXPANDED|M_PRECIOUS); + break; + + case 'W': + case 'w': { + CELLPTR wif; + _do_f_flag( 'w', *++argv, &whatif ); argc--; + wif = Def_cell(whatif); + wif->ce_attr |= A_WHATIF; + whatif = NIL(char); + + if ( *p == 'W') + break; + } + /*FALLTHRU*/ + + case 'n': + Trace = TRUE; + break; + + case 'k': Continue = TRUE; break; + case 'c': Comment = TRUE; break; + case 'p': Listing = TRUE; break; + case 'r': Rules = FALSE; break; + case 't': Touch = TRUE; break; + case 'q': Check = TRUE; break; + case 'u': Force = TRUE; break; + case 'x': m_export = TRUE; break; + case 'X': No_exec = TRUE; break; + case 'T': Transitive = FALSE; break; + case 'e': Get_env = 'e'; break; + case 'E': Get_env = 'E'; break; + + case 'V': Version(); Quit(NIL(CELL)); break; + case 'A': Def_macro("AUGMAKE", "y", M_EXPANDED); break; + case 'B': Def_macro(".NOTABS", "y", M_EXPANDED); break; + case 'i': Def_macro(".IGNORE", "y", M_EXPANDED); break; + case 's': Def_macro(".SILENT", "y", M_EXPANDED); break; + case 'S': Def_macro(".SEQUENTIAL", "y", M_EXPANDED); break; + case 'g': Def_macro(".IGNOREGROUP","y", M_EXPANDED); break; + case 'd': Def_macro(".DIRCACHE",NIL(char),M_EXPANDED); break; + + case 'v': + if( p[-1] != '-' ) Usage(TRUE); + while( p[1] ) switch( *++p ) { + case 'c': Verbose |= V_DIR_CACHE; break; + case 'd': Verbose |= V_DIR_SET; break; + case 'f': Verbose |= V_FILE_IO; break; + case 'i': Verbose |= V_INFER; break; + case 'm': Verbose |= V_MAKE; break; + case 't': Verbose |= V_LEAVE_TMP; break; + case 'w': Verbose |= V_WARNALL; break; + + default: Usage(TRUE); break; + } + if( !Verbose ) Verbose = V_ALL; + break; + + case 'P': + if( p[1] ) { + Def_macro( "MAXPROCESS", p+1, M_MULTI|M_EXPANDED ); + p += strlen(p)-1; + } + else + Fatal( "Missing number for -P flag" ); + break; + +#ifdef DBUG + case '#': + DB_PUSH(p+1); + p += strlen(p)-1; + break; +#endif + + case 'h': Usage(FALSE); break; + case 0: break; /* lone - */ + default: Usage(TRUE); break; + } + } + else if( (q = strchr(p, '=')) != NIL(char) ) { + cmdmacs = DmStrAdd( cmdmacs, DmStrDup2(p), TRUE ); + Parse_macro( p, (q[-1]!='+')?M_PRECIOUS:M_DEFAULT ); + } + else { + register CELLPTR cp; + targets = DmStrAdd( targets, DmStrDup(p), TRUE ); + Add_prerequisite(Targets, cp = Def_cell(p), FALSE, FALSE); + cp->ce_flag |= F_TARGET; + cp->ce_attr |= A_FRINGE; + Target = TRUE; + } + } + + Def_macro( "MAKEMACROS", cmdmacs, M_PRECIOUS|M_NOEXPORT ); + Def_macro( "MAKETARGETS", targets, M_PRECIOUS|M_NOEXPORT ); + if( cmdmacs != NIL(char) ) FREE(cmdmacs); + if( targets != NIL(char) ) FREE(targets); + + Def_macro( "MFLAGS", Buffer, M_PRECIOUS|M_NOEXPORT ); + Def_macro( "%", "$@", M_PRECIOUS|M_NOEXPORT ); + + if( *Buffer ) Def_macro( "MAKEFLAGS", Buffer+1, M_PRECIOUS|M_NOEXPORT ); + + _warn = FALSE; /* disable warnings for builtin rules */ + ex_val = Target; /* make sure we don't mark any */ + Target = TRUE; /* of the default rules as */ + Make_rules(); /* potential targets */ + _warn = TRUE; + + if( Rules ) { + char *fname; + + if( (mkfil=Search_file("MAKESTARTUP", &fname)) != NIL(FILE) ) { + Parse(mkfil); + Def_macro( "MAKESTARTUP", fname, M_EXPANDED|M_MULTI|M_FORCE ); + } + else + Fatal( "Configuration file `%s' not found", fname ); + } + + Target = ex_val; + + if( Get_env == 'E' ) _do_ReadEnvironment(); + + if( fil_name != NIL(char) ) + mkfil = Openfile( fil_name, FALSE, TRUE ); + else { + /* Search .MAKEFILES dependent list looking for a makefile. + */ + register CELLPTR cp; + + cp = Def_cell( ".MAKEFILES" ); + mkfil = TryFiles(cp->CE_PRQ); + } + + if( mkfil != NIL(FILE) ) { + char *f = Filename(); + char *p; + + if( strcmp(f, "stdin") == 0 ) f = "-"; + p = DmStrAdd( "-f", f, FALSE ); + Def_macro( "MAKEFILE", p, M_PRECIOUS|M_NOEXPORT ); + Parse( mkfil ); + } + else if( !Rules ) + Fatal( "No `makefile' present" ); + + if( Nest_level ) Fatal( "Missing .END for .IF" ); + if( Get_env == 'e' ) _do_ReadEnvironment(); + + _do_VPATH(); /* kludge it up with .SOURCE */ + + if( Listing ) Dump(); /* print out the structures */ + if( Trace ) Glob_attr &= ~A_SILENT; /* make sure we see the trace */ + + if( !Target ) + Fatal( "No target" ); + else { + Test_circle( Root, TRUE ); + Check_circle_dfa(); + } + + if( m_export ) { + int i; + + for( i=0; i<HASH_TABLE_SIZE; ++i ) { + HASHPTR hp = Macs[i]; + + while( hp ) { + if( !(hp->ht_flag & M_NOEXPORT) && hp->ht_value != NIL(char) ) + if( Write_env_string(hp->ht_name, hp->ht_value) != 0 ) + Warning( "Could not export %s", hp->ht_name ); + hp = hp->ht_next; + } + } + } + + if( Buffer != NIL(char) ) {FREE( Buffer ); Buffer = NIL(char);} + if( Trace ) Def_macro(".SEQUENTIAL", "y", M_EXPANDED); + if( Glob_attr & A_SEQ ) Def_macro( "MAXPROCESS", "1", M_EXPANDED|M_FORCE ); + + ex_val = Make_targets(); + + Clear_signals(); + Epilog(ex_val); /* Does not return -- EVER */ +} + + +static void +_do_f_flag( flag, name, fname ) +char flag; +char *name; +char **fname; +{ + if( *fname == NIL(char) ) { + if( name != NIL(char) ) { + *fname = name; + } else + Fatal("No file name for -%c", flag); + } else + Fatal("Only one `-%c file' allowed", flag); +} + + +static void +_do_ReadEnvironment() +{ + t_attr saveattr = Glob_attr; + + Glob_attr |= A_SILENT; + ReadEnvironment(); + Glob_attr = saveattr; +} + + +static void +_do_VPATH() +{ + HASHPTR hp; + char *_rl[2]; + extern char **Rule_tab; + + hp = GET_MACRO("VPATH"); + if( hp == NIL(HASH) ) return; + + _rl[0] = ".SOURCE :^ $(VPATH:s/:/ /)"; + _rl[1] = NIL(char); + + Rule_tab = _rl; + Parse( NIL(FILE) ); +} + + +/* The file table and pointer to the next FREE slot for use by both + Openfile and Closefile. Each open stacks the new file onto the open + file stack, and a corresponding close will close the passed file, and + return the next file on the stack. The maximum number of nested + include files is limited by the value of MAX_INC_DEPTH */ + +static struct { + FILE *file; /* file pointer */ + char *name; /* name of file */ + int numb; /* line number */ +} ftab[ MAX_INC_DEPTH ]; + +static int next_file_slot = 0; + +/* Set the proper macro value to reflect the depth of the .INCLUDE directives + * and the name of the file we are reading. + */ +static void +_set_inc_depth() +{ + char buf[10]; + sprintf( buf, "%d", next_file_slot ); + Def_macro( "INCDEPTH", buf, M_MULTI|M_NOEXPORT ); + Def_macro( "INCFILENAME", + next_file_slot ? ftab[next_file_slot-1].name : "", + M_MULTI|M_NOEXPORT ); +} + + +PUBLIC FILE * +Openfile(name, mode, err)/* +=========================== + This routine opens a file for input or output depending on mode. + If the file name is `-' then it returns standard input. + The file is pushed onto the open file stack. */ +char *name; +int mode; +int err; +{ + FILE *fil; + + DB_ENTER("Openfile"); + + if( name == NIL(char) || !*name ) + if( !err ) + DB_RETURN(NIL(FILE)); + else + Fatal( "Openfile: NIL filename" ); + + if( next_file_slot == MAX_INC_DEPTH ) + Fatal( "Too many open files. Max nesting level is %d.", MAX_INC_DEPTH); + + DB_PRINT( "io", ("Opening file [%s], in slot %d", name, next_file_slot) ); + + if( strcmp("-", name) == 0 ) { + name = "stdin"; + fil = stdin; + } + else + fil = fopen( name, mode ? "w":"r" ); + + if( Verbose & V_FILE_IO ) + printf( "%s: Openning [%s] for %s", Pname, name, mode?"write":"read" ); + + if( fil == NIL(FILE) ) { + if( Verbose & V_FILE_IO ) printf( " (fail)\n" ); + if( err ) + Fatal( mode ? "Cannot open file %s for write" : "File %s not found", + name ); + } + else { + if( Verbose & V_FILE_IO ) printf( " (success)\n" ); + ftab[next_file_slot].file = fil; + ftab[next_file_slot].numb = Line_number; + ftab[next_file_slot++].name = DmStrDup(name); + Line_number = 0; + _set_inc_depth(); + } + + DB_RETURN(fil); +} + + +PUBLIC FILE * +Closefile()/* +============= + This routine is used to close the last file opened. This forces make + to open files in a last open first close fashion. It returns the + file pointer to the next file on the stack, and NULL if the stack is empty.*/ +{ + DB_ENTER("Closefile"); + + if( !next_file_slot ) + DB_RETURN( NIL(FILE) ); + + if( ftab[--next_file_slot].file != stdin ) { + DB_PRINT( "io", ("Closing file in slot %d", next_file_slot) ); + + if( Verbose & V_FILE_IO ) + printf( "%s: Closing [%s]\n", Pname, ftab[next_file_slot].name ); + + fclose( ftab[next_file_slot].file ); + FREE( ftab[next_file_slot].name ); + } + + _set_inc_depth(); + + if( next_file_slot > 0 ) { + Line_number = ftab[next_file_slot].numb; + DB_RETURN( ftab[next_file_slot-1].file ); + } + else + Line_number = 0; + + DB_RETURN( NIL(FILE) ); +} + + +PUBLIC FILE * +Search_file( macname, rname ) +char *macname; +char **rname; +{ + HASHPTR hp; + FILE *fil = NIL(FILE); + char *fname; + char *ename = NIL(char); + + /* order of precedence is: + * + * MACNAME from command line (precious is marked) + * ... via MACNAME:=filename definition. + * MACNAME from environment + * MACNAME from builtin rules (not precious) + */ + + if( (hp = GET_MACRO(macname)) != NIL(HASH) ) + ename = fname = Expand(hp->ht_value); + + if( hp->ht_flag & M_PRECIOUS ) fil = Openfile(fname, FALSE, FALSE); + + if( fil == NIL(FILE) ) { + fname=Expand(Read_env_string(macname)); + if( (fil = Openfile(fname, FALSE, FALSE)) != NIL(FILE) ) FREE(ename); + } + + if( fil == NIL(FILE) && hp != NIL(HASH) ) + fil = Openfile(fname=ename, FALSE, FALSE); + + if( rname ) *rname = fname; + + return(fil); +} + + +PUBLIC char * +Filename()/* +============ + Return name of file on top of stack */ +{ + return( next_file_slot==0 ? NIL(char) : ftab[next_file_slot-1].name ); +} + + +PUBLIC int +Nestlevel()/* +============= + Return the file nesting level */ +{ + return( next_file_slot ); +} + + +PUBLIC FILE * +TryFiles(lp) +LINKPTR lp; +{ + FILE *mkfil = NIL(FILE); + + if( lp != NIL(LINK) ) { + int s_n, s_t, s_q; + + s_n = Trace; + s_t = Touch; + s_q = Check; + + Trace = Touch = Check = FALSE; + Makemkf = Wait_for_completion = TRUE; + mkfil = NIL(FILE); + + for(; lp != NIL(LINK) && mkfil == NIL(FILE); lp=lp->cl_next) { + if( lp->cl_prq->ce_attr & A_FRINGE ) continue; + + mkfil = Openfile( lp->cl_prq->CE_NAME, FALSE, FALSE ); + + if( mkfil == NIL(FILE) && + Make(lp->cl_prq, NIL(CELL)) != -1 ) + mkfil = Openfile( lp->cl_prq->CE_NAME, FALSE, FALSE ); + } + + Trace = s_n; + Touch = s_t; + Check = s_q; + Makemkf = Wait_for_completion = FALSE; + } + + return(mkfil); +} + + +/* +** print error message from variable arg list +*/ + +static int errflg = TRUE; +static int warnflg = FALSE; + +static void +errargs(fmt, args) +char *fmt; +va_list args; +{ + int warn = _warn && warnflg && !(Glob_attr & A_SILENT); + + if( errflg || warn ) { + char *f = Filename(); + + fprintf( stderr, "%s: ", Pname ); + if( f != NIL(char) ) fprintf(stderr, "%s: line %d: ", f, Line_number); + + if( errflg ) + fprintf(stderr, "Error -- "); + else if( warn ) + fprintf(stderr, "Warning -- "); + + vfprintf( stderr, fmt, args ); + putc( '\n', stderr ); + if( errflg && !Continue ) Quit( NIL(CELL) ); + } +} + + +/* +** Print error message and abort +*/ +PUBLIC void +#ifndef __MWERKS__ +Fatal(ARG(char *,fmt), ARG(va_alist_type,va_alist)) +#else +Fatal(char * fmt, ...) +#endif +DARG(char *,fmt) +DARG(va_alist_type,va_alist) +{ + va_list args; + + va_start(args, fmt); + Continue = FALSE; + errargs(fmt, args); + va_end(args); +} + +/* +** error message and exit (unless -k) +*/ +PUBLIC void +#ifndef __MWERKS__ +Error(ARG(char *,fmt), ARG(va_alist_type,va_alist)) +#else +Error(char * fmt, ...) +#endif +DARG(char *,fmt) +DARG(va_alist_type,va_alist) +{ + va_list args; + + va_start(args, fmt); + errargs(fmt, args); + va_end(args); +} + + +/* +** non-fatal message +*/ +PUBLIC void +#ifndef __MWERKS__ +Warning(ARG(char *,fmt), ARG(va_alist_type,va_alist)) +#else +Warning(char * fmt , ...) +#endif +DARG(char *,fmt) +DARG(va_alist_type,va_alist) +{ + va_list args; + + va_start(args, fmt); + warnflg = TRUE; + errflg = FALSE; + errargs(fmt, args); + errflg = TRUE; + warnflg = FALSE; + va_end(args); +} + + +PUBLIC void +No_ram() +{ + Fatal( "No more memory" ); +} + + +PUBLIC void +Usage( eflag ) +int eflag; +{ + register char *p; + char *fill; + + fill = DmStrDup(Pname); + for(p=fill; *p; p++) *p=' '; + + if( eflag ) { + fprintf(stderr, USAGE, Pname); + fprintf(stderr, USAGE2, fill); + } + else { + printf(USAGE, Pname); + printf(USAGE2, fill); + puts(" -P# - set max number of child processes for parallel make"); + puts(" -f file - use file as the makefile"); +#ifdef MSDOS + puts(" -C [+]file - duplicate console output to file, ('+' => append)"); +#endif + puts(" -K file - use file as the .KEEP_STATE file"); + puts(" -w target - show what you would do if 'target' were out of date"); + puts(" -W target - rebuild pretending that 'target' is out of date"); + puts(" -v{cdfimtw}- verbose, indicate what we are doing, (-v => -vcdfimtw)"); + puts(" c => dump directory cache info only" ); + puts(" d => dump change of directory info only" ); + puts(" f => dump file open/close info only" ); + puts(" i => dump inference information only" ); + puts(" m => dump make of target information only" ); + puts(" t => keep temporary files when done" ); + puts(" w => issue non-essential warnings\n" ); + + puts("Options: (can be catenated, ie -irn == -i -r -n)"); + puts(" -A - enable AUGMAKE special target mapping"); + puts(" -B - enable the use of spaces instead of tabs to start recipes"); + puts(" -c - use non standard comment scanning"); + puts(" -d - do not use directory cache"); + puts(" -E - define environment strings as macros"); + puts(" -e - same as -E but done after parsing makefile"); + puts(" -g - disable the special meaning of [ ... ] for group recipes"); + puts(" -h - print out usage info"); + puts(" -i - ignore errors"); + puts(" -k - make independent targets, even if errors"); + puts(" -n - trace and print, do not execute commands"); + puts(" -p - print out a version of the makefile"); + puts(" -q - check if target is up to date. Does not do"); + puts(" anything. Returns 0 if up to date, 1 otherwise"); + puts(" -r - don't use internal rules"); + puts(" -s - do your work silently"); + puts(" -S - disable parallel (force sequential) make, overrides -P"); + puts(" -t - touch, update time stamps without executing commands"); + puts(" -T - do not apply transitive closure on inference rules"); + puts(" -u - force unconditional update of target"); + puts(" -V - print out version number"); + puts(" -x - export macro values to environment"); + puts(" -X - ignore #! lines at start of makefile"); + } + + Quit(NIL(CELL)); +} + + +PUBLIC void +Version() +{ + extern char **Rule_tab; + char **p; + + printf("%s - %s, ", Pname, sccid); + printf("Version %s, PL %d\n\n", VERSION, PATCHLEVEL); + + puts("Default Configuration:"); + for (p=Rule_tab; *p != NIL(char); p++) + printf("\t%s\n", *p); + + printf("\n"); +printf("Please read the file readme/release for the latest release notes.\n"); +#if 0 +printf("\n"); +printf("Please support the DMAKE Reference Manual project. See the file\n"); +printf("readme/release for additional information on where to send contributions.\n"); +printf("Or, send mail to dvadura@plg.uwaterloo.ca for additional information if the\n"); +printf("above file is not readily available.\n"); +#endif +} diff --git a/dmake/dmake.h b/dmake/dmake.h new file mode 100644 index 000000000000..69240f5b2695 --- /dev/null +++ b/dmake/dmake.h @@ -0,0 +1,200 @@ +/* RCS $Id: dmake.h,v 1.1.1.1 2000-09-22 15:33:25 hr Exp $ +-- +-- SYNOPSIS +-- Global defines for dmake. +-- +-- DESCRIPTION +-- All the interesting bits and flags that dmake uses are defined here. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef _DMAKE_INCLUDED_ +#define _DMAKE_INCLUDED_ + +#define MAX_INC_DEPTH 10 /* max of ten nested include files */ +#define MAX_COND_DEPTH 20 /* max nesting level of conditionals */ +#define ERROR_EXIT_VALUE 255 /* return code of aborted make */ +#define CONTINUATION_CHAR '\\' /* line continuation \<nl> */ +#define DEF_ESCAPE_CHAR '\\' /* escape char for used chars */ +#define ESCAPE_CHAR *Escape_char +#define COMMENT_CHAR '#' /* start of comment chars */ +#define TGT_DEP_SEP ':' /* separator for targets and dependents */ +#define CONDSTART '.' /* start of conditional token eg .IF */ +#define DEF_MAKE_PNAME "dmake"/* default name to use as name of make */ + + +/* ............... Hashing function constants ......................... */ +#define HASH_TABLE_SIZE 200 /* See hash.c for description */ + + +/* Bit flags for cells and macro definitions. */ +#define M_DEFAULT 0x0000 /* default flag value */ +#define M_MARK 0x0001 /* mark for circularity checks */ +#define M_PRECIOUS 0x0002 /* keep macro, same as A_PRE... */ +#define M_MULTI 0x0004 /* multiple redefinitions ok! */ +#define M_EXPANDED 0x0008 /* macro has been assigned */ +#define M_USED 0x0010 /* macro has been expanded */ +#define M_LITERAL 0x0020 /* don't strip w/s on macro def */ +#define M_NOEXPORT 0x0040 /* don't export macro for -x */ +#define M_FORCE 0x0080 /* Force a macro redefinition */ +#define M_PUSH 0x0100 /* Push previous macro defintn */ +#define M_INIT 0x0200 /* Macro defined initially */ +#define M_VAR_BIT 0x1000 /* macro bit variable */ +#define M_VAR_CHAR 0x2000 /* macro char variable */ +#define M_VAR_STRING 0x4000 /* macro string variable */ +#define M_VAR_INT 0x8000 /* macro integer variable */ + +#define M_VAR_MASK 0xf000 /* macro variable mask */ + + + +/* Global and target attribute flag definitions. + * If you change the values of these or re-order them make appropriate changes + * in dump.c so that the output of dmake -p matches the attribute info for a + * target. */ + +#define A_DEFAULT 0x00000 /* default flag value */ +#define A_PRECIOUS 0x00001 /* object is precious */ +#define A_SILENT 0x00002 /* don't echo commands */ +#define A_LIBRARY 0x00004 /* target is an archive */ +#define A_EPILOG 0x00008 /* insert shell epilog code */ +#define A_PROLOG 0x00010 /* insert shell prolog code */ +#define A_IGNORE 0x00020 /* ignore errors */ +#define A_SYMBOL 0x00040 /* lib member is a symbol */ +#define A_NOINFER 0x00080 /* no trans closure from cell */ +#define A_UPDATEALL 0x00100 /* all targets of rule modified */ +#define A_SEQ 0x00200 /* sequential make attribute */ +#define A_SETDIR 0x00400 /* cd to dir when making target */ +#define A_SHELL 0x00800 /* run the recipe using a shell */ +#define A_SWAP 0x01000 /* swap on exec. */ +#define A_MKSARGS 0x02000 /* use MKS argument swapping */ +#define A_PHONY 0x04000 /* .PHONY attribute */ +#define A_NOSTATE 0x08000 /* don't track state for me */ +#define A_IGNOREGROUP 0x10000 /* Ignore group recipe */ +#define A_EXECUTE 0x20000 /* execute this recipe under -n */ +#define A_ERRREMOVE 0x40000 /* remove this target if error */ +#define MAX_ATTR A_ERRREMOVE /* highest valid attribute */ +#define A_LIBRARYM 0x80000 /* target is an archive member */ +#define A_FRINGE 0x100000 /* cell is on the fringe */ +#define A_COMPOSITE 0x200000 /* member of lib(targ) name */ +#define A_FFNAME 0x400000 /* if set, free ce_fname in stat*/ +#define A_UPDATED 0x800000 /* Used to mark cell as updated */ +#define A_ROOT 0x01000000 /* True if it is a root prereq */ +#define A_GROUP 0x02000000 /* True if rule is to be a group*/ +#define A_WHATIF 0x04000000 /* used for WHATIF tests */ +#define A_POOL 0x08000000 /* used for directory pool */ +#define A_ERROR 0x10000000 /* used to halt construction */ +#define A_FIRST 0x20000000 /* used for .INCLUDE termination*/ + + +/* Global and target bit flag definitions */ + +#define F_DEFAULT 0x0000 /* default flag value */ +#define F_MARK 0x0001 /* circularity check mark */ +#define F_MULTI 0x0002 /* multiple rules for target */ +#define F_SINGLE 0x0004 /* exec rules one/prerequisite */ +#define F_TARGET 0x0008 /* marks a target */ +#define F_RULES 0x0010 /* indicates target has rules */ +#define F_GROUP 0x0020 /* indicates that rules are to */ + /* fed to the shell as a group */ + +#define F_TRANS 0x0040 /* same as F_STAT not used tgthr*/ +#define F_STAT 0x0040 /* target already stated */ +#define F_VISITED 0x0080 /* target scheduled for make */ +#define F_USED 0x0080 /* used in rulparse.c */ +#define F_SPECIAL 0x0100 /* marks a special target */ +#define F_DFA 0x0200 /* bit for marking added DFA */ +#define F_EXPLICIT 0x0400 /* explicit target in makefile */ +#define F_PERCENT 0x0800 /* marks a target as a % rule */ +#define F_REMOVE 0x1000 /* marks an intermediate target */ +#define F_MAGIC 0x2000 /* marks a magic target */ +#define F_INFER 0x4000 /* target is result of inference*/ +#define F_MADE 0x8000 /* target is manufactured */ + + +/* Definitions for the Parser states */ +#define NORMAL_SCAN 0 /* normal processing state */ +#define RULE_SCAN 1 /* scan of rule text */ + +/* definitions for macro operator types */ +#define M_OP_EQ 1 /* macro operation is '=' 0000 0001 */ +#define M_OP_CL 3 /* macro operation is ':=' 0000 0011 */ +#define M_OP_PL 5 /* macro operation is '+=' 0000 0101 */ +#define M_OP_DF 9 /* macro operation is '*=' 0000 1001 */ +#define M_OP_PLCL 7 /* macro operation is '+:=' 0000 0111 */ +#define M_OP_DFCL 11 /* macro operation is '*:=' 0000 1011 */ +#define M_OP_CM 17 /* macro operation is '?=' 0001 0001 */ +#define M_OP_SI 32 /* macro operation is '!' 0010 ---- */ + +/* definitions for rule operator types */ +#define R_OP_CL 1 /* rule operation is ':' */ +#define R_OP_DCL 2 /* rule operation is '::' */ +#define R_OP_BG 4 /* rule operation is ':!' */ +#define R_OP_UP 8 /* rule operation is ':^' */ +#define R_OP_MI 16 /* rule operation is ':-' */ +#define R_OP_OR 32 /* rule operation is ':|' */ + +/* definitions for modifier application in Apply_modifiers in expand.c */ +#define SUFFIX_FLAG 1 /* defines for macro modifier code */ +#define DIRECTORY_FLAG 2 +#define FILE_FLAG 4 +#define WHOLENAME_FLAGS 7 +#define TOLOWER_FLAG 8 +#define TOUPPER_FLAG 16 +#define INFNAME_FLAG 32 +#define JUST_FIRST_FLAG 64 + +/* special target definitions for use inside dmake */ +#define ST_IF 1 +#define ST_ELSE 2 +#define ST_END 3 +#define ST_REST 4 /* remaining special targets */ +#define ST_INCLUDE 5 +#define ST_SOURCE 7 +#define ST_EXPORT 8 +#define ST_IMPORT 9 +#define ST_ELIF 10 +#define ST_KEEP 11 +#define ST_EXIT 12 +#define ST_IFEQ 13 +#define ST_IFNEQ 14 + +/* Flags for controling use of -v switch */ +#define V_NONE 0x00 +#define V_LEAVE_TMP 0x01 +#define V_DIR_SET 0x02 +#define V_DIR_CACHE 0x04 +#define V_INFER 0x08 +#define V_MAKE 0x10 +#define V_FILE_IO 0x20 +#define V_WARNALL 0x40 +#define V_ALL (V_LEAVE_TMP | V_DIR_SET | V_INFER | V_MAKE |\ + V_FILE_IO | V_DIR_CACHE | V_WARNALL) + +/* Macro definitions for use inside dmake */ +#define SET_TOKEN(A, B) (A)->tk_str = (B);\ + (A)->tk_cchar = *(B);\ + (A)->tk_quote = 1; + +#define CLEAR_TOKEN(A) *(A)->tk_str = (A)->tk_cchar +#define GET_MACRO(A) Get_name(A, Macs, FALSE) +#define iswhite(C) ((C == ' ') || (C == '\t')) +#define STOBOOL(A) (A && ((*A | 0x20) == 'y')) + +#endif + diff --git a/dmake/dmdump.c b/dmake/dmdump.c new file mode 100644 index 000000000000..9b4b86adf20c --- /dev/null +++ b/dmake/dmdump.c @@ -0,0 +1,259 @@ +/* RCS $Id: dmdump.c,v 1.1.1.1 2000-09-22 15:33:25 hr Exp $ +-- +-- SYNOPSIS +-- Dump the internal dag to stdout. +-- +-- DESCRIPTION +-- This file contains the routine that is called to dump a version of +-- the digested makefile to the standard output. May be useful perhaps +-- to the ordinary user, and invaluable for debugging make. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include "extern.h" + +#define M_TEST (M_PRECIOUS | M_VAR_MASK) + +static void dump_name ANSI((CELLPTR, int, int)); +static void dump_normal_target ANSI((CELLPTR, CELLPTR, int)); +static void dump_prerequisites ANSI((LINKPTR, CELLPTR, int, int, int)); +static void dump_conditionals ANSI((CELLPTR,STRINGPTR,int,int)); +static void dump_macro ANSI((HASHPTR, int)); + + +PUBLIC void +Dump()/* +======== Dump onto standard output the digested makefile. Note that + the form of the dump is not representative of the contents + of the original makefile contents at all */ +{ + HASHPTR hp; + int i; + + DB_ENTER( "Dump" ); + + puts( "# Dump of dmake macro variables:" ); + for( i=0; i<HASH_TABLE_SIZE; i++) + for( hp=Macs[i]; hp != NIL(HASH); hp = hp->ht_next ) { + int flag = hp->ht_flag; + dump_macro(hp, flag); + } + + puts( "\n#====================================" ); + puts( "# Dump of targets:\n" ); + + for( i=0; i<HASH_TABLE_SIZE; i++ ) + for( hp = Defs[i]; hp != NIL(HASH); hp = hp->ht_next ) + if( !(hp->CP_OWNR->ce_flag & F_PERCENT) ) { + if( hp->CP_OWNR == Root ) + puts( "# ******* ROOT TARGET ********" ); + if (Targets->ce_prq && hp->CP_OWNR == Targets->ce_prq->cl_prq) + puts( "# ******* FIRST USER DEFINED TARGET ******" ); + dump_normal_target( hp->CP_OWNR,NIL(CELL),hp->CP_OWNR->ce_flag); + } + + puts( "\n#====================================" ); + puts( "# Dump of inference graph\n" ); + + for( i=0; i<HASH_TABLE_SIZE; i++ ) + for( hp = Defs[i]; hp != NIL(HASH); hp = hp->ht_next ) + if( (hp->CP_OWNR->ce_flag & F_PERCENT) && + !(hp->CP_OWNR->ce_flag & F_MAGIC) ) + dump_normal_target(hp->CP_OWNR,NIL(CELL),hp->CP_OWNR->ce_flag); + + DB_VOID_RETURN; +} + + + +PUBLIC void +Dump_recipe( sp )/* +=================== + Given a string pointer print the recipe line out */ +STRINGPTR sp; +{ + char *st; + char *nl; + + if( sp == NIL(STRING) ) return; + + putchar( '\t' ); + if( sp->st_attr & A_SILENT ) putchar( '@' ); + if( sp->st_attr & A_IGNORE ) putchar( '-' ); + if( sp->st_attr & A_SHELL ) putchar( '+' ); + if( sp->st_attr & A_SWAP ) putchar( '%' ); + + st = sp->st_string; + for( nl=strchr(st,'\n'); nl != NIL( char); nl=strchr(st,'\n') ) { + *nl = '\0'; + printf( "%s\\\n", st ); + *nl = '\n'; + st = nl+1; + } + printf( "%s\n", st ); +} + + +static char *_attrs[] = { ".PRECIOUS", ".SILENT", ".LIBRARY", + ".EPILOG", ".PROLOG", ".IGNORE", ".SYMBOL", ".NOINFER", + ".UPDATEALL", ".SEQUENTIAL", ".SETDIR=", ".USESHELL", ".SWAP", ".MKSARGS", + ".PHONY", ".NOSTATE", ".IGNOREGROUP", ".EXECUTE", ".ERRREMOVE" }; + +static void +dump_normal_target( cp, namecp, flag )/* +======================================== + Dump in makefile like format the dag information */ +CELLPTR cp; +CELLPTR namecp; +int flag; +{ + register STRINGPTR sp; + t_attr attr; + unsigned int k; + + DB_ENTER( "dump_normal_target" ); + + if(!(cp->ce_flag & F_TARGET) && !cp->ce_attr && !cp->ce_prq) { + DB_VOID_RETURN; + } + + if(cp->ce_set && cp->ce_set != cp) { + DB_VOID_RETURN; + } + + if( cp->ce_flag & F_MULTI ) { + int tflag = cp->ce_prq->cl_prq->ce_flag; + if( !(cp->ce_flag & F_PERCENT) ) tflag |= F_MULTI; + dump_conditionals(cp, cp->ce_cond, TRUE, TRUE); + putchar('\n'); + dump_prerequisites(cp->ce_prq,(cp->ce_flag&F_PERCENT)?NIL(CELL):cp, + FALSE, TRUE, tflag); + } + else { + dump_name(namecp?namecp:cp, FALSE, TRUE ); + + for( k=0, attr=1; attr <= MAX_ATTR; attr <<= 1, k++ ) + if( cp->ce_attr & attr ) { + printf( "%s%s ", _attrs[k], + (attr != A_SETDIR) ? "" : (cp->ce_dir?cp->ce_dir:"") ); + } + + putchar( ':' ); + + if( flag & F_MULTI ) putchar( ':' ); + if( flag & F_SINGLE ) putchar( '!' ); + putchar( ' ' ); + + dump_prerequisites( cp->ce_prq, NIL(CELL), FALSE, FALSE, F_DEFAULT); + dump_prerequisites( cp->ce_indprq, NIL(CELL),TRUE, FALSE, F_DEFAULT); + + putchar( '\n' ); + if( cp->ce_flag & F_GROUP ) puts( "[" ); + for( sp = cp->ce_recipe; sp != NIL(STRING); sp = sp->st_next ) + Dump_recipe( sp ); + if( cp->ce_flag & F_GROUP ) { + puts( "]" ); + putchar( '\n' ); + } + dump_conditionals(cp, cp->ce_cond, flag&F_MULTI, FALSE); + putchar('\n'); + } + + DB_VOID_RETURN; +} + + +static void +dump_conditionals( cp, sp, multi, global ) +CELLPTR cp; +STRINGPTR sp; +int multi; +int global; +{ + if (sp) { + dump_name(cp, FALSE, TRUE); + printf(".%sCONDITIONALS %s\n", global?"GLOBAL":"",multi?"::":":"); + + while(sp) { + printf("\t%s\n",sp->st_string); + sp=sp->st_next; + } + } +} + + +static void +dump_macro(hp, flag) +HASHPTR hp; +int flag; +{ + printf( "%s ", hp->ht_name ); + if(flag & M_EXPANDED) + putchar( ':' ); + + printf( "= " ); + if(hp->ht_value != NIL(char)) + printf( "%s",hp->ht_value ); + + if(flag & M_PRECIOUS) + printf( "\t # PRECIOUS " ); + + putchar( '\n' ); +} + + +static void +dump_prerequisites( lp, namecp, quote, recurse, flag ) +LINKPTR lp; +CELLPTR namecp; +int quote; +int recurse; +int flag; +{ + for( ; lp; lp=lp->cl_next ) + if( recurse ) + dump_normal_target(lp->cl_prq, namecp, flag); + else if( lp->cl_prq ) + dump_name(lp->cl_prq, quote, FALSE); +} + + +static void +dump_name( cp, quote, all )/* +============================= + print out a name */ +CELLPTR cp; +int quote; +int all; +{ + LINKPTR lp; + char qc = '\''; + + for(lp=CeMeToo(cp);lp;lp=lp->cl_next) { + if( !quote && strchr(lp->cl_prq->CE_NAME,' ') != NIL(char)) { + quote = TRUE; + qc = '"'; + } + + if (quote) putchar(qc); + printf( "%s", lp->cl_prq->CE_NAME ); + if (quote) putchar(qc); + putchar(' '); + if (!all) break; + } +} diff --git a/dmake/dmstring.c b/dmake/dmstring.c new file mode 100644 index 000000000000..b4ff6177c368 --- /dev/null +++ b/dmake/dmstring.c @@ -0,0 +1,287 @@ +/* RCS $Id: dmstring.c,v 1.1.1.1 2000-09-22 15:33:25 hr Exp $ +-- +-- SYNOPSIS +-- String handling code +-- +-- DESCRIPTION +-- Routines to handle string manipulation. This code is not specific +-- to dmake and has/and will be used in other programs. The string +-- "" is considered the NULL string, if NIL(char) is received instead +-- undefined results may occurr. (In reality NIL(char) is checked for +-- but in general it is not safe to assume NIL(char) == NULL) +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include "extern.h" + +PUBLIC char * +DmStrJoin( src, data, n, fr )/* +=============================== + Join data to src according to value of n. + + n = -1 - return strcat( src, data ) + n >= 0 - return strncat( src, data, n ) + + FREE original src if fr == TRUE, else leave it alone */ + +char *src; +char *data; +int n; +int fr; +{ + char *t; + int l; + int flag = FALSE; + + DB_ENTER( "DmStrJoin" ); + + if( src == NIL(char) ) { src = ""; flag = TRUE; } + if( data == NIL(char) ) data = ""; + DB_PRINT( "str", ("Joining [%s] [%s] %d", src, data, n) ); + + if( n == -1 ) n = strlen( data ); + + l = strlen( src ) + n + 1; + if( (t = MALLOC( l, char )) == NIL(char) ) No_ram(); + + strcpy( t, src ); + if (n) strncat( t, data, n ); + t[ l-1 ] = '\0'; + + if( !flag && fr ) FREE( src ); + + DB_PRINT( "str", ("Result [%s]", t) ); + DB_RETURN( t ); +} + + + + +PUBLIC char * +DmStrAdd( src, data, fr )/* +=========================== + append data to src with space in between if src is not NIL(char) or "" + and free both src and data if fr == TRUE, otherwise leave them be */ + +char *src; +char *data; +int fr; +{ + char *t; + int l; + int sflag; + int dflag; + + DB_ENTER( "DmStrAdd" ); + + sflag = dflag = fr; + + if( src == NIL(char) ) { src = ""; sflag = FALSE; } + if( data == NIL(char) ) { data = ""; dflag = FALSE; } + DB_PRINT( "str", ("Adding [%s] [%s] %d", src, data, fr) ); + + l = strlen(src) + strlen(data) + 1; + if( *src ) l++; + + if( (t = MALLOC( l, char )) == NIL(char) ) No_ram(); + + strcpy( t, src ); + + if( *data ) + { + if( *src ) strcat( t, " " ); + strcat( t, data ); + } + + if( sflag ) FREE( src ); + if( dflag ) FREE( data ); + + DB_PRINT( "str", ("Result [%s]", t) ); + DB_RETURN( t ); +} + + + +PUBLIC char * +DmStrApp( src1, src2 )/* +======================== + Append two strings together, and return the result with a space between + the two strings. FREE the first string if it is not NIL and always + leave the second string be. */ +char *src1; +char *src2; +{ + src2 = DmStrAdd( src1, src2, FALSE ); + if( src1 != NIL(char) ) FREE( src1 ); + return( src2 ); +} + + +PUBLIC char * +DmStrDup( str )/* +================= Duplicate the contents of a string, by using malloc */ +char *str; +{ + char *t; + + if( str == NIL(char) ) return( NIL(char) ); + + if( (t = MALLOC( strlen( str )+1, char )) == NIL(char) ) No_ram(); + strcpy( t, str ); + + return( t ); +} + + + +PUBLIC char * +DmStrDup2( str )/* +================== + This function is used solely to properly quote command line arguments when + they are reinserted int MAKEMACROS so that they can be used further in + a processing line. */ +char *str; +{ + char *t; + size_t size; + size_t alloced; + char *tmp; + char *dest; + int seen_equal = 0; + + if(str == NIL(char)) return(NIL(char)); + size = strlen(str) + 1; + alloced = size + 2; /* for two quotes */ + + for(tmp = str; *tmp; tmp++) + if(*tmp == '"') + alloced++; + + if((t = MALLOC(alloced, char)) == NIL(char)) No_ram(); + + for(tmp = str, dest = t; *tmp; tmp++, dest++) { + if(*tmp == '=' && !seen_equal) { + seen_equal = 1; + *dest++ = *tmp; + *dest = '"'; + continue; + } + if(*tmp == '"') + *dest++ = '\\'; + *dest = *tmp; + } + + if(!seen_equal) + Fatal("DmStrDup2 invoked without argument of form x=y\n"); + + *dest++ = '"'; + *dest = 0; + + return t; +} + + + +PUBLIC char * +DmStrPbrk( s1, s2 )/* +==================== + find first occurence of char in s2 in string s1. + Returns a pointer to the first occurrence. NOTE '\0' is considered part + of s2 and a pointer to it is returned if no other chars match. */ + +char *s1; +char *s2; +{ + register char *t; + + if( s1 == NIL(char) || s2 == NIL(char) ) return( "" ); + + for( t=s1; *t && (strchr( s2, *t ) == NIL(char)); t++ ); + return( t ); +} + + + + +PUBLIC char * +DmStrSpn( s1, s2 )/* +==================== + return pointer to first char in s1 that does not belong to s2. + Returns the pointer if match found, else returns pointer to null char + in s1. (ie. "" ) */ + +char *s1; +char *s2; +{ + register char *t; + + if( s1 == NIL(char) || s2 == NIL(char) ) return( "" ); + + for( t=s1; *t && (strchr( s2, *t ) != NIL(char)); t++ ); + return( t ); +} + + + + +PUBLIC char * +DmStrStr( s1, s2 )/* +==================== find first occurrence in s1 of s2 */ +char *s1; +char *s2; +{ + register char *s; + register char *p; + register char *r; + + if( s1 != NIL(char) && s2 != NIL(char) ) + for( s=s1; *s; s++ ) + if( *s == *s2 ) + { + for( r=s+1, p = s2+1; *p && (*r == *p); r++, p++ ); + if( !*p ) return( s ); + } + + return( NIL(char) ); +} + + + +PUBLIC char * +DmSubStr( s, e )/* +================== + Return the string between the two pointers s and e, not including the + char that e points to. NOTE: This routine assumes that s and e point + into the same string. */ + +char *s; +char *e; +{ + char save; + int len = e-s; + + if( len < 0 || len > strlen(s) ) + Fatal( "Internal Error: SubStr fails consistency test" ); + + save = *e; + *e = '\0'; + s = DmStrDup( s ); + *e = save; + + return( s ); +} diff --git a/dmake/dstdarg.h b/dmake/dstdarg.h new file mode 100644 index 000000000000..f0dc760b5db4 --- /dev/null +++ b/dmake/dstdarg.h @@ -0,0 +1,43 @@ +/* RCS $Id: dstdarg.h,v 1.1.1.1 2000-09-22 15:33:25 hr Exp $ +-- +-- SYNOPSIS +-- +-- DESCRIPTION +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ +#include <stdarg.h> + +#define ARG(a,b) a + +#if __STDC__ || defined(__TURBOC__) || defined(__IBMC__) +# define va_alist_type ... +# ifdef va_alist +# undef va_alist +# endif +# define va_alist +# define DARG(a,b) +#else +# ifdef va_alist +# define va_alist_type int +# define DARG(a,b) a b; +# else +# define va_alist_type ... +# define va_alist +# define DARG(a,b) +# endif +#endif diff --git a/dmake/expand.c b/dmake/expand.c new file mode 100644 index 000000000000..664aa03ddc09 --- /dev/null +++ b/dmake/expand.c @@ -0,0 +1,1066 @@ +/* RCS $Id: expand.c,v 1.1.1.1 2000-09-22 15:33:25 hr Exp $ +-- +-- SYNOPSIS +-- Macro expansion code. +-- +-- DESCRIPTION +-- +-- This routine handles all the necessary junk that deals with macro +-- expansion. It understands the following syntax. If a macro is +-- not defined it expands to NULL, and {} are synonyms for (). +-- +-- $$ - expands to $ +-- {{ - expands to { +-- }} - expands to } +-- $A - expands to whatever the macro A is defined as +-- $(AA) - expands to whatever the macro AA is defined as +-- $($(A)) - represents macro indirection +-- <+...+> - get mapped to $(mktmp ...) +-- +-- following macro is recognized +-- +-- string1{ token_list }string2 +-- +-- and expands to string1 prepended to each element of token_list and +-- string2 appended to each of the resulting tokens from the first +-- operation. If string2 is of the form above then the result is +-- the cross product of the specified (possibly modified) token_lists. +-- +-- The folowing macro modifiers are defined and expanded: +-- +-- $(macro:modifier_list:modifier_list:...) +-- +-- where modifier_list a combination of: +-- +-- D or d - Directory portion of token including separator +-- F or f - File portion of token including suffix +-- B or b - basename portion of token not including suffix +-- T or t - for tokenization +-- E or e - Suffix portion of name +-- L or l - translate to lower case +-- U or u - translate to upper case +-- I or i - return inferred names +-- +-- or a single +-- S or s - pattern substitution (simple) +-- +-- NOTE: Modifiers are applied once the macro value has been found. +-- Thus the construct $($(test):s/joe/mary/) is defined and +-- modifies the value of $($(test)) +-- +-- Also the construct $(m:d:f) is not the same as $(m:df) +-- the first applies d to the value of $(m) and then +-- applies f to the value of that whereas the second form +-- applies df to the value of $(m). +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include "extern.h" + +/* Microsoft BRAINDAMAGE ALERT!!!! + * This #ifdef is here only to satisfy stupid bugs in MSC5.0 and MSC5.1 + * it isn't needed for anything else. It turns loop optimization off. */ +#if defined(_MSC_VER) +#include "optoff.h" +#endif + +static char* _scan_macro ANSI((char*, char**, int)); +static char* _scan_brace ANSI((char*, char**, int*)); +static char* _cross_prod ANSI((char*, char*)); + +#if !defined(__GNUC__) && !defined(__IBMC__) +static char* _scan_ballanced_parens ANSI((char*, char)); +#else +static char* _scan_ballanced_parens ANSI((char*, int)); +#endif + + +PUBLIC char * +Expand( src )/* +=============== + This is the driver routine for the expansion, it identifies non-white + space tokens and gets the ScanToken routine to figure out if they should + be treated in a special way. */ + +char *src; /* pointer to source string */ +{ + char *tmp; /* pointer to temporary str */ + char *res; /* pointer to result string */ + char *start; /* pointer to start of token */ + + DB_ENTER( "Expand" ); + DB_PRINT( "exp", ("Expanding [%s]", src) ); + + res = DmStrDup( "" ); + if( src == NIL(char) ) DB_RETURN( res ); + + while( *src ) { + char *ks, *ke; + + /* Here we find the next non white space token in the string + * and find it's end, with respect to non-significant white space. */ + +#ifndef _MPW + start = DmStrSpn( src, " \t\n" ); +#else + start = DmStrSpn( src, " \t\r\n" ); +#endif + + res = DmStrJoin( res, src, start-src, TRUE ); + if( !(*start) ) break; + + /* START <+...+> KLUDGE */ + if( (ks=DmStrStr(start,"<+")) != NIL(char) + && (ke=DmStrStr(ks,"+>")) != NIL(char) ){ + char *t1, *t2; + + res = DmStrJoin( res, t2=Expand(t1=DmSubStr(start,ks)), -1, TRUE); + FREE(t1); FREE(t2); + + t1 = DmSubStr(ks+2, ke+1); t1[ke-ks-2] = ')'; + t2 = DmStrJoin( "$(mktmp ", t1, -1,FALSE); + FREE(t1); + res = DmStrJoin( res, t2=Expand(t2), -1, TRUE); + FREE(t2); + src = ke+2; + } + /* END <+...+> KLUDGE */ + else { + res = DmStrJoin( res, tmp = ScanToken(start,&src,TRUE), -1, TRUE ); + FREE( tmp ); + } + } + + DB_PRINT( "exp", ("Returning [%s]", res) ); + DB_RETURN( res ); +} + + +PUBLIC char * +Apply_edit( src, pat, subst, fr, anchor )/* +=========================================== + Take the src string and apply the pattern substitution. ie. look for + occurrences of pat in src and replace each occurrence with subst. This is + NOT a regular expressions pattern substitution, it's just not worth it. + + if anchor == TRUE then the src pattern match must be at the end of a token. + ie. this is for SYSV compatibility and is only used for substitutions of + the caused by $(macro:pat=sub). So if src = "fre.o.k june.o" then + $(src:.o=.a) results in "fre.o.k june.a", and $(src:s/.o/.a) results in + "fre.a.k june.a" */ + +char *src; /* the source string */ +char *pat; /* pattern to find */ +char *subst; /* substitute string */ +int fr; /* if TRUE free src */ +int anchor; /* if TRUE anchor */ +{ + char *res; + char *p; + char *s; + int l; + + DB_ENTER( "Apply_edit" ); + + if( !*pat ) DB_RETURN( src ); /* do nothing if pat is NULL */ + + DB_PRINT( "mod", ("Source str: [%s]", src) ); + DB_PRINT( "mod", ("Replacing [%s], with [%s]", pat, subst) ); + + s = src; + l = strlen( pat ); + if( (p = DmStrStr( s, pat )) != NIL(char) ) { + res = DmStrDup( "" ); + do { + if( anchor ) + if( !*(p+l) || (strchr(" \t", *(p+l)) != NIL(char)) ) + res = DmStrJoin( DmStrJoin(res,s,p-s,TRUE), subst, -1, TRUE ); + else + res = DmStrJoin( res, s, p+l-s, TRUE ); + else + res = DmStrJoin( DmStrJoin(res,s,p-s,TRUE), subst, -1, TRUE ); + + s = p + l; + } + while( (p = DmStrStr( s, pat )) != NIL(char) ); + + res = DmStrJoin( res, s, -1, TRUE ); + if( fr ) FREE( src ); + } + else + res = src; + + + DB_PRINT( "mod", ("Result [%s]", res) ); + DB_RETURN( res ); +} + + +PUBLIC void +Map_esc( tok )/* +================ + Map an escape sequence and replace it by it's corresponding character + value. It is assumed that tok points at the initial \, the esc + sequence in the original string is replaced and the value of tok + is not modified. */ +char *tok; +{ + if( strchr( "\"\\vantbrf01234567", tok[1] ) ) { + switch( tok[1] ) { + case 'a' : *tok = 0x07; break; + case 'b' : *tok = '\b'; break; + case 'f' : *tok = '\f'; break; + case 'n' : *tok = '\n'; break; + case 'r' : *tok = '\r'; break; + case 't' : *tok = '\t'; break; + case 'v' : *tok = 0x0b; break; + case '\\': *tok = '\\'; break; + case '\"': *tok = '\"'; break; + + default: { + register int i = 0; + register int j = 0; + for( ; i<2 && isdigit(tok[2]); i++ ) { + j = (j << 3) + (tok[1] - '0'); + strcpy( tok+1, tok+2 ); + } + j = (j << 3) + (tok[1] - '0'); + *tok = j; + } + } + strcpy( tok+1, tok+2 ); + } +} + + +PUBLIC char* +Apply_modifiers( mod, src )/* +============================= + This routine applies the appropriate modifiers to the string src + and returns the proper result string */ + +int mod; +char *src; +{ + char *s; + char *e; + TKSTR str; + + DB_ENTER( "Apply_modifiers" ); + + if ( mod & INFNAME_FLAG ) { + SET_TOKEN( &str, src ); + e = NIL(char); + + while( *(s = Get_token( &str, "", FALSE )) != '\0' ) { + HASHPTR hp; + + if ( (hp = Get_name(s, Defs, FALSE)) != NIL(HASH) + && hp->CP_OWNR + && hp->CP_OWNR->ce_fname + ) { + e = DmStrApp(e,hp->CP_OWNR->ce_fname); + } + else + e = DmStrApp(e,s); + } + + FREE(src); + src = e; + mod &= ~INFNAME_FLAG; + } + + if(mod & (TOLOWER_FLAG|TOUPPER_FLAG) ) { + int lower; + lower = mod & TOLOWER_FLAG; + + for (s=src; *s; s++) + if ( isalpha(*s) ) + *s = ((lower) ? tolower(*s) : toupper(*s)); + + mod &= ~(TOLOWER_FLAG|TOUPPER_FLAG); + } + + if (mod & JUST_FIRST_FLAG) { + SET_TOKEN(&str, src); + if ((s = Get_token(&str,"",FALSE)) != '\0') { + e = DmStrDup(s); + CLEAR_TOKEN(&str); + FREE(src); + src = e; + } + else { + CLEAR_TOKEN(&str); + } + mod &= ~JUST_FIRST_FLAG; + } + + if( !mod || mod == (SUFFIX_FLAG | DIRECTORY_FLAG | FILE_FLAG) ) + DB_RETURN( src ); + + SET_TOKEN( &str, src ); + DB_PRINT( "mod", ("Source string [%s]", src) ); + + while( *(s = Get_token( &str, "", FALSE )) != '\0' ) { + /* search for the directory portion of the filename. If the + * DIRECTORY_FLAG is set, then we want to keep the directory portion + * othewise throw it away and blank out to the end of the token */ + + if( (e = Basename(s)) != s) + if( !(mod & DIRECTORY_FLAG) ) { + strcpy(s, e); + e = s+(str.tk_str-e); + for(; e != str.tk_str; e++) + *e = ' '; + } + else + s = e; + + /* search for the suffix, if there is none, treat it as a NULL suffix. + * if no file name treat it as a NULL file name. same copy op as + * for directory case above */ + + e = strrchr( s, '.' ); /* NULL suffix if e=0 */ + if( e == NIL(char) ) e = s+strlen(s); + + if( !(mod & FILE_FLAG) ) { + strcpy( s, e ); + e = s+(str.tk_str-e); + for( ; e != str.tk_str; e++ ) *e = ' '; + } + else + s = e; + + /* The last and final part. This is the suffix case, if we don't want + * it then just erase to the end of the token. */ + + if( s != NIL(char) ) + if( !(mod & SUFFIX_FLAG) ) + for( ; s != str.tk_str; s++ ) *s = ' '; + } + + /* delete the extra white space, it looks ugly */ + for( s = src, e = NIL(char); *s; s++ ) + if( *s == ' ' || *s == '\t' || *s == '\n' ) { + if( e == NIL(char) ) + e = s; + } + else { + if( e != NIL(char) ) { + if( e+1 < s ) { + strcpy( e+1, s ); + s = e+1; + *e = ' '; + } + e = NIL(char); + } + } + + if( e != NIL(char) ) + if( e < s ) + strcpy( e, s ); + + DB_PRINT( "mod", ("Result string [%s]", src) ); + DB_RETURN( src ); +} + + +PUBLIC char* +Tokenize( src, separator, op, mapesc )/* +======================================== + Tokenize the input of src and join each token found together with + the next token separated by the separator string. + + When doing the tokenization, <sp>, <tab>, <nl>, and \<nl> all + constitute white space. */ + +char *src; +char *separator; +char op; +int mapesc; +{ + TKSTR tokens; + char *tok; + char *res; + int first = (op == 't' || op == 'T'); + + DB_ENTER( "Tokenize" ); + + /* map the escape codes in the separator string first */ + if ( mapesc ) + for(tok=separator; (tok = strchr(tok,ESCAPE_CHAR)) != NIL(char); tok++) + Map_esc( tok ); + + DB_PRINT( "exp", ("Separator [%s]", separator) ); + + /* By default we return an empty string */ + res = DmStrDup( "" ); + + /* Build the token list */ + SET_TOKEN( &tokens, src ); + while( *(tok = Get_token( &tokens, "", FALSE )) != '\0' ) { + char *x; + + if( first ) { + FREE( res ); + res = DmStrDup( tok ); + first = FALSE; + } + else if (op == '^') { + res = DmStrAdd(res, DmStrJoin(separator, tok, -1, FALSE), TRUE); + } + else if (op == '+') { + res = DmStrAdd(res, DmStrJoin(tok, separator, -1, FALSE), TRUE); + } + else { + res = DmStrJoin(res, x =DmStrJoin(separator, tok, -1, FALSE), + -1, TRUE); + FREE( x ); + } + + DB_PRINT( "exp", ("Tokenizing [%s] --> [%s]", tok, res) ); + } + + FREE( src ); + DB_RETURN( res ); +} + + +static char* +_scan_ballanced_parens(p, delim) +char *p; +char delim; +{ + int pcount = 0; + int bcount = 0; + + if ( p ) { + do { + if (delim) + if( !(bcount || pcount) && *p == delim) { + return(p); + } + + if ( *p == '(' ) pcount++; + else if ( *p == '{' ) bcount++; + else if ( *p == ')' && pcount ) pcount--; + else if ( *p == '}' && bcount ) bcount--; + + p++; + } + while (*p && (pcount || bcount || delim)); + } + + return(p); +} + + +PUBLIC char* +ScanToken( s, ps, doexpand )/* +============================== + This routine scans the token characters one at a time and identifies + macros starting with $( and ${ and calls _scan_macro to expand their + value. the string1{ token_list }string2 expansion is also handled. + In this case a temporary result is maintained so that we can take it's + cross product with any other token_lists that may possibly appear. */ + +char *s; /* pointer to start of src string */ +char **ps; /* pointer to start pointer */ +int doexpand; +{ + char *res; /* pointer to result */ + char *start; /* pointer to start of prefix */ + int crossproduct = 0; /* if 1 then computing X-prod */ + + start = s; + res = DmStrDup( "" ); + while( 1 ) { + switch( *s ) { + /* Termination, We halt at seeing a space or a tab or end of string. + * We return the value of the result with any new macro's we scanned + * or if we were computing cross_products then we return the new + * cross_product. + * NOTE: Once we start computing cross products it is impossible to + * stop. ie. the semantics are such that once a {} pair is + * seen we compute cross products until termination. */ + + case ' ': + case '\t': + case '\n': + case '\0': + { + char *tmp; + + *ps = s; + if( !crossproduct ) + tmp = DmStrJoin( res, start, (s-start), TRUE ); + else + { + tmp = DmSubStr( start, s ); + tmp = _cross_prod( res, tmp ); + } + return( tmp ); + } + + case '$': + case '{': + { + /* Handle if it's a macro or if it's a {} construct. + * The results of a macro expansion are handled differently based + * on whether we have seen a {} beforehand. */ + + char *tmp; + tmp = DmSubStr( start, s ); /* save the prefix */ + + if( *s == '$' ) { + start = _scan_macro( s+1, &s, doexpand ); + + if( crossproduct ) { + res = _cross_prod( res, DmStrJoin( tmp, start, -1, TRUE ) ); + } + else { + res = DmStrJoin(res,tmp=DmStrJoin(tmp,start,-1,TRUE),-1,TRUE); + FREE( tmp ); + } + FREE( start ); + } + else if( strchr("{ \t",s[1]) == NIL(char) ){ + int ok; + start = _scan_brace( s+1, &s, &ok ); + + if( ok ) { + if ( crossproduct ) { + res = _cross_prod(res,_cross_prod(tmp,start)); + } + else { + char *freeres; + res = Tokenize(start, + freeres=DmStrJoin(res,tmp,-1,TRUE), + '^', FALSE); + FREE(freeres); + FREE(tmp); + } + crossproduct = TRUE; + } + else { + res =DmStrJoin(res,tmp=DmStrJoin(tmp,start,-1,TRUE),-1,TRUE); + FREE( start ); + FREE( tmp ); + } + } + else { /* handle the {{ case */ + res = DmStrJoin( res, start, (s-start+1), TRUE ); + s += (s[1]=='{')?2:1; + FREE( tmp ); + } + + start = s; + } + break; + + case '}': + if( s[1] != '}' ) { + /* error malformed macro expansion */ + s++; + } + else { /* handle the }} case */ + res = DmStrJoin( res, start, (s-start+1), TRUE ); + s += 2; + start = s; + } + break; + + default: s++; + } + } +} + + +static char* +_scan_macro( s, ps, doexpand )/* +================================ + This routine scans a macro use and expands it to the value. It + returns the macro's expanded value and modifies the pointer into the + src string to point at the first character after the macro use. + The types of uses recognized are: + + $$ and $<sp> - expands to $ + $(name) - expands to value of name + ${name} - same as above + $($(name)) - recurses on macro names (any level) + and + $(func[,args ...] [data]) + and + $(name:modifier_list:modifier_list:...) + + see comment for Expand for description of valid modifiers. + + NOTE that once a macro name bounded by ( or { is found only + the appropriate terminator (ie. ( or } is searched for. */ + +char *s; /* pointer to start of src string */ +char **ps; /* pointer to start pointer */ +int doexpand; /* If TRUE enables macro expansion */ +{ + char sdelim; /* start of macro delimiter */ + char edelim; /* corresponding end macro delim */ + char *start; /* start of prefix */ + char *macro_name; /* temporary macro name */ + char *recurse_name; /* recursive macro name */ + char *result; /* result for macro expansion */ + int bflag = 0; /* brace flag, ==0 => $A type macro */ + int done = 0; /* != 0 => done macro search */ + int lev = 0; /* brace level */ + int mflag = 0; /* != 0 => modifiers present in mac */ + int fflag = 0; /* != 0 => GNU style function */ + HASHPTR hp; /* hash table pointer for macros */ + + DB_ENTER( "_scan_macro" ); + + /* Check for $ at end of line, or $ followed by white space */ + if( !*s || strchr(" \t", *s) != NIL(char)) { + *ps = s; + DB_RETURN( DmStrDup("") ); + } + + if( *s == '$' ) { /* Take care of the simple $$ case. */ + *ps = s+1; + DB_RETURN( DmStrDup("$") ); + } + + sdelim = *s; /* set and remember start/end delim */ + if( sdelim == '(' ) + edelim = ')'; + else + edelim = '}'; + + start = s; /* build up macro name, find its end*/ + while( !done ) { + switch( *s ) { + case '(': /* open macro brace */ + case '{': + if( *s == sdelim ) { + lev++; + bflag++; + } + break; + + case ':': /* halt at modifier */ + if( lev == 1 && !fflag && doexpand ) { + done = TRUE; + mflag = 1; + } + break; + + case ' ': + case '\t': + case '\n': + if ( lev == 1 ) fflag = 1; + break; + + case '\0': /* check for null */ + *ps = s; + done = TRUE; + if( lev ) { + bflag = 0; + s = start; + } + break; + + case ')': /* close macro brace */ + case '}': + if( *s == edelim && lev ) --lev; + /*FALLTHRU*/ + + default: + done = !lev; + } + s++; + } + + /* Check if this is a $A type macro. If so then we have to + * handle it a little differently. */ + if( bflag ) + macro_name = DmSubStr( start+1, s-1 ); + else + macro_name = DmSubStr( start, s ); + + if (!doexpand) { + *ps = s; + DB_RETURN(macro_name); + } + + /* Check to see if the macro name contains spaces, if so then treat it + * as a GNU style function invocation and call the function mapper to + * deal with it. We do not call the function expander if the function + * invocation begins with a '$' */ + if( fflag && *macro_name != '$' ) { + result = Exec_function(macro_name); + } + else { + /* Check if the macro is a recursive macro name, if so then + * EXPAND the name before expanding the value */ + if( strchr( macro_name, '$' ) != NIL(char) ) { + recurse_name = Expand( macro_name ); + FREE( macro_name ); + macro_name = recurse_name; + } + + /* Code to do value expansion goes here, NOTE: macros whose assign bit + is one have been evaluated and assigned, they contain no further + expansions and thus do not need their values expanded again. */ + + if( (hp = GET_MACRO( macro_name )) != NIL(HASH) ) { + if( hp->ht_flag & M_MARK ) + Fatal( "Detected circular macro [%s]", hp->ht_name ); + + if( !(hp->ht_flag & M_EXPANDED) ) { + hp->ht_flag |= M_MARK; + result = Expand( hp->ht_value ); + hp->ht_flag ^= M_MARK; + } + else if( hp->ht_value != NIL(char) ) + result = DmStrDup( hp->ht_value ); + else + result = DmStrDup( "" ); + + /* + * Mark macros as used only if we are not expanding them for + * the purpose of a .IF test, so we can warn about redef after use*/ + + if( !If_expand ) hp->ht_flag |= M_USED; + } + else + result = DmStrDup( "" ); + } + + if( mflag ) { + char separator; + int modifier_list = 0; + int aug_mod = FALSE; + char *pat1; + char *pat2; + char *p; + + /* Yet another brain damaged AUGMAKE kludge. We should accept the + * AUGMAKE bullshit of $(f:pat=sub) form of macro expansion. In + * order to do this we will forgo the normal processing if the + * AUGMAKE solution pans out, otherwise we will try to process the + * modifiers ala dmake. + * + * So we look for = in modifier string. + * If found we process it and not do the normal stuff */ + + for( p=s; *p && *p != '=' && *p != edelim; p++ ); + + if( *p == '=' ) { + char *tmp; + + pat1 = Expand(tmp = DmSubStr(s,p)); FREE(tmp); + s = p+1; + p = _scan_ballanced_parens(s+1, edelim); + + if ( !*p ) { + Warning( "Incomplete macro expression [%s]", s ); + p = s+1; + } + pat2 = Expand(tmp = DmSubStr(s,p)); FREE(tmp); + + result = Apply_edit( result, pat1, pat2, TRUE, TRUE ); + FREE( pat1 ); + FREE( pat2 ); + s = p; + aug_mod = TRUE; + } + + if( !aug_mod ) + while( *s && *s != edelim ) { /* while not at end of macro */ + char switch_char; + + switch( switch_char = *s++ ) { + case '1': modifier_list |= JUST_FIRST_FLAG; break; + + case 'b': + case 'B': modifier_list |= FILE_FLAG; break; + + case 'd': + case 'D': modifier_list |= DIRECTORY_FLAG; break; + + case 'f': + case 'F': modifier_list |= FILE_FLAG | SUFFIX_FLAG; break; + + case 'e': + case 'E': modifier_list |= SUFFIX_FLAG; break; + + case 'l': + case 'L': modifier_list |= TOLOWER_FLAG; break; + + case 'i': + case 'I': modifier_list |= INFNAME_FLAG; break; + + case 'u': + case 'U': modifier_list |= TOUPPER_FLAG; break; + + case 'S': + case 's': + if( modifier_list ) { + Warning( "Edit modifier must appear alone, ignored"); + modifier_list = 0; + } + else { + separator = *s++; + for( p=s; *p != separator && *p != edelim; p++ ); + + if( *p == edelim ) + Warning("Syntax error in edit pattern, ignored"); + else { + char *t1, *t2; + pat1 = DmSubStr( s, p ); + for(s=p=p+1; (*p != separator) && (*p != edelim); p++ ); + pat2 = DmSubStr( s, p ); + t1 = Expand(pat1); FREE(pat1); + t2 = Expand(pat2); FREE(pat2); + result = Apply_edit( result, t1, t2, TRUE, FALSE ); + FREE( t1 ); + FREE( t2 ); + } + s = p; + } + /* find the end of the macro spec, or the start of a new + * modifier list for further processing of the result */ + + for( ; (*s != edelim) && (*s != ':'); s++ ); + if( *s == ':' ) s++; + break; + + case 'T': + case 't': + case '^': + case '+': + if( modifier_list ) { + Warning( "Tokenize modifier must appear alone, ignored"); + modifier_list = 0; + } + else { + separator = *s++; + + if( separator == '$' ) { + p = _scan_ballanced_parens(s,'\0'); + + if ( *p ) { + char *tmp; + pat1 = Expand(tmp = DmSubStr(s-1,p)); + FREE(tmp); + result = Tokenize(result, pat1, switch_char, TRUE); + FREE(pat1); + } + else { + Warning( "Incomplete macro expression [%s]", s ); + } + s = p; + } + else if ( separator == '\"' ) { + /* we change the semantics to allow $(v:t")") */ + for (p = s; *p && *p != separator; p++) + if (*p == '\\') + if (p[1] == '\\' || p[1] == '"') + p++; + + if( *p == 0 ) + Fatal( "Unterminated separator string" ); + else { + pat1 = DmSubStr( s, p ); + result = Tokenize( result, pat1, switch_char, TRUE); + FREE( pat1 ); + } + s = p; + } + else { + Warning( + "Separator must be a quoted string or macro expression"); + } + + /* find the end of the macro spec, or the start of a new + * modifier list for further processing of the result */ + + for( ; (*s != edelim) && (*s != ':'); s++ ); + if( *s == ':' ) s++; + } + break; + + case ':': + if( modifier_list ) { + result = Apply_modifiers( modifier_list, result ); + modifier_list = 0; + } + break; + + default: + Warning( "Illegal modifier in macro, ignored" ); + break; + } + } + + if( modifier_list ) /* apply modifier */ + result = Apply_modifiers( modifier_list, result ); + + s++; + } + + *ps = s; + FREE( macro_name ); + DB_RETURN( result ); +} + + +static char* +_scan_brace( s, ps, flag )/* +============================ + This routine scans for { token_list } pairs. It expands the value of + token_list by calling Expand on it. Token_list may be anything at all. + Note that the routine count's ballanced parentheses. This means you + cannot have something like { fred { joe }, if that is what you really + need the write it as { fred {{ joe }, flag is set to 1 if all ok + and to 0 if the braces were unballanced. */ + +char *s; +char **ps; +int *flag; +{ + char *t; + char *start; + char *res; + int lev = 1; + int done = 0; + + DB_ENTER( "_scan_brace" ); + + start = s; + while( !done ) + switch( *s++ ) { + case '{': + if( *s == '{' ) break; /* ignore {{ */ + lev++; + break; + + case '}': + if( *s == '}' ) break; /* ignore }} */ + if( lev ) + if( --lev == 0 ) done = TRUE; + break; + + case '$': + if( *s == '{' || *s == '}' ) { + if( (t = strchr(s,'}')) != NIL(char) ) + s = t; + s++; + } + break; + + case '\0': + if( lev ) { + done = TRUE; + s--; + /* error malformed macro expansion */ + } + break; + } + + start = DmSubStr( start, (lev) ? s : s-1 ); + + if( lev ) { + /* Braces were not ballanced so just return the string. + * Do not expand it. */ + + res = DmStrJoin( "{", start, -1, FALSE ); + *flag = 0; + } + else { + *flag = 1; + res = Expand( start ); + + if( (t = DmStrSpn( res, " \t" )) != res ) strcpy( res, t ); + } + + FREE( start ); /* this is ok! start is assigned a DmSubStr above */ + *ps = s; + + DB_RETURN( res ); +} + + +static char* +_cross_prod( x, y )/* +===================== + Given two strings x and y compute the cross-product of the tokens found + in each string. ie. if x = "a b" and y = "c d" return "ac ad bc bd". + + NOTE: buf will continue to grow until it is big enough to handle + all cross product requests. It is never freed! (maybe I + will fix this someday) */ + +char *x; +char *y; +{ + static char *buf = NULL; + static int buf_siz = 0; + char *brkx; + char *brky; + char *cy; + char *cx; + char *res; + int i; + + if( *x && *y ) { + res = DmStrDup( "" ); cx = x; + while( *cx ) { + cy = y; + brkx = DmStrPbrk( cx, " \t\n" ); + if( (brkx-cx == 2) && *cx == '\"' && *(cx+1) == '\"' ) cx = brkx; + + while( *cy ) { + brky = DmStrPbrk( cy, " \t\n" ); + if( (brky-cy == 2) && *cy == '\"' && *(cy+1) == '\"' ) cy = brky; + i = brkx-cx + brky-cy + 2; + + if( i > buf_siz ) { /* grow buf to the correct size */ + if( buf != NIL(char) ) FREE( buf ); + if( (buf = MALLOC( i, char )) == NIL(char)) No_ram(); + buf_siz = i; + } + + strncpy( buf, cx, (i = brkx-cx) ); + buf[i] = '\0'; + if (brky-cy > 0) strncat( buf, cy, brky-cy ); + buf[i+(brky-cy)] = '\0'; + strcat( buf, " " ); + res = DmStrJoin( res, buf, -1, TRUE ); + cy = DmStrSpn( brky, " \t\n" ); + } + cx = DmStrSpn( brkx, " \t\n" ); + } + + FREE( x ); + res[ strlen(res)-1 ] = '\0'; + } + else + res = DmStrJoin( x, y, -1, TRUE ); + + FREE( y ); + return( res ); +} diff --git a/dmake/extern.h b/dmake/extern.h new file mode 100644 index 000000000000..563910a2c9de --- /dev/null +++ b/dmake/extern.h @@ -0,0 +1,66 @@ +/* RCS $Id: extern.h,v 1.1.1.1 2000-09-22 15:33:25 hr Exp $ +-- +-- SYNOPSIS +-- External declarations for dmake functions. +-- +-- DESCRIPTION +-- ANSI is a macro that allows the proper handling of ANSI style +-- function declarations. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef EXTERN_h +#define EXTERN_h + +/* Define this for the RS/6000 if it breaks something then we have to put a + * #ifdef around it. */ +#if defined(rs6000) +#define _POSIX_SOURCE +#endif + +#include <limits.h> +#include <stdio.h> +#include <string.h> +#include <ctype.h> +#include <stdlib.h> +#include <fcntl.h> +#if defined (_MPW) +# include <types.h> +# include <time.h> +#else +# include <sys/types.h> +# include <sys/stat.h> +#endif +#include <signal.h> +#include "itypes.h" +#include "stdmacs.h" +#include "alloc.h" +#include "db.h" +#include "dstdarg.h" +#include "dmake.h" +#include "struct.h" +#include "vextern.h" +#include "public.h" + +/* Include this last as it invalidates some functions that are defined + * externally above and turns them into no-ops. Have to do this after + * the extern declarations however. */ +#include "config.h" +#include "posix.h" + +#endif diff --git a/dmake/function.c b/dmake/function.c new file mode 100644 index 000000000000..d3bcffbb25b9 --- /dev/null +++ b/dmake/function.c @@ -0,0 +1,625 @@ +/* RCS $Id: function.c,v 1.1.1.1 2000-09-22 15:33:25 hr Exp $ +-- +-- SYNOPSIS +-- GNU style functions for dmake. +-- +-- DESCRIPTION +-- All GNU stule functions understood by dmake are implemented in this +-- file. Currently the only such function is $(mktmp ...) which is +-- not part of GNU-make is an extension provided by dmake. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include "extern.h" + +static char *_exec_mktmp ANSI((char *, char *, char *)); +static char *_exec_subst ANSI((char *, char *, char *)); +static char *_exec_iseq ANSI((char *, char *, char *, int)); +static char *_exec_sort ANSI((char *)); +static char *_exec_echo ANSI((char *)); +static char *_exec_uniq ANSI((char *)); +static char *_exec_shell ANSI((char *, char *)); +static char *_exec_call ANSI((char *, char *)); +static char *_exec_assign ANSI((char *)); +static char *_exec_foreach ANSI((char *, char *, char *)); +static char *_exec_andor ANSI((char *, int)); +static char *_exec_not ANSI((char *)); +static int _mystrcmp ANSI((CONST PVOID, CONST PVOID)); + + +PUBLIC char * +Exec_function(buf)/* +==================== + Execute the function given by the value of args. + + So far mktmp is the only valid function, anything else elicits and error + message. It is my hope to support the GNU style functions in this portion + of the code at some time in the future. */ +char *buf; +{ + char *fname; + char *args; + char *mod1; + char *mod2 = NIL(char); + char *res = NIL(char); + + /* This must succeed since the presence of ' ', \t or \n is what + * determines if this function is called in the first place. */ + FREE(ScanToken(buf, &args, FALSE)); + fname = DmSubStr(buf, args); + + if( (mod1 = strchr(fname,',')) != NIL(char) ){ + *mod1 = '\0'; + mod1++; + + if( (mod2 = strchr(mod1,',')) != NIL(char) ){ + *mod2 = '\0'; + mod2++; + } + } + + switch( *fname ) { + case 'a': + if(strncmp(fname,"assign",6) == 0) + res = _exec_assign(args); + else if(strncmp(fname,"and",3) == 0) + res = _exec_andor(args, TRUE); + else + res = _exec_call(fname,args); + break; + + case 'e': + if(strncmp(fname,"eq",2) == 0) + res = _exec_iseq(mod1,mod2,args,TRUE); + else if (strncmp(fname,"echo",4) == 0) + res = _exec_echo(args); + else + res = _exec_call(fname,args); + break; + + case 'f': + if(strncmp(fname,"foreach",7) == 0) + res = _exec_foreach(mod1,mod2,args); + else + res = _exec_call(fname,args); + break; + + case 'm': + if(strncmp(fname,"mktmp",5) == 0) + res = _exec_mktmp(mod1,mod2,args); + else + res = _exec_call(fname,args); + break; + + case 'n': + if( strncmp(fname,"null", 4) == 0 ) + res = _exec_iseq(mod1,NIL(char),args,TRUE); + else if (strncmp(fname,"nil",3) == 0 ) + res = DmStrDup(""); + else if (strncmp(fname,"not",3) == 0 ) + res = _exec_not(args); + else + res = _exec_call(fname,args); + break; + + case '!': + if(strncmp(fname,"!null",5) == 0) + res = _exec_iseq(mod1,NIL(char),args,FALSE); + else if(strncmp(fname,"!eq",3) ==0) + res = _exec_iseq(mod1,mod2,args,FALSE); + else + res = _exec_call(fname,args); + break; + + case 'o': + if(strncmp(fname,"or",2) == 0) + res = _exec_andor(args, FALSE); + else + res = _exec_call(fname,args); + break; + + case 's': + if(strncmp(fname,"sort",4) == 0) + res = _exec_sort(args); + else if(strncmp(fname,"shell",5)==0) + res = _exec_shell(args,mod1); + else if(strncmp(fname,"strip",5)==0) + res = Tokenize(Expand(args)," ",'t',TRUE); + else if(strncmp(fname,"subst",5)==0) + res = _exec_subst(mod1,mod2,args); + else + res = _exec_call(fname,args); + break; + + case 'u': + if(strncmp(fname,"uniq",4) == 0) + res = _exec_uniq(args); + else + res = _exec_call(fname,args); + break; + + default: + res = _exec_call(fname,args); + } + + if( res == NIL(char) ) res = DmStrDup(""); + + FREE(fname); + return(res); +} + + +static char * +_exec_assign( macrostring ) +char *macrostring; +{ + if ( !Parse_macro(macrostring, M_MULTI|M_FORCE) ) { + Error( "Dynamic macro assignment failed, while making [%s]\n", + Current_target ? Current_target->CE_NAME : "NIL"); + return(DmStrDup("")); + } + + return(DmStrDup(LastMacName)); +} + + +static char * +_exec_echo(data) +char *data; +{ + return(DmStrDup(DmStrSpn(data," \t"))); +} + + +static char * +_exec_call( var, list ) +char *var; +char *list; +{ + char *res = NIL(char); + char *s; + TKSTR tk; + int i=0; + + list = Expand(list); + + SET_TOKEN(&tk,list); + while( *(s=Get_token(&tk, "", FALSE)) != '\0' ) { + char buf[40]; + + sprintf(buf, "%d", i++); + Def_macro(buf,s,M_MULTI|M_NOEXPORT|M_FORCE|M_PUSH); + } + CLEAR_TOKEN(&tk); + + var = DmStrJoin(DmStrJoin("$(",var,-1,FALSE),")",-1,TRUE); + res = Expand(var); + + i=0; + SET_TOKEN(&tk,list); + while( *(s=Get_token(&tk, "", FALSE)) != '\0' ) { + HASHPTR hp; + char buf[40]; + + sprintf(buf, "%d", i++); + hp = GET_MACRO(buf); + Pop_macro(hp); + FREE(hp->ht_name); + if(hp->ht_value) FREE(hp->ht_value); + FREE(hp); + } + CLEAR_TOKEN(&tk); + + FREE(var); + FREE(list); + return(res); +} + + +static char * +_exec_foreach( var, list, data ) +char *var; +char *list; +char *data; +{ + char *res = NIL(char); + char *s; + TKSTR tk; + HASHPTR hp; + + var = Expand(var); + list = Expand(list); + + data = DmStrSpn(data," \t\n"); + SET_TOKEN(&tk,list); + hp = Def_macro(var,"",M_MULTI|M_NOEXPORT|M_FORCE|M_PUSH); + + while( *(s=Get_token(&tk, "", FALSE)) != '\0' ) { + Def_macro(var,s,M_MULTI|M_NOEXPORT|M_FORCE); + res = DmStrAdd(res,Expand(data),TRUE); + } + + CLEAR_TOKEN(&tk); + Pop_macro(hp); + FREE(hp->ht_name); + if(hp->ht_value) FREE(hp->ht_value); + FREE(hp); + FREE(var); + FREE(list); + + return(res); +} + + +static char * +_exec_mktmp( file, text, data ) +char *file; +char *text; +char *data; +{ + register char *p; + char *tmpname; + char *name; + FILE *tmpfile = NIL(FILE); + + /* This is only a test of the recipe line so prevent the tempfile side + * effects. */ + if( Suppress_temp_file ) return(NIL(char)); + + name = Current_target ? Current_target->CE_NAME:"makefile text"; + + if( file && *file ) { + char *newtmp; + + /* This call to Get_temp sets TMPFILE for subsequent expansion of file. + * DO NOT DELETE IT! */ + Get_temp( &newtmp, "", FALSE ); FREE(newtmp); + tmpname = Expand(file); + + if( *tmpname ) { + if( (tmpfile = fopen(tmpname, "w")) == NIL(FILE) ) + Open_temp_error( tmpname, name ); + + Def_macro("TMPFILE", tmpname, M_EXPANDED|M_MULTI); + Link_temp( Current_target, tmpfile, tmpname ); + } + else + FREE(tmpname); + } + + if( !tmpfile ) + tmpfile = Start_temp( "", Current_target, &tmpname ); + + if( !text || !*text ) text = tmpname; + data = Expand(DmStrSpn(data, " \t\n")); + + for(p=strchr(data,'\n'); p; p=strchr(p,'\n')) { + char *q = DmStrSpn(++p," \t"); + strcpy(p,q); + } + +/* do not map escape sequences while writing a tmpfile */ +/* Append_line( data, FALSE, tmpfile, name, FALSE, TRUE ); */ + Append_line( data, FALSE, tmpfile, name, FALSE, FALSE ); + Close_temp( Current_target, tmpfile ); + FREE(data); + + return( Expand(text) ); +} + + +static char * +_exec_iseq( lhs, rhs, data, eq ) +char *lhs; +char *rhs; +char *data; +int eq; +{ + char *l = Expand(lhs); + char *r = Expand(rhs); + char *i = DmStrSpn(data, " \t\n"); + char *e = strchr(i, ' '); + char *res = NIL(char); + int val = strcmp(l,r); + + if( (!val && eq) || (val && !eq) ) { + if( e != NIL(char) ) *e = '\0'; + res = Expand(i); + } + else if( e != NIL(char) ) { + e = DmStrSpn(e," \t\n"); + if( *e ) res = Expand(e); + } + + FREE(l); + FREE(r); + return(res); +} + + +static char * +_exec_sort( args ) +char *args; +{ + char *res = NIL(char); + char *data = Expand(args); + char **tokens; + char *p; + char *white = " \t\n"; + int j; + int i; + + for(i=0,p=DmStrSpn(data,white);*p;p=DmStrSpn(DmStrPbrk(p,white),white),i++); + + if( i != 0 ) { + TALLOC(tokens, i, char *); + + for( i=0,p=DmStrSpn(data,white); *p; p=DmStrSpn(p,white),i++){ + tokens[i] = p; + p = DmStrPbrk(p,white); + if( *p ) *p++ = '\0'; + } + + qsort( tokens, i, sizeof(char *), _mystrcmp ); + + for( j=0; j<i; j++ ) res = DmStrApp(res, tokens[j]); + FREE(data); + FREE(tokens); + } + + return(res); +} + + +static char * +_exec_uniq( args ) +char *args; +{ + char *res = NIL(char); + char *data = Expand(args); + char **tokens; + char **tokens_after; + char *p; + char *white = " \t\n"; + int j; + int i; + char *last = ""; + int k = 0; + + for(i=0,p=DmStrSpn(data,white);*p;p=DmStrSpn(DmStrPbrk(p,white),white),i++); + + if( i != 0 ) { + TALLOC(tokens, i, char *); + TALLOC(tokens_after, i, char *); + + for( i=0,p=DmStrSpn(data,white); *p; p=DmStrSpn(p,white),i++){ + tokens[i] = p; + p = DmStrPbrk(p,white); + if( *p ) *p++ = '\0'; + } + + qsort( tokens, i, sizeof(char *), _mystrcmp ); + + for( j=0; j<i; j++ ) { + if (strcmp(tokens[j], last) != 0) { + tokens_after[k++] = tokens[j]; + last = tokens[j]; + } + } + + for( j=0; j<k; j++ ) res = DmStrApp(res, tokens_after[j]); + FREE(data); + FREE(tokens); + FREE(tokens_after); + } + + return(res); +} + +static int +_mystrcmp( p, q ) +CONST PVOID p; +CONST PVOID q; +{ + return(strcmp(*((CONST char **)p),*((CONST char **)q))); +} + + +static char * +_exec_subst( pat, subst, data ) +char *pat; +char *subst; +char *data; +{ + char *res; + + pat = Expand(pat); + subst = Expand(subst); + res = Apply_edit( Expand(data), pat, subst, TRUE, FALSE ); + FREE(pat); + FREE(subst); + + return(res); +} + + +static char * +_exec_shell( data, mod1 ) +char *data; +char *mod1; +{ + extern char *tempnam(); + static int nestlevel = 0; + static int org_out; + static int bsize; + static char *buffer; + static char *tmpnm; + static FILE *tmp; + + int wait = Wait_for_completion; + uint16 vflag = Verbose; + int tflag = Trace; + char *res = NIL(char); + CELL cell; + STRING rcp; + HASH cname; + + if( Suppress_temp_file ) return(NIL(char)); + + /* Set the temp CELL used for building prerequisite candidates to + * all zero so that we don't have to keep initializing all the + * fields. */ + { + register char *s = (char *) &cell; + register int n = sizeof(CELL); + while( n ) { *s++ = '\0'; n--; } + } + rcp.st_string = DmStrSpn(data, " \t+-%@"); + rcp.st_attr = Rcp_attribute( data ); + rcp.st_next = NIL(STRING); + cname.ht_name = "Shell escape"; + cell.ce_name = &cname; + cell.ce_all.cl_prq = &cell; + cell.ce_all.cl_next = NIL(LINK); + cell.ce_all.cl_flag = 0; + cell.ce_fname = cname.ht_name; + cell.ce_recipe = &rcp; + cell.ce_flag = F_TARGET|F_RULES; + cell.ce_attr = A_PHONY|A_SILENT; + + if( nestlevel == 0 ) { + tmpnm = tempnam(NIL(char),"mk"); + org_out = dup(1); + + if( (tmp = fopen(tmpnm, "w+")) == NIL(FILE) ) + Open_temp_error( tmpnm, cname.ht_name ); + + close(1); + dup( fileno(tmp) ); + + bsize = (Buffer_size < BUFSIZ)?BUFSIZ:Buffer_size; + buffer = MALLOC(bsize,char); + } + + Wait_for_completion = TRUE; + Verbose &= V_LEAVE_TMP; + Trace = FALSE; + nestlevel++; + Exec_commands( &cell ); + Unlink_temp_files( &cell ); + nestlevel--; + Trace = tflag; + Verbose = vflag; + Wait_for_completion = wait; + + /* Now we have to read the temporary file, get the tokens and return them + * as a string. */ + rewind(tmp); + while( fgets(buffer, bsize, tmp) ) { + char *p = strchr(buffer, '\n'); + + if( p == NIL(char) ) + res = DmStrJoin(res,buffer,-1,TRUE); + else { + *p = '\0'; + res = DmStrApp(res,buffer); + } + } + + fclose(tmp); + if( nestlevel == 0 ) { + close(1); + dup(org_out); + close(org_out); + Remove_file(tmpnm); + FREE(tmpnm); + FREE(buffer); + } + else { + if( (tmp = fopen(tmpnm, "w+")) == NIL(FILE) ) + Open_temp_error( tmpnm, cname.ht_name ); + + close(1); + dup( fileno(tmp) ); + } + + if ( mod1 ) { + mod1 = Expand(res); + FREE(res); + res = mod1; + } + + return(res); +} + + +static int +not (arg) +int arg; +{ + return(!arg); +} + + +static int +nop (arg) +int arg; +{ + return(arg); +} + + +static char * +_exec_andor( args, doand ) +char *args; +int doand; +{ + char *next; + char *p; + char *white = " \t\n"; + int res=doand; + + args = DmStrSpn(args,white); + do { + p=ScanToken(args, &next, TRUE); + + if (doand ? !*p : *p) { + res = !doand; + FREE(p); + break; + } + + FREE(p); + } + while (*(args=DmStrSpn(next,white))); + + return(res ? DmStrDup("t") : DmStrDup("")); +} + + +static char * +_exec_not( args ) +char *args; +{ + char *white = " \t\n"; + char *p=Expand(args); + int res = (*DmStrSpn(p,white) == '\0'); + + FREE(p); + return(res ? DmStrDup("t") : DmStrDup("")); +} diff --git a/dmake/getinp.c b/dmake/getinp.c new file mode 100644 index 000000000000..7d2af1dc8e43 --- /dev/null +++ b/dmake/getinp.c @@ -0,0 +1,671 @@ +/* RCS $Id: getinp.c,v 1.1.1.1 2000-09-22 15:33:25 hr Exp $ +-- +-- SYNOPSIS +-- Handle reading of input. +-- +-- DESCRIPTION +-- The code in this file reads the input from the specified stream +-- into the provided buffer of size Buffer_size. In doing so it deletes +-- comments. Comments are delimited by the #, and +-- <nl> character sequences. An exception is \# which +-- is replaced by # in the input. Line continuations are signalled +-- at the end of a line and are recognized inside comments. +-- The line continuation is always <\><nl>. +-- +-- If the file to read is NIL(FILE) then the Get_line routine returns the +-- next rule from the builtin rule table if there is one. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include "extern.h" + +#define IS_WHITE(A) ((A == ' ') || (A == '\t') || (A == '\n') || (A == '\r')) +#define SCAN_WHITE(A) \ + while( IS_WHITE(*A) ) A++; + +static int _is_conditional ANSI((char*)); +static int _handle_conditional ANSI((int, TKSTRPTR)); + +static int rule_ind = 0; /* index of rule when reading Rule_tab */ +static int skip = FALSE; /* if true the skip input */ + + +PUBLIC int +Get_line( buf, fil )/* +====================== + Read a line of input from the file stripping + off comments. The routine returns TRUE if EOF */ +char *buf; +FILE *fil; +{ + extern char **Rule_tab; + register char *p; + register char *c; + char *q; + char *buf_org; + static int ignore = FALSE; + int cont = FALSE; + int pos = 0; + int res; + register char *tmp = NIL(char); + + DB_ENTER( "Get_line" ); + + if( Skip_to_eof ) { + Skip_to_eof = FALSE; + rule_ind = 0; + + if( Verbose & V_MAKE ) + Warning("Ignoring remainder of file %s", Filename()); + + DB_RETURN(TRUE); + } + + if( fil == NIL(FILE) ) { + /* Reading the internal rule table. Set the rule_index to zero. + * This way ReadEnvironment works as expected every time. */ + + while( (p = Rule_tab[ rule_ind++ ]) != NIL(char) ) + /* The last test in this if *p != '~', handles the environment + * passing conventions used by MKS to pass arguments. We want to + * skip those environment entries. */ + if( !Readenv || (Readenv && (strchr(p,'=') != NIL(char)) && *p!='~')){ + strcpy( buf, p ); + + DB_PRINT( "io", ("Returning [%s]", buf) ); + DB_RETURN( FALSE ); + } + + rule_ind = 0; + + DB_PRINT( "io", ("Done Ruletab") ); + DB_RETURN( TRUE ); + } + + buf_org = buf; + +do_again: + do { + p = buf+pos; + if(feof( fil ) || (fgets( p, Buffer_size-pos, fil ) == NIL(char))) + DB_RETURN( TRUE ); + +#ifdef _MPW + if ( p[0] == 10 && p[1] == COMMENT_CHAR) + p[0] = ' '; +#endif + + Line_number++; + + /* ignore input if ignore flag set and line ends in a continuation + character. */ + q = p+strlen(p)-2; + if( q<p ) q=p; + + /* ignore each RETURN at the end of a line before any further + * processing */ + if( q[0] == '\r' && q[1] == '\n' ) { + q[0] = '\n'; + q[1] = '\0'; + q--; + } + /* you also have to deal with END_OF_FILE chars to process raw + * DOS-Files. Normally they are the last chars in file, but after + * working on these file with vi, there is an additional NEWLINE + * after the last END_OF_FILE. So if the second last char in the + * actual line is END_OF_FILE, you can skip the last char. Then + * you can search the line back until you find no more END_OF_FILE + * and nuke each you found by string termination. */ + if( q[0] == '\032' ) + q--; + while( q[1] == '\032' ) { + q[1] = '\0'; + q--; + } + + if( ignore ) { + if( q[0] != CONTINUATION_CHAR || q[1] != '\n' ) ignore = FALSE; + *p = '\0'; + continue; + } + + c = Do_comment(p, &q, Group || (*buf == '\t') || (Notabs && *buf ==' ')); + + /* Does the end of the line end in a continuation sequence? */ + + if( (q[0] == CONTINUATION_CHAR) && (q[1] == '\n')) { + /* If the continuation was at the end of a comment then ignore the + * next input line, (or lines until we get one ending in just <nl>) + * else it's a continuation, so build the input line from several + * text lines on input. The maximum size of this is governened by + * Buffer_size */ + if( q != p && q[-1] == CONTINUATION_CHAR ) { + strcpy( q, q+1 ); + q--; + cont = FALSE; + } + else if( c != NIL(char) ) + ignore = TRUE; + else + cont = TRUE; + } + else { + cont = FALSE; + } + + q = ( c == NIL(char) ) ? q+2 : c; + pos += q-p; + } + while( (cont || !*buf) && (pos <= Buffer_size) ); + + if( buf[ pos-1 ] == '\n' ) + buf[ --pos ] = '\0'; + else + if( pos == Buffer_size-1 ) + Fatal( "Input line too long, increase MAXLINELENGTH" ); + + /* STUPID AUGMAKE uses "include" at the start of a line as + * a signal to include a new file, so let's look for it. + * if we see it replace it by .INCLUDE: and stick this back + * into the buffer. We also allow GNU make if[n]eq/else/endif. + * + * These substitutions are made only if we are not parsing a group + * recipe. */ + if( (p = DmStrSpn(buf, " \t\r\n")) == NIL(char) ) + p = buf; + + if (!Group) { + if( !strncmp( "include", p, 7 ) && + (p[7] == ' ' || p[7] == '\t') ) + tmp = DmStrJoin( ".INCLUDE:", p+7, -1, FALSE ); + else if( !strncmp( "ifeq", p, 4 ) && + (p[4] == ' ' || p[4] == '\t') ) + tmp = DmStrJoin( ".IFEQ", p+4, -1, FALSE ); + else if( !strncmp( "ifneq", p, 5 ) && + (p[5] == ' ' || p[5] == '\t') ) + tmp = DmStrJoin( ".IFNEQ", p+5, -1, FALSE ); + else if( !strncmp( "elif", p, 4 ) && + (p[4] == ' ' || p[4] == '\t') ) + tmp = DmStrJoin( ".ELIF", p+4, -1, FALSE ); + else if( !strncmp( "else", p, 4 ) && + (p[4] == ' ' || p[4] == '\t' || p[4] == '\0') ) + tmp = DmStrJoin( ".ELSE", p+4, -1, FALSE ); + else if( !strncmp( "endif", p, 5 ) && + (p[5] == ' ' || p[5] == '\t' || p[5] == '\0') ) + tmp = DmStrJoin( ".END", p+5, -1, FALSE ); + } + + if( tmp != NIL(char)) { + strcpy( buf, tmp ); + FREE( tmp ); + tmp = NIL(char); + } + + /* Now that we have the next line of input to make, we should check to + * see if it is a conditional expression. If it is then process it, + * otherwise pass it on to the parser. */ + + if( *(p = DmStrSpn(buf, " \t\r\n")) == CONDSTART ) { + TKSTR token; + + SET_TOKEN( &token, p ); + + p = Get_token( &token, "", FALSE ); + + if( (res = _is_conditional(p)) != 0 ) /* ignore non-control special */ + { /* targets */ + res = _handle_conditional( res, &token ); + skip = TRUE; + } + else { + CLEAR_TOKEN( &token ); + res = TRUE; + } + } + + if( skip ) { + buf = buf_org; /* ignore line just read in */ + pos = 0; + skip = res; + goto do_again; + } + + DB_PRINT( "io", ("Returning [%s]", buf) ); + DB_RETURN( FALSE ); +} + + +PUBLIC char * +Do_comment(str, pend, keep)/* +============================= + Search the input string looking for comment chars. If it contains + comment chars then NUKE the remainder of the line, if the comment + char is preceeded by \ then shift the remainder of the line left + by one char. */ +char *str; +char **pend; +int keep; +{ + char *c = str; + + while( (c = strchr(c, COMMENT_CHAR)) != NIL(char) ) { + if( Comment || State == NORMAL_SCAN ) + if( c != str && c[-1] == ESCAPE_CHAR ) { + strcpy( c-1, c ); /* copy it left, due to \# */ + if( pend ) (*pend)--; /* shift tail pointer left */ + } + else { + if( !No_exec + && c == str + && c[1] == '!' + && Line_number == 1 + && Nestlevel() == 1 ) { + char *cmnd; + + cmnd = Expand(c+2); + cmnd[strlen(cmnd)-1] = '\0'; /* strip last newline */ + Current_target = Root; + Swap_on_exec = TRUE; + Wait_for_completion = TRUE; + Do_cmnd(cmnd, FALSE, TRUE, Current_target, FALSE, FALSE, TRUE); + } + + *c = '\0'; /* a true comment so break */ + break; + } + else { + if( keep ) + c = NIL(char); + else + *c = '\0'; + + break; + } + } + + return(c); +} + + +PUBLIC char * +Get_token( string, brk, anchor )/* +================================== + Return the next token in string. + + Returns empty string when no more tokens in string. + brk is a list of chars that also cause breaks in addition to space and + tab, but are themselves returned as tokens. if brk is NULL then the + remainder of the line is returned as a single token. + + 'anchor' if 1, says break on chars in the brk list, but only if + the entire token begins with the first char of the brk list, if + 0 then any char of brk will cause a break to occurr. + + If 'anchor' is 2, then break only seeing the first char in the break + list allowing only chars in the break list to form the prefix. */ + +TKSTRPTR string; +char *brk; +int anchor; +{ + register char *s; + register char *curp; + register char *t; + int done = FALSE; + char space[100]; + + DB_ENTER( "Get_token" ); + + s = string->tk_str; /* Get string parameters */ + *s = string->tk_cchar; /* ... and strip leading w/s */ + + SCAN_WHITE( s ); + + DB_PRINT( "tok", ("What's left [%s]", s) ); + + if( !*s ) { + DB_PRINT( "tok", ("Returning NULL token") ); + DB_RETURN( "" ); + } + + + /* Build the space list. space contains all those chars that may possibly + * cause breaks. This includes the brk list as well as white space. */ + + if( brk != NIL(char) ) { + strcpy( space, " \t\r\n" ); + strcat( space, brk ); + } + else { + space[0] = 0xff; /* a char we know will not show up */ + space[1] = 0; + } + + + /* Handle processing of quoted tokens. Note that this is disabled if + * brk is equal to NIL */ + + while( *s == '\"' && ((brk != NIL(char)) || !string->tk_quote) ) { + s++; + if( string->tk_quote ) { + curp = s-1; + do { curp = strchr( curp+1, '\"' ); } + while( (curp != NIL(char)) && (*(curp+1) == '\"')); + + if( curp == NIL(char) ) Fatal( "Unmatched quote in token" ); + string->tk_quote = !string->tk_quote; + + /* Check for "" case, and if found ignore it */ + if( curp == s ) continue; + goto found_token; + } + else + SCAN_WHITE( s ); + + string->tk_quote = !string->tk_quote; + } + + + /* Check for a token break character at the beginning of the token. + * If found return the next set of break chars as a token. */ + + if( anchor == 2 && brk != NIL(char) ) { + curp = s; + while( *curp && (strchr(brk,*curp)!=NIL(char)) && (*curp!=*brk) ) curp++; + done = (*brk == *curp++); + } + else if( (brk != NIL(char)) && (strchr( brk, *s ) != NIL(char)) ) { + curp = DmStrSpn( s, brk ); + done = (anchor == 0) ? TRUE : + ((anchor == 1)?(*s == *brk) : (*brk == curp[-1])); + } + + + /* Scan for the next token in the list and return it less the break char + * that was used to terminate the token. It will possibly be returned in + * the next call to Get_token */ + + if( !done ) { + SCAN_WHITE( s ); + + t = s; + do { + done = TRUE; + curp = DmStrPbrk(t, space); + + if( anchor && *curp && !IS_WHITE( *curp ) ) + if( ((anchor == 1)?*curp:DmStrSpn(curp,brk)[-1]) != *brk ) { + t++; + done = FALSE; + } + } + while( !done ); + + if( (curp == s) && (strchr(brk, *curp) != NIL(char)) ) curp++; + } + +found_token: + string->tk_str = curp; + string->tk_cchar = *curp; + *curp = '\0'; + + DB_PRINT( "tok", ("Returning [%s]", s) ); + DB_RETURN( s ); +} + + +static int +_is_conditional( tg )/* +======================= + Look at tg and return it's value if it is a conditional identifier + otherwise return 0. */ +char *tg; +{ + DB_ENTER( "_is_conditional" ); + + tg++; + switch( *tg ) { + case 'I': if( !strcmp( tg, "IF" )) DB_RETURN( ST_IF ); + else if( !strcmp( tg, "IFEQ" )) DB_RETURN( ST_IFEQ ); + else if( !strcmp( tg, "IFNEQ" )) DB_RETURN( ST_IFNEQ ); break; + + case 'E': + if( !strcmp( tg, "END" )) DB_RETURN( ST_END ); + else if( !strcmp( tg, "ENDIF")) DB_RETURN( ST_END ); + else if( !strcmp( tg, "ELSE" )) DB_RETURN( ST_ELSE ); + else if( !strcmp( tg, "ELIF" )) DB_RETURN( ST_ELIF ); + break; + } + + DB_RETURN( 0 ); +} + + + +#define SEEN_END 0x00 +#define SEEN_IF 0x01 +#define SEEN_ELSE 0x02 +#define SEEN_ELIF 0x04 + +#define ACCEPT_IF 0x10 +#define ACCEPT_ELIF 0x20 + +static int +_handle_conditional( opcode, tg )/* +=================================== + Perform the necessary processing for .IF conditinal targets. + Someday this should be modified to do bracketted expressions ala + CPP... sigh */ +int opcode; +TKSTRPTR tg; +{ + static short action[MAX_COND_DEPTH]; + static char ifcntl[MAX_COND_DEPTH]; + char *tok, *lhs, *rhs, *op, *expr; + char *lop, *partstr; + int result, n, m; + + DB_ENTER( "_handle_conditional" ); + + switch( opcode ) { + case ST_ELIF: + if( !(ifcntl[Nest_level] & SEEN_IF) || (ifcntl[Nest_level]&SEEN_ELSE) ) + Fatal(".ELIF without a preceeding .IF" ); + /*FALLTHRU*/ + + case ST_IF: + case ST_IFEQ: + case ST_IFNEQ: + if( opcode != ST_ELIF && (Nest_level+1) == MAX_COND_DEPTH ) + Fatal( ".IF .ELSE ... .END nesting too deep" ); + + If_expand = TRUE; + expr = Expand( Get_token( tg, NIL(char), FALSE )); + If_expand = FALSE; + lhs = DmStrSpn( expr, " \t" ); + if( !*lhs ) lhs = NIL(char); + + if ( (lop = DmStrStr(lhs, "&&" )) != NIL(char) ) + Fatal( ".IF do not support && " ); + if ( (lop = DmStrStr(lhs, "defined" )) != NIL(char) ) + Fatal( ".IF do not support defined " ); + if ( (lop = DmStrStr(lhs, "DEFINED" )) != NIL(char) ) + Fatal( ".IF do not support defined " ); +/*-----------------18.03.99 14:38------------------- + * hjs - simple OR fixed and less code +--------------------------------------------------*/ + if ( (lop = DmStrStr(lhs, "||" )) != NIL(char) ) + { +/* printf("todo: %s\n", expr ); */ + partstr = MALLOC( strlen (lhs ) + 5, char); + result = FALSE; + while(( lop = DmStrStr(lhs, "||" )) != NIL(char) ) + { + n = strlen( lop ); + m = strlen( lhs ); + strncpy( partstr, lhs, m - n ); + partstr[ m - n ] = '\0'; + result |= partcomp( partstr, opcode); + lhs = lop+2; + lhs = DmStrSpn( lhs, " \t" ); + } + result |= partcomp( lhs, opcode ); +/* + if ( result ) + printf("TRUE\n\n"); + else + printf("false\n\n"); + FREE( partstr ); +*/ + } +/*--------------------------------------------------*/ + else + result = partcomp( lhs, opcode ); + + if( expr != NIL(char) ) FREE( expr ); + + if( opcode != ST_ELIF ) { + Nest_level++; + action[Nest_level] = 1; + } + ifcntl[Nest_level] |= (opcode==ST_ELIF)?SEEN_ELIF:SEEN_IF; + + if( result ) { + if( !(ifcntl[Nest_level] & (ACCEPT_IF|ACCEPT_ELIF)) ) { + action[ Nest_level ] = action[ Nest_level-1 ]; + ifcntl[Nest_level] |= (opcode==ST_ELIF)?ACCEPT_ELIF:ACCEPT_IF; + } + else + action[Nest_level] = 1; + } + else + action[Nest_level] = 1; + break; + + case ST_ELSE: + if( Nest_level <= 0 ) Fatal( ".ELSE without .IF" ); + if( ifcntl[Nest_level] & SEEN_ELSE ) + Fatal( "Missing .IF or .ELIF before .ELSE" ); + + if( ifcntl[Nest_level] & (ACCEPT_IF|ACCEPT_ELIF) ) + action[Nest_level] = 1; + else if( action[ Nest_level-1 ] != 1 ) + action[ Nest_level ] ^= 0x1; /* flip between 0 and 1 */ + + ifcntl[Nest_level] |= SEEN_ELSE; + break; + + case ST_END: + ifcntl[Nest_level] = SEEN_END; + Nest_level--; + if( Nest_level < 0 ) Fatal( "Unmatched .END[IF]" ); + break; + } + + DB_RETURN( action[ Nest_level ] ); +} + + +int partcomp( char* lhs, int opcode ) +{ + + char *tok, *rhs, *op; + int result, opsind; + const int localopscount=4; + char* localops[]={"==","!=","<=",">="}; + int lint, rint; + +#define EQUAL 0 +#define NOTEQUAL 1 +#define LESS_EQUAL 2 +#define GREATER_EQUAL 3 + + opsind=0; +/* printf( "eval: %s\n", lhs);*/ + if( opcode == ST_IFEQ || opcode == ST_IFNEQ ) { /* no == */ + for( op = lhs; ((*op)&&(*op != ' ')&&(*op != '\t')); op++ ); + if( *op ) + op++; + else + op = NIL(char); + } else while ( opsind < localopscount && (op = DmStrStr( lhs, localops[opsind] )) == NIL(char)) + { +/* printf("%d %s\n", opsind, localops[opsind]);*/ + opsind++; + } + +/* if ( opsind == localopscount ) + Fatal( "Unknown Operator\n" );*/ + + if( op == NIL(char) ) + result = (lhs != NIL(char)); + else { +/* printf("op#%s\n",op);*/ + if( opcode != ST_IFEQ && opcode != ST_IFNEQ ) /* no == */ + op[1] = op[0]; +/* printf("op#%s\n",op);*/ + if( lhs != op ) { + for( tok = op-1; (tok != lhs) && ((*tok == ' ')||(*tok == '\t')); + tok-- ); + tok[1] = '\0'; + } + else + lhs = NIL(char); + + if( opcode == ST_IFEQ || opcode == ST_IFNEQ ) /* no == */ + op--; + else + op++; + rhs = DmStrSpn( op+1, " \t" ); + if( !*rhs ) rhs = NIL(char); + + if ( opsind > NOTEQUAL ) { +/* printf("new ops\n");*/ + switch( opsind ){ + case LESS_EQUAL: + case GREATER_EQUAL: + if ( lhs[0] == '"' ) lhs++; + if ( rhs[0] == '"' ) rhs++; + lint = atoi( lhs ); + rint = atoi( rhs ); + result = ( lint >= rint ) ? TRUE : FALSE; + if ( opsind == LESS_EQUAL && lint != rint ) + result = !result; + break; + default: + result = FALSE; + } + } + else { + if( (rhs == NIL(char)) || (lhs == NIL(char)) ) + result = (rhs == lhs) ? TRUE : FALSE; + else { + tok = rhs + strlen( rhs ); + for( tok=tok-1; (tok != lhs) && ((*tok == ' ')||(*tok == '\t')); + tok--); + tok[1] = '\0'; + + result = (strcmp( lhs, rhs ) == 0) ? TRUE : FALSE; + } + if( *op == '!' || opcode == ST_IFNEQ ) result = !result; + } + } +/* printf("partresult %d\n",result);*/ + return result; +}; + diff --git a/dmake/hash.c b/dmake/hash.c new file mode 100644 index 000000000000..c2387da4456b --- /dev/null +++ b/dmake/hash.c @@ -0,0 +1,52 @@ +/* RCS $Id: hash.c,v 1.1.1.1 2000-09-22 15:33:25 hr Exp $ +-- +-- SYNOPSIS +-- Hashing function for hash tables. +-- +-- DESCRIPTION +-- Hash an identifier. The hashing function works by computing the sum +-- of each char and the previous hash value multiplied by 129. Finally the +-- length of the identifier is added in. This way the hash depends on the +-- chars as well as the length, and appears to be sufficiently unique, +-- and is FAST to COMPUTE, unlike the previous hash function... +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include "extern.h" + +PUBLIC uint16 +Hash( id, phv )/* +================= + This function computes the identifier's hash value and returns the hash + value modulo the key size as well as the full hash value. The reason + for returning both is so that hash table searches can be sped up. You + compare hash keys instead and compare strings only for those whose 32-bit + hash keys match. (not many) */ + +char *id; +uint32 *phv; +{ + register char *p = id; + register uint32 hash = (uint32) 0; + + while( *p ) hash = (hash << 7) + hash + (uint32) (*p++); + *phv = hash = hash + (uint32) (p-id); + + return( (uint16) (hash % HASH_TABLE_SIZE) ); +} + diff --git a/dmake/imacs.c b/dmake/imacs.c new file mode 100644 index 000000000000..bb92255d7ed1 --- /dev/null +++ b/dmake/imacs.c @@ -0,0 +1,181 @@ +/* RCS $Id: imacs.c,v 1.1.1.1 2000-09-22 15:33:25 hr Exp $ +-- +-- SYNOPSIS +-- Define default internal macros. +-- +-- DESCRIPTION +-- This file adds to the internal macro tables the set of default +-- internal macros, and for those that are accessible internally via +-- variables creates these variables, and initializes them to point +-- at the default values of these macros. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include "extern.h" +#include "version.h" + +static void _set_int_var ANSI((char *, char *, int, int *)); +static void _set_string_var ANSI((char *, char *, int, char **)); +static void _set_bit_var ANSI((char *, char *, int)); + +/* +** Arrange to parse the strings stored in Rules[] +*/ +PUBLIC void +Make_rules() +{ + Parse(NIL(FILE)); +} + + +#define M_FLAG M_DEFAULT | M_EXPANDED + +/* +** Add to the macro table all of the internal macro variables plus +** create secondary variables which will give access to their values +** easily, both when needed and when the macro value is modified. +** The latter is accomplished by providing a flag in the macro and a field +** which gives a pointer to the value if it is a char or string macro value +** and a mask representing the bit of the global flag register that is affected +** by this macro's value. +*/ +PUBLIC void +Create_macro_vars() +{ + static char* switchar; + static char* version; + char swchar[2]; + char buf[20]; + + swchar[0] = Get_switch_char(), swchar[1] = '\0'; + _set_string_var("SWITCHAR", swchar, M_PRECIOUS, &switchar); + if (*swchar == '/') + DirSepStr = "\\"; + else +#if (_MPW) + DirSepStr = ":"; +#else + DirSepStr = "/"; +#endif + _set_string_var("DIRSEPSTR", DirSepStr, M_DEFAULT,&DirSepStr); + _set_string_var("DIRBRKSTR", DirBrkStr, M_DEFAULT, &DirBrkStr); + swchar[0] = DEF_ESCAPE_CHAR, swchar[1] = '\0'; + _set_string_var(".ESCAPE_PREFIX", swchar, M_FLAG, &Escape_char); + + _set_bit_var(".SILENT", "", A_SILENT ); + _set_bit_var(".IGNORE", "", A_IGNORE ); + _set_bit_var(".PRECIOUS", "", A_PRECIOUS); + _set_bit_var(".EPILOG", "", A_EPILOG ); + _set_bit_var(".PROLOG", "", A_PROLOG ); + _set_bit_var(".NOINFER", "", A_NOINFER ); + _set_bit_var(".SEQUENTIAL","",A_SEQ ); + _set_bit_var(".USESHELL", "", A_SHELL ); + _set_bit_var(".SWAP", "", A_SWAP ); + _set_bit_var(".MKSARGS", "", A_MKSARGS ); + _set_bit_var(".IGNOREGROUP","",A_IGNOREGROUP); + + Glob_attr = A_DEFAULT; /* set all flags to NULL */ + + _set_string_var("SHELL", "", M_DEFAULT, &Shell ); + _set_string_var("SHELLFLAGS", " ", M_DEFAULT, &Shell_flags ); + _set_string_var("GROUPSHELL", "", M_DEFAULT, &GShell ); + _set_string_var("GROUPFLAGS", " ", M_DEFAULT, &GShell_flags); + _set_string_var("SHELLMETAS", "", M_DEFAULT, &Shell_metas ); + _set_string_var("GROUPSUFFIX", "", M_DEFAULT, &Grp_suff ); + _set_string_var("AUGMAKE",NIL(char), M_DEFAULT, &Augmake ); + _set_string_var(".KEEP_STATE", "", M_DEFAULT, &Keep_state ); + _set_string_var(".NOTABS", "", M_MULTI, &Notabs ); + _set_string_var(".DIRCACHE", "y", M_DEFAULT, &UseDirCache ); + _set_string_var(".DIRCACHERESPECTCASE", "", M_DEFAULT, &DcacheRespCase); + + _set_string_var("MAKEDIR",Get_current_dir(),M_PRECIOUS|M_NOEXPORT,&Makedir); + _set_string_var("MAKEVERSION", VERSION, M_DEFAULT|M_PRECIOUS, &version); + _set_string_var("PWD", Makedir, M_DEFAULT|M_NOEXPORT, &Pwd); + _set_string_var("TMD", "", M_DEFAULT|M_NOEXPORT, &Tmd); + + Def_macro("NULL", "", M_PRECIOUS|M_NOEXPORT|M_FLAG); + + _set_int_var( "MAXLINELENGTH", "0", M_DEFAULT|M_NOEXPORT, &Buffer_size ); + _set_int_var( "PREP", "0", M_DEFAULT, &Prep ); + (void) Def_macro("MAXLINELENGTH", "1024", M_FLAG | M_DEFAULT); + + /* set MAXPROCESSLIMIT high initially so that it allows MAXPROCESS to + * change from command line. */ + _set_int_var( "MAXPROCESSLIMIT", "100", M_DEFAULT|M_NOEXPORT,&Max_proclmt ); + _set_int_var( "MAXPROCESS", "1", M_DEFAULT|M_NOEXPORT, &Max_proc ); + _set_int_var( "DYNAMICNESTINGLEVEL", "100", M_DEFAULT|M_NOEXPORT, + &DynamicNestLevel); + sprintf(buf,"%d",NAME_MAX); + _set_int_var( "NAMEMAX", buf, M_DEFAULT|M_NOEXPORT, &NameMax); +} + + +/* +** Define an integer variable value, and set up the macro. +*/ +static void +_set_int_var(name, val, flag, var) +char *name; +char *val; +int flag; +int *var; +{ + HASHPTR hp; + + hp = Def_macro(name, val, M_FLAG | flag); + hp->ht_flag |= M_VAR_INT | M_MULTI | M_INIT; + hp->MV_IVAR = var; + *var = atoi(val); +} + + +/* +** Define a string variables value, and set up the macro. +*/ +static void +_set_string_var(name, val, flag, var) +char *name; +char *val; +int flag; +char **var; +{ + HASHPTR hp; + + hp = Def_macro(name, val, M_FLAG | flag); + hp->ht_flag |= M_VAR_STRING | M_MULTI | M_INIT; + hp->MV_SVAR = var; + *var = hp->ht_value; +} + + +/* +** Define a bit variable value, and set up the macro. +*/ +static void +_set_bit_var(name, val, mask) +char *name; +char *val; +int mask; +{ + HASHPTR hp; + + hp = Def_macro(name, val, M_FLAG); + hp->ht_flag |= M_VAR_BIT | M_MULTI | M_INIT; + hp->MV_MASK = mask; + hp->MV_BVAR = &Glob_attr; +} diff --git a/dmake/infer.c b/dmake/infer.c new file mode 100644 index 000000000000..478db5867f9a --- /dev/null +++ b/dmake/infer.c @@ -0,0 +1,832 @@ +/* RCS $Id: infer.c,v 1.1.1.1 2000-09-22 15:33:25 hr Exp $ +-- +-- SYNOPSIS +-- Infer how to make a target. +-- +-- DESCRIPTION +-- This file contains the code to infer a recipe, and possibly some new +-- prerequisites for a target which dmake does not know how to make, or +-- has no explicit recipe. +-- +-- The inference fails if no path through the inference graph can be +-- found by which we can make the target. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include "extern.h" + +/* attributes that get transfered from the % start cell to the inferred + * cells. */ + +#define A_TRANSFER (A_EPILOG | A_PRECIOUS | A_SILENT | A_SHELL | A_SETDIR |\ + A_SEQ | A_LIBRARY | A_IGNORE | A_PROLOG | A_SWAP |\ + A_NOSTATE ) + + +/* Define local static functions */ +static DFALINKPTR dfa_subset ANSI((DFALINKPTR, DFASETPTR)); +static void free_dfas ANSI((DFALINKPTR)); +static int count_dots ANSI((char *)); +static char * buildname ANSI((char *, char *, char *)); +static void free_icells ANSI((void)); +static ICELLPTR union_iset ANSI((ICELLPTR, ICELLPTR)); +static ICELLPTR add_iset ANSI((ICELLPTR,ICELLPTR,CELLPTR,DFALINKPTR, + CELLPTR,int,int,char *,char *, int)); +static ICELLPTR derive_prerequisites ANSI((ICELLPTR, ICELLPTR *)); +static char * dump_inf_chain ANSI((ICELLPTR, int, int)); + + +PUBLIC void +Infer_recipe( cp, setdirroot )/* +================================ + Perform a breadth-first search of the inference graph and return if + possible an inferred set of prerequisites for making the current target. */ +CELLPTR cp; +CELLPTR setdirroot; +{ + ICELLPTR nomatch, match; + + DB_ENTER("Infer_recipe"); + + if( cp->ce_attr & A_NOINFER ) {DB_VOID_RETURN;} + + match = NIL(ICELL); + nomatch = add_iset( NIL(ICELL), NIL(ICELL), NIL(CELL), NIL(DFALINK), + setdirroot, Prep+count_dots(cp->CE_NAME), 0, + DmStrDup(cp->CE_NAME), NIL(char), + cp->ce_time != (time_t)0L); + + /* Make sure we try whole heartedly to infer at least one suffix */ + if( nomatch->ic_dmax == 0 ) ++nomatch->ic_dmax; + + DB_EXECUTE( "inf", _dump_iset("nomatch",nomatch); ); + + while( nomatch != NIL(ICELL) ) { + ICELLPTR new_nomatch = NIL(ICELL); + ICELLPTR ic, pmatch, mmatch; + CELLPTR prereq; + int first; + + for( ic=nomatch; ic != NIL(ICELL); ic=ic->ic_next ) { + int ipush = FALSE; + + if( ic->ic_dir ) ipush = Push_dir(ic->ic_dir, ic->ic_name, FALSE); + match = union_iset(match, derive_prerequisites(ic, &new_nomatch)); + if( ipush ) Pop_dir(FALSE); + } + + DB_EXECUTE( "inf", _dump_iset("match",match); ); + DB_EXECUTE( "inf", _dump_iset("nomatch",new_nomatch); ); + + /* We have now deduced the two sets MATCH and NOMATCH. MATCH holds the + * set of edges that we encountered that matched. If this set is empty + * then we can apply transitive closure (if enabled) to the elements of + * NOMATCH to see if we can find some other method to make the target. + * + * If MATCH is non-empty, we have found a method for making the target. + * It is the shortest method for doing so (ie. uses fewest number of + * steps). If MATCH contains more than one element then we have a + * possible ambiguity. + */ + if( match == NIL(ICELL) ) { + nomatch = new_nomatch; + if( Transitive ) continue; + goto all_done; + } + + /* Ok, we have a set of possible matches in MATCH, we should check the + * set for ambiguity. If more than one inference path exists of the + * same depth, then we may issue an ambiguous inference error message. + * + * The message is suppressed if MATCH contains two elements and one of + * them is the empty-prerequisite-rule. In this case we ignore the + * ambiguity and take the rule that infers the prerequisite. + * + * Also if there are any chains that rely on a non-existant prerequisite + * that may get made because it has a recipe then we prefer any that + * rely on existing final prerequisites over those that we have to make. + */ + + /* Split out those that have to be made from those that end in + * prerequisites that already exist. */ + pmatch = mmatch = NIL(ICELL); + for(; match; match = ic ) { + ic = match->ic_next; + match->ic_next = NIL(ICELL); + + if( match->ic_exists ) + pmatch = union_iset(pmatch, match); + else + mmatch = union_iset(mmatch, match); + } + + if( pmatch ) + match = pmatch; + else + match = mmatch; + + /* Make sure it is unique */ + if( match->ic_next != NIL(ICELL) ) { + int dump = (match->ic_next->ic_next != NIL(ICELL)); + + /* Check for definite ambiguity */ + if( !dump ) + if( (match->ic_meta->ce_prq && match->ic_next->ic_meta->ce_prq) || + (!match->ic_meta->ce_prq && !match->ic_next->ic_meta->ce_prq) ) + dump = TRUE; + else if(!match->ic_meta->ce_prq && match->ic_next->ic_meta->ce_prq ) + match = match->ic_next; + + if( dump ) { + int count = 1; + + Continue = TRUE; + Error( "Ambiguous inference chains for target '%s'", cp->CE_NAME ); + for( ic=match; ic; ic=ic->ic_next ) + (void) dump_inf_chain(ic, TRUE, count++); + Fatal( "resolve ambiguity before proceeding."); + /*NOTREACHED*/ + } + } + + /* MATCH now points at the derived recipe. We must now take cp, and + * construct the correct graph so that the make may proceed. */ + + if( Verbose & V_INFER ) { + char *tmp = dump_inf_chain(match, TRUE, FALSE); + printf("%s: Inferring prerequistes and recipes using:\n%s: ... %s\n", + Pname, Pname, tmp ); + FREE(tmp); } + + pmatch = NIL(ICELL); + prereq = NIL(CELL); + first = TRUE; + + while( match ) { + CELLPTR infcell=NIL(CELL); + + /* Compute the inferred prerequisite first. */ + if( match->ic_name ) { + if( match->ic_meta ) + infcell = Def_cell( match->ic_name ); + else + infcell = cp; + + infcell->ce_flag |= F_TARGET; + + if( infcell != cp ) { + infcell->ce_flag |= F_INFER; + if( !first ) infcell->ce_flag |= F_REMOVE; + } + + if( !match->ic_flag ) + infcell->ce_attr |= A_NOINFER; + + first = FALSE; + } + + /* Add global prerequisites from previous rule if there are any and + * the recipe. */ + if( pmatch ) { + CELLPTR imeta = pmatch->ic_meta; + LINKPTR lp; + + infcell->ce_per = pmatch->ic_dfa->dl_per; + infcell->ce_attr |= (imeta->ce_attr & A_TRANSFER); + + if( !(infcell->ce_flag & F_RULES) ) { + infcell->ce_flag |= (imeta->ce_flag&(F_SINGLE|F_GROUP))|F_RULES; + infcell->ce_recipe = imeta->ce_recipe; + } + + /* Add any conditional macro definitions that may be associated + * with the inferred cell. */ + if (imeta->ce_cond != NIL(STRING)) { + STRINGPTR sp,last; + + last = infcell->ce_cond; + for(sp=imeta->ce_cond; sp; sp=sp->st_next) { + STRINGPTR new; + TALLOC(new, 1, STRING); + new->st_string = DmStrDup(sp->st_string); + if(last) + last->st_next = new; + else + infcell->ce_cond = new; + last = new; + } + } + + pmatch->ic_dfa->dl_per = NIL(char); + + /* If infcell already had a directory set then modify it based on + * whether it was the original cell or some intermediary. */ + if( imeta->ce_dir ) + if( infcell->ce_dir && infcell == cp ) { + /* cp->ce_dir was set and we have pushed the directory prior + * to calling this routine. We should therefore pop it and + * push the new concatenated directory required by the + * inference. */ + infcell->ce_dir=DmStrDup(Build_path(infcell->ce_dir, + imeta->ce_dir)); + } + else + infcell->ce_dir = imeta->ce_dir; + + for( lp=imeta->ce_indprq; lp != NIL(LINK); lp=lp->cl_next ) { + char *name = lp->cl_prq->CE_NAME; + CELLPTR tcp; + + name = buildname( cp->CE_NAME, name, infcell->ce_per ); + tcp = Def_cell( name ); + tcp->ce_flag |= F_REMOVE; + Add_prerequisite( infcell, tcp, FALSE, FALSE ); + + if( Verbose & V_INFER ) + printf( "%s: Inferred indirect prerequisite [%s]\n", + Pname, name ); + FREE(name); + } + } + + /* Add the previous cell as the prerequisite */ + if( prereq ) + (Add_prerequisite(infcell,prereq,FALSE,FALSE))->cl_flag |=F_TARGET; + + pmatch = match; + prereq = infcell; + match = match->ic_parent; + } + + DB_PRINT("inf", ("Terminated due to a match")); + break; + } + +all_done: + free_icells(); + + DB_VOID_RETURN; +} + + +static ICELLPTR +derive_prerequisites( ic, nnmp )/* +=================================== + Take a cell and derive a set of prerequisites from the cell. Categorize + them into those that MATCH (ie. those that we found in the file system), + and those that do not match NOMATCH that we may possibly have a look at + later. When we process the next level of the breadth-first search. + + Once MATCH is non-empty we will stop inserting elements into NOMATCH + since we know that either MATCH is successful and unique or it will + issue an ambiguity error. We will never go on to look at elements + in NOMATCH after wards. */ +ICELLPTR ic; +ICELLPTR *nnmp; +{ + ICELLPTR match = NIL(ICELL); + DFALINKPTR pdfa; + DFALINKPTR dfas; + + DB_ENTER("derive_prerequisites"); + + /* If none of the inference nodes match then forget about the inference. + * The user did not tell us how to make such a target. We also stop the + * Inference if the new set of DFA's is a proper subset of a previous + * subset and it's PREP counts exceed the value of Prep. + */ + dfas = dfa_subset( Match_dfa(ic->ic_name), &ic->ic_dfastack ); + + DB_EXECUTE("inf", _dump_dfa_stack(dfas, &ic->ic_dfastack); ); + + /* Ok, we have nothing here to work with so return an empty cell. */ + if( dfas == NIL(DFALINK) ) { + DB_PRINT( "mem", ("%s:<- mem %ld",ic->ic_name, (long)coreleft())); + DB_PRINT( "inf", ("<<< Exit, no dfas, cp = %04x", NIL(CELL)) ); + DB_RETURN( NIL(ICELL) ); + } + + /* Save the dfas, we are going to use on the stack for this cell. */ + ic->ic_dfastack.df_set = dfas; + + /* Run through the %-meta cells, build the prerequisite cells. For each + * %-meta go through it's list of edges and try to use each in turn to + * deduce a likely prerequisite. We perform a breadth-first search + * matching the first path that results in a unique method for making the + * target. */ + for( pdfa = dfas; pdfa != NIL(DFALINK); pdfa = pdfa->dl_next ) { + LINK tl; + LINKPTR edge; + CELLPTR pmeta; + + pmeta = pdfa->dl_meta; + DB_PRINT( "inf", ("Using dfa: [%s]", pmeta->CE_NAME) ); + + /* If the %-meta is a singleton meta then deal with it differently from + * the case when it is a bunch of %-meta's found on the original entries + * prerequisite list. */ + if( pmeta->ce_flag & F_MULTI ) + edge = pmeta->ce_prq; + else { + tl.cl_prq = pmeta; + tl.cl_next = NIL(LINK); + edge = &tl; + } + + /* Now run through the list of prerequisite edge's for the %-meta. */ + for( ; edge != NIL(LINK); edge = edge->cl_next ) { + HASHPTR thp; /* temporary hash table pointer */ + HASH iprqh; /* hash cell for new prerequisite */ + CELL iprq; /* inferred prerequisite to look for */ + CELLPTR idirroot; /* Inferred prerequisite root */ + CELLPTR nidirroot; /* Inferred prerequisite root */ + STRINGPTR ircp; /* Inferred prerequisites recipe */ + char *idir; /* directory to CD to. */ + int ipush = 0; /* flag for push on inferred prereq */ + char *name = NIL(char); /* prerequisite name */ + CELLPTR meta = edge->cl_prq; + int dmax_fix; + int trans; + int noinf; + int exists; + + if( meta->ce_prq ) + name = meta->ce_prq->cl_prq->CE_NAME; + + DB_PRINT( "inf", ("Trying edge from [%s] to [%s] for [%s]", + meta->CE_NAME, name?name:"(nil)", ic->ic_name) ); + + /* Set the temp CELL used for building prerequisite candidates to + * all zero so that we don't have to keep initializing all the + * fields. */ + { + register char *s = (char *) &iprq; + register int n = sizeof(CELL); + while( n ) { *s++ = '\0'; n--; } + } + + nidirroot = idirroot = ic->ic_setdirroot; + iprq.ce_name = &iprqh; + + if( name ) { + /* Build the prerequisite name from the %-meta prerequisite given + * for the %-meta rule. */ + iprqh.ht_name = buildname( ic->ic_name, name, pdfa->dl_per ); + if((dmax_fix = (count_dots(name)-count_dots(meta->CE_NAME))) < 0) + dmax_fix = 0; + + if( !strcmp(ic->ic_name, iprqh.ht_name) || + (count_dots(iprqh.ht_name) > ic->ic_dmax + dmax_fix) ) { + FREE( iprqh.ht_name ); + continue; + } + + DB_PRINT( "inf", ("Checking prerequisite [%s]", iprqh.ht_name) ); + + /* See if the prerequisite CELL has been previously defined. If + * it has, then make a copy of it into iprq, and use it to try + * the inference. We make the copy so that we don't modify the + * stat of the inferred cell if the inference fails. + */ + thp = Get_name( iprqh.ht_name, Defs, FALSE ); + if(thp != NIL(HASH)) { + iprq = *thp->CP_OWNR; + ircp = iprq.ce_recipe; + } + else + ircp = NIL(STRING); + } + else + iprqh.ht_name = NIL(char); + + + /* If the %-meta has a .SETDIR set then we change to the new + * directory prior to performing the stat of the new prerequisite. + * If the change of directory fails then the rule is droped from + * further consideration. + */ + if( iprq.ce_dir ) { + if( (ipush = Push_dir(iprq.ce_dir, iprqh.ht_name, TRUE)) != 0 ) { + nidirroot = thp->CP_OWNR; + idir = Pwd; + } + else { + if( iprqh.ht_name ) FREE( iprqh.ht_name ); + continue; + } + } + else + idir = NIL(char); + + + /* Stat the inferred prerequisite. + */ + if( name ) { + if( Verbose & V_INFER ) + printf( "%s: Trying prerequisite [%s] for [%s]\n", Pname, + iprqh.ht_name, ic->ic_name ); + + if( !(iprq.ce_flag & F_STAT) ) Stat_target(&iprq, FALSE, FALSE); + } + + + /* If the STAT succeeded or if the prerequisite has a recipe for + * making it then it's a match and a candidate for getting infered. + * Otherwise it is not a match, and we cannot yet tell if it is + * going to be a successful path to follow, so we save it for + * later consideration. + */ + noinf = ((Glob_attr)&A_NOINFER); + if( meta->ce_prq ) + noinf |= ((meta->ce_prq->cl_prq->ce_attr)&A_NOINFER); + trans = Transitive || !noinf; + exists = (iprq.ce_time != (time_t)0L); + + if( exists || (ircp != NIL(STRING)) || !name ) { + match = add_iset( match, ic, meta, pdfa, idirroot, ic->ic_dmax, + trans, iprq.ce_name->ht_name, idir, exists ); + DB_PRINT("inf",("Added to MATCH %s",iprq.ce_name->ht_name)); + } + else if( !noinf && match == NIL(ICELL) ) { + *nnmp = add_iset( *nnmp, ic, meta, pdfa, nidirroot, ic->ic_dmax, + trans, iprq.ce_name->ht_name, idir, exists ); + DB_PRINT("inf",("Added to NOMATCH %s",iprq.ce_name->ht_name)); + } + + /* If we pushed a directory for the inferred prerequisite then + * pop it. + */ + if( ipush ) Pop_dir(FALSE); + if( iprqh.ht_name ) FREE(iprqh.ht_name); + } + } + + DB_RETURN(match); +} + + +static char * +buildname( tg, meta, per ) +char *tg; +char *meta; +char *per; +{ + char *name; + + name = Apply_edit( meta, "%", per, FALSE, FALSE ); + if( strchr(name, '$') ) { + HASHPTR m_at; + char *tmp; + + m_at = Def_macro( "@", tg, M_MULTI ); + tmp = Expand( name ); + + if( m_at->ht_value != NIL(char) ) { + FREE( m_at->ht_value ); + m_at->ht_value = NIL(char); + } + + if( name != meta ) FREE( name ); + name = tmp; + } + else if( name == meta ) + name = DmStrDup( name ); + + return(name); +} + + +static DFALINKPTR +dfa_subset( pdfa, stack )/* +============================ + This is the valid DFA subset computation. Whenever a CELL has a Match_dfa + subset computed this algorithm is run to see if any of the previously + computed sets on the DFA stack are proper subsets of the new set. If they + are, then any elements of the matching subset whose Prep counts exceed + the allowed maximum given by Prep are removed from the computed DFA set, + and hence from consideration, thereby cutting off the cycle in the + inference graph. */ +DFALINKPTR pdfa; +register DFASETPTR stack; +{ + register DFALINKPTR element; + DFALINKPTR nelement; + + DB_ENTER( "dfa_subset" ); + + DB_PRINT("inf",("Computing DFA subset, PREP = %d",Prep)); + DB_EXECUTE("inf", _dump_dfa_stack(pdfa, stack); ); + + for(; pdfa != NIL(DFALINK) && stack != NIL(DFASET); stack = stack->df_next) { + int subset = TRUE; + + for( element=stack->df_set; subset && element != NIL(DFALINK); + element=element->dl_next ) { + register DFALINKPTR subel; + + for( subel = pdfa; + subel != NIL(DFALINK) && (subel->dl_meta != element->dl_meta); + subel = subel->dl_next ); + + DB_PRINT("inf",("Looking for %s, (%s)",element->dl_meta->CE_NAME, + (subel != NIL(DFALINK))?"succ":"fail")); + + if( (subset = (subel != NIL(DFALINK))) != 0 ) + element->dl_member = subel; + } + + if( subset ) + for( element=stack->df_set; element != NIL(DFALINK); + element=element->dl_next ) { + DFALINKPTR mem = element->dl_member; + int npr = element->dl_prep + 1; + + if( npr > Prep ) + mem->dl_delete++; + else + mem->dl_prep = npr; + } + } + + for( element = pdfa; element != NIL(DFALINK); element = nelement ) { + nelement = element->dl_next; + + if( element->dl_delete ) { + /* A member of the subset has a PREP count equal to PREP, so + * it should not be considered further in the inference, hence + * we remove it from the doubly linked set list */ + if( element == pdfa ) + pdfa = element->dl_next; + else + element->dl_prev->dl_next = element->dl_next; + + if( element->dl_next != NIL(DFALINK) ) + element->dl_next->dl_prev = element->dl_prev; + + DB_PRINT("inf", ("deleting dfa [%s]", element->dl_meta->CE_NAME)); + FREE( element->dl_per ); + FREE( element ); + } + } + + DB_RETURN( pdfa ); +} + + + +static void +free_dfas( chain )/* +===================== + Free the list of DFA's constructed by Match_dfa, and linked together by + LINK cells. FREE the % value as well, as long as it isn't NIL. */ +DFALINKPTR chain; +{ + register DFALINKPTR tl; + + DB_ENTER( "free_dfas" ); + + for( tl=chain; tl != NIL(DFALINK); chain = tl ) { + tl = tl->dl_next; + + DB_PRINT( "inf", ("Freeing DFA [%s], %% = [%s]", chain->dl_meta->CE_NAME, + chain->dl_per) ); + + if( chain->dl_per != NIL(char) ) FREE( chain->dl_per ); + FREE( chain ); + } + + DB_VOID_RETURN; +} + + +static int +count_dots( name )/* +=====================*/ +char *name; +{ + register char *p; + register int i = 0; + + for( p = name; *p; p++ ) if(*p == '.') i++; + + return( i ); +} + + +static ICELLPTR _icells = NIL(ICELL); +#ifdef DBUG +static int _icell_cost = 0; +#endif + +static ICELLPTR +add_iset( iset, parent, meta, dfa, setdirroot, dmax, noinf, name, dir, exists) +ICELLPTR iset; +ICELLPTR parent; +CELLPTR meta; +DFALINKPTR dfa; +CELLPTR setdirroot; +int dmax; +int noinf; +char *name; +char *dir; +int exists; +{ + ICELLPTR icell; + + DB_ENTER("add_iset"); + TALLOC(icell, 1, ICELL); + + DB_EXECUTE("inf", _icell_cost+=(sizeof(ICELL)+strlen(dir?dir:"")+strlen(name?name:"")+2);); + + icell->ic_meta = meta; + icell->ic_dfa = dfa; + icell->ic_setdirroot = setdirroot; + + if( parent ) icell->ic_dfastack.df_next = &parent->ic_dfastack; + + icell->ic_dmax = dmax; + icell->ic_dir = DmStrDup(dir); + icell->ic_name = DmStrDup(name); + icell->ic_parent = parent; + icell->ic_next = iset; + icell->ic_flag = noinf; + icell->ic_exists = exists; + + icell->ic_link = _icells; + _icells = icell; + + DB_RETURN(icell); +} + + +static void +free_icells() +{ + register ICELLPTR ic; + + DB_ENTER("free_icells"); + + for( ; _icells; _icells = ic ) { + ic = _icells->ic_link; + + free_dfas(_icells->ic_dfastack.df_set); + if( _icells->ic_dir ) FREE(_icells->ic_dir); + if( _icells->ic_name) FREE(_icells->ic_name); + FREE(_icells); + } + + DB_PRINT("inf",("Used %d memory for icells",_icell_cost)); + DB_EXECUTE("inf", _icell_cost=0; ); + + DB_VOID_RETURN; +} + + +static ICELLPTR +union_iset( iset, uset ) +ICELLPTR iset; +ICELLPTR uset; +{ + register ICELLPTR ic; + + if( iset == NIL(ICELL) ) return(uset); + + for( ic=iset; ic->ic_next != NIL(ICELL); ic=ic->ic_next ); + ic->ic_next = uset; + + return(iset); +} + + +static char * +dump_inf_chain( ip, flag, print )/* +====================================*/ +ICELLPTR ip; +int flag; +int print; +{ + char *tmp; + + if( ip == NIL(ICELL) ) return(NIL(char)); + + tmp = dump_inf_chain(ip->ic_parent, FALSE, FALSE); + + if( ip->ic_meta ) { + tmp = DmStrJoin(tmp, "(", -1, TRUE); + tmp = DmStrJoin(tmp, ip->ic_meta->CE_NAME, -1, TRUE); + + if( ip->ic_dir && !*ip->ic_dir ) { + tmp = DmStrJoin(tmp, "[", -1, TRUE); + if( strncmp(Makedir,ip->ic_dir, strlen(Makedir)) ) + tmp = DmStrJoin(tmp, ip->ic_dir, -1, TRUE); + else + tmp = DmStrJoin(tmp, ip->ic_dir+strlen(Makedir)+1, -1, TRUE); + tmp = DmStrJoin(tmp, "]", -1, TRUE); + } + tmp = DmStrJoin(tmp, (ip->ic_name)?") -->":")", -1, TRUE); + } + + if( ip->ic_name ) tmp = DmStrApp( tmp, ip->ic_name ); + + if( flag && ip->ic_meta->ce_prq) { + tmp = DmStrJoin(tmp, "(", -1, TRUE); + tmp = DmStrJoin(tmp, ip->ic_meta->ce_prq->cl_prq->CE_NAME, -1, TRUE); + tmp = DmStrJoin(tmp, ")", -1, TRUE); + } + + if( print ) { + fprintf( stderr, "%s: %2d. %s\n", Pname, print, tmp ); + FREE(tmp); + tmp = NIL(char); + } + + return(tmp); +} + + +#ifdef DBUG +_dump_dfa_stack(dfas, dfa_stack) +DFALINKPTR dfas; +DFASETPTR dfa_stack; +{ + register DFALINKPTR pdfa; + char *tmp = NIL(char); + DFASETPTR ds; + + for( pdfa = dfas; pdfa != NIL(DFALINK); pdfa = pdfa->dl_next ) + tmp = DmStrApp( tmp, pdfa->dl_meta->CE_NAME ); + + tmp = DmStrApp( tmp, ":: {" ); + for( ds = dfa_stack; ds != NIL(DFASET); ds = ds->df_next ) { + tmp = DmStrApp( tmp, "[" ); + for( pdfa = ds->df_set; pdfa != NIL(DFALINK); pdfa = pdfa->dl_next ) + tmp = DmStrApp( tmp, pdfa->dl_meta->CE_NAME ); + tmp = DmStrApp( tmp, "]" ); + } + tmp = DmStrApp( tmp, "}" ); + + printf( "DFA set and stack contents:\n%s\n", tmp ); + FREE(tmp); +} + + +_dump_iset( name, iset ) +char *name; +ICELLPTR iset; +{ + int cell = 0; + + printf( "**** ISET for %s\n", name ); + for( ; iset != NIL(ICELL); iset = iset->ic_next ){ + printf( "cell %d\n", cell++ ); + if( iset->ic_meta ) + printf( "edge: %s --> %s\n", iset->ic_meta->CE_NAME, + iset->ic_meta->ce_prq ? + iset->ic_meta->ce_prq->cl_prq->CE_NAME : + "(nil)" ); + else + printf( "edge: (nil)\n" ); + + if( iset->ic_dfa ) + printf( "dfa: %s\n", iset->ic_dfa->dl_meta->CE_NAME ); + else + printf( "dfa: (nil)\n" ); + + printf( "sdr: %04x\n", iset->ic_setdirroot ); + _dump_dfa_stack(iset->ic_dfastack.df_set, &iset->ic_dfastack); + + printf( "dmax: %d\n", iset->ic_dmax ); + printf( "name: %s\n", iset->ic_name ); + printf( "dir: %s\n", iset->ic_dir?iset->ic_dir:"(nil)" ); + + printf( "parent: " ); + if( iset->ic_parent ) + if( iset->ic_parent->ic_meta ) + printf( "%s --> %s\n", + iset->ic_parent->ic_meta->CE_NAME, + iset->ic_parent->ic_meta->ce_prq ? + iset->ic_parent->ic_meta->ce_prq->cl_prq->CE_NAME : + "(nil)" ); + else + printf( "(nil)\n" ); + else + printf( "(nil)\n" ); + } + printf( "==================================\n" ); +} +#endif diff --git a/dmake/itypes.h b/dmake/itypes.h new file mode 100644 index 000000000000..a218c9e0704b --- /dev/null +++ b/dmake/itypes.h @@ -0,0 +1,47 @@ +/* RCS $Id: itypes.h,v 1.1.1.1 2000-09-22 15:33:25 hr Exp $ +-- +-- SYNOPSIS +-- Type declarations for common types +-- +-- DESCRIPTION +-- portable type declarations. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + + +#ifndef ITYPES_h +#define ITYPES_h + +#if defined(M_I86) || defined(MC68000) +typedef char int8; /* typedefs for right size ints */ +typedef int int16; +typedef long int32; +typedef unsigned char uint8; +typedef unsigned int uint16; +typedef unsigned long uint32; +#else +typedef char int8; /* typedefs for right size ints */ +typedef short int16; +typedef long int32; +typedef unsigned char uint8; +typedef unsigned short uint16; +typedef unsigned long uint32; +#endif + +#endif + diff --git a/dmake/mac/arlib.c b/dmake/mac/arlib.c new file mode 100644 index 000000000000..2f06bca68f9e --- /dev/null +++ b/dmake/mac/arlib.c @@ -0,0 +1,56 @@ +/* RCS $Id: arlib.c,v 1.1.1.1 2000-09-22 15:33:26 hr Exp $ +-- +-- SYNOPSIS +-- Library access code. +-- +-- DESCRIPTION +-- This implementation uses the library timestamp inplace of the +-- library member timestamp. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include "extern.h" + +PUBLIC time_t +seek_arch(name, lib) +char* name; +char* lib; +{ + static int warned = FALSE; + + if (!warned && !(Glob_attr&A_SILENT)) + warned = TRUE, + Warning("Can't extract library member timestamp;\n\ + using library timestamp instead."); + return (Do_stat(lib, NULL, NULL, TRUE)); +} + +PUBLIC int +touch_arch(name, lib) +char* name; +char* lib; +{ + static int warned = FALSE; + + if (!warned && !(Glob_attr&A_SILENT)) + warned = TRUE, + Warning("Can't update library member timestamp;\n\ + touching library instead."); + return (Do_touch(lib, NULL, NULL)); +} + diff --git a/dmake/mac/bogus.c b/dmake/mac/bogus.c new file mode 100644 index 000000000000..efd7d39b9470 --- /dev/null +++ b/dmake/mac/bogus.c @@ -0,0 +1,99 @@ +/* RCS $Id: bogus.c,v 1.1.1.1 2000-09-22 15:33:27 hr Exp $ +-- +-- SYNOPSIS +-- Write the shell of subroutines we can't or don't +-- need to implement +-- +-- DESCRIPTION +-- dmake uses a couple of functions which I am either unable to figure out +-- how to implement or which are not needed. The shells of these routines +-- are in this file. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include "extern.h" + + + +/* + * tzset() is a Microsoft "extension" to ANSI C. It sets global + * variables telling if we are in dayling savings time, the time + * zone, and difference between the current time and GMT. + * None of these globals are used by dmake, so this routine is + * not needed + */ +PUBLIC void +tzset () +{ +} + + + +/* + * Add an environmental variable that child processes can use. + * Since MPW currently doesn't allow child processes, this isn't + * needed. + */ +PUBLIC int +putenv (char *pEnvString) +{ + return (0); +} + + + +/* + * Execute a child process. This may be able to be done with + * the MPW system() call someday, but cannot be done currently. + */ +PUBLIC int +runargv (CELLPTR target, int ignore, int, + int last, int shell, char *pCmd) +{ + static int warned = FALSE; + + if (!warned && !(Glob_attr & A_SILENT)) { + warned = TRUE; + Fatal ("Can't execute any targets: use '-n' option."); + } /* if */ + + return (0); +} /* int runargv () */ + + + +/* + * Wait for the child process to complete. Only needed to be implemented + * if we could executing multiple processes at once. + */ +PUBLIC int +Wait_for_child(int abort_flg, int pid) +{ + return (1); +} + + + +/* + * Do any cleanup for any processes when we quit. + */ +PUBLIC void +Clean_up_processes() +{ +} diff --git a/dmake/mac/config.mk b/dmake/mac/config.mk new file mode 100644 index 000000000000..2a6806cff159 --- /dev/null +++ b/dmake/mac/config.mk @@ -0,0 +1,44 @@ +# This is an OS Mac specific configuration file +# It assumes that OBJDIR, TARGET and DEBUG are previously defined. +# It defines CFLAGS, LDARGS, CPPFLAGS, STARTUPFILE, LDOBJS +# It augments SRC, OBJDIR, TARGET, CFLAGS, LDLIBS +# + +STARTUPFILE = :$(OS):startup.mk + +CPPFLAGS = $(CFLAGS) +LDOBJS = $(CSTARTUP) :$(OBJDIR):{$(<:f)} +LDARGS = $(LDFLAGS) -o $@ $(LDOBJS) $(LDLIBS) + +# Debug flags +DB_CFLAGS = -sym on +DB_LDFLAGS = -sym on +DB_LDLIBS = + +# NO Debug flags +NDB_CFLAGS = -sym off +NDB_LDFLAGS = -sym off +NDB_LDLIBS = + +# Local configuration modifications for CFLAGS. +CFLAGS += -I :$(OS) -d _MPW -s $(<:b) +LDFLAGS += -w -c 'MPS ' -t MPST + +# Since we writing out what files we want to execute, we can't use .SETDIR +# to specify the files to compile in the Mac directory. +# Instead, we copy the files to the (top-level) current directory and compile +# them there. +%.c : ":$(OS):%.c" + duplicate -y $< $@ + +# Common Mac source files. +OS_SRC = arlib.c bogus.c dirbrk.c directry.c environ.c main.c rmprq.c \ + ruletab.c tempnam.c tomacfil.c +.IF $(SHELL) != mwp + .SETDIR=$(OS) : $(OS_SRC) +.ENDIF +SRC += $(OS_SRC) + +# Set source dirs so that we can find files named in this +# config file. +.SOURCE.h : $(OS) diff --git a/dmake/mac/dirbrk.c b/dmake/mac/dirbrk.c new file mode 100644 index 000000000000..c584ad22cad1 --- /dev/null +++ b/dmake/mac/dirbrk.c @@ -0,0 +1,42 @@ +/* RCS $Id: dirbrk.c,v 1.1.1.1 2000-09-22 15:33:27 hr Exp $ +-- +-- SYNOPSIS +-- Define the directory separator string. +-- +-- DESCRIPTION +-- Define this string for any character that may appear in a path name +-- and can be used as a directory separator. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include "extern.h" + +/* mac only uses ':' */ +char* DirBrkStr = ":"; + +/* +** Return TRUE if the name is the full specification of a path name to a file +** starting at the root of the file system, otherwise return FALSE +*/ +PUBLIC int +If_root_path(name) +char *name; +{ + return( (strchr(name, ':') != NIL(char)) && + (name[0] != ':') ); +} diff --git a/dmake/mac/directry.c b/dmake/mac/directry.c new file mode 100644 index 000000000000..b1d452d073ba --- /dev/null +++ b/dmake/mac/directry.c @@ -0,0 +1,264 @@ +/* RCS $Id: directry.c,v 1.1.1.1 2000-09-22 15:33:27 hr Exp $ +-- +-- SYNOPSIS +-- Fake directory and file functions for the Mac +-- +-- DESCRIPTION +-- This file contains implementations for some ANSI standard routines dmake +-- uses which are not otherwise available for the mac. +-- +-- Assume we are using at least 128K ROMS. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include <Errors.h> +#include <Files.h> +#include <OSUtils.h> +#include <StdLib.h> +#include <Strings.h> +/* + * We now include LowMem.h instead of SysEqu.h as LowMem.h is what Apple recommends + * we use. + */ +#include <LowMem.h> +#include "extern.h" + + + +/* + * Implementation of stat function for dmake on the mac. + * + * Many fields aren't filled in, and the times are seconds from 1/1//1904, + * but it should be enough for dmake (I think we only need st_mtime and + * st_mode's S_IFDIR set correctly). + */ +PUBLIC int +stat(pPath, pStat) +char *pPath; +struct stat *pStat; +{ + CInfoPBRec infoPB; + OSErr err; + int retVal; + + infoPB.hFileInfo.ioCompletion = NULL; + infoPB.hFileInfo.ioNamePtr = c2pstr (pPath); + infoPB.hFileInfo.ioVRefNum = 0; + infoPB.hFileInfo.ioFDirIndex = 0; + infoPB.hFileInfo.ioDirID = 0; + err = PBGetCatInfo(&infoPB, FALSE); + p2cstr ((StringPtr) pPath); + + if (err == noErr) { + pStat->st_mtime = (time_t) infoPB.hFileInfo.ioFlMdDat; + pStat->st_ctime = (time_t) infoPB.hFileInfo.ioFlCrDat; + pStat->st_mode = S_IREAD | S_IEXEC; + + /* If it is a directory ... */ + if (infoPB.hFileInfo.ioFlAttrib & 0x10) { + pStat->st_size = infoPB.dirInfo.ioDrNmFls; + pStat->st_mode |= S_IFDIR; + } else { + pStat->st_size = infoPB.hFileInfo.ioFlLgLen; + pStat->st_mode |= S_IFREG; + } /* if ... else */ + + /* If it is writeable */ + if ((infoPB.hFileInfo.ioFlAttrib & 0x1) == 0) { + pStat->st_mode |= S_IWRITE; + } /* if */ + + retVal = 0; + + } else { + retVal = -1; + } /* if ... else */ + + return (retVal); +} /* PUBLIC int stat () */ + + + +/* + * Return the current working directory, or NULL if there is an error. + */ +PUBLIC char * +getcwd(char *pPath, size_t pathSize) +{ + DirInfo dirInfo; + OSErr err; + Str255 dirName; + char *pBeginName; + char *pC; + size_t len; + size_t spaceForColon; + + /* Set up the info for the PBGetCatInfo() calls */ + dirInfo.ioCompletion = NULL; + dirInfo.ioNamePtr = dirName; + dirInfo.ioVRefNum = 0; + dirInfo.ioFDirIndex = -1; + dirInfo.ioDrDirID = 0; + pBeginName = pPath + pathSize - 1; + spaceForColon = 0; /* Make sure we don't have an end colon on the name */ + + /* + * Keep going up the directory path until the end is reached or an error + * occurs. Ideally, we would check for errors at every level and stop + * when we received an fnfErr (File Not Found), but it appears that there + * are some problems with network volumes. (During testing, I received + * a paramErr (No Default Volume) beyond the top level.) Thus, to keep it + * simple, I assume any error past the first directory indicates we have + * seen all directories. + */ + while (TRUE) { + err = PBGetCatInfo ((CInfoPBPtr) &dirInfo, FALSE); + len = ((size_t)(unsigned char) dirName[0]); + if ((err == noErr) && (len < pBeginName - pPath)) { + p2cstr (dirName); + pBeginName -= len + spaceForColon; + strcpy (pBeginName, (char *)dirName); + /* Note that strcpy() adds the '\0' at the end of + the first directory for us */ + if (spaceForColon == 1) { + pBeginName[len] = ':'; + } else { + /* The end of the string shouldn't have a ':' */ + spaceForColon = 1; + } /* if */ + + /* Set up for the next call to PBGetCatInfo() with + the parent's directory ID */ + dirInfo.ioDrDirID = dirInfo.ioDrParID; + + } else if (spaceForColon == 1) { + /* We got past the top-level directory */ + break; + + } else { + /* We either have an error when looking at the first directory + or have run out of room. */ + return (NULL); + } /* if ... elses */ + } /* while */ + + /* Now copy the directory string to the beginning of the path string. + (It's possible the directory already starts at the beginning of the + string, but this is unlikely and doesn't hurt anything if it does, + so we don't bother to check for it.) */ + pC = pPath; + while ((*(pC++) = *(pBeginName++)) != '\0') + ; + + return (pPath); +} /* PUBLIC char *getcwd () */ + + + +/* + * Change the directory to a new default directory. + * + * Return 0 if successful, or -1 if there is an error. + */ +PUBLIC int +chdir(char *pPath) +{ + WDPBRec WDPB; + VolumeParam vParam; + OSErr err; + int result; + char *pC; + char c; + + /* Set up the directory */ + c2pstr (pPath); + WDPB.ioCompletion = NULL; + WDPB.ioNamePtr = (unsigned char *)pPath; + WDPB.ioVRefNum = 0; + WDPB.ioWDProcID = 0; + WDPB.ioWDDirID = 0; + err = PBOpenWD (&WDPB, FALSE); + /* Restore path to a C-type string in case the caller wants + to use it after this call. */ + p2cstr ((unsigned char *)pPath); + if (err != noErr) { + return (-1); + } /* if */ + + /* Set up the volume if necessary */ + if (*pPath != ':') { + for (pC = pPath + 1; (*pC != ':') && (*pC != '\0'); ++pC) + ; + c = *pC; + *pC = '\0'; + vParam.ioCompletion = NULL; + vParam.ioNamePtr = c2pstr (pPath); + vParam.ioVRefNum = WDPB.ioVRefNum; + err = PBSetVol ((ParmBlkPtr) &vParam, FALSE); + p2cstr ((unsigned char *)pPath); + *pC = c; + result = ((err == noErr) ? 0 : -1); + + } else { + result = 0; + } /* if ... else */ + + return (result); +} /* PUBLIC int chdir () */ + + + +/* + * Change the modification time for the file to the current time. + * + * The normal version of utime can set the modification time to any + * time, this function aborts the function if this is tried. + * + * We return 0 if the modification time was updated and -1 if there + * was an error. + */ +PUBLIC int +utime(char *pPath, time_t *pTimes) +{ + CInfoPBRec infoPB; + OSErr err; + + if (pTimes != NULL) { + Fatal ("SUBROUTINE SHORTCOMING: utime cannot take a utimbuf struct"); + } /* if */ + + /* Get the old info */ + infoPB.hFileInfo.ioCompletion = NULL; + infoPB.hFileInfo.ioNamePtr = c2pstr (pPath); + infoPB.hFileInfo.ioVRefNum = 0; + infoPB.hFileInfo.ioFDirIndex = 0; + infoPB.hFileInfo.ioDirID = 0; + err = PBGetCatInfo (&infoPB, FALSE); + if (err != noErr) { + p2cstr ((StringPtr) pPath); + return (-1); + } /* if */ + + /* Change the modification time and set the new info */ + GetDateTime (&(infoPB.hFileInfo.ioFlMdDat)); + infoPB.hFileInfo.ioDirID = 0; + err = PBSetCatInfo (&infoPB, FALSE); + p2cstr ((StringPtr) pPath); + return ((err == noErr) ? 0 : -1); +} /* PUBLIC int utime () */ diff --git a/dmake/mac/dompwmak b/dmake/mac/dompwmak new file mode 100644 index 000000000000..c71ed12ca16d --- /dev/null +++ b/dmake/mac/dompwmak @@ -0,0 +1,67 @@ +newfolder objects +c -I. -I :mac -d _MPW -s infer -sym off -o :objects:infer.c.o infer.c +c -I. -I :mac -d _MPW -s make -sym off -o :objects:make.c.o make.c +c -I. -I :mac -d _MPW -s stat -sym off -o :objects:stat.c.o stat.c +c -I. -I :mac -d _MPW -s expand -sym off -o :objects:expand.c.o expand.c +c -I. -I :mac -d _MPW -s dmstring -sym off -o :objects:dmstring.c.o dmstring.c +c -I. -I :mac -d _MPW -s hash -sym off -o :objects:hash.c.o hash.c +c -I. -I :mac -d _MPW -s dag -sym off -o :objects:dag.c.o dag.c +c -I. -I :mac -d _MPW -s dmake -sym off -o :objects:dmake.c.o dmake.c +c -I. -I :mac -d _MPW -s path -sym off -o :objects:path.c.o path.c +c -I. -I :mac -d _MPW -s imacs -sym off -o :objects:imacs.c.o imacs.c +c -I. -I :mac -d _MPW -s sysintf -sym off -o :objects:sysintf.c.o sysintf.c +c -I. -I :mac -d _MPW -s parse -sym off -o :objects:parse.c.o parse.c +c -I. -I :mac -d _MPW -s getinp -sym off -o :objects:getinp.c.o getinp.c +c -I. -I :mac -d _MPW -s quit -sym off -o :objects:quit.c.o quit.c +c -I. -I :mac -d _MPW -s state -sym off -o :objects:state.c.o state.c +c -I. -I :mac -d _MPW -s basename -sym off -o :objects:basename.c.o basename.c +c -I. -I :mac -d _MPW -s dmdump -sym off -o :objects:dmdump.c.o dmdump.c +c -I. -I :mac -d _MPW -s macparse -sym off -o :objects:macparse.c.o macparse.c +c -I. -I :mac -d _MPW -s rulparse -sym off -o :objects:rulparse.c.o rulparse.c +c -I. -I :mac -d _MPW -s percent -sym off -o :objects:percent.c.o percent.c +c -I. -I :mac -d _MPW -s function -sym off -o :objects:function.c.o function.c +duplicate -y :mac:arlib.c arlib.c +c -I. -I :mac -d _MPW -s arlib -sym off -o :objects:arlib.c.o arlib.c +delete arlib.c +duplicate -y :mac:bogus.c bogus.c +c -I. -I :mac -d _MPW -s bogus -sym off -o :objects:bogus.c.o bogus.c +delete bogus.c +duplicate -y :mac:dirbrk.c dirbrk.c +c -I. -I :mac -d _MPW -s dirbrk -sym off -o :objects:dirbrk.c.o dirbrk.c +delete dirbrk.c +duplicate -y :mac:directry.c directry.c +c -I. -I :mac -d _MPW -s directry -sym off -o :objects:directry.c.o directry.c +delete directry.c +duplicate -y :mac:environ.c environ.c +c -I. -I :mac -d _MPW -s environ -sym off -o :objects:environ.c.o environ.c +delete environ.c +duplicate -y :mac:main.c main.c +c -I. -I :mac -d _MPW -s main -sym off -o :objects:main.c.o main.c +delete main.c +duplicate -y :mac:rmprq.c rmprq.c +c -I. -I :mac -d _MPW -s rmprq -sym off -o :objects:rmprq.c.o rmprq.c +delete rmprq.c +duplicate -y :mac:ruletab.c ruletab.c +c -I. -I :mac -d _MPW -s ruletab -sym off -o :objects:ruletab.c.o ruletab.c +delete ruletab.c +duplicate -y :mac:tempnam.c tempnam.c +c -I. -I :mac -d _MPW -s tempnam -sym off -o :objects:tempnam.c.o tempnam.c +delete tempnam.c +duplicate -y :mac:tomacfil.c tomacfil.c +c -I. -I :mac -d _MPW -s tomacfil -sym off -o :objects:tomacfil.c.o tomacfil.c +delete tomacfil.c +Set p1 ":objects:infer.c.o :objects:make.c.o :objects:stat.c.o :objects:expand.c.o" +Set p2 ":objects:dmstring.c.o :objects:hash.c.o :objects:dag.c.o :objects:dmake.c.o" +Set p3 ":objects:path.c.o :objects:imacs.c.o :objects:sysintf.c.o :objects:parse.c.o" +Set p4 ":objects:getinp.c.o :objects:quit.c.o :objects:state.c.o :objects:basename.c.o" +Set p5 ":objects:dmdump.c.o :objects:macparse.c.o :objects:rulparse.c.o" +Set p6 ":objects:percent.c.o :objects:function.c.o :objects:arlib.c.o :objects:bogus.c.o" +Set p7 ":objects:dirbrk.c.o :objects:directry.c.o :objects:environ.c.o :objects:main.c.o" +Set p8 ":objects:rmprq.c.o :objects:ruletab.c.o :objects:tempnam.c.o" +Set p9 ":objects:tomacfil.c.o Micah:MPW:Libraries:CLibraries:CSANELib.o" +Set p10 "Micah:MPW:Libraries:CLibraries:Math.o" +Set p11 "Micah:MPW:Libraries:CLibraries:StdCLib.o" +Set p12 "Micah:MPW:Libraries:Libraries:Runtime.o" +Set p13 "Micah:MPW:Libraries:Libraries:Interface.o Micah:MPW:Libraries:Libraries:Toollibs.o" +link -w -c 'MPS ' -t MPST -sym off -o dmake {p1} {p2} {p3} {p4} {p5} {p6} {p7} {p8} {p9} {p10} {p11} {p12} {p13} +duplicate :mac:startup.mk startup.mk diff --git a/dmake/mac/environ.c b/dmake/mac/environ.c new file mode 100644 index 000000000000..b9bd6d014da9 --- /dev/null +++ b/dmake/mac/environ.c @@ -0,0 +1,231 @@ +/* RCS $Id: environ.c,v 1.1.1.1 2000-09-22 15:33:27 hr Exp $ +-- +-- SYNOPSIS +-- Set up and free for environ +-- +-- DESCRIPTION +-- This file contains routines that will fill in and dispose of the +-- list of environmental variables in the environ global variable. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include "extern.h" + +/* The char used to replace the equal signs in environmental variable names. */ +const char kEqualReplace = '_'; + +/* Maximum size of a "name=value" environmental string, including the ending '\0'. + Larger environmental variables will be clipped before dmake sees them. + (Caution: When I tested the program, the Mac or dmake trashed memory + when environmental variables of >4K were read in. I looked around a bit + and couldn't find out the exact cause, so I simply made this variable. + The memory trashing may be related to the value for MAXLINELENGTH.) */ +const int kMaxEnvLen = 1024; + + +/* The list of environmental variables in the form "name=value". + (Once make_env() has been called.) */ +char **environ = NULL; + +/* Characters replaced during make_env() */ +struct ReplaceChar { + char *fpPos; + char fC; + struct ReplaceChar *fpNext; +}; /* struct ReplaceChar */ +struct ReplaceChar *gpReplaceList = NULL; + + +void AddReplace (char *pReplacePos); + + + +/* + * Set up the environmental variables in a format used by + * the environ global variable. + * + * environ has already been set to main's envp argument when + * this suboroutine is called. We assume that envp is a copy + * MPW makes for this process' use alone, so we can modify it + * below. + */ +PUBLIC void +make_env() +{ + char **ppCurEnv; + char *pCurPos; +#if 0 + char **ppMacEnv; + char *pMacPos; + + if (!gMECalled) { + gMECalled = TRUE; + +environ = MALLOC (1, char *); +*environ = NULL; +#endif +#if 0 +{ + int numenv; + int len; + int firstnil; + + numenv = 1; + ppMacEnv = environ; + while (*(ppMacEnv++) != NULL) { + ++numenv; + } /* while */ + + ppMacEnv = environ; + if ((environ = MALLOC (numenv, char *)) == NULL) { + No_ram (); + } /* if */ + +numenv = 80; + for (ppCurEnv = environ; (numenv-- > 0) && (*ppMacEnv != NULL); ++ppCurEnv, ++ppMacEnv) { + pMacPos = *ppMacEnv; + len = strlen (pMacPos) + 1; + len += strlen (pMacPos + len) + 1; +#define MAXLEN 4098 +if (len > MAXLEN) len = MAXLEN; + if ((*ppCurEnv = MALLOC (len, char)) == NULL) { + No_ram (); + } /* if */ + + firstnil = TRUE; + for (pCurPos = *ppCurEnv; ((pCurPos - *ppCurEnv) < MAXLEN - 1); ++pCurPos, ++pMacPos) { + if (*pMacPos == '=') { + *pCurPos = gEqualReplace; + + } else if (*pMacPos == '\0') { + if (firstnil) { + *pCurPos = '='; + firstnil = FALSE; + } else { + *pCurPos = *pMacPos; + break; + } /* if ... else */ + + } else { + *pCurPos = *pMacPos; + } /* if ... elses */ + } /* for */ +firstnil = FALSE; + } /* for */ + *ppCurEnv = NULL; +} +#endif +{ + int firstnil; + + /* Get rid of any equal signs in any environmental name, and put + equal signs between the names and their values */ + for (ppCurEnv = environ; *ppCurEnv != NULL; ++ppCurEnv) { + + firstnil = TRUE; + for (pCurPos = *ppCurEnv; + ((pCurPos - *ppCurEnv < kMaxEnvLen - 1) && + ((*pCurPos != '\0') || firstnil)); + ++pCurPos) { + if (*pCurPos == '=') { + AddReplace (pCurPos); + *pCurPos = kEqualReplace; + + } else if (*pCurPos == '\0') { + AddReplace (pCurPos); + *pCurPos = '='; + firstnil = FALSE; + } /* if ... else if */ + } /* for */ + + /* If the environtmental variable was too large ... */ + if (*pCurPos != '\0') { + AddReplace (pCurPos); + *pCurPos = '\0'; + if (firstnil) { + AddReplace (--pCurPos); + *pCurPos = '='; + } /* if */ + } /* if */ + } /* for */ +} +#if 0 + } /* if */ +#endif +} /* PUBLIC void make_env () */ + + +/* + * The character at pReplacePos is about to be replaced. Remember the + * old value so we can restore it when we're done. + */ +void AddReplace (char *pReplacePos) { + struct ReplaceChar *pReplaceChar; + + if ((pReplaceChar = MALLOC (1, struct ReplaceChar)) == NULL) { + No_ram (); + } /* if */ + pReplaceChar->fpPos = pReplacePos; + pReplaceChar->fC = *pReplacePos; + pReplaceChar->fpNext = gpReplaceList; + gpReplaceList = pReplaceChar; +} /* void AddReplace () */ + + +/* + * Restore the old environmental variables to the way they looked before + * the make_env() call, on the unlikely chance that something else will look + * at our copy of the environmental variables during the program execution. + * + */ +PUBLIC void +free_env() +{ + struct ReplaceChar *pReplaceChar; + + while (gpReplaceList != NULL) { + pReplaceChar = gpReplaceList; + gpReplaceList = pReplaceChar->fpNext; + + *(pReplaceChar->fpPos) = pReplaceChar->fC; + + FREE (pReplaceChar); + } /* while */ + +#if 0 + char **ppCurEnv; + char *pCurPos; + + if (!gFECalled) { + gFECalled = TRUE; + +//FREE (environ); +environ = NULL; +#endif +#if 0 + /* Restore the environment list to what it was before we + read it in. */ + for (ppCurEnv = environ; *ppCurEnv != NULL; ++ppCurEnv) { + for (pCurPos = *ppCurEnv; *pCurPos != '='; ++pCurPos) + ; + *pCurPos = '\0'; + } /* for */ + } /* if */ +#endif +} /* PUBLIC void free_env () */ diff --git a/dmake/mac/eold.c b/dmake/mac/eold.c new file mode 100644 index 000000000000..5c389c5851db --- /dev/null +++ b/dmake/mac/eold.c @@ -0,0 +1,119 @@ +/* RCS $Id: eold.c,v 1.1.1.1 2000-09-22 15:33:27 hr Exp $ +-- +-- SYNOPSIS +-- Set up and free for environ +-- +-- DESCRIPTION +-- This file contains routines that will fill in and dispose of the +-- list of environmental variables in the environ global variable. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include "extern.h" + + +/* + * Keep track of any environmental variables that have '='s in their + * name. + */ +struct EqualPos { + char *fpPos; + struct equalsign *fpNext; +} /* struct EqualPos */ + +struct EqualPos *gpEqualList; + +/* + * The character used to replae the equal signs. + */ +const char gEqualReplace = '_'; + + + +/* + * Set up the environmental variables in a format used by + * the environ global variable. + * + * environ has already been set to main's envp argument when + * this suboroutine is called. + */ +void main_env () { + char **ppCurEnv; + char *pCurPos; + struct equalpos *pNewEqual; + + gpEqualList = NULL; + + for (ppCurEnv = environ; *ppCurEnv != NULL; ++ppCurEnv) { + for (pCurPos = *ppCurEnv; *pCurPos != '\0'; ++pCurPos) { + if (*pCurPos == '=') { + if ((pNewEqual = + (struct EqualPos *) malloc (sizeof (struct EqualPos))) == + NULL) { + fputs ("Out of Memory", stderr); + exit (EXIT_FAILURE); + } /* if */ + pNewEqual->fpPos = pCurPos; + pNewEqual->fpNext = gpEqualList; + gpEqualList = pNewEqual; + + *pCurPos = gEqualReplace; + } /* if */ + } /* for */ + + *pCurPos = '='; + } /* for */ +} /* void main_env () */ + + + +/* + * Reset the environmental variables so they look like they did + * before the main_env() call. + * + * environ has already been set to main's envp argument when + * this suboroutine is called. + */ +void main_env () { + char **ppCurEnv; + char *pCurPos; + struct equalpos *pNewEqual; + + gpEqualList = NULL; + + for (ppCurEnv = environ; *ppCurEnv != NULL; ++ppCurEnv) { + for (pCurPos = *ppCurEnv; *pCurPos != '\0'; ++pCurPos) { + if (*pCurPos == '=') { + if ((pNewEqual = + (struct EqualPos *) malloc (sizeof (struct EqualPos))) == + NULL) { + fputs ("Out of Memory", stderr); + exit (EXIT_FAILURE); + } /* if */ + pNewEqual->fpPos = pCurPos; + pNewEqual->fpNext = gpEqualList; + gpEqualList = pNewEqual; + + *pCurPos = gEqualReplace; + } /* if */ + } /* for */ + + *pCurPos = '='; + } /* for */ +} /* void main_env () */ diff --git a/dmake/mac/main.c b/dmake/mac/main.c new file mode 100644 index 000000000000..53cc7d7cd9fe --- /dev/null +++ b/dmake/mac/main.c @@ -0,0 +1,43 @@ +/* RCS $Id: main.c,v 1.1.1.1 2000-09-22 15:33:27 hr Exp $ +-- +-- SYNOPSIS +-- The real main function +-- +-- DESCRIPTION +-- In order to get the third argument to main(), which is a list of +-- environmental variables, we have #defined main to dmakemain, +-- and put the real main here. +-- +-- The environmental variables are placed in the environ global variable +-- and set up for processing by dmake in make_env(). +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include "extern.h" + + + +/* + * Put envp in environ and call dmake's main(). + */ +#undef main +void main(int argc, char **argv, char **envp) { + environ = envp; + dmakemain (argc, argv); +} /* void main () */ diff --git a/dmake/mac/make.sh b/dmake/mac/make.sh new file mode 100644 index 000000000000..fc2b8db02b0f --- /dev/null +++ b/dmake/mac/make.sh @@ -0,0 +1,107 @@ +# +# $Id: make.sh,v 1.1.1.1 2000-09-22 15:33:27 hr Exp $ +# +# This MPW script builds the dmake executable using the Metroworks PPC compiler +# and linker. The resulting dmake binary will only run on the PPC platform. +# +# To execute this script, you will need the following tools: +# - MacOS 8 or later +# - CodeWarrior for MacOS Release 5 or later +# +# To run this script, you need to open the MPW Shell that is bundled with CodeWarrior. +# If you have another instance of MPW installed other than the one bundled with +# CodeWarrior, you may encounter problems. Once you open the MPW Shell that is bundled +# with CodeWarrior, you will need to set MPW's working directory to the "dmake" +# directory (the directory above the directory that this script is in). Then, execute +# this script from the MPW Worksheet by typing the following command: +# +# :mac:make.sh +# +set Exit 1 +if ( "{0}" != ':mac:make.sh' ) + Echo "You cannot run this script from the current directory." + Echo "To run this script, you need to be in the "dmake" directory and then" + Echo "execute the following command: ":mac:make.sh"" + Exit +end +if ( ! `Exists -d objects` ) + NewFolder :objects +end +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle infer.c +Move -y infer.c.o :objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle make.c +Move -y make.c.o :objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle stat.c +Move -y stat.c.o :objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle expand.c +Move -y expand.c.o :objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle dmstring.c +Move -y dmstring.c.o :objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle hash.c +Move -y hash.c.o :objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle dag.c +Move -y dag.c.o :objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle dmake.c +Move -y dmake.c.o :objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle path.c +Move -y path.c.o :objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle imacs.c +Move -y imacs.c.o :objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle sysintf.c +Move -y sysintf.c.o :objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle parse.c +Move -y parse.c.o :objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle getinp.c +Move -y getinp.c.o :objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle quit.c +Move -y quit.c.o :objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle state.c +Move -y state.c.o :objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle dmdump.c +Move -y dmdump.c.o :objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle macparse.c +Move -y macparse.c.o :objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle rulparse.c +Move -y rulparse.c.o :objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle percent.c +Move -y percent.c.o :objects +# Note that function.c needs to have __useAppleExts__ defined. Otherwise, it won't link. +MWCPPC -o : -ansi off -I :mac -d _MPW -d __useAppleExts__ -sym off -proto ignoreoldstyle function.c +Move -y function.c.o :objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle :mac:arlib.c +Move -y arlib.c.o :objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle :mac:bogus.c +Move -y bogus.c.o :objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle :mac:dirbrk.c +Move -y dirbrk.c.o :objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle :mac:directry.c +Move -y directry.c.o :objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle :mac:environ.c +Move -y environ.c.o :objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle :mac:main.c +Move -y main.c.o :objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle :mac:rmprq.c +Move -y rmprq.c.o :objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle :mac:ruletab.c +Move -y ruletab.c.o :objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle :mac:tempnam.c +Move -y tempnam.c.o :objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle :mac:tomacfil.c +Move -y tomacfil.c.o :objects +MWLinkPPC -w -c 'MPS ' -t MPST -sym off -xm m -o dmake :objects:infer.c.o :objects:make.c.o + :objects:stat.c.o :objects:expand.c.o :objects:dmstring.c.o :objects:hash.c.o + :objects:dag.c.o :objects:dmake.c.o :objects:path.c.o :objects:imacs.c.o + :objects:sysintf.c.o :objects:parse.c.o :objects:getinp.c.o :objects:quit.c.o + :objects:state.c.o :objects:dmdump.c.o :objects:macparse.c.o :objects:rulparse.c.o + :objects:percent.c.o :objects:function.c.o :objects:arlib.c.o :objects:bogus.c.o + :objects:dirbrk.c.o :objects:directry.c.o :objects:environ.c.o :objects:main.c.o + :objects:rmprq.c.o :objects:ruletab.c.o :objects:tempnam.c.o :objects:tomacfil.c.o + "{SharedLibraries}StdCLib" + "{SharedLibraries}InterfaceLib" + "{PPCLibraries}StdCRuntime.o" + "{PPCLibraries}PPCCRuntime.o" + "{PPCLibraries}PPCToolLibs.o" +if ( `Exists -f :startup:config.mk` ) + SetFile -a l :startup:config.mk +end +Duplicate -y :mac:template.mk :startup:config.mk diff --git a/dmake/mac/make_mac.sh b/dmake/mac/make_mac.sh new file mode 100644 index 000000000000..9e6c4cc54949 --- /dev/null +++ b/dmake/mac/make_mac.sh @@ -0,0 +1,105 @@ +# +# $Id: make_mac.sh,v 1.1.1.1 2000-09-22 15:33:26 hr Exp $ +# +# This MPW script builds the dmake executable using the Metroworks PPC compiler +# and linker. The resulting dmake binary will only run on the PPC platform. +# +# To execute this script, you will need the following tools: +# - MacOS 8 or later +# - CodeWarrior for MacOS Release 5 or later +# +# To run this script, you need to open the MPW Shell that is bundled with CodeWarrior. +# If you have another instance of MPW installed other than the one bundled with +# CodeWarrior, you may encounter problems. Once you open the MPW Shell that is bundled +# with CodeWarrior, you will need to set MPW's working directory to the "dmake" +# directory (the directory above the directory that this script is in). Then, execute +# this script from the MPW Worksheet by typing the following command: +# +# :mac:make_mac.sh +# +set Exit 1 +if ( "{0}" != ':mac:make_mac.sh' ) + Echo "You cannot run this script from the current directory." + Echo "To run this script, you need to be in the "dmake" directory and then" + Echo "execute the following command: ":mac:make_mac.sh"" + Exit +end +if ( ! `Exists -d objects` ) + NewFolder objects +end +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle infer.c +Move -y infer.c.o objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle make.c +Move -y make.c.o objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle stat.c +Move -y stat.c.o objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle expand.c +Move -y expand.c.o objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle dmstring.c +Move -y dmstring.c.o objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle hash.c +Move -y hash.c.o objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle dag.c +Move -y dag.c.o objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle dmake.c +Move -y dmake.c.o objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle path.c +Move -y path.c.o objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle imacs.c +Move -y imacs.c.o objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle sysintf.c +Move -y sysintf.c.o objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle parse.c +Move -y parse.c.o objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle getinp.c +Move -y getinp.c.o objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle quit.c +Move -y quit.c.o objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle state.c +Move -y state.c.o objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle dmdump.c +Move -y dmdump.c.o objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle macparse.c +Move -y macparse.c.o objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle rulparse.c +Move -y rulparse.c.o objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle percent.c +Move -y percent.c.o objects +# Note that function.c needs to have __useAppleExts__ defined. Otherwise, it won't link. +MWCPPC -o : -ansi off -I :mac -d _MPW -d __useAppleExts__ -sym off -proto ignoreoldstyle function.c +Move -y function.c.o objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle :mac:arlib.c +Move -y arlib.c.o objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle :mac:bogus.c +Move -y bogus.c.o objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle :mac:dirbrk.c +Move -y dirbrk.c.o objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle :mac:directry.c +Move -y directry.c.o objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle :mac:environ.c +Move -y environ.c.o objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle :mac:main.c +Move -y main.c.o objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle :mac:rmprq.c +Move -y rmprq.c.o objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle :mac:ruletab.c +Move -y ruletab.c.o objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle :mac:tempnam.c +Move -y tempnam.c.o objects +MWCPPC -o : -ansi off -I :mac -d _MPW -sym off -proto ignoreoldstyle :mac:tomacfil.c +Move -y tomacfil.c.o objects +MWLinkPPC -w -c 'MPS ' -t MPST -sym off -xm m -o dmake :objects:infer.c.o :objects:make.c.o + :objects:stat.c.o :objects:expand.c.o :objects:dmstring.c.o :objects:hash.c.o + :objects:dag.c.o :objects:dmake.c.o :objects:path.c.o :objects:imacs.c.o + :objects:sysintf.c.o :objects:parse.c.o :objects:getinp.c.o :objects:quit.c.o + :objects:state.c.o :objects:dmdump.c.o :objects:macparse.c.o :objects:rulparse.c.o + :objects:percent.c.o :objects:function.c.o :objects:arlib.c.o :objects:bogus.c.o + :objects:dirbrk.c.o :objects:directry.c.o :objects:environ.c.o :objects:main.c.o + :objects:rmprq.c.o :objects:ruletab.c.o :objects:tempnam.c.o :objects:tomacfil.c.o + "{SharedLibraries}StdCLib" + "{SharedLibraries}InterfaceLib" + "{PPCLibraries}StdCRuntime.o" + "{PPCLibraries}PPCCRuntime.o" + "{PPCLibraries}PPCToolLibs.o" +SetFile -a l :startup:config.mk +Duplicate -y :mac:template.mk :startup:config.mk diff --git a/dmake/mac/public.h b/dmake/mac/public.h new file mode 100644 index 000000000000..31cc8fa62d49 --- /dev/null +++ b/dmake/mac/public.h @@ -0,0 +1,172 @@ +/* RCS $Id: public.h,v 1.1.1.1 2000-09-22 15:33:27 hr Exp $ +-- WARNING -- This file is AUTOMATICALLY GENERATED DO NOT EDIT IT +-- +-- +-- SYNOPSIS +-- Local functions exported to be visible by others. +-- +-- DESCRIPTION +-- This file is generated by 'genpub'. Function declarations +-- that appear in this file are extracted by 'genpub' from +-- source files. Any function in the source file whose definition +-- appears like: +-- +-- PUBLIC return_type +-- function( arg_list ); +-- type_expr1 arg1; +-- ... +-- +-- has its definition extracted and a line of the form: +-- +-- return_type function ANSI((type_expr1,type_expr2,...)); +-- +-- entered into the output file. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef _DMAKE_PUBLIC_h +#define _DMAKE_PUBLIC_h + +#ifdef EXTERN +#undef EXTERN +#endif +#if defined(DEFINE_DMAKE_VARIABLES) +#define EXTERN +#else +#define EXTERN extern +#endif + +/***** genpub: Begin list of generated function headers */ +void Infer_recipe ANSI((CELLPTR, CELLPTR)); +int Make_targets ANSI(()); +int Make ANSI((CELLPTR, CELLPTR)); +int Exec_commands ANSI((CELLPTR)); +void Print_cmnd ANSI((char *, int, int)); +int Push_dir ANSI((char *, char *, int)); +void Pop_dir ANSI((int)); +void Append_line ANSI((char *, int, FILE *, char *, int, int)); +void Stat_target ANSI((CELLPTR, int, int)); +char *Expand ANSI((char *)); +char *Apply_edit ANSI((char *, char *, char *, int, int)); +void Map_esc ANSI((char *)); +char* Apply_modifiers ANSI((int, char *)); +char* Tokenize ANSI((char *, char *, char, int)); +char* ScanToken ANSI((char *, char **, int)); +char *DmStrJoin ANSI((char *, char *, int, int)); +char *DmStrAdd ANSI((char *, char *, int)); +char *DmStrApp ANSI((char *, char *)); +char *DmStrDup ANSI((char *)); +char *DmStrDup2 ANSI((char *)); +char *DmStrPbrk ANSI((char *, char *)); +char *DmStrSpn ANSI((char *, char *)); +char *DmStrStr ANSI((char *, char *)); +char *DmSubStr ANSI((char *, char *)); +uint16 Hash ANSI((char *, uint32 *)); +HASHPTR Get_name ANSI((char *, HASHPTR *, int)); +HASHPTR Search_table ANSI((HASHPTR *, char *, uint16 *, uint32 *)); +HASHPTR Push_macro ANSI((HASHPTR)); +HASHPTR Pop_macro ANSI((HASHPTR)); +HASHPTR Def_macro ANSI((char *, char *, int)); +CELLPTR Def_cell ANSI((char *)); +LINKPTR Add_prerequisite ANSI((CELLPTR, CELLPTR, int, int)); +void Clear_prerequisites ANSI((CELLPTR)); +int Test_circle ANSI((CELLPTR, int)); +STRINGPTR Def_recipe ANSI((char *, STRINGPTR, int, int)); +t_attr Rcp_attribute ANSI((char *)); +void main ANSI((int, char **, char **)); +FILE *Openfile ANSI((char *, int, int)); +FILE *Closefile ANSI(()); +FILE *Search_file ANSI((char *, char **)); +char *Filename ANSI(()); +int Nestlevel ANSI(()); +FILE *TryFiles ANSI((LINKPTR)); +void Fatal ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Error ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Warning ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void No_ram ANSI(()); +void Usage ANSI((int)); +void Version ANSI(()); +char *Get_suffix ANSI((char *)); +char *Basename ANSI((char *)); +char *Filedir ANSI((char *)); +char *Build_path ANSI((char *, char *)); +void Make_rules ANSI(()); +void Create_macro_vars ANSI(()); +time_t Do_stat ANSI((char *, char *, char **, int)); +int Do_touch ANSI((char *, char *, char **)); +void Void_lib_cache ANSI((char *, char *)); +time_t Do_time ANSI(()); +int Do_cmnd ANSI((char *, int, int, CELLPTR, int, int, int)); +char ** Pack_argv ANSI((int, int, char *)); +char *Read_env_string ANSI((char *)); +int Write_env_string ANSI((char *, char *)); +void ReadEnvironment ANSI(()); +void Catch_signals ANSI((void (*)())); +void Clear_signals ANSI(()); +void Prolog ANSI((int, char* [])); +void Epilog ANSI((int)); +char *Get_current_dir ANSI(()); +int Set_dir ANSI((char*)); +char Get_switch_char ANSI(()); +FILE* Get_temp ANSI((char **, char *, int)); +FILE *Start_temp ANSI((char *, CELLPTR, char **)); +void Open_temp_error ANSI((char *, char *)); +void Link_temp ANSI((CELLPTR, FILE *, char *)); +void Close_temp ANSI((CELLPTR, FILE *)); +void Unlink_temp_files ANSI((CELLPTR)); +void Handle_result ANSI((int, int, int, CELLPTR)); +void Update_time_stamp ANSI((CELLPTR)); +int Remove_file ANSI((char *)); +void Parse ANSI((FILE *)); +int Get_line ANSI((char *, FILE *)); +char *Do_comment ANSI((char *, char **, int)); +char *Get_token ANSI((TKSTRPTR, char *, int)); +void Quit ANSI(()); +void Read_state ANSI(()); +void Write_state ANSI(()); +int Check_state ANSI((CELLPTR, STRINGPTR *, int)); +void Dump ANSI(()); +void Dump_recipe ANSI((STRINGPTR)); +int Parse_macro ANSI((char *, int)); +int Macro_op ANSI((char *)); +int Parse_rule_def ANSI((int *)); +int Rule_op ANSI((char *)); +void Add_recipe_to_list ANSI((char *, int, int)); +void Bind_rules_to_targets ANSI((int)); +int Set_group_attributes ANSI((char *)); +DFALINKPTR Match_dfa ANSI((char *)); +void Check_circle_dfa ANSI(()); +void Add_nfa ANSI((char *)); +char *Exec_function ANSI((char *)); +time_t seek_arch ANSI((char*, char*)); +int touch_arch ANSI((char*, char*)); +//void tzset () {}/PUBLIC int putenv (char *pEnvString) {return (0); }/ ANSI(()); +void tzset ANSI(()); +int Wait_for_child ANSI((int ,int )); +void Clean_up_processes ANSI(()); +int If_root_path ANSI((char *)); +int stat ANSI((char *, struct stat *)); +char *getcwd ANSI((char *,size_t )); +int chdir ANSI((char *)); +int utime ANSI((char *,time_t *)); +void make_env ANSI(()); +void free_env ANSI(()); +void Remove_prq ANSI((CELLPTR)); +char *tempnam ANSI((char *,char *)); + +#endif diff --git a/dmake/mac/rmprq.c b/dmake/mac/rmprq.c new file mode 100644 index 000000000000..424b9a060009 --- /dev/null +++ b/dmake/mac/rmprq.c @@ -0,0 +1,38 @@ +/* RCS $Id: rmprq.c,v 1.1.1.1 2000-09-22 15:33:27 hr Exp $ +-- +-- SYNOPSIS +-- Remove prerequisites code. +-- +-- DESCRIPTION +-- This code is different for The Mac and for UNIX and parallel make +-- architectures since the parallel case requires the rm's to be +-- run in parallel, whereas The Mac guarantees to run them sequentially. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include "extern.h" + +PUBLIC void +Remove_prq( tcp ) +CELLPTR tcp; +{ + tcp->ce_flag &= ~(F_MADE|F_VISITED); + tcp->ce_time = 0L; + + Make( tcp, tcp ); +} diff --git a/dmake/mac/ruletab.c b/dmake/mac/ruletab.c new file mode 100644 index 000000000000..d970b6eb9848 --- /dev/null +++ b/dmake/mac/ruletab.c @@ -0,0 +1,43 @@ +/* RCS $Id: ruletab.c,v 1.1.1.1 2000-09-22 15:33:27 hr Exp $ +-- +-- SYNOPSIS +-- Default initial configuration of dmake. +-- +-- DESCRIPTION +-- Define here the initial set of rules that are defined before +-- dmake performs any processing. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +/* These are control macros for dmake that MUST be defined at some point + * if they are NOT dmake will not work! These are default definitions. They + * may be overridden inside the .STARTUP makefile, they are here + * strictly so that dmake can parse the STARTUP makefile */ + +static char *_rules[] = { + "MAXLINELENGTH := 4094", + "MAXPROCESSLIMIT := 1", + "MAXPROCESS := 1", + ".IMPORT .IGNORE: DMAKEROOT SOLARVER UPD INPATH OS UPDMINOREXT", + ".MAKEFILES : makefile.mk Makefile makefile", + ".SOURCE : .NULL", +#include "startup.h" + 0 }; + +char **Rule_tab = _rules; /* for sundry reasons in Get_environment() */ + diff --git a/dmake/mac/startup.h b/dmake/mac/startup.h new file mode 100644 index 000000000000..f4d18a5d6506 --- /dev/null +++ b/dmake/mac/startup.h @@ -0,0 +1,28 @@ +/* RCS $Id: startup.h,v 1.1.1.1 2000-09-22 15:33:27 hr Exp $ +-- +-- SYNOPSIS +-- Default value of MAKESTARTUP. +-- +-- DESCRIPTION +-- Default value is used if the environment variable is not +-- defined. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +"MAKESTARTUP := $(DMAKEROOT):startup.mk", + diff --git a/dmake/mac/sysintf.h b/dmake/mac/sysintf.h new file mode 100644 index 000000000000..f7ef353a343a --- /dev/null +++ b/dmake/mac/sysintf.h @@ -0,0 +1,42 @@ +/* RCS $Id: sysintf.h,v 1.1.1.1 2000-09-22 15:33:27 hr Exp $ +-- +-- SYNOPSIS +-- Assorted bits of system interface +-- +-- DESCRIPTION +-- This file is used to abstract away some of the functions in +-- sysintf.c. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ +#define DMSTAT stat +#define VOID_LCACHE(l,m) +#define Hook_std_writes(A) +#define GETPID 1 +#define DMSTRLWR(A,B) + +/* for directory cache */ +#define CacheStat(A,B) really_dostat(A,&buf) + +/* +** standard C items +*/ + +/* +** Mac interface standard items +*/ +#define getswitchar() '-' diff --git a/dmake/mac/template.mk b/dmake/mac/template.mk new file mode 100644 index 000000000000..0cf10289c826 --- /dev/null +++ b/dmake/mac/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= mac + OSRELEASE *:= + OSENVIRONMENT *:= diff --git a/dmake/mac/tempnam.c b/dmake/mac/tempnam.c new file mode 100644 index 000000000000..ee86ccb6a0a2 --- /dev/null +++ b/dmake/mac/tempnam.c @@ -0,0 +1,65 @@ +/* RCS $Id: tempnam.c,v 1.1.1.1 2000-09-22 15:33:27 hr Exp $ +-- +-- SYNOPSIS +-- Fake tempnam function for the mac +-- +-- DESCRIPTION +-- Get a temporary file name. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + + +#include "extern.h" +#include <StdIO.h> +#include <String.h> + + + +/* + * Try to open a temporary file in the given directory (if non-NULL) + * with the given prefix (if non-NULL). + * + * We ignore the directory argument. + */ +PUBLIC char * +tempnam(char *pDir, char * pPrefix) +{ + char *pName; + char *pFullName; + + pName = tmpnam ((char *) NULL); + + /* Assume that if the name returned by tmpnam is not being used, + the name with the prefix is also not being used. */ + pFullName = MALLOC (((pPrefix != NULL) ? strlen (pPrefix) : 0) + + strlen (pName) + 1, char); + + /* Copy in the name if we successfully allocated space for it. */ + if (pFullName != NULL) { + if (pPrefix != NULL) { + strcpy (pFullName, pPrefix); + } else { + *pFullName = '\0'; + } /* if ... else */ + + strcat (pFullName, pName); + } /* if */ + + return (pFullName); +} /* PUBLIC char *tempnam () */ diff --git a/dmake/mac/tomacfil.c b/dmake/mac/tomacfil.c new file mode 100644 index 000000000000..d5f1ea72a496 --- /dev/null +++ b/dmake/mac/tomacfil.c @@ -0,0 +1,38 @@ +/* RCS $Id: tomacfil.c,v 1.1.1.1 2000-09-22 15:33:27 hr Exp $ +-- +-- SYNOPSIS +-- Routines to change unix file names to mac file names +-- +-- DESCRIPTION +-- Dmake sometimes assumes that files have '/' as a directory parameter in some makefiles. +-- This works, even on DOS, but not on the Mac. In fact, on the Mac, you can't even do a +-- a simple switch of ':' for '/' because all other the Mac has decided to reverse the use +-- of a first-character directory delimiter to mean a relative path rather than absolute path. +-- (i.e., ':test:b' means directory test is relative to the current directory, rather than +-- a top-level directory. Thus, this file attempts to do the directory conversion behind +-- the back of the rest of the program. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +/* This file no longer contains an override to the fopen() function as we now accept only + * Mac style path names + */ +#include <Files.h> + +#include "extern.h" diff --git a/dmake/macparse.c b/dmake/macparse.c new file mode 100644 index 000000000000..a842b091b6e5 --- /dev/null +++ b/dmake/macparse.c @@ -0,0 +1,211 @@ +/* RCS $Id: macparse.c,v 1.1.1.1 2000-09-22 15:33:25 hr Exp $ +-- +-- SYNOPSIS +-- Parse a macro definition +-- +-- DESCRIPTION +-- This file contains the code that parses a macro definition +-- stored in a buffer. If the string in buffer is not a valid +-- macro definition the routie Parse_macro returns 0, otherwise it +-- returns 1 to indicate success. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include "extern.h" + +PUBLIC int +Parse_macro( buffer, flag )/* +============================= + Parse the string in buffer and define it as a macro if it is a valid macro. + Note especially the string .SETDIR= since it is an attribute, but looks a + lot like a macro definition. This would not be a problem if make used + white space as token separators, since this is not the case we must do + something about it. */ +char *buffer; +int flag; +{ + char *result; /* temporary pointer for strings */ + TKSTR input; /* place to scan the buffer from */ + HASHPTR hv; /* pointer to hash table value */ + int operator; /* what macro operator do we have */ + char *tok1; /* temporary place to keep a token */ + char *tok2; /* temporary place to keep a token */ + + DB_ENTER( "Parse_macro" ); + + SET_TOKEN( &input, buffer ); + tok1 = Get_token( &input, "=+:*!?", 0 ); + + operator=Macro_op(tok1); + if( operator ) { + Error( "No macro name" ); + CLEAR_TOKEN( &input ); + DB_RETURN( 1 ); + } + + tok1 = DmStrDup(tok1); + tok2 = Get_token( &input, "=+:*!?", 2 ); + if( !(operator = Macro_op(tok2)) || !strcmp(tok1,".SETDIR") ) { + CLEAR_TOKEN( &input ); + FREE(tok1); + DB_RETURN(0); + } + + tok2 = Expand(tok1); FREE(tok1); tok1 = tok2; + tok2 = Get_token(&input, NIL( char ), FALSE); + + /* Make sure we can force the assignment. */ + if ( operator & M_OP_SI ) { + flag |= M_FORCE|M_MULTI; + operator &= ~M_OP_SI; + } + + switch( operator ) { + case M_OP_PLCL: + tok2 = Expand( tok2 ); + /* Fall thru */ + + case M_OP_PL: + /* Add to an existing macro, if it is not defined, though, then + * just define a new macro */ + + if( (hv = GET_MACRO(tok1)) == NIL(HASH) || hv->ht_value == NIL(char) ) + Def_macro( tok1, tok2, flag ); + else { + result = DmStrAdd( hv->ht_value, tok2, FALSE ); + Def_macro( tok1, result, flag ); + FREE( result ); + } + if( operator == M_OP_PLCL ) FREE(tok2); + break; + + case M_OP_DF: + if( (hv = GET_MACRO(tok1)) != NIL(HASH) && !(hv->ht_flag & M_INIT) ) + break; + /* else FALLTHRU */ + + case M_OP_EQ: + Def_macro( tok1, tok2, flag ); + break; + + case M_OP_DFCL: + if( (hv = GET_MACRO(tok1)) != NIL(HASH) && !(hv->ht_flag & M_INIT) ) + break; + /* else FALLTHRU */ + + case M_OP_CL: + tok2 = Expand( tok2 ); + Def_macro( tok1, tok2, M_EXPANDED | flag ); + FREE( tok2 ); + break; + + case M_OP_CM:{ + CELLPTR cp; + STRINGPTR sp; + + if (flag & M_PUSH) { + Error("Nested conditional definition [%s ?= %s] ignored", + tok1, tok2); + } + else { + cp = Def_cell(tok1); + if (cp->ce_flag & F_MULTI) { + LINKPTR lp; + for(lp=cp->ce_prq; lp->cl_next; lp=lp->cl_next); + cp = lp->cl_prq; + } + TALLOC(sp,1,STRING); + sp->st_string = DmStrDup(tok2); + sp->st_next = cp->ce_cond; + cp->ce_cond = sp; + + tok1 = NIL(char); + } + } + break; + } + + if (tok1) { + if ( LastMacName != NIL(char) ) + FREE( LastMacName ); + + LastMacName = tok1; + } + + DB_RETURN( 1 ); +} + + + +PUBLIC int +Macro_op( op )/* +================ + Check the passed in op string and map it to one of the macro operators */ +char *op; +{ + int ret = 0; + DB_ENTER( "macro_op" ); + + if ( *op == '!' ) { + ret = M_OP_SI; + op++; + } + + switch( *op ) { + case '=': ret |= M_OP_EQ; break; + case ':': ret |= M_OP_CL; op++; break; + + case '+': + op++; + if( *op == ':' ) { + ret |= M_OP_PLCL; + op++; + } + else { + ret |= M_OP_PL; + } + break; + + case '*': + op++; + if( *op == ':' ) { + ret |= M_OP_DFCL; + op++; + } + else { + ret |= M_OP_DF; + } + break; + + case '?': + ret |= M_OP_CM; + op++; + break; + } + + if( *op != '=' ) + ret = 0; + else { + op++; + + if( *op != '\0' ) + ret = 0; + } + + DB_RETURN( ret ); +} diff --git a/dmake/make.bat b/dmake/make.bat new file mode 100755 index 000000000000..a0e3fdea8bcf --- /dev/null +++ b/dmake/make.bat @@ -0,0 +1,273 @@ +echo off +cls +rem *** This is the make batchfile that is used under MSDOS to make the +rem *** first version of dmake. It isn't pretty but it does work, assuming +rem *** the compilers have been correctly setup. See the warning below +rem *** concerning tlink, if you are building any of the Borland compiler +rem *** versions. +rem + +if %0%1 == %0 goto error +if %1 == tcc20swp goto mktccswp + +if %1 == bcc30swp goto mkbcc30swp +if %1 == bcc40swp goto mkbcc40swp +if %1 == bcc45swp goto mkbcc45swp +if %1 == bcc50swp goto mkbcc50swp + +if %1 == msc51 goto mkms51 +if %1 == msc51swp goto mkms51swp +if %1 == msc60 goto mkms60 +if %1 == msc60swp goto mkms60swp + +if %1 == win95-bcc50 goto mkw32b50 +if %1 == win95-vpp40 goto mkw32vp40 + +rem label the possible DOS variations for dmake here. +:error +echo MSDOS: You must specify 'make target' where target is one of: +echo ------------- +echo tcc20swp - Turbo C 2.0 compile of swapping dmake.. + +echo bcc30swp - Borland C++ 3.0 compile of swapping dmake. +echo bcc40swp - Borland C++ 4.0 compile of swapping dmake. +echo bcc45swp - Borland C++ 4.5 compile of swapping dmake. +echo bcc50swp - Borland C++ 5.0 compile of swapping dmake. + +echo msc51 - Microsoft C 5.1 compile. +echo msc51swp - Microsoft C 5.1, MASM 5.1 compile of swapping dmake. +echo msc60 - Microsoft C 6.0 compile. +echo msc60swp - Microsoft C 6.0, MASM 5.1 compile of swapping dmake. + +echo win95-bcc50 - Borland C++ 5.0 32-bit compile of dmake. +echo win95-vpp40 - Microsoft VC++ 4.0 32-bit compile of dmake. +goto end + +rem This is the script that makes dmake using Microsoft C 5.1 +:mkms51 +msdos\microsft\msc51\mk.bat +goto end + +:mkms51swp +msdos\microsft\msc51\mkswp.bat +goto end + +rem This is the script that makes dmake using Microsoft C 6.0 +:mkms60 +msdos\microsft\msc60\mk.bat +goto end + +:mkms60swp +msdos\microsft\msc60\mkswp.bat +goto end + +:mkw32vp40 +win95\microsft\vpp40\mk.bat +goto end + +rem This is the script that makes dmake using Turbo C 2.0 or higher. +:mktcc +cls +echo WARNING: +echo The default response files: +echo msdos\borland\tcc20\obj.rsp +echo msdos\borland\tcc20\lib.rsp +echo contain absolute paths to TURBO-C runtime startup objects, and to +echo the standard libraries. You should check that these files contain +echo the correct path names for your installation of Turbo-C before +echo proceeding further. Also check that the mkdir command at the start +echo of the response file and the copy command at the end of the response +echo file will work on your system. +echo -- +echo Continue if ok, or abort and edit the response files. +pause +msdos\borland\tcc20\mk.bat +goto end + +:mktccswp +cls +echo WARNING: +echo The default response files: +echo msdos\borland\tcc20\objswp.rsp +echo msdos\borland\tcc20\libswp.rsp +echo contain absolute paths to TURBO-C runtime startup objects, and to +echo the standard libraries. You should check that these files contain +echo the correct path names for your installation of Turbo-C before +echo proceeding further. Also check that the mkdir command at the start +echo of the response file and the copy command at the end of the response +echo file will work on your system. +echo -- +echo Continue if ok, or abort and edit the response files. +pause +msdos\borland\tcc20\mkswp.bat +goto end + +rem This is the script that makes dmake using Borland C++ 3.0. +:mkbcc30 +cls +echo WARNING: +echo The default response files: +echo msdos\borland\bcc30\obj.rsp +echo msdos\borland\bcc30\lib.rsp +echo contain absolute paths to Borland C++ runtime startup objects, and to +echo the standard libraries. You should check that these files contain +echo the correct path names for your installation of Borland C++ before +echo proceeding further. Also check that the mkdir command at the start +echo of the response file and the copy command at the end of the response +echo file will work on your system. +echo -- +echo Continue if ok, or abort and edit the response files. +pause +msdos\borland\bcc30\mk.bat +goto end + +:mkbcc30swp +cls +echo WARNING: +echo The default response files: +echo msdos\borland\bcc30\objswp.rsp +echo msdos\borland\bcc30\libswp.rsp +echo contain absolute paths to Borland C++ runtime startup objects, and to +echo the standard libraries. You should check that these files contain +echo the correct path names for your installation of Borland C++ before +echo proceeding further. Also check that the mkdir command at the start +echo of the response file and the copy command at the end of the response +echo file will work on your system. +echo -- +echo Continue if ok, or abort and edit the response files. +pause +msdos\borland\bcc30\mkswp.bat +goto end + +rem This is the script that makes dmake using Borland C++ 4.0. +:mkbcc40 +cls +echo WARNING: +echo The default response files: +echo msdos\borland\bcc40\obj.rsp +echo msdos\borland\bcc40\lib.rsp +echo contain absolute paths to Borland C++ runtime startup objects, and to +echo the standard libraries. You should check that these files contain +echo the correct path names for your installation of Borland C++ before +echo proceeding further. Also check that the mkdir command at the start +echo of the response file and the copy command at the end of the response +echo file will work on your system. +echo -- +echo Continue if ok, or abort and edit the response files. +pause +msdos\borland\bcc40\mk.bat +goto end + +:mkbcc40swp +cls +echo WARNING: +echo The default response files: +echo msdos\borland\bcc40\objswp.rsp +echo msdos\borland\bcc40\libswp.rsp +echo contain absolute paths to Borland C++ runtime startup objects, and to +echo the standard libraries. You should check that these files contain +echo the correct path names for your installation of Borland C++ before +echo proceeding further. Also check that the mkdir command at the start +echo of the response file and the copy command at the end of the response +echo file will work on your system. +echo -- +echo Continue if ok, or abort and edit the response files. +pause +msdos\borland\bcc40\mkswp.bat +goto end + +rem This is the script that makes dmake using Borland C++ 4.5. +:mkbcc45 +cls +echo WARNING: +echo The default response files: +echo msdos\borland\bcc45\obj.rsp +echo msdos\borland\bcc45\lib.rsp +echo contain absolute paths to Borland C++ runtime startup objects, and to +echo the standard libraries. You should check that these files contain +echo the correct path names for your installation of Borland C++ before +echo proceeding further. Also check that the mkdir command at the start +echo of the response file and the copy command at the end of the response +echo file will work on your system. +echo -- +echo Continue if ok, or abort and edit the response files. +pause +msdos\borland\bcc45\mk.bat +goto end + +:mkbcc45swp +cls +echo WARNING: +echo The default response files: +echo msdos\borland\bcc45\objswp.rsp +echo msdos\borland\bcc45\libswp.rsp +echo contain absolute paths to Borland C++ runtime startup objects, and to +echo the standard libraries. You should check that these files contain +echo the correct path names for your installation of Borland C++ before +echo proceeding further. Also check that the mkdir command at the start +echo of the response file and the copy command at the end of the response +echo file will work on your system. +echo -- +echo Continue if ok, or abort and edit the response files. +pause +msdos\borland\bcc45\mkswp.bat +goto end + +rem This is the script that makes dmake using Borland C++ 5.0. +:mkbcc50 +cls +echo WARNING: +echo The default response files: +echo msdos\borland\bcc50\obj.rsp +echo msdos\borland\bcc50\lib.rsp +echo contain absolute paths to Borland C++ runtime startup objects, and to +echo the standard libraries. You should check that these files contain +echo the correct path names for your installation of Borland C++ before +echo proceeding further. Also check that the mkdir command at the start +echo of the response file and the copy command at the end of the response +echo file will work on your system. +echo -- +echo Continue if ok, or abort and edit the response files. +pause +msdos\borland\bcc50\mk.bat +goto end + +:mkbcc50swp +cls +echo WARNING: +echo The default response files: +echo msdos\borland\bcc50\objswp.rsp +echo msdos\borland\bcc50\libswp.rsp +echo contain absolute paths to Borland C++ runtime startup objects, and to +echo the standard libraries. You should check that these files contain +echo the correct path names for your installation of Borland C++ before +echo proceeding further. Also check that the mkdir command at the start +echo of the response file and the copy command at the end of the response +echo file will work on your system. +echo -- +echo Continue if ok, or abort and edit the response files. +pause +msdos\borland\bcc50\mkswp.bat +goto end + +rem This is the script that makes 32-bit dmake using Borland C++ 5.0. +:mkw32b50 +cls +echo WARNING: +echo The default response files: +echo win95\borland\bcc50\obj.rsp +echo win95\borland\bcc50\lib.rsp +echo contain absolute paths to Borland C++ runtime startup objects, and to +echo the standard libraries. You should check that these files contain +echo the correct path names for your installation of Borland C++ before +echo proceeding further. Also check that the mkdir command at the start +echo of the response file and the copy command at the end of the response +echo file will work on your system. +echo -- +echo Continue if ok, or abort and edit the response files. +pause +win95\borland\bcc50\mk.bat +goto end + +rem All done! +:end diff --git a/dmake/make.c b/dmake/make.c new file mode 100644 index 000000000000..2586e58c28ba --- /dev/null +++ b/dmake/make.c @@ -0,0 +1,1412 @@ +/* RCS $Id: make.c,v 1.1.1.1 2000-09-22 15:33:25 hr Exp $ +-- +-- SYNOPSIS +-- Perform the update of all outdated targets. +-- +-- DESCRIPTION +-- This is where we traverse the make graph looking for targets that +-- are out of date, and we try to infer how to make them if we can. +-- The usual make macros are understood, as well as some new ones: +-- +-- $$ - expands to $ +-- $@ - full target name +-- $* - target name with no suffix, same as $(@:db) +-- or, the value of % in % meta rule recipes +-- $? - list of out of date prerequisites +-- $< - all prerequisites associated with rules line +-- $& - all prerequisites associated with target +-- $> - library name for target (if any) +-- $^ - out of date prerequisites taken from value of $< +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include "extern.h" +#include "sysintf.h" + +typedef struct cell { + char *datum; + struct cell *next; + size_t len; +} LISTCELL, *LISTCELLPTR; + +typedef struct { + LISTCELLPTR first; + LISTCELLPTR last; + size_t len; +} LISTSTRING, *LISTSTRINGPTR; + + +static void _drop_mac ANSI((HASHPTR)); +static void _set_recipe ANSI((char*, int)); +static void _set_tmd ANSI(()); +static void _append_file ANSI((STRINGPTR, FILE*, char*, int)); +static LINKPTR _dup_prq ANSI((LINKPTR)); +static LINKPTR _expand_dynamic_prq ANSI(( LINKPTR, LINKPTR, char * )); +static char* _prefix ANSI((char *, char *)); +static char* _pool_lookup ANSI((char *)); + +#define RP_GPPROLOG 0 +#define RP_RECIPE 1 +#define RP_GPEPILOG 2 +#define NUM_RECIPES 3 + +static STRINGPTR _recipes[NUM_RECIPES]; +static LISTCELLPTR _freelist=NULL; + +static LISTCELLPTR +get_cell() +{ + LISTCELLPTR cell; + + if (!_freelist) { + if ((cell=MALLOC(1,LISTCELL)) == NULL) + No_ram(); + } + else { + cell = _freelist; + _freelist = cell->next; + } + + return(cell); +} + + +static void +free_cell(LISTCELLPTR cell) +{ + cell->next = _freelist; + _freelist = cell; +} + + +static void +free_list(LISTCELLPTR c) +{ + if(c) { + free_list(c->next); + free_cell(c); + } +} + + +static void +list_init(LISTSTRINGPTR s) +{ + s->first = NULL; + s->last = NULL; + s->len = 0; +} + + +static void +list_add(LISTSTRINGPTR s, char *str) +{ + LISTCELLPTR p; + int l; + + if ((l = strlen(str)) == 0) + return; + + p = get_cell(); + p->datum = str; + p->next = NULL; + p->len = l; + + if(s->first == NULL) + s->first = p; + else + s->last->next = p; + + s->last = p; + s->len += l+1; +} + + +static char * +list_string(LISTSTRINGPTR s) +{ + LISTCELLPTR next, cell; + int len; + char *result; + char *p; + + if(s->len == 0) + return(NIL(char)); + + if((p = result = MALLOC(s->len, char)) == NULL) No_ram(); + + for (cell=s->first; cell; cell=next) { + memcpy((void *)p, (void *)cell->datum, len=cell->len); + p += len; + *p++ = ' '; + next = cell->next; + free_cell(cell); + } + + *--p = '\0'; + list_init(s); + + return(result); +} + + +PUBLIC int +Make_targets()/* +================ + Actually go and make the targets on the target list */ +{ + LINKPTR lp; + int done = 0; + + DB_ENTER( "Make_targets" ); + + Read_state(); + _set_recipe( ".GROUPPROLOG", RP_GPPROLOG ); + _set_recipe( ".GROUPEPILOG", RP_GPEPILOG ); + + /* Prevent recipe inference for .ROOT */ + if ( Root->ce_recipe == NIL(STRING) ) { + TALLOC( Root->ce_recipe, 1, STRING ); + Root->ce_recipe->st_string = ""; + } + + /* Prevent recipe inference for .TARGETS */ + if ( Targets->ce_recipe == NIL(STRING) ) { + TALLOC( Targets->ce_recipe, 1, STRING ); + Targets->ce_recipe->st_string = ""; + } + + /* Make sure that user defined targets are marked as root targets */ + for( lp = Targets->ce_prq; lp != NIL(LINK); lp = lp->cl_next ) + lp->cl_prq->ce_attr |= A_ROOT; + + while( !done ) { + int rval; + + if( (rval = Make(Root, NIL(CELL))) == -1 ) + DB_RETURN(1); + else + done = Root->ce_flag & F_MADE; + + if( !rval && !done ) Wait_for_child( FALSE, -1 ); + } + + for( lp = Targets->ce_prq; lp != NIL(LINK); lp = lp->cl_next ) { + CELLPTR tgt = lp->cl_prq; + if( !(tgt->ce_attr & A_UPDATED) ) + printf( "`%s' is up to date\n", tgt->CE_NAME ); + } + + DB_RETURN( 0 ); +} + + + +PUBLIC int +Make( cp, setdirroot )/* +======================== Make a specified target */ +CELLPTR cp; +CELLPTR setdirroot; +{ + register LINKPTR dp, prev,next; + register CELLPTR tcp; + CELLPTR nsetdirroot; + char *name, *lib; + HASHPTR m_at, m_q, m_b, m_g, m_l, m_bb, m_up; + LISTSTRING all_list, imm_list, outall_list, inf_list; + char *all = NIL(char); + char *inf = NIL(char); + char *outall = NIL(char); + char *imm = NIL(char); + int rval = 0; + int push = 0; + int made = F_MADE; + int ignore; + time_t otime = (time_t) 1L; + time_t ttime = (time_t) 1L; + int mark_made = FALSE; + + DB_ENTER( "Make" ); + DB_PRINT( "mem", ("%s:-> mem %ld", cp->CE_NAME, (long) coreleft()) ); + + /* Initialize the various temporary storage */ + m_q = m_b = m_g = m_l = m_bb = m_up = NIL(HASH); + list_init(&all_list); + list_init(&imm_list); + list_init(&outall_list); + list_init(&inf_list); + + if (cp->ce_set && cp->ce_set != cp) { + if( Verbose & V_MAKE ) + printf( "%s: Building .UPDATEALL representative [%s]\n", Pname, + cp->ce_set->CE_NAME ); + cp = cp->ce_set; + } + + /* If we are supposed to change directories for this target then do so. + * If we do change dir, then modify the setdirroot variable to reflect + * that fact for all of the prerequisites that we will be making. */ + + nsetdirroot = setdirroot; + ignore = (((cp->ce_attr|Glob_attr)&A_IGNORE) != 0); + m_at = Def_macro( "@", cp->ce_fname, M_MULTI ); + + if( cp->ce_attr & A_SETDIR ) { + /* Change directory only if the previous .SETDIR is a different + * directory from the current one. ie. all cells with the same .SETDIR + * attribute are assumed to come from the same directory. */ + + if( (setdirroot == NIL(CELL) || setdirroot->ce_dir != cp->ce_dir) && + (push = Push_dir(cp->ce_dir,cp->CE_NAME,ignore)) != 0 ) + setdirroot = cp; + } + + DB_PRINT( "mem", ("%s:-A mem %ld", cp->CE_NAME, (long) coreleft()) ); + if( cp->ce_recipe == NIL(STRING) ) { + char *dir = cp->ce_dir; + + if( Verbose & V_MAKE ) + printf( "%s: Infering prerequisite(s) and recipe for [%s]\n", Pname, + cp->CE_NAME ); + + Infer_recipe( cp, setdirroot ); + + /* See if the directory has changed, if it has then make sure we + * push it. */ + if( dir != cp->ce_dir ) { + if( push ) Pop_dir(FALSE); + push = Push_dir( cp->ce_dir, cp->CE_NAME, ignore ); + setdirroot = cp; + } + } + + for(dp=CeMeToo(cp); dp; dp=dp->cl_next) { + tcp = dp->cl_prq; + if( push ) { + if( !(tcp->ce_attr & A_POOL) && tcp->ce_dir ) FREE( tcp->ce_dir ); + tcp->ce_dir = _pool_lookup(Pwd); + tcp->ce_attr |= A_SETDIR|A_POOL; + } + tcp->ce_setdir = nsetdirroot; + } + + DB_PRINT( "mem", ("%s:-A mem %ld", cp->CE_NAME, (long) coreleft()) ); + /* If we have not yet statted the target then do so. */ + if( !(cp->ce_flag & F_STAT) && !(cp->ce_attr&A_PHONY) ) { + time_t itime = cp->ce_time; + + if (cp->ce_parent && (cp->ce_parent->ce_flag & F_MULTI)) { + /* Inherit the stat info from the parent. */ + cp->ce_time = cp->ce_parent->ce_time; + cp->ce_flag |= F_STAT; + cp->ce_attr |= cp->ce_parent->ce_attr & A_PRECIOUS; + } + else { + for(dp=CeMeToo(cp); dp; dp=dp->cl_next) { + tcp = dp->cl_prq; + Stat_target( tcp, TRUE, FALSE ); + + if( tcp->ce_time == (time_t)0L ) { + if( tcp->ce_flag & F_INFER ) + tcp->ce_time = itime; + } + else { + /* File exists so don't remove it later. */ + tcp->ce_attr |= A_PRECIOUS; + } + + if( Verbose & V_MAKE ) + printf("%s: Time stamp of [%s] is %ld\n",Pname,tcp->CE_NAME, + tcp->ce_time); + } + } + } + + DB_PRINT( "make", ("(%s, %ld, 0x%08x, 0x%04x)", cp->CE_NAME, + cp->ce_time, cp->ce_attr, cp->ce_flag) ); + + if( !(cp->ce_flag & F_TARGET) && (cp->ce_time == (time_t) 0L) ) + if( Makemkf ) { + rval = -1; + goto stop_making_it; + } + else if( cp->ce_prq != NIL(LINK) + || (STOBOOL(Augmake) && (cp->ce_flag&F_EXPLICIT))) + /* Assume an empty recipe for a target that we have run inference on + * but do not have a set of rules for but for which we have inferred + * a list of prerequisites. */ + cp->ce_flag |= F_RULES; + else + Fatal( "`%s' not found, and can't be made", cp->CE_NAME ); + + DB_PRINT( "mem", ("%s:-A mem %ld", cp->CE_NAME, (long) coreleft()) ); + + /* set value of $* if we have not infered a recipe, in this case $* is + * the same as $(@:db), this allows us to be compatible with BSD make */ + if( cp->ce_per == NIL(char) ) cp->ce_per = "$(@:db)"; + + /* Search the prerequisite list for dynamic prerequisites and if we find + * them copy the list of prerequisites for potential later re-use. */ + if ( cp->ce_prqorg == NIL(LINK) ) { + for( dp = cp->ce_prq; dp != NIL(LINK); dp = dp->cl_next ) + if ( strchr(dp->cl_prq->CE_NAME, '$') != NULL ) + break; + + if (dp != NIL(LINK)) { + cp->ce_prqorg = _dup_prq(cp->ce_prq); + } + } + + m_at = Def_macro("@", cp->ce_fname, M_MULTI); + + /* Define conditional macros if any, note this is done BEFORE we process + * prerequisites for the current target. Thus the making of a prerequisite + * is done using the current value of the conditional macro. */ + for(dp=CeMeToo(cp); dp; dp=dp->cl_next) { + tcp=dp->cl_prq; + if (tcp->ce_cond != NIL(STRING)) { + STRINGPTR sp; + + tcp->ce_pushed = NIL(HASH); + for(sp=tcp->ce_cond; sp; sp=sp->st_next) { + if(Parse_macro(sp->st_string,M_MULTI|M_PUSH)) { + HASHPTR hp; + + hp = GET_MACRO(LastMacName); + hp->ht_link = tcp->ce_pushed; + tcp->ce_pushed = hp; + } + else { + Error("Invalid conditional macro expression [%s]",sp->st_string); + } + } + } + } + + for( prev=NULL,dp=cp->ce_prq; dp != NIL(LINK); prev=dp, dp=next ) { + int seq; + int nesting_count; + + /* This is the only macro that needs to be reset while building + * prerequisites since it is set when we make each prerequisite. */ + if (m_at->ht_value == NIL(char)) { + m_at = Def_macro("@", cp->ce_fname, M_MULTI); + } + + /* Make the prerequisite, note that if the current target has the + * .LIBRARY attribute set we pass on to the prerequisite the .LIBRARYM + * attribute and pass on the name of the current target as the library + * name, and we take it away when we are done. */ + next = dp->cl_next; + + tcp = dp->cl_prq; + seq = (((cp->ce_attr | Glob_attr) & A_SEQ) != 0); + + if( tcp->ce_flag & F_VISITED ) + if( _explode_graph(tcp, dp, setdirroot) == 0 ) { + /* didn't blow it up so see if we need to wait for it. */ + if( tcp->ce_flag & F_MADE ) { + if( tcp->ce_time > ttime ) ttime = tcp->ce_time; + continue; + } + else + goto stop_making_it; + } + else + tcp = dp->cl_prq; + + if( seq && !made ) goto stop_making_it; + + nesting_count = 0; + while ( tcp + && strchr(tcp->CE_NAME, '$') + ) { + if ( nesting_count++ > DynamicNestLevel ) { + Fatal( "Dynamic Macro nesting level exceeded [%s]", + cp->CE_NAME ); + } + /* Make this prerequisite link point at the real prerequisite we + * are after, ie figure out what the dynamic one is and point at it.*/ + + name = Expand( tcp->CE_NAME ); + if( strcmp(name,cp->CE_NAME) == 0 ) + Fatal("Detected circular dynamic dependency; generated '%s'",name); + + dp = _expand_dynamic_prq( cp->ce_prq, dp, name ); + FREE( name ); + + tcp = dp->cl_prq; + if ( tcp ) { + next = dp->cl_next; + } + } + + /* Dynamic expansion results in a NULL cell only when the the new + * prerequisite is already in the prerequisite list. In this case + * delete the cell and continue. */ + if ( tcp == NIL(CELL) ) { + FREE(dp); + if ( prev == NIL(LINK) ) { + cp->ce_prq = next; + } + else { + prev->cl_next = next; + } + continue; + } + + if( cp->ce_attr & A_LIBRARY ) { + tcp->ce_attr |= A_LIBRARYM; + tcp->ce_lib = cp->ce_fname; + } + + if( (tcp->ce_flag & (F_INFER|F_STAT))==F_INFER && cp->ce_time >= ttime ) + tcp->ce_time = cp->ce_time; + + /* Propagate the parent's F_REMOVE and F_INFER flags to the children. + * Make certain to do this AFTER propagating the time, since the + * time propagation test above uses the F_INFER flag to decide if + * it should do so. */ + tcp->ce_flag |= cp->ce_flag & (F_REMOVE|F_INFER); + + /* Propagate parents A_ROOT attribute to a child if the parent is a + * F_MULTI target. */ + if( (cp->ce_flag & F_MULTI) && (cp->ce_attr & A_ROOT) ) + tcp->ce_attr |= A_ROOT; + + tcp->ce_parent = cp; + rval |= Make(tcp, setdirroot); + + if( cp->ce_attr & A_LIBRARY ) + tcp->ce_attr ^= A_LIBRARYM; + + if( rval == -1 || (seq && (rval==1)) ) + goto stop_making_it; + + if( tcp->ce_time > ttime ) ttime = tcp->ce_time; + made &= tcp->ce_flag & F_MADE; + } + + + /* Do the loop again. We are most definitely going to make the current + * cell now. NOTE: doing this loop here also results in a reduction + * in peak memory usage by the algorithm. */ + + for( dp = cp->ce_prq; dp != NIL(LINK); dp = dp->cl_next ) { + int tgflg; + tcp = dp->cl_prq; + name = tcp->ce_fname; + + /* make certain that all prerequisites are made prior to advancing. */ + if( !(tcp->ce_flag & F_MADE) ) goto stop_making_it; + + /* If the target is a library, then check to make certain that a member + * is newer than an object file sitting on disk. If the disk version + * is newer then set the time stamps so that the archived member is + * replaced. */ + if( cp->ce_attr & A_LIBRARY ) + if( tcp->ce_time < cp->ce_time ) { + time_t mtime = Do_stat( name, tcp->ce_lib, NIL(char *), FALSE ); + if( mtime < tcp->ce_time ) tcp->ce_time = cp->ce_time+1L; + } + + if( tcp->ce_time > otime ) otime = tcp->ce_time; + + list_add(&all_list, name); + if( (tgflg = (dp->cl_flag & F_TARGET)) != 0 ) + list_add(&inf_list, name); + + if((cp->ce_time<tcp->ce_time) || ((tcp->ce_flag & F_TARGET) && Force)) { + list_add(&outall_list, name); + if( tgflg ) + list_add(&imm_list, name); + } + } + + all = list_string(&all_list); + imm = list_string(&imm_list); + outall = list_string(&outall_list); + inf = list_string(&inf_list); + + DB_PRINT( "mem", ("%s:-C mem %ld", cp->CE_NAME, (long) coreleft()) ); + DB_PRINT( "make", ("I make '%s' if %ld > %ld", cp->CE_NAME, otime, + cp->ce_time) ); + + if( Verbose & V_MAKE && !(cp->ce_flag & F_MULTI) ) { + printf( "%s: >>>> Making ", Pname ); + if( cp->ce_count != 0 ) + printf( "[%s::{%d}]\n", cp->CE_NAME, cp->ce_count ); + else + printf( "[%s]\n", cp->CE_NAME ); + } + + m_at = Def_macro( "@", cp->ce_fname, M_MULTI ); + m_g = Def_macro( ">", cp->ce_lib, M_MULTI|M_EXPANDED ); + m_q = Def_macro( "?", outall, M_MULTI|M_EXPANDED ); + m_b = Def_macro( "<", inf, M_MULTI|M_EXPANDED ); + m_l = Def_macro( "&", all, M_MULTI|M_EXPANDED ); + m_up = Def_macro( "^", imm, M_MULTI|M_EXPANDED ); + m_bb = Def_macro( "*", cp->ce_per, M_MULTI ); + + _recipes[ RP_RECIPE ] = cp->ce_recipe; + + /* We attempt to make the target if + * 1. it has a newer prerequisite + * 2. It is a target and Force is set + * 3. It's set of recipe lines has changed. + */ + if( Check_state(cp, _recipes, NUM_RECIPES ) + || (cp->ce_time < otime) + || ((cp->ce_flag & F_TARGET) && Force) + ) { + + /* Only checking so stop as soon as we determine we will make + * something */ + if( Check ) { + rval = -1; + goto stop_making_it; + } + + if( Verbose & V_MAKE ) + printf( "%s: Updating [%s], (%ld > %ld)\n", Pname, + cp->CE_NAME, otime, cp->ce_time ); + + if( Touch ) { + name = cp->ce_fname; + lib = cp->ce_lib; + + if( (!(Glob_attr & A_SILENT) || !Trace) && !(cp->ce_attr & A_PHONY) ) + if( lib == NIL(char) ) + printf("touch(%s)", name ); + else if( cp->ce_attr & A_SYMBOL ) + printf("touch(%s((%s)))", lib, name ); + else + printf("touch(%s(%s))", lib, name ); + + if( !Trace && !(cp->ce_attr & A_PHONY) ) + if( Do_touch( name, lib, + (cp->ce_attr & A_SYMBOL) ? &name : NIL(char *) ) != 0 ) + printf( " not touched - non-existant" ); + + if( (!(Glob_attr & A_SILENT) || !Trace) && !(cp->ce_attr & A_PHONY) ) + printf( "\n" ); + + Update_time_stamp( cp ); + } + else if( cp->ce_recipe != NIL(STRING) ) { + if( !(cp->ce_flag & F_SINGLE) ) + rval = Exec_commands( cp ); + else { + TKSTR tk; + + _drop_mac( m_q ); + + if( outall && *outall ) { + SET_TOKEN( &tk, outall ); + + Doing_bang = TRUE; + name = Get_token( &tk, "", FALSE ); + do { + m_q->ht_value = name; + + Wait_for_completion = TRUE; /* Reset in Exec_commands */ + rval = Exec_commands( cp ); + Unlink_temp_files(cp); + } + while( *(name = Get_token( &tk, "", FALSE )) != '\0' ); + Doing_bang = FALSE; + } + + Update_time_stamp( cp ); + m_q->ht_value = NIL(char); + } + } + else if( !(cp->ce_flag & F_RULES) && !(cp->ce_flag & F_STAT) && + (!(cp->ce_attr & A_ROOT) || !(cp->ce_flag & F_EXPLICIT)) ) + Fatal( "Don't know how to make `%s'",cp->CE_NAME ); + else { + /* Empty recipe, set the flag as MADE and update the time stamp */ + Update_time_stamp( cp ); + } + } + else { + mark_made = TRUE; + } + + /* Make sure everyone gets remade if Force is set */ + for(dp=CeMeToo(cp); dp; dp=dp->cl_next) { + tcp=dp->cl_prq; + + if( !(tcp->ce_flag & F_TARGET) && Force ) tcp->ce_time = Do_time(); + if( mark_made ) { + tcp->ce_flag |= F_MADE; + if( tcp->ce_flag & F_MULTI ) { + LINKPTR tdp; + for( tdp = tcp->ce_prq; tdp != NIL(LINK); tdp = tdp->cl_next ) + tcp->ce_attr |= tdp->cl_prq->ce_attr & A_UPDATED; + } + } + + tcp->ce_flag |= F_VISITED; + + /* Note: If the prerequisite was made using a .SETDIR= attribute + * directory then we will include the directory in the fname + * of the target. */ + if( push ) { + char *dir = nsetdirroot ? nsetdirroot->ce_dir : Makedir; + char *pref = _prefix(dir,tcp->ce_dir); + char *nname = Build_path(pref, tcp->ce_fname); + + FREE(pref); + if( (tcp->ce_attr & A_FFNAME) && (tcp->ce_fname != NIL(char)) ) + FREE( tcp->ce_fname ); + + tcp->ce_fname = DmStrDup(nname); + tcp->ce_attr |= A_FFNAME; + } + } + +stop_making_it: + _drop_mac( m_g ); + _drop_mac( m_q ); + _drop_mac( m_b ); + _drop_mac( m_l ); + _drop_mac( m_bb ); + _drop_mac( m_up ); + _drop_mac( m_at ); + + /* undefine conditional macros if any */ + for(dp=CeMeToo(cp); dp; dp=dp->cl_next) { + tcp=dp->cl_prq; + + while (tcp->ce_pushed != NIL(HASH)) { + HASHPTR cur = tcp->ce_pushed; + tcp->ce_pushed = cur->ht_link; + + Pop_macro(cur); + FREE(cur->ht_name); + if(cur->ht_value) + FREE(cur->ht_value); + FREE(cur); + } + } + + while( push-- ) + Pop_dir(FALSE); + + /* Undefine the strings that we used for constructing inferred + * prerequisites. */ + if( inf != NIL(char) ) FREE( inf ); + if( all != NIL(char) ) FREE( all ); + if( imm != NIL(char) ) FREE( imm ); + if( outall != NIL(char) ) FREE( outall ); + free_list(all_list.first); + free_list(imm_list.first); + free_list(outall_list.first); + free_list(inf_list.first); + + DB_PRINT( "mem", ("%s:-< mem %ld", cp->CE_NAME, (long) coreleft()) ); + DB_RETURN(rval); +} + + +static char * +_prefix( pfx, pat ) +char *pfx; +char *pat; +{ + char *cmp1=pfx; + char *cmp2=pat; + char *result = DmStrDup(""); + char *up; + + while(*pfx && *pat) { + pfx = DmStrSpn(cmp1, DirBrkStr); + pat = DmStrSpn(cmp2, DirBrkStr); + + cmp1 = DmStrPbrk(pfx, DirBrkStr); + cmp2 = DmStrPbrk(pat, DirBrkStr); + + if ( (cmp1-pfx) != (cmp2-pat) || strncmp(pfx,pat,cmp1-pfx) != 0 ) + break; + } + + up = DmStrJoin("..",DirSepStr,-1,FALSE); + cmp1 = pfx; + while ( *(pfx=DmStrSpn(cmp1,DirBrkStr)) != '\0' ) { + cmp1 = DmStrPbrk(pfx,DirBrkStr); + result = DmStrJoin(result,up,-1,TRUE); + } + + cmp2 = pat; + while ( *(pat=DmStrSpn(cmp2,DirBrkStr)) != '\0' ) { + char *tmp; + char *x; + cmp2 = DmStrPbrk(pat, DirBrkStr); + tmp = DmStrDup(Build_path(result,x=DmSubStr(pat,cmp2))); + FREE(result); + FREE(x); + result = tmp; + } + + return(result); +} + + +static LINKPTR +_dup_prq( lp ) +LINKPTR lp; +{ + LINKPTR tlp; + + if( lp == NIL(LINK) ) return(lp); + + TALLOC(tlp, 1, LINK); + tlp->cl_prq = lp->cl_prq; + tlp->cl_flag = lp->cl_flag; + tlp->cl_next = _dup_prq( lp->cl_next ); + + return(tlp); +} + + +static LINKPTR +_expand_dynamic_prq( head, lp, name ) +LINKPTR head; +LINKPTR lp; +char *name; +{ + CELLPTR cur = lp->cl_prq; + + if ( strchr(name, ' ') == NIL(char) ) { + CELLPTR prq = Def_cell(name); + LINKPTR tmp; + + for(tmp=head;tmp != NIL(LINK) && tmp->cl_prq != prq;tmp=tmp->cl_next); + + if ( !tmp ) + lp->cl_prq = prq; + } + else { + LINKPTR tlp = lp; + LINKPTR next = lp->cl_next; + TKSTR token; + char *p; + int first=TRUE; + + SET_TOKEN(&token, name); + while (*(p=Get_token(&token, "", FALSE)) != '\0') { + CELLPTR prq = Def_cell(p); + LINKPTR tmp; + + for(tmp=head;tmp != NIL(LINK) && tmp->cl_prq != prq;tmp=tmp->cl_next); + if ( tmp ) continue; + + if ( first ) { + first = FALSE; + } + else { + TALLOC(tlp->cl_next,1,LINK); + tlp = tlp->cl_next; + tlp->cl_flag |= F_TARGET; + tlp->cl_next = next; + } + + tlp->cl_prq = prq; + } + CLEAR_TOKEN( &token ); + } + + if ( lp->cl_prq == cur ) { + lp->cl_prq = NIL(CELL); + lp->cl_flag = 0; + } + + return(lp); +} + + +static void +_drop_mac( hp )/* +================ set a macro value to zero. */ +HASHPTR hp; +{ + if( hp && hp->ht_value != NIL(char) ) { + FREE( hp->ht_value ); + hp->ht_value = NIL(char); + } +} + + + +int +_explode_graph( cp, parent, setdirroot )/* +========================================== + Check to see if we have made the node already. If so then don't do + it again, except if the cell's ce_setdir field is set to something other + than the value of setdirroot. If they differ then, and we have made it + already, then make it again and set the cell's stat bit to off so that + we do the stat again. */ +CELLPTR cp; +LINKPTR parent; +CELLPTR setdirroot; +{ + static CELLPTR removecell = NIL(CELL); + + if ( removecell == NIL(CELL) ) + removecell = Def_cell(".REMOVE"); + + /* we may return if we made it already from the same setdir location, + * or if it is not a library member whose lib field is non NULL. (if + * it is such a member then we have a line of the form: + * lib1 lib2 .LIBRARY : member_list... + * and we have to make sure all members are up to date in both libs. */ + + if ( setdirroot == removecell ) + return( 0 ); + + if( cp->ce_setdir == setdirroot && + !((cp->ce_attr & A_LIBRARYM) && (cp->ce_lib != NIL(char))) ) + return( 0 ); + + /* We check to make sure that we are comming from a truly different + * directory, ie. ".SETDIR=joe : a.c b.c d.c" are all assumed to come + * from the same directory, even though setdirroot is different when + * making dependents of each of these targets. */ + + if( cp->ce_setdir != NIL(CELL) && + setdirroot != NIL(CELL) && + cp->ce_dir && + setdirroot->ce_dir && + !strcmp(cp->ce_dir, setdirroot->ce_dir) ) + return( 0 ); + + if( Max_proc > 1 ) { + LINKPTR dp; + + TALLOC(parent->cl_prq, 1, CELL); + *parent->cl_prq = *cp; + cp = parent->cl_prq; + cp->ce_prq = _dup_prq(cp->ce_prqorg); + cp->ce_all.cl_prq = cp; + CeNotMe(cp) = _dup_prq(CeNotMe(cp)); + + for(dp=CeNotMe(cp);dp;dp=dp->cl_next) { + CELLPTR tcp = dp->cl_prq; + TALLOC(dp->cl_prq,1,CELL); + *dp->cl_prq = *tcp; + dp->cl_prq->ce_flag &= ~(F_STAT|F_VISITED|F_MADE); + dp->cl_prq->ce_set = cp; + } + } + cp->ce_flag &= ~(F_STAT|F_VISITED|F_MADE); + + /* Indicate that we exploded the graph and that the current node should + * be made. */ + return(1); +} + + + +PUBLIC int +Exec_commands( cp )/* +===================== + Execute the commands one at a time that are pointed to by the rules pointer + of the target cp. If a group is indicated, then the ce_attr determines + .IGNORE and .SILENT treatment for the group. + + The function returns 0, if the command is executed and has successfully + returned, and returns 1 if the command is executing but has not yet + returned (for parallel makes). + + The F_MADE bit in the cell is guaranteed set when the command has + successfully completed. */ +CELLPTR cp; +{ + static HASHPTR useshell = NIL(HASH); + static HASHPTR command = NIL(HASH); + static int read_cmnd = 0; + register STRINGPTR rp; + STRINGPTR orp; + char *cmnd; + char *groupfile; + FILE *tmpfile; + int do_it; + t_attr attr; + int group; + int trace; + int rval = 0; + + DB_ENTER( "Exec_commands" ); + + attr = Glob_attr | cp->ce_attr; + trace = Trace || !(attr & A_SILENT); + group = cp->ce_flag & F_GROUP; + + /* Do it again here for those that call us from places other than Make() + * above. */ + orp = _recipes[ RP_RECIPE ]; + _recipes[ RP_RECIPE ] = cp->ce_recipe; + + if( group ) { + /* Leave this assignment of Current_target here. It is needed just + * incase the user hits ^C after the tempfile for the group recipe + * has been opened. */ + Current_target = cp; + trace = Trace || !(attr & A_SILENT); + + if( !Trace ) tmpfile = Start_temp( Grp_suff, cp, &groupfile ); + if( trace ) fputs( "[\n", stdout ); + + /* Emit group prolog */ + if( attr & A_PROLOG ) + _append_file( _recipes[RP_GPPROLOG], tmpfile, cp->CE_NAME, trace ); + } + + if( !useshell ) + useshell=Def_macro("USESHELL",NIL(char),M_MULTI|M_EXPANDED); + + if( !read_cmnd ) { + command = GET_MACRO("COMMAND"); + read_cmnd = 1; + } + + /* Process commands in recipe. If in group, merely append to file. + * Otherwise, run them. */ + for( rp=_recipes[RP_RECIPE]; rp != NIL(STRING); rp=rp->st_next,FREE(cmnd)){ + t_attr a_attr = A_DEFAULT; + t_attr l_attr; + char *p; + int new_attr = FALSE; + int shell; + + /* Reset it for each recipe line otherwise tempfiles don't get removed. + * Since processing of $(mktmp ...) depends on Current_target being + * correctly set. */ + Current_target = cp; + + /* Only check for +,-,%,@ if the recipe line begins with a '$' macro + * expansion. Otherwise there is no way it is going to find these + * now. */ + if( *rp->st_string == '$' && !group ) { + t_attr s_attr = Glob_attr; + Glob_attr |= A_SILENT; + Suppress_temp_file = TRUE; + cmnd = Expand(rp->st_string); + Suppress_temp_file = FALSE; + a_attr |= Rcp_attribute(cmnd); + FREE(cmnd); + ++new_attr; + Glob_attr = s_attr; + } + + l_attr = attr|a_attr|rp->st_attr; + shell = ((l_attr & A_SHELL) != 0); + useshell->ht_value = (group||shell)?"yes":"no"; + + cmnd = Expand( rp->st_string ); + + if( new_attr && (p = DmStrSpn(cmnd," \t\n+-@%")) != cmnd ) + strcpy(cmnd,p); + + /* COMMAND macro is set to "$(CMNDNAME) $(CMNDARGS)" by default, it is + * possible for the user to reset it to, for example + * COMMAND = $(CMNDNAME) @$(mktmp $(CMNDARGS)) + * in order to get a different interface for his command execution. */ + if( command != NIL(HASH) && !group ) { + char *cname = cmnd; + char cmndbuf[30]; + + if ( *(p=DmStrPbrk(cmnd," \t\n")) != '\0' ) { + *p = '\0'; + (void)Def_macro("CMNDARGS",DmStrSpn(p+1," \t\n"),M_MULTI|M_EXPANDED); + } + else + (void) Def_macro("CMNDARGS","",M_MULTI|M_EXPANDED); + + (void) Def_macro("CMNDNAME",cname,M_MULTI|M_EXPANDED); + + strcpy(cmndbuf, "$(COMMAND)"); + cmnd = Expand(cmndbuf); + FREE(cname); /* cname == cmnd at this point. */ + + /* Collect up any new attributes */ + l_attr |= Rcp_attribute(cmnd); + shell = ((l_attr & A_SHELL) != 0); + + /* clean up the attributes that we may have just added. */ + if( (p = DmStrSpn(cmnd," \t\n+-@%")) != cmnd ) + strcpy(cmnd,p); + } + + Swap_on_exec = ((l_attr & A_SWAP) != 0); /* Swapping for DOS only */ + do_it = !Trace; + + /* We force execution of the recipe if we are tracing and the .EXECUTE + * attribute was given or if the it is not a group recipe and the + * recipe line contains the string $(MAKE). */ + if( Trace + && ((l_attr & A_EXECUTE)||(!group && DmStrStr(rp->st_string,"$(MAKE)"))) + ) { + Wait_for_completion |= Trace; + do_it = TRUE; + } + + if( group ) + Append_line( cmnd, TRUE, tmpfile, cp->CE_NAME, trace, 0 ); + else { + if( *DmStrSpn(cmnd, " \t") != '\0' ) + Print_cmnd(cmnd, !(do_it && (l_attr & A_SILENT)), 0); + else + do_it = FALSE; + + rval=Do_cmnd(cmnd,FALSE,do_it,cp,(l_attr&A_IGNORE)!=0, shell, + rp->st_next == NIL(STRING) ); + } + } + + /* If it is a group then output the EPILOG if required and possibly + * execute the command */ + if( group && !(cp->ce_attr & A_ERROR) ) { + if( attr & A_EPILOG ) /* emit epilog */ + _append_file( _recipes[RP_GPEPILOG], tmpfile, cp->CE_NAME, trace ); + + if( trace ) fputs("]\n", stdout); + + do_it = !Trace; + if( do_it ) + { + Close_temp( cp, tmpfile ); +#if defined(UNIX) + + chmod(groupfile,0700); +#endif + } + rval = Do_cmnd(groupfile, TRUE, do_it, cp, (attr & A_IGNORE)!=0, + TRUE, TRUE); + } + + Wait_for_completion = FALSE; + _recipes[ RP_RECIPE ] = orp; + cp->ce_attr &= ~A_ERROR; + DB_RETURN( rval ); +} + + +PUBLIC void +Print_cmnd( cmnd, echo, map )/* +================================ + This routine is called to print out the command to stdout. If echo is + false the printing to stdout is supressed, but the new lines in the command + are still deleted. */ +char *cmnd; +int echo; +int map; +{ + register char *p; + register char *n; + char tmp[3]; + + DB_ENTER( "Print_cmnd" ); + + if( echo ) { + printf( "%s\n", cmnd ); + fflush(stdout); + } + + tmp[0] = ESCAPE_CHAR; + tmp[1] = CONTINUATION_CHAR; + tmp[2] = '\0'; + + for( p=cmnd; *(n = DmStrPbrk(p,tmp)) != '\0'; ) + if(*n == CONTINUATION_CHAR && n[1] == '\n') { + DB_PRINT( "make", ("fixing [%s]", p) ); + strcpy( n, n+2 ); + p = n; + } + else { + if( *n == ESCAPE_CHAR && map ) Map_esc( n ); + p = n+1; + } + + DB_VOID_RETURN; +} + + + +/* These routines are used to maintain a stack of directories when making + * the targets. If a target cd's to the directory then it is assumed that + * it will undo it when it is finished making itself. */ + +static STRINGPTR dir_stack = NIL(STRING); + +PUBLIC int +Push_dir( dir, name, ignore )/* +=============================== + Change the current working directory to dir and save the current + working directory on the stack so that we can come back. + + If ignore is TRUE then do not complain about _ch_dir if not possible.*/ +char *dir; +char *name; +int ignore; +{ + STRINGPTR new_dir; + int freedir=FALSE; + + DB_ENTER( "Push_dir" ); + + if( dir == NIL(char) || *dir == '\0' ) dir = Pwd; + if( *dir == '\'' && dir[strlen(dir)-1] == '\'' ) { + dir = DmStrDup(dir+1); + dir[strlen(dir)-1]='\0'; + freedir=TRUE; + } + else if (strchr(dir,'$') != NIL(char)) { + dir = Expand(dir); + freedir=TRUE; + } + else + dir = DmStrDup(dir); + + if( Set_dir(dir) ) { + if( !ignore ) + Fatal( "Unable to change to directory `%s', target is [%s]", + dir, name ); + if (freedir) FREE(dir); + DB_RETURN( 0 ); + } + + DB_PRINT( "dir", ("Push: [%s]", dir) ); + if( Verbose & V_DIR_SET ) + printf( "%s: Changed to directory [%s]\n", Pname, dir ); + + if (freedir) FREE( dir ); + TALLOC( new_dir, 1, STRING ); + new_dir->st_next = dir_stack; + dir_stack = new_dir; + new_dir->st_string = DmStrDup( Pwd ); + + Def_macro( "PWD", Get_current_dir(), M_MULTI | M_EXPANDED ); + _set_tmd(); + + DB_RETURN( 1 ); +} + + + +PUBLIC void +Pop_dir(ignore)/* +================= + Change the current working directory to the previous saved dir. */ +int ignore; +{ + STRINGPTR old_dir; + char *dir; + + DB_ENTER( "Pop_dir" ); + + if( dir_stack == NIL(STRING) ) + if( ignore ) { + DB_VOID_RETURN; + } + else + Error( "Directory stack empty for return from .SETDIR" ); + + if( Set_dir(dir = dir_stack->st_string) ) + Fatal( "Could not change to directory `%s'", dir ); + + Def_macro( "PWD", dir, M_MULTI | M_EXPANDED ); + DB_PRINT( "dir", ("Pop: [%s]", dir) ); + if( Verbose & V_DIR_SET ) + printf( "%s: Changed back to directory [%s]\n", Pname, dir); + + old_dir = dir_stack; + dir_stack = dir_stack->st_next; + + FREE( old_dir->st_string ); + FREE( old_dir ); + _set_tmd(); + + DB_VOID_RETURN; +} + + + +static void +_set_tmd()/* +============ + Set the TWD Macro */ +{ + TKSTR md, pd; + char *m, *p; + char *tmd; + int is_sep; + int first = 1; + + SET_TOKEN( &md, Makedir ); + SET_TOKEN( &pd, Pwd ); + + m = Get_token( &md, DirBrkStr, FALSE ); + (void) Get_token( &pd, DirBrkStr, FALSE ); + is_sep = (strchr(DirBrkStr, *m) != NIL(char)); + tmd = DmStrDup( "" ); + + do { + m = Get_token( &md, DirBrkStr, FALSE ); + p = Get_token( &pd, DirBrkStr, FALSE ); + + if( !is_sep && strcmp(m, p) ) { /* they differ */ + char *tmp; + if( first ) { /* They differ in the first component */ + tmd = Makedir; /* In this case use the full path */ + break; + } + + if( *p ) tmp = Build_path( "..", tmd ); + if( *m ) tmp = Build_path( tmd, m ); + FREE( tmd ); + tmd = DmStrDup( tmp ); + } + + is_sep = 1-is_sep; + first = 0; + } while (*m || *p); + + CLEAR_TOKEN( &md ); + CLEAR_TOKEN( &pd ); + + Def_macro( "TMD", tmd, M_MULTI | M_EXPANDED ); + if( tmd != Makedir ) FREE( tmd ); +} + + +static void +_set_recipe( target, ind )/* +============================ + Set up the _recipes static variable so that the slot passed in points + at the rules corresponding to the target supplied. */ +char *target; +int ind; +{ + CELLPTR cp; + HASHPTR hp; + + if( (hp = Get_name(target, Defs, FALSE)) != NIL(HASH) ) { + cp = hp->CP_OWNR; + _recipes[ ind ] = cp->ce_recipe; + } + else + _recipes[ ind ] = NIL(STRING); +} + + + +PUBLIC void +Append_line( cmnd, newline, tmpfile, name, printit, map ) +char *cmnd; +int newline; +FILE *tmpfile; +char *name; +int printit; +int map; +{ + Print_cmnd( cmnd, printit, map ); + + if( Trace ) return; + + fputs(cmnd, tmpfile); + if( newline ) fputc('\n', tmpfile); + fflush(tmpfile); + + if( ferror(tmpfile) ) + Fatal("Write error on temporary file, while processing `%s'", name); +} + + + +static void +_append_file( rp, tmpfile, name, printit ) +register STRINGPTR rp; +FILE *tmpfile; +char *name; +int printit; +{ + char *cmnd; + + while( rp != NIL(STRING) ) { + Append_line(cmnd = Expand(rp->st_string), TRUE, tmpfile, name, printit,0); + FREE(cmnd); + rp = rp->st_next; + } +} + + +#define NUM_BUCKETS 20 + +typedef struct strpool { + char *string; /* a pointer to the string value */ + uint32 keyval; /* the strings hash value */ + struct strpool *next; /* hash table link pointer */ +} POOL, *POOLPTR; + +static POOLPTR strings[ NUM_BUCKETS ]; + +static char * +_pool_lookup( str )/* +===================== + Scan down the list of chained strings and see if one of them matches + the string we are looking for. */ +char *str; +{ + register POOLPTR key; + uint32 keyval; + uint16 hv; + uint16 keyindex; + char *string; + + DB_ENTER( "_pool_lookup" ); + + if( str == NIL(char) ) DB_RETURN(""); + + hv = Hash(str, &keyval); + key = strings[ keyindex = (hv % NUM_BUCKETS) ]; + + while( key != NIL(POOL) ) + if( (key->keyval != keyval) || strcmp(str, key->string) ) + key = key->next; + else + break; + + if( key == NIL(POOL) ) { + DB_PRINT( "pool", ("Adding string [%s]", str) ); + TALLOC( key, 1, POOL ); /* not found so add string */ + + key->string = string = DmStrDup(str); + key->keyval = keyval; + + key->next = strings[ keyindex ]; + strings[ keyindex ] = key; + } + else { + DB_PRINT( "pool", ("Found string [%s], key->string") ); + string = key->string; + } + + DB_RETURN( string ); +} diff --git a/dmake/make.cmd b/dmake/make.cmd new file mode 100755 index 000000000000..ba209a24a3c3 --- /dev/null +++ b/dmake/make.cmd @@ -0,0 +1,102 @@ +echo off +cls +rem *** This is the make command file that is used under OS/2 to make the +rem *** first version of dmake. It isn't pretty but it does work, assuming +rem *** the compilers have been correctly setup. +rem + +if %0%1 == %0 goto error + +if %1 == os2-ibm goto mkibm +if %1 == os2-ibm3 goto mkibm3 +if %1 == winnt-bcc40 goto mkwntb40 +if %1 == winnt-bcc45 goto mkwntb45 +if %1 == winnt-bcc50 goto mkwntb50 +if %1 == winnt-vpp40 goto mkwntv40 + + +rem label the possible DOS variations for dmake here. +:error +echo OS/2 INDEX: You must specify one of: +echo ------------------ +echo os2-ibm - IBM OS/2 ICC compile. +echo os2-ibm3 - IBM OS/2 ICC3 compile. +echo winnt-bcc40 - Windows-NT Borland C++ 4.0 Compile +echo winnt-bcc45 - Windows-NT Borland C++ 4.5 Compile +echo winnt-bcc50 - Windows-NT Borland C++ 5.0 Compile +echo winnt-vpp40 - Windows-NT Microsoft VC++ 4.0 Compile +goto end + +rem This is the script that bilds OS/2 dmake using IBM ICC Compiler +:mkibm +os2\ibm\icc\mk.cmd +goto end + +:mkibm3 +os2\ibm\icc3\mk.cmd +goto end + +rem This is the script that makes 32-bit dmake using Borland C++ 4.0. +:mkwntb40 +cls +echo WARNING: +echo The default response files: +echo winnt\borland\bcc40\obj.rsp +echo winnt\borland\bcc40\lib.rsp +echo contain absolute paths to Borland C++ runtime startup objects, and to +echo the standard libraries. You should check that these files contain +echo the correct path names for your installation of Borland C++ before +echo proceeding further. Also check that the mkdir command at the start +echo of the response file and the copy command at the end of the response +echo file will work on your system. +echo -- +echo Continue if ok, or abort and edit the response files. +pause +winnt\borland\bcc40\mk.bat +goto end + +rem This is the script that makes 32-bit dmake using Borland C++ 4.5. +:mkwntb45 +cls +echo WARNING: +echo The default response files: +echo winnt\borland\bcc45\obj.rsp +echo winnt\borland\bcc45\lib.rsp +echo contain absolute paths to Borland C++ runtime startup objects, and to +echo the standard libraries. You should check that these files contain +echo the correct path names for your installation of Borland C++ before +echo proceeding further. Also check that the mkdir command at the start +echo of the response file and the copy command at the end of the response +echo file will work on your system. +echo -- +echo Continue if ok, or abort and edit the response files. +pause +winnt\borland\bcc45\mk.bat +goto end + +rem All done! +rem This is the script that makes 32-bit dmake using Borland C++ 5.0. +:mkwntb50 +cls +echo WARNING: +echo The default response files: +echo winnt\borland\bcc50\obj.rsp +echo winnt\borland\bcc50\lib.rsp +echo contain absolute paths to Borland C++ runtime startup objects, and to +echo the standard libraries. You should check that these files contain +echo the correct path names for your installation of Borland C++ before +echo proceeding further. Also check that the mkdir command at the start +echo of the response file and the copy command at the end of the response +echo file will work on your system. +echo -- +echo Continue if ok, or abort and edit the response files. +pause +winnt\borland\bcc50\mk.bat +goto end + +:mkwntv40 +winnt\microsft\vpp40\mk.bat +goto end + +rem All done! +:end diff --git a/dmake/makefile.mk b/dmake/makefile.mk new file mode 100644 index 000000000000..17c0a75e3815 --- /dev/null +++ b/dmake/makefile.mk @@ -0,0 +1,429 @@ +# //// Makefile for DMAKE. \\\\ +# The target system is characterized by the following macros imported from +# the environment. +# +# OS - gives the class of operating system +# OSRELEASE - optionally specifies the particular release of the OS +# OSENVIRONMENT - optionally specifies the environment under which the +# OS and OSENVIRONMENT are running. +# +# For valid values for the above macros consult the readme/* files or type +# 'make' by itself to get a summary of what is available. + +# First target in the makefile, do this so that targets declared in the +# included files are never marked as being the first *default* target. +first : all ; + +#Enable keeping of state for future compiles +.KEEP_STATE *:= _state.mk + +# Define $(PUBLIC) +_osenv := $(OSENVIRONMENT)$/ +_osre := $(OSRELEASE)$/$(!null,$(OSENVIRONMENT) $(_osenv)) +ENVDIR = $(OS)$/$(!null,$(OSRELEASE) $(_osre)) +PUBLIC = $(ENVDIR)public.h +MKCONFIG := startup/config.mk + +# Define the source files +SRC =\ + infer.c make.c stat.c expand.c dmstring.c hash.c dag.c dmake.c\ + path.c imacs.c sysintf.c parse.c getinp.c quit.c state.c\ + dmdump.c macparse.c rulparse.c percent.c function.c + +# Common Include files. +HDR = dmake.h extern.h struct.h vextern.h patchlvl.h version.h + +# Define the TARGET we are making, and where the OBJECT files go. +OBJDIR := objects +TARGET = dmake$E +CFLAGS += $(SWITCHAR)I. + +# Meta rule for making .o's from .c's (give our own so we can move object +# to objects directory in a portable, compiler independent way) +# Define it before the .INCLUDE so that different OS combinations can redefine +# it. +%$O : %.c +.IF $(SHELL) == mpw + %$(CC) $(CFLAGS) -o :$(OBJDIR:s,/,:,):$@ $< +.ELSE + %$(CC) $(SWITCHAR)c $(CFLAGS) $< +.IF $(SHELL) != $(COMSPEC) + mv $(@:f) $(OBJDIR) +.ELSE + +copy $(@:f) $(OBJDIR) + +del $(@:f) +.ENDIF +.ENDIF + +# Pull in the proper configuration files, based on the value of OS. +.INCLUDE : $(OS)/config.mk +.INCLUDE : dbug/dbug.mk + +# Set the .SOURCE targets so that we look for things in the right place. +.SOURCE.c :^ .NULL +.SOURCE.h :^ .NULL +.SOURCE$O :^ $(OBJDIR) +.PRECIOUS : $(HDR) + +# Must come after the above INCLUDE so that it gets ALL objects. +OBJECTS := {$(ASRC:b) $(SRC:b)}$O + +# The main target, make sure the objects directory exists first. +# LDARGS is defined in config.mk file of each OS/OSRELEASE combination. +all : $(TARGET) $(MKCONFIG); +$(TARGET) : $(OBJDIR) +$(TARGET) : $(OBJECTS);$(LD) $(LDARGS) + +# Use this for install targets +.IF $(SHELL) == mpw + $(MKCONFIG) : template.mk + duplicate :$(<:s,/,:,) $@ +.ELSE + $(MKCONFIG) : template.mk + $(eq,$(SHELL),$(COMSPEC) +copy cp) $< $@ +.ENDIF + +# how to make public.h +public .PHONY : $(PUBLIC); +$(PUBLIC) .GROUP .NOSTATE: $(SRC) + genpub -n DMAKE $< >$@ +# drcsclean ./rcsclean.awk $@ > /dev/null + +# Other obvious targets... +.IF $(SHELL) == mpw + $(OBJDIR):;-newfolder $@ +.ELSE + $(OBJDIR):;-$(eq,$(SHELL),$(COMSPEC) +md mkdir) $@ +.ENDIF + +# remaining dependencies should be automatically generated +sysintf$O : sysintf.h +ruletab$O : startup.h #khc 01NOV90 - dependency was missing +$(OBJECTS) : $(HDR) + +clean:;+- $(RM:f) -rf dmake$E dbdmake$E objects* _*state*.mk startup/config.mk + +# Rules for making the manual pages. +man .SETDIR=man : dmake.nc dmake.uue ; +dmake.nc : dmake.p ; scriptfix < $< > $@ +dmake.p : dmake.tf; groff -man -Tascii $< > $@ +dmake.uue : dmake.p + compress -b 12 dmake.p + mv dmake.p.Z dmake.Z + uuencode dmake.Z dmake.Z >dmake.uue + /bin/rm -f dmake.Z + +template.mk ".SETDIR=$(ENVDIR)" .USESHELL .MKDIR : $$(TMD)startup/template.mk + cat $< |\ + sed -e 's/xxOSxx/$(OS)/' |\ + sed -e 's/xxOSRELEASExx/$(OSRELEASE)/' |\ + sed -e 's/xxOSENVIRONMENTxx/$(OSENVIRONMENT)/' > $@ + +#-------------------------------------------------------------------------- +# Make the various archives for shipping the thing around. +# +archives : zip tar + $(RM) -rf src-list dmake + +zip .PHONY : dmake.zip ; +shar .PHONY : dmake.shar; +tar .PHONY : dmake.tar; + +dmake.zip : dir-copy + zip -r $(@:b) $(@:b) + +dmake.shar : dir-copy + find dmake -type f -print >src-list + xshar -vc -o$@ -L40 `cat src-list` + +dmake.tar : dir-copy + tar cf $@ dmake + +dir-copy .PHONY : src-list +[ + echo 'tmp.tar .SILENT :$$(ALLSRC) ;tar -cf tmp.tar $$(ALLSRC)' >> $< + $(MAKECMD) -f $< tmp.tar + mkdir dmake + cd dmake + tar xf ../tmp.tar; chmod -R u+rw . + cd .. + /bin/rm -f tmp.tar +] + +src-list : clean + echo 'MAXLINELENGTH := 65536' > $@ + echo 'ALLSRC = \' >>$@ + find . -type f -print |\ + sed -e 's/,v//'\ + -e 's/$$/\\/'\ + -e 's/^\.\// /'|\ + sort -u |\ + grep -v tst | grep -v $@ | grep -v license |\ + grep -v CVS | grep -v RCS |\ + grep -v '\.zip' | grep -v '\.tar'| grep -v '\.shar' >> $@ + echo ' readme/license.txt' >> $@ + +#-------------------------------------------------------------------------- +# This section can be used to make the necessary script files so that dmake +# can be bootstrapped. +# +# dmake scripts -- makes all the script files at once. +# +FIX-SH = $(SH:s,fix/,,) +FIX95-SH = $(SH:s,fix95nt/,,) +SH = $(SH_n:s/c40d/cd/:s/c50d/cd/:s/c51d/cd/:s/c60d/cd/) +SH_n = $(@:s/swp-/-/:s,-,/,:s/scripts/${SCRIPTFILE}/) +MS = MAKESTARTUP=startup/startup.mk +FS := "SHELL := $(SHELL)" "SHELLFLAGS := -ce" +SET-TMP:= TMPDIR:=/tmp + +scripts: unix-scripts\ + atari-tos-scripts apple-mac-scripts qssl-qnx-scripts\ + msdos-scripts win95-scripts os2-scripts; + +# To add a new environment for UNIX, simply create the appropriate entry +# in the style below for the macro which contains the OS, OSRELEASE and +# OSENVIRONMENT flags. Then add the entry as a recipe line for the target +# unix-scripts. +# +unix-bsd43-scripts-flags = OS=unix OSRELEASE=bsd43 OSENVIRONMENT= +unix-linux-gnu-scripts-flags = OS=unix OSRELEASE=linux OSENVIRONMENT=gnu +unix-solaris-scripts-flags = OS=unix OSRELEASE=solaris OSENVIRONMENT= +unix-solaris-gnu-scripts-flags = OS=unix OSRELEASE=solaris OSENVIRONMENT=gnu +unix-bsd43-uw-scripts-flags= OS=unix OSRELEASE=bsd43 OSENVIRONMENT=uw +unix-bsd43-vf-scripts-flags= OS=unix OSRELEASE=bsd43 OSENVIRONMENT=vf +unix-sysvr4-scripts-flags = OS=unix OSRELEASE=sysvr4 OSENVIRONMENT= +unix-sysvr3-scripts-flags = OS=unix OSRELEASE=sysvr3 OSENVIRONMENT= +unix-sysvr3-pwd-scripts-flags = OS=unix OSRELEASE=sysvr3 OSENVIRONMENT=pwd +unix-xenix-scripts-flags = OS=unix OSRELEASE=xenix OSENVIRONMENT= +unix-xenix-pwd-scripts-flags = OS=unix OSRELEASE=xenix OSENVIRONMENT=pwd +unix-sysvr1-scripts-flags = OS=unix OSRELEASE=sysvr1 OSENVIRONMENT= +unix-386ix-scripts-flags = OS=unix OSRELEASE=386ix OSENVIRONMENT= +unix-coherent-ver40-scripts-flags= OS=unix OSRELEASE=coherent OSENVIRONMENT=ver40 +unix-coherent-ver42-scripts-flags= OS=unix OSRELEASE=coherent OSENVIRONMENT=ver42 +unix-macosx-gnu-scripts-flags = OS=unix OSRELEASE=macosx OSENVIRONMENT=gnu +qssl--scripts-flags = OS=qssl OSRELEASE= OSENVIRONMENT= +tos--scripts-flags = OS=tos OSRELEASE= OSENVIRONMENT= +mac--scripts-flags = OS=mac OSRELEASE= OSENVIRONMENT= + +unix-scripts .SWAP : clean + $(MAKE) SCRIPTFILE=make.sh unix-bsd43-scripts + $(MAKE) SCRIPTFILE=make.sh unix-bsd43-uw-scripts + $(MAKE) SCRIPTFILE=make.sh unix-bsd43-vf-scripts + $(MAKE) SCRIPTFILE=make.sh unix-linux-gnu-scripts + $(MAKE) SCRIPTFILE=make.sh unix-solaris-scripts + $(MAKE) SCRIPTFILE=make.sh unix-solaris-gnu-scripts + $(MAKE) SCRIPTFILE=make.sh unix-sysvr4-scripts + $(MAKE) SCRIPTFILE=make.sh unix-sysvr3-scripts + $(MAKE) SCRIPTFILE=make.sh unix-sysvr3-pwd-scripts + $(MAKE) SCRIPTFILE=make.sh unix-xenix-scripts + $(MAKE) SCRIPTFILE=make.sh unix-xenix-pwd-scripts + $(MAKE) SCRIPTFILE=make.sh unix-sysvr1-scripts + $(MAKE) SCRIPTFILE=make.sh unix-386ix-scripts + $(MAKE) SCRIPTFILE=make.sh unix-coherent-ver40-scripts + $(MAKE) SCRIPTFILE=make.sh unix-coherent-ver42-scripts + $(MAKE) SCRIPTFILE=make.sh unix-macosx-gnu-scripts + +atari-tos-scripts .SWAP : clean + $(MAKE) SCRIPTFILE=make.sh tos--scripts + +qssl-qnx-scripts .SWAP : clean + $(MAKE) SCRIPTFILE=make.sh qssl--scripts + +apple-mac-scripts .SWAP : clean + $(MAKE) SCRIPTFILE=make.sh mac--scripts + +unix-%-scripts .SWAP : + $(MAKECMD) -su $($@-flags) .KEEP_STATE:= $(FS) public template.mk + $(MAKECMD) -ns .KEEP_STATE:= $(MS) $($@-flags) >/tmp/dmscr + dfold </tmp/dmscr >$(SH) + +qssl-%-scripts .SWAP : + $(MAKECMD) -su $($@-flags) .KEEP_STATE:= $(FS) public template.mk + $(MAKECMD) -ns .KEEP_STATE:= $(MS) $($@-flags) >/tmp/dmscr + dfold </tmp/dmscr >$(SH) + +tos-%-scripts .SWAP : + $(MAKECMD) -su $($@-flags) .KEEP_STATE:= $(FS) public template.mk + $(MAKECMD) -ns .KEEP_STATE:= $(MS) $($@-flags) >/tmp/dmscr + dfold </tmp/dmscr >$(SH) + +mac-%-scripts .SWAP : + $(MAKECMD) -su $($@-flags) .KEEP_STATE:= $(FS) public template.mk + $(MAKECMD) -ns .KEEP_STATE:= $(MS) $($@-flags) >$(SH) + sed 's/ mac\/\(.*\)$$/ :mac:\1/' <$(SH) | dfold >/tmp/dmscr + /bin/mv /tmp/dmscr $(SH) + +# We make the standard dos scripts here, but we have to go and fix up the +# mkXX.bat file since it contains names of temporary files for the response +# files required by the linker. We need to also construct the response file +# contents. These two functions are performed by the fix-msdos-%-scripts +# meta-target. +# +# To add a new DOS environment just do what is described for adding a new +# unix environment, and then make certain that the fix-msdos-%-scripts target +# performs the correct function for the new environment. +msdos-cf = OS=msdos +win95-cf = OS=win95 +winnt-cf = OS=winnt + +msdos-borland-tcc20swp-scripts-flags = $(msdos-cf) OSRELEASE=borland OSENVIRONMENT=tcc20 +msdos-borland-bcc30-scripts-flags = $(msdos-cf) OSRELEASE=borland OSENVIRONMENT=bcc30 SWAP=n +msdos-borland-bcc30swp-scripts-flags = $(msdos-cf) OSRELEASE=borland OSENVIRONMENT=bcc30 +msdos-borland-bcc40swp-scripts-flags = $(msdos-cf) OSRELEASE=borland OSENVIRONMENT=bcc40 +msdos-borland-bcc45swp-scripts-flags = $(msdos-cf) OSRELEASE=borland OSENVIRONMENT=bcc45 +msdos-borland-bcc50swp-scripts-flags = $(msdos-cf) OSRELEASE=borland OSENVIRONMENT=bcc50 +msdos-borland-bcc32-scripts-flags = $(msdos-cf) OSRELEASE=borland OSENVIRONMENT=bcc32 SWAP=n +msdos-microsft-msc51-scripts-flags= $(msdos-cf) OSRELEASE=microsft SWAP=n MSC_VER=5.1 OSENVIRONMENT=msc51 +msdos-microsft-msc51swp-scripts-flags = $(msdos-cf) OSRELEASE=microsft MSC_VER=5.1 OSENVIRONMENT=msc51 +msdos-microsft-msc60-scripts-flags= $(msdos-cf) OSRELEASE=microsft SWAP=n MSC_VER=6.0 OSENVIRONMENT=msc60 +msdos-microsft-msc60swp-scripts-flags = $(msdos-cf) OSRELEASE=microsft MSC_VER=6.0 OSENVIRONMENT=msc60 +msdos-zortech-scripts-flags= $(msdos-cf) OSRELEASE=zortech SWAP=n OSENVIRONMENT= +msdos-zortechswp-scripts-flags= $(msdos-cf) OSRELEASE=zortech OSENVIRONMENT= +win95-borland-bcc50-scripts-flags = $(win95-cf) OSRELEASE=borland OSENVIRONMENT=bcc50 SWAP=n +win95-microsft-vpp40-scripts-flags = $(win95-cf) OSRELEASE=microsft OSENVIRONMENT=vpp40 SWAP=n + +winnt-borland-bcc50-scripts-flags = $(winnt-cf) OSRELEASE=borland OSENVIRONMENT=bcc50 SWAP=n +winnt-microsft-vpp40-scripts-flags = $(winnt-cf) OSRELEASE=microsft OSENVIRONMENT=vpp40 SWAP=n + + +msdos-scripts: clean\ + msdos-borland-turbo-scripts\ + msdos-borland-c++-scripts\ + msdos-microsoft-scripts; + +win95-scripts: clean\ + win95-borland-c++-scripts\ + win95-microsft-vc++-scripts; + +winnt-scripts: clean\ + winnt-borland-c++-scripts\ + winnt-microsft-vc++-scripts; + +msdos-borland-turbo-scripts .SWAP : + $(MAKECMD) SCRIPTFILE=mkswp.bat msdos-borland-tcc20swp-scripts + +msdos-borland-c++-scripts .SWAP :! 30 40 45 50 + $(MAKECMD) SCRIPTFILE=mkswp.bat msdos-borland-bcc$?swp-scripts + +msdos-microsoft-scripts .SWAP :! 51 60 + $(MAKECMD) SCRIPTFILE=mk.bat msdos-microsft-msc$?-scripts + $(MAKECMD) SCRIPTFILE=mkswp.bat msdos-microsft-msc$?swp-scripts + +msdos-zortech-scripts .SWAP : + $(MAKECMD) SCRIPTFILE=mk.bat msdos-zortech-scripts + $(MAKECMD) SCRIPTFILE=mkswp.bat msdos-zortechswp-scripts + +win95-borland-c++-scripts .SWAP :! 50 + $(MAKECMD) SCRIPTFILE=mk.bat win95-borland-bcc$?-scripts + +win95-microsft-vc++-scripts .SWAP :! 40 + $(MAKECMD) SCRIPTFILE=mk.bat win95-microsft-vpp$?-scripts + +winnt-borland-c++-scripts .SWAP :! 50 + $(MAKECMD) SCRIPTFILE=mk.cmd winnt-borland-bcc$?-scripts + +winnt-microsft-vc++-scripts .SWAP :! 40 + $(MAKECMD) SCRIPTFILE=mk.cmd winnt-microsft-vpp$?-scripts + +msdos-%-scripts .SWAP .SILENT: + $(MAKECMD) -su $($@-flags) .KEEP_STATE:= $(FS) public template.mk + $(MAKECMD) -ns DIRSEPSTR:=$(DIRSEPSTR) SHELL=command.com COMSPEC=command.com .KEEP_STATE:= $(MS) $($@-flags) >$(SH) + $(MAKECMD) -s $(MAKEMACROS) $(MS) $($@-flags) $(SET-TMP) fix-msdos-$*-scripts + +win95-borland-%-scripts .SWAP .SILENT: + $(MAKECMD) -u $($@-flags) .KEEP_STATE:= $(FS) public template.mk + $(MAKECMD) -n DIRSEPSTR:=$(DIRSEPSTR) SHELL=command.com COMSPEC=command.com .KEEP_STATE:= $(MS) $($@-flags) >$(SH) + $(MAKECMD) -s $(MAKEMACROS) $(MS) $($@-flags) $(SET-TMP) fix-win95-borland-$*-scripts + +win95-microsft-%-scripts .SWAP .SILENT: + $(MAKECMD) -su $($@-flags) .KEEP_STATE:= $(FS) public template.mk + $(MAKECMD) -ns DIRSEPSTR:=$(DIRSEPSTR) SHELL=command.com COMSPEC=command.com .KEEP_STATE:= $(MS) $($@-flags) >$(SH) + $(MAKECMD) -s $(MAKEMACROS) $(MS) $($@-flags) $(SET-TMP) fix95nt-win95-microsft-$*-scripts + +winnt-borland-%-scripts .SWAP .SILENT: + $(MAKECMD) -su $($@-flags) .KEEP_STATE:= $(FS) public template.mk + $(MAKECMD) -ns DIRSEPSTR:=$(DIRSEPSTR) SHELL=cmd.exe COMSPEC=cmd.exe .KEEP_STATE:= $(MS) $($@-flags) >$(SH) + $(MAKECMD) -s $(MAKEMACROS) $(MS) $($@-flags) $(SET-TMP) fix-winnt-borland-$*-scripts + +winnt-microsft-%-scripts .SWAP .SILENT: + $(MAKECMD) -su $($@-flags) .KEEP_STATE:= $(FS) public template.mk + $(MAKECMD) -ns DIRSEPSTR:=$(DIRSEPSTR) SHELL=cmd.exe COMSPEC=cmd.exe .KEEP_STATE:= $(MS) $($@-flags) >$(SH) + $(MAKECMD) -s $(MAKEMACROS) $(MS) $($@-flags) $(SET-TMP) fix95nt-winnt-microsft-$*-scripts + + +# We make the standard OS/2 scripts here, but we have to go and fix up the +# mkXX.cmd file since it contains names of temporary files for the response +# files required by the linker. We need to also construct the response file +# contents. These two functions are performed by the fix-msdos-%-scripts +# meta-target. +# +# To add a new OS/2 environment just do what is described for adding a new +# unix environment, and then make certain that the fix-msdos-%-scripts target +# performs the correct function for the new environment. +os2-cf = OS=os2 +os2-ibm-icc-scripts-flags= $(os2-cf) OSRELEASE=ibm OSENVIRONMENT=icc + +os2-scripts: clean os2-ibm-scripts; + +os2-ibm-scripts .SWAP :! icc + $(MAKECMD) SCRIPTFILE=mk.cmd os2-ibm-$?-scripts + +os2-%-scripts .SWAP : + $(MAKECMD) -su $($@-flags) .KEEP_STATE:= $(FS) public template.mk + $(MAKECMD) -ns DIRSEPSTR:=$(DIRSEPSTR) SHELL=cmd.exe COMSPEC=cmd.exe .KEEP_STATE:= $(MS) SWITCHAR:=- $($@-flags) >$(SH) + $(MAKECMD) -s $(MAKEMACROS) $(MS) $($@-flags) $(SET-TMP) fix-os2-$*-scripts + cat $(SH) | sed -e 's, -, /,g' >tmp-out + mv tmp-out $(SH) + +# Signify NULL targets for the various Compiler versions. +icc 30 40 45 50 51 60 .PHONY:; + +# Go over the created script file and make sure all the '/' that are in +# filenames are '\', and make sure the final link command line looks +# reasonable. +MAPOBJ = obj$(SWAP:s/y/swp/:s/n//).rsp +MAPLIB = lib$(SWAP:s/y/swp/:s/n//).rsp +OBJRSP = $(SH:s,fix/,,:s,${SCRIPTFILE},${MAPOBJ},) +LIBRSP = $(SH:s,fix/,,:s,${SCRIPTFILE},${MAPLIB},) +OBJRSP95 = $(SH:s,fix95nt/,,:s,${SCRIPTFILE},${MAPOBJ},) +LIBRSP95 = $(SH:s,fix95nt/,,:s,${SCRIPTFILE},${MAPLIB},) +DOSOBJ = $(CSTARTUP) $(OBJDIR)/{$(OBJECTS)} + +# Use group recipes, as SHELL has an invalid value in some platform instances. +fix-%-scripts .GROUP: + tac $(FIX-SH) >tmp-sh-r + tail +3 tmp-sh-r | sed -e 's,/,\\,g' >tmp-out + tac tmp-out|\ + sed -e 's,\\nologo,/nologo,g' >$(FIX-SH) + head -2 tmp-sh-r |\ + sed -e 's,\\tmp\\mkA[a-zA-Z0-9]*,$(OBJRSP:s,/,\\),'\ + -e 's,\\tmp\\mkB[a-zA-Z0-9]*,$(LIBRSP:s,/,\\),'\ + -e 's,\\tmp\\mk[0-9]*a[a-z]*,$(OBJRSP:s,/,\\),'\ + -e 's,\\tmp\\mk[0-9]*b[a-z]*,$(LIBRSP:s,/,\\),'\ + -e 's,/,\\,g'\ + -e 's,\\nologo,/nologo,g'\ + -e 's,-,/,g' |\ + tac >>$(FIX-SH) + rm -f tmp-sh-r tmp-out + mv <+$(DOSOBJ:s,/,\\,:t"+\n")\n+> $(OBJRSP) + mv <+$(LDLIBS:s,/,\\,:t"+\n")\n+> $(LIBRSP) + +# Use group recipes, as SHELL has an invalid value in some platform instances. +fix95nt-%-scripts .GROUP: + tac $(FIX95-SH) >tmp-sh-r + tail +3 tmp-sh-r | sed -e 's,/,\\,g' >tmp-out + tac tmp-out|\ + sed -e 's,\\nologo,/nologo,g' >$(FIX95-SH) + head -2 tmp-sh-r |\ + sed -e 's,\\tmp\\mkA[a-zA-Z0-9]*,$(OBJRSP95:s,/,\\),'\ + -e 's,\\tmp\\mkB[a-zA-Z0-9]*,$(LIBRSP95:s,/,\\),'\ + -e 's,\\tmp\\mk[0-9]*a[a-z]*,$(OBJRSP95:s,/,\\),'\ + -e 's,\\tmp\\mk[0-9]*b[a-z]*,$(LIBRSP95:s,/,\\),'\ + -e 's,/,\\,g'\ + -e 's,\\nologo,/nologo,g'\ + -e 's,-,/,g' |\ + tac >>$(FIX95-SH) + rm -f tmp-sh-r tmp-out + mv <+$(DOSOBJ:s,/,\\,:t"\n")\n+> $(OBJRSP95) + mv <+$(LDLIBS:s,/,\\,:t"\n")\n+> $(LIBRSP95) diff --git a/dmake/man/dmake.nc b/dmake/man/dmake.nc new file mode 100644 index 000000000000..ea3c579a2881 --- /dev/null +++ b/dmake/man/dmake.nc @@ -0,0 +1,3696 @@ + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + +NAME + dmake - maintain program groups, or interdependent files + +SYNOPSIS + dmake [-P#] [-{f|C|K} file] [-{w|W} target ...] + [macro[[!][*][+][:]]=value ...] [-v{cdfimtw}] + [-ABcdeEghiknpqrsStTuVxX] [target ...] + +DESCRIPTION + dmake is a re-implementation of the UNIX Make utility with + significant enhancements. dmake executes commands found + in an external file called a makefile to update one or + more target names. Each target may depend on zero or more + prerequisite targets. If any of the target's prerequi- + sites is newer than the target or if the target itself + does not exist, then dmake will attempt to make the tar- + get. + + If no -f command line option is present then dmake + searches for an existing makefile from the list of prereq- + uisites specified for the special target .MAKEFILES (see + the STARTUP section for more details). If "-" is the name + of the file specified to the -f flag then dmake uses stan- + dard input as the source of the makefile text. + + Any macro definitions (arguments with embedded "=" signs) + that appear on the command line are processed first and + supercede definitions for macros of the same name found + within the makefile. In general it is impossible for def- + initions found inside the makefile to redefine a macro + defined on the command line, see the MACROS section for + exceptions. + + If no target names are specified on the command line, then + dmake uses the first non-special target found in the make- + file as the default target. See the SPECIAL TARGETS sec- + tion for the list of special targets and their function. + Makefiles written for most previous versions of Make will + be handled correctly by dmake. Known differences between + dmake and other versions of make are discussed in the COM- + PATIBILITY section found at the end of this document. + dmake returns 0 if no errors were detected and a non-zero + result if an error occurred. + +OPTIONS + -A Enable AUGMAKE special inference rule transforma- + tions (see the "PERCENT(%) RULES" section), these + are set to off by default. + + -B Enable the use of spaces instead of <tabs> to begin + recipe lines. This flag equivalent to the .NOTABS + special macro and is further described below. + + -c Use non-standard comment stripping. If you specify + + + +Version 4.01 PL0 UW 1 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + -c then dmake will treat any # character as a start + of comment character wherever it may appear unless + it is escaped by a \. + + -C [+]file + This option writes to file a copy of standard out- + put and standard error from any child processes and + from the dmake process itself. If you specify a + + prior to the file name then the text is appended to + the previous contents of file. This option is + active in the MSDOS implementation only and is + ignored by non-MSDOS versions of dmake. + + -d Disable the use of the directory cache. Normally + dmake caches directories as it checks file times- + tamps. Giving this flag is equivalent to the + .DIRCACHE attribute or macro being set to no. + + -E Read the environment and define all strings of the + form 'ENV-VAR=evalue' defined within as macros + whose name is ENV-VAR, and whose value is 'evalue'. + The environment is processed prior to processing + the user specified makefile thereby allowing defi- + nitions in the makefile to override definitions in + the environment. + + -e Same as -E, except that the environment is pro- + cessed after the user specified makefile has been + processed (thus definitions in the environment + override definitions in the makefile). The -e and + -E options are mutually exclusive. If both are + given the latter takes effect. + + -f file + Use file as the source for the makefile text. Only + one -f option is allowed. + + -g Globally disable group recipe parsing, equivalent + to the .IGNOREGROUP attribute or macro being set to + yes at the start of the makefile. + + -h Print the command summary for dmake. + + -i Tells dmake to ignore errors, and continue making + other targets. This is equivalent to the .IGNORE + attribute or macro. + + -K file + Turns on .KEEP_STATE state tracking and tells dmake + to use file as the state file. + + -k Causes dmake to ignore errors caused by command + execution and to make all targets not depending on + targets that could not be made. Ordinarily dmake + + + +Version 4.01 PL0 UW 2 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + stops after a command returns a non-zero status, + specifying -k causes dmake to ignore the error and + continue to make as much as possible. + + -n Causes dmake to print out what it would have exe- + cuted, but does not actually execute the commands. + A special check is made for the string "$(MAKE)" + inside a recipe line, if it is found, the line is + expanded and invoked, thereby enabling recursive + makes to give a full description of all that they + will do. This check is disabled inside group + recipes. + + -p Print out a version of the digested makefile in + human readable form. (useful for debugging, but + cannot be re-read by dmake) + + -P# On systems that support multi-processing cause + dmake to use # concurrent child processes to make + targets. See the "MULTI PROCESSING" section for + more information. + + -q Check and see if the target is up to date. Exits + with code 0 if up to date, 1 otherwise. + + -r Tells dmake not to read the initial startup make- + file, see STARTUP section for more details. + + -s Tells dmake to do all its work silently and not + echo the commands it is executing to stdout (also + suppresses warnings). This is equivalent to the + .SILENT attribute or macro. + + -S Force sequential execution of recipes on architec- + tures which support concurrent makes. For backward + compatibility with old makefiles that have nasty + side-effect prerequisite dependencies. + + -t Causes dmake to touch the targets and bring them up + to date without executing any commands. Note that + targets will not be created if they do not already + exist. + + -T Tells dmake to not perform transitive closure on + the inference graph. + + -u Force an unconditional update. (ie. do everything + that would be done if everything that a target + depended on was out of date) + + -v[dfimtw] + Verbose flag, when making targets print to stdout + what we are going to make and what we think its + time stamp is. The optional flags [dfimt] can be + + + +Version 4.01 PL0 UW 3 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + used to restrict the information that is displayed. + In the absence of any optional flags all are + assumed to be given (ie. -v is equivalent to + -vdfimt). The meanings of the optional flags are: + + c Notify of directory cache operations only. + + d Notify of change directory operations only. + + f Notify of file I/O operations only. + + i Notify of inference algorithm operation + only. + + m Notify of target update operations only. + + t Keep any temporary files created; normally + they are automatically deleted. + + w Notify of non-essential warnings (these are + historical). + + -V Print the version of dmake, and values of builtin + macros. + + -W target + Run dmake pretending that target is out of date. + + -w target + What if? Show what would be made if target were out + of date. + + -x Upon processing the user makefile export all non- + internally defined macros to the user's environ- + ment. This option together with the -e option + allows SYSV AUGMAKE recursive makes to function as + expected. + + -X Inhibit the execution of #! lines found at the + beginning of a makefile. The use of this flag pre- + vents non-termination of recursive make invoca- + tions. + +INDEX + Here is a list of the sections that follow and a short + description of each. Perhaps you won't have to read the + entire man page to find what you need. + + STARTUP Describes dmake initialization. + + SYNTAX Describes the syntax of makefile + expressions. + + ATTRIBUTES Describes the notion of attributes and + + + +Version 4.01 PL0 UW 4 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + how they are used when making targets. + + MACROS Defining and expanding macros. + + RULES AND TARGETS How to define targets and their prereq- + uisites. + + RECIPES How to tell dmake how to make a target. + + TEXT DIVERSIONS How to use text diversions in recipes + and macro expansions. + + SPECIAL TARGETS Some targets are special. + + SPECIAL MACROS Macros used by dmake to alter the pro- + cessing of the makefile, and those + defined by dmake for the user. + + CONTROL MACROS Itemized list of special control + macros. + + RUNTIME MACROS Discussion of special run-time macros + such as $@ and $<. + + FUNCTION MACROS GNU style function macros, only $(mktmp + ...) for now. + + CONDITIONAL MACROS Target specific conditional macros. + + DYNAMIC PREREQUISITES + Processing of prerequisites which con- + tain macro expansions in their name. + + BINDING TARGETS The rules that dmake uses to bind a + target to an existing file in the file + system. + + PERCENT(%) RULES Specification of recipes to be used by + the inference algorithm. + + MAKING INFERENCES The rules that dmake uses when infer- + ring how to make a target which has no + explicit recipe. This and the previous + section are really a single section in + the text. + + MAKING TARGETS How dmake makes targets other than + libraries. + + MAKING LIBRARIES How dmake makes libraries. + + KEEP STATE A discussion of how .KEEP_STATE works. + + MULTI PROCESSING Discussion of dmake's parallel make + + + +Version 4.01 PL0 UW 5 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + facilities for architectures that sup- + port them. + + CONDITIONALS Conditional expressions which control + the processing of the makefile. + + EXAMPLES Some hopefully useful examples. + + COMPATIBILITY How dmake compares with previous ver- + sions of make. + + LIMITS Limitations of dmake. + + PORTABILITY Comments on writing portable makefiles. + + FILES Files used by dmake. + + SEE ALSO Other related programs, and man pages. + + AUTHOR The guy responsible for this thing. + + BUGS Hope not. + +STARTUP + When dmake begins execution it first processes the command + line and then processes an initial startup-makefile. This + is followed by an attempt to locate and process a user + supplied makefile. The startup file defines the default + values of all required control macros and the set of + default rules for making targets and inferences. When + searching for the startup makefile, dmake searches the + following locations, in the order specified, until a + startup file is located: + + + 1. The location given as the value of the macro + MAKESTARTUP defined on the command line. + + 2. The location given as the value of the envi- + ronment variable MAKESTARTUP defined in the + current environment. + + 3. The location given as the value of the macro + MAKESTARTUP defined internally within dmake. + + The above search is disabled by specifying the -r option + on the command line. An error is issued if a startup + makefile cannot be found and the -r option was not speci- + fied. A user may substitute a custom startup file by + defining the MAKESTARTUP environment variable or by + redefining the MAKESTARTUP macro on the command line. To + determine where dmake looks for the default startup file, + check your environment or issue the command "dmake -V". + + + + +Version 4.01 PL0 UW 6 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + A similar search is performed to locate a default user + makefile when no -f command line option is specified. By + default, the prerequisite list of the special target + .MAKEFILES specifies the names of possible makefiles and + the search order that dmake should use to determine if one + exists. A typical definition for this target is: + + .MAKEFILES : makefile.mk Makefile makefile + + dmake will first look for makefile.mk and then the others. + If a prerequisite cannot be found dmake will try to make + it before going on to the next prerequisite. For example, + makefile.mk can be checked out of an RCS file if the + proper rules for doing so are defined in the startup file. + + If the first line of the user makefile is of the form: + + + then dmake will expand and run the command prior to read- + ing any additional input. If the return code of the com- + mand is zero then dmake will continue on to process the + remainder of the user makefile, if the return code is non- + zero then dmake will exit. + + dmake builds the internal dependency graph as it parses a + user specified makefile. The graph is rooted at the spe- + cial target .ROOT. .ROOT is the top level target that + dmake builds when it starts to build targets. All user + specified targets (those from the command line or taken as + defaults from the makefile) are made prerequisites of the + special target .TARGETS. dmake by default creates the + relationship that .ROOT depends on .TARGETS and as a + result everything is made. This approach allows the user + to customize, within their makefile, the order and which, + target, is built first. For example the default makefiles + come with settings for .ROOT that specify: + + .ROOT .PHONY .NOSTATE .SEQUENTIAL : .INIT .TARGETS + .DONE + + with .INIT and .DONE defined as: + + .INIT .DONE .PHONY:; + + which nicely emulates the behaviour of Sun's make exten- + sions. The building of .ROOT's prerequisites is always + forced to be sequential. However, this definition is + trivially chaned by supplying the definition: + + .ROOT : .TARGETS + + which skips the preamble and postamble phases of building + .TARGETS. + + + + +Version 4.01 PL0 UW 7 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + +SYNTAX + This section is a summary of the syntax of makefile state- + ments. The description is given in a style similar to + BNF, where { } enclose items that may appear zero or more + times, and [ ] enclose items that are optional. Alterna- + tive productions for a left hand side are indicated by + '->', and newlines are significant. All symbols in bold + type are text or names representing text supplied by the + user. + + + + Makefile -> { Statement } + + Statement -> Macro-Definition + -> Conditional-Macro-Definition + -> Conditional + -> Rule-Definition + -> Attribute-Definition + + Macro-Definition -> MACRO = LINE + -> MACRO [!]*= LINE + -> MACRO [!]:= LINE + -> MACRO [!]*:= LINE + -> MACRO [!]+= LINE + -> MACRO [!]+:= LINE + + Conditional-Macro-Definition -> TARGET ?= Macro-Definition + + Conditional -> .IF expression + Makefile + [ .ELIF expression + Makefile ] + [ .ELSE + Makefile ] + .END + + expression -> LINE + -> STRING == LINE + -> STRING != LINE + + Rule-Definition -> target-definition + [ recipe ] + + target-definition -> targets [attrs] op { PREREQUISITE } [; rcp-line] + + targets -> target { targets } + -> "target" { targets } + + target -> special-target + -> TARGET + + attrs -> attribute { attrs } + -> "attribute" { attrs } + + + +Version 4.01 PL0 UW 8 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + op -> : { modifier } + + modifier -> : + -> ^ + -> ! + -> - + -> | + + recipe -> { TAB rcp-line } + -> [@][%][-] [ + { LINE } + ] + + rcp-line -> [@][%][-][+] LINE + + Attribute-Definition -> attrs : targets + + attribute -> .EPILOG + -> .ERRREMOVE + -> .EXECUTE + -> .GROUP + -> .IGNORE + -> .IGNOREGROUP + -> .LIBRARY + -> .MKSARGS + -> .NOINFER + -> .NOSTATE + -> .PHONY + -> .PRECIOUS + -> .PROLOG + -> .SETDIR=path + -> .SILENT + -> .SEQUENTIAL + -> .SWAP + -> .USESHELL + -> .SYMBOL + -> .UPDATEALL + + special-target -> .ERROR + -> .EXIT + -> .EXPORT + -> .GROUPEPILOG + -> .GROUPPROLOG + -> .IMPORT + -> .INCLUDE + -> .INCLUDEDIRS + -> .MAKEFILES + -> .REMOVE + -> .SOURCE + -> .SOURCE.suffix + -> .suffix1.suffix2 + + + Where, TAB represents a <tab> character, STRING represents + + + +Version 4.01 PL0 UW 9 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + an arbitrary sequence of characters, and LINE represents a + possibly empty sequence of characters terminated by a non- + escaped (not immediately preceded by a backslash '\') new- + line character. MACRO, PREREQUISITE, and TARGET each rep- + resent a string of characters not including space or tab + which respectively form the name of a macro, prerequisite + or target. The name may itself be a macro expansion + expression. A LINE can be continued over several physical + lines by terminating it with a single backslash character. + Comments are initiated by the pound # character and extend + to the end of line. All comment text is discarded, a '#' + may be placed into the makefile text by escaping it with + '\' (ie. \# translates to # when it is parsed). An excep- + tion to this occurs when a # is seen inside a recipe line + that begins with a <tab> or is inside a group recipe. If + you specify the -c command line switch then this behavior + is disabled and dmake will treat all # characters as start + of comment indicators unless they are escaped by \. A set + of continued lines may be commented out by placing a sin- + gle # at the start of the first line. A continued line + cannot span more than one makefile. + + white space is defined to be any combination of <space>, + <tab>, and the sequence \<nl> when \<nl> is used to termi- + nate a LINE. When processing macro definition lines, any + amount of white space is allowed on either side of the + macro operator and white space is stripped from both + before and after the macro value string. The sequence + \<nl> is treated as white space during recipe expansion + and is deleted from the final recipe string. You must + escape the \<nl> with another \ in order to get a \ at the + end of a recipe line. The \<nl> sequence is deleted from + macro values when they are expanded. + + When processing target definition lines, the recipe for a + target must, in general, follow the first definition of + the target (See the RULES AND TARGETS section for an + exception), and the recipe may not span across multiple + makefiles. Any targets and prerequisites found on a tar- + get definition line are taken to be white space separated + tokens. The rule operator (op in SYNTAX section) is also + considered to be a token but does not require white space + to precede or follow it. Since the rule operator begins + with a `:', traditional versions of make do not allow the + `:' character to form a valid target name. dmake allows + `:' to be present in target/prerequisite names as long as + the entire target/prerequisite name is quoted. For exam- + ple: + + a:fred : test + + would be parsed as TARGET = a, PREREQUISITES={fred, :, + test}, which is not what was intended. To fix this you + must write: + + + +Version 4.01 PL0 UW 10 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + "a:fred" : test + + Which will be parsed as expected. Quoted target and pre- + requisite specifications may also contain white space + thereby allowing the use of complex function macro expres- + sions.. See the EXAMPLES section for how to apply " quot- + ing to a list of targets. + +ATTRIBUTES + dmake defines several target attributes. Attributes may + be assigned to a single target, a group of targets, or to + all targets in the makefile. Attributes are used to mod- + ify dmake actions during target update. The recognized + attributes are: + + + .EPILOG Insert shell epilog code when executing a + group recipe associated with any target having + this attribute set. + + .ERRREMOVE Always remove any target having this attribute + if an error is encountered while making them. + Setting this attribute overrides the .PRECIOUS + attribute. + + .EXECUTE If the -n flag was given then execute the + recipe associated with any target having this + attribute set. + + .FIRST Used in conjunction with .INCLUDE. Terminates + the inclusion with the first successfully + included prerequisite. + + .GROUP Force execution of a target's recipe as a + group recipe. + + .IGNORE Ignore an error when trying to make any target + with this attribute set. + + .IGNOREGROUP + Disable the special meaning of '[' to initiate + a group recipe. + + .LIBRARY Target is a library. + + .MKSARGS If running in an MSDOS environment then use + MKS extended argument passing conventions to + pass arguments to commands. Non-MSDOS envi- + ronments ignore this attribute. + + .NOINFER Any target with this attribute set will not be + subjected to transitive closure if it is + inferred as a prerequisite of a target whose + recipe and prerequisites are being inferred. + + + +Version 4.01 PL0 UW 11 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + (i.e. the inference algorithm will not use any + prerequisite with this attribute set, as a + target) If specified as '.NOINFER:' (ie. with + no prerequisites or targets) then the effect + is equivalent to specifying -T on the command + line. + + .NOSTATE Any target with this attribute set will not + have command line flag information stored in + the state file if .KEEP_STATE has been + enabled. + + .PHONY Any target with this attribute set will have + its recipe executed each time the target is + made even if a file matching the target name + can be located. Any targets that have a + .PHONY attributed target as a prerequisite + will be made each time the .PHONY attributed + prerequisite is made. + + .PRECIOUS Do not remove associated target under any cir- + cumstances. Set by default for any targets + whose corresponding files exist in the file + system prior to the execution of dmake. + + .PROLOG Insert shell prolog code when executing a + group recipe associated with any target having + this attribute set. + + .SEQUENTIAL Force a sequential make of the associated tar- + get's prerequisites. + + .SETDIR Change current working directory to specified + directory when making the associated target. + You must specify the directory at the time the + attribute is specified. To do this simply + give .SETDIR=path as the attribute. path is + expanded and the result is used as the value + of the directory to change to. If path con- + tains $$@ then the name of the target to be + built is used in computing the path to change + directory to. If path is surrounded by single + quotes then path is not expanded, and is used + literally as the directory name. If the path + contains any `:' characters then the entire + attribute string must be quoted using ". If a + target having this attribute set also has the + .IGNORE attribute set then if the change to + the specified directory fails it will be + ignored, and no error message will be issued. + + .SILENT Do not echo the recipe lines when making any + target with this attribute set, and do not + issue any warnings. + + + +Version 4.01 PL0 UW 12 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + .SWAP Under MSDOS when making a target with this + attribute set swap the dmake executable to + disk prior to executing the recipe line. Also + see the '%' recipe line flag defined in the + RECIPES section. + + .SYMBOL Target is a library member and is an entry + point into a module in the library. This + attribute is used only when searching a + library for a target. Targets of the form + lib((entry)) have this attribute set automati- + cally. + + .USESHELL Force each recipe line of a target to be exe- + cuted using a shell. Specifying this + attribute is equivalent to specifying the '+' + character at the start of each line of a non- + group recipe. + + .UPDATEALL Indicates that all the targets listed in this + rule are updated by the execution of the + accompanying recipe. A common example is the + production of the y.tab.c and y.tab.h files by + yacc when it is run on a grammar. Specifying + .UPDATEALL in such a rule prevents the running + of yacc twice, once for the y.tab.c file and + once for the y.tab.h file. .UPDATEALL targets + that are specified in a single rule are + treated as a single target and all timestamps + are updated whenever any target in the set is + made. As a side-effect, dmake internally + sorts such targets in ascending alphabetical + order and the value of $@ is always the first + target in the sorted set. + + All attributes are user setable and except for .UPDATEALL, + .SETDIR and .MKSARGS may be used in one of two forms. The + .MKSARGS attribute is restricted to use as a global + attribute, and the use of the .UPDATEALL and .SETDIR + attributes is restricted to rules of the second form only. + + ATTRIBUTE_LIST : targets + + assigns the attributes specified by ATTRIBUTE_LIST to each + target in targets or + + targets ATTRIBUTE_LIST : ... + + assigns the attributes specified by ATTRIBUTE_LIST to each + target in targets. In the first form if targets is empty + (ie. a NULL list), then the list of attributes will apply + to all targets in the makefile (this is equivalent to the + common Make construct of ".IGNORE :" but has been modified + to the notion of an attribute instead of a special + + + +Version 4.01 PL0 UW 13 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + target). Not all of the attributes have global meaning. + In particular, .LIBRARY, .NOSTATE, .PHONY, .SETDIR, .SYM- + BOL and .UPDATEALL have no assigned global meaning. + + Any attribute may be used with any target, even with the + special targets. Some combinations are useless (e.g. + .INCLUDE .PRECIOUS: ... ), while others are useful (e.g. + .INCLUDE .IGNORE : "file.mk" will not complain if file.mk + cannot be found using the include file search rules, see + the section on SPECIAL TARGETS for a description of + .INCLUDE). If a specified attribute will not be used with + the special target a warning is issued and the attribute + is ignored. + +MACROS + dmake supports six forms of macro assignment. + + + MACRO = LINE This is the most common and familiar form + of macro assignment. It assigns LINE lit- + erally as the value of MACRO. Future + expansions of MACRO recursively expand its + value. + + MACRO *= LINE This form behaves exactly as the simple + '=' form with the exception that if MACRO + already has a value then the assignment is + not performed. + + MACRO := LINE This form differs from the simple '=' form + in that it expands LINE prior to assigning + it as the value of MACRO. Future expan- + sions of MACRO do not recursively expand + its value. + + MACRO *:= LINE This form behaves exactly as the ':=' form + with the exception that if MACRO already + has a value then the assignment and expan- + sion are not performed. + + MACRO += LINE This form of macro assignment allows macro + values to grow. It takes the literal + value of LINE and appends it to the previ- + ous value of MACRO separating the two by a + single space. Future expansions of MACRO + recursively expand its value. + + MACRO +:= LINE This form is similar to the '+=' form + except that the value of LINE is expanded + prior to being added to the value of + MACRO. + + Macro expressions specified on the command line allow the + macro value to be redefined within the makefile only if + + + +Version 4.01 PL0 UW 14 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + the macro is defined using the '+=' and '+:=' operators. + Other operators will define a macro that cannot be further + modified. + + Each of the preceeding macro assignment operators may be + prefixed by ! to indicate that the assignment should be + forced and that no warnings should be issued. Thus, spec- + ifying ! has the effect of silently forcing the specified + macro assignment. + + When dmake defines a non-environment macro it strips lead- + ing and trailing white space from the macro value. Macros + imported from the environment via either the .IMPORT spe- + cial target (see the SPECIAL TARGETS section), or the -e, + or -E flags are an exception to this rule. Their values + are always taken literally and white space is never + stripped. In addition, named macros defined using the + .IMPORT special target do not have their values expanded + when they are used within a makefile. In contrast, envi- + ronment macros that are imported due to the specification + of the -e or -E flags are subject to expansion when used. + + To specify a macro expansion enclose the name in () or {} + and precede it with a dollar sign $. Thus $(TEST) repre- + sents an expansion of the macro variable named TEST. If + TEST is defined then $(TEST) is replaced by its expanded + value. If TEST is not defined then $(TEST) expands to the + NULL string (this is equivalent to defining a macro as + 'TEST=' ). A short form may be used for single character + named macros. In this case the parentheses are optional, + and $(I) is equivalent to $I. Macro expansion is recur- + sive, hence, if the value string contains an expression + representing a macro expansion, the expansion is per- + formed. Circular macro expansions are detected and cause + an error to be issued. + + When defining a macro the given macro name is first + expanded before being used to define the macro. Thus it + is possible to define macros whose names depend on values + of other macros. For example, suppose CWD is defined as + + CWD = $(PWD:b) + + then the value of $(CWD) is the name of the current direc- + tory. This can be used to define macros specific to this + directory, for example: + + _$(CWD).prt = list of files to print... + + The actual name of the defined macro is a function of the + current directory. A construct such as this is useful + when processing a hierarchy of directories using .SETDIR + attributed targets and a collection of small distributed + makefile stubs. + + + +Version 4.01 PL0 UW 15 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + Macro variables may be defined within the makefile, on the + command line, or imported from the environment. + + dmake supports several non-standard macro expansions: The + first is of the form: + + $(macro_name:modifier_list:modifier_list:...) + + where modifier_list is chosen from the set { B or b, D or + d, E or e, F or f, I or i, L or l, S or s, T or t, U or u, + ^, +, 1 } and + + b - file (not including suffix) portion of path names + d - directory portion of all path names + e - suffix portion of path names + f - file (including suffix) portion of path names + i - inferred names of targets + l - macro value in lower case + s - simple pattern substitution + t - tokenization. + u - macro value in upper case + ^ - prepend a prefix to each token + + - append a suffix to each token + 1 - return the first white space separated token from value + + Thus if we have the example: + test = d1/d2/d3/a.out f.out d1/k.out + The following macro expansions produce the values on the + right of '->' after expansion. + + $(test:d) -> d1/d2/d3/ d1/ + $(test:b) -> a f k + $(test:f) -> a.out f.out k.out + ${test:db} -> d1/d2/d3/a f d1/k + ${test:s/out/in/:f} -> a.in f.in k.in + $(test:f:t"+") -> a.out+f.out+k.out + $(test:e) -> .out .out .out + $(test:u) -> D1/D2/D3/A.OUT F.OUT D1/K.OUT + $(test:1) -> d1/d2/d3/a.out + + If a token ends in a string composed from the value of the + macro DIRBRKSTR (ie. ends in a directory separator string, + e.g. '/' in UNIX) and you use the :d modifier then the + expansion returns the directory name less the final direc- + tory separator string. Thus successive pairs of :d modi- + fiers each remove a level of directory in the token + string. + + The tokenization modifier takes all white space separated + tokens from the macro value and separates them by the + quoted separator string. The separator string may contain + the following escape codes \a => <bel>, \b => <backspace>, + \f => <formfeed>, \n => <nl>, \r => <cr>, \t => <tab>, \v + => <vertical tab>, \" => ", and \xxx => <xxx> where xxx is + + + +Version 4.01 PL0 UW 16 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + the octal representation of a character. Thus the expan- + sion: + + $(test:f:t"+\n") + produces: + a.out+ + f.out+ + k.out + + The prefix operator ^ takes all white space separated + tokens from the macro value and prepends string to each. + + $(test:f:^mydir/) + produces: + mydir/a.out mydir/f.out mydir/k.out + + The suffix operator + takes all white space separated + tokens from the macro value and appends string to each. + + $(test:b:+.c) + produces: + a.c f.c k.c + + The next non-standard form of macro expansion allows for + recursive macros. It is possible to specify a + $(macro_name) or ${macro_name} expansion where macro_name + contains more $( ... ) or ${ ... } macro expansions + itself. + + For example $(CC$(_HOST)$(_COMPILER)) will first expand + CC$(_HOST)$(_COMPILER) to get a result and use that result + as the name of the macro to expand. This is useful for + writing a makefile for more than one target environment. + As an example consider the following hypothetical case. + Suppose that _HOST and _COMPILER are imported from the + environment and are set to represent the host machine type + and the host compiler respectively. + + CFLAGS_VAX_CC = -c -O # _HOST == "_VAX", _COMPILER == "_CC" + CFLAGS_PC_MSC = -c -ML # _HOST == "_PC", _COMPILER == "_MSC" + + # redefine CFLAGS macro as: + + CFLAGS := $(CFLAGS$(_HOST)$(_COMPILER)) + + This causes CFLAGS to take on a value that corresponds to + the environment in which the make is being invoked. + + The final non-standard macro expansion is of the form: + + string1{token_list}string2 + + where string1, string2 and token_list are expanded. After + expansion, string1 is prepended to each token found in + + + +Version 4.01 PL0 UW 17 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + token_list and string2 is appended to each resulting token + from the previous prepend. string1 and string2 are not + delimited by white space whereas the tokens in token_list + are. A null token in the token list is specified using + "". Thus using another example we have: + + test/{f1 f2}.o --> test/f1.o test/f2.o + test/ {f1 f2}.o --> test/ f1.o f2.o + test/{f1 f2} .o --> test/f1 test/f2 .o + test/{"f1" ""}.o --> test/f1.o test/.o + + and + + test/{d1 d2}/{f1 f2}.o --> test/d1/f1.o test/d1/f2.o + test/d2/f1.o test/d2/f2.o + + This last expansion is activated only when the first char- + acters of token_list appear immediately after the opening + '{' with no intervening white space. The reason for this + restriction is the following incompatibility with Bourne + Shell recipes. The line + + { echo hello;} + + is valid /bin/sh syntax; while + + {echo hello;} + + is not. Hence the latter triggers the enhanced macro + expansion while the former causes it to be suppressed. + See the SPECIAL MACROS section for a description of the + special macros that dmake defines and understands. + +RULES AND TARGETS + A makefile contains a series of entries that specify + dependencies. Such entries are called target/prerequisite + or rule definitions. Each rule definition is optionally + followed by a set of lines that provide a recipe for + updating any targets defined by the rule. Whenever dmake + attempts to bring a target up to date and an explicit + recipe is provided with a rule defining the target, that + recipe is used to update the target. A rule definition + begins with a line having the following syntax: + + <targets> [<attributes>] <ruleop> [<prerequisites>] [;<recipe>] + + targets is a non-empty list of targets. If the target is + a special target (see SPECIAL TARGETS section below) then + it must appear alone on the rule line. For example: + + .IMPORT .ERROR : ... + + is not allowed since both .IMPORT and .ERROR are special + targets. Special targets are not used in the construction + + + +Version 4.01 PL0 UW 18 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + of the dependency graph and will not be made. + + attributes is a possibly empty list of attributes. Any + attribute defined in the ATTRIBUTES section above may be + specified. All attributes will be applied to the list of + named targets in the rule definition. No other targets + will be affected. + + + NOTE: As stated earlier, if both the target list and + prerequisite list are empty but the attributes + list is not, then the specified attributes affect + all targets in the makefile. + + + ruleop is a separator which is used to identify the tar- + gets from the prerequisites. Optionally it also provides + a facility for modifying the way in which dmake handles + the making of the associated targets. In its simplest + form the operator is a single ':', and need not be sepa- + rated by white space from its neighboring tokens. It may + additionally be followed by any of the modifiers { !, ^, + -, :, | }, where: + + + ! says execute the recipe for the associated targets + once for each out of date prerequisite. Ordinarily + the recipe is executed once for all out of date + prerequisites at the same time. + + ^ says to insert the specified prerequisites, if any, + before any other prerequisites already associated + with the specified targets. In general, it is not + useful to specify ^ with an empty list of prerequi- + sites. + + - says to clear the previous list of prerequisites + before adding the new prerequisites. Thus, + + .SUFFIXES : + .SUFFIXES : .a .b + + can be replaced by + + .SUFFIXES :- .a .b + + however the old form still works as expected. + NOTE: .SUFFIXES is ignored by dmake it is used + here simply as an example. + + : When the rule operator is not modified by a second + ':' only one set of rules may be specified for mak- + ing a target. Multiple definitions may be used to + add to the list of prerequisites that a target + + + +Version 4.01 PL0 UW 19 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + depends on. However, if a target is multiply + defined only one definition may specify a recipe + for making the target. + + When a target's rule operator is modified by a sec- + ond ':' (:: for example) then this definition may + not be the only definition with a recipe for the + target. There may be other :: target definition + lines that specify a different set of prerequisites + with a different recipe for updating the target. + Any such target is made if any of the definitions + find it to be out of date with respect to the + related prerequisites and the corresponding recipe + is used to update the target. By definition all + '::' recipes that are found to be out of date for + are executed. + + In the following simple example, each rule has a + `::' ruleop. In such an operator we call the first + `:' the operator, and the second `:' the modifier. + + a.o :: a.c b.h + first recipe for making a.o + + a.o :: a.y b.h + second recipe for making a.o + + If a.o is found to be out of date with respect to + a.c then the first recipe is used to make a.o. If + it is found out of date with respect to a.y then + the second recipe is used. If a.o is out of date + with respect to b.h then both recipes are invoked + to make a.o. In the last case the order of invoca- + tion corresponds to the order in which the rule + definitions appear in the makefile. + + | Is defined only for PERCENT rule target defini- + tions. When specified it indicates that the fol- + lowing construct should be parsed using the old + semantinc meaning: + + %.o :| %.c %.r %.f ; some rule + + is equivalent to: + + %.o : %.c ; some rule + %.o : %.r ; some rule + %.o : %.f ; some rule + + Targets defined using a single `:' operator with a recipe + may be redefined again with a new recipe by using a `:' + operator with a `:' modifier. This is equivalent to a + target having been initially defined with a rule using a + `:' modifier. Once a target is defined using a `:' + + + +Version 4.01 PL0 UW 20 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + modifier it may not be defined again with a recipe using + only the `:' operator with no `:' modifier. In both cases + the use of a `:' modifier creates a new list of prerequi- + sites and makes it the current prerequisite list for the + target. The `:' operator with no recipe always modifies + the current list of prerequisites. Thus assuming each of + the following definitions has a recipe attached, then: + + joe : fred ... (1) + joe :: more ... (2) + + and + + joe :: fred ... (3) + joe :: more ... (4) + + are legal and mean: add the recipe associated with (2), + or (4) to the set of recipes for joe, placing them after + existing recipes for making joe. The constructs: + + joe :: fred ... (5) + joe : more ... (6) + + and + + joe : fred ... (7) + joe : more ... (8) + + are errors since we have two sets of perfectly good + recipes for making the target. + + prerequisites is a possibly empty list of targets that + must be brought up to date before making the current tar- + get. + + recipe is a short form and allows the user to specify + short rule definitions on a single line. It is taken to + be the first recipe line in a larger recipe if additional + lines follow the rule definition. If the semi-colon is + present but the recipe line is empty (ie. null string) + then it is taken to be an empty rule. Any target so + defined causes the Don't know how to make ... error mes- + sage to be suppressed when dmake tries to make the target + and fails. This silence is maintained for rules that are + terminated by a semicolon and have no following recipe + lines, for targets listed on the command line, for the + first target found in the makefile, and for any target + having no recipe but containing a list of prerequisites + (see the COMPATIBILITY section for an exception to this + rule if the AUGMAKE (-A) flag was specified. + +RECIPES + The traditional format used by most versions of Make + defines the recipe lines as arbitrary strings that may + + + +Version 4.01 PL0 UW 21 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + contain macro expansions. They follow a rule definition + line and may be spaced apart by comment or blank lines. + The list of recipe lines defining the recipe is terminated + by a new target definition, a macro definition, or end-of- + file. Each recipe line MUST begin with a <TAB> character + which may optionally be followed with one or all of the + characters '@%+-'. The '-' indicates that non-zero exit + values (ie. errors) are to be ignored when this recipe + line is executed, the '+' indicates that the current + recipe line is to be executed using the shell, the '%' + indicates that dmake should swap itself out to secondary + storage (MSDOS only) before running the recipe and the '@' + indicates that the recipe line should NOT be echoed to the + terminal prior to being executed. Each switch is off by + default (ie. by default, errors are significant, commands + are echoed, no swapping is done and a shell is used only + if the recipe line contains a character found in the value + of the SHELLMETAS macro). Global settings activated via + command line options or special attribute or target names + may also affect these settings. An example recipe: + + target : + first recipe line + second recipe line, executed independent of first. + @a recipe line that is not echoed + -and one that has errors ignored + %and one that causes dmake to swap out + +and one that is executed using a shell. + + The second and new format of the recipe block begins the + block with the character '[' (the open group character) in + the last non-white space position of a line, and termi- + nates the block with the character ']' (the close group + character) in the first non-white space position of a + line. In this form each recipe line need not have a lead- + ing TAB. This is called a recipe group. Groups so + defined are fed intact as a single unit to a shell for + execution whenever the corresponding target needs to be + updated. If the open group character '[' is preceded by + one or all of -, @ or % then they apply to the entire + group in the same way that they apply to single recipe + lines. You may also specify '+' but it is redundant as a + shell is already being used to run the recipe. See the + MAKING TARGETS section for a description of how dmake + invokes recipes. Here is an example of a group recipe: + + target : + [ + first recipe line + second recipe line + tall of these recipe lines are fed to a + single copy of a shell for execution. + ] + + + + +Version 4.01 PL0 UW 22 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + +TEXT DIVERSIONS + dmake supports the notion of text diversions. If a recipe + line contains the macro expression + + $(mktmp[,[file][,text]] data) + + then all text contained in the data expression is expanded + and is written to a temporary file. The return value of + the macro is the name of the temporary file. + + data can be any text and must be separated from the + 'mktmp' portion of the macro name by white-space. The + only restriction on the data text is that it must contain + a balanced number of parentheses of the same kind as are + used to initiate the $(mktmp ...) expression. For exam- + ple: + + $(mktmp $(XXX)) + + is legal and works as expected, but: + + $(mktmp text (to dump to file) + + is not legal. You can achieve what you wish by either + defining a macro that expands to '(' or by using {} in the + macro expression; like this: + + ${mktmp text (to dump to file} + + Since the temporary file is opened when the macro contain- + ing the text diversion expression is expanded, diversions + may be nested and any diversions that are created as part + of ':=' macro expansions persist for the duration of the + dmake run. The diversion text may contain the same escape + codes as those described in the MACROS section. Thus if + the data text is to contain new lines they must be + inserted using the \n escape sequence. For example the + expression: + + all: + cat $(mktmp this is a\n\ + test of the text diversion\n) + + is replaced by: + + cat /tmp/mk12294AA + + where the temporary file contains two lines both of which + are terminated by a new-line. If the data text spans mul- + tiple lines in the makefile then each line must be contin- + ued via the use of a \. A second more illustrative exam- + ple generates a response file to an MSDOS link command: + + OBJ = fred.obj mary.obj joe.obj + + + +Version 4.01 PL0 UW 23 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + all : $(OBJ) + link @$(mktmp $(^:t"+\n")\n) + + The result of making `all' in the second example is the + command: + + link @/tmp/mk02394AA + + where the temporary file contains: + + fred.obj+ + mary.obj+ + joe.obj + + The last line of the file is terminated by a new-line + which is inserted due to the \n found at the end of the + data string. + + If the optional file specifier is present then its + expanded value is the name of the temporary file to cre- + ate. Whenever a $(mktmp ...) macro is expanded the macro + $(TMPFILE) is set to a new temporary file name. Thus the + construct: + + $(mktmp,$(TMPFILE) data) + + is completely equivalent to not specifying the $(TMPFILE) + optional argument. Another example that would be useful + for MSDOS users with a Turbo-C compiler + + $(mktmp,turboc.cfg $(CFLAGS)) + + will place the contents of CFLAGS into a local turboc.cfg + file. The second optional argument, text, if present + alters the name of the value returned by the $(mktmp ...) + macro. + + Under MS-DOS text diversions may be a problem. Many DOS + tools require that path names which contain directories + use the \ character to delimit the directories. Some + users however wish to use the '/' to delimit pathnames and + use environments that allow them to do so. The macro USE- + SHELL is set to "yes" if the current recipe is forced to + use a shell via the .USESHELL or '+' directives, otherwise + its value is "no". The dmake startup files define the + macro DIVFILE whose value is either the value of TMPFILE + or the value of TMPFILE edited to replace any '/' charac- + ters to the appropriate value based on the current shell + and whether it will be used to execute the recipe. + + Previous versions of dmake defined text diversions using + <+, +> strings, where <+ started a text diversion and +> + terminated one. dmake is backward compatible with this + construct only if the <+ and +> appear literally on the + + + +Version 4.01 PL0 UW 24 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + same recipe line or in the same macro value string. In + such instances the expression: + + <+data+> + + is mapped to: + + $(mktmp data) + + which is fully output compatible with the earlier con- + struct. <+, +> constructs whose text spans multiple lines + must be converted by hand to use $(mktmp ...). + + If the environment variable TMPDIR is defined then the + temporary file is placed into the directory specified by + that variable. A makefile can modify the location of tem- + porary files by defining a macro named TMPDIR and export- + ing it using the .EXPORT special target. + +SPECIAL TARGETS + This section describes the special targets that are recog- + nized by dmake. Some are affected by attributes and oth- + ers are not. + + .ERROR If defined then the recipe associated with + this target is executed whenever an error + condition is detected by dmake. All + attributes that can be used with any other + target may be used with this target. Any + prerequisites of this target will be brought + up to date during its processing. NOTE: + errors will be ignored while making this + target, in extreme cases this may cause some + problems. + + .EXIT If this target is encountered while parsing + a makefile then the parsing of the makefile + is immediately terminated at that point. + + .EXPORT All prerequisites associated with this tar- + get are assumed to correspond to macro names + and they and their values are exported to + the environment as environment strings at + the point in the makefile at which this tar- + get appears. Any attributes specified with + this target are ignored. Only macros which + have been assigned a value in the makefile + prior to the export directive are exported, + macros as yet undefined or macros whose + value contains any of the characters "+=:*" + are not exported. is suppre + + .IMPORT Prerequisite names specified for this target + are searched for in the environment and + + + +Version 4.01 PL0 UW 25 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + defined as macros with their value taken + from the environment. If the special name + .EVERYTHING is used as a prerequisite name + then all environment variables defined in + the environment are imported. The function- + ality of the -E flag can be forced by plac- + ing the construct .IMPORT : .EVERYTHING at + the start of a makefile. Similarly, by + placing the construct at the end, one can + emulate the effect of the -e command line + flag. If a prerequisite name cannot be + found in the environment an error message is + issued. .IMPORT accepts the .IGNORE + attribute. When given, it causes dmake to + ignore the above error. See the MACROS sec- + tion for a description of the processing of + imported macro values. + + .INCLUDE Parse another makefile just as if it had + been located at the point of the .INCLUDE in + the current makefile. The list of prerequi- + sites gives the list of makefiles to try to + read. If the list contains multiple make- + files then they are read in order from left + to right. The following search rules are + used when trying to locate the file. If the + filename is surrounded by " or just by + itself then it is searched for in the cur- + rent directory. If it is not found it is + then searched for in each of the directories + specified as prerequisites of the + .INCLUDEDIRS special target. If the file + name is surrounded by < and >, (ie. + <my_spiffy_new_makefile>) then it is + searched for only in the directories given + by the .INCLUDEDIRS special target. In both + cases if the file name is a fully qualified + name starting at the root of the file system + then it is only searched for once, and the + .INCLUDEDIRS list is ignored. If .INCLUDE + fails to find the file it invokes the infer- + ence engine to try to infer and hence make + the file to be included. In this way the + file can be checked out of an RCS repository + for example. .INCLUDE accepts the .IGNORE, + .SETDIR, and .NOINFER attributes. If the + .IGNORE attribute is given and the file can- + not be found then dmake continues process- + ing, otherwise an error message is gener- + ated. If the .NOINFER attribute is given + and the file cannot be found then dmake will + not attempt to infer and make the file. The + .SETDIR attribute causes dmake to change + directories to the specified directory prior + + + +Version 4.01 PL0 UW 26 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + to attempting the include operation. If all + fails dmake attempts to make the file to be + included. If making the file fails then + dmake terminates unless the .INCLUDE direc- + tive also specified the .IGNORE attribute. + If .FIRST is specified along with .INCLUDE + then dmake attempts to include each named + prerequisite and will terminate the inclu- + sion with the first prerequisite that + results in a successful inclusion. + + .INCLUDEDIRS The list of prerequisites specified for this + target defines the set of directories to + search when trying to include a makefile. + + .KEEP_STATE This special target is a synonym for the + macro definition + + .KEEP_STATE := _state.mk + + It's effect is to turn on STATE keeping and + to define _state.mk as the state file. + + .MAKEFILES The list of prerequisites is the set of + files to try to read as the default make- + file. By default this target is defined as: + + .MAKEFILES : makefile.mk Makefile makefile + + + .SOURCE The prerequisite list of this target defines + a set of directories to check when trying to + locate a target file name. See the section + on BINDING of targets for more information. + + .SOURCE.suff The same as .SOURCE, except that the + .SOURCE.suff list is searched first when + trying to locate a file matching the a tar- + get whose name ends in the suffix .suff. + + .REMOVE The recipe of this target is used whenever + dmake needs to remove intermediate targets + that were made but do not need to be kept + around. Such targets result from the appli- + cation of transitive closure on the depen- + dency graph. + + In addition to the special targets above, several other + forms of targets are recognized and are considered spe- + cial, their exact form and use is defined in the sections + that follow. + +SPECIAL MACROS + dmake defines a number of special macros. They are + + + +Version 4.01 PL0 UW 27 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + divided into three classes: control macros, run-time + macros, and function macros. The control macros are used + by dmake to configure its actions, and are the preferred + method of doing so. In the case when a control macro has + the same function as a special target or attribute they + share the same name as the special target or attribute. + The run-time macros are defined when dmake makes targets + and may be used by the user inside recipes. The function + macros provide higher level functions dealing with macro + expansion and diversion file processing. + +CONTROL MACROS + To use the control macros simply assign them a value just + like any other macro. The control macros are divided into + three groups: string valued macros, character valued + macros, and boolean valued macros. + + The following are all of the string valued macros. This + list is divided into two groups. The first group gives + the string valued macros that are defined internally and + cannot be directly set by the user. + + INCDEPTH This macro's value is a string of digits + representing the current depth of makefile + inclusion. In the first makefile level + this value is zero. + + MFLAGS Is the list of flags that were given on + the command line including a leading + switch character. The -f flag is not + included in this list. + + MAKECMD Is the name with which dmake was invoked. + + MAKEDIR Is the full path to the initial directory + in which dmake was invoked. + + MAKEFILE Contains the string "-f makefile" where, + makefile is the name of initial user make- + file that was first read. + + MAKEFLAGS Is the same as $(MFLAGS) but has no lead- + ing switch character. (ie. MFLAGS = + -$(MAKEFLAGS)) + + MAKEMACROS Contains the complete list of macro + expressions that were specified on the + command line. + + MAKETARGETS Contains the name(s) of the target(s), if + any, that were specified on the command + line. + + MAKEVERSION Contains a string indicating the current + + + +Version 4.01 PL0 UW 28 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + dmake version number. + + MAXPROCESSLIMIT Is a numeric string representing the maxi- + mum number of processes that dmake can use + when making targets using parallel mode. + + NULL Is permanently defined to be the NULL + string. This is useful when comparing a + conditional expression to an NULL value. + + PWD Is the full path to the current directory + in which make is executing. + + TMPFILE Is set to the name of the most recent tem- + porary file opened by dmake. Temporary + files are used for text diversions and for + group recipe processing. + + TMD Stands for "To Make Dir", and is the path + from the present directory (value of + $(PWD)) to the directory that dmake was + started up in (value of $(MAKEDIR)). This + macro is modified when .SETDIR attributes + are processed. + + USESHELL The value of this macro is set to "yes" if + the current recipe is forced to use a + shell for its execution via the .USESHELL + or '+' directives, its value is "no" oth- + erwise. + + + The second group of string valued macros control dmake + behavior and may be set by the user. + + .DIRCACHE If set to "yes" enables the directory + cache (this is the default). If set to + "no" disables the directory cache (equiva- + lent to -d command-line flag). + + .DIRCACHERESPCASE + If set to "yes" causes the directory + cache, if enabled, to respect file case, + if set to "no" facilities of the native OS + are used to match file case. + + .NAMEMAX Defines the maximum length of a filename + component. The value of the variable is + initialized at startup to the value of the + compiled macro NAME_MAX. On some systems + the value of NAME_MAX is too short by + default. Setting a new value for .NAMEMAX + will override the compiled value. + + + + +Version 4.01 PL0 UW 29 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + .NOTABS When set to "yes" enables the use of + spaces as well as <tabs> to begin recipe + lines. By default a non-group recipe is + terminated by a line without any leading + white-space or by a line not beggining + with a <tab> character. Enabling this + mode modifies the first condition of the + above termination rule to terminate a + non-group recipe with a line that contains + only white-space. This mode does not + effect the parsing of group recipes brack- + eted by []. + + AUGMAKE If set to "yes" value will enable the + transformation of special meta targets to + support special AUGMAKE inferences (See + the COMPATIBILITY section). + + DIRBRKSTR Contains the string of chars used to ter- + minate the name of a directory in a path- + name. Under UNIX its value is "/", under + MSDOS its value is "/\:". + + DIRSEPSTR Contains the string that is used to sepa- + rate directory components when path names + are constructed. It is defined with a + default value at startup. + + DIVFILE Is defined in the startup file and gives + the name that should be returned for the + diversion file name when used in $(mktmp + ...) expansions, see the TEXT DIVERSION + section for details. + + DYNAMICNESTINGLEVEL + Specifies the maximum number of recursive + dynamic macro expansions. Its initial + value is 100. + + .KEEP_STATE Assigning this macro a value tells dmake + the name of the state file to use and + turns on the keeping of state information + for any targets that are brought up to + date by the make. + + GROUPFLAGS This macro gives the set of flags to pass + to the shell when invoking it to execute a + group recipe. The value of the macro is + the list of flags with a leading switch + indicator. (ie. `-' under UNIX) + + GROUPSHELL This macro defines the full path to the + executable image to be used as the shell + when processing group recipes. This macro + + + +Version 4.01 PL0 UW 30 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + must be defined if group recipes are used. + It is assigned a default value in the + startup makefile. Under UNIX this value + is /bin/sh. + + GROUPSUFFIX If defined, this macro gives the string to + use as a suffix when creating group recipe + files to be handed to the command inter- + preter. For example, if it is defined as + .sh, then all temporary files created by + dmake will end in the suffix .sh. Under + MSDOS if you are using command.com as your + GROUPSHELL, then this suffix must be set + to .bat in order for group recipes to + function correctly. The setting of GROUP- + SUFFIX and GROUPSHELL is done automati- + cally for command.com in the startup.mk + files. + + MAKE Is defined in the startup file by default. + Initially this macro is defined to have + the value "$(MAKECMD) $(MFLAGS)". The + string $(MAKE) is recognized when using + the -n switch. + + MAKESTARTUP This macro defines the full path to the + initial startup makefile. Use the -V com- + mand line option to discover its initial + value. + + MAXLINELENGTH This macro defines the maximum size of a + single line of makefile input text. The + size is specified as a number, the default + value is defined internally and is shown + via the -V option. A buffer of this size + plus 2 is allocated for reading makefile + text. The buffer is freed before any tar- + gets are made, thereby allowing files con- + taining long input lines to be processed + without consuming memory during the actual + make. This macro can only be used to + extend the line length beyond it's default + minimum value. + + MAXPROCESS Specify the maximum number of child pro- + cesses to use when making targets. The + default value of this macro is "1" and its + value cannot exceed the value of the macro + MAXPROCESSLIMIT. Setting the value of + MAXPROCESS on the command line or in the + makefile is equivalent to supplying a cor- + responding value to the -P flag on the + command line. + + + + +Version 4.01 PL0 UW 31 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + PREP This macro defines the number of itera- + tions to be expanded automatically when + processing % rule definitions of the form: + + % : %.suff + + See the sections on PERCENT(%) RULES for + details on how PREP is used. + + SHELL This macro defines the full path to the + executable image to be used as the shell + when processing single line recipes. This + macro must be defined if recipes requiring + the shell for execution are to be used. + It is assigned a default value in the + startup makefile. Under UNIX this value + is /bin/sh. + + SHELLFLAGS This macro gives the set of flags to pass + to the shell when invoking it to execute a + single line recipe. The value of the + macro is the list of flags with a leading + switch indicator. (ie. `-' under UNIX) + + SHELLMETAS Each time dmake executes a single recipe + line (not a group recipe) the line is + searched for any occurrence of a character + defined in the value of SHELLMETAS. If + such a character is found the recipe line + is defined to require a shell to ensure + its correct execution. In such instances + a shell is used to invoke the recipe line. + If no match is found the recipe line is + executed without the use of a shell. + + + There is only one character valued macro defined by dmake: + SWITCHAR contains the switch character used to introduce + options on command lines. For UNIX its value is `-', and + for MSDOS its value may be `/' or `-'. The macro is + internally defined and is not user setable. The MSDOS + version of dmake attempts to first extract SWITCHAR from + an environment variable of the same name. If that fails + it then attempts to use the undocumented getswitchar sys- + tem call, and returns the result of that. Under MSDOS + version 4.0 you must set the value of the environment + macro SWITCHAR to '/' to obtain predictable behavior. + + All boolean macros currently understood by dmake corre- + spond directly to the previously defined attributes. + These macros provide a second way to apply global + attributes, and represent the preferred method of doing + so. They are used by assigning them a value. If the + value is not a NULL string then the boolean condition is + + + +Version 4.01 PL0 UW 32 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + set to on. If the value is a NULL string then the condi- + tion is set to off. There are five conditions defined and + they correspond directly to the attributes of the same + name. Their meanings are defined in the ATTRIBUTES sec- + tion above. The macros are: .EPILOG, .IGNORE, .MKSARGS, + .NOINFER, .PRECIOUS, .PROLOG, .SEQUENTIAL, .SILENT, .SWAP, + and .USESHELL. Assigning any of these a non NULL value + will globally set the corresponding attribute to on. + +RUNTIME MACROS + These macros are defined when dmake is making targets, and + may take on different values for each target. $@ is + defined to be the full target name, $? is the list of all + out of date prerequisites, $& is the list of all prerequi- + sites, $> is the name of the library if the current target + is a library member, and $< is the list of prerequisites + specified in the current rule. If the current target had + a recipe inferred then $< is the name of the inferred pre- + requisite even if the target had a list of prerequisites + supplied using an explicit rule that did not provide a + recipe. In such situations $& gives the full list of pre- + requisites. + + $* is defined as $(@:db) when making targets with explicit + recipes and is defined as the value of % when making tar- + gets whose recipe is the result of an inference. In the + first case $* is the target name with no suffix, and in + the second case, is the value of the matched % pattern + from the associated %-rule. $^ expands to the set of out + of date prerequisites taken from the current value of $<. + In addition to these, $$ expands to $, {{ expands to {, }} + expands to }, and the strings <+ and +> are recognized as + respectively starting and terminating a text diversion + when they appear literally together in the same input + line. + + The difference between $? and $^ can best be illustrated + by an example, consider: + + fred.out : joe amy hello + rules for making fred + + fred.out : my.c your.h his.h her.h # more prerequisites + + Assume joe, amy, and my.c are newer then fred.out. When + dmake executes the recipe for making fred.out the values + of the following macros will be: + + $@ --> fred.out + $* --> fred + $? --> joe amy my.c # note output of $? vs $^ + $^ --> joe amy + $< --> joe amy hello + $& --> joe amy hello my.c your.h his.h her.h + + + +Version 4.01 PL0 UW 33 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + +FUNCTION MACROS + dmake supports a full set of functional macros. One of + these, the $(mktmp ...) macro, is discussed in detail in + the TEXT DIVERSION section and is not covered here. + + + $(and macroterm ...) + expands each macroterm in turn until there + are no more or one of them returns an empty + string. If all expand to non-empty strings + the macro returs the string "t" otherwise it + returns an empty string. + + + $(assign expression) + Causes expression to be parsed as a macro + assignment expression and results in the + specified assignment being made. An error + is issued if the assignment is not syntati- + cally correct. expression may contain white + space. This is in effect a dynamic macro + assignment facility and may appear anywhere + any other macro may appear. The result of + the expanding a dynamic macro assignment + expression is the name of the macro that was + assigned and $(NULL) if the expression is + not a valid macro assignment expression. + Some examples are: + + $(assign foo := fred) + $(assign $(ind_macro_name) +:= $(morejunk)) + + $(echo list) + Echo's the value of list. list is not + expanded. + + $(eq,text_a,text_b true false) + expands text_a and text_b and compares their + results. If equal it returns the result of + the expansion of the true term, otherwise it + returns the expansion of the false term. + + $(!eq,text_a,text_b true false) + Behaves identically to the previous macro + except that the true string is chosen if the + expansions of the two strings are not equal + + $(foreach,var,list data) + Implements iterative macro expansion over + data using var as the iterator taking on + values from list. var and list are expanded + and the result is the concatenation of + expanding data with var being set to each + whitespace separated token from list. For + + + +Version 4.01 PL0 UW 34 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + example: + + list = a b c + all :; echo [$(foreach,i,$(list) [$i])] + + will output + + [[a] [b] [c]] + + The iterator variable is defined as a local + variable to this foreach instance. The fol- + lowing expression illustrates this: + + $(foreach,i,$(foreach,i,$(sort c a b) root/$i) [$i/f.h]) + + when evaluated the result is: + + [root/a/f.h] [root/b/f.h] [root/c/f.h] + + The specification of list must be a valid + macro expression, such as: + + $($(assign list=a b c)) + $(sort d a b c) + $(echo a b c) + + and cannot just be the list itself. That + is, the following foreach expression: + + $(foreach,i,a b c [$i]) + + yields: + + "b c [a]" + + when evaluated. + + $(nil expression) + Always returns the value of $(NULL) regard- + less of what expression is. This function + macro can be used to discard results of + expanding macro expressions. + + $(not macroterm) + expands macroterm and returs the string "t" + if the result of the expansion is the empty + string; otherwise, it returns the empty + string. + + $(null,text true false) + expands the value of text. If it is NULL + then the macro returns the value of the + expansion of true and the expansion of false + otherwise. The terms true, and false must + + + +Version 4.01 PL0 UW 35 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + be strings containing no white-space. + + $(!null,text true false) + Behaves identically to the previous macro + except that the true string is chosen if the + expansion of text is not NULL. + + $(or macroterm ...) + expands each macroterm in turn and returs + the empty string if each term expands to the + empty string; otherwise, it returs the + string "t". + + $(shell command) + Runs command as if it were part of a recipe + and returns, separated by a single space, + all the non-white space terms written to + stdout by the command. For example: + + $(shell ls *.c) + + will return "a.c b.c c.c d.c" if the files + exist in the current directory. The recipe + modification flags [+@%-] are honored if + they appear as the first characters in the + command. For example: + + $(shell +ls *.c) + + will run the command using the current + shell. + + $(shell,expand command) + Is an extension to the $(shell... function + macro that expands the result of running + command. + + $(sort list) + Will take all white-space separated tokens + in list and will return their sorted equiva- + lent list. + + $(strip data) + Will replace all strings of white-space in + data by a single space. + + $(subst,pat,replacement data) + Will search for pat in data and will replace + any occurrence of pat with the replacement + string. The expansion + + $(subst,.o,.c $(OBJECTS)) + + is equivalent to: + + + +Version 4.01 PL0 UW 36 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + $(OBJECTS:s/.o/.c/) + + + $(uniq list) + Will take all white-space separated tokens + in list and will return their sorted equiva- + lent list containing no duplicates. + +CONDITIONAL MACROS + dmake supports conditional macros. These allow the defi- + nition of target specific macro values. You can now say + the following: + + target ?= MacroName MacroOp Value + + This creates a definition for MacroName whose value is + Value only when target is being made. You may use a con- + ditional macro assignment anywhere that a regular macro + assignment may appear, including as the value of a + $(assign ...) macro. + + The new definition is associated with the most recent cell + definition for target. If no prior definition exists then + one is created. The implications of this are immediately + evident in the following example: + + foo := hello + + all : cond;@echo "all done, foo=[$(foo)] bar=[$(bar)]" + + cond ?= bar := global decl + + cond .SETDIR=unix::;@echo $(foo) $(bar) + cond ?= foo := hi + + cond .SETDIR=msdos::;@echo $(foo) $(bar) + cond ?= foo := hihi + + The first conditional assignment creates a binding for + 'bar' that is activated when 'cond' is made. The bindings + following the :: definitions are activated when their + respective recipe rules are used. Thus the first binding + serves to provide a global value for 'bar' while any of + the cond :: rules are processed, and the local bindings + for 'foo' come into effect when their associated :: rule + is processed. + + Conditionals for targets of .UPDATEALL are all activated + before the target group is made. Assignments are pro- + cessed in order. Note that the value of a conditional + macro assignment is NOT AVAILABLE until the associated + target is made, thus the construct + + mytarget ?= bar := hello + + + +Version 4.01 PL0 UW 37 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + mytarget ?= foo := $(bar) + + results in $(foo) expanding to "", if you want the result + to be "hello" you must use: + + mytarget ?= bar := hello + mytarget ?= foo = $(bar) + + Once a target is made any associated conditional macros + are deactivated and their values are no longer available. + Activation occurrs after all inference, and .SETDIR direc- + tives have been processed and after $@ is assigned, but + before prerequisites are processed; thereby making the + values of conditional macro definitions available during + construction of prerequisites. + + If a %-meta rule target has associated conditional macro + assignments, and the rule is chosen by the inference algo- + rithm then the conditional macro assignments are inferred + together with the associated recipe. + +DYNAMIC PREREQUISITES + dmake looks for prerequisites whose names contain macro + expansions during target processing. Any such prerequi- + sites are expanded and the result of the expansion is used + as the prerequisite name. As an example the line: + + fred : $$@.c + + causes the $$@ to be expanded when dmake is making fred, + and it resolves to the target fred. This enables dynamic + prerequisites to be generated. The value of @ may be mod- + ified by any of the valid macro modifiers. So you can say + for example: + + fred.out : $$(@:b).c + + where the $$(@:b) expands to fred. Note the use of $$ + instead of $ to indicate the dynamic expansion, this is + due to the fact that the rule line is expanded when it is + initially parsed, and $$ then returns $ which later trig- + gers the dynamic prerequisite expansion. If you really + want a $ to be part of a prerequisite name you must use + $$$$. Dynamic macro expansion is performed in all user + defined rules, and the special targets .SOURCE*, and + .INCLUDEDIRS. + + If dynamic macro expansion results in multiple white space + separated tokens then these are inserted into the prereq- + uisite list inplace of the dynamic prerequisite. If the + new list contains additional dynamic prerequisites they + will be expanded when they are processed. The level of + recursion in this expansion is controlled by the value of + the variable DYNAMICNESTINGLEVEL and is set to 100 by + + + +Version 4.01 PL0 UW 38 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + default. + +BINDING TARGETS + This operation takes a target name and binds it to an + existing file, if possible. dmake makes a distinction + between the internal target name of a target and its asso- + ciated external file name. Thus it is possible for a tar- + get's internal name and its external file name to differ. + To perform the binding, the following set of rules is + used. Assume that we are trying to bind a target whose + name is of the form X.suff, where .suff is the suffix and + X is the stem portion (ie. that part which contains the + directory and the basename). dmake takes this target name + and performs a series of search operations that try to + find a suitably named file in the external file system. + The search operation is user controlled via the settings + of the various .SOURCE targets. + + 1. If target has the .SYMBOL attribute set then + look for it in the library. If found, + replace the target name with the library + member name and continue with step 2. If + the name is not found then return. + + 2. Extract the suffix portion (that following + the `.') of the target name. If the suffix + is not null, look up the special target + .SOURCE.<suff> (<suff> is the suffix). If + the special target exists then search each + directory given in the .SOURCE.<suff> pre- + requisite list for the target. If the tar- + get's suffix was null (ie. .suff was empty) + then perform the above search but use the + special target .SOURCE.NULL instead. If at + any point a match is found then terminate + the search. If a directory in the prerequi- + site list is the special name `.NULL ' per- + form a search for the full target name with- + out prepending any directory portion (ie. + prepend the NULL directory). + + 3. The search in step 2. failed. Repeat the + same search but this time use the special + target .SOURCE. (a default target of + '.SOURCE : .NULL' is defined by dmake at + startup, and is user redefinable) + + 4. The search in step 3. failed. If the target + has the library member attribute (.LIBMEM- + BER) set then try to find the target in the + library which was passed along with the + .LIBMEMBER attribute (see the MAKING + LIBRARIES section). The bound file name + assigned to a target which is successfully + + + +Version 4.01 PL0 UW 39 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + located in a library is the same name that + would be assigned had the search failed (see + 5.). + + 5. The search failed. Either the target was + not found in any of the search directories + or no applicable .SOURCE special targets + exist. If applicable .SOURCE special tar- + gets exist, but the target was not found, + then dmake assigns the first name searched + as the bound file name. If no applicable + .SOURCE special targets exist, then the full + original target name becomes the bound file + name. + + There is potential here for a lot of search operations. + The trick is to define .SOURCE.x special targets with + short search lists and leave .SOURCE as short as possible. + The search algorithm has the following useful side effect. + When a target having the .LIBMEMBER (library member) + attribute is searched for, it is first searched for as an + ordinary file. When a number of library members require + updating it is desirable to compile all of them first and + to update the library at the end in a single operation. + If one of the members does not compile and dmake stops, + then the user may fix the error and make again. dmake + will not remake any of the targets whose object files have + already been generated as long as none of their prerequi- + site files have been modified as a result of the fix. + + When dmake constructs target pathnames './' substrings are + removed and substrings of the form 'foo/..' are elimi- + nated. This may result in somewhat unexpected values of + the macro expansion $@, but is infact the corect result. + + When defining .SOURCE and .SOURCE.x targets the construct + + + is equivalent to + + + dmake correctly handles the UNIX Make variable VPATH. By + definition VPATH contains a list of ':' separated directo- + ries to search when looking for a target. dmake maps + VPATH to the following special rule: + + + Which takes the value of VPATH and sets .SOURCE to the + same set of directories as specified in VPATH. + +PERCENT(%) RULES AND MAKING INFERENCES + When dmake makes a target, the target's set of prerequi- + sites (if any) must exist and the target must have a + recipe which dmake can use to make it. If the makefile + + + +Version 4.01 PL0 UW 40 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + does not specify an explicit recipe for the target then + dmake uses special rules to try to infer a recipe which it + can use to make the target. Previous versions of Make + perform this task by using rules that are defined by tar- + gets of the form .<suffix>.<suffix> and by using the .SUF- + FIXES list of suffixes. The exact workings of this mecha- + nism were sometimes difficult to understand and often lim- + iting in their usefulness. Instead, dmake supports the + concept of %-meta rules. The syntax and semantics of + these rules differ from standard rule lines as follows: + + <%-target> [<attributes>] <ruleop> [<%-prerequisites>] [;<recipe>] + + where %-target is a target containing exactly a single `%' + sign, attributes is a list (possibly empty) of attributes, + ruleop is the standard set of rule operators, %-prerequi- + sites , if present, is a list of prerequisites containing + zero or more `%' signs, and recipe, if present, is the + first line of the recipe. + + The %-target defines a pattern against which a target + whose recipe is being inferred gets matched. The pattern + match goes as follows: all chars are matched exactly from + left to right up to but not including the % sign in the + pattern, % then matches the longest string from the actual + target name not ending in the suffix given after the % + sign in the pattern. Consider the following examples: + + %.c matches fred.c but not joe.c.Z + dir/%.c matches dir/fred.c but not dd/fred.c + fred/% matches fred/joe.c but not f/joe.c + % matches anything + + In each case the part of the target name that matched the + % sign is retained and is substituted for any % signs in + the prerequisite list of the %-meta rule when the rule is + selected during inference and dmake constructs the new + dependency. As an example the following %-meta rules + describe the following: + + %.c : %.y ; recipe... + + describes how to make any file ending in .c if a corre- + sponding file ending in .y can be found. + + foo%.o : fee%.k ; recipe... + + is used to describe how to make fooxxxx.o from feexxxx.k. + + %.a :; recipe... + + describes how to make a file whose suffix is .a without + inferring any prerequisites. + + + + +Version 4.01 PL0 UW 41 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + %.c : %.y yaccsrc/%.y ; recipe... + + is a short form for the construct: + + %.c : %.y ; recipe... + %.c : yaccsrc/%.y ; recipe... + + ie. It is possible to specify the same recipe for two + %-rules by giving more than one prerequisite in the pre- + requisite list. A more interesting example is: + + % : RCS/%,v ; co $< + + which describes how to take any target and check it out of + the RCS directory if the corresponding file exists in the + RCS directory. The equivalent SCCS rule would be: + + % : s.% ; get $< + + + The previous RCS example defines an infinite rule, because + it says how to make anything from RCS/%,v, and anything + also includes RCS/fred.c,v. To limit the size of the + graph that results from such rules dmake uses the macro + variable PREP (stands for % repetition). By default the + value of this variable is 0, which says that no repeti- + tions of a %-rule are to be generated. If it is set to + something greater than 0, then that many repetitions of + any infinite %-rule are allowed. If in the above example + PREP was set to 1, then dmake would generate the depen- + dency graph: + + % --> RCS/%,v --> RCS/RCS/%,v,v + + Where each link is assigned the same recipe as the first + link. PREP should be used only in special cases, since it + may result in a large increase in the number of possible + prerequisites tested. dmake further assumes that any tar- + get that has no suffix can be made from a prerequisite + that has at least one suffix. + + dmake supports dynamic prerequisite generation for prereq- + uisites of %-meta rules. This is best illustrated by an + example. The RCS rule shown above can infer how to check + out a file from a corresponding RCS file only if the tar- + get is a simple file name with no directory information. + That is, the above rule can infer how to find RCS/fred.c,v + from the target fred.c, but cannot infer how to find + srcdir/RCS/fred.c,v from srcdir/fred.c because the above + rule will cause dmake to look for RCS/srcdir/fred.c,v; + which does not exist (assume that srcdir has its own RCS + directory as is the common case). + + A more versatile formulation of the above RCS check out + + + +Version 4.01 PL0 UW 42 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + rule is the following: + + % : $$(@:d)RCS/$$(@:f),v : co $@ + + This rule uses the dynamic macro $@ to specify the prereq- + uisite to try to infer. During inference of this rule the + macro $@ is set to the value of the target of the %-meta + rule and the appropriate prerequisite is generated by + extracting the directory portion of the target name (if + any), appending the string RCS/ to it, and appending the + target file name with a trailing ,v attached to the previ- + ous result. + + dmake can also infer indirect prerequisites. An inferred + target can have a list of prerequisites added that will + not show up in the value of $< but will show up in the + value of $? and $&. Indirect prerequisites are specified + in an inference rule by quoting the prerequisite with sin- + gle quotes. For example, if you had the explicit depen- + dency: + + fred.o : fred.c ; rule to make fred.o + fred.o : local.h + + then this can be inferred for fred.o from the following + inference rule: + + %.o : %.c 'local.h' ; makes a .o from a .c + + You may infer indirect prerequisites that are a function + of the value of '%' in the current rule. The meta-rule: + + %.o : %.c '$(INC)/%.h' ; rule to make a .o from a + .c + + infers an indirect prerequisite found in the INC directory + whose name is the same as the expansion of $(INC), and the + prerequisite name depends on the base name of the current + target. The set of indirect prerequisites is attached to + the meta rule in which they are specified and are inferred + only if the rule is used to infer a recipe for a target. + They do not play an active role in driving the inference + algorithm. The construct: + + %.o : %.c %.f 'local.h'; recipe + + is equivalent to: + + %.o : %.c 'local.h' : recipe + + while: + + %.o :| %.c %.f 'local.h'; recipe + + + + +Version 4.01 PL0 UW 43 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + is equivalent to: + + %.o : %.c 'local.h' : recipe + %.o : %.f 'local.h' : recipe + + + If any of the attributes .SETDIR, .EPILOG, .PROLOG, + .SILENT, .USESHELL, .SWAP, .PRECIOUS, .LIBRARY, .NOSTATE + and .IGNORE are given for a %-rule then when that rule is + bound to a target as the result of an inference, the tar- + get's set of attributes is augmented by the attributes + from the above set that are specified in the bound %-rule. + Other attributes specified for %-meta rules are not inher- + ited by the target. The .SETDIR attribute is treated in a + special way. If the target already had a .SETDIR + attribute set then dmake changes to that directory prior + to performing the inference. During inference any .SETDIR + attributes for the inferred prerequisite are honored. The + directories must exist for a %-meta rule to be selected as + a possible inference path. If the directories do not + exist no error message is issued, instead the correspond- + ing path in the inference graph is rejected. + + dmake also supports the old format special target .<suf- + fix>.<suffix> by identifying any rules of this form and + mapping them to the appropriate %-rule. So for example if + an old makefile contains the construct: + + .c.o :; cc -c $< -o $@ + + dmake maps this into the following %-rule: + + %.o : %.c; cc -c $< -o $@ + + Furthermore, dmake understands several SYSV AUGMAKE spe- + cial targets and maps them into corresponding %-meta + rules. These transformation must be enabled by providing + the -A flag on the command line or by setting the value of + AUGMAKE to non-NULL. The construct + + .suff :; recipe + + gets mapped into: + + % : %.suff; recipe + + and the construct + + .c~.o :; recipe + + gets mapped into: + + %.o : s.%.c ; recipe + + + + +Version 4.01 PL0 UW 44 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + In general, a special target of the form .<str>~ is + replaced by the %-rule construct s.%.<str>, thereby pro- + viding support for the syntax used by SYSV AUGMAKE for + providing SCCS support. When enabled, these mappings + allow processing of existing SYSV makefiles without modi- + fications. + + dmake bases all of its inferences on the inference graph + constructed from the %-rules defined in the makefile. It + knows exactly which targets can be made from which prereq- + uisites by making queries on the inference graph. For + this reason .SUFFIXES is not needed and is completely + ignored. + + For a %-meta rule to be inferred as the rule whose recipe + will be used to make a target, the target's name must + match the %-target pattern, and any inferred %-prerequi- + site must already exist or have an explicit recipe so that + the prerequisite can be made. Without transitive closure + on the inference graph the above rule describes precisely + when an inference match terminates the search. If transi- + tive closure is enabled (the usual case), and a prerequi- + site does not exist or cannot be made, then dmake invokes + the inference algorithm recursively on the prerequisite to + see if there is some way the prerequisite can be manufac- + tured. For, if the prerequisite can be made then the cur- + rent target can also be made using the current %-meta + rule. This means that there is no longer a need to give a + rule for making a .o from a .y if you have already given a + rule for making a .o from a .c and a .c from a .y. In + such cases dmake can infer how to make the .o from the .y + via the intermediary .c and will remove the .c when the .o + is made. Transitive closure can be disabled by giving the + -T switch on the command line. + + A word of caution. dmake bases its transitive closure on + the %-meta rule targets. When it performs transitive clo- + sure it infers how to make a target from a prerequisite by + performing a pattern match as if the potential prerequi- + site were a new target. The set of rules: + + %.o : %.c :; rule for making .o from .c + %.c : %.y :; rule for making .c from .y + % : RCS/%,v :; check out of RCS file + + will, by performing transitive closure, allow dmake to + infer how to make a .o from a .y using a .c as an interme- + diate temporary file. Additionally it will be able to + infer how to make a .y from an RCS file, as long as that + RCS file is in the RCS directory and has a name which ends + in .y,v. The transitivity computation is performed dynam- + ically for each target that does not have a recipe. This + has potential to be costly if the %-meta rules are not + carefully specified. The .NOINFER attribute is used to + + + +Version 4.01 PL0 UW 45 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + mark a %-meta node as being a final target during infer- + ence. Any node with this attribute set will not be used + for subsequent inferences. As an example the node RCS/%,v + is marked as a final node since we know that if the RCS + file does not exist there likely is no other way to make + it. Thus the standard startup makefile contains an entry + similar to: + .NOINFER : RCS/%,v + Thereby indicating that the RCS file is the end of the + inference chain. Whenever the inference algorithm deter- + mines that a target can be made from more than one prereq- + uisite and the inference chains for the two methods are + the same length the algorithm reports an ambiguity and + prints the ambiguous inference chains. + + dmake tries to remove intermediate files resulting from + transitive closure if the file is not marked as being PRE- + CIOUS, or the -u flag was not given on the command line, + and if the inferred intermediate did not previously exist. + Intermediate targets that existed prior to being made are + never removed. This is in keeping with the philosophy + that dmake should never remove things from the file system + that it did not add. If the special target .REMOVE is + defined and has a recipe then dmake constructs a list of + the intermediate files to be removed and makes them pre- + requisites of .REMOVE. It then makes .REMOVE thereby + removing the prerequisites if the recipe of .REMOVE says + to. Typically .REMOVE is defined in the startup file as: + + .REMOVE :; $(RM) $< + +MAKING TARGETS + In order to update a target dmake must execute a recipe. + When a recipe needs to be executed it is first expanded so + that any macros in the recipe text are expanded, and it is + then either executed directly or passed to a shell. dmake + supports two types of recipes. The regular recipes and + group recipes. + + When a regular recipe is invoked dmake executes each line + of the recipe separately using a new copy of a shell if a + shell is required. Thus effects of commands do not gener- + ally persist across recipe lines (e.g. cd requests in a + recipe line do not carry over to the next recipe line). + This is true even in environments such as MSDOS, where + dmake internally sets the current working director to + match the directory it was in before the command was exe- + cuted. + + The decision on whether a shell is required to execute a + command is based on the value of the macro SHELLMETAS or + on the specification of '+' or .USESHELL for the current + recipe or target respectively. If any character in the + value of SHELLMETAS is found in the expanded recipe text- + + + +Version 4.01 PL0 UW 46 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + line or the use of a shell is requested explicitly via '+' + or .USESHELL then the command is executed using a shell, + otherwise the command is executed directly. The shell + that is used for execution is given by the value of the + macro SHELL. The flags that are passed to the shell are + given by the value of SHELLFLAGS. Thus dmake constructs + the command line: + + $(SHELL) $(SHELLFLAGS) $(expanded_recipe_command) + + Normally dmake writes the command line that it is about to + invoke to standard output. If the .SILENT attribute is + set for the target or for the recipe line (via @), then + the recipe line is not echoed. + + Group recipe processing is similar to that of regular + recipes, except that a shell is always invoked. The shell + that is invoked is given by the value of the macro GROUP- + SHELL, and its flags are taken from the value of the macro + GROUPFLAGS. If a target has the .PROLOG attribute set + then dmake prepends to the shell script the recipe associ- + ated with the special target .GROUPPROLOG, and if the + attribute .EPILOG is set as well, then the recipe associ- + ated with the special target .GROUPEPILOG is appended to + the script file. This facility can be used to always + prepend a common header and common trailer to group + recipes. Group recipes are echoed to standard output just + like standard recipes, but are enclosed by lines beginning + with [ and ]. + + The recipe flags [+,-,%,@] are recognized at the start of + a recipe line even if they appear in a macro. For exam- + ple: + + SH = + + all: + $(SH)echo hi + + is completely equivalent to writing + + SH = + + all: + +echo hi + + + The last step performed by dmake prior to running a recipe + is to set the macro CMNDNAME to the name of the command to + execute (determined by finding the first white-space end- + ing token in the command line). It then sets the macro + CMNDARGS to be the remainder of the line. dmake then + expands the macro COMMAND which by default is set to + + COMMAND = $(CMNDNAME) $(CMNDARGS) + + + + +Version 4.01 PL0 UW 47 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + The result of this final expansion is the command that + will be executed. The reason for this expansion is to + allow for a different interface to the argument passing + facilities (esp. under DOS) than that provided by dmake. + You can for example define COMMAND to be + + COMMAND = $(CMNDNAME) @$(mktmp $(CMNDARGS)) + + which dumps the arguments into a temporary file and runs + the command + + $(CMNDNAME) @/tmp/ASAD23043 + + which has a much shorter argument list. It is now up to + the command to use the supplied argument as the source for + all other arguments. As an optimization, if COMMAND is + not defined dmake does not perform the above expansion. + On systems, such as UNIX, that handle long command lines + this provides a slight saving in processing the makefiles. + +MAKING LIBRARIES + Libraries are easy to maintain using dmake. A library is + a file containing a collection of object files. Thus to + make a library you simply specify it as a target with the + .LIBRARY attribute set and specify its list of prerequi- + sites. The prerequisites should be the object members + that are to go into the library. When dmake makes the + library target it uses the .LIBRARY attribute to pass to + the prerequisites the .LIBMEMBER attribute and the name of + the library. This enables the file binding mechanism to + look for the member in the library if an appropriate + object file cannot be found. dmake now supports Elf + libraries on systems that support Elf and hence supports, + on those systems, long member file names. A small example + best illustrates this. + + mylib.a .LIBRARY : mem1.o mem2.o mem3.o + rules for making library... + # remember to remove .o's when lib is made + + # equivalent to: '%.o : %.c ; ...' + .c.o :; rules for making .o from .c say + + dmake will use the .c.o rule for making the library mem- + bers if appropriate .c files can be found using the search + rules. NOTE: this is not specific in any way to C pro- + grams, they are simply used as an example. + + dmake tries to handle the old library construct format in + a sensible way. The construct lib(member.o) is separated + and the lib portion is declared as a library target. The + new target is defined with the .LIBRARY attribute set and + the member.o portion of the construct is declared as a + prerequisite of the lib target. If the construct + + + +Version 4.01 PL0 UW 48 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + lib(member.o) appears as a prerequisite of a target in the + makefile, that target has the new name of the lib assigned + as its prerequisite. Thus the following example: + + a.out : ml.a(a.o) ml.a(b.o); $(CC) -o $@ $< + + .c.o :; $(CC) -c $(CFLAGS) -o $@ $< + %.a: + ar rv $@ $? + ranlib $@ + rm -rf $? + + constructs the following dependency graph. + + a.out : ml.a; $(CC) -o $@ $< + ml.a .LIBRARY : a.o b.o + + %.o : %.c ; $(CC) -c $(CFLAGS) -o $@ $< + %.a : + ar rv $@ $? + ranlib $@ + rm -rf $? + + and making a.out then works as expected. + + The same thing happens for any target of the form + lib((entry)). These targets have an additional feature in + that the entry target has the .SYMBOL attribute set auto- + matically. + + NOTE: If the notion of entry points is supported by the + archive and by dmake (currently not the case) then dmake + will search the archive for the entry point and return not + only the modification time of the member which defines the + entry but also the name of the member file. This name + will then replace entry and will be used for making the + member file. Once bound to an archive member the .SYMBOL + attribute is removed from the target. This feature is + presently disabled as there is little standardization + among archive formats, and we have yet to find a makefile + utilizing this feature (possibly due to the fact that it + is unimplemented in most versions of UNIX Make). + + Finally, when dmake looks for a library member it must + first locate the library file. It does so by first look- + ing for the library relative to the current directory and + if it is not found it then looks relative to the current + value of $(TMD). This allows commonly used libraries to + be kept near the root of a source tree and to be easily + found by dmake. + +KEEP STATE + dmake supports the keeping of state information for tar- + gets that it makes whenever the macro .KEEP_STATE is + + + +Version 4.01 PL0 UW 49 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + assigned a value. The value of the macro should be the + name of a state file that will contain the state informa- + tion. If state keeping is enabled then each target that + does not poses the .NOSTATE attribute will have a record + written into the state file indicating the target's name, + the current directory, the command used to update the tar- + get, and which, if any, :: rule is being used. When you + make this target again if any of this information does not + match the previous settings and the target is not out + dated it will still be re-made. The assumption is that + one of the conditions above has changed and that we wish + to remake the target. For example, state keeping is used + in the maintenance of dmake to test compile different ver- + sions of the source using different compilers. Changing + the compiler causes the compilation flags to be modified + and hence all sources to be recompiled. + + The state file is an ascii file and is portable, however + it is not in human readable form as the entries represent + hash keys of the above information. + + The Sun Microsystem's Make construct + + .KEEP_STATE : + + is recognized and is mapped to .KEEP_STATE:=_state.mk. + The dmake version of state keeping does not include scan- + ning C source files for dependencies like Sun Make. This + is specific to C programs and it was felt that it does not + belong in make. dmake instead provides the tool, cdepend, + to scan C source files and to produce depedency informa- + tion. Users are free to modify cdepend to produce other + dependency files. (NOTE: cdepend does not come with the + distribution at this time, but will be available in a + patch in the near future) + +MULTI PROCESSING + If the architecture supports it then dmake is capable of + making a target's prerequisites in parallel. dmake will + make as much in parallel as it can and use a number of + child processes up to the maximum specified by MAXPROCESS + or by the value supplied to the -P command line flag. A + parallel make is enabled by setting the value of MAXPRO- + CESS (either directly or via -P option) to a value which + is > 1. dmake guarantees that all dependencies as speci- + fied in the makefile are honored. A target will not be + made until all of its prerequisites have been made. Note + that when you specify -P 4 then four child processes are + run concurrently but dmake actually displays the fifth + command it will run immediately upon a child process + becomming free. This is an artifact of the method used to + traverse the dependency graph and cannot be removed. If a + parallel make is being performed then the following + restrictions on parallelism are enforced. + + + +Version 4.01 PL0 UW 50 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + 1. Individual recipe lines in a non-group + recipe are performed sequentially in the + order in which they are specified within the + makefile and in parallel with the recipes of + other targets. + + 2. If a target contains multiple recipe defini- + tions (cf. :: rules) then these are per- + formed sequentially in the order in which + the :: rules are specified within the make- + file and in parallel with the recipes of + other targets. + + 3. If a target rule contains the `!' modifier, + then the recipe is performed sequentially + for the list of outdated prerequisites and + in parallel with the recipes of other tar- + gets. + + 4. If a target has the .SEQUENTIAL attribute + set then all of its prerequisites are made + sequentially relative to one another (as if + MAXPROCESS=1), but in parallel with other + targets in the makefile. + + Note: If you specify a parallel make then the order of + target update and the order in which the associated + recipes are invoked will not correspond to that displayed + by the -n flag. + +CONDITIONALS + dmake supports a makefile construct called a conditional. + It allows the user to conditionally select portions of + makefile text for input processing and to discard other + portions. This becomes useful for writing makefiles that + are intended to function for more than one target host and + environment. The conditional expression is specified as + follows: + + .IF expression + ... if text ... + .ELIF expression + ... if text ... + .ELSE + ... else text ... + .END + + The .ELSE and .ELIF portions are optional, and the condi- + tionals may be nested (ie. the text may contain another + conditional). .IF, .ELSE, and .END may appear anywhere in + the makefile, but a single conditional expression may not + span multiple makefiles. + + expression can be one of the following three forms: + + + +Version 4.01 PL0 UW 51 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + <text> | <text> == <text> | <text> != <text> + + where text is either text or a macro expression. In any + case, before the comparison is made, the expression is + expanded. The text portions are then selected and com- + pared. White space at the start and end of the text por- + tion is discarded before the comparison. This means that + a macro that evaluates to nothing but white space is con- + sidered a NULL value for the purpose of the comparison. + In the first case the expression evaluates TRUE if the + text is not NULL otherwise it evaluates FALSE. The + remaining two cases both evaluate the expression on the + basis of a string comparison. If a macro expression needs + to be equated to a NULL string then compare it to the + value of the macro $(NULL). You can use the $(shell ...) + macro to construct more complex test expressions. + +EXAMPLES + # A simple example showing how to use make + # + prgm : a.o b.o + cc a.o b.o -o prgm + a.o : a.c g.h + cc a.c -o $@ + b.o : b.c g.h + cc b.c -o $@ + + In the previous example prgm is remade only if a.o and/or + b.o is out of date with respect to prgm. These dependen- + cies can be stated more concisely by using the inference + rules defined in the standard startup file. The default + rule for making .o's from .c's looks something like this: + + %.o : %.c; cc -c $(CFLAGS) -o $@ $< + + Since there exists a rule (defined in the startup file) + for making .o's from .c's dmake will use that rule for + manufacturing a .o from a .c and we can specify our depen- + dencies more concisely. + + prgm : a.o b.o + cc -o prgm $< + a.o b.o : g.h + + A more general way to say the above using the new macro + expansions would be: + + SRC = a b + OBJ = {$(SRC)}.o + + prgm : $(OBJ) + cc -o $@ $< + + $(OBJ) : g.h + + + +Version 4.01 PL0 UW 52 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + If we want to keep the objects in a separate directory, + called objdir, then we would write something like this. + + SRC = a b + OBJ = {$(SRC)}.o + + prgm : $(OBJ) + cc $< -o $@ + + $(OBJ) : g.h + %.o : %.c + $(CC) -c $(CFLAGS) -o $(@:f) $< + mv $(@:f) objdir + + .SOURCE.o : objdir # tell dmake to look here for .o's + + An example of building library members would go something + like this: (NOTE: The same rules as above will be used to + produce .o's from .c's) + + SRC= a b + LIB= lib + LIBm= { $(SRC) }.o + + prgm: $(LIB) + cc -o $@ $(LIB) + + $(LIB) .LIBRARY : $(LIBm) + ar rv $@ $< + rm $< + + Finally, suppose that each of the source files in the pre- + vious example had the `:' character in their target name. + Then we would write the above example as: + + SRC= f:a f:b + LIB= lib + LIBm= "{ $(SRC) }.o" # put quotes around each token + + prgm: $(LIB) + cc -o $@ $(LIB) + + $(LIB) .LIBRARY : $(LIBm) + ar rv $@ $< + rm $< + +COMPATIBILITY + There are two notable differences between dmake and the + standard version of BSD UNIX 4.2/4.3 Make. + + 1. BSD UNIX 4.2/4.3 Make supports wild card file- + name expansion for prerequisite names. Thus if + a directory contains a.h, b.h and c.h, then a + line like + + + +Version 4.01 PL0 UW 53 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + target: *.h + + will cause UNIX make to expand the *.h into "a.h + b.h c.h". dmake does not support this type of + filename expansion. + + 2. Unlike UNIX make, touching a library member + causes dmake to search the library for the mem- + ber name and to update the library time stamp. + This is only implemented in the UNIX version. + MSDOS and other versions may not have librarians + that keep file time stamps, as a result dmake + touches the library file itself, and prints a + warning. + + dmake is not compatible with GNU Make. In particular it + does not understand GNU Make's macro expansions that query + the file system. + + dmake is fully compatible with SYSV AUGMAKE, and supports + the following AUGMAKE features: + + 1. GNU Make style include, and if/else/endif direc- + tives are allowed in non-group recipes. Thus, + the word include appearing at the start of a + line that is not part of a gruop recipe will be + mapped to the ".INCLUDE" directive that damke + uses. Similarly, the words + ifeq,ifneq,elif,else, and endif are mapped to + their corresponding dmake equivalents. + + 2. The macro modifier expression $(macro:str=sub) + is understood and is equivalent to the expres- + sion $(macro:s/str/sub), with the restriction + that str must match the following regular + expression: + + str[ |\t][ |\t]* + + (ie. str only matches at the end of a token + where str is a suffix and is terminated by a + space, a tab, or end of line) Normally sub is + expanded before the substitution is made, if you + specify -A on the command line then sub is not + expanded. + + 3. The macro % is defined to be $@ (ie. $% expands + to the same value as $@). + + 4. The AUGMAKE notion of libraries is handled cor- + rectly. + + 5. When defining special targets for the inference + rules and the AUGMAKE special target handling is + + + +Version 4.01 PL0 UW 54 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + + enabled then the special target .X is equivalent + to the %-rule "% : %.X". + + 6. Directories are always made if you specify -A. + This is consistent with other UNIX versions of + Make. + + 7. Makefiles that utilize virtual targets to force + making of other targets work as expected if AUG- + MAKE special target handling is enabled. For + example: + + FRC: + myprog.o : myprog.c $(FRC) ; ... + + Works as expected if you issue the command + + 'dmake -A FRC=FRC' + + but fails with a 'don't know how to make FRC' + error message if you do not specify AUGMAKE spe- + cial target handling via the -A flag (or by set- + ting AUGMAKE:=yes internally). + + 8. The MSDOS version of dmake now supports a single + buitin runtime command noop, which returns suc- + cess if requested and does nothing. + +LIMITS + In some environments the length of an argument string is + restricted. (e.g. MSDOS command line arguments cannot be + longer than 128 bytes if you are using the standard com- + mand.com command interpreter as your shell, dmake text + diversions may help in these situations.) + +PORTABILITY + To write makefiles that can be moved from one environment + to another requires some forethought. In particular you + must define as macros all those things that may be differ- + ent in the new environment. dmake has two facilities that + help to support writing portable makefiles, recursive + macros and conditional expressions. The recursive macros, + allow one to define environment configurations that allow + different environments for similar types of operating sys- + tems. For example the same make script can be used for + SYSV and BSD but with different macro definitions. + + To write a makefile that is portable between UNIX and + MSDOS requires both features since in almost all cases you + will need to define new recipes for making targets. The + recipes will probably be quite different since the capa- + bilities of the tools on each machine are different. Dif- + ferent macros will be needed to help handle the smaller + differences in the two environments. + + + +Version 4.01 PL0 UW 55 + + + + + +DMAKE(p) Unsupported Free Software DMAKE(p) + + +FILES + Makefile, makefile, startup.mk (use dmake -V to tell you + where the startup file is) + +SEE ALSO + sh(1), csh(1), touch(1), f77(1), pc(1), cc(1) + S.I. Feldman Make - A Program for Maintaining Computer + Programs + +AUTHOR + Dennis Vadura, dvadura@wticorp.com + Many thanks to Carl Seger for his helpful suggestions, and + to Trevor John Thompson for his many excellent ideas and + informative bug reports. Many thanks also go to those on + the NET that have helped in making dmake one of the best + Make tools available. + +BUGS + Some system commands return non-zero status inappropri- + ately. Use -i (`-' within the makefile) to overcome the + difficulty. + + Some systems do not have easily accessible time stamps for + library members (MSDOS, AMIGA, etc) for these dmake uses + the time stamp of the library instead and prints a warning + the first time it does so. This is almost always ok, + except when multiple makefiles update a single library + file. In these instances it is possible to miss an update + if one is not careful. + + This man page is way too long. + +WARNINGS + Rules supported by make(1) may not work if transitive clo- + sure is turned off (-T, .NOINFER). + + PWD from csh/ksh will cause problems if a cd operation is + performed and -e or -E option is used. + + Using internal macros such as COMMAND, may wreak havoc if + you don't understand their functionality. + + + + + + + + + + + + + + + + +Version 4.01 PL0 UW 56 + + diff --git a/dmake/man/dmake.tf b/dmake/man/dmake.tf new file mode 100644 index 000000000000..582230c10cc1 --- /dev/null +++ b/dmake/man/dmake.tf @@ -0,0 +1,3152 @@ +.\" Copyright (c) 1990,...,1995 Dennis Vadura, All rights reserved. +.\" +.\" You must use groff to format this man page!!! +.\" +.ds TB "0.2i +0.2i +0.2i +0.2i +0.2i +0.2i +0.2i +0.2i +0.2i +0.2i +0.2i +0.2i +0.2i +0.2i +0.2i +0.2i +0.2i +0.2i +0.2i +0.2i +0.2i +0.2i +0.2i +0.2i +0.2i +0.2i +0.5i +0.5i +2.0i +.de Ip +.sp \\n[PD]u +.fi +.nr an-prevailing-indent (n;\w@\\$1 @u) +.it 1 an-trap +.if !\\n[an-div?] .di an-div +.in 0 +.nr an-div? 1 +.nf +\&\\$1 \\$2 +.. +.de Is +.nr an-prevailing-indent \w@\\$1@u +.. +.de Ii +.fi +.it 1 an-trap +.if !\\n[an-div?] .di an-div +.in 0 +.nr an-div? 1 +.nf +\&\\$1 +.. +.TH DMAKE p "UW" "Version 4.01 PL0" "Unsupported Free Software" +.SH NAME +\fBdmake\fR \- maintain program groups, or interdependent files +.SH SYNOPSIS +.B dmake +[\-P#] [\-{f|C|K} file] [\-{w|W} target ...] +[macro[[!][*][+][:]]=\fIvalue\fP ...] +[\-v{cdfimtw}] [\-ABcdeEghiknpqrsStTuVxX] [target ...] +.SH DESCRIPTION +.PP +.B dmake +is a re-implementation of the UNIX Make utility with significant enhancements. +.B dmake +executes commands found in an external file called a +.I makefile +to update one or more target names. +Each target may depend on zero or more prerequisite targets. +If any of the target's prerequisites is newer than the target or if the target +itself does not exist, then +.B dmake +will attempt to make the target. +.PP +If no +.B \-f +command line option is present then +.B dmake +searches for an existing +.I makefile +from the list of prerequisites specified for the special target \fI.MAKEFILES\fR +(see the STARTUP section for more details). +If "\-" is the name of the file specified to the +.B \-f +flag then \fBdmake\fR uses standard input as the source of the makefile text. +.PP +Any macro definitions (arguments with embedded "=" +signs) that appear on the command line are processed first +and supercede definitions for macros of the same name found +within the makefile. In general it is impossible for definitions found +inside the makefile to redefine a macro defined on the command line, see the +MACROS section for exceptions. +.PP +If no +.I target +names are specified on the command line, then \fBdmake\fR uses the first +non-special target found in the makefile as the default target. +See the +.B "SPECIAL TARGETS" +section for the list of special targets and their function. +Makefiles written for most previous +versions of +.I Make +will be handled correctly by +.B dmake. +Known differences between \fBdmake\fR and other versions of make +are discussed in the +.B COMPATIBILITY +section found at the end of this document. +.B dmake +returns 0 if no errors were detected and a non-zero result if an error +occurred. +.SH OPTIONS +.IP "\fB\-A\fR" +Enable AUGMAKE special inference rule transformations +(see the "PERCENT(%) RULES" section), these are set to off by default. +.IP "\fB\-B\fR" +Enable the use of spaces instead of <tabs> to begin recipe lines. +This flag equivalent to the .NOTABS special macro and is further described +below. +.IP "\fB\-c\fR" +Use non-standard comment stripping. If you specify \fB\-c\fP then +.B dmake +will treat any \fB#\fP character as a start of comment character wherever it +may appear unless it is escaped by a \e. +.IP "\fB\-C [+]file\fR" +This option writes to \fIfile\fP a copy of standard output and +standard error from any child processes and from the +.B dmake +process itself. If you specify a \fB+\fP prior to the file name then +the text is appended to the previous contents of \fIfile\fP. +This option is active in the MSDOS implementation only and is ignored +by non-MSDOS versions of +.B dmake. +.IP "\fB\-d\fR" +Disable the use of the directory cache. Normally \fBdmake\fP caches directories +as it checks file timestamps. Giving this flag is equivalent to the +\&.DIRCACHE attribute or macro being set to \fIno\fP. +.IP "\fB\-E\fR" +Read the environment and define all strings of the +form '\fBENV\-VAR\fP=\fIevalue\fP' +defined within as macros whose name is \fBENV\-VAR\fP, +and whose value is '\fIevalue\fP'. +The environment is processed prior to processing the user +specified makefile thereby allowing definitions in the makefile to override +definitions in the environment. +.IP "\fB\-e\fR" +Same as \-E, except that the environment is processed after the +user specified makefile has been processed +(thus definitions in the environment override definitions in the makefile). +The \-e and \-E options are mutually exclusive. +If both are given the latter takes effect. +.IP "\fB\-f file\fR" +Use \fBfile\fR as the source for the makefile text. +Only one \fB\-f\fR option is allowed. +.IP "\fB\-g\fR" +Globally disable group recipe parsing, equivalent to the .IGNOREGROUP +attribute or macro being set to \fIyes\fP at the start of the makefile. +.IP "\fB\-h\fR" +Print the command summary for \fBdmake\fR. +.IP "\fB\-i\fR" +Tells \fBdmake\fR to ignore errors, and continue making other targets. +This is equivalent to the .IGNORE attribute or macro. +.IP "\fB\-K file\fR" +Turns on \fB.KEEP_STATE\fP state tracking and tells \fBdmake\fP to use +\fIfile\fP as the state file. +.IP "\fB\-k\fR" +Causes \fBdmake\fR to ignore errors caused by command execution and to make +all targets not depending on targets that could not be made. +Ordinarily \fBdmake\fR stops after a command returns a non-zero status, +specifying \fB\-k\fR causes \fBdmake\fR to ignore the error +and continue to make as much as possible. +.IP "\fB\-n\fR" +Causes \fBdmake\fR to print out what it would have executed, +but does not actually execute the commands. A special check is made for +the string "$(MAKE)" inside a recipe line, if it is found, +the line is expanded and invoked, thereby enabling recursive makes to give a +full description of all that they will do. +This check is disabled inside group recipes. +.IP "\fB\-p\fR" +Print out a version of the digested makefile in human readable form. +(useful for debugging, but cannot be re-read by \fBdmake\fP) +.IP "\fB\-P#\fR" +On systems that support multi-processing cause \fBdmake\fP to use \fI#\fP +concurrent child processes to make targets. +See the "MULTI PROCESSING" section for more information. +.IP "\fB\-q\fR" +Check and see if the target is up to date. Exits with code 0 if up to date, +1 otherwise. +.IP "\fB\-r\fR" +Tells \fBdmake\fR not to read the initial startup makefile, see STARTUP +section for more details. +.IP "\fB\-s\fR" +Tells \fBdmake\fR to do all its work silently and not echo the commands it is +executing to stdout (also suppresses warnings). +This is equivalent to the .SILENT attribute or macro. +.IP "\fB\-S\fR" +Force sequential execution of recipes on architectures which support +concurrent makes. For backward compatibility with old makefiles that have +nasty side-effect prerequisite dependencies. +.IP "\fB\-t\fR" +Causes \fBdmake\fR to touch the targets and bring them up to date +without executing any commands. +Note that targets will not be created if they do not already exist. +.IP "\fB\-T\fR" +Tells \fBdmake\fP to not perform transitive closure on the inference graph. +.IP "\fB\-u\fR" +Force an unconditional update. (ie. do everything that would +be done if everything that a target depended on was out of date) +.IP "\fB\-v[dfimtw]\fR" +Verbose flag, when making targets print to stdout what we are going to make +and what we think its time stamp is. The optional flags \fB[dfimt]\fP can be +used to restrict the information that is displayed. In the absence of any +optional flags all are assumed to be given (ie. \fB\-v\fP is equivalent to +\fB\-vdfimt\fP). The meanings of the optional flags are: +.RS +.IP "\fBc\fP" +Notify of directory cache operations only. +.IP "\fBd\fP" +Notify of change directory operations only. +.IP "\fBf\fP" +Notify of file I/O operations only. +.IP "\fBi\fP" +Notify of inference algorithm operation only. +.IP "\fBm\fP" +Notify of target update operations only. +.IP "\fBt\fP" +Keep any temporary files created; normally they are automatically deleted. +.IP "\fBw\fP" +Notify of non-essential warnings (these are historical). +.RE +.IP "\fB\-V\fR" +Print the version of \fBdmake\fR, and values of builtin macros. +.IP "\fB\-W target\fR" +Run \fBdmake\fP pretending that \fItarget\fP is out of date. +.IP "\fB\-w target\fR" +\fIWhat if?\fP Show what would be made if \fItarget\fP were out of date. +.IP "\fB\-x\fR" +Upon processing the user makefile export all non-internally defined macros +to the user's environment. This option together with the \-e option +allows SYSV AUGMAKE recursive makes to function as expected. +.IP "\fB\-X\fR" +Inhibit the execution of \fB#!\fP lines found at the beginning of a makefile. +The use of this flag prevents non-termination of recursive make invocations. +.SH INDEX +Here is a list of the sections that follow and a short description of each. +Perhaps you won't have to read the entire man page to find +what you need. +.IP \fBSTARTUP\fP 1.9i +Describes \fBdmake\fP initialization. +.IP \fBSYNTAX\fP 1.9i +Describes the syntax of makefile expressions. +.IP \fBATTRIBUTES\fP 1.9i +Describes the notion of attributes and how they are used when +making targets. +.IP \fBMACROS\fP 1.9i +Defining and expanding macros. +.IP "\fBRULES AND TARGETS" 1.9i +How to define targets and their prerequisites. +.IP \fBRECIPES\fP 1.9i +How to tell \fBdmake\fP how to make a target. +.IP "\fBTEXT DIVERSIONS\fP" 1.9i +How to use text diversions in recipes and macro expansions. +.IP "\fBSPECIAL TARGETS\fP" 1.9i +Some targets are special. +.IP "\fBSPECIAL MACROS\fP" 1.9i +Macros used by \fBdmake\fP to alter the processing of the makefile, +and those defined by \fBdmake\fP for the user. +.IP "\fBCONTROL MACROS\fP" 1.9i +Itemized list of special control macros. +.IP "\fBRUNTIME MACROS\fP" 1.9i +Discussion of special run-time macros such as $@ and $<. +.IP "\fBFUNCTION MACROS\fP" 1.9i +GNU style function macros, only $(mktmp ...) for now. +.IP "\fBCONDITIONAL MACROS\fP" 1.9i +Target specific conditional macros. +.IP "\fBDYNAMIC PREREQUISITES\fP" 1.9i +Processing of prerequisites which contain macro expansions in their name. +.IP "\fBBINDING TARGETS\fP" 1.9i +The rules that \fBdmake\fP uses to bind +a target to an existing file in the file system. +.IP "\fBPERCENT(%) RULES\fP" 1.9i +Specification of recipes to be used by the inference algorithm. +.IP "\fBMAKING INFERENCES\fP" 1.9i +The rules that \fBdmake\fP uses when inferring how to make a target which +has no explicit recipe. This and the previous section are really a single +section in the text. +.IP "\fBMAKING TARGETS\fP" 1.9i +How \fBdmake\fP makes targets other than libraries. +.IP "\fBMAKING LIBRARIES\fP" 1.9i +How \fBdmake\fP makes libraries. +.IP "\fBKEEP STATE\fP" 1.9i +A discussion of how .KEEP_STATE works. +.IP "\fBMULTI PROCESSING\fP" 1.9i +Discussion of \fBdmake's\fP parallel make facilities for architectures that +support them. +.IP "\fBCONDITIONALS\fP" 1.9i +Conditional expressions which control the processing of the makefile. +.IP "\fBEXAMPLES\fP" 1.9i +Some hopefully useful examples. +.IP "\fBCOMPATIBILITY\fP" 1.9i +How \fBdmake\fP compares with previous versions of make. +.IP "\fBLIMITS\fP" 1.9i +Limitations of \fBdmake\fP. +.IP \fBPORTABILITY\fP 1.9i +Comments on writing portable makefiles. +.IP \fBFILES\fP 1.9i +Files used by \fBdmake\fP. +.IP "\fBSEE ALSO\fP" 1.9i +Other related programs, and man pages. +.IP "\fBAUTHOR\fP" 1.9i +The guy responsible for this thing. +.IP \fBBUGS\fP 1.9i +Hope not. +.SH STARTUP +When +.B dmake +begins execution it first processes the command line and then processes +an initial startup-makefile. +This is followed by an attempt to locate and process a user supplied makefile. +The startup file defines the default values of all required control macros +and the set of default rules for making targets and inferences. +When searching for the startup makefile, +.B dmake +searches the following locations, in the order specified, +until a startup file is located: +.LP +.RS +.IP 1. +The location given as the value of the macro +MAKESTARTUP defined on the command line. +.IP 2. +The location given as the value of the environment variable MAKESTARTUP +defined in the current environment. +.IP 3. +The location given as the value of the macro +MAKESTARTUP defined internally within \fBdmake\fP. +.RE +.LP +The above search is disabled by specifying the \-r option on the command line. +An error is issued if a startup makefile cannot be found and the \-r +option was not specified. +A user may substitute a custom startup file by defining +the MAKESTARTUP environment variable or by redefining the +MAKESTARTUP macro on the command line. +To determine where +.B dmake +looks for the default startup file, check your environment or issue the command +\fI"dmake \-V"\fP. +.PP +A similar search is performed to locate a default user makefile when no +\fB\-f\fP command line option is specified. +By default, the prerequisite list of the special target .MAKEFILES +specifies the names of possible makefiles and the search order that +\fBdmake\fP should use to determine if one exists. +A typical definition for this target is: +.RS +.sp +\&.MAKEFILES : makefile.mk Makefile makefile +.sp +.RE +\fBdmake\fP will first look for makefile.mk and then the others. +If a prerequisite +cannot be found \fBdmake\fP will try to make it before going on to the next +prerequisite. For example, makefile.mk can be checked out of an RCS file +if the proper rules for doing so are defined in the startup file. +.PP +If the first line of the user makefile is of the form: +.RS +.sp +\#! command command_args +.sp +.RE +then \fBdmake\fP will expand and run the command prior to reading any +additional input. If the return code of the command is zero then \fBdmake\fP +will continue on to process the remainder of the user makefile, if the return +code is non-zero then dmake will exit. +.PP +\fBdmake\fP builds the internal dependency graph as it parses a user specified +makefile. The graph is rooted at the special target \fB.ROOT\fP. .ROOT is the +top level target that dmake builds when it starts to build targets. All user +specified targets (those from the command line or taken as defaults from +the makefile) are made prerequisites of the special target \fB.TARGETS\fP. +\fBdmake\fP by default creates the relationship that .ROOT depends on .TARGETS +and as a result everything is made. This approach allows the user to customize, within +their makefile, the order and which, target, is built first. For example the +default makefiles come with settings for .ROOT that specify: +.sp +.RS +\&.ROOT .PHONY .NOSTATE .SEQUENTIAL : .INIT .TARGETS .DONE +.RE +.sp +with .INIT and .DONE defined as: +.sp +.RS +\&.INIT .DONE .PHONY:; +.RE +.sp +which nicely emulates the behaviour of Sun's make extensions. The building of +\&.ROOT's prerequisites is always forced to be sequential. However, this +definition is trivially chaned by supplying the definition: +.sp +.RS +\&.ROOT : .TARGETS +.RE +.sp +which skips the preamble and postamble phases of building .TARGETS. +.SH SYNTAX +This section is a summary of the syntax of makefile statements. +The description is given in a style similar to BNF, where { } enclose +items that may appear zero or more times, and [ ] enclose items that +are optional. Alternative productions for a left hand side are indicated +by '\(->', and newlines are significant. All symbols in \fBbold\fP type +are text or names representing text supplied by the user. +.sp 2 +.RS +.Ip "Makefile" "\(-> { Statement }" +.Ip "Statement" "\(-> Macro-Definition" +\(-> Conditional-Macro-Definition +\(-> Conditional +\(-> Rule-Definition +\(-> Attribute-Definition +.Ip "Macro-Definition" "\(-> \fBMACRO = LINE\fP" +\(-> \fBMACRO [\fB!\fR]*= LINE\fP +\(-> \fBMACRO [\fB!\fR]:= LINE\fP +\(-> \fBMACRO [\fB!\fR]*:= LINE\fP +\(-> \fBMACRO [\fB!\fR]+= LINE\fP +\(-> \fBMACRO [\fB!\fR]+:= LINE\fP +.Ip "Conditional-Macro-Definition \(-> " "\fBTARGET\fP ?= Macro-Definition" +.Ip "Conditional \(-> " "\fB\&.IF\fR expression" + Makefile +[ \fB.ELIF\fR expression + Makefile ] +[ \fB.ELSE\fR + Makefile ] +\fB\&.END\fR +.Ip "expression" "\(-> \fBLINE\fR" +\(-> \fBSTRING == LINE\fR +\(-> \fBSTRING != LINE\fR +.Ip "Rule-Definition \(-> " "target-definition" + [ recipe ] +.PP +target-definition \(-> targets [attrs] op { \fBPREREQUISITE\fP } [\fB;\fR rcp-line] +.Ip "targets" "\(-> target { targets }" +\(-> \fB"\fRtarget\fB"\fR { targets } +.Ip "target" "\(-> special-target" +\(-> \fBTARGET\fR +.Ip "attrs" "\(-> attribute { attrs }" +\(-> \fB"\fRattribute\fB"\fR { attrs } +.Ip "op" "\(-> \fB:\fR { modifier }" +.Ip "modifier" "\(-> \fB:\fR" +\(-> \fB^\fR +\(-> \fB!\fR +\(-> \fB\-\fR +\(-> \fB|\fR +.Ip "recipe" "\(-> { \fBTAB\fR rcp-line }" +\(-> [\fB@\fR][\fB%\fR][\fB\-\fR] \fB[ +.Is "recipe \(-> " +.Ii " " + \fR{ \fBLINE\fR } +.Ii " " +\fB]\fR +.Ip "rcp-line" "\(-> [\fB@\fR][\fB%\fR][\fB\-\fR][\fB+\fR] \fBLINE\fR" +.Ip Attribute-Definition "\(-> attrs \fB:\fR targets" +.Ip attribute "\(-> \fB.EPILOG\fR" +\(-> \fB.ERRREMOVE\fR +\(-> \fB.EXECUTE\fR +\(-> \fB.GROUP\fR +\(-> \fB.IGNORE\fR +\(-> \fB.IGNOREGROUP\fR +\(-> \fB.LIBRARY\fR +\(-> \fB.MKSARGS\fR +\(-> \fB.NOINFER\fR +\(-> \fB.NOSTATE\fR +\(-> \fB.PHONY\fR +\(-> \fB.PRECIOUS\fR +\(-> \fB.PROLOG\fR +\(-> \fB.SETDIR=\fIpath\fP\fR +\(-> \fB.SILENT\fR +\(-> \fB.SEQUENTIAL\fR +\(-> \fB.SWAP\fR +\(-> \fB.USESHELL\fR +\(-> \fB.SYMBOL\fR +\(-> \fB.UPDATEALL\fR +.Ip "special-target" "\(-> \fB.ERROR\fR" +\(-> \fB.EXIT\fR +\(-> \fB.EXPORT\fR +\(-> \fB.GROUPEPILOG\fR +\(-> \fB.GROUPPROLOG\fR +\(-> \fB.IMPORT\fR +\(-> \fB.INCLUDE\fR +\(-> \fB.INCLUDEDIRS\fR +\(-> \fB.MAKEFILES\fR +\(-> \fB.REMOVE\fR +\(-> \fB.SOURCE\fR +\(-> \fB.SOURCE.\fIsuffix\fR +\(-> .\fIsuffix1\fR.\fIsuffix2\fR +.fi +.RE +.sp 1 +.PP +Where, \fBTAB\fP represents a <tab> character, \fBSTRING\fP represents an +arbitrary sequence of characters, and +\fBLINE\fP represents a +possibly empty sequence of characters terminated by a non-escaped +(not immediately preceded by a backslash '\e') new-line character. +\fBMACRO\fP, \fBPREREQUISITE\fP, +and \fBTARGET\fP each represent a string of characters not +including space or tab which respectively form the name of a macro, +prerequisite or target. +The name may itself be a macro expansion expression. +A \fBLINE\fP can be continued over several physical lines by terminating it with +a single backslash character. Comments are initiated by the +pound \fB#\fR character and extend to the end of line. +All comment text is discarded, a '#' may be placed into the makefile text +by escaping it with '\e' (ie. \e# translates to # when it is parsed). +An exception to this occurs when a # is seen inside +a recipe line that begins with a <tab> or is inside a group recipe. +If you specify the \fB\-c\fP command line switch then this behavior is +disabled and +.B dmake +will treat all # characters as start of comment indicators unless they +are escaped by \e. +A set of continued lines may be commented out by placing a single # at the +start of the first line. +A continued line cannot span more than one makefile. +.PP +\fBwhite space\fP is defined to be any combination of +<space>, <tab>, and the sequence \e<nl> +when \e<nl> is used to terminate a LINE. +When processing \fBmacro\fP definition lines, +any amount of white space is allowed on either side of the macro operator +and white space is stripped from both before and after the macro +value string. +The sequence \e<nl> is treated as white space during recipe expansion +and is deleted from the final recipe string. +You must escape the \e<nl> with another \e in order to get a \e at the end +of a recipe line. +The \e<nl> sequence is deleted from macro values when they are expanded. +.PP +When processing \fBtarget\fP definition lines, +the recipe for a target must, in general, follow the first definition +of the target (See the RULES AND TARGETS section for an exception), and +the recipe may not span across multiple makefiles. +Any targets and prerequisites found on a target definition line are taken +to be white space separated tokens. +The rule operator (\fIop\fP in SYNTAX section) is also considered +to be a token but does not require +white space to precede or follow it. Since the rule operator begins with a `:', +traditional versions of make do not allow the `:' character to +form a valid target name. \fBdmake\fP allows `:' to be present in +target/prerequisite names as long as the entire target/prerequisite name is +quoted. For example: +.sp +\ta:fred : test +.sp +would be parsed as TARGET = a, PREREQUISITES={fred, :, test}, which +is not what was intended. To fix this you must write: +.sp +\t"a:fred" : test +.sp +Which will be parsed as expected. Quoted target and prerequisite +specifications may also contain white space thereby allowing the use of +complex function macro expressions.. +See the EXAMPLES section for how to apply \fB"\fP quoting +to a list of targets. +.SH ATTRIBUTES +.B dmake +defines several target attributes. Attributes may be +assigned to a single target, a group of targets, or to all targets in the +makefile. Attributes are used to modify +\fBdmake\fP actions during target update. +The recognized attributes are: +.sp +.IP \fB.EPILOG\fP 1.2i +Insert shell epilog code when executing a group recipe associated with +any target having this attribute set. +.IP \fB.ERRREMOVE\fP 1.2i +Always remove any target having this attribute if an error is encountered +while making them. Setting this attribute overrides the .PRECIOUS attribute. +.IP \fB.EXECUTE\fP 1.2i +If the \-n flag was given then execute the recipe associated with any +target having this attribute set. +.IP \fB.FIRST\fP 1.2i +Used in conjunction with .INCLUDE. Terminates the inclusion with the first +successfully included prerequisite. +.IP \fB.GROUP\fP 1.2i +Force execution of a target's recipe as a group recipe. +.IP \fB.IGNORE\fP 1.2i +Ignore an error when trying to make any target with this attribute set. +.IP \fB.IGNOREGROUP\fP 1.2i +Disable the special meaning of '[' to initiate a group recipe. +.IP \fB.LIBRARY\fP 1.2i +Target is a library. +.IP \fB.MKSARGS\fP 1.2i +If running in an MSDOS environment then use MKS extended argument passing +conventions to pass arguments to commands. Non-MSDOS +environments ignore this attribute. +.IP \fB.NOINFER\fP 1.2i +Any target with this attribute set will not be subjected +to transitive closure if it is inferred as a prerequisite +of a target whose recipe and prerequisites are being inferred. +(i.e. the inference algorithm will not use any prerequisite with this attribute +set, as a target) +If specified as '.NOINFER:' (ie. with no prerequisites or targets) then the +effect is equivalent to specifying \fB\-T\fP on the command line. +.IP \fB.NOSTATE\fP 1.2i +Any target with this attribute set will not have command line flag +information stored in the state file if .KEEP_STATE has been enabled. +.IP \fB.PHONY\fP 1.2i +Any target with this attribute set will have its recipe executed +each time the target is made even if a file matching the target name can +be located. Any targets that have a .PHONY attributed target as a +prerequisite will be made each time the .PHONY attributed prerequisite is +made. +.IP \fB.PRECIOUS\fP 1.2i +Do not remove associated target under any circumstances. +Set by default for any targets whose corresponding files exist in the file +system prior to the execution of \fBdmake\fP. +.IP \fB.PROLOG\fP 1.2i +Insert shell prolog code when executing a group recipe associated with +any target having this attribute set. +.IP \fB.SEQUENTIAL\fP 1.2i +Force a sequential make of the associated target's prerequisites. +.IP \fB.SETDIR\fP 1.2i +Change current working directory to specified directory when making the +associated target. You must +specify the directory at the time the attribute is specified. To do this +simply give \fI.SETDIR=path\fP as the attribute. \fIpath\fP is expanded and +the result is used as the value of the directory to change to. +If \fIpath\fP contains \fB$$@\fP then the name of the target to be built is +used in computing the path to change directory to. +If path is surrounded by single quotes then path is not expanded, and is used +literally as the directory name. +If the \fIpath\fP contains any `:' characters then the entire attribute string +must be quoted using ". +If a target having this attribute set also has the .IGNORE +attribute set then if the change to the specified directory fails it will be +ignored, and no error message will be issued. +.IP \fB.SILENT\fP 1.2i +Do not echo the recipe lines when making any target with this attribute set, +and do not issue any warnings. +.IP \fB.SWAP\fP 1.2i +Under MSDOS +when making a target with this attribute set swap the \fBdmake\fP executable +to disk prior to executing the recipe line. Also see the '%' recipe line +flag defined in the RECIPES section. +.IP \fB.SYMBOL\fP 1.2i +Target is a library member and is an entry point into a module in the +library. This attribute is used only when searching a library for a target. +Targets of the form lib((entry)) have this attribute set automatically. +.IP \fB.USESHELL\fP 1.2i +Force each recipe line of a target to be executed using a shell. +Specifying this attribute is equivalent to specifying the '+' character at the +start of each line of a non-group recipe. +.IP \fB.UPDATEALL\fP 1.2i +Indicates that all the targets listed in this rule are updated by the +execution of the accompanying recipe. +A common example is the production of the +.I y.tab.c +and +.I y.tab.h +files by +.B yacc +when it is run on a grammar. Specifying .UPDATEALL in such a rule +prevents the running of yacc twice, once for the y.tab.c file and once +for the y.tab.h file. .UPDATEALL targets that are specified in a single rule +are treated as a single target and all timestamps are updated whenever any +target in the set is made. As a side-effect, \fBdmake\fP internally sorts +such targets in ascending alphabetical order and the value of $@ is always +the first target in the sorted set. +.LP +All attributes are user setable and except for .UPDATEALL, .SETDIR and .MKSARGS +may be used in one of two forms. +The .MKSARGS attribute is restricted to use as a global attribute, and +the use of the .UPDATEALL and .SETDIR attributes is restricted to rules +of the second form only. +.sp +\tATTRIBUTE_LIST : \fItargets\fP +.sp +assigns the attributes specified by ATTRIBUTE_LIST to each target in +.I targets +or +.sp +\t\fItargets\fP ATTRIBUTE_LIST : ... +.sp +assigns the attributes specified by ATTRIBUTE_LIST to each target in +.I targets. +In the first form if +.I targets +is empty (ie. a NULL list), then the +list of attributes will apply to all targets in the makefile +(this is equivalent to the common Make construct of \fI".IGNORE :"\fP +but has been modified to the notion of an attribute instead of +a special target). +Not all of the attributes have global meaning. +In particular, .LIBRARY, .NOSTATE, .PHONY, .SETDIR, .SYMBOL and .UPDATEALL +have no assigned global meaning. +.PP +Any attribute may be used with any target, even with the special targets. +Some combinations are useless (e.g. .INCLUDE .PRECIOUS: ... ), +while others are useful (e.g. .INCLUDE .IGNORE : "file.mk" will not complain +if file.mk cannot be found using the include file search rules, +see the section on SPECIAL TARGETS for a description of .INCLUDE). +If a specified attribute will not be used with the special target a warning +is issued and the attribute is ignored. +.SH MACROS +.B dmake +supports six forms of macro assignment. +.sp +.IP "\fBMACRO = LINE\fP" 1.55i +This is the most common and familiar form of macro assignment. It assigns +LINE literally as the value of MACRO. +Future expansions of MACRO recursively expand its value. +.IP "\fBMACRO *= LINE\fP" 1.55i +This form behaves exactly as the simple '=' form with the exception that if +MACRO already has a value then the assignment is not performed. +.IP "\fBMACRO := LINE\fP" 1.55i +This form differs from the simple '=' form in that it expands LINE +prior to assigning it as the value of MACRO. +Future expansions of MACRO do not recursively expand its value. +.IP "\fBMACRO *:= LINE\fP" 1.55i +This form behaves exactly as the ':=' form with the exception that if +MACRO already has a value then the assignment and expansion are not performed. +.IP "\fBMACRO += LINE\fP" 1.55i +This form of macro assignment allows macro values to grow. It takes the +literal value of LINE and appends it to the previous value of MACRO separating +the two by a single space. +Future expansions of MACRO recursively expand its value. +.IP "\fBMACRO +:= LINE\fP" 1.55i +This form is similar to the '+=' form except that the value of LINE is expanded +prior to being added to the value of MACRO. +.PP +Macro expressions specified on the command line allow the macro value +to be redefined within the makefile only if the macro is defined using +the '+=' and '+:=' operators. Other operators will define a macro that cannot +be further modified. +.PP +Each of the preceeding macro assignment operators may be prefixed by \fB!\fP +to indicate that the assignment should be forced and that no warnings should +be issued. Thus, specifying \fB!\fP has the effect of silently forcing the +specified macro assignment. +.PP +When \fBdmake\fP defines a non-environment macro it strips leading and +trailing white space from the macro value. +Macros imported from the environment via either the .IMPORT special +target (see the SPECIAL TARGETS section), or the \fB\-e\fP, or \fB\-E\fP flags +are an exception to this rule. Their values are +always taken literally and white space is never stripped. +In addition, named macros defined using the .IMPORT special target do +not have their values expanded when they are used within a makefile. +In contrast, environment macros that are imported +due to the specification of the \fB\-e\fP or \fB\-E\fP flags +are subject to expansion when used. +.PP +To specify a macro expansion +enclose the name in () or {} and precede it with a dollar sign $. +Thus $(TEST) represents an expansion of the macro variable named TEST. +If TEST is +defined then $(TEST) is replaced by its expanded value. If TEST is not +defined then $(TEST) expands to the NULL string (this is equivalent to +defining a macro as 'TEST=' ). A short form may be used for single character +named macros. In this case the parentheses are optional, and $(I) is +equivalent to $I. +Macro expansion is recursive, hence, if the value string contains an expression +representing a macro expansion, the expansion is performed. Circular macro +expansions are detected and cause an error to be issued. +.PP +When defining a macro the given macro name is first expanded before being used +to define the macro. Thus it is possible to define macros whose names +depend on values of other macros. For example, suppose CWD is defined as +.sp +\tCWD = $(PWD:b) +.sp +then the value of $(CWD) is the name of the current directory. +This can be used to define macros specific to this directory, for +example: +.sp +\t_$(CWD).prt = list of files to print... +.sp +The actual name of the defined macro is a function of the current directory. +A construct such as this is useful when processing a hierarchy of directories +using .SETDIR attributed targets and a collection of small distributed +makefile stubs. +.PP +Macro variables may be defined within the makefile, on the command +line, or imported from the environment. +.PP +.B \fBdmake\fR +supports several non-standard macro expansions: +The first is of the form: +.RS +.IP \fI$(macro_name:modifier_list:modifier_list:...)\fR +.RE +.LP +where +.I modifier_list +is chosen from the set { B or b, D or d, E or e, F or f, I or i, L or l, S or +s, T or t, U or u, ^, +, 1 } and +.RS +.sp +.Is "b " +.Ii "b " +\- file (not including suffix) portion of path names +.Ii "d" +\- directory portion of all path names +.Ii "e" +\- suffix portion of path names +.Ii "f" +\- file (including suffix) portion of path names +.Ii "i" +\- inferred names of targets +.Ii "l" +\- macro value in lower case +.Ii "s" +\- simple pattern substitution +.Ii "t" +\- tokenization. +.Ii "u" +\- macro value in upper case +.Ii "^" +\- prepend a prefix to each token +.Ii "+" +\- append a suffix to each token +.Ii "1" +\- return the first white space separated token from value +.sp +.RE +.fi +Thus if we have the example: +.RS +test = d1/d2/d3/a.out f.out d1/k.out +.RE +The following macro expansions produce the values on the right of '\(->' after +expansion. +.RS +.sp +.Is "$(test:s/out/in/:f) " +.Ii "$(test:d)" +\(-> d1/d2/d3/ d1/ +.Ii "$(test:b)" +\(-> a f k +.Ii "$(test:f)" +\(-> a.out f.out k.out +.Ii "${test:db}" +\(-> d1/d2/d3/a f d1/k +.Ii "${test:s/out/in/:f}" +\(-> a.in f.in k.in +.Ii $(test:f:t"+") +\(-> a.out+f.out+k.out +.Ii $(test:e) +\(-> .out .out .out +.Ii $(test:u) +\(-> D1/D2/D3/A.OUT F.OUT D1/K.OUT +.Ii $(test:1) +\(-> d1/d2/d3/a.out +.RE +.fi +.PP +If a token ends in a string composed from the value of the macro DIRBRKSTR +(ie. ends in a directory separator string, e.g. '/' in UNIX) and you use the +\fB:d\fP modifier then the expansion returns the directory name less the +final directory separator string. Thus successive pairs of :d modifiers +each remove a level of directory in the token string. +.PP +The tokenization modifier takes all white space separated tokens from the +macro value and separates them by the quoted separator string. The separator +string may contain the following escape codes \ea => <bel>, +\&\eb => <backspace>, \ef => <formfeed>, \en => <nl>, \er => <cr>, +\&\et => <tab>, \ev => <vertical tab>, \e" => ", and \exxx => <xxx> where +xxx is the octal representation of a character. Thus the +expansion: +.LP +.RS +.nf +$(test:f:t"+\en") +.RE +produces: +.RS +a.out+ +f.out+ +k.out +.fi +.RE +.PP +The prefix operator \fB^\fP takes all white space separated tokens from the +macro value and prepends \fIstring\fP to each. +.LP +.RS +.nf +$(test:f:^mydir/) +.RE +produces: +.RS +mydir/a.out mydir/f.out mydir/k.out +.fi +.RE +.PP +The suffix operator \fB+\fP takes all white space separated tokens from the +macro value and appends \fIstring\fP to each. +.LP +.RS +.nf +$(test:b:+.c) +.RE +produces: +.RS +a.c f.c k.c +.fi +.RE +.PP +The next non-standard form of macro expansion allows for recursive macros. +It is possible to specify a $(\fImacro_name\fR) or ${\fImacro_name\fR} expansion +where \fImacro_name\fR contains more $( ... ) or ${ ... } macro expansions +itself. +.PP +For example $(CC$(_HOST)$(_COMPILER)) will first expand CC$(_HOST)$(_COMPILER) +to get a result and use that result as the name of the macro to expand. +This is useful for writing a makefile for more than one target +environment. As an example consider the following hypothetical case. +Suppose that _HOST and _COMPILER are imported from the environment +and are set to represent the host machine type and the host compiler +respectively. +.RS +.sp +.nf +CFLAGS_VAX_CC = \-c \-O # _HOST == "_VAX", _COMPILER == "_CC" +CFLAGS_PC_MSC = \-c \-ML # _HOST == "_PC", _COMPILER == "_MSC" +.sp +# redefine CFLAGS macro as: +.sp +CFLAGS := $(CFLAGS$(_HOST)$(_COMPILER)) +.fi +.sp +.RE +This causes CFLAGS to take on a value that corresponds to the +environment in which the make is being invoked. +.PP +The final non-standard macro expansion is of the form: +.RS +.sp +string1{token_list}string2 +.RE +.LP +where string1, string2 and token_list are expanded. After expansion, +string1 is prepended to each token found in token_list and +string2 is appended to each resulting token from the previous prepend. +string1 and string2 are not delimited by white space +whereas the tokens in token_list are. +A null token in the token list +is specified using "". +Thus using another example we have: +.RS +.sp +.Is "test/{f1 f2}.o " +.Ii "test/{f1 f2}.o" +--> test/f1.o test/f2.o +.Ii "test/ {f1 f2}.o" +--> test/ f1.o f2.o +.Ii "test/{f1 f2} .o" +--> test/f1 test/f2 .o +.Ii "test/{""f1"" """"}.o" +--> test/f1.o test/.o +.sp +.Ii and +.sp +.Is "test/{d1 d2}/{f1 f2}.o --> " +.Ii "test/{d1 d2}/{f1 f2}.o --> " +test/d1/f1.o test/d1/f2.o +test/d2/f1.o test/d2/f2.o +.sp +.RE +.fi +This last expansion is activated only when the first characters of +\fItoken_list\fP +appear immediately after the opening '{' with no intervening white space. +The reason for this restriction is the following incompatibility with +Bourne Shell recipes. The line +.RS +.sp +{ echo hello;} +.sp +.RE +is valid /bin/sh syntax; while +.RS +.sp +{echo hello;} +.sp +.RE +.fi +is not. Hence the latter triggers the enhanced macro expansion while the former +causes it to be suppressed. +See the SPECIAL MACROS section for a description of the special macros that +\fBdmake\fP defines and understands. +.SH "RULES AND TARGETS" +A makefile contains a series of entries that specify dependencies. +Such entries are called \fItarget/prerequisite\fP or \fIrule\fP definitions. +Each rule definition +is optionally followed by a set of lines that provide a recipe for updating +any targets defined by the rule. +Whenever +.B dmake +attempts to bring a target up to date and an explicit recipe is provided with +a rule defining the target, that recipe is used to update the +target. A rule definition begins with a line having the following syntax: +.sp +.RS +.nf +\fI<targets>\fP [\fI<attributes>\fP] \fI<ruleop>\fP [\fI<prerequisites>\fP] [;\fI<recipe>\fP] +.fi +.RE +.sp +.I targets +is a non-empty list of targets. If the target is a +special target (see SPECIAL TARGETS section below) then it must appear alone +on the rule line. For example: +.sp +.RS +\&.IMPORT .ERROR : ... +.RE +.sp +is not allowed since both .IMPORT and .ERROR are special targets. +Special targets are not used in the construction of the dependency graph and +will not be made. +.PP +.I attributes +is a possibly empty list of attributes. Any attribute defined in the +ATTRIBUTES section above may be specified. All attributes will be applied to +the list of named targets in the rule definition. No other targets will +be affected. +.sp +.IP NOTE: 0.75i +As stated earlier, +if both the target list and prerequisite list are empty but the attributes +list is not, then the specified attributes affect all targets in the makefile. +.sp +.PP +.I ruleop +is a separator which is used to identify the targets from the prerequisites. +Optionally it also provides a facility for modifying the way in which +.B dmake +handles the making of the associated targets. +In its simplest form the operator is a single ':', and need not be separated +by white space from its neighboring tokens. It may additionally be followed +by any of the modifiers { !, ^, \-, :, | }, where: +.sp +.IP \fB!\fP +says execute the recipe for the associated targets once for each out of date +prerequisite. Ordinarily the recipe is executed +once for all out of date prerequisites at the same time. +.IP \fB^\fP +says to insert the specified prerequisites, if any, before any +other prerequisites already associated with the specified targets. +In general, it is not useful to specify ^ with an empty +list of prerequisites. +.IP \fB\-\fP +says to clear the previous list of prerequisites before adding +the new prerequisites. Thus, +.sp +\t.SUFFIXES : +.br +\t.SUFFIXES : .a .b +.sp +can be replaced by +.sp +\t.SUFFIXES :\- .a .b +.sp +however the old form still works as expected. NOTE: .SUFFIXES is ignored by +.B dmake +it is used here simply as an example. +.IP \fB:\fP +When the rule operator is not modified by a second ':' +only one set of rules may be specified for making a target. +Multiple definitions may be used to add to the +list of prerequisites that a target depends on. +However, if a target is multiply defined +only one definition may specify a recipe +for making the target. +.sp +When a target's rule operator is modified by a second ':' +(:: for example) then this definition may not be the only +definition with a recipe for the target. There may be other :: target +definition lines that specify a different set of prerequisites with a +different recipe for updating the target. +Any such target is made if any of the definitions +find it to be out of date +with respect to the related prerequisites +and the corresponding recipe is used to update the +target. By definition all '::' recipes that are found to be out of date for +are executed. +.sp +In the following simple example, each rule has a `::' \fIruleop\fP. In such an +operator we call the first `:' the operator, and the second `:' the modifier. +.sp +.nf +a.o :: a.c b.h + first recipe for making a.o + +a.o :: a.y b.h + second recipe for making a.o +.fi +.sp +If a.o is found to be out of date with respect to a.c then the first recipe +is used to make a.o. If it is found out of date with respect to a.y then +the second recipe is used. If a.o is out of date with respect to +b.h then both recipes are invoked to make a.o. +In the last case the order of invocation corresponds to the order in which the +rule definitions appear in the makefile. +.IP \fB|\fP +Is defined only for PERCENT rule target definitions. When specified it +indicates that the following construct should be parsed using the old +semantinc meaning: +.sp +.nf +%.o :| %.c %.r %.f ; some rule +.sp +is equivalent to: +.sp +%.o : %.c ; some rule +%.o : %.r ; some rule +%.o : %.f ; some rule +.fi +.PP +Targets defined using a single `:' operator +with a recipe may be redefined again with a new recipe by using a +`:' operator with a `:' modifier. +This is equivalent to a target having been +initially defined with a rule using a `:' modifier. +Once a target is defined using a `:' +modifier it may not be defined again with a recipe using only the `:' operator +with no `:' modifier. In both cases the use of a `:' modifier creates a new +list of prerequisites and makes it the current prerequisite list for the target. +The `:' operator with no recipe always modifies the current list +of prerequisites. +Thus assuming each of the following definitions has a recipe attached, then: +.RS +.sp +.nf +joe : fred ... (1) +joe :: more ... (2) +.sp +and +.sp +joe :: fred ... (3) +joe :: more ... (4) +.sp +.fi +.RE +are legal and mean: add the recipe associated with (2), or (4) to the set +of recipes for joe, placing them after existing recipes for +making joe. +The constructs: +.RS +.sp +.nf +joe :: fred ... (5) +joe : more ... (6) +.sp +and +.sp +joe : fred ... (7) +joe : more ... (8) +.sp +.fi +.RE +are errors since we have two sets of perfectly good recipes for +making the target. +.PP +.I prerequisites +is a possibly empty list of targets that must be brought up to date before +making the current target. +.PP +.I recipe +is a short form and allows the user to specify short rule definitions +on a single line. +It is taken to be the first recipe line in a larger recipe +if additional lines follow the rule definition. +If the semi-colon is present but the recipe line is empty (ie. null string) +then it is taken +to be an empty rule. Any target so defined causes the +.I "Don't know how to make ..." +error message to be suppressed when +.B dmake +tries to make the target and fails. +This silence is maintained for rules that are terminated +by a semicolon and have no following recipe lines, for targets listed on the +command line, for the first target found in the makefile, and for any target +having no recipe but containing a list of prerequisites (see the COMPATIBILITY +section for an exception to this rule if the AUGMAKE (\fB\-A\fP) flag +was specified. +.SH "RECIPES" +The traditional format used by most versions of Make defines the recipe +lines as arbitrary strings that may contain macro expansions. They +follow a rule definition line and may be spaced +apart by comment or blank lines. +The list of recipe lines defining the recipe is terminated by a new target +definition, a macro definition, or end-of-file. +Each recipe line +.B MUST +begin with a \fB<TAB>\fP character which +may optionally be followed with one or all +of the characters +.IR "'@%+\-'" "." +The +.I "'\-'" +indicates that non-zero exit values (ie. errors) +are to be ignored when this recipe line is executed, the +.I "'\+'" +indicates that the current recipe line is to be executed using the shell, the +.I "'%'" +indicates that +.B dmake +should swap itself out to secondary storage (MSDOS only) before running the +recipe and the +.I "'@'" +indicates that the recipe line should NOT be echoed to the terminal prior to +being executed. Each switch is off by default +(ie. by default, errors are significant, commands are echoed, no swapping is +done and a shell is +used only if the recipe line contains a character found in the value of the +SHELLMETAS macro). +Global settings activated via command line options or special attribute or +target names may also affect these settings. +An example recipe: +.sp +.RS +.nf +target : +\tfirst recipe line +\tsecond recipe line, executed independent of first. +\t@a recipe line that is not echoed +\t\-and one that has errors ignored +\t%and one that causes dmake to swap out +\t\+and one that is executed using a shell. +.fi +.RE +.PP +The second and new format of the recipe block begins the block with the +character '[' (the open group character) in the last non-white space +position of a line, and terminates the +block with the character ']' (the close group character) +in the first non-white space position of a line. +In this form each recipe line need not have a leading TAB. This is +called a recipe group. Groups so defined are fed intact as a single +unit to a shell for execution whenever the corresponding target needs to +be updated. If the open group character '[' is preceded +by one or all of \-, @ or % +then they apply to the entire group in the same way that they +apply to single recipe lines. You may also specify '+' but it is +redundant as a shell is already being used to run the recipe. +See the MAKING TARGETS section for a description of how +.B dmake +invokes recipes. +Here is an example of a group recipe: +.sp +.RS +.nf +target : +[ + first recipe line + second recipe line + tall of these recipe lines are fed to a + single copy of a shell for execution. +] +.fi +.RE +.sp +.SH "TEXT DIVERSIONS" +.B dmake +supports the notion of text diversions. +If a recipe line contains the macro expression +.RS +.sp +$(mktmp[,[\fIfile\fP][,\fItext\fP]] \fIdata\fP) +.sp +.RE +then all text contained in the \fIdata\fP expression is expanded and +is written to a temporary file. The return +value of the macro is the name of the temporary file. +.PP +.I data +can be any text and must be separated from the 'mktmp' portion of the +macro name by white-space. The only restriction on the data text is that +it must contain a balanced number of parentheses of the same kind as are +used to initiate the $(mktmp ...) expression. For example: +.RS +.sp +$(mktmp $(XXX)) +.sp +.RE +is legal and works as expected, but: +.RS +.sp +$(mktmp text (to dump to file) +.sp +.RE +is not legal. You can achieve what you wish by either defining a macro that +expands to '(' or by using {} in the macro expression; like this: +.RS +.sp +${mktmp text (to dump to file} +.sp +.RE +Since the temporary file is opened when the +macro containing the text diversion expression is expanded, diversions may +be nested and any diversions that are created as part of ':=' macro +expansions persist for the duration of the +.B dmake +run. +The diversion text may contain +the same escape codes as those described in the MACROS section. +Thus if the \fIdata\fP text is to contain new lines they must be inserted +using the \en escape sequence. For example the expression: +.RS +.sp +.nf +all: + cat $(mktmp this is a\en\e + test of the text diversion\en) +.fi +.sp +.RE +is replaced by: +.RS +.sp +cat /tmp/mk12294AA +.sp +.RE +where the temporary file contains two lines both of which are terminated +by a new-line. If the \fIdata\fP text spans multiple lines in the makefile +then each line must be continued via the use of a \e. +A second more illustrative example generates a response file to an MSDOS +link command: +.RS +.sp +.nf +OBJ = fred.obj mary.obj joe.obj +all : $(OBJ) + link @$(mktmp $(^:t"+\en")\en) +.fi +.sp +.RE +The result of making `all' in the second example is the command: +.RS +.sp +link @/tmp/mk02394AA +.sp +.RE +where the temporary file contains: +.RS +.sp +.nf +fred.obj+ +mary.obj+ +joe.obj +.fi +.sp +.RE +The last line of the file is terminated by a new-line which is inserted +due to the \en found at the end of the \fIdata\fP string. +.PP +If the optional \fIfile\fP specifier is present then its expanded value +is the name of the temporary file to create. Whenever a $(mktmp ...) macro +is expanded the macro $(TMPFILE) is set to a new temporary file name. Thus +the construct: +.RS +.sp +$(mktmp,$(TMPFILE) data) +.sp +.RE +is completely equivalent to not specifying the $(TMPFILE) optional argument. +Another example that would be useful for MSDOS users with a Turbo-C compiler +.RS +.sp +$(mktmp,turboc.cfg $(CFLAGS)) +.sp +.RE +will place the contents of CFLAGS into a local \fIturboc.cfg\fP file. +The second optional argument, \fItext\fP, if present alters the name +of the value returned by the $(mktmp ...) macro. +.PP +Under MS-DOS text diversions may be a problem. Many DOS tools require +that path names which contain directories use the \e character to delimit +the directories. Some users however wish to use the '/' to delimit pathnames +and use environments that allow them to do so. +The macro USESHELL is set to "yes" if the +current recipe is forced to use a shell via the .USESHELL or '+' directives, +otherwise its value is "no". +The +.B dmake +startup files define the macro DIVFILE whose value is either the +value of TMPFILE or the value of TMPFILE edited to replace any '/' characters +to the appropriate value based on the current shell and whether it will be +used to execute the recipe. +.PP +Previous versions of +.B dmake +defined text diversions using <+, +> strings, +where <+ started a text diversion and +> terminated one. +.B dmake +is backward compatible with this construct only +if the <+ and +> appear literally +on the same recipe line or in the same macro value string. In such instances +the expression: +.sp +\t<+data+> +.sp +is mapped to: +.sp +\t$(mktmp data) +.sp +which is fully output compatible with the earlier construct. <+, +> +constructs whose text spans multiple lines must be converted by hand to use +$(mktmp ...). +.PP +If the environment variable TMPDIR is defined then the +temporary file is placed into the directory specified by that variable. +A makefile can modify the location of temporary files by +defining a macro named TMPDIR and exporting it using the .EXPORT special +target. +.SH "SPECIAL TARGETS" +This section describes the special targets that are recognized by \fBdmake\fP. +Some are affected by attributes and others are not. +.IP \fB.ERROR\fP 1.4i +If defined then the recipe associated with this target is executed +whenever an error condition is detected by \fBdmake\fP. All attributes that +can be used with any other target may be used with this target. Any +prerequisites of this target will be brought up to date during its processing. +NOTE: errors will be ignored while making this target, in extreme cases this +may cause some problems. +.IP \fB.EXIT\fP 1.4i +If this target is encountered while parsing a makefile then the parsing of the +makefile is immediately terminated at that point. +.IP \fB.EXPORT\fP 1.4i +All prerequisites associated with this target are assumed to +correspond to macro names and they and their values +are exported to the environment as environment strings at the point in +the makefile at which this target appears. +Any attributes specified with this target are ignored. +Only macros which have been assigned a value in the makefile prior to the +export directive are exported, macros as yet undefined +or macros whose value contains any of the characters "+=:*" +are not exported. +is suppre +.IP \fB.IMPORT\fP 1.4i +Prerequisite names specified for this target are searched for in the +environment and defined as macros with their value taken from the environment. +If the special name \fB.EVERYTHING\fP is used as a prerequisite name then +all environment variables defined in the environment are imported. +The functionality of the \fB\-E\fP flag can be forced by placing the construct +\&\fI.IMPORT : .EVERYTHING\fP at the start of a makefile. Similarly, by +placing the construct at the end, one can emulate the effect of the \fB\-e\fP +command line flag. +If a prerequisite name cannot be found in the environment +an error message is issued. +\&.IMPORT accepts the .IGNORE attribute. When given, it causes \fBdmake\fP +to ignore the above error. +See the MACROS section for a description of the processing of imported macro +values. +.IP \fB.INCLUDE\fP 1.4i +Parse another makefile just as if it had been located at the point of the +\&.INCLUDE in the current makefile. +The list of prerequisites gives the list of +makefiles to try to read. If the list contains multiple makefiles then they +are read in order from left to right. The following search rules are used +when trying to locate the file. If the filename is surrounded by " or just +by itself then it is searched for in the current directory. If it is not +found it is then searched for in each of the directories specified +as prerequisites of the \&.INCLUDEDIRS special target. +If the file name is surrounded by < and >, (ie. +<my_spiffy_new_makefile>) then it is searched for only in the directories +given by the .INCLUDEDIRS special target. In both cases if the file name is a +fully qualified name starting at the root of the file system then it is only +searched for once, and the .INCLUDEDIRS list is ignored. +If .INCLUDE fails to find the file it invokes the inference engine to +try to infer and hence make the file to be included. In this way the +file can be checked out of an RCS repository for example. +\&.INCLUDE accepts +the .IGNORE, .SETDIR, and .NOINFER attributes. +If the .IGNORE attribute is given and the file +cannot be found then \fBdmake\fP continues processing, +otherwise an error message is generated. +If the .NOINFER attribute is given and the file +cannot be found then \fBdmake\fP will not attempt to +\fIinfer and make\fP the file. +The .SETDIR attribute causes +.B dmake +to change directories to the specified directory prior to attempting the +include operation. If all fails \fBdmake\fP attempts to \fImake\fP the file +to be included. If making the file fails then \fBdmake\fP terminates unless +the .INCLUDE directive also specified the .IGNORE attribute. +If .FIRST is specified along with .INCLUDE then \fBdmake\fP attempts to +include each named prerequisite and will terminate the inclusion with the +first prerequisite that results in a successful inclusion. +.IP \fB.INCLUDEDIRS\fP 1.4i +The list of prerequisites specified for this target defines the set of +directories to search when trying to include a makefile. +.IP \fB.KEEP_STATE\fP 1.4i +This special target is a synonym for the macro definition +.sp +\&\t.KEEP_STATE := _state.mk +.sp +It's effect is to turn on STATE keeping and to define \fI_state.mk\fP +as the state file. +.IP \fB.MAKEFILES\fP 1.4i +The list of prerequisites is the set of files to try to read as the default +makefile. By default this target is defined as: +.sp +\t\&.MAKEFILES : makefile.mk Makefile makefile +.sp +.IP \fB.SOURCE\fP 1.4i +The prerequisite list of this target defines a set of directories to check +when trying to locate a target file name. See the section on BINDING of +targets for more information. +.IP \fB.SOURCE.suff\fP 1.4i +The same as .SOURCE, except that the .SOURCE.suff list is searched first when +trying to locate a file matching the a target whose name ends in the suffix +\&.suff. +.IP \fB.REMOVE\fP 1.4i +The recipe of this target is used whenever \fBdmake\fP needs to remove +intermediate targets that were made but do not need to be kept around. +Such targets result from the application of transitive closure on the +dependency graph. +.PP +In addition to the special targets above, +several other forms of targets are recognized and are considered special, +their exact form and use is defined in the sections that follow. +.SH "SPECIAL MACROS" +.B dmake +defines a number of special macros. They are divided into three classes: +control macros, run-time macros, and function macros. +The control macros are used by +.B dmake +to configure its actions, and are the preferred method of doing so. +In the case when a control macro has the same function as a special +target or attribute they share the same name as the special target or +attribute. +The run-time macros are defined when +.B dmake +makes targets and may be used by the user inside recipes. +The function macros provide higher level functions dealing with macro +expansion and diversion file processing. +.SH "CONTROL MACROS" +To use the control macros simply assign them a value just like any other +macro. The control macros are divided into three groups: +string valued macros, character valued macros, and boolean valued macros. +.PP +The following are all of the string valued macros. +This list is divided into two groups. The first group gives the string +valued macros that are defined internally and cannot be directly set by the +user. +.IP \fBINCDEPTH\fP 1.6i +This macro's value is a string of digits representing +the current depth of makefile inclusion. +In the first makefile level this value is zero. +.IP \fBMFLAGS\fP 1.6i +Is the list of flags +that were given on the command line including a leading switch character. +The \-f flag is not included in this list. +.IP \fBMAKECMD\fP 1.6i +Is the name with which \fBdmake\fP was invoked. +.IP \fBMAKEDIR\fP 1.6i +Is the full path to the initial directory in which +.B dmake +was invoked. +.IP \fBMAKEFILE\fP 1.6i +Contains the string "\-f \fImakefile\fP" where, \fImakefile\fP is the name +of initial user makefile that was first read. +.IP \fBMAKEFLAGS\fP 1.6i +Is the same as $(MFLAGS) but has no leading switch +character. (ie. MFLAGS = \-$(MAKEFLAGS)) +.IP \fBMAKEMACROS\fP 1.6i +Contains the complete list of macro expressions that were specified on the +command line. +.IP \fBMAKETARGETS\fP 1.6i +Contains the name(s) of the target(s), if any, that were +specified on the command line. +.IP \fBMAKEVERSION\fP 1.6i +Contains a string indicating the current \fBdmake\fP version number. +.IP \fBMAXPROCESSLIMIT\fP 1.6i +Is a numeric string representing the maximum number of processes that +\fBdmake\fP can use when making targets using parallel mode. +.IP \fBNULL\fP 1.6i +Is permanently defined to be the NULL string. +This is useful when comparing a conditional expression to an NULL value. +.IP \fBPWD\fP 1.6i +Is the full path to the +current directory in which make is executing. +.IP \fBTMPFILE\fP 1.6i +Is set to the name of the most recent temporary file opened by \fBdmake\fP. +Temporary files are used for text diversions and for group recipe processing. +.IP \fBTMD\fP 1.6i +Stands for "To Make Dir", and +is the path from the present directory (value of $(PWD)) to the directory +that \fBdmake\fP was started up in (value of $(MAKEDIR)). +This macro is modified when .SETDIR attributes are processed. +.IP \fBUSESHELL\fP 1.6i +The value of this macro is set to "yes" if the current recipe is forced to +use a shell for its execution via the .USESHELL or '+' directives, its value +is "no" otherwise. +.sp +.PP +The second group of string valued macros control +.B dmake +behavior and may be set by the user. +.IP \fB.DIRCACHE\fP 1.6i +If set to "yes" enables the directory cache (this is the default). If set to +"no" disables the directory cache (equivalent to -d command-line flag). +.IP \fB.DIRCACHERESPCASE\fP 1.6i +If set to "yes" causes the directory cache, if enabled, to respect +file case, if set to "no" facilities of the native OS are used to +match file case. +.IP \fB.NAMEMAX\fP 1.6i +Defines the maximum length of a filename component. The value of the variable +is initialized at startup to the value of the compiled macro NAME_MAX. On +some systems the value of NAME_MAX is too short by default. Setting a new +value for .NAMEMAX will override the compiled value. +.IP \fB.NOTABS\fP 1.6i +When set to "yes" enables the use of spaces as well as <tabs> to begin +recipe lines. +By default a non\-group recipe is terminated by a line without any leading +white\-space or by a line not beggining with a <tab> character. +Enabling this mode modifies the first condition of +the above termination rule to terminate a +non\-group recipe with a line that contains only white\-space. +This mode does not effect the parsing of group recipes bracketed by []. +.IP \fBAUGMAKE\fP 1.6i +If set to "yes" value will enable the transformation of special +meta targets to support special AUGMAKE inferences (See the COMPATIBILITY +section). +.IP \fBDIRBRKSTR\fP 1.6i +Contains the string of chars used to terminate +the name of a directory in a pathname. +Under UNIX its value is "/", under MSDOS its value is "/\e:". +.IP \fBDIRSEPSTR\fP 1.6i +Contains the string that is used to separate directory components when +path names are constructed. It is defined with a default value at startup. +.IP \fBDIVFILE\fP 1.6i +Is defined in the startup file and gives the name that should be returned for +the diversion file name when used in +$(mktmp ...) expansions, see the TEXT DIVERSION section for details. +.IP \fBDYNAMICNESTINGLEVEL\fP 1.6i +Specifies the maximum number of recursive dynamic macro expansions. Its +initial value is 100. +.IP \fB.KEEP_STATE\fP 1.6i +Assigning this macro a value tells +.B dmake +the name of the state file to use and turns on the keeping of state +information for any targets that are brought up to date by the make. +.IP \fBGROUPFLAGS\fP 1.6i +This macro gives the set of flags to pass to the shell when +invoking it to execute a group recipe. The value of the macro is the +list of flags with a leading switch indicator. (ie. `\-' under UNIX) +.IP \fBGROUPSHELL\fP 1.6i +This macro defines the full +path to the executable image to be used as the shell when +processing group recipes. This macro must be defined if group recipes are +used. It is assigned a default value in the startup makefile. Under UNIX +this value is /bin/sh. +.IP \fBGROUPSUFFIX\fP 1.6i +If defined, this macro gives the string to use as a suffix +when creating group recipe files to be handed to the command interpreter. +For example, if it is defined as .sh, then all +temporary files created by \fBdmake\fP will end in the suffix .sh. +Under MSDOS if you are using command.com as your GROUPSHELL, then this suffix +must be set to .bat in order for group recipes to function correctly. +The setting of GROUPSUFFIX and GROUPSHELL is done automatically for +command.com in the startup.mk files. +.IP \fBMAKE\fP 1.6i +Is defined in the startup file by default. +Initially this macro is defined to have the value "$(MAKECMD) $(MFLAGS)". +The string $(MAKE) is recognized when using the \-n switch. +.IP \fBMAKESTARTUP\fP 1.6i +This macro defines the full path to the initial startup +makefile. Use the \fB\-V\fP command line option to discover its initial +value. +.IP \fBMAXLINELENGTH\fP 1.6i +This macro defines the maximum size of a single line of +makefile input text. The size is specified as a number, the default value +is defined internally and is shown via the \fB\-V\fP option. +A buffer of this size plus 2 is allocated for reading makefile text. The +buffer is freed before any targets are made, thereby allowing files containing +long input lines to be processed without consuming memory during the actual +make. +This macro can only be used to extend the line length beyond it's default +minimum value. +.IP \fBMAXPROCESS\fP 1.6i +Specify the maximum number of child processes to use when making targets. +The default value of this macro is "1" and its value cannot exceed the value +of the macro MAXPROCESSLIMIT. Setting the value of MAXPROCESS on the command +line or in the makefile is equivalent to supplying a corresponding value to +the -P flag on the command line. +.IP \fBPREP\fP 1.6i +This macro defines the number of iterations to be expanded +automatically when processing % rule definitions of the form: +.sp +% : %.suff +.sp +See the sections on PERCENT(%) RULES for details on how PREP is used. +.IP \fBSHELL\fP 1.6i +This macro defines the full path to the executable +image to be used as the shell when +processing single line recipes. This macro must be defined if recipes +requiring the shell for execution are to be used. +It is assigned a default value in the startup makefile. +Under UNIX this value is /bin/sh. +.IP \fBSHELLFLAGS\fP 1.6i +This macro gives the set of flags to pass to the shell when +invoking it to execute a single line recipe. The value of the macro is the +list of flags with a leading switch indicator. (ie. `\-' under UNIX) +.IP \fBSHELLMETAS\fP 1.6i +Each time +.B dmake +executes a single recipe line (not a group recipe) the line is +searched for any occurrence of a character defined in the value of SHELLMETAS. +If such a character is found the recipe line is defined to require a shell +to ensure its correct execution. In such instances +a shell is used to invoke the recipe line. +If no match is found the recipe line is executed without the use of a shell. +.sp +.PP +There is only one character valued macro defined by \fBdmake\fP: +\fBSWITCHAR\fP contains the switch character used +to introduce options on command lines. For UNIX its value is `\-', and for +MSDOS its value may be `/' or `\-'. +The macro is internally defined and is not user setable. +The MSDOS version of \fBdmake\fP attempts to first extract SWITCHAR from an +environment variable of the same name. If that fails it then attempts to +use the undocumented getswitchar system call, and returns the result of +that. Under MSDOS version 4.0 you must set the value of the environment +macro SWITCHAR to '/' to obtain predictable behavior. +.PP +All boolean macros currently understood by +.B dmake +correspond directly to the previously defined attributes. +These macros provide +a second way to apply global attributes, and represent the +preferred method of doing so. They are used by assigning them a +value. If the value is not a NULL string then the boolean condition +is set to on. +If the value is a NULL string then the condition is set to off. +There are five conditions defined and they correspond directly to the +attributes of the same name. Their meanings are defined in the ATTRIBUTES +section above. +The macros are: +\&\fB.EPILOG\fP, +\&\fB.IGNORE\fP, +\&\fB.MKSARGS\fP, +\&\fB.NOINFER\fP, +\&\fB.PRECIOUS\fP, +\&\fB.PROLOG\fP, +\&\fB.SEQUENTIAL\fP, +\&\fB.SILENT\fP, +\&\fB.SWAP\fP, and +\&\fB.USESHELL\fP. +Assigning any of these a non NULL value will globally set +the corresponding attribute to on. +.SH "RUNTIME MACROS" +These macros are defined +when \fBdmake\fP is making targets, and may take on different values for each +target. \fB$@\fP is defined to be the full target name, \fB$?\fP is the +list of all out of date prerequisites, \fB$&\fP is the list of all +prerequisites, \fB$>\fP is the name of the library if the current target is a +library member, and +\fB$<\fP is the list of prerequisites specified in the current rule. +If the current target had a recipe inferred then \fB$<\fP is the name of the +inferred prerequisite even if the target had a list of prerequisites supplied +using an explicit rule that did not provide a recipe. In such situations +\fB$&\fP gives the full list of prerequisites. +.PP +\fB$*\fP is defined as +\fB$(@:db)\fP when making targets with explicit recipes and is defined as the +value of % when making targets whose recipe is the result of an inference. +In the first case \fB$*\fP is the target name with no suffix, +and in the second case, is the value of the matched % pattern from +the associated %-rule. +\fB$^\fP expands to the set of out of date prerequisites taken from the +current value of \fB$<\fP. +In addition to these, +\fB$$\fP expands to $, \fB{{\fP expands to {, \fB}}\fP expands to }, and the +strings \fB<+\fP and \fB+>\fP are recognized +as respectively starting and terminating a text diversion when they appear +literally together in the same input line. +.PP +The difference between $? and $^ can best be illustrated by an example, +consider: +.RS +.sp +.nf +fred.out : joe amy hello +\trules for making fred + +fred.out : my.c your.h his.h her.h # more prerequisites +.fi +.sp +.RE +Assume joe, amy, and my.c are newer then fred.out. When +.B dmake +executes the recipe for making fred.out the values of the following macros +will be: +.RS +.sp +.nf +.Is "$@ " +.Ii "$@" +--> fred.out +.Ii "$*" +--> fred +.Ii "$?" +--> joe amy my.c # note output of $? vs $^ +.Ii "$^" +--> joe amy +.Ii "$<" +--> joe amy hello +.Ii "$&" +--> joe amy hello my.c your.h his.h her.h +.fi +.sp +.RE +.SH "FUNCTION MACROS" +.B dmake +supports a full set of functional macros. One of these, the $(mktmp ...) +macro, is discussed in detail in the TEXT DIVERSION section and is not +covered here. +.RS +.sp +.IP "$(\fBand\fP \fBmacroterm ...\fP)" +expands each \fBmacroterm\fP in turn until there are no more or one of +them returns an empty string. If all expand to non-empty strings the +macro returs the string "t" otherwise it returns an empty string. +.sp +.IP "$(\fBassign\fP \fBexpression\fP)" +Causes \fIexpression\fP to be parsed as a macro assignment expression and results +in the specified assignment being made. An error is issued if the assignment +is not syntatically correct. \fIexpression\fP may contain white space. This is +in effect a dynamic macro assignment facility and may appear anywhere any +other macro may appear. The result of the expanding a dynamic macro +assignment expression is the name of the macro that was assigned and $(NULL) +if the \fIexpression\fP is not a valid macro assignment expression. +Some examples are: +.RS +.sp +.nf +$(assign foo := fred) +$(assign $(ind_macro_name) +:= $(morejunk)) +.fi +.RE +.IP "$(\fBecho\fP \fBlist\fP)" +Echo's the value of \fIlist\fP. \fIlist\fP is not expanded. +.IP "$(\fBeq\fP,\fItext_a\fP,\fItext_b\fP \fBtrue\fP \fBfalse\fP)" +expands +.I text_a +and +.I text_b +and compares their results. If equal it returns the result of the expansion +of the +.B true +term, otherwise it returns the expansion of the +.B false +term. +.IP "$(\fB!eq\fP,\fItext_a\fP,\fItext_b\fP \fBtrue\fP \fBfalse\fP)" +Behaves identically to the previous macro except that the +.B true +string is chosen if the expansions of the two strings are not equal +.IP "$(\fBforeach\fP,\fIvar\fP,\fIlist\fP \fBdata\fP)" +Implements iterative macro expansion over \fIdata\fP using \fBvar\fP as the +iterator taking on values from \fIlist\fP. \fIvar\fP and \fIlist\fP are +expanded and the result is the concatenation of expanding \fIdata\fP with +\fIvar\fP being set to each whitespace separated token from \fIlist\fP. +For example: +.RS +.RS +.sp +.nf +list = a b c +all :; echo [$(foreach,i,$(list) [$i])] +.fi +.sp +.RE +will output +.RS +.sp +.nf +[[a] [b] [c]] +.fi +.sp +.RE +The iterator variable is defined as a local variable to this foreach +instance. The following expression illustrates this: +.RS +.sp +.nf +$(foreach,i,$(foreach,i,$(sort c a b) root/$i) [$i/f.h]) +.fi +.sp +.RE +when evaluated the result is: +.RS +.sp +.nf +[root/a/f.h] [root/b/f.h] [root/c/f.h] +.fi +.sp +.RE +The specification of list must be a valid macro expression, such as: +.RS +.sp +.nf +$($(assign list=a b c)) +$(sort d a b c) +$(echo a b c) +.fi +.sp +.RE +and cannot just be the list itself. That is, the following foreach +expression: +.RS +.sp +.nf +$(foreach,i,a b c [$i]) +.fi +.sp +.RE +yields: +.RS +.sp +.nf +"b c [a]" +.fi +.sp +.RE +when evaluated. +.RE +.IP "$(\fBnil\fP \fBexpression\fP)" +Always returns the value of $(NULL) regardless of what \fIexpression\fP is. +This function macro can be used to discard results of expanding +macro expressions. +.IP "$(\fBnot\fP \fBmacroterm\fP)" +expands \fBmacroterm\fP and returs the string "t" if the result of the +expansion is the empty string; otherwise, it returns the empty string. +.IP "$(\fBnull\fP,\fItext\fP \fBtrue\fP \fBfalse\fP)" +expands the value of +.I text. +If it is NULL then the macro returns the value of the expansion of \fBtrue\fP +and the expansion of \fBfalse\fP otherwise. The terms \fBtrue\fP, and +\fBfalse\fP must be strings containing no white\-space. +.IP "$(\fB!null\fP,\fItext\fP \fBtrue\fP \fBfalse\fP)" +Behaves identically to the previous macro except that the +.B true +string is chosen if the expansion of +.I text +is not NULL. +.IP "$(\fBor\fP \fBmacroterm ...\fP)" +expands each \fBmacroterm\fP in turn and returs the empty string if +each term expands to the empty string; otherwise, it returs the string +"t". +.IP "$(\fBshell\fP \fBcommand\fP)" +Runs \fIcommand\fP as if it were part of a recipe and returns, +separated by a single space, all the non-white +space terms written to stdout by the command. +For example: +.RS +.RS +.sp +$(shell ls *.c) +.sp +.RE +will return \fI"a.c b.c c.c d.c"\fP if the files exist in the current +directory. The recipe modification flags \fB[+@%\-]\fP are honored if they +appear as the first characters in the command. For example: +.RS +.sp +$(shell +ls *.c) +.sp +.RE +will run the command using the current shell. +.RE +.IP "$(\fBshell,expand\fP \fBcommand\fP)" +Is an extension to the \fB$(shell...\fP function macro that expands the result +of running \fBcommand\fP. +.IP "$(\fBsort\fP \fBlist\fP)" +Will take all white\-space separated tokens in \fIlist\fP and will +return their sorted equivalent list. +.IP "$(\fBstrip\fP \fBdata\fP)" +Will replace all strings of white\-space in data by a single space. +.IP "$(\fBsubst\fP,\fIpat\fP,\fIreplacement\fP \fBdata\fP)" +Will search for \fIpat\fP in +.B data +and will replace any occurrence of +.I pat +with the +.I replacement +string. The expansion +.RS +.sp +$(subst,.o,.c $(OBJECTS)) +.sp +.RE +is equivalent to: +.RS +.sp +$(OBJECTS:s/.o/.c/) +.sp +.RE +.IP "$(\fBuniq\fP \fBlist\fP)" +Will take all white\-space separated tokens in \fIlist\fP and will +return their sorted equivalent list containing no duplicates. +.RE +.SH "CONDITIONAL MACROS" +.B dmake +supports conditional macros. These allow the definition of target specific +macro values. You can now say the following: +.RS +.sp +\fBtarget\fP ?= \fIMacroName MacroOp Value\fP +.sp +.RE +This creates a definition for \fIMacroName\fP whose value is \fIValue\fP +only when \fBtarget\fP is being made. You may use a conditional macro +assignment anywhere that a regular macro assignment may appear, including +as the value of a $(assign ...) macro. +.LP +The new definition is associated with the most recent cell definition +for \fBtarget\fP. If no prior definition exists then one is created. The +implications of this are immediately evident in the following example: +.sp +.RS +.nf +foo := hello +.sp +all : cond;@echo "all done, foo=[$(foo)] bar=[$(bar)]" +.sp +cond ?= bar := global decl +.sp +cond .SETDIR=unix::;@echo $(foo) $(bar) +cond ?= foo := hi +.sp +cond .SETDIR=msdos::;@echo $(foo) $(bar) + cond ?= foo := hihi +.fi +.RE +.sp +The first conditional assignment creates a binding for 'bar' that is +activated when 'cond' is made. The bindings following the :: definitions are +activated when their respective recipe rules are used. Thus the +first binding serves to provide a global value for 'bar' while any of the +cond :: rules are processed, and the local bindings for 'foo' come into +effect when their associated :: rule is processed. +.LP +Conditionals for targets of .UPDATEALL are all activated before the +target group is made. Assignments are processed in order. Note that +the value of a conditional macro assignment is NOT AVAILABLE until the +associated target is made, thus the construct +.sp +.RS +.nf +mytarget ?= bar := hello +mytarget ?= foo := $(bar) +.fi +.RE +.sp +results in $(foo) expanding to "", if you want the result to be "hello" +you must use: +.sp +.RS +.nf +mytarget ?= bar := hello +mytarget ?= foo = $(bar) +.fi +.RE +.sp +Once a target is made any associated conditional macros are deactivated +and their values are no longer available. Activation occurrs after all +inference, and .SETDIR directives have been processed and after $@ is +assigned, but before prerequisites are processed; thereby making the values of +conditional macro definitions available during construction of prerequisites. +.LP +If a %-meta rule target has associated conditional macro assignments, +and the rule is chosen by the inference algorithm then the conditional +macro assignments are inferred together with the associated recipe. +.SH "DYNAMIC PREREQUISITES" +.B dmake +looks for prerequisites whose names contain macro expansions during target +processing. Any such prerequisites are expanded and the result of the +expansion is used as the prerequisite name. As an example the line: +.sp +\tfred : $$@.c +.sp +causes the $$@ to be expanded when \fBdmake\fP is making fred, and it resolves +to the target \fIfred\fP. +This enables dynamic prerequisites to be generated. The value +of @ may be modified by any of the valid macro modifiers. So you can say for +example: +.sp +\tfred.out : $$(@:b).c +.sp +where the $$(@:b) expands to \fIfred\fP. +Note the use of $$ instead of $ to indicate the dynamic expansion, this +is due to the fact that the rule line is expanded when it is initially parsed, +and $$ then returns $ which later triggers the dynamic prerequisite expansion. +If you really want a $ to be part of a prerequisite name you must use $$$$. +Dynamic macro expansion is performed in all user defined rules, +and the special targets .SOURCE*, and .INCLUDEDIRS. +.PP +If dynamic macro expansion results in multiple white space separated tokens +then these are inserted into the prerequisite list inplace of the dynamic +prerequisite. If the new list contains additional dynamic prerequisites they +will be expanded when they are processed. The level of recursion in this +expansion is controlled by the value of the variable \fBDYNAMICNESTINGLEVEL\fP +and is set to 100 by default. +.SH "BINDING TARGETS" +This operation takes a target name and binds it to an existing file, if +possible. +.B dmake +makes a distinction between the internal target name of a target and its +associated external file name. +Thus it is possible for a target's internal name and its external +file name to differ. +To perform the binding, the following set of rules is used. +Assume that we are +trying to bind a target whose name is of the form \fIX.suff\fP, +where \fI.suff\fP is the suffix and \fIX\fP is the stem portion +(ie. that part which contains the directory and the basename). +.B dmake +takes this target name and performs a series of search operations that try to +find a suitably named file in the external file system. +The search operation is user controlled +via the settings of the various .SOURCE targets. +.RS +.IP 1. +If target has the .SYMBOL attribute set then look for it in the library. +If found, replace the target name with the library member name and continue +with step 2. If the name is not found then return. +.IP 2. +Extract the suffix portion (that following the `.') of the target name. +If the suffix is not null, look up the special target .SOURCE.<suff> +(<suff> is the suffix). +If the special target exists then search each directory given in +the .SOURCE.<suff> prerequisite list for the target. +If the target's suffix was null (ie. \fI.suff\fP was empty) then +perform the above search but use the special target .SOURCE.NULL instead. +If at any point a match is found then terminate the search. +If a directory in the prerequisite list is the special name `.NULL ' perform +a search for the full target name without prepending any directory portion +(ie. prepend the NULL directory). +.IP 3. +The search in step 2. failed. Repeat the same search but this time +use the special target .SOURCE. +(a default target of '.SOURCE : .NULL' is defined by \fBdmake\fP at startup, +and is user redefinable) +.IP 4. +The search in step 3. failed. +If the target has the library member attribute (.LIBMEMBER) +set then try to find the target in the library which was passed along +with the .LIBMEMBER attribute (see the MAKING LIBRARIES section). +The bound file name assigned to a target which is successfully +located in a library is the same name that would be assigned had the search +failed (see 5.). +.IP 5. +The search failed. Either the target was not found in any of the search +directories or no applicable .SOURCE special targets exist. +If applicable .SOURCE special targets exist, but the target was not found, +then \fBdmake\fP assigns the first name searched as the bound file name. +If no applicable .SOURCE special targets exist, +then the full original target name becomes the bound file name. +.RE +.PP +There is potential here for a lot of search operations. The trick is to +define .SOURCE.x special targets with short search lists and leave .SOURCE +as short as possible. +The search algorithm has the following useful side effect. +When a target having the .LIBMEMBER (library member) attribute is searched for, +it is first searched for as an ordinary file. +When a number of library members require updating it is desirable to compile +all of them first and to update the library at the end in a single operation. +If one of the members does not compile and \fBdmake\fP stops, then +the user may fix the error and make again. \fBdmake\fP will not remake any +of the targets whose object files have already been generated as long as +none of their prerequisite files have been modified as a result of the fix. +.PP +When \fBdmake\fP constructs target pathnames './' substrings are removed and +substrings of the form 'foo/..' are eliminated. This may result in somewhat +unexpected values of the macro expansion \fB$@\fP, but is infact the corect +result. +.PP +When defining .SOURCE and .SOURCE.x targets the construct +.RS +.sp +.SOURCE : +.br +.SOURCE : fred gery +.sp +.RE +is equivalent to +.RS +.sp +.SOURCE :\- fred gery +.RE +.PP +\fBdmake\fP correctly handles the UNIX Make variable VPATH. By definition VPATH +contains a list of ':' separated directories to search when looking for a +target. \fBdmake\fP maps VPATH to the following special rule: +.RS +.sp +.SOURCE :^ $(VPATH:s/:/ /) +.sp +.RE +Which takes the value of VPATH and sets .SOURCE to the same set of directories +as specified in VPATH. +.SH "PERCENT(%) RULES AND MAKING INFERENCES" +When \fBdmake\fP makes a target, the target's set of prerequisites (if any) +must exist and the target must have a recipe which \fBdmake\fP +can use to make it. +If the makefile does not specify an explicit recipe for the target then +.B dmake +uses special rules to try to infer a recipe which it can use +to make the target. Previous versions of Make perform this task by using +rules that are defined by targets of the form .<suffix>.<suffix> and by +using the .SUFFIXES list of suffixes. The exact workings of this mechanism +were sometimes difficult to understand and often limiting in their usefulness. +Instead, \fBdmake\fP supports the concept of \fI%-meta\fP rules. +The syntax and semantics of these rules differ from standard rule lines as +follows: +.sp +.nf +.RS +\fI<%-target>\fP [\fI<attributes>\fP] \fI<ruleop>\fP [\fI<%-prerequisites>\fP] [;\fI<recipe>\fP] +.RE +.fi +.sp +where \fI%-target\fP is a target containing exactly a single `%' sign, +.I attributes +is a list (possibly empty) of attributes, +.I ruleop +is the standard set of rule operators, +.I "%-prerequisites" +\&, if present, is a list of prerequisites containing zero or more `%' signs, +and +.I recipe, +if present, is the first line of the recipe. +.PP +The +.I %-target +defines a pattern against which a target whose recipe is +being inferred gets matched. The pattern match goes as follows: all chars are +matched exactly from left to right up to but not including the % sign in the +pattern, % then matches the longest string from the actual target name +not ending in +the suffix given after the % sign in the pattern. +Consider the following examples: +.RS +.sp +.nf +.Is "dir/%.c " +.Ii "%.c" +matches fred.c but not joe.c.Z +.Ii "dir/%.c" +matches dir/fred.c but not dd/fred.c +.Ii "fred/%" +matches fred/joe.c but not f/joe.c +.Ii "%" +matches anything +.fi +.sp +.RE +In each case the part of the target name that matched the % sign is retained +and is substituted for any % signs in the prerequisite list of the %-meta rule +when the rule is selected during inference and +.B dmake +constructs the new dependency. +As an example the following %-meta rules describe the following: +.RS +.sp +%.c : %.y ; recipe... +.sp +.RE +describes how to make any file ending in .c if a corresponding file ending +in .y can be found. +.RS +.sp +foo%.o : fee%.k ; recipe... +.sp +.RE +is used to describe how to make fooxxxx.o from feexxxx.k. +.RS +.sp +%.a :; recipe... +.sp +.RE +describes how to make a file whose suffix is .a without inferring any +prerequisites. +.RS +.sp +%.c : %.y yaccsrc/%.y ; recipe... +.sp +.RE +is a short form for the construct: +.RS +.sp +%.c : %.y ; recipe... +.br +%.c : yaccsrc/%.y ; recipe... +.sp +.RE +ie. It is possible to specify the same recipe for two %-rules by giving +more than one prerequisite in the prerequisite list. +A more interesting example is: +.RS +.sp +% : RCS/%,v ; co $< +.sp +.RE +which describes how to take any target and check it out of +the RCS directory if the corresponding file exists in the RCS directory. +The equivalent SCCS rule would be: +.RS +.sp +% : s.% ; get $< +.sp +.RE +.PP +The previous RCS example defines an infinite rule, because it says how to make +.I anything +from RCS/%,v, and +.I anything +also includes RCS/fred.c,v. +To limit the size of the graph that results from such rules +.B dmake +uses the macro variable PREP (stands for % repetition). By default the value +of this variable is 0, which says that no repetitions of a %-rule are to be +generated. If it is set to something greater than 0, then that many +repetitions of any infinite %-rule are allowed. If in the above +example PREP was set to 1, then \fBdmake\fP would generate the dependency +graph: +.RS +.sp +% --> RCS/%,v --> RCS/RCS/%,v,v +.sp +.RE +Where each link is assigned the same recipe as the first link. +PREP should be used only in special cases, since it may result in +a large increase in the number of possible prerequisites tested. +.B dmake +further assumes that any target that has no suffix can be made from +a prerequisite that has at least one suffix. +.PP +.B dmake +supports dynamic prerequisite generation for prerequisites of %-meta rules. +This is best illustrated by an example. The RCS rule shown above can infer +how to check out a file from a corresponding RCS file only if the target +is a simple file name with no directory information. That is, the above rule +can infer how to find \fIRCS/fred.c,v\fP from the target \fIfred.c\fP, +but cannot infer how to find \fIsrcdir/RCS/fred.c,v\fP from \fIsrcdir/fred.c\fP +because the above rule will cause \fBdmake\fP to look for RCS/srcdir/fred.c,v; +which does not exist (assume that srcdir has its own RCS directory as is the +common case). +.PP +A more versatile formulation of the above RCS check out rule is the following: +.RS +.sp +% : $$(@:d)RCS/$$(@:f),v : co $@ +.sp +.RE +This rule uses the dynamic macro $@ to specify the prerequisite to try to +infer. During inference of this rule the macro $@ is set to the value of +the target of the %-meta rule and the appropriate prerequisite is generated by +extracting the directory portion of the target name (if any), appending the +string \fIRCS/\fP to it, and appending the target file name with a trailing +\fI,v\fP attached to the previous result. +.PP +.B dmake +can also infer indirect prerequisites. +An inferred target can have a list of prerequisites added that will not +show up in the value of $< but will show up in the value of $? and $&. +Indirect prerequisites are specified in an inference rule by quoting the +prerequisite with single quotes. For example, if you had the explicit +dependency: +.RS +.sp +.nf +fred.o : fred.c ; rule to make fred.o +fred.o : local.h +.fi +.sp +.RE +then this can be inferred for fred.o from the following inference rule: +.RS +.sp +%.o : %.c 'local.h' ; makes a .o from a .c +.sp +.RE +You may infer indirect prerequisites that are a function of the value of '%' +in the current rule. The meta-rule: +.RS +.sp +%.o : %.c '$(INC)/%.h' ; rule to make a .o from a .c +.sp +.RE +infers an indirect prerequisite found in the INC directory whose name is the +same as the expansion of $(INC), and the prerequisite name depends on the +base name of the current target. +The set of indirect prerequisites is attached to the meta rule in which they +are specified and are inferred only if the rule is used to infer a recipe +for a target. They do not play an active role in driving the inference +algorithm. +The construct: +.RS +.sp +%.o : %.c %.f 'local.h'; recipe +.sp +.RE +is equivalent to: +.RS +.sp +.nf +%.o : %.c 'local.h' : recipe +.fi +.sp +.RE +while: +.RS +.sp +%.o :| %.c %.f 'local.h'; recipe +.sp +.RE +is equivalent to: +.RS +.sp +.nf +%.o : %.c 'local.h' : recipe +%.o : %.f 'local.h' : recipe +.fi +.sp +.RE +.PP +If any of the attributes .SETDIR, .EPILOG, .PROLOG, .SILENT, +\&.USESHELL, .SWAP, .PRECIOUS, .LIBRARY, .NOSTATE and .IGNORE +are given for a %-rule then when that rule is bound to a target +as the result of an inference, the target's set of attributes is augmented by +the attributes from the above set that are specified in the bound %-rule. +Other attributes specified for %-meta rules are not inherited by the target. +The .SETDIR attribute is treated in a special way. +If the target already had a .SETDIR attribute set then +.B dmake +changes to that directory prior to performing the inference. +During inference any .SETDIR attributes for the inferred prerequisite +are honored. +The directories must exist for a %-meta rule to be selected as a possible +inference path. If the directories do not exist no error message is issued, +instead the corresponding path in the inference graph is rejected. +.PP +.B dmake +also supports the old format special target .<suffix>.<suffix> +by identifying any rules +of this form and mapping them to the appropriate %-rule. So for example if +an old makefile contains the construct: +.RS +.sp +\&.c.o :; cc \-c $< \-o $@ +.sp +.RE +.B dmake +maps this into the following %-rule: +.RS +.sp +%.o : %.c; cc \-c $< \-o $@ +.sp +.RE +Furthermore, +.B dmake +understands several SYSV AUGMAKE special targets and maps them into +corresponding %-meta rules. These transformation must be enabled by providing +the \-A flag on the command line or by setting the value of AUGMAKE to +non\-NULL. +The construct +.RS +.sp +\&.suff :; recipe +.sp +.RE +gets mapped into: +.RS +.sp +% : %.suff; recipe +.sp +.RE +and the construct +.RS +.sp +\&.c~.o :; recipe +.sp +.RE +gets mapped into: +.RS +.sp +%.o : s.%.c ; recipe +.sp +.RE +In general, a special target of the form .<str>~ is replaced by the %-rule +construct s.%.<str>, thereby providing support for the syntax used by SYSV +AUGMAKE for providing SCCS support. +When enabled, these mappings allow processing of existing SYSV +makefiles without modifications. +.PP +.B dmake +bases all of its inferences on the inference graph constructed from the +%-rules defined in the makefile. +It knows exactly which targets can be made from which prerequisites by +making queries on the inference graph. For this reason .SUFFIXES is not +needed and is completely ignored. +.PP +For a %-meta rule to be inferred as the +rule whose recipe will be used to make a target, the target's name must match +the %-target pattern, and any inferred %-prerequisite must already exist or +have an explicit recipe so that the prerequisite can be made. +Without \fItransitive closure\fP on the inference graph the above rule +describes precisely when an inference match terminates the search. +If transitive closure is enabled (the usual case), and a prerequisite does +not exist or cannot be made, then +.B dmake +invokes the inference algorithm recursively on the prerequisite to see if +there is some way the prerequisite can be manufactured. For, if the +prerequisite can be made then the current target can also be made using the +current %-meta rule. +This means that there is no longer a need to give a rule +for making a .o from a .y if you have already given a rule for making a .o +from a .c and a .c from a .y. In such cases +.B dmake +can infer how to make the +\&.o from the .y via the intermediary .c and will remove the .c when the .o is +made. Transitive closure can be disabled by giving the \-T switch on the +command line. +.PP +A word of caution. +.B dmake +bases its transitive closure on the %-meta rule targets. +When it performs transitive closure it infers how to make a target from a +prerequisite by performing a pattern match as if the potential prerequisite +were a new target. +The set of rules: +.RS +.nf +.sp +%.o : %.c :; rule for making .o from .c +%.c : %.y :; rule for making .c from .y +% : RCS/%,v :; check out of RCS file +.fi +.sp +.RE +will, by performing transitive closure, allow \fBdmake\fP to infer how to make +a .o from a .y using a .c as an intermediate temporary file. Additionally +it will be able to infer how to make a .y from an RCS file, as long as that +RCS file is in the RCS directory and has a name which ends in .y,v. +The transitivity computation is performed dynamically for each target that +does not have a recipe. This has potential to be costly if the %-meta +rules are not carefully specified. The .NOINFER attribute is used to mark +a %-meta node as being a final target during inference. Any node with this +attribute set will not be used for subsequent inferences. As an example +the node RCS/%,v is marked as a final node since we know that if the RCS file +does not exist there likely is no other way to make it. Thus the standard +startup makefile contains an entry similar to: +.RS +.nf +\&.NOINFER : RCS/%,v +.fi +.RE +Thereby indicating that the RCS file is the end of the inference chain. +Whenever the inference algorithm determines that a target can be made from +more than one prerequisite and the inference chains for the two methods +are the same length the algorithm reports an ambiguity and prints the +ambiguous inference chains. +.PP +.B dmake +tries to +remove intermediate files resulting from transitive closure if the file +is not marked as being PRECIOUS, or the \fB\-u\fP flag was not given on the +command line, and if the inferred intermediate did not previously exist. +Intermediate targets that existed prior to being made are never removed. +This is in keeping with the philosophy that +.B dmake +should never remove things from the file system that it did not add. +If the special target .REMOVE is defined and has a recipe then +.B dmake +constructs a list of the intermediate files to be removed and makes them +prerequisites of .REMOVE. It then makes .REMOVE thereby removing the +prerequisites if the recipe of .REMOVE says to. Typically .REMOVE is defined +in the startup file as: +.RS +.sp +\&.REMOVE :; $(RM) $< +.RE +.SH "MAKING TARGETS" +In order to update a target \fBdmake\fP must execute a recipe. +When a recipe needs to be executed it is first expanded so that any macros +in the recipe text are expanded, and it is then either executed directly or +passed to a shell. +.B dmake +supports two types of recipes. The regular recipes and group recipes. +.PP +When a regular recipe is invoked \fBdmake\fP executes each line of the recipe +separately using a new copy of a shell if a shell is required. +Thus effects of commands do not generally persist across recipe lines +(e.g. cd requests in a recipe line do not carry over to the next recipe line). +This is true even in environments such as \fBMSDOS\fP, where dmake internally +sets the current working director to match the directory it was in before +the command was executed. +.PP +The decision on whether a shell is required to execute a command is based on +the value of the macro SHELLMETAS or on the specification of '+' or .USESHELL +for the current recipe or target respectively. +If any character in the value of +SHELLMETAS is found in the expanded recipe text-line or the use of a shell +is requested explicitly via '+' or .USESHELL then the command is +executed using a shell, otherwise the command is executed directly. +The shell that is used for execution is given by the value of the macro SHELL. +The flags that are passed to the shell are given by the value of SHELLFLAGS. +Thus \fBdmake\fP constructs the command line: +.sp +\t$(SHELL) $(SHELLFLAGS) $(expanded_recipe_command) +.sp +Normally +.B dmake +writes the command line that it is about to invoke to standard output. +If the .SILENT attribute is set for the target or for +the recipe line (via @), then the recipe line is not echoed. +.PP +Group recipe processing is similar to that of regular recipes, except that +a shell is always invoked. The shell that is invoked is given by the value of +the macro GROUPSHELL, and its flags are taken from the value of the macro +GROUPFLAGS. If a target has the .PROLOG attribute set then +.B dmake +prepends to the shell script the recipe associated with the special target +\&.GROUPPROLOG, and if the attribute .EPILOG is set as well, then the recipe +associated with the special target .GROUPEPILOG is appended to the script +file. +This facility can be used to always prepend a common header and common trailer +to group recipes. +Group recipes are echoed to standard output just like standard recipes, but +are enclosed by lines beginning with [ and ]. +.PP +The recipe flags [+,\-,%,@] are recognized at the start of a recipe line +even if they appear in a macro. For example: +.RS +.sp +.nf +SH = + +all: +\t$(SH)echo hi +.fi +.sp +.RE +is completely equivalent to writing +.RS +.sp +.nf +SH = + +all: +\t+echo hi +.fi +.sp +.RE +.PP +The last step performed by +.B dmake +prior to running a recipe is to set the macro CMNDNAME to the name of the +command to execute (determined by finding the first white\-space ending token +in the command line). It then sets the macro CMNDARGS to be the remainder +of the line. +.B dmake +then expands the macro COMMAND which by default is set to +.RS +.sp +COMMAND = $(CMNDNAME) $(CMNDARGS) +.sp +.RE +The result of this final expansion is the command that will be executed. +The reason for this expansion is to allow for a different interface to +the argument passing facilities (esp. under DOS) than that provided by +.B dmake\fR.\fP +You can for example define COMMAND to be +.RS +.sp +COMMAND = $(CMNDNAME) @$(mktmp $(CMNDARGS)) +.sp +.RE +which dumps the arguments into a temporary file and runs the command +.RS +.sp +$(CMNDNAME) @/tmp/ASAD23043 +.sp +.RE +which has a much shorter argument list. It is now up to the command to +use the supplied argument as the source for all other arguments. +As an optimization, if COMMAND is not defined +.B dmake +does not perform the above expansion. On systems, such as UNIX, that +handle long command lines this provides a slight saving in processing the +makefiles. +.SH "MAKING LIBRARIES" +Libraries are easy to maintain using \fBdmake\fP. A library is a file +containing a collection of object files. +Thus to make a library you simply specify it as a target with the .LIBRARY +attribute set and specify its list of prerequisites. The prerequisites should +be the object members that are to go into the library. When +.B dmake +makes the library target it uses the .LIBRARY attribute to pass to the +prerequisites the .LIBMEMBER attribute and the name of the library. This +enables the file binding mechanism to look for the member in the library if an +appropriate object file cannot be found. +.B dmake +now supports \fBElf\fP libraries on systems that support \fBElf\fP and +hence supports, on those systems, long member file names. +A small example best illustrates this. +.RS +.nf +.sp +mylib.a .LIBRARY : mem1.o mem2.o mem3.o +\trules for making library... +\t# remember to remove .o's when lib is made +.sp +# equivalent to: '%.o : %.c ; ...' +\&.c.o :; rules for making .o from .c say +.sp +.fi +.RE +.B dmake +will use the .c.o rule for making the library members if appropriate .c files +can be found using the search rules. NOTE: this is not specific in any way +to C programs, they are simply used as an example. +.PP +.B dmake +tries to handle the old library construct format in a sensible way. +The construct +.I lib(member.o) +is separated and the \fIlib\fP portion is declared +as a library target. +The new target is defined +with the .LIBRARY attribute set and the \fImember.o\fP portion of the +construct is +declared as a prerequisite of the lib target. +If the construct \fIlib(member.o)\fP +appears as a prerequisite of a target in the +makefile, that target has the new name of the lib assigned as its +prerequisite. Thus the following example: +.RS +.sp +.nf +a.out : ml.a(a.o) ml.a(b.o); $(CC) \-o $@ $< + +\&.c.o :; $(CC) \-c $(CFLAGS) \-o $@ $< +%.a: +.RS +ar rv $@ $? +ranlib $@ +rm \-rf $? +.RE +.sp +.fi +.RE +constructs the following dependency +graph. +.RS +.sp +.nf +a.out : ml.a; $(CC) \-o $@ $< +ml.a .LIBRARY : a.o b.o + +%.o : %.c ; $(CC) -c $(CFLAGS) \-o $@ $< +%.a : +.RS +ar rv $@ $? +ranlib $@ +rm -rf $? +.RE +.sp +.fi +.RE +and making a.out then works as expected. +.PP +The same thing happens for any target of the form \fIlib((entry))\fP. +These targets have an +additional feature in that the \fIentry\fP target has the .SYMBOL attribute +set automatically. +.PP +NOTE: If the notion of entry points is supported by the archive and by +\fBdmake\fP (currently not the case) then +.B dmake +will search the archive for the entry point and return not only the +modification time of the member which defines the entry but also the name of +the member file. This name will then replace \fIentry\fP and will be used for +making the member file. Once bound to an archive member the .SYMBOL +attribute is removed from the target. +This feature is presently disabled as there is little standardization +among archive formats, and we have yet to find a makefile utilizing this +feature (possibly due to the fact that it is unimplemented in most versions +of UNIX Make). +.PP +Finally, when +.B dmake +looks for a library member it must first locate the library file. +It does so by first looking for the library relative to the current directory +and if it is not found it then looks relative to the current value of +$(TMD). This allows commonly used libraries to be kept near the root of +a source tree and to be easily found by +.B dmake\fR.\fP +.SH "KEEP STATE" +.B dmake +supports the keeping of state information for targets that it makes whenever +the macro .KEEP_STATE is assigned a value. The value of the macro should be +the name of a state file that will contain the state information. If state +keeping is enabled then each target that does not poses the .NOSTATE +attribute will have a record written into the state file indicating the +target's name, the current directory, the command used to update the target, +and which, if any, :: rule is being used. When you make this target again +if any of this information does not match the previous settings and the +target is not out dated it will still be re\-made. The assumption is that one +of the conditions above has changed and that we wish to remake the target. +For example, +state keeping is used in the maintenance of +.B dmake +to test compile different versions of the source using different compilers. +Changing the compiler causes the compilation flags to be modified and hence +all sources to be recompiled. +.PP +The state file is an ascii file and is portable, however it is +not in human readable form as the entries represent hash keys of the above +information. +.PP +The Sun Microsystem's Make construct +.RS +.sp +\&.KEEP_STATE : +.sp +.RE +is recognized and is mapped to \fB.KEEP_STATE:=_state.mk\fP. +The +.B dmake +version of state keeping does not include scanning C source files for +dependencies like Sun Make. This is specific to C programs and it was +felt that it does not belong in make. +.B dmake +instead provides the tool, \fBcdepend\fP, to scan C source files and to produce +depedency information. Users are free to modify cdepend to produce other +dependency files. (NOTE: +.B cdepend +does not come with the distribution at this time, but will be available in +a patch in the near future) +.SH "MULTI PROCESSING" +If the architecture supports it then \fBdmake\fP is capable of making a target's +prerequisites in parallel. \fBdmake\fP will make as much in parallel as it +can and use a number of child processes up to the maximum specified by +MAXPROCESS or by the value supplied to the \-P command line flag. +A parallel make is enabled by setting the value of MAXPROCESS (either directly +or via \-P option) to a value which is > 1. +\fBdmake\fP guarantees that all dependencies as specified in the makefile are +honored. A target will not be made until all of its prerequisites have been +made. Note that when you specify \fB-P 4\fP then four child processes are +run concurrently but \fBdmake\fP actually displays the fifth command it will +run immediately upon a child process becomming free. This is an artifact of +the method used to traverse the dependency graph and cannot be removed. +If a parallel make is being performed then the following restrictions on +parallelism are enforced. +.RS +.IP 1. +Individual recipe lines in a non-group recipe are performed sequentially in +the order in which they are specified within the makefile and in parallel with +the recipes of other targets. +.IP 2. +If a target contains multiple recipe definitions (cf. :: rules) then these are +performed sequentially in the order in which the :: rules are specified within +the makefile and in parallel with the recipes of other targets. +.IP 3. +If a target rule contains the `!' modifier, then the recipe is performed +sequentially for the list of outdated prerequisites and in parallel with the recipes of other targets. +.IP 4. +If a target has the .SEQUENTIAL attribute set then all of its prerequisites +are made sequentially relative to one another (as if MAXPROCESS=1), but in +parallel with other targets in the makefile. +.RE +.PP +Note: If you specify a parallel make then +the order of target update and the order in which the associated recipes are +invoked will not correspond to that displayed by the \-n flag. +.SH "CONDITIONALS" +.B dmake +supports a makefile construct called a \fIconditional\fR. It allows +the user +to conditionally select portions of makefile text for input processing +and to discard other portions. This becomes useful for +writing makefiles that are intended to function for more than one target +host and environment. The conditional expression is specified as follows: +.sp +.RS +.nf +\&.IF \fIexpression\fR + ... if text ... +\&.ELIF \fIexpression\fR + ... if text ... +\&.ELSE + ... else text ... +\&.END +.RE +.fi +.sp +The .ELSE and .ELIF portions are optional, and the conditionals may be +nested (ie. the text may contain another conditional). +\&.IF, .ELSE, and .END +may appear anywhere in the makefile, but a single conditional expression +may not span multiple makefiles. +.PP +\fIexpression\fR can be one of the following three forms: +.sp +\t<text> | <text> == <text> | <text> != <text> +.sp +where \fItext\fR is either text or a macro expression. In any case, +before the comparison is made, the expression is expanded. The text +portions are then selected and compared. White space at the start and +end of the text portion is discarded before the comparison. This means +that a macro that evaluates to nothing but white space is considered a +NULL value for the purpose of the comparison. +In the first case the expression evaluates TRUE if the text is not NULL +otherwise it evaluates FALSE. The remaining two cases both evaluate the +expression on the basis of a string comparison. +If a macro expression needs to be equated to a NULL string then compare it to +the value of the macro $(NULL). +You can use the $(shell ...) macro to construct more complex test expressions. +.SH "EXAMPLES" +.RS +.nf +.sp +# A simple example showing how to use make +# +prgm : a.o b.o + cc a.o b.o \-o prgm +a.o : a.c g.h + cc a.c \-o $@ +b.o : b.c g.h + cc b.c \-o $@ +.fi +.RE +.sp +In the previous +example prgm is remade only if a.o and/or b.o is out of date with +respect to prgm. +These dependencies can be stated more concisely +by using the inference rules defined in the standard startup file. +The default rule for making .o's from .c's looks something like this: +.sp +\&\t%.o : %.c; cc \-c $(CFLAGS) \-o $@ $< +.sp +Since there exists a rule (defined in the startup file) +for making .o's from .c's +\fBdmake\fR will use that rule +for manufacturing a .o from a .c and we can specify our dependencies +more concisely. +.sp +.RS +.nf +prgm : a.o b.o + cc \-o prgm $< +a.o b.o : g.h +.fi +.RE +.sp +A more general way to say the above using the new macro expansions +would be: +.sp +.RS +.nf +SRC = a b +OBJ = {$(SRC)}.o +.sp +prgm : $(OBJ) + cc \-o $@ $< +.sp +$(OBJ) : g.h +.fi +.RE +.sp +If we want to keep the objects in a separate directory, called +objdir, then we would write +something like this. +.sp +.RS +.nf +SRC = a b +OBJ = {$(SRC)}.o +.sp +prgm : $(OBJ) + cc $< \-o $@ +.sp +$(OBJ) : g.h +\&%.o : %.c + $(CC) \-c $(CFLAGS) \-o $(@:f) $< + mv $(@:f) objdir + +\&.SOURCE.o : objdir # tell dmake to look here for .o's +.fi +.RE +.sp +An example of building library members would go something like this: +(NOTE: The same rules as above will be used to produce .o's from .c's) +.sp +.RS +.nf +SRC\t= a b +LIB\t= lib +LIBm\t= { $(SRC) }.o +.sp +prgm: $(LIB) + cc \-o $@ $(LIB) +.sp +$(LIB) .LIBRARY : $(LIBm) + ar rv $@ $< + rm $< +.fi +.RE +.sp +Finally, suppose that each of the source files in the previous example had +the `:' character in their target name. Then we would write the above example +as: +.sp +.RS +.nf +SRC\t= f:a f:b +LIB\t= lib +LIBm\t= "{ $(SRC) }.o" # put quotes around each token +.sp +prgm: $(LIB) + cc \-o $@ $(LIB) +.sp +$(LIB) .LIBRARY : $(LIBm) + ar rv $@ $< + rm $< +.fi +.RE +.SH "COMPATIBILITY" +There are two notable differences between +.B \fBdmake\fR +and the standard version of BSD UNIX 4.2/4.3 Make. +.RS +.IP 1. .3i +BSD UNIX 4.2/4.3 Make supports wild card filename expansion for +prerequisite names. Thus if a directory contains a.h, b.h and c.h, then a +line like +.sp +\ttarget: *.h +.sp +will cause UNIX make to expand the *.h into "a.h b.h c.h". \fBdmake\fR +does not support this type of filename expansion. +.IP 2. .3i +Unlike UNIX make, touching a library member causes \fBdmake\fR +to search the library for the member name and to update the library time stamp. +This is only implemented in the UNIX version. +MSDOS and other versions may not have librarians that keep file time stamps, +as a result \fBdmake\fR touches the library file itself, and prints a warning. +.RE +.PP +\fBdmake\fP is not compatible with GNU Make. In particular it does not +understand GNU Make's macro expansions that query the file system. +.PP +.B dmake +is fully compatible with SYSV AUGMAKE, and supports the following AUGMAKE +features: +.RS +.IP 1. .3i +GNU Make style \fBinclude\fP, and \fBif/else/endif\fP directives are allowed +in non-group recipes. +Thus, the word \fBinclude\fP appearing at +the start of a line that is not part of a gruop recipe will be mapped +to the ".INCLUDE" directive that \fBdamke\fP uses. +Similarly, the words \fBifeq\fP,\fBifneq\fP,\fBelif\fP,\fBelse\fP, +and \fBendif\fP are mapped to their corresponding \fBdmake\fP equivalents. +.IP 2. .3i +The macro modifier expression $(macro:str=sub) is understood and is equivalent +to the expression $(macro:s/str/sub), with the restriction that str must match +the following regular expression: +.sp +\tstr[ |\et][ |\et]* +.sp +(ie. str only matches at the end of a token where str is a suffix and is +terminated by a space, a tab, or end of line) +Normally \fIsub\fP is expanded before the substitution is made, if you specify +\-A on the command line then sub is not expanded. +.IP 3. +The macro % is defined to be $@ (ie. $% expands to the same value as $@). +.IP 4. +The AUGMAKE notion of libraries is handled correctly. +.IP 5. +When defining special targets for the inference rules and the AUGMAKE special +target handling is enabled then the special target +\&.X is equivalent to the %-rule "% : %.X". +.IP 6. +Directories are always made if you specify \fB\-A\fP. This is consistent +with other UNIX versions of Make. +.IP 7. +Makefiles that utilize virtual targets to force making of other targets work +as expected if AUGMAKE special target handling is enabled. For example: +.sp +.nf +\tFRC: +\tmyprog.o : myprog.c $(FRC) ; ... +.fi +.sp +Works as expected if you issue the command +.sp +\t'\fBdmake\fP \-A FRC=FRC' +.sp +but fails with a 'don't know how to make FRC' +error message if you do not specify AUGMAKE special target handling via +the \-A flag (or by setting AUGMAKE:=yes internally). +.IP 8. +The \fBMSDOS\fP version of \fBdmake\fP now supports a single buitin runtime +command \fBnoop\fP, which returns success if requested and does nothing. +.RE +.SH "LIMITS" +In some environments the length of an argument string is restricted. +(e.g. MSDOS command line arguments cannot be longer than 128 bytes if you are +using the standard command.com command interpreter as your shell, +.B dmake +text diversions may help in these situations.) +.SH "PORTABILITY" +To write makefiles that can be moved from one environment to another requires +some forethought. In particular you must define as macros all those things +that may be different in the new environment. +.B dmake +has two facilities that help to support writing portable makefiles, recursive +macros and conditional expressions. The recursive macros, allow one to define +environment configurations that allow different environments for similar types +of operating systems. For example the same make script can be used for SYSV and +BSD but with different macro definitions. +.PP +To write a makefile that is portable between UNIX and MSDOS requires both +features since in almost all cases you will need to define new recipes for +making targets. The recipes will probably be quite different since the +capabilities of the tools on each machine are different. Different +macros will be needed to help handle the smaller differences in the two +environments. +.SH FILES +Makefile, makefile, startup.mk (use dmake \-V to tell you where the startup +file is) +.SH "SEE ALSO" +sh(1), csh(1), touch(1), f77(1), pc(1), cc(1) +.br +S.I. Feldman \fIMake - A Program for Maintaining Computer Programs\fP +.SH "AUTHOR" +Dennis Vadura, dvadura@wticorp.com +.br +Many thanks to Carl Seger for his helpful suggestions, +and to Trevor John Thompson for his many excellent ideas and +informative bug reports. Many thanks also go to those on the +NET that have helped in making \fBdmake\fP one of the best Make tools +available. +.SH BUGS +Some system commands return non-zero status inappropriately. +Use +.B \-i +(`\-' within the makefile) to overcome the difficulty. +.PP +Some systems do not have easily accessible +time stamps for library members (MSDOS, AMIGA, etc) +for these \fBdmake\fR uses the time stamp of the library instead and prints +a warning the first time it does so. This is almost always ok, except when +multiple makefiles update a single library file. In these instances it is +possible to miss an update if one is not careful. +.PP +This man page is way too long. +.SH WARNINGS +Rules supported by make(1) may not work if transitive closure is turned off +(-T, .NOINFER). +.PP +PWD from csh/ksh will cause problems if a cd operation is performed and +-e or -E option is used. +.PP +Using internal macros such as COMMAND, may wreak havoc if you don't understand +their functionality. diff --git a/dmake/man/readme b/dmake/man/readme new file mode 100644 index 000000000000..f9fc689e6076 --- /dev/null +++ b/dmake/man/readme @@ -0,0 +1,26 @@ +This directory contains the DMAKE manual page. The typeset version of the +manual is compressed and uuencoded as this is the only reasonable method of +shipping the control-character filled manpage around. + +To unpack the typeset manual page please issue the following sequence of +commands: + + uudecode dmake.uue + uncompress dmake.Z + mv dmake dmake.p + +NOTE: You only need to do this if you cannot typeset the manual page + yourself. + +The other two files found here are: + + dmake.tf - troff source for the manual page, you must use + GNU groff to typeset it. + dmake.nc - a typeset version of the manual page containing + no control characters. + +Alternately visit the dmake WWW site, at + + http://www.wticorp.com/dmake/dmake.html + +Dennis diff --git a/dmake/msdos/arlib.c b/dmake/msdos/arlib.c new file mode 100644 index 000000000000..ecd556b7d621 --- /dev/null +++ b/dmake/msdos/arlib.c @@ -0,0 +1,56 @@ +/* RCS $Id: arlib.c,v 1.1.1.1 2000-09-22 15:33:27 hr Exp $ +-- +-- SYNOPSIS +-- Library access code. +-- +-- DESCRIPTION +-- This implementation uses the library timestamp inplace of the +-- library member timestamp. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include "extern.h" + +PUBLIC time_t +seek_arch(name, lib) +char* name; +char* lib; +{ + static int warned = FALSE; + + if (!warned && !(Glob_attr&A_SILENT)) + warned = TRUE, + Warning("Can't extract library member timestamp;\n\ + using library timestamp instead."); + return (Do_stat(lib, NULL, NULL, TRUE)); +} + +PUBLIC int +touch_arch(name, lib) +char* name; +char* lib; +{ + static int warned = FALSE; + + if (!warned && !(Glob_attr&A_SILENT)) + warned = TRUE, + Warning("Can't update library member timestamp;\n\ + touching library instead."); + return (Do_touch(lib, NULL, NULL)); +} + diff --git a/dmake/msdos/borland/bcc30/config.h b/dmake/msdos/borland/bcc30/config.h new file mode 100644 index 000000000000..8e02779edd75 --- /dev/null +++ b/dmake/msdos/borland/bcc30/config.h @@ -0,0 +1,48 @@ +/* RCS $Id: config.h,v 1.1.1.1 2000-09-22 15:33:28 hr Exp $ +-- +-- SYNOPSIS +-- Configurarion include file. +-- +-- DESCRIPTION +-- There is one of these for each specific machine configuration. +-- It can be used to further tweek the machine specific sources +-- so that they compile. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +/* define this for configurations that don't have the coreleft function + * so that the code compiles. To my knowledge coreleft exists only on + * Turbo C, but it is needed here since the function is used in many debug + * macros. */ +/*#define coreleft() 0L*/ +extern unsigned int coreleft(); + +#define SIGQUIT SIGTERM /* turbo C doesn't understand SIGQUIT */ + +/* Turbo-C understands const declarations. */ +#define CONST const + +#ifndef MSDOS +# define MSDOS 1 +#endif + +/* a small problem with pointer to voids on some unix machines needs this */ +#define PVOID void * + +/* Have to pull this in for the standard lib defines */ +#include <io.h> diff --git a/dmake/msdos/borland/bcc30/config.mk b/dmake/msdos/borland/bcc30/config.mk new file mode 100644 index 000000000000..0b1d122a868c --- /dev/null +++ b/dmake/msdos/borland/bcc30/config.mk @@ -0,0 +1,8 @@ + +# Definition of macros for library, and C startup code. +osedir = $(osrdir)$(DIRSEPSTR)$(OSENVIRONMENT) + +LDLIBS = e:/cc/borland/bcc30/lib/c$(MODEL) +CSTARTUP = e:/cc/borland/bcc30/lib/c0$(MODEL).obj + +CFLAGS += -I$(osedir) -w-pia diff --git a/dmake/msdos/borland/bcc30/lib.rsp b/dmake/msdos/borland/bcc30/lib.rsp new file mode 100644 index 000000000000..41e591347bae --- /dev/null +++ b/dmake/msdos/borland/bcc30/lib.rsp @@ -0,0 +1 @@ +d:\cc\borland\bcc30\lib\cl diff --git a/dmake/msdos/borland/bcc30/libswp.rsp b/dmake/msdos/borland/bcc30/libswp.rsp new file mode 100644 index 000000000000..64f053bf1fb1 --- /dev/null +++ b/dmake/msdos/borland/bcc30/libswp.rsp @@ -0,0 +1 @@ +e:\cc\borland\bcc30\lib\cl diff --git a/dmake/msdos/borland/bcc30/mkswp.bat b/dmake/msdos/borland/bcc30/mkswp.bat new file mode 100755 index 000000000000..9266d8dfc0cd --- /dev/null +++ b/dmake/msdos/borland/bcc30/mkswp.bat @@ -0,0 +1,107 @@ +md objects +tasm -t -mx -dmlarge msdos\exec.asm,,,; +mv exec.obj objects +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc30 -w-pia infer.c +copy infer.obj objects +del infer.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc30 -w-pia make.c +copy make.obj objects +del make.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc30 -w-pia stat.c +copy stat.obj objects +del stat.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc30 -w-pia expand.c +copy expand.obj objects +del expand.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc30 -w-pia dmstring.c +copy dmstring.obj objects +del dmstring.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc30 -w-pia hash.c +copy hash.obj objects +del hash.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc30 -w-pia dag.c +copy dag.obj objects +del dag.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc30 -w-pia dmake.c +copy dmake.obj objects +del dmake.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc30 -w-pia path.c +copy path.obj objects +del path.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc30 -w-pia imacs.c +copy imacs.obj objects +del imacs.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc30 -w-pia sysintf.c +copy sysintf.obj objects +del sysintf.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc30 -w-pia parse.c +copy parse.obj objects +del parse.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc30 -w-pia getinp.c +copy getinp.obj objects +del getinp.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc30 -w-pia quit.c +copy quit.obj objects +del quit.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc30 -w-pia state.c +copy state.obj objects +del state.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc30 -w-pia dmdump.c +copy dmdump.obj objects +del dmdump.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc30 -w-pia macparse.c +copy macparse.obj objects +del macparse.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc30 -w-pia rulparse.c +copy rulparse.obj objects +del rulparse.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc30 -w-pia percent.c +copy percent.obj objects +del percent.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc30 -w-pia function.c +copy function.obj objects +del function.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc30 -w-pia msdos\ruletab.c +copy ruletab.obj objects +del ruletab.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc30 -w-pia msdos\dirbrk.c +copy dirbrk.obj objects +del dirbrk.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc30 -w-pia msdos\runargv.c +copy runargv.obj objects +del runargv.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc30 -w-pia msdos\arlib.c +copy arlib.obj objects +del arlib.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc30 -w-pia msdos\dchdir.c +copy dchdir.obj objects +del dchdir.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc30 -w-pia msdos\switchar.c +copy switchar.obj objects +del switchar.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc30 -w-pia msdos\rmprq.c +copy rmprq.obj objects +del rmprq.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc30 -w-pia msdos\spawn.c +copy spawn.obj objects +del spawn.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc30 -w-pia msdos\find.c +copy find.obj objects +del find.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc30 -w-pia msdos\dirlib.c +copy dirlib.obj objects +del dirlib.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc30 -w-pia msdos\dstrlwr.c +copy dstrlwr.obj objects +del dstrlwr.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc30 -w-pia unix\dcache.c +copy dcache.obj objects +del dcache.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc30 -w-pia msdos\borland\tempnam.c +copy tempnam.obj objects +del tempnam.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc30 -w-pia msdos\borland\utime.c +copy utime.obj objects +del utime.obj +tlink @msdos\borland\bcc30\objswp.rsp,dmake.exe,NUL.MAP,@msdos\borland\bcc30\libswp.rsp +copy msdos\borland\bcc30\template.mk startup\config.mk diff --git a/dmake/msdos/borland/bcc30/obj.rsp b/dmake/msdos/borland/bcc30/obj.rsp new file mode 100644 index 000000000000..3f396242ce36 --- /dev/null +++ b/dmake/msdos/borland/bcc30/obj.rsp @@ -0,0 +1,34 @@ +d:\cc\borland\bcc30\lib\c0l.obj+ +objects\infer.obj+ +objects\make.obj+ +objects\stat.obj+ +objects\expand.obj+ +objects\dmstring.obj+ +objects\hash.obj+ +objects\dag.obj+ +objects\dmake.obj+ +objects\path.obj+ +objects\imacs.obj+ +objects\sysintf.obj+ +objects\parse.obj+ +objects\getinp.obj+ +objects\quit.obj+ +objects\state.obj+ +objects\dmdump.obj+ +objects\macparse.obj+ +objects\rulparse.obj+ +objects\percent.obj+ +objects\function.obj+ +objects\ruletab.obj+ +objects\dirbrk.obj+ +objects\runargv.obj+ +objects\arlib.obj+ +objects\dchdir.obj+ +objects\switchar.obj+ +objects\rmprq.obj+ +objects\tee.obj+ +objects\dirlib.obj+ +objects\find.obj+ +objects\dcache.obj+ +objects\tempnam.obj+ +objects\utime.obj diff --git a/dmake/msdos/borland/bcc30/objswp.rsp b/dmake/msdos/borland/bcc30/objswp.rsp new file mode 100644 index 000000000000..aa0bf5e5831a --- /dev/null +++ b/dmake/msdos/borland/bcc30/objswp.rsp @@ -0,0 +1,36 @@ +e:\cc\borland\bcc30\lib\c0l.obj+ +objects\exec.obj+ +objects\infer.obj+ +objects\make.obj+ +objects\stat.obj+ +objects\expand.obj+ +objects\dmstring.obj+ +objects\hash.obj+ +objects\dag.obj+ +objects\dmake.obj+ +objects\path.obj+ +objects\imacs.obj+ +objects\sysintf.obj+ +objects\parse.obj+ +objects\getinp.obj+ +objects\quit.obj+ +objects\state.obj+ +objects\dmdump.obj+ +objects\macparse.obj+ +objects\rulparse.obj+ +objects\percent.obj+ +objects\function.obj+ +objects\ruletab.obj+ +objects\dirbrk.obj+ +objects\runargv.obj+ +objects\arlib.obj+ +objects\dchdir.obj+ +objects\switchar.obj+ +objects\rmprq.obj+ +objects\spawn.obj+ +objects\find.obj+ +objects\dirlib.obj+ +objects\dstrlwr.obj+ +objects\dcache.obj+ +objects\tempnam.obj+ +objects\utime.obj diff --git a/dmake/msdos/borland/bcc30/public.h b/dmake/msdos/borland/bcc30/public.h new file mode 100644 index 000000000000..a091150efedc --- /dev/null +++ b/dmake/msdos/borland/bcc30/public.h @@ -0,0 +1,169 @@ +/* RCS $Id: public.h,v 1.1.1.1 2000-09-22 15:33:28 hr Exp $ +-- WARNING -- This file is AUTOMATICALLY GENERATED DO NOT EDIT IT +-- +-- +-- SYNOPSIS +-- Local functions exported to be visible by others. +-- +-- DESCRIPTION +-- This file is generated by 'genpub'. Function declarations +-- that appear in this file are extracted by 'genpub' from +-- source files. Any function in the source file whose definition +-- appears like: +-- +-- PUBLIC return_type +-- function( arg_list ); +-- type_expr1 arg1; +-- ... +-- +-- has its definition extracted and a line of the form: +-- +-- return_type function ANSI((type_expr1,type_expr2,...)); +-- +-- entered into the output file. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef _DMAKE_PUBLIC_h +#define _DMAKE_PUBLIC_h + +#ifdef EXTERN +#undef EXTERN +#endif +#if defined(DEFINE_DMAKE_VARIABLES) +#define EXTERN +#else +#define EXTERN extern +#endif + +/***** genpub: Begin list of generated function headers */ +void Infer_recipe ANSI((CELLPTR, CELLPTR)); +int Make_targets ANSI(()); +int Make ANSI((CELLPTR, CELLPTR)); +int Exec_commands ANSI((CELLPTR)); +void Print_cmnd ANSI((char *, int, int)); +int Push_dir ANSI((char *, char *, int)); +void Pop_dir ANSI((int)); +void Append_line ANSI((char *, int, FILE *, char *, int, int)); +void Stat_target ANSI((CELLPTR, int, int)); +char *Expand ANSI((char *)); +char *Apply_edit ANSI((char *, char *, char *, int, int)); +void Map_esc ANSI((char *)); +char* Apply_modifiers ANSI((int, char *)); +char* Tokenize ANSI((char *, char *, char, int)); +char* ScanToken ANSI((char *, char **, int)); +char *DmStrJoin ANSI((char *, char *, int, int)); +char *DmStrAdd ANSI((char *, char *, int)); +char *DmStrApp ANSI((char *, char *)); +char *DmStrDup ANSI((char *)); +char *DmStrDup2 ANSI((char *)); +char *DmStrPbrk ANSI((char *, char *)); +char *DmStrSpn ANSI((char *, char *)); +char *DmStrStr ANSI((char *, char *)); +char *DmSubStr ANSI((char *, char *)); +uint16 Hash ANSI((char *, uint32 *)); +HASHPTR Get_name ANSI((char *, HASHPTR *, int)); +HASHPTR Search_table ANSI((HASHPTR *, char *, uint16 *, uint32 *)); +HASHPTR Push_macro ANSI((HASHPTR)); +HASHPTR Pop_macro ANSI((HASHPTR)); +HASHPTR Def_macro ANSI((char *, char *, int)); +CELLPTR Def_cell ANSI((char *)); +LINKPTR Add_prerequisite ANSI((CELLPTR, CELLPTR, int, int)); +void Clear_prerequisites ANSI((CELLPTR)); +int Test_circle ANSI((CELLPTR, int)); +STRINGPTR Def_recipe ANSI((char *, STRINGPTR, int, int)); +t_attr Rcp_attribute ANSI((char *)); +void main ANSI((int, char **)); +FILE *Openfile ANSI((char *, int, int)); +FILE *Closefile ANSI(()); +FILE *Search_file ANSI((char *, char **)); +char *Filename ANSI(()); +int Nestlevel ANSI(()); +FILE *TryFiles ANSI((LINKPTR)); +void Fatal ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Error ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Warning ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void No_ram ANSI(()); +void Usage ANSI((int)); +void Version ANSI(()); +char *Get_suffix ANSI((char *)); +char *Basename ANSI((char *)); +char *Filedir ANSI((char *)); +char *Build_path ANSI((char *, char *)); +void Make_rules ANSI(()); +void Create_macro_vars ANSI(()); +time_t Do_stat ANSI((char *, char *, char **, int)); +int Do_touch ANSI((char *, char *, char **)); +void Void_lib_cache ANSI((char *, char *)); +time_t Do_time ANSI(()); +int Do_cmnd ANSI((char *, int, int, CELLPTR, int, int, int)); +char ** Pack_argv ANSI((int, int, char *)); +char *Read_env_string ANSI((char *)); +int Write_env_string ANSI((char *, char *)); +void ReadEnvironment ANSI(()); +void Catch_signals ANSI((void (*)())); +void Clear_signals ANSI(()); +void Prolog ANSI((int, char* [])); +void Epilog ANSI((int)); +char *Get_current_dir ANSI(()); +int Set_dir ANSI((char*)); +char Get_switch_char ANSI(()); +FILE* Get_temp ANSI((char **, char *, int)); +FILE *Start_temp ANSI((char *, CELLPTR, char **)); +void Open_temp_error ANSI((char *, char *)); +void Link_temp ANSI((CELLPTR, FILE *, char *)); +void Close_temp ANSI((CELLPTR, FILE *)); +void Unlink_temp_files ANSI((CELLPTR)); +void Handle_result ANSI((int, int, int, CELLPTR)); +void Update_time_stamp ANSI((CELLPTR)); +int Remove_file ANSI((char *)); +void Parse ANSI((FILE *)); +int Get_line ANSI((char *, FILE *)); +char *Do_comment ANSI((char *, char **, int)); +char *Get_token ANSI((TKSTRPTR, char *, int)); +void Quit ANSI(()); +void Read_state ANSI(()); +void Write_state ANSI(()); +int Check_state ANSI((CELLPTR, STRINGPTR *, int)); +void Dump ANSI(()); +void Dump_recipe ANSI((STRINGPTR)); +int Parse_macro ANSI((char *, int)); +int Macro_op ANSI((char *)); +int Parse_rule_def ANSI((int *)); +int Rule_op ANSI((char *)); +void Add_recipe_to_list ANSI((char *, int, int)); +void Bind_rules_to_targets ANSI((int)); +int Set_group_attributes ANSI((char *)); +DFALINKPTR Match_dfa ANSI((char *)); +void Check_circle_dfa ANSI(()); +void Add_nfa ANSI((char *)); +char *Exec_function ANSI((char *)); +int If_root_path ANSI((char *)); +int runargv ANSI((CELLPTR, int, int, int, int, char *)); +void Clean_up_processes ANSI(()); +int Wait_for_child ANSI((int, int)); +time_t seek_arch ANSI((char*, char*)); +int touch_arch ANSI((char*, char*)); +int dchdir ANSI((char *)); +void Remove_prq ANSI((CELLPTR)); +int spawnvpe ANSI((int, char *, char **, char **)); +void Hook_std_writes ANSI((char *)); +void dstrlwr ANSI((char *, char *)); +time_t CacheStat ANSI((char *, int)); + +#endif diff --git a/dmake/msdos/borland/bcc30/template.mk b/dmake/msdos/borland/bcc30/template.mk new file mode 100644 index 000000000000..df574e09c7aa --- /dev/null +++ b/dmake/msdos/borland/bcc30/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= msdos + OSRELEASE *:= borland + OSENVIRONMENT *:= bcc30 diff --git a/dmake/msdos/borland/bcc40/config.h b/dmake/msdos/borland/bcc40/config.h new file mode 100644 index 000000000000..994a10eab1ba --- /dev/null +++ b/dmake/msdos/borland/bcc40/config.h @@ -0,0 +1,51 @@ +/* RCS $Id: config.h,v 1.1.1.1 2000-09-22 15:33:28 hr Exp $ +-- +-- SYNOPSIS +-- Configurarion include file. +-- +-- DESCRIPTION +-- There is one of these for each specific machine configuration. +-- It can be used to further tweek the machine specific sources +-- so that they compile. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +/* define this for configurations that don't have the coreleft function + * so that the code compiles. To my knowledge coreleft exists only on + * Turbo C, but it is needed here since the function is used in many debug + * macros. */ +/*#define coreleft() 0L*/ +extern unsigned int coreleft(); + +#define SIGQUIT SIGTERM /* turbo C doesn't understand SIGQUIT */ + +/* Turbo-C understands const declarations. */ +#define CONST const + +#ifndef MSDOS +# define MSDOS 1 +#endif + +/* a small problem with pointer to voids on some unix machines needs this */ +#define PVOID void * + +/* Borland redefined the environment variable, sigh */ +#define environ _environ + +/* Have to pull this in for the standard lib defines */ +#include <io.h> diff --git a/dmake/msdos/borland/bcc40/config.mk b/dmake/msdos/borland/bcc40/config.mk new file mode 100644 index 000000000000..550b86950705 --- /dev/null +++ b/dmake/msdos/borland/bcc40/config.mk @@ -0,0 +1,7 @@ +# Definition of macros for library, and C startup code. +osedir = $(osrdir)$(DIRSEPSTR)$(OSENVIRONMENT) + +LDLIBS = e:/cc/borland/bcc40/lib/c$(MODEL) +CSTARTUP = e:/cc/borland/bcc40/lib/c0$(MODEL).obj + +CFLAGS += -I$(osedir) -w-pro diff --git a/dmake/msdos/borland/bcc40/lib.rsp b/dmake/msdos/borland/bcc40/lib.rsp new file mode 100644 index 000000000000..828ccf4ab0b8 --- /dev/null +++ b/dmake/msdos/borland/bcc40/lib.rsp @@ -0,0 +1,2 @@ +e:\cc\borland\bcc40\lib\cw32+ +e:\cc\borland\bcc40\lib\import32 diff --git a/dmake/msdos/borland/bcc40/libswp.rsp b/dmake/msdos/borland/bcc40/libswp.rsp new file mode 100644 index 000000000000..1557935cd40c --- /dev/null +++ b/dmake/msdos/borland/bcc40/libswp.rsp @@ -0,0 +1 @@ +e:\cc\borland\bcc40\lib\cl diff --git a/dmake/msdos/borland/bcc40/mkswp.bat b/dmake/msdos/borland/bcc40/mkswp.bat new file mode 100755 index 000000000000..d8a1bf824de4 --- /dev/null +++ b/dmake/msdos/borland/bcc40/mkswp.bat @@ -0,0 +1,107 @@ +md objects +tasm -t -mx -dmlarge msdos\exec.asm,,,; +mv exec.obj objects +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc40 -w-pro infer.c +copy infer.obj objects +del infer.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc40 -w-pro make.c +copy make.obj objects +del make.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc40 -w-pro stat.c +copy stat.obj objects +del stat.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc40 -w-pro expand.c +copy expand.obj objects +del expand.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc40 -w-pro dmstring.c +copy dmstring.obj objects +del dmstring.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc40 -w-pro hash.c +copy hash.obj objects +del hash.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc40 -w-pro dag.c +copy dag.obj objects +del dag.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc40 -w-pro dmake.c +copy dmake.obj objects +del dmake.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc40 -w-pro path.c +copy path.obj objects +del path.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc40 -w-pro imacs.c +copy imacs.obj objects +del imacs.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc40 -w-pro sysintf.c +copy sysintf.obj objects +del sysintf.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc40 -w-pro parse.c +copy parse.obj objects +del parse.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc40 -w-pro getinp.c +copy getinp.obj objects +del getinp.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc40 -w-pro quit.c +copy quit.obj objects +del quit.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc40 -w-pro state.c +copy state.obj objects +del state.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc40 -w-pro dmdump.c +copy dmdump.obj objects +del dmdump.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc40 -w-pro macparse.c +copy macparse.obj objects +del macparse.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc40 -w-pro rulparse.c +copy rulparse.obj objects +del rulparse.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc40 -w-pro percent.c +copy percent.obj objects +del percent.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc40 -w-pro function.c +copy function.obj objects +del function.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc40 -w-pro msdos\ruletab.c +copy ruletab.obj objects +del ruletab.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc40 -w-pro msdos\dirbrk.c +copy dirbrk.obj objects +del dirbrk.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc40 -w-pro msdos\runargv.c +copy runargv.obj objects +del runargv.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc40 -w-pro msdos\arlib.c +copy arlib.obj objects +del arlib.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc40 -w-pro msdos\dchdir.c +copy dchdir.obj objects +del dchdir.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc40 -w-pro msdos\switchar.c +copy switchar.obj objects +del switchar.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc40 -w-pro msdos\rmprq.c +copy rmprq.obj objects +del rmprq.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc40 -w-pro msdos\spawn.c +copy spawn.obj objects +del spawn.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc40 -w-pro msdos\find.c +copy find.obj objects +del find.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc40 -w-pro msdos\dirlib.c +copy dirlib.obj objects +del dirlib.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc40 -w-pro msdos\dstrlwr.c +copy dstrlwr.obj objects +del dstrlwr.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc40 -w-pro unix\dcache.c +copy dcache.obj objects +del dcache.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc40 -w-pro msdos\borland\tempnam.c +copy tempnam.obj objects +del tempnam.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc40 -w-pro msdos\borland\utime.c +copy utime.obj objects +del utime.obj +tlink @msdos\borland\bcc40\objswp.rsp,dmake.exe,NUL.MAP,@msdos\borland\bcc40\libswp.rsp +copy msdos\borland\bcc40\template.mk startup\config.mk diff --git a/dmake/msdos/borland/bcc40/obj.rsp b/dmake/msdos/borland/bcc40/obj.rsp new file mode 100644 index 000000000000..572259dca8ea --- /dev/null +++ b/dmake/msdos/borland/bcc40/obj.rsp @@ -0,0 +1,34 @@ +e:\cc\borland\bcc40\lib\c0x32.obj+ +objects\infer.obj+ +objects\make.obj+ +objects\stat.obj+ +objects\expand.obj+ +objects\dmstring.obj+ +objects\hash.obj+ +objects\dag.obj+ +objects\dmake.obj+ +objects\path.obj+ +objects\imacs.obj+ +objects\sysintf.obj+ +objects\parse.obj+ +objects\getinp.obj+ +objects\quit.obj+ +objects\state.obj+ +objects\dmdump.obj+ +objects\macparse.obj+ +objects\rulparse.obj+ +objects\percent.obj+ +objects\function.obj+ +objects\ruletab.obj+ +objects\dirbrk.obj+ +objects\runargv.obj+ +objects\arlib.obj+ +objects\dchdir.obj+ +objects\switchar.obj+ +objects\rmprq.obj+ +objects\find.obj+ +objects\tee.obj+ +objects\dirlib.obj+ +objects\dcache.obj+ +objects\tempnam.obj+ +objects\utime.obj diff --git a/dmake/msdos/borland/bcc40/objswp.rsp b/dmake/msdos/borland/bcc40/objswp.rsp new file mode 100644 index 000000000000..712d47f47504 --- /dev/null +++ b/dmake/msdos/borland/bcc40/objswp.rsp @@ -0,0 +1,36 @@ +e:\cc\borland\bcc40\lib\c0l.obj+ +objects\exec.obj+ +objects\infer.obj+ +objects\make.obj+ +objects\stat.obj+ +objects\expand.obj+ +objects\dmstring.obj+ +objects\hash.obj+ +objects\dag.obj+ +objects\dmake.obj+ +objects\path.obj+ +objects\imacs.obj+ +objects\sysintf.obj+ +objects\parse.obj+ +objects\getinp.obj+ +objects\quit.obj+ +objects\state.obj+ +objects\dmdump.obj+ +objects\macparse.obj+ +objects\rulparse.obj+ +objects\percent.obj+ +objects\function.obj+ +objects\ruletab.obj+ +objects\dirbrk.obj+ +objects\runargv.obj+ +objects\arlib.obj+ +objects\dchdir.obj+ +objects\switchar.obj+ +objects\rmprq.obj+ +objects\spawn.obj+ +objects\find.obj+ +objects\dirlib.obj+ +objects\dstrlwr.obj+ +objects\dcache.obj+ +objects\tempnam.obj+ +objects\utime.obj diff --git a/dmake/msdos/borland/bcc40/public.h b/dmake/msdos/borland/bcc40/public.h new file mode 100644 index 000000000000..a091150efedc --- /dev/null +++ b/dmake/msdos/borland/bcc40/public.h @@ -0,0 +1,169 @@ +/* RCS $Id: public.h,v 1.1.1.1 2000-09-22 15:33:28 hr Exp $ +-- WARNING -- This file is AUTOMATICALLY GENERATED DO NOT EDIT IT +-- +-- +-- SYNOPSIS +-- Local functions exported to be visible by others. +-- +-- DESCRIPTION +-- This file is generated by 'genpub'. Function declarations +-- that appear in this file are extracted by 'genpub' from +-- source files. Any function in the source file whose definition +-- appears like: +-- +-- PUBLIC return_type +-- function( arg_list ); +-- type_expr1 arg1; +-- ... +-- +-- has its definition extracted and a line of the form: +-- +-- return_type function ANSI((type_expr1,type_expr2,...)); +-- +-- entered into the output file. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef _DMAKE_PUBLIC_h +#define _DMAKE_PUBLIC_h + +#ifdef EXTERN +#undef EXTERN +#endif +#if defined(DEFINE_DMAKE_VARIABLES) +#define EXTERN +#else +#define EXTERN extern +#endif + +/***** genpub: Begin list of generated function headers */ +void Infer_recipe ANSI((CELLPTR, CELLPTR)); +int Make_targets ANSI(()); +int Make ANSI((CELLPTR, CELLPTR)); +int Exec_commands ANSI((CELLPTR)); +void Print_cmnd ANSI((char *, int, int)); +int Push_dir ANSI((char *, char *, int)); +void Pop_dir ANSI((int)); +void Append_line ANSI((char *, int, FILE *, char *, int, int)); +void Stat_target ANSI((CELLPTR, int, int)); +char *Expand ANSI((char *)); +char *Apply_edit ANSI((char *, char *, char *, int, int)); +void Map_esc ANSI((char *)); +char* Apply_modifiers ANSI((int, char *)); +char* Tokenize ANSI((char *, char *, char, int)); +char* ScanToken ANSI((char *, char **, int)); +char *DmStrJoin ANSI((char *, char *, int, int)); +char *DmStrAdd ANSI((char *, char *, int)); +char *DmStrApp ANSI((char *, char *)); +char *DmStrDup ANSI((char *)); +char *DmStrDup2 ANSI((char *)); +char *DmStrPbrk ANSI((char *, char *)); +char *DmStrSpn ANSI((char *, char *)); +char *DmStrStr ANSI((char *, char *)); +char *DmSubStr ANSI((char *, char *)); +uint16 Hash ANSI((char *, uint32 *)); +HASHPTR Get_name ANSI((char *, HASHPTR *, int)); +HASHPTR Search_table ANSI((HASHPTR *, char *, uint16 *, uint32 *)); +HASHPTR Push_macro ANSI((HASHPTR)); +HASHPTR Pop_macro ANSI((HASHPTR)); +HASHPTR Def_macro ANSI((char *, char *, int)); +CELLPTR Def_cell ANSI((char *)); +LINKPTR Add_prerequisite ANSI((CELLPTR, CELLPTR, int, int)); +void Clear_prerequisites ANSI((CELLPTR)); +int Test_circle ANSI((CELLPTR, int)); +STRINGPTR Def_recipe ANSI((char *, STRINGPTR, int, int)); +t_attr Rcp_attribute ANSI((char *)); +void main ANSI((int, char **)); +FILE *Openfile ANSI((char *, int, int)); +FILE *Closefile ANSI(()); +FILE *Search_file ANSI((char *, char **)); +char *Filename ANSI(()); +int Nestlevel ANSI(()); +FILE *TryFiles ANSI((LINKPTR)); +void Fatal ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Error ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Warning ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void No_ram ANSI(()); +void Usage ANSI((int)); +void Version ANSI(()); +char *Get_suffix ANSI((char *)); +char *Basename ANSI((char *)); +char *Filedir ANSI((char *)); +char *Build_path ANSI((char *, char *)); +void Make_rules ANSI(()); +void Create_macro_vars ANSI(()); +time_t Do_stat ANSI((char *, char *, char **, int)); +int Do_touch ANSI((char *, char *, char **)); +void Void_lib_cache ANSI((char *, char *)); +time_t Do_time ANSI(()); +int Do_cmnd ANSI((char *, int, int, CELLPTR, int, int, int)); +char ** Pack_argv ANSI((int, int, char *)); +char *Read_env_string ANSI((char *)); +int Write_env_string ANSI((char *, char *)); +void ReadEnvironment ANSI(()); +void Catch_signals ANSI((void (*)())); +void Clear_signals ANSI(()); +void Prolog ANSI((int, char* [])); +void Epilog ANSI((int)); +char *Get_current_dir ANSI(()); +int Set_dir ANSI((char*)); +char Get_switch_char ANSI(()); +FILE* Get_temp ANSI((char **, char *, int)); +FILE *Start_temp ANSI((char *, CELLPTR, char **)); +void Open_temp_error ANSI((char *, char *)); +void Link_temp ANSI((CELLPTR, FILE *, char *)); +void Close_temp ANSI((CELLPTR, FILE *)); +void Unlink_temp_files ANSI((CELLPTR)); +void Handle_result ANSI((int, int, int, CELLPTR)); +void Update_time_stamp ANSI((CELLPTR)); +int Remove_file ANSI((char *)); +void Parse ANSI((FILE *)); +int Get_line ANSI((char *, FILE *)); +char *Do_comment ANSI((char *, char **, int)); +char *Get_token ANSI((TKSTRPTR, char *, int)); +void Quit ANSI(()); +void Read_state ANSI(()); +void Write_state ANSI(()); +int Check_state ANSI((CELLPTR, STRINGPTR *, int)); +void Dump ANSI(()); +void Dump_recipe ANSI((STRINGPTR)); +int Parse_macro ANSI((char *, int)); +int Macro_op ANSI((char *)); +int Parse_rule_def ANSI((int *)); +int Rule_op ANSI((char *)); +void Add_recipe_to_list ANSI((char *, int, int)); +void Bind_rules_to_targets ANSI((int)); +int Set_group_attributes ANSI((char *)); +DFALINKPTR Match_dfa ANSI((char *)); +void Check_circle_dfa ANSI(()); +void Add_nfa ANSI((char *)); +char *Exec_function ANSI((char *)); +int If_root_path ANSI((char *)); +int runargv ANSI((CELLPTR, int, int, int, int, char *)); +void Clean_up_processes ANSI(()); +int Wait_for_child ANSI((int, int)); +time_t seek_arch ANSI((char*, char*)); +int touch_arch ANSI((char*, char*)); +int dchdir ANSI((char *)); +void Remove_prq ANSI((CELLPTR)); +int spawnvpe ANSI((int, char *, char **, char **)); +void Hook_std_writes ANSI((char *)); +void dstrlwr ANSI((char *, char *)); +time_t CacheStat ANSI((char *, int)); + +#endif diff --git a/dmake/msdos/borland/bcc40/template.mk b/dmake/msdos/borland/bcc40/template.mk new file mode 100644 index 000000000000..30a27692f3ed --- /dev/null +++ b/dmake/msdos/borland/bcc40/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= msdos + OSRELEASE *:= borland + OSENVIRONMENT *:= bcc40 diff --git a/dmake/msdos/borland/bcc45/config.h b/dmake/msdos/borland/bcc45/config.h new file mode 100644 index 000000000000..994a10eab1ba --- /dev/null +++ b/dmake/msdos/borland/bcc45/config.h @@ -0,0 +1,51 @@ +/* RCS $Id: config.h,v 1.1.1.1 2000-09-22 15:33:28 hr Exp $ +-- +-- SYNOPSIS +-- Configurarion include file. +-- +-- DESCRIPTION +-- There is one of these for each specific machine configuration. +-- It can be used to further tweek the machine specific sources +-- so that they compile. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +/* define this for configurations that don't have the coreleft function + * so that the code compiles. To my knowledge coreleft exists only on + * Turbo C, but it is needed here since the function is used in many debug + * macros. */ +/*#define coreleft() 0L*/ +extern unsigned int coreleft(); + +#define SIGQUIT SIGTERM /* turbo C doesn't understand SIGQUIT */ + +/* Turbo-C understands const declarations. */ +#define CONST const + +#ifndef MSDOS +# define MSDOS 1 +#endif + +/* a small problem with pointer to voids on some unix machines needs this */ +#define PVOID void * + +/* Borland redefined the environment variable, sigh */ +#define environ _environ + +/* Have to pull this in for the standard lib defines */ +#include <io.h> diff --git a/dmake/msdos/borland/bcc45/config.mk b/dmake/msdos/borland/bcc45/config.mk new file mode 100644 index 000000000000..550b86950705 --- /dev/null +++ b/dmake/msdos/borland/bcc45/config.mk @@ -0,0 +1,7 @@ +# Definition of macros for library, and C startup code. +osedir = $(osrdir)$(DIRSEPSTR)$(OSENVIRONMENT) + +LDLIBS = e:/cc/borland/bcc40/lib/c$(MODEL) +CSTARTUP = e:/cc/borland/bcc40/lib/c0$(MODEL).obj + +CFLAGS += -I$(osedir) -w-pro diff --git a/dmake/msdos/borland/bcc45/lib.rsp b/dmake/msdos/borland/bcc45/lib.rsp new file mode 100644 index 000000000000..db2b78d82438 --- /dev/null +++ b/dmake/msdos/borland/bcc45/lib.rsp @@ -0,0 +1,2 @@ +e:\cc\borland\bcc45\lib\cw32+ +e:\cc\borland\bcc45\lib\import32 diff --git a/dmake/msdos/borland/bcc45/libswp.rsp b/dmake/msdos/borland/bcc45/libswp.rsp new file mode 100644 index 000000000000..1557935cd40c --- /dev/null +++ b/dmake/msdos/borland/bcc45/libswp.rsp @@ -0,0 +1 @@ +e:\cc\borland\bcc40\lib\cl diff --git a/dmake/msdos/borland/bcc45/mkswp.bat b/dmake/msdos/borland/bcc45/mkswp.bat new file mode 100755 index 000000000000..c6bfede2f370 --- /dev/null +++ b/dmake/msdos/borland/bcc45/mkswp.bat @@ -0,0 +1,107 @@ +md objects +tasm -t -mx -dmlarge msdos\exec.asm,,,; +mv exec.obj objects +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc45 -w-pro infer.c +copy infer.obj objects +del infer.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc45 -w-pro make.c +copy make.obj objects +del make.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc45 -w-pro stat.c +copy stat.obj objects +del stat.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc45 -w-pro expand.c +copy expand.obj objects +del expand.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc45 -w-pro dmstring.c +copy dmstring.obj objects +del dmstring.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc45 -w-pro hash.c +copy hash.obj objects +del hash.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc45 -w-pro dag.c +copy dag.obj objects +del dag.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc45 -w-pro dmake.c +copy dmake.obj objects +del dmake.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc45 -w-pro path.c +copy path.obj objects +del path.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc45 -w-pro imacs.c +copy imacs.obj objects +del imacs.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc45 -w-pro sysintf.c +copy sysintf.obj objects +del sysintf.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc45 -w-pro parse.c +copy parse.obj objects +del parse.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc45 -w-pro getinp.c +copy getinp.obj objects +del getinp.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc45 -w-pro quit.c +copy quit.obj objects +del quit.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc45 -w-pro state.c +copy state.obj objects +del state.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc45 -w-pro dmdump.c +copy dmdump.obj objects +del dmdump.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc45 -w-pro macparse.c +copy macparse.obj objects +del macparse.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc45 -w-pro rulparse.c +copy rulparse.obj objects +del rulparse.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc45 -w-pro percent.c +copy percent.obj objects +del percent.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc45 -w-pro function.c +copy function.obj objects +del function.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc45 -w-pro msdos\ruletab.c +copy ruletab.obj objects +del ruletab.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc45 -w-pro msdos\dirbrk.c +copy dirbrk.obj objects +del dirbrk.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc45 -w-pro msdos\runargv.c +copy runargv.obj objects +del runargv.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc45 -w-pro msdos\arlib.c +copy arlib.obj objects +del arlib.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc45 -w-pro msdos\dchdir.c +copy dchdir.obj objects +del dchdir.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc45 -w-pro msdos\switchar.c +copy switchar.obj objects +del switchar.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc45 -w-pro msdos\rmprq.c +copy rmprq.obj objects +del rmprq.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc45 -w-pro msdos\spawn.c +copy spawn.obj objects +del spawn.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc45 -w-pro msdos\find.c +copy find.obj objects +del find.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc45 -w-pro msdos\dirlib.c +copy dirlib.obj objects +del dirlib.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc45 -w-pro msdos\dstrlwr.c +copy dstrlwr.obj objects +del dstrlwr.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc45 -w-pro unix\dcache.c +copy dcache.obj objects +del dcache.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc45 -w-pro msdos\borland\tempnam.c +copy tempnam.obj objects +del tempnam.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc45 -w-pro msdos\borland\utime.c +copy utime.obj objects +del utime.obj +tlink @msdos\borland\bcc45\objswp.rsp,dmake.exe,NUL.MAP,@msdos\borland\bcc45\libswp.rsp +copy msdos\borland\bcc45\template.mk startup\config.mk diff --git a/dmake/msdos/borland/bcc45/obj.rsp b/dmake/msdos/borland/bcc45/obj.rsp new file mode 100644 index 000000000000..e1d4b1e23186 --- /dev/null +++ b/dmake/msdos/borland/bcc45/obj.rsp @@ -0,0 +1,34 @@ +e:\cc\borland\bcc45\lib\c0x32.obj+ +objects\infer.obj+ +objects\make.obj+ +objects\stat.obj+ +objects\expand.obj+ +objects\dmstring.obj+ +objects\hash.obj+ +objects\dag.obj+ +objects\dmake.obj+ +objects\path.obj+ +objects\imacs.obj+ +objects\sysintf.obj+ +objects\parse.obj+ +objects\getinp.obj+ +objects\quit.obj+ +objects\state.obj+ +objects\dmdump.obj+ +objects\macparse.obj+ +objects\rulparse.obj+ +objects\percent.obj+ +objects\function.obj+ +objects\ruletab.obj+ +objects\dirbrk.obj+ +objects\runargv.obj+ +objects\arlib.obj+ +objects\dchdir.obj+ +objects\switchar.obj+ +objects\rmprq.obj+ +objects\find.obj+ +objects\tee.obj+ +objects\dirlib.obj+ +objects\dcache.obj+ +objects\tempnam.obj+ +objects\utime.obj diff --git a/dmake/msdos/borland/bcc45/objswp.rsp b/dmake/msdos/borland/bcc45/objswp.rsp new file mode 100644 index 000000000000..712d47f47504 --- /dev/null +++ b/dmake/msdos/borland/bcc45/objswp.rsp @@ -0,0 +1,36 @@ +e:\cc\borland\bcc40\lib\c0l.obj+ +objects\exec.obj+ +objects\infer.obj+ +objects\make.obj+ +objects\stat.obj+ +objects\expand.obj+ +objects\dmstring.obj+ +objects\hash.obj+ +objects\dag.obj+ +objects\dmake.obj+ +objects\path.obj+ +objects\imacs.obj+ +objects\sysintf.obj+ +objects\parse.obj+ +objects\getinp.obj+ +objects\quit.obj+ +objects\state.obj+ +objects\dmdump.obj+ +objects\macparse.obj+ +objects\rulparse.obj+ +objects\percent.obj+ +objects\function.obj+ +objects\ruletab.obj+ +objects\dirbrk.obj+ +objects\runargv.obj+ +objects\arlib.obj+ +objects\dchdir.obj+ +objects\switchar.obj+ +objects\rmprq.obj+ +objects\spawn.obj+ +objects\find.obj+ +objects\dirlib.obj+ +objects\dstrlwr.obj+ +objects\dcache.obj+ +objects\tempnam.obj+ +objects\utime.obj diff --git a/dmake/msdos/borland/bcc45/public.h b/dmake/msdos/borland/bcc45/public.h new file mode 100644 index 000000000000..a091150efedc --- /dev/null +++ b/dmake/msdos/borland/bcc45/public.h @@ -0,0 +1,169 @@ +/* RCS $Id: public.h,v 1.1.1.1 2000-09-22 15:33:28 hr Exp $ +-- WARNING -- This file is AUTOMATICALLY GENERATED DO NOT EDIT IT +-- +-- +-- SYNOPSIS +-- Local functions exported to be visible by others. +-- +-- DESCRIPTION +-- This file is generated by 'genpub'. Function declarations +-- that appear in this file are extracted by 'genpub' from +-- source files. Any function in the source file whose definition +-- appears like: +-- +-- PUBLIC return_type +-- function( arg_list ); +-- type_expr1 arg1; +-- ... +-- +-- has its definition extracted and a line of the form: +-- +-- return_type function ANSI((type_expr1,type_expr2,...)); +-- +-- entered into the output file. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef _DMAKE_PUBLIC_h +#define _DMAKE_PUBLIC_h + +#ifdef EXTERN +#undef EXTERN +#endif +#if defined(DEFINE_DMAKE_VARIABLES) +#define EXTERN +#else +#define EXTERN extern +#endif + +/***** genpub: Begin list of generated function headers */ +void Infer_recipe ANSI((CELLPTR, CELLPTR)); +int Make_targets ANSI(()); +int Make ANSI((CELLPTR, CELLPTR)); +int Exec_commands ANSI((CELLPTR)); +void Print_cmnd ANSI((char *, int, int)); +int Push_dir ANSI((char *, char *, int)); +void Pop_dir ANSI((int)); +void Append_line ANSI((char *, int, FILE *, char *, int, int)); +void Stat_target ANSI((CELLPTR, int, int)); +char *Expand ANSI((char *)); +char *Apply_edit ANSI((char *, char *, char *, int, int)); +void Map_esc ANSI((char *)); +char* Apply_modifiers ANSI((int, char *)); +char* Tokenize ANSI((char *, char *, char, int)); +char* ScanToken ANSI((char *, char **, int)); +char *DmStrJoin ANSI((char *, char *, int, int)); +char *DmStrAdd ANSI((char *, char *, int)); +char *DmStrApp ANSI((char *, char *)); +char *DmStrDup ANSI((char *)); +char *DmStrDup2 ANSI((char *)); +char *DmStrPbrk ANSI((char *, char *)); +char *DmStrSpn ANSI((char *, char *)); +char *DmStrStr ANSI((char *, char *)); +char *DmSubStr ANSI((char *, char *)); +uint16 Hash ANSI((char *, uint32 *)); +HASHPTR Get_name ANSI((char *, HASHPTR *, int)); +HASHPTR Search_table ANSI((HASHPTR *, char *, uint16 *, uint32 *)); +HASHPTR Push_macro ANSI((HASHPTR)); +HASHPTR Pop_macro ANSI((HASHPTR)); +HASHPTR Def_macro ANSI((char *, char *, int)); +CELLPTR Def_cell ANSI((char *)); +LINKPTR Add_prerequisite ANSI((CELLPTR, CELLPTR, int, int)); +void Clear_prerequisites ANSI((CELLPTR)); +int Test_circle ANSI((CELLPTR, int)); +STRINGPTR Def_recipe ANSI((char *, STRINGPTR, int, int)); +t_attr Rcp_attribute ANSI((char *)); +void main ANSI((int, char **)); +FILE *Openfile ANSI((char *, int, int)); +FILE *Closefile ANSI(()); +FILE *Search_file ANSI((char *, char **)); +char *Filename ANSI(()); +int Nestlevel ANSI(()); +FILE *TryFiles ANSI((LINKPTR)); +void Fatal ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Error ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Warning ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void No_ram ANSI(()); +void Usage ANSI((int)); +void Version ANSI(()); +char *Get_suffix ANSI((char *)); +char *Basename ANSI((char *)); +char *Filedir ANSI((char *)); +char *Build_path ANSI((char *, char *)); +void Make_rules ANSI(()); +void Create_macro_vars ANSI(()); +time_t Do_stat ANSI((char *, char *, char **, int)); +int Do_touch ANSI((char *, char *, char **)); +void Void_lib_cache ANSI((char *, char *)); +time_t Do_time ANSI(()); +int Do_cmnd ANSI((char *, int, int, CELLPTR, int, int, int)); +char ** Pack_argv ANSI((int, int, char *)); +char *Read_env_string ANSI((char *)); +int Write_env_string ANSI((char *, char *)); +void ReadEnvironment ANSI(()); +void Catch_signals ANSI((void (*)())); +void Clear_signals ANSI(()); +void Prolog ANSI((int, char* [])); +void Epilog ANSI((int)); +char *Get_current_dir ANSI(()); +int Set_dir ANSI((char*)); +char Get_switch_char ANSI(()); +FILE* Get_temp ANSI((char **, char *, int)); +FILE *Start_temp ANSI((char *, CELLPTR, char **)); +void Open_temp_error ANSI((char *, char *)); +void Link_temp ANSI((CELLPTR, FILE *, char *)); +void Close_temp ANSI((CELLPTR, FILE *)); +void Unlink_temp_files ANSI((CELLPTR)); +void Handle_result ANSI((int, int, int, CELLPTR)); +void Update_time_stamp ANSI((CELLPTR)); +int Remove_file ANSI((char *)); +void Parse ANSI((FILE *)); +int Get_line ANSI((char *, FILE *)); +char *Do_comment ANSI((char *, char **, int)); +char *Get_token ANSI((TKSTRPTR, char *, int)); +void Quit ANSI(()); +void Read_state ANSI(()); +void Write_state ANSI(()); +int Check_state ANSI((CELLPTR, STRINGPTR *, int)); +void Dump ANSI(()); +void Dump_recipe ANSI((STRINGPTR)); +int Parse_macro ANSI((char *, int)); +int Macro_op ANSI((char *)); +int Parse_rule_def ANSI((int *)); +int Rule_op ANSI((char *)); +void Add_recipe_to_list ANSI((char *, int, int)); +void Bind_rules_to_targets ANSI((int)); +int Set_group_attributes ANSI((char *)); +DFALINKPTR Match_dfa ANSI((char *)); +void Check_circle_dfa ANSI(()); +void Add_nfa ANSI((char *)); +char *Exec_function ANSI((char *)); +int If_root_path ANSI((char *)); +int runargv ANSI((CELLPTR, int, int, int, int, char *)); +void Clean_up_processes ANSI(()); +int Wait_for_child ANSI((int, int)); +time_t seek_arch ANSI((char*, char*)); +int touch_arch ANSI((char*, char*)); +int dchdir ANSI((char *)); +void Remove_prq ANSI((CELLPTR)); +int spawnvpe ANSI((int, char *, char **, char **)); +void Hook_std_writes ANSI((char *)); +void dstrlwr ANSI((char *, char *)); +time_t CacheStat ANSI((char *, int)); + +#endif diff --git a/dmake/msdos/borland/bcc45/template.mk b/dmake/msdos/borland/bcc45/template.mk new file mode 100644 index 000000000000..83b5e009033d --- /dev/null +++ b/dmake/msdos/borland/bcc45/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= msdos + OSRELEASE *:= borland + OSENVIRONMENT *:= bcc45 diff --git a/dmake/msdos/borland/bcc50/config.h b/dmake/msdos/borland/bcc50/config.h new file mode 100644 index 000000000000..994a10eab1ba --- /dev/null +++ b/dmake/msdos/borland/bcc50/config.h @@ -0,0 +1,51 @@ +/* RCS $Id: config.h,v 1.1.1.1 2000-09-22 15:33:28 hr Exp $ +-- +-- SYNOPSIS +-- Configurarion include file. +-- +-- DESCRIPTION +-- There is one of these for each specific machine configuration. +-- It can be used to further tweek the machine specific sources +-- so that they compile. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +/* define this for configurations that don't have the coreleft function + * so that the code compiles. To my knowledge coreleft exists only on + * Turbo C, but it is needed here since the function is used in many debug + * macros. */ +/*#define coreleft() 0L*/ +extern unsigned int coreleft(); + +#define SIGQUIT SIGTERM /* turbo C doesn't understand SIGQUIT */ + +/* Turbo-C understands const declarations. */ +#define CONST const + +#ifndef MSDOS +# define MSDOS 1 +#endif + +/* a small problem with pointer to voids on some unix machines needs this */ +#define PVOID void * + +/* Borland redefined the environment variable, sigh */ +#define environ _environ + +/* Have to pull this in for the standard lib defines */ +#include <io.h> diff --git a/dmake/msdos/borland/bcc50/config.mk b/dmake/msdos/borland/bcc50/config.mk new file mode 100644 index 000000000000..550b86950705 --- /dev/null +++ b/dmake/msdos/borland/bcc50/config.mk @@ -0,0 +1,7 @@ +# Definition of macros for library, and C startup code. +osedir = $(osrdir)$(DIRSEPSTR)$(OSENVIRONMENT) + +LDLIBS = e:/cc/borland/bcc40/lib/c$(MODEL) +CSTARTUP = e:/cc/borland/bcc40/lib/c0$(MODEL).obj + +CFLAGS += -I$(osedir) -w-pro diff --git a/dmake/msdos/borland/bcc50/lib.rsp b/dmake/msdos/borland/bcc50/lib.rsp new file mode 100644 index 000000000000..fd89d29f284c --- /dev/null +++ b/dmake/msdos/borland/bcc50/lib.rsp @@ -0,0 +1,2 @@ +e:\cc\borland\bcc50\lib\cw32+ +e:\cc\borland\bcc50\lib\import32 diff --git a/dmake/msdos/borland/bcc50/libswp.rsp b/dmake/msdos/borland/bcc50/libswp.rsp new file mode 100644 index 000000000000..1557935cd40c --- /dev/null +++ b/dmake/msdos/borland/bcc50/libswp.rsp @@ -0,0 +1 @@ +e:\cc\borland\bcc40\lib\cl diff --git a/dmake/msdos/borland/bcc50/mkswp.bat b/dmake/msdos/borland/bcc50/mkswp.bat new file mode 100755 index 000000000000..14de52506f56 --- /dev/null +++ b/dmake/msdos/borland/bcc50/mkswp.bat @@ -0,0 +1,107 @@ +md objects +tasm -t -mx -dmlarge msdos\exec.asm,,,; +mv exec.obj objects +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc50 -w-pro infer.c +copy infer.obj objects +del infer.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc50 -w-pro make.c +copy make.obj objects +del make.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc50 -w-pro stat.c +copy stat.obj objects +del stat.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc50 -w-pro expand.c +copy expand.obj objects +del expand.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc50 -w-pro dmstring.c +copy dmstring.obj objects +del dmstring.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc50 -w-pro hash.c +copy hash.obj objects +del hash.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc50 -w-pro dag.c +copy dag.obj objects +del dag.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc50 -w-pro dmake.c +copy dmake.obj objects +del dmake.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc50 -w-pro path.c +copy path.obj objects +del path.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc50 -w-pro imacs.c +copy imacs.obj objects +del imacs.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc50 -w-pro sysintf.c +copy sysintf.obj objects +del sysintf.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc50 -w-pro parse.c +copy parse.obj objects +del parse.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc50 -w-pro getinp.c +copy getinp.obj objects +del getinp.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc50 -w-pro quit.c +copy quit.obj objects +del quit.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc50 -w-pro state.c +copy state.obj objects +del state.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc50 -w-pro dmdump.c +copy dmdump.obj objects +del dmdump.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc50 -w-pro macparse.c +copy macparse.obj objects +del macparse.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc50 -w-pro rulparse.c +copy rulparse.obj objects +del rulparse.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc50 -w-pro percent.c +copy percent.obj objects +del percent.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc50 -w-pro function.c +copy function.obj objects +del function.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc50 -w-pro msdos\ruletab.c +copy ruletab.obj objects +del ruletab.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc50 -w-pro msdos\dirbrk.c +copy dirbrk.obj objects +del dirbrk.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc50 -w-pro msdos\runargv.c +copy runargv.obj objects +del runargv.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc50 -w-pro msdos\arlib.c +copy arlib.obj objects +del arlib.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc50 -w-pro msdos\dchdir.c +copy dchdir.obj objects +del dchdir.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc50 -w-pro msdos\switchar.c +copy switchar.obj objects +del switchar.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc50 -w-pro msdos\rmprq.c +copy rmprq.obj objects +del rmprq.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc50 -w-pro msdos\spawn.c +copy spawn.obj objects +del spawn.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc50 -w-pro msdos\find.c +copy find.obj objects +del find.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc50 -w-pro msdos\dirlib.c +copy dirlib.obj objects +del dirlib.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc50 -w-pro msdos\dstrlwr.c +copy dstrlwr.obj objects +del dstrlwr.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc50 -w-pro unix\dcache.c +copy dcache.obj objects +del dcache.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc50 -w-pro msdos\borland\tempnam.c +copy tempnam.obj objects +del tempnam.obj +bcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\bcc50 -w-pro msdos\borland\utime.c +copy utime.obj objects +del utime.obj +tlink @msdos\borland\bcc50\objswp.rsp,dmake.exe,NUL.MAP,@msdos\borland\bcc50\libswp.rsp +copy msdos\borland\bcc50\template.mk startup\config.mk diff --git a/dmake/msdos/borland/bcc50/obj.rsp b/dmake/msdos/borland/bcc50/obj.rsp new file mode 100644 index 000000000000..08ea653f70f4 --- /dev/null +++ b/dmake/msdos/borland/bcc50/obj.rsp @@ -0,0 +1,34 @@ +e:\cc\borland\bcc50\lib\c0x32.obj+ +objects\infer.obj+ +objects\make.obj+ +objects\stat.obj+ +objects\expand.obj+ +objects\dmstring.obj+ +objects\hash.obj+ +objects\dag.obj+ +objects\dmake.obj+ +objects\path.obj+ +objects\imacs.obj+ +objects\sysintf.obj+ +objects\parse.obj+ +objects\getinp.obj+ +objects\quit.obj+ +objects\state.obj+ +objects\dmdump.obj+ +objects\macparse.obj+ +objects\rulparse.obj+ +objects\percent.obj+ +objects\function.obj+ +objects\ruletab.obj+ +objects\dirbrk.obj+ +objects\runargv.obj+ +objects\arlib.obj+ +objects\dchdir.obj+ +objects\switchar.obj+ +objects\rmprq.obj+ +objects\find.obj+ +objects\tee.obj+ +objects\dirlib.obj+ +objects\dcache.obj+ +objects\tempnam.obj+ +objects\utime.obj diff --git a/dmake/msdos/borland/bcc50/objswp.rsp b/dmake/msdos/borland/bcc50/objswp.rsp new file mode 100644 index 000000000000..712d47f47504 --- /dev/null +++ b/dmake/msdos/borland/bcc50/objswp.rsp @@ -0,0 +1,36 @@ +e:\cc\borland\bcc40\lib\c0l.obj+ +objects\exec.obj+ +objects\infer.obj+ +objects\make.obj+ +objects\stat.obj+ +objects\expand.obj+ +objects\dmstring.obj+ +objects\hash.obj+ +objects\dag.obj+ +objects\dmake.obj+ +objects\path.obj+ +objects\imacs.obj+ +objects\sysintf.obj+ +objects\parse.obj+ +objects\getinp.obj+ +objects\quit.obj+ +objects\state.obj+ +objects\dmdump.obj+ +objects\macparse.obj+ +objects\rulparse.obj+ +objects\percent.obj+ +objects\function.obj+ +objects\ruletab.obj+ +objects\dirbrk.obj+ +objects\runargv.obj+ +objects\arlib.obj+ +objects\dchdir.obj+ +objects\switchar.obj+ +objects\rmprq.obj+ +objects\spawn.obj+ +objects\find.obj+ +objects\dirlib.obj+ +objects\dstrlwr.obj+ +objects\dcache.obj+ +objects\tempnam.obj+ +objects\utime.obj diff --git a/dmake/msdos/borland/bcc50/public.h b/dmake/msdos/borland/bcc50/public.h new file mode 100644 index 000000000000..3130d161c24e --- /dev/null +++ b/dmake/msdos/borland/bcc50/public.h @@ -0,0 +1,169 @@ +/* RCS $Id: public.h,v 1.1.1.1 2000-09-22 15:33:29 hr Exp $ +-- WARNING -- This file is AUTOMATICALLY GENERATED DO NOT EDIT IT +-- +-- +-- SYNOPSIS +-- Local functions exported to be visible by others. +-- +-- DESCRIPTION +-- This file is generated by 'genpub'. Function declarations +-- that appear in this file are extracted by 'genpub' from +-- source files. Any function in the source file whose definition +-- appears like: +-- +-- PUBLIC return_type +-- function( arg_list ); +-- type_expr1 arg1; +-- ... +-- +-- has its definition extracted and a line of the form: +-- +-- return_type function ANSI((type_expr1,type_expr2,...)); +-- +-- entered into the output file. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef _DMAKE_PUBLIC_h +#define _DMAKE_PUBLIC_h + +#ifdef EXTERN +#undef EXTERN +#endif +#if defined(DEFINE_DMAKE_VARIABLES) +#define EXTERN +#else +#define EXTERN extern +#endif + +/***** genpub: Begin list of generated function headers */ +void Infer_recipe ANSI((CELLPTR, CELLPTR)); +int Make_targets ANSI(()); +int Make ANSI((CELLPTR, CELLPTR)); +int Exec_commands ANSI((CELLPTR)); +void Print_cmnd ANSI((char *, int, int)); +int Push_dir ANSI((char *, char *, int)); +void Pop_dir ANSI((int)); +void Append_line ANSI((char *, int, FILE *, char *, int, int)); +void Stat_target ANSI((CELLPTR, int, int)); +char *Expand ANSI((char *)); +char *Apply_edit ANSI((char *, char *, char *, int, int)); +void Map_esc ANSI((char *)); +char* Apply_modifiers ANSI((int, char *)); +char* Tokenize ANSI((char *, char *, char, int)); +char* ScanToken ANSI((char *, char **, int)); +char *DmStrJoin ANSI((char *, char *, int, int)); +char *DmStrAdd ANSI((char *, char *, int)); +char *DmStrApp ANSI((char *, char *)); +char *DmStrDup ANSI((char *)); +char *DmStrDup2 ANSI((char *)); +char *DmStrPbrk ANSI((char *, char *)); +char *DmStrSpn ANSI((char *, char *)); +char *DmStrStr ANSI((char *, char *)); +char *DmSubStr ANSI((char *, char *)); +uint16 Hash ANSI((char *, uint32 *)); +HASHPTR Get_name ANSI((char *, HASHPTR *, int)); +HASHPTR Search_table ANSI((HASHPTR *, char *, uint16 *, uint32 *)); +HASHPTR Push_macro ANSI((HASHPTR)); +HASHPTR Pop_macro ANSI((HASHPTR)); +HASHPTR Def_macro ANSI((char *, char *, int)); +CELLPTR Def_cell ANSI((char *)); +LINKPTR Add_prerequisite ANSI((CELLPTR, CELLPTR, int, int)); +void Clear_prerequisites ANSI((CELLPTR)); +int Test_circle ANSI((CELLPTR, int)); +STRINGPTR Def_recipe ANSI((char *, STRINGPTR, int, int)); +t_attr Rcp_attribute ANSI((char *)); +void main ANSI((int, char **)); +FILE *Openfile ANSI((char *, int, int)); +FILE *Closefile ANSI(()); +FILE *Search_file ANSI((char *, char **)); +char *Filename ANSI(()); +int Nestlevel ANSI(()); +FILE *TryFiles ANSI((LINKPTR)); +void Fatal ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Error ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Warning ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void No_ram ANSI(()); +void Usage ANSI((int)); +void Version ANSI(()); +char *Get_suffix ANSI((char *)); +char *Basename ANSI((char *)); +char *Filedir ANSI((char *)); +char *Build_path ANSI((char *, char *)); +void Make_rules ANSI(()); +void Create_macro_vars ANSI(()); +time_t Do_stat ANSI((char *, char *, char **, int)); +int Do_touch ANSI((char *, char *, char **)); +void Void_lib_cache ANSI((char *, char *)); +time_t Do_time ANSI(()); +int Do_cmnd ANSI((char *, int, int, CELLPTR, int, int, int)); +char ** Pack_argv ANSI((int, int, char *)); +char *Read_env_string ANSI((char *)); +int Write_env_string ANSI((char *, char *)); +void ReadEnvironment ANSI(()); +void Catch_signals ANSI((void (*)())); +void Clear_signals ANSI(()); +void Prolog ANSI((int, char* [])); +void Epilog ANSI((int)); +char *Get_current_dir ANSI(()); +int Set_dir ANSI((char*)); +char Get_switch_char ANSI(()); +FILE* Get_temp ANSI((char **, char *, int)); +FILE *Start_temp ANSI((char *, CELLPTR, char **)); +void Open_temp_error ANSI((char *, char *)); +void Link_temp ANSI((CELLPTR, FILE *, char *)); +void Close_temp ANSI((CELLPTR, FILE *)); +void Unlink_temp_files ANSI((CELLPTR)); +void Handle_result ANSI((int, int, int, CELLPTR)); +void Update_time_stamp ANSI((CELLPTR)); +int Remove_file ANSI((char *)); +void Parse ANSI((FILE *)); +int Get_line ANSI((char *, FILE *)); +char *Do_comment ANSI((char *, char **, int)); +char *Get_token ANSI((TKSTRPTR, char *, int)); +void Quit ANSI(()); +void Read_state ANSI(()); +void Write_state ANSI(()); +int Check_state ANSI((CELLPTR, STRINGPTR *, int)); +void Dump ANSI(()); +void Dump_recipe ANSI((STRINGPTR)); +int Parse_macro ANSI((char *, int)); +int Macro_op ANSI((char *)); +int Parse_rule_def ANSI((int *)); +int Rule_op ANSI((char *)); +void Add_recipe_to_list ANSI((char *, int, int)); +void Bind_rules_to_targets ANSI((int)); +int Set_group_attributes ANSI((char *)); +DFALINKPTR Match_dfa ANSI((char *)); +void Check_circle_dfa ANSI(()); +void Add_nfa ANSI((char *)); +char *Exec_function ANSI((char *)); +int If_root_path ANSI((char *)); +int runargv ANSI((CELLPTR, int, int, int, int, char *)); +void Clean_up_processes ANSI(()); +int Wait_for_child ANSI((int, int)); +time_t seek_arch ANSI((char*, char*)); +int touch_arch ANSI((char*, char*)); +int dchdir ANSI((char *)); +void Remove_prq ANSI((CELLPTR)); +int spawnvpe ANSI((int, char *, char **, char **)); +void Hook_std_writes ANSI((char *)); +void dstrlwr ANSI((char *, char *)); +time_t CacheStat ANSI((char *, int)); + +#endif diff --git a/dmake/msdos/borland/bcc50/template.mk b/dmake/msdos/borland/bcc50/template.mk new file mode 100644 index 000000000000..51b575677985 --- /dev/null +++ b/dmake/msdos/borland/bcc50/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= msdos + OSRELEASE *:= borland + OSENVIRONMENT *:= bcc50 diff --git a/dmake/msdos/borland/config.mk b/dmake/msdos/borland/config.mk new file mode 100644 index 000000000000..42361968671d --- /dev/null +++ b/dmake/msdos/borland/config.mk @@ -0,0 +1,46 @@ +# This is the Turbo C++ 2.0 DOS configuration file for DMAKE +# It simply modifies the values of SRC, and checks to see if +# OSENVIRONMENT is defined. If so it includes the appropriate +# config.mk file. +# +# It also sets the values of .SOURCE.c and .SOURCE.h to include the local +# directory. +# +osrdir := $(OS)$(DIRSEPSTR)$(OSRELEASE) + +# The following sources are required for TURBO C++ 2.0 +OSR_SRC = tempnam.c utime.c +.SETDIR=$(osrdir) : $(OSR_SRC) + +SRC += $(OSR_SRC) +.SOURCE.h : $(osrdir) + +# Local configuration modifications for CFLAGS. Make sure your turboc.cfg +# file contains a -D__STDC__=1 and -DM_I86=1, if not then uncomment the line +# below! +#CFLAGS += -DM_I86=1 -D__STDC__=1 + +# You can get a smaller executable still, buy adding a -1 to the list of +# flags below, but then you can't run this on an 8086/88 cpu. +#CFLAGS += -1 +CFLAGS += -I$(osrdir) -d -O -N- -w-nod $(C_$(MODEL)) +ASFLAGS += -t -mx $(S_$(MODEL)) + +# Debugging information for Turbo-C +DB_CFLAGS += -v +DB_LDFLAGS += /v + +# See if we modify anything in the lower levels. +.IF $(OSENVIRONMENT) != $(NULL) + .INCLUDE .IGNORE : $(osrdir)$(DIRSEPSTR)$(OSENVIRONMENT)$(DIRSEPSTR)config.mk +.END + +C_s = +C_m = -mm +C_c = -mc +C_l = -ml + +S_s = -dmsmall +S_m = -dmmedium +S_c = -dmcompact +S_l = -dmlarge diff --git a/dmake/msdos/borland/tcc20/config.h b/dmake/msdos/borland/tcc20/config.h new file mode 100644 index 000000000000..fdf421e87910 --- /dev/null +++ b/dmake/msdos/borland/tcc20/config.h @@ -0,0 +1,48 @@ +/* RCS $Id: config.h,v 1.1.1.1 2000-09-22 15:33:29 hr Exp $ +-- +-- SYNOPSIS +-- Configurarion include file. +-- +-- DESCRIPTION +-- There is one of these for each specific machine configuration. +-- It can be used to further tweek the machine specific sources +-- so that they compile. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +/* define this for configurations that don't have the coreleft function + * so that the code compiles. To my knowledge coreleft exists only on + * Turbo C, but it is needed here since the function is used in many debug + * macros. */ +/*#define coreleft() 0L*/ +extern unsigned int coreleft(); + +#define SIGQUIT SIGTERM /* turbo C doesn't understand SIGQUIT */ + +/* Turbo-C understands const declarations. */ +#define CONST const + +#ifndef MSDOS +# define MSDOS 1 +#endif + +/* a small problem with pointer to voids on some unix machines needs this */ +#define PVOID void * + +/* Have to pull this in for the standard lib defines */ +#include <io.h> diff --git a/dmake/msdos/borland/tcc20/config.mk b/dmake/msdos/borland/tcc20/config.mk new file mode 100644 index 000000000000..e7c53757d2b6 --- /dev/null +++ b/dmake/msdos/borland/tcc20/config.mk @@ -0,0 +1,10 @@ +# Definition of macros for library, and C startup code. +osedir = $(osrdir)$(DIRSEPSTR)$(OSENVIRONMENT) + +LDLIBS = e:/cc/borland/tcc20/lib/c$(MODEL) +CSTARTUP = e:/cc/borland/tcc20/lib/c0$(MODEL).obj + +CFLAGS += -I$(osedir) -f- + +# Case of identifiers is significant +NDB_LDFLAGS += -c diff --git a/dmake/msdos/borland/tcc20/libswp.rsp b/dmake/msdos/borland/tcc20/libswp.rsp new file mode 100644 index 000000000000..68d583f00580 --- /dev/null +++ b/dmake/msdos/borland/tcc20/libswp.rsp @@ -0,0 +1 @@ +e:\cc\borland\tcc20\lib\cl diff --git a/dmake/msdos/borland/tcc20/mkswp.bat b/dmake/msdos/borland/tcc20/mkswp.bat new file mode 100755 index 000000000000..52f6748e8ef3 --- /dev/null +++ b/dmake/msdos/borland/tcc20/mkswp.bat @@ -0,0 +1,107 @@ +md objects +tasm -t -mx -dmlarge msdos\exec.asm,,,; +mv exec.obj objects +tcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\tcc20 -f- infer.c +copy infer.obj objects +del infer.obj +tcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\tcc20 -f- make.c +copy make.obj objects +del make.obj +tcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\tcc20 -f- stat.c +copy stat.obj objects +del stat.obj +tcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\tcc20 -f- expand.c +copy expand.obj objects +del expand.obj +tcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\tcc20 -f- dmstring.c +copy dmstring.obj objects +del dmstring.obj +tcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\tcc20 -f- hash.c +copy hash.obj objects +del hash.obj +tcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\tcc20 -f- dag.c +copy dag.obj objects +del dag.obj +tcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\tcc20 -f- dmake.c +copy dmake.obj objects +del dmake.obj +tcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\tcc20 -f- path.c +copy path.obj objects +del path.obj +tcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\tcc20 -f- imacs.c +copy imacs.obj objects +del imacs.obj +tcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\tcc20 -f- sysintf.c +copy sysintf.obj objects +del sysintf.obj +tcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\tcc20 -f- parse.c +copy parse.obj objects +del parse.obj +tcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\tcc20 -f- getinp.c +copy getinp.obj objects +del getinp.obj +tcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\tcc20 -f- quit.c +copy quit.obj objects +del quit.obj +tcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\tcc20 -f- state.c +copy state.obj objects +del state.obj +tcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\tcc20 -f- dmdump.c +copy dmdump.obj objects +del dmdump.obj +tcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\tcc20 -f- macparse.c +copy macparse.obj objects +del macparse.obj +tcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\tcc20 -f- rulparse.c +copy rulparse.obj objects +del rulparse.obj +tcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\tcc20 -f- percent.c +copy percent.obj objects +del percent.obj +tcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\tcc20 -f- function.c +copy function.obj objects +del function.obj +tcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\tcc20 -f- msdos\ruletab.c +copy ruletab.obj objects +del ruletab.obj +tcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\tcc20 -f- msdos\dirbrk.c +copy dirbrk.obj objects +del dirbrk.obj +tcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\tcc20 -f- msdos\runargv.c +copy runargv.obj objects +del runargv.obj +tcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\tcc20 -f- msdos\arlib.c +copy arlib.obj objects +del arlib.obj +tcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\tcc20 -f- msdos\dchdir.c +copy dchdir.obj objects +del dchdir.obj +tcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\tcc20 -f- msdos\switchar.c +copy switchar.obj objects +del switchar.obj +tcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\tcc20 -f- msdos\rmprq.c +copy rmprq.obj objects +del rmprq.obj +tcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\tcc20 -f- msdos\spawn.c +copy spawn.obj objects +del spawn.obj +tcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\tcc20 -f- msdos\find.c +copy find.obj objects +del find.obj +tcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\tcc20 -f- msdos\dirlib.c +copy dirlib.obj objects +del dirlib.obj +tcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\tcc20 -f- msdos\dstrlwr.c +copy dstrlwr.obj objects +del dstrlwr.obj +tcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\tcc20 -f- unix\dcache.c +copy dcache.obj objects +del dcache.obj +tcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\tcc20 -f- msdos\borland\tempnam.c +copy tempnam.obj objects +del tempnam.obj +tcc -c -I. -Imsdos -Imsdos\borland -d -O -N- -w-nod -ml -Imsdos\borland\tcc20 -f- msdos\borland\utime.c +copy utime.obj objects +del utime.obj +tlink /c @msdos\borland\tcc20\objswp.rsp,dmake.exe,NUL.MAP,@msdos\borland\tcc20\libswp.rsp +copy msdos\borland\tcc20\template.mk startup\config.mk diff --git a/dmake/msdos/borland/tcc20/objswp.rsp b/dmake/msdos/borland/tcc20/objswp.rsp new file mode 100644 index 000000000000..c177fda3efbd --- /dev/null +++ b/dmake/msdos/borland/tcc20/objswp.rsp @@ -0,0 +1,36 @@ +e:\cc\borland\tcc20\lib\c0l.obj+ +objects\exec.obj+ +objects\infer.obj+ +objects\make.obj+ +objects\stat.obj+ +objects\expand.obj+ +objects\dmstring.obj+ +objects\hash.obj+ +objects\dag.obj+ +objects\dmake.obj+ +objects\path.obj+ +objects\imacs.obj+ +objects\sysintf.obj+ +objects\parse.obj+ +objects\getinp.obj+ +objects\quit.obj+ +objects\state.obj+ +objects\dmdump.obj+ +objects\macparse.obj+ +objects\rulparse.obj+ +objects\percent.obj+ +objects\function.obj+ +objects\ruletab.obj+ +objects\dirbrk.obj+ +objects\runargv.obj+ +objects\arlib.obj+ +objects\dchdir.obj+ +objects\switchar.obj+ +objects\rmprq.obj+ +objects\spawn.obj+ +objects\find.obj+ +objects\dirlib.obj+ +objects\dstrlwr.obj+ +objects\dcache.obj+ +objects\tempnam.obj+ +objects\utime.obj diff --git a/dmake/msdos/borland/tcc20/public.h b/dmake/msdos/borland/tcc20/public.h new file mode 100644 index 000000000000..3130d161c24e --- /dev/null +++ b/dmake/msdos/borland/tcc20/public.h @@ -0,0 +1,169 @@ +/* RCS $Id: public.h,v 1.1.1.1 2000-09-22 15:33:29 hr Exp $ +-- WARNING -- This file is AUTOMATICALLY GENERATED DO NOT EDIT IT +-- +-- +-- SYNOPSIS +-- Local functions exported to be visible by others. +-- +-- DESCRIPTION +-- This file is generated by 'genpub'. Function declarations +-- that appear in this file are extracted by 'genpub' from +-- source files. Any function in the source file whose definition +-- appears like: +-- +-- PUBLIC return_type +-- function( arg_list ); +-- type_expr1 arg1; +-- ... +-- +-- has its definition extracted and a line of the form: +-- +-- return_type function ANSI((type_expr1,type_expr2,...)); +-- +-- entered into the output file. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef _DMAKE_PUBLIC_h +#define _DMAKE_PUBLIC_h + +#ifdef EXTERN +#undef EXTERN +#endif +#if defined(DEFINE_DMAKE_VARIABLES) +#define EXTERN +#else +#define EXTERN extern +#endif + +/***** genpub: Begin list of generated function headers */ +void Infer_recipe ANSI((CELLPTR, CELLPTR)); +int Make_targets ANSI(()); +int Make ANSI((CELLPTR, CELLPTR)); +int Exec_commands ANSI((CELLPTR)); +void Print_cmnd ANSI((char *, int, int)); +int Push_dir ANSI((char *, char *, int)); +void Pop_dir ANSI((int)); +void Append_line ANSI((char *, int, FILE *, char *, int, int)); +void Stat_target ANSI((CELLPTR, int, int)); +char *Expand ANSI((char *)); +char *Apply_edit ANSI((char *, char *, char *, int, int)); +void Map_esc ANSI((char *)); +char* Apply_modifiers ANSI((int, char *)); +char* Tokenize ANSI((char *, char *, char, int)); +char* ScanToken ANSI((char *, char **, int)); +char *DmStrJoin ANSI((char *, char *, int, int)); +char *DmStrAdd ANSI((char *, char *, int)); +char *DmStrApp ANSI((char *, char *)); +char *DmStrDup ANSI((char *)); +char *DmStrDup2 ANSI((char *)); +char *DmStrPbrk ANSI((char *, char *)); +char *DmStrSpn ANSI((char *, char *)); +char *DmStrStr ANSI((char *, char *)); +char *DmSubStr ANSI((char *, char *)); +uint16 Hash ANSI((char *, uint32 *)); +HASHPTR Get_name ANSI((char *, HASHPTR *, int)); +HASHPTR Search_table ANSI((HASHPTR *, char *, uint16 *, uint32 *)); +HASHPTR Push_macro ANSI((HASHPTR)); +HASHPTR Pop_macro ANSI((HASHPTR)); +HASHPTR Def_macro ANSI((char *, char *, int)); +CELLPTR Def_cell ANSI((char *)); +LINKPTR Add_prerequisite ANSI((CELLPTR, CELLPTR, int, int)); +void Clear_prerequisites ANSI((CELLPTR)); +int Test_circle ANSI((CELLPTR, int)); +STRINGPTR Def_recipe ANSI((char *, STRINGPTR, int, int)); +t_attr Rcp_attribute ANSI((char *)); +void main ANSI((int, char **)); +FILE *Openfile ANSI((char *, int, int)); +FILE *Closefile ANSI(()); +FILE *Search_file ANSI((char *, char **)); +char *Filename ANSI(()); +int Nestlevel ANSI(()); +FILE *TryFiles ANSI((LINKPTR)); +void Fatal ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Error ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Warning ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void No_ram ANSI(()); +void Usage ANSI((int)); +void Version ANSI(()); +char *Get_suffix ANSI((char *)); +char *Basename ANSI((char *)); +char *Filedir ANSI((char *)); +char *Build_path ANSI((char *, char *)); +void Make_rules ANSI(()); +void Create_macro_vars ANSI(()); +time_t Do_stat ANSI((char *, char *, char **, int)); +int Do_touch ANSI((char *, char *, char **)); +void Void_lib_cache ANSI((char *, char *)); +time_t Do_time ANSI(()); +int Do_cmnd ANSI((char *, int, int, CELLPTR, int, int, int)); +char ** Pack_argv ANSI((int, int, char *)); +char *Read_env_string ANSI((char *)); +int Write_env_string ANSI((char *, char *)); +void ReadEnvironment ANSI(()); +void Catch_signals ANSI((void (*)())); +void Clear_signals ANSI(()); +void Prolog ANSI((int, char* [])); +void Epilog ANSI((int)); +char *Get_current_dir ANSI(()); +int Set_dir ANSI((char*)); +char Get_switch_char ANSI(()); +FILE* Get_temp ANSI((char **, char *, int)); +FILE *Start_temp ANSI((char *, CELLPTR, char **)); +void Open_temp_error ANSI((char *, char *)); +void Link_temp ANSI((CELLPTR, FILE *, char *)); +void Close_temp ANSI((CELLPTR, FILE *)); +void Unlink_temp_files ANSI((CELLPTR)); +void Handle_result ANSI((int, int, int, CELLPTR)); +void Update_time_stamp ANSI((CELLPTR)); +int Remove_file ANSI((char *)); +void Parse ANSI((FILE *)); +int Get_line ANSI((char *, FILE *)); +char *Do_comment ANSI((char *, char **, int)); +char *Get_token ANSI((TKSTRPTR, char *, int)); +void Quit ANSI(()); +void Read_state ANSI(()); +void Write_state ANSI(()); +int Check_state ANSI((CELLPTR, STRINGPTR *, int)); +void Dump ANSI(()); +void Dump_recipe ANSI((STRINGPTR)); +int Parse_macro ANSI((char *, int)); +int Macro_op ANSI((char *)); +int Parse_rule_def ANSI((int *)); +int Rule_op ANSI((char *)); +void Add_recipe_to_list ANSI((char *, int, int)); +void Bind_rules_to_targets ANSI((int)); +int Set_group_attributes ANSI((char *)); +DFALINKPTR Match_dfa ANSI((char *)); +void Check_circle_dfa ANSI(()); +void Add_nfa ANSI((char *)); +char *Exec_function ANSI((char *)); +int If_root_path ANSI((char *)); +int runargv ANSI((CELLPTR, int, int, int, int, char *)); +void Clean_up_processes ANSI(()); +int Wait_for_child ANSI((int, int)); +time_t seek_arch ANSI((char*, char*)); +int touch_arch ANSI((char*, char*)); +int dchdir ANSI((char *)); +void Remove_prq ANSI((CELLPTR)); +int spawnvpe ANSI((int, char *, char **, char **)); +void Hook_std_writes ANSI((char *)); +void dstrlwr ANSI((char *, char *)); +time_t CacheStat ANSI((char *, int)); + +#endif diff --git a/dmake/msdos/borland/tcc20/template.mk b/dmake/msdos/borland/tcc20/template.mk new file mode 100644 index 000000000000..3cac6b22a240 --- /dev/null +++ b/dmake/msdos/borland/tcc20/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= msdos + OSRELEASE *:= borland + OSENVIRONMENT *:= tcc20 diff --git a/dmake/msdos/borland/tempnam.c b/dmake/msdos/borland/tempnam.c new file mode 100644 index 000000000000..c4d599de5971 --- /dev/null +++ b/dmake/msdos/borland/tempnam.c @@ -0,0 +1,109 @@ +/* RCS $Id: tempnam.c,v 1.1.1.1 2000-09-22 15:33:28 hr Exp $ +-- +-- SYNOPSIS +-- tempnam +-- +-- DESCRIPTION +-- temp file name generation routines. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ +/*LINTLIBRARY*/ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <dos.h> + +#if defined(max) +# undef max +#endif +#define max(A,B) (((A)<(B))?(B):(A)) + +extern char *mktemp(); +extern int access(); +int d_access(); + +/* Turbo C stdio.h doesn't define P_tmpdir, so let's do it here */ +/* Under DOS leave the default tmpdir pointing here! */ +#ifndef P_tmpdir +static char *P_tmpdir = ""; +#endif + +char * +tempnam(dir, prefix) +char *dir; /* use this directory please (if non-NULL) */ +char *prefix; /* use this (if non-NULL) as filename prefix */ +{ + static int count = 0; + register char *p, *q, *tmpdir; + int tl=0, dl=0, pl; + char buf[30]; + + pl = strlen(P_tmpdir); + + if( (tmpdir = getenv("TMPDIR")) != NULL ) tl = strlen(tmpdir); + else if( (tmpdir = getenv("TMP")) != NULL ) tl = strlen(tmpdir); + if( dir != NULL ) dl = strlen(dir); + + if( (p = malloc((unsigned)(max(max(dl,tl),pl)+13))) == NULL ) + return(NULL); + + *p = '\0'; + + if( (tl == 0) || (d_access( strcpy(p, tmpdir), 0) != 0) ) + if( (dl == 0) || (d_access( strcpy(p, dir), 0) != 0) ) + if( d_access( strcpy(p, P_tmpdir), 0) != 0 ) + if( !prefix ) + prefix = "tp"; + + if(prefix) + { + *(p+strlen(p)+2) = '\0'; + (void)strncat(p, prefix, 2); + } + + sprintf( buf, "%08x", _psp ); + buf[6]='\0'; + (void)strcat(p, buf ); + sprintf( buf, "%04d", count++ ); + q=p+strlen(p)-6; + *q++ = buf[0]; *q++ = buf[1]; + *q++ = buf[2]; *q = buf[3]; + + if( (q = strrchr(p,'.')) != NULL ) *q = '\0'; + + return(p); +} + + + +d_access( name, flag ) +char *name; +int flag; +{ + extern char *DirSepStr; + char *p; + int r; + + if( name == NULL || !*name ) return(1); /* NULL dir means current dir */ + r = access( name, flag ); + p = name+strlen(name)-1; + + if(*p != '/' && *p != '\\') strcat( p, DirSepStr ); + + return( r ); +} diff --git a/dmake/msdos/borland/utime.c b/dmake/msdos/borland/utime.c new file mode 100644 index 000000000000..2b87022fe3f1 --- /dev/null +++ b/dmake/msdos/borland/utime.c @@ -0,0 +1,66 @@ +/* RCS $Id: utime.c,v 1.1.1.1 2000-09-22 15:33:28 hr Exp $ +-- +-- SYNOPSIS +-- utime +-- +-- DESCRIPTION +-- chage the last modified time on a file. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ +#include <sys/stat.h> +#include <stdlib.h> +#include <stdio.h> +#include <fcntl.h> +#include <io.h> +#include <time.h> + +int +utime(name, timep)/* +==================== + Broken for turbo C it only sets the file time to the current time by + touching a character in the file */ +char* name; +time_t timep[2]; +{ + struct stat buf; + int fil; + char data; + + if (stat(name, &buf) != 0) + return (-1); + if (buf.st_size != 0) { + if ((fil = open(name, O_RDWR, S_IWRITE)) < 0) + return (-1); + if (read(fil, &data, 1) < 1) { + close(fil); + return (-1); + } + lseek(fil, 0L, 0); + if (write(fil, &data, 1) < 1) { + close(fil); + return (-1); + } + close(fil); + return (0); + } else if ((fil = creat(name, S_IWRITE)) < 0) { + return (-1); + } else { + close(fil); + return (0); + } +} diff --git a/dmake/msdos/config.mk b/dmake/msdos/config.mk new file mode 100644 index 000000000000..77a32bf419de --- /dev/null +++ b/dmake/msdos/config.mk @@ -0,0 +1,71 @@ +# This is an OS specific configuration file +# It assumes that OBJDIR, TARGET and DEBUG are previously defined. +# It defines CFLAGS, LDARGS, CPPFLAGS, STARTUPFILE, LDOBJS +# It augments SRC, OBJDIR, TARGET, CFLAGS, LDLIBS +# + +# Memory model to compile for +# set to s - small, m - medium, c - compact, l - large +# Need large model now, dmake has grown up :-) +MODEL = l + +STARTUPFILE = $(OS)/startup.mk + +CPPFLAGS = $(CFLAGS) +LDOBJS = $(CSTARTUP) $(OBJDIR)/{$(<:f)} +LDARGS = $(LDHEAD) $(LDFLAGS:s/ //) @$(LDTMPOBJ),$(TARGET),NUL.MAP$(LDTAIL) +LDTAIL = $(_libs) +_libs = $(!null,$(LDLIBS) ,@$(LDTMPLIB)) +LDTMPOBJ = $(mktmp,,$(DIVFILE) $(LDOBJS:s,/,\\,:t"+\n")\n) +LDTMPLIB = $(mktmp,,$(DIVFILE) $(LDLIBS:s,/,\\,:t"+\n")\n) + +# Debug flags +DB_CFLAGS = -DDBUG +DB_LDFLAGS = +DB_LDLIBS = + +# NO Debug flags +NDB_CFLAGS = +NDB_LDFLAGS = +NDB_LDLIBS = + +# Local configuration modifications for CFLAGS. +CFLAGS += -I$(OS) + +# Common MSDOS source files. +# Define SWAP to anything but 'y' for the swap code to be excluded on making. +# Swapping for DOS versions is enabled by default. +# Note: swapping is handled specially for ZTC in msdos/zortech/config.mk. +SWAP *= y + +.IF $(OSRELEASE) != zortech + .IF $(SWAP) == y + SWP_SRC += spawn.c + ASRC += exec.asm + .ELSE + SWP_SRC += tee.c + .END +.ELSE + SWP_SRC += tee.c +.END + +OS_SRC += ruletab.c dirbrk.c runargv.c arlib.c dchdir.c switchar.c rmprq.c\ + $(SWP_SRC) find.c dirlib.c dstrlwr.c +UNIXSRC := dcache.c +SRC += $(OS_SRC) $(UNIXSRC) +.SETDIR=$(OS) : $(ASRC) $(OS_SRC) +.SETDIR=unix : $(UNIXSRC) + +# Provide our own %$O : %$S rule. +%$O : %$S + +$(AS) $(ASFLAGS) $(<:s,\,${__.DIVSEP-sh-${USESHELL}},:s,/,${__.DIVSEP-sh-${USESHELL}},),,,; + mv $(@:f) $(OBJDIR) + +# Set source dirs so that we can find files named in this +# config file. +.SOURCE.h : $(OS) + +# See if we modify anything in the lower levels. +.IF $(OSRELEASE) != $(NULL) + .INCLUDE : $(OS)$(DIRSEPSTR)$(OSRELEASE)$(DIRSEPSTR)config.mk +.END diff --git a/dmake/msdos/dchdir.c b/dmake/msdos/dchdir.c new file mode 100644 index 000000000000..19006825b7f6 --- /dev/null +++ b/dmake/msdos/dchdir.c @@ -0,0 +1,47 @@ +/* RCS $Id: dchdir.c,v 1.1.1.1 2000-09-22 15:33:27 hr Exp $ +-- +-- SYNOPSIS +-- Change directory. +-- +-- DESCRIPTION +-- Under DOS change the current drive as well as the current directory. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include <dos.h> +#include "extern.h" + +PUBLIC int +dchdir(path) +char *path; +{ + int res; + + res = chdir(path); + + if (res != -1 && path[1] == ':') { + union REGS reg; + + /* we must change the logged drive, since the chdir worked. */ + reg.h.ah = 0x0E; + reg.h.dl = (*path & ~0x20) - 'A' + 1; + intdos(®, ®); + } + + return (res); +} diff --git a/dmake/msdos/dirbrk.c b/dmake/msdos/dirbrk.c new file mode 100644 index 000000000000..d8aab76b6f96 --- /dev/null +++ b/dmake/msdos/dirbrk.c @@ -0,0 +1,42 @@ +/* RCS $Id: dirbrk.c,v 1.1.1.1 2000-09-22 15:33:27 hr Exp $ +-- +-- SYNOPSIS +-- Define the directory separator string. +-- +-- DESCRIPTION +-- Define this string for any character that may appear in a path name +-- and can be used as a directory separator. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include "extern.h" + +/* dos uses /, \, and : */ +char* DirBrkStr = "/\\:"; + +/* +** Return TRUE if the name is the full specification of a path name to a file +** starting at the root of the file system, otherwise return FALSE +*/ +PUBLIC int +If_root_path(name) +char *name; +{ + return( (strchr(DirBrkStr, *name) != NIL(char)) || + (isalpha(*name) && name[1] == ':') ); +} diff --git a/dmake/msdos/dirent.h b/dmake/msdos/dirent.h new file mode 100644 index 000000000000..24ad5681da59 --- /dev/null +++ b/dmake/msdos/dirent.h @@ -0,0 +1,32 @@ +/* DIRLIB.H by M. J. Weinstein Released to public domain 1-Jan-89 */ + +#ifndef _DIRLIB_h_ +#define _DIRLIB_h_ + +#include <stdio.h> +#include "stdmacs.h" +#include "dosdta.h" + +#define MAXNAMLEN 15 + +struct dirent { + long d_ino; + unsigned short d_reclen; + unsigned short d_namlen; + char d_name[MAXNAMLEN+1]; +}; + +typedef struct { + DTA dd_dta; /* disk transfer area for this dir. */ + short dd_stat; /* status return from last lookup */ + char dd_name[1]; /* full name of file -- struct is extended */ +} DIR; + +extern DIR *opendir ANSI((char *)); +extern struct dirent *readdir ANSI((DIR *)); +extern long telldir ANSI((DIR *)); +extern void seekdir ANSI((DIR *, long)); +extern void closedir ANSI((DIR *)); + +#define rewinddir(dirp) seekdir(dirp,0L) +#endif diff --git a/dmake/msdos/dirlib.c b/dmake/msdos/dirlib.c new file mode 100644 index 000000000000..eaef928772af --- /dev/null +++ b/dmake/msdos/dirlib.c @@ -0,0 +1,285 @@ +/* + DIRLIB for MS-DOS + ----------------- + +Enclosed is an implementation of the `dirlib' package for MS-DOS. +The implementation is targeted for MS-C, although any reasonably +competent C compiler should manage. The package consists of: + + dir.h the header file + dir.c the functions + testdir.c a q&d test program + +The package tries to view directory naming in a Un*x light; in particular, +directories such as '/.' and '/..' (as well as `.' and `..' if your +current directory is root) are understood. Indefinite paths like +`/../.././../..' will correctly refer to the root (of the particular disk). +Names such as `a:////./../' are okay too. + +I've tried to be as sensible about DTA's as possible, since you never +know who will be using one; they are set before use, and reset afterwards. + +There is some cruft in the package, namely the way `seekdir' and +`telldir' are done. The code was derived from a little experimentation, +and may not work after a certain point (although I believe the 2.x version +to be solid). Caveat utilitor. + +Documentation for the package is available in the public domain; the +package's functionality was derived from this documentation. + +Bug reports and comments are welcome. Enjoy! + + - Matt + +------- +UUCP: {ucbvax,ihnp4,randvax,trwrb!trwspp,ism780}!ucla-cs!matt +ARPA: matt@LOCUS.UCLA.EDU +Ph: (213) 825-2756 + +-------- +Modified for use in dmake by Dennis Vadura. Mostly just clean up and an +effort to make correctly typed objects are passed to functions in find.c. +Also deleted all dos version 2.0 specific code. It is not required any +more. +*/ + +/* + * revision history: + * + * VER MM/DD/YY COMMENTS + * ---- -------- -------- + * 0.99 02/24/86 Beta release to INTERNET + */ + +#include <stdlib.h> +#include <ctype.h> +#include <errno.h> +#include <string.h> +#include <dos.h> + +#include "dirent.h" + +extern int find_err; + + +static char * +getdcwd(drive) +int drive; +{ + union REGS r; + struct SREGS s; + static char xcwd[64]; + char far *cwd = xcwd; + + r.h.ah = 0x47; + r.h.dl = drive; + r.x.si = FP_OFF(cwd); + s.ds = FP_SEG(cwd); + intdosx(&r, &r, &s); + find_err = r.x.ax; + if (r.x.cflag) + return (char *) 0; + return xcwd; +} + + + +/* + * opendir + */ + +#define SUFFIX "\\*.*" +#define SLASH "\\" +#define streq(a,b) (strcmp(a,b)==0) + +DIR * +opendir(name) +char *name; +{ + register DIR *nd; + char *cwd; + char drive[3]; + int atroot = 0; + int rooted = 0; + + /* + * hack off drive designator if present + */ + + if (name[1] == ':') { + cwd = getdcwd(toupper(name[0]) - 'A' + 1); + drive[0] = name[0]; drive[1] = ':'; drive[2] = '\0'; + name += 2; + } + else { + cwd = getdcwd(0); + drive[0] = '\0'; + } + + /* is the name 'rooted'? */ + if ((*name == '/') || (*name == '\\')) ++rooted; + + /* see if we are at the root directory for this device */ + if (!*cwd) ++atroot; + + /* + * MSDOS '/' doesn't have a '.' or '..' + * also, double '/' sequences don't make sense. + * many ported programs expect them to work, so we fix it up... + */ + + /* chop off leading . and .. if at root */ + if (atroot && (*name == '.')) { + switch (*++name) { + case '\0': + case '/': + case '\\': + break; + + case '.': + switch (*++name) { + case '\0': + case '/': + case '\\': + break; + default: + --name; + --name; + } + break; + + default: + --name; + } + } + + /* chop off leading /'s, /.'s and /..'s to make naming sensible */ + while (*name && ((*name == '/') || (*name == '\\'))) { + if (*++name == '.') { + switch (*++name) { + case '\0': + case '/': + case '\\': + break; + + case '.': + switch (*++name) { + case '\0': + case '/': + case '\\': + break; + + default: + --name; + --name; + } + break; + + default: + --name; + } + } + } + + + /* + * name should now look like: path/path/path + * we must now construct name based on whether or not it + * was 'rooted' (started with a /) + */ + + if (rooted) cwd = ""; + + /* construct DIR */ + if (!(nd = (DIR *)malloc( + sizeof(DIR)+strlen(drive)+strlen(cwd)+strlen(SLASH)+ + strlen(name)+strlen(SUFFIX)))) + return (DIR *) 0; + + /* create long name */ + strcpy(nd->dd_name, drive); + if (*cwd) { + strcat(nd->dd_name, SLASH); + strcat(nd->dd_name, cwd); + } + if (*name) { + strcat(nd->dd_name, SLASH); + strcat(nd->dd_name, name); + } + strcat(nd->dd_name, SUFFIX); + + /* search */ + if (!findfirst(&nd->dd_name[0], &nd->dd_dta)) { + free((char *)nd); + errno = ENOENT; + return (DIR *) 0; + } + nd->dd_stat = 0; + return nd; +} + + +struct dirent * +readdir(dirp) +DIR *dirp; +{ + static struct dirent dir; + + if (dirp->dd_stat) + return (struct dirent *) 0; + + /* format structure */ + dir.d_ino = 0; /* not valid for DOS */ + dir.d_reclen = 0; + strcpy(dir.d_name, dirp->dd_dta.name); + dir.d_namlen = strlen(dir.d_name); + strlwr(dir.d_name); /* DOSism */ + + /* read ahead */ + if (findnext(&dirp->dd_dta) != NULL) + dirp->dd_stat = 0; + else + dirp->dd_stat = find_err; + + return &dir; +} + + +void +closedir(dirp) +DIR *dirp; +{ + free((char *)dirp); +} + + +void +seekdir(dirp, pos) +DIR *dirp; +long pos; +{ + /* + * check against DOS limits + */ + + if ((pos < 0) || (pos > 4095)) { + dirp->dd_stat = 1; + return; + } + + *(short *)&dirp->dd_dta.fcb[13] = pos + 1; + + /* read ahead */ + if (findnext(&dirp->dd_dta)) + dirp->dd_stat = 0; + else + dirp->dd_stat = find_err; +} + + +long +telldir(dirp) +DIR *dirp; +{ + return (long) (*(short *)&dirp->dd_dta.fcb[13] - 2); +} diff --git a/dmake/msdos/dosdta.h b/dmake/msdos/dosdta.h new file mode 100644 index 000000000000..c9642715d937 --- /dev/null +++ b/dmake/msdos/dosdta.h @@ -0,0 +1,16 @@ +#ifndef _DOSDTA_ +#define _DOSDTA_ + +#include "stdmacs.h" +typedef struct { + char fcb[21]; + char attr; + short time; + short date; + long size; + char name[13]; +} DTA; + +extern DTA *findfirst ANSI((char *, DTA *)); +extern DTA *findnext ANSI((DTA *)); +#endif diff --git a/dmake/msdos/dstrlwr.c b/dmake/msdos/dstrlwr.c new file mode 100644 index 000000000000..64027eb36481 --- /dev/null +++ b/dmake/msdos/dstrlwr.c @@ -0,0 +1,49 @@ +/* RCS $Id: dstrlwr.c,v 1.1.1.1 2000-09-22 15:33:27 hr Exp $ +-- +-- SYNOPSIS +-- Rotines for computing case mappings in Win95/NT environments. +-- +-- DESCRIPTION +-- This code is an attempt at providing sane case mappings to help +-- deal with the disparity in file name case between 8.3 and long +-- file names under Win95/NT. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ +#include "extern.h" + +PUBLIC void +dstrlwr(entry, target) +char *entry; +char *target; +{ + char *p; + + if (STOBOOL(DcacheRespCase)) + return; + + /* Look for the target being lower case, if so then lower the case + * of the directory entry. Note that we only check the first + * character of the target. This is a bit of a kludge but there is + * really no other way to know, particularly since this test will be + * performed for each member of the directory but against the same + * target. */ + if (islower(*target)) + strlwr(entry); + + return; +} diff --git a/dmake/msdos/exec.asm b/dmake/msdos/exec.asm new file mode 100644 index 000000000000..db745aece6b2 --- /dev/null +++ b/dmake/msdos/exec.asm @@ -0,0 +1,1234 @@ +; +; DESCRIPTION +; This code is a model independent version of DOS exec that will swap +; the calling process out to secondary storage prior to running the +; child. The prototype for calling the exec function is below. +; +; exec( int swap, char far *program, char far *cmdtail, +; int environment_seg, char far *tmpfilename ); +; +; +; To assemble this file issue the command: +; +; tasm /mx /t /dmmodel exec.asm +; +; where 'model' is one of {small, compact, medium, large}, you may +; also use MASM 5.1 to assemble this file, in this case simply replace +; 'tasm' with 'masm' in the above command line. +; +; AUTHOR +; Dennis Vadura, dvadura@watdragon.uwaterloo.ca +; CS DEPT, University of Waterloo, Waterloo, Ont., Canada +; +; COPYRIGHT +; Copyright (c) 1990 by Dennis Vadura. All rights reserved. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; (version 1), as published by the Free Software Foundation, and +; found in the file 'LICENSE' included with this distribution. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warrant of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +; +ifdef have286 + .286 ; define have286 with -D for 80286 processor or better + mpusha Macro + pusha + Endm + + mpopa Macro + popa + Endm + +else ; 8088/8086 compatible + mpusha Macro + push ax + push cx + push dx + push bx + push sp + push bp + push si + push di + Endm + + mpopa Macro + pop di + pop si + pop bp + add sp,2 + pop bx + pop dx + pop cx + pop ax + Endm +endif + +ifdef msmall + .model small +argbase equ 4 +endif +ifdef mcompact + .model compact +argbase equ 4 +endif +ifdef mmedium + .model medium +argbase equ 6 +endif +ifdef mlarge + .model large +argbase equ 6 +endif +a_swap equ <bp+argbase+0> +a_prog equ <bp+argbase+2> +a_tail equ <bp+argbase+6> +a_env equ <bp+argbase+10> +a_tmp equ <bp+argbase+12> + +a_handle equ <bp+argbase> + + +; Define all useful equ's +swap_xms equ 0 ; we swapped it out to xms +swap_ems equ 2 ; we swapped it out to ems +swap_file equ 4 ; we swapped it out to a file +seg_no_alloc equ 0 ; this is part of a segment +seg_alloc equ 1 ; this is a full segment header +seg_data equ 2 ; this is data for part of a segment + + +; Define any global/external variables that we will be accessing from here. + .data + extrn _errno:word ; Set to dos ret code from exec + public _Interrupted ; Set to 1 if interrupted 0 +_Interrupted dw 0 ; otherwise + + .code + assume cs:@code, ds:@code, ss:@code, es:@code + + even +execstack dw 64 dup (?) ; put the temporary exec stack right +exec_sp label word ; at the start. + +old_ss dw ? ; save stack seg across exec +old_sp dw ? ; save stack ptr across exec +progsize dw ? ; original size of the program +rootsize dw ? ; size of base root kept during swap +resend dw ? ; paragraph where resident code ends +envseg dw ? ; paragraph of environment segment +psp dw ? ; our own psp +swap dw ? ; swapping selection flag +eretcode dw ? ; return code from exec +interrupted dw ? ; interrupted flag for exec +arenahead dw ? ; start of memory block list +alstr dw ? ; allocation strategy save spot +in_exec dw 0 ; flag, 1 ==> in exec + +cmdpath db 65 dup(?) ; file to exec +cmdtail db 129 dup(?) ; its command tail +fcb db 37 dup(0) ; dummy fcb +tmpseg db 7 dup(?) ; block header buffer + +tmpname db 65 dup(0) ; name of temporary file resource + + even +tmphandle dw ? ; handle for temporary file +real_21h dd 0 ; will be DOS's 21h vector if doing -C + +std_fil_handle dw ? ; file handle for -C file +std_fil_number db ? ; system file number for -C file +our_stdout db ? ; sys file number our stdout handle + +error_rhdr db "exec: Failure reading header block", 0DH, 0AH, '$' +error_rseg db "exec: Failure reading segment data", 0DH, 0AH, '$' +error_resize db "exec: Failure on resize", 0DH, 0AH, '$' +error_free db "exec: Failure to free a block", 0DH, 0AH, '$' +error_string db "exec: Program swap failure", 0DH, 0AH, '$' +error_alloc db "exec: Memory blocks don't match", 0DH, 0AH, '$' + + even +write_header label word + whdr_xms_ptr dw word ptr whdr_xms + whdr_ems_ptr dw word ptr whdr_ems + whdr_file_ptr dw word ptr whdr_file + +write_seg label word + wseg_xms_ptr dw word ptr wseg_xms + wseg_ems_ptr dw word ptr wseg_ems + wseg_file_ptr dw word ptr wseg_file + +read_header label word + rhdr_xms_ptr dw word ptr rhdr_xms + rhdr_ems_ptr dw word ptr rhdr_ems + rhdr_file_ptr dw word ptr rhdr_file + +read_seg label word + rseg_xms_ptr dw word ptr rseg_xms + rseg_ems_ptr dw word ptr rseg_ems + rseg_file_ptr dw word ptr rseg_file + +free_resource label word + free_xms_ptr dw word ptr free_xms_resource + free_ems_ptr dw word ptr free_ems_resource + free_file_ptr dw word ptr free_file_resource + +reset_resource label word + reset_xms_ptr dw word ptr reset_xms_resource + reset_ems_ptr dw word ptr reset_ems_resource + reset_file_ptr dw word ptr reset_file_resource + +old_ctl_brk label dword + old_ctl_brk_off dw ? + old_ctl_brk_seg dw ? + +old_crit_err label dword + old_crit_err_off dw ? + old_crit_err_seg dw ? + +exec_block label word + ex_envseg dw ? ; env seg, use parent's if 0 + ex_cmdtail dd ? ; command tail for exec + ex_fcb1 dd far ptr fcb ; fcb's aren't used by dmake + ex_fcb2 dd far ptr fcb + ex_ss dw ? ; saved ss for exec + ex_sp dw ? ; saved sp for exec + ex_error dw 0 ; error code for dos exec + + +; Special 21h (DOS call) handler to tee stdout/stderr writes to the -C file. +; Ignore 21h calls that aren't writes to 1 or 2; i.e., pass them to DOS handler. +; If write call was from this process, it's pretty simple to duplicate it +; to the -C file. If it's from another process, we try to write to its +; inherited handle. Worst case is where the handle wasn't inherited: someone +; closed it. In that instance we have to switch to dmake's PSP to do the +; duplicate write. + +; Subprocesses do not get their stdout/stderr teed to the -C file if +; their stdout/stderr no longer points to the file/device that dmake's +; stdout points to. This is tested by looking at the process's job +; file table, which is a table that maps process handles to DOS system file +; table numbers. (The far pointer to the JFT is at the PSP offset 34h.) +; The JFT is also queried to see if the -C file was inherited. + +; O_BINARY, O_TEXT problems are ignored here. These are fudged by the +; C library before it calls DOS; since we're working below that level +; we don't have to worry about it. + +simulate_21h Macro + pushf ;; direct call to DOS + call cs:[real_21h] + Endm + + assume cs:@code, ds:nothing, es:nothing, ss:nothing +our_21h_handler proc far + pushf + cmp ah,40h ; is this a write? + jne call_dos ; --no + cmp bx,1 ; write on handle 1 (stdout?) + je duplicate_it + cmp bx,2 ; stderr? + je duplicate_it + +call_dos: + popf + jmp [real_21h] ; far jump to real handler, which will do the sys call + ; and return to the original caller + +duplicate_it: + mpusha + push ds + push es + mov bp,sp + + mov di,std_fil_handle ; handle of the -C file + + If @CodeSize eq 0 + ; Small/compact models allow for quick test of us versus subprocess. + ; False negative (it's us with a different CS) will be picked + ; up by code just below. (Might happen due to call from C library.) + ; False positives would be bad, but can't happen. + mov ax,[bp+24] ; caller's CS + cmp ax,@code ; same as us? + je call_from_dmake + Endif + + mov ah,51h ; get PSP ("undocumented version" works in DOS 2.0+) + simulate_21h ; PSP segment returned in BX + cmp bx,psp ; our PSP? + je call_from_dmake ; --yes, no PSP changing needed + + mov es,bx ; set ES to current (caller's) PSP + lds bx,es:[34h] ; set DS:BX pointing to caller's job file table + + mov si,[bp+12] ; file handle caller passed in (known to be 1 or 2) + mov al,[bx+si] ; system file number corresponding to caller's handle + cmp al,our_stdout ; same as our stdout? + jne do_real_write ; no--subprocess must have redirected it + + mov al,[bx+di] ; see if caller has dup of -C file still open + cmp al,std_fil_number + je use_dup ; yes--we can write using caller's PSP + + ; Calling process (or some intermediate process) has closed + ; the -C descriptor. We'll use dmake's (our) -C descriptor, but + ; to do so we'll have to change the PSP. Disable BREAK handling + ; so that ^break doesn't kill the wrong process. + + mov ax,3300h ; get BREAK flag + simulate_21h + mov si,dx ; save BREAK state in SI + sub dx,dx ; now turn break flag off + mov ax,3301h + simulate_21h ; don't want ^Break recoginized while PSP changed + mov bx,psp ; set dmake's PSP + mov ah,50h + simulate_21h + + mov bx,di ; handle of -C file + ; CX still has caller's count + mov ds,[bp+2] ; restore caller's DS + mov dx,[bp+14] ; DS:DX again points to caller's buffer + mov ah,40h + simulate_21h ; write the copy + + mov bx,es ; caller's PSP + mov ah,50h ; set PSP + simulate_21h ; restore caller's PSP + mov dx,si ; break state before we changed it + mov ax,3301h + simulate_21h ; restore break state + + jmp short do_real_write + +use_dup: + mov ds,[bp+2] ; restore caller's DS + mov dx,[bp+14] ; DS:DX again points to caller's buffer + +call_from_dmake: + mov bx,di ; handle of -C file + mov ah,40h ; write + ; CX still has caller's count + simulate_21h ; write to the file + +do_real_write: + pop es + pop ds + mpopa + popf + jmp [real_21h] ; far jump to real handler, which will do the sys call + ; and return to the original caller +our_21h_handler endp + + assume cs:@code, ds:@code, ss:@code, es:@code + +;----------------------------------------------------------------------------- +; First define the critical-error and control-brk handlers. +; The critical error handler simply pops the machine state and returns an +; access denied result code. +crit_err_handler proc far + add sp, 6 ; ip/cs/flags ... + pop ax + pop bx + pop cx + pop dx + pop si + pop di + pop bp + pop ds + pop es + push bp ; fix up the return flags + mov bp, sp + xchg ax, [bp+6] ; get the flag byte. + or ax, 1 ; set the carry bit + xchg ax, [bp+6] ; put it back. + pop bp + mov ax, 5 ; access denied + iret +crit_err_handler endp + + +;----------------------------------------------------------------------------- +; Here we set the interrupted flag, and terminate the currently running +; process. +ctl_brk_handler proc far + clc ; make sure carry is clear + inc cs:interrupted ; set the flag + +; Make certain it isn't us that is going to get terminated. +; There is a small window where the in_exec flag is set but the child is +; not running yet, I assume that DOS doesn't test for ctl_brk at that time +; as it is bussily creating a new process. + cmp cs:in_exec,0 + je just_return ; note this implies CF == 0 + stc ; set CF to abort child +just_return: iret +ctl_brk_handler endp + + +;----------------------------------------------------------------------------- +; Something really nasty happened, so abort the exec call and exit. +; This kills the calling process altogether, and is a very nasty way of +; termination since files may still be open etc. +abort_exec_rhdr label near + mov dx, offset error_rhdr + jmp print_it +abort_exec_rseg label near + mov dx, offset error_rseg + jmp print_it +abort_exec_resize label near + mov dx, offset error_resize + jmp print_it +abort_exec_free label near + mov dx, offset error_free + jmp print_it +abort_exec_alloc label near + mov dx, offset error_alloc + jmp print_it +abort_exec proc near + mov dx, offset error_string +print_it: push dx + mov bx, [swap] + call [free_resource+bx] + mov ax, cs + mov ds, ax + pop dx + mov ah, 9 + int 21H +kill_program: mov ax, 04cffH ; nuke it! + int 21H +abort_exec endp + + +;----------------------------------------------------------------------------- +; lodsw/stosw loop to copy data. Called only for word copy operations. +; ds:si - point at source +; es:di - point at destination +; cx - count of bytes to copy. +copy_data proc near + shr cx, 1 ; convert to word count + jnc copy_words + movsb +copy_words: rep movsw ; copy the words. + ret +copy_data endp + + + +;============================================================================= +; THE FOLLOWING SECTION DEALS WITH ALL ROUTINES REQUIRED TO READ XMS RECORDS. +;============================================================================= +rhdr_xms proc near + ret +rhdr_xms endp + +rseg_xms proc near + ret +rseg_xms endp + +reset_xms_resource proc near + ret +reset_xms_resource endp + +free_xms_resource proc near + ret +free_xms_resource endp +;============================================================================= + + + +;============================================================================= +; THE FOLLOWING SECTION DEALS WITH ALL ROUTINES REQUIRED TO READ EMS RECORDS. +;============================================================================= +rhdr_ems proc near + ret +rhdr_ems endp + +rseg_ems proc near + ret +rseg_ems endp + +reset_ems_resource proc near + ret +reset_ems_resource endp + +free_ems_resource proc near + ret +free_ems_resource endp +;============================================================================= + + + +;============================================================================= +; THE FOLLOWING SECTION DEALS WITH ALL ROUTINES REQUIRED TO READ FILE RECORDS. +;============================================================================= +; This routine reads a segment header from a file. +; The header is a seven byte record formatted as follows: +; segment address - of data +; offset address - of data +; length in paragraphs - of data +; mode - 1 => segment header (allocate seg on read) +; 0 => subsegment, don't allocate on read. +; The information is placed into the tmpseg data area in the code segment. +; The routine aborts if an error is detected. +rhdr_file proc near + mov dx, offset tmpseg ; read the header record out + mov cx, 7 + mov bx, [tmphandle] + mov ah, 03fH + int 21H + jnc rhdr_done ; make sure it worked + jmp abort_exec_rhdr + +rhdr_done: cmp ax, 7 + je exit_rhdr_file + or ax, ax + je signal_eof + jmp abort_exec_rhdr + +signal_eof: stc +exit_rhdr_file: ret +rhdr_file endp + + +;----------------------------------------------------------------------------- +; Read a segment from the temporary file whose handle is in cs:tmphandle. +; The routine aborts if an error is detected. +rseg_file proc near + push ds + mov ds, word ptr cs:tmpseg; Now read the whole segment + mov dx, word ptr cs:tmpseg+2 + mov cx, word ptr cs:tmpseg+4 + mov bx, cs:tmphandle + mov ah, 03fH + int 21H + pop ds + jnc rseg_done + jmp abort_exec_rseg + +rseg_done: cmp ax, [word ptr tmpseg+4] + je exit_rseg_file + jmp abort_exec_rseg ; If we didn't get read full +exit_rseg_file: ret ; segment then abort +rseg_file endp + + +;----------------------------------------------------------------------------- +; Seek to the beginning of the file. +reset_file_resource proc near + mov bx, [tmphandle] + xor cx, cx + mov dx, cx + mov ax, 04200H ; seek to begining of file + int 21H + ret +reset_file_resource endp + + +;----------------------------------------------------------------------------- +; unlink the temporary file allocated for swapping. +; We close the file first, and then delete it. We ignore errors here since +; we can't do anything about them anyway. +free_file_resource proc near + mov bx, [tmphandle] ; get the file handle + mov ah, 03eH ; close the file + int 21H + mov dx, offset tmpname ; Now delete the temp file + mov ah, 041H + int 21H + ret +free_file_resource endp +;============================================================================= + + + +;============================================================================= +; CODE TO SWAP THE IMAGE IN FROM SECONDARY STORAGE +;============================================================================= +swap_in proc near + mov bx, [alstr] ; get previous alloc strategy + mov ax, 5801H ; and set it back + int 21H + mov bx, [swap] ; get type of resource + call [reset_resource+bx] ; reset the resource + mov es, [psp] ; resize the program back + mov bx, [progsize] ; to original size + mov ah, 04AH + int 21H + jnc read_seg_loop + jmp abort_exec + +read_seg_loop: mov bx, [swap] ; get type of resource + call [read_header+bx] ; get seg header + jc exit_swap_in ; all done + mov al, [tmpseg+6] + cmp al, seg_no_alloc ; see if dummy segment header + je read_seg_loop + cmp al, seg_alloc ; do we need to do an alloc? + jne read_data ; nope + +; Allocate back the memory for a segment that is not the [psp], note that this +; must come back to the same segment we had previously since other segments +; may have pointers stored in their variables that point to this segment using +; segment:offset long pointers. + mov bx, [word ptr tmpseg+4] ; get count of paragraphs + mov ah, 048H ; dos_alloc + int 21H + jc alloc_error ; oops! + cmp ax, [word ptr tmpseg] ; did we get the same segment? + je read_seg_loop ; yup! +alloc_error: jmp abort_exec_alloc + +read_data: mov bx, [swap] + call [read_seg+bx] ; this must succeed, if fail + jmp read_seg_loop ; we never come back here + +exit_swap_in: mov bx, [swap] ; all done, so free resource + call [free_resource+bx] + ret +swap_in endp + + +;============================================================================= +; CODE TO SWAP THE IMAGE OUT TO SECONDARY STORAGE +;============================================================================= +; This routine is called to swap the non-resident portion of the program +; out to the resource specified by the value of [cs:swap]. If the swap out +; fails, then appropriate routines are called to free the resources allocated +; up to that point. +; +; The steps used to swap the program out are as follows: +; - calculate new size of program to remain resident and size to swap +; out. +; - write out non-resident portion of current segment +; - walk DOS allocation chain and write out all other segments owned by +; the current program that are contiguous with the _psp segment +; - copy the environment down to low memory +; - resize the current _psp segment to savesize +; - free all segments belonging to program except current _psp segment +swap_out proc near + mov ax, 05800H ; get memory alocation strategy + int 021H + mov [alstr], ax ; and save it for future restoration. + mov di, [psp] ; compute length of program to current + mov bx, cs ; value of cs, and find program size + sub bx, di ; by looking at length stored in + mov ax, di ; arena header found in front of psp + dec ax + mov es, ax + mov si, es:3 ; si is size of program in paragraphs + mov [progsize], si ; progsize now contains the size. + +; Now compute length of program segment to save. +; Length is: cs - psp + (offset overlay_code_here+15 >> 4) + mov ax, offset overlay_code_here+15 + shr ax, 1 + shr ax, 1 + shr ax, 1 + shr ax, 1 + add bx, ax ; bx is size of program to keep + sub si, bx ; si is # of paragraphs to save. + add di, bx ; di is paragraph to start at + mov rootsize, bx + mov resend, di ; cs:resend is saved start para + mov al, seg_no_alloc ; set no allocation for segment + call write_segment + jc abort_swap_out + +; We have now saved the portion of the program segment that will not remain +; resident during the exec. We should now walk the DOS allocation chain and +; write out all other segments owned by the current process. +save_segments: mov ax, [psp] + dec ax + mov es, ax + mov bx, offset write_segment_data + call walk_arena_chain + jc abort_swap_out + +; Now we must walk the chain of allocated memory blocks again and free +; all those that are owned by the current process, except the one that is +; the current process' psp. +free_segments: mov ax, [psp] + dec ax + mov es,ax + mov bx, offset free_dos_segment + call walk_arena_chain + jnc resize_program + jmp abort_exec_free ; can't fix it up now. + +; We now resize the program to the size specified by cs:rootsize. This will +; free most of the memory taken up by the current program segment. +resize_program: mov es, [psp] ; es is segment to resize. + mov bx, [rootsize] ; bx is size of segment. + mov ah, 04aH ; resize memory block + int 21H + jnc swap_out_ok + jmp abort_exec_resize ; disaster +swap_out_ok: ret + +; The swap out failed for some reason, so free any allocated resources +; and set the carry bit. +abort_swap_out: mov bx, [swap] + call [free_resource+bx] + xor ax, ax + mov [swap], ax ; clear the swap flag + stc + ret +swap_out endp + + +;============================================================================= +; CODE TO SET-UP FOR AND EXEC THE CHILD PROCESS +;============================================================================= +; Actually execute the program. If cs:swap is set, this code will invoke the +; swap-out/swap-in code as required. +do_exec proc near + cmp [swap], 0 ; does the user want to swap? + je no_swap_out ; nope + call init_swap ; figger out where to swap to + jc no_swap_out ; if carry set then don't swap + call swap_out + +no_swap_out: cmp [interrupted], 0 ; were we interrupted? + jne leave_exec ; yep, so clean up, don't exec + +; free passed in environment block if it is non zero. +; This way the parent program does not need to free it. + mov ax, [envseg] + or ax, ax + je setup_block + push ax + mov es, ax + mov ah, 49H + int 21H + pop ax + +; set up the parameter block for the DOS exec call. +; offset contents +; 00 segment address of environment to be passed, +; 0 => use parents env. +; 02 pointer to command tail for new process. +; 06 pointer to fcb1 +; 0a pointer to fcb2 +setup_block: mov ax, [envseg] + mov [ex_envseg], ax + mov cx, cs + mov [word ptr ex_cmdtail], offset cmdtail + mov [word ptr ex_cmdtail+2], cx + +; set up registers for exec call +; ds:dx - pointer to pathname of program to execute +; es:bx - pointer to above parameter block + mov dx, offset cmdpath + mov es, cx + mov bx, offset exec_block + +; Under DOS 2.x exec is notorious for clobbering registers and guarantees +; to preserve only cs:ip. + push ds + mov [ex_sp], sp + mov [ex_ss], ss + mov [ex_error], 0 ; clear exec error code + inc [in_exec] ; set internal flag + mov ax, 04b00H + int 21H + +; returned from exec, so restore possibly clobbered registers. + mov ss, cs:ex_ss + mov sp, cs:ex_sp + pop ds + +; check to make certain the exec call worked. + jnc it_worked + +; exec call failed. Save return code from msdos. + mov [ex_error], ax + jmp leave_exec + +it_worked: mov ah, 04dH ; get the return code + int 21H + cmp ah,1 ; check if terminated by ^C + jnz nosigint + inc interrupted ; yes so set flag +nosigint: xor ah, ah ; 8-bit return code, so clear ah + mov [eretcode], ax + +leave_exec: cmp [swap], 0 ; check swap, if non-zero swap back in + je no_swap_in + call swap_in + +; Clear the in_exec after the swap back in. This way we are guaranteed to +; get parent in and the resources freed should a ^C be hit when we are reading +; the image in. +no_swap_in: mov [in_exec], 0 + ret +do_exec endp + + + +;============================================================================== +; Everything past this point is overwriten with the environment and new +; program after the currently executing program is swapped out. +;============================================================================== +overlay_code_here label word + +;----------------------------------------------------------------------------- +; Figure out where we can swap to and initialize the resource we are going to +; use. We try XMS, EMS, and a tempfile (if specified), in that order. We set +; [cs:swap] to the correct value based on which of the resources exists. +; If none can be used, then [cs:swap] is set to 0, and no swap takes place. +; The exec code will still attempt to execute the child in this instance, but +; may fail due to lack of resources. Each swap_out_* routine must provide +; its own clean-up handler should it not be able to write all program +; segments to the swap resource. +init_swap proc near + mov [swap], 0 +;call init_xms +;jnc init_done +;call init_ems +;jnc init_done + call init_file +init_done: ret +init_swap endp + + +;----------------------------------------------------------------------------- +; This routine is used to walk the DOS allocated memory block chain +; starting at address supplied in the es register. For each block it +; calls the routine specified by the bx register with the segment length +; in si, and its address in di. It does not apply the routine to the +; segment if the segment is the same as the current program's [cs:psp] value. +memheader struc + magic db ? ; either 'Z' for end or 'M' for allocated + owner dw ? ; psp of owner block + len dw ? ; length in paragraphs of segment +memheader ends + +walk_arena_chain proc near + mov si, word ptr es:3 ; get length + mov di, es + inc di + mov ax, word ptr es:1 + +; Stop the search if the block is NOT owned by us. Ignore our own psp block +; and our environment segment block. + cmp ax, cs:psp ; is it owned by us? + jne walk_done ; NOPE! -- all done + cmp di, cs:envseg ; skip our environment + je next_block + cmp di, cs:psp ; skip our psp + je next_block + +; Now save state and call the routine pointed at by [bx]. + push di + push si + push bx + call bx + pop bx + pop si + pop di + jc exit_walk ; if error then stop + mov al, byte ptr es:0 ; check if at end + cmp al, 'Z' + je walk_done + +next_block: add di, si ; go on to next segment + mov es, di + jmp walk_arena_chain +walk_done: clc +exit_walk: ret +walk_arena_chain endp + + +;----------------------------------------------------------------------------- +; This routine takes a dos segment found in the di register and free's it. +free_dos_segment proc near + mov es, di ; free dos memory block + mov ah, 49H + int 21H + ret +free_dos_segment endp + + +;----------------------------------------------------------------------------- +; Called to invoke write_segment with proper values in the al register. Only +; ever called from walk_arena_chain, and so al should be set to seg_alloc. +write_segment_data label near + mov al, seg_alloc ; and fall through into write_segment +;----------------------------------------------------------------------------- +; This routine writes a segment as a block of data segments if the number of +; paragraphs to write exceeds 0x0fff (rarely the case). +; It stuffs the info into tmpseg, and then calls wheader and wseg to get the +; data out. +; +; di:dx segment:offset of segment; offset is ALWAYS zero. +; si number of paragraphs to write. +; al mode of header to write +write_segment proc near + push di + push si + xor dx,dx + mov bx, [swap] + call [write_header+bx] + pop si + pop di + jc exit_wseg + +do_io_loop: cmp si, 0 ; are we done yet? + je exit_wseg ; yup so leave. + mov cx, si ; # of paragraphs to move + cmp cx, 0fffH ; see if we have lots to move? + jle do_io + mov cx, 0fffH ; reset to max I/O size + +do_io: push cx ; save # of paragraphs we are writing + shl cx, 1 ; shift cx by four to the left + shl cx, 1 + shl cx, 1 + shl cx, 1 + push di ; save the start, and count left + push si + mov si, cx + xor dx,dx + mov al, seg_data + mov bx, [swap] + push bx + call [write_header+bx] + pop bx + call [write_seg+bx] + pop si + pop di + pop dx ; original paragraph count in dx + jc exit_wseg ; it failed so exit. + add di, dx ; adjust the pointers, and continue. + sub si, dx + jmp do_io_loop +exit_wseg: ret +write_segment endp + + +;============================================================================= +; THE FOLLOWING SECTION DEALS WITH ALL ROUTINES REQUIRED TO WRITE XMS RECORDS. +;============================================================================= +init_xms proc near + ret +init_xms endp + +whdr_xms proc near + ret +whdr_xms endp + +wseg_xms proc near + ret +wseg_xms endp +;============================================================================= + + +;============================================================================= +; THE FOLLOWING SECTION DEALS WITH ALL ROUTINES REQUIRED TO WRITE EMS RECORDS. +;============================================================================= +init_ems proc near + ret +init_ems endp + +whdr_ems proc near + ret +whdr_ems endp + +wseg_ems proc near + ret +wseg_ems endp +;============================================================================= + + +;============================================================================= +; THE FOLLOWING SECTION DEALS WITH ALL ROUTINES REQUIRED TO WRITE FILES. +;============================================================================= +;----------------------------------------------------------------------------- +; Attempt to create a temporary file. If the tempfile name is NIL then return +; with the cary flag set. +init_file proc near + mov al, [tmpname] + or al, al + je err_init_file + mov dx, offset tmpname + xor cx, cx + mov ah, 03cH + int 21H + jc err_init_file ; if carry set then failure + mov [tmphandle], ax ; init swapping + mov [swap], swap_file + jmp exit_init_file +err_init_file: stc +exit_init_file: ret +init_file endp + + +;----------------------------------------------------------------------------- +; This routine writes a segment header to a file. +; The header is a seven byte record formatted as follows: +; segment address - of data +; offset address - of data +; length in paragraphs - of data +; mode - 1 => segment header (allocate seg on read) +; 0 => subsegment, don't allocate on read. +; Routine takes three arguments: +; di:dx segment:offset of segment +; si number of paragraphs to write. +; al mode of header to write +whdr_file proc near + mov [word ptr tmpseg], di ; save the segment/offset + mov [word ptr tmpseg+2], dx + mov [word ptr tmpseg+4], si ; save the segment length + mov [tmpseg+6], al + mov dx, offset tmpseg ; write the header record out + mov cx, 7 + mov bx, [tmphandle] + mov ah, 040H + int 21H + jc exit_whdr_file ; make sure it worked + cmp ax, 7 + je exit_whdr_file ; oh oh, disk is full! +err_whdr_file: stc +exit_whdr_file: ret +whdr_file endp + + +;----------------------------------------------------------------------------- +; Write a segment to the temporary file whose handle is in cs:tmphandle +; Parameters for the write are assumed to be stored in the tmpseg data area. +; function returns carry set if failed, carry clear otherwise. +wseg_file proc near + push ds + mov ds, word ptr cs:tmpseg ; Now write the whole segment + mov dx, word ptr cs:tmpseg+2 + mov cx, word ptr cs:tmpseg+4 + mov bx, cs:tmphandle + mov ah, 040H + int 21H + pop ds + jc exit_wseg_file ; make sure it worked + cmp ax, [word ptr tmpseg+4] + je exit_wseg_file +err_wseg_file: stc ; it failed (usually disk full) +exit_wseg_file: ret +wseg_file endp +;============================================================================= + + +;============================================================================= +; _exec: THIS IS THE MAIN ENTRY ROUTINE TO THIS MODULE +;============================================================================= +; This is the main entry routine into the swap code and corresponds to the +; following C function call: +; +; exec( int swap, char far *program, char far *cmdtail, int environment_seg, +; char far *tmpfilename ); +; +; Exec performs the following: +; 1. set up the local code segment copies of arguments to the exec call. +; 2. switch to a local stack frame so that we don't clobber the user +; stack. +; 3. save old interrupt vectors for ctrl-brk. +; 4. install our own handler for the ctrl-brk interrupt, our handler +; terminates the current running process, and returns with non-zero +; status code. +; 5. get our psp +; 6. setup arguments for exec call +; 7. exec the program, save result code on return. +; 8. restore previous ctrl-brk and crit-error handler. +; 9. restore previous process stack, and segment registers. +; 10. return from exec with child result code in AX +; and global _Interrupted flag set to true if child execution was +; interrupted. + +; NOTE: When first called the segments here assume the standard segment +; settings. + assume cs:@code, ds:DGROUP,es:DGROUP,ss:DGROUP + + public _exec +_exec proc + push bp ; set up the stack frame + mov bp, sp + push si ; save registers we shouldn't step on. + push di + push ds + +; set up for copying of parameters passed in with long pointers. + push cs ; going to use lodsb/stosb, set up es + pop es ; as destination. + assume es:@code ; let the assembler know :-) + cld ; make sure direction is right + +; Copy all parameters into the bottom of the code segment. After doing so we +; will immediately switch stacks, so that the user stack is preserved intact. + mov ax, ss:[a_swap] ; save swap + mov es:swap, ax + mov ax, ss:[a_env] ; save env seg to use + mov es:envseg, ax + + mov di, offset cs:cmdpath ; copy the command + lds si, ss:[a_prog] ; 65 bytes worth + mov cx, 65 + call copy_data + + mov di, offset cs:cmdtail ; copy the command tail + lds si, ss:[a_tail] ; 129 bytes worth + mov cx, 129 + call copy_data + + mov di, offset cs:tmpname ; copy the temp file name + lds si, ss:[a_tmp] ; 65 bytes worth. + mov cx, 65 + call copy_data + +; Now we save the current ss:sp stack pointer and swap stack to our temporary +; stack located in the current code segment. At the same time we reset the +; segment pointers to point into the code segment only. +swap_stacks: mov ax, ss + mov es:old_ss, ax + mov es:old_sp, sp + mov ax, cs + mov ds, ax + mov ss, ax ; set ss first, ints are then + mov sp, offset cs:exec_sp ; disabled for this instr too + assume ds:@code, ss:@code ; let the assembler know :-) + +; Now we save the old control break and critical error handler addresses. +; We replace them by our own routines found in the resident portion of the +; swapping exec code. +set_handlers: mov [interrupted], 0 ; clear interrupted flag + mov [eretcode], 0 ; clear the return code + mov ax, 03523H ; get int 23 handler address + int 21H + mov cs:old_ctl_brk_off, bx + mov cs:old_ctl_brk_seg, es + mov dx, offset ctl_brk_handler + mov ax, 02523H ; set int 23 handler address + int 21H + + mov ax, 03524H ; get int 24 handler address + int 21H + mov cs:old_crit_err_off, bx + mov cs:old_crit_err_seg, es + mov dx, offset crit_err_handler + mov ax, 02524H ; set int 24 handler address + int 21H + +; Go and execute the child, we've set up all of its parameters. The do_exec +; routine will attempt to perform a swap of the code if requested to do so by +; a non-zero value in the variable cs:swap. + mov ah, 051H ; get the psp + int 21H + mov cs:psp, bx + call do_exec + +; We're back from the exec, so fix things up the way they were. +; Restore the old control-break and critical-error handlers. + lds dx, cs:old_ctl_brk + mov ax, 02523H + int 21H + lds dx, cs:old_crit_err + mov ax, 02524H + int 21H + +; Restore previous program stack segment registers, and data segment. + mov ax, cs:old_ss + mov ss, ax ; mov into ss first, that way + mov sp, cs:old_sp ; no interrupts in this instr. + pop ds + +; Tell the assembler we have swaped segments again. + assume ds:DGROUP,es:DGROUP,ss:DGROUP + +; Set the global Interrupted flag so that parent can tell it was interrupted. + mov ax, seg DGROUP:_Interrupted + mov es, ax + mov ax, cs:interrupted + mov es:_Interrupted, ax + +; Set the global errno value to reflect the success/failure of the DOS +; exec call. + mov ax, seg DGROUP:_errno + mov es, ax + mov ax, cs:ex_error + mov es:_errno, ax + +; Fetch the child's return code, pop rest of stuff off of the stack +; and return to the caller. + mov ax, cs:eretcode + pop di + pop si + pop bp + ret +_exec endp + +; void do_hook_std_writes(int handle); +; This saves the 21h interrupt vector and changes it to point +; into this code. Argument is the file handle of the -C file. + + public _do_hook_std_writes +_do_hook_std_writes proc + push bp + mov bp,sp + push di + + mov di, ss:[a_handle] ; handle of -C file + mov std_fil_handle, di + + mov ah, 51h ; request our PSP + int 21h + mov [psp], bx ; save it + + mov es, bx + les bx, es:[34h] ; pointer to job file table + mov al, es:[bx+1] ; system file # of our stdout + mov [our_stdout], al + mov al, es:[bx+di] ; system file number of -C file + mov std_fil_number, al + + mov ax,3521h ; request vector 21h + int 21h ; it's returned in ES:BX + mov word ptr [real_21h], bx + mov word ptr [real_21h+2], es + + push ds + mov ax,cs + mov ds,ax + lea dx,our_21h_handler ; DS:DX is the new vector + mov ax,2521h ; set vector 21h + int 21h + + pop ds + pop di + pop bp + ret +_do_hook_std_writes endp + +; void do_unhook_std_writes(void); +; This restores the 21h interrupt vector. +; The saved vector is zero if it wasn't changed (no -C option). + + public _do_unhook_std_writes +_do_unhook_std_writes proc + push ds + + lds dx, [real_21h] ; put saved vector into DS:DX + mov ax, ds + or ax, dx + jz unhook_return ; zero means we didn't hook 21h + + mov ax,2521h ; set vector 21h + simulate_21h + +unhook_return: pop ds + ret +_do_unhook_std_writes endp +end diff --git a/dmake/msdos/exec.h b/dmake/msdos/exec.h new file mode 100644 index 000000000000..f603bc43d2cb --- /dev/null +++ b/dmake/msdos/exec.h @@ -0,0 +1,43 @@ +/* RCS $Id: exec.h,v 1.1.1.1 2000-09-22 15:33:27 hr Exp $ +-- +-- SYNOPSIS +-- Internal version of exec for dmake. +-- +-- DESCRIPTION +-- External defines for the exec.c code. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ +#ifndef _EXEC_h_ +#define _EXEC_h_ + +#ifndef ANSI +#if defined(__STDC__) || defined(__TURBOC__) +#define ANSI(x) x +#else +#define ANSI(x) () +#endif +#endif + +extern int exec ANSI((int, char far *, char far *, unsigned int, char far *)); + +#ifndef MK_FP +#define MK_FP(seg,ofs) \ + ((void far *) (((unsigned long)(seg) << 16) | (unsigned)(ofs))) +#endif + +#endif diff --git a/dmake/msdos/exec.uue b/dmake/msdos/exec.uue new file mode 100644 index 000000000000..90a1c3e661e8 --- /dev/null +++ b/dmake/msdos/exec.uue @@ -0,0 +1,63 @@ +begin 777 exec.obj +M@! #DU31$]37&5X96,N87-M;(@@ '%1U<F)O($%S<V5M8FQE<B @5F5R +M<VEO;B S+C";B!8 0.DJ<T$=#DU31$]37&5X96,N87-M.H@# $#I3)8" !H +MB , 0*&4EA "45814-?5$585 1#3T1%:9@' $@:" (# ?&6# %7T1!5$$$ +M1$%40<*8!P!( @ $!0$-E@@ !D1'4D]54(N:! &_P);C D !E]E<G)N;P#@ +MD!, 0(,7TEN=&5R<G5P=&5D 69 < !%5]D;U]U;FAO;VM?<W1D7W=R +M:71E<P,( &>0# 05?97AE8^$& '.0&@ 1-?9&]?:&]O:U]S=&1?=W)I +M=&5SN < FH@$ $"B 9&@!@ !F ,&B#@ !7 $E $ 0 $ RJ(. &( +M 4$ 0 ! 0""H@X <D! 0 ! $ ! (&@" !S $ BJ#' '4 +M 65X96,Z($9A:6QU<F4@<F5A9&EN9R!H96%D97(@8FQO8VL-"B1E>&5C.B!& +M86EL=7)E(')E861I;F<@<V5G;65N="!D871A#0HD97AE8SH@1F%I;'5R92!O +M;B!R97-I>F4-"B1E>&5C.B!&86EL=7)E('1O(&9R964@82!B;&]C:PT*)&5X +M96,Z(%!R;V=R86T@<W=A<"!F86EL=7)E#0HD97AE8SH@365M;W)Y(&)L;V-K +M<R!D;VXG="!M871C: T*)+>B#@ !EP(! $ 0 $ LJ H &8 G(&=0:7 +M!G,&=@:]!@,$!P0+! 0$" 0J! 8$"@1@! 4$"012! J<20#$ %0!Q )4 <0$ +M5 '$!E0!Q A4 <0*5 '$#%0!Q Y4 <005 '$$E0!Q!14 <065 '$&%0!Q!I4 +M <0<5 '$'E0!Q"!4 <0B5 $GH P <H"7 $ %P! #-G D S !4 <P$5 $5 +MH,T# =8" "<@/Q =0J#^P%T"X/[ G0&G2[_+LP!4%%24U155E<>!HOL+HL^ +MT &T49PN_Q[, 2X['HP =&R.PR;%'C0 BW8,B@ N.@;3 75CB@$N.@;2 71* +MN SG"[_'LP!B_(KTK@!,YPN_Q[, 2Z+'HP M%"<+O\>S &+WXY> HM6#K1 +MG"[_'LP!C,.T4)PN_Q[, 8O6N $SG"[_'LP!ZQ".7@*+5@Z+W[1 G"[_'LP! +M!Q]?7EV#Q );6EE8G2[_+LP!@\0&6%M96EY?71\'58OLAT8�$ AT8&7;@% +M ,_X+O\&D@ N@SZ8 !T ?G/NM0!ZQR0NOD!ZQ:0NAX"ZQ"0NC@"ZPJ0NG4" +MZP20NE@"4HL>C@#_E[ "C,B.V%JT"<TAN/],S2'1Z7,!I/.EP\/#P\/#P\/# +MNH$!N0< BQ[* ;0_S2%S NNF/0< = <+P'0"ZYOYPQXNCAZ! 2Z+%H,!+HL. +MA0$NBQ[* ;0_S2$?<P+K@3L&A0%T ^EX_\.+'LH!,\F+T;@ 0LTAPXL>R@&T +M/LTANH@!M$'-(<.+'I8 N %8S2&+'HX _Y>V HX&C "+'H0 M$K-(7,#Z4__ +MBQZ. /^7I )R**"' 3P =.\\ 743BQZ% ;1(S2%R!CL&@0%TV^DA_XL>C@#_ +MEZH"Z\Z+'HX _Y>P L.X %C-(:.6 (L^C ",RRO?B\=(CL FBS8# (DVA "X +MYP71Z-'HT>C1Z /8*_,#^XD>A@")/H@ L #H'0%R,:&, $B.P+LD!NC+ '(C +MH8P 2([ NQT&Z+T <P/IJ_Z.!HP BQZ& +1*S2%S ^F4_L.+'HX _Y>P C/ +MHXX ^<.#/HX '0(Z(, <@/H<_^#/I( '5FH8H "\!T"%".P+1)S2%8H8H +MH\0"C,G'!L8"VP")#L@"NIH CL&[Q (>B2;4 HP6T@+'!M8" #_!I@ N !+ +MS2$NCA;2 BZ+)M0"'W,&H]8"ZQ.0M$W-(8#\ 74$_P:2 #+DHY @SZ. !T +M ^B?_L<&F ,/'!HX #HE@##)HLV P",QT<FH0$ +CL&C !U)BX[/HH +M=!DN.SZ, '025U93_]-;7E]R#R:@ \6G0& _Z.Q^O'^,..Q[1)S2'#L %7 +M5C/2BQZ. /^7F )>7W(Z@_X =#6+SH'Y_P]^ [G_#U'1X='AT>'1X5=6B_$S +MTK "BQZ. %/_EY@"6_^7G@)>7UIR!@/Z*_+KQL/#P\/#P\.@B $*P'07NH@! +M,\FT/,TA<@RCR@''!HX ! #K I#YPXD^@0&)%H,!(YR1 <065 '$)U0!Q"]4 +M <0T5 '$1U0!Q%!4 <1;5 '$:%0!Q&U4 <1U5 '$A50!Q(]4 <2:5 '$K%0! +MQ+Y4 <3A5 '$YE0!Q.Y4 <3T5 '$^E0!Q0!4 <4&5 '%#%0!Q1%4 <455 '% +M-E0!Q3U4 <585 '%750!Q6)4 <5G5 '%=%0!Q7Y4 <6,5 '%DU0!Q9Q4 <6E +M5 '%J50!Q:U4 <6Q5 '%OE0!Q<)4 <7'5 '%TU0!Q=U4 <865 '&/%0!QDI4 +M <7F5 '%ZE0!Q?!4 <7T5 '%_50!Q@%4 <835 '&*%0!QBQ4 <8V5 '&1%0! +MQE94 <9:5 '&:%0!QFQ4 <9Q5 '&=U0!QH94 <:,5 '&FU0!QIY4 <:D5 '& +MIE0!QJI4 <:M5 '&LE0!QK=4 <:[5 '&OU0!QL54 <;/5 '&U%0!QMI4 <;J +M5 '&[U0!QO-4 <;]5 ''!%0!QQM4 <<B5 ''*50!QU94 <=:5 ''@U0!QXA4 +M <>-5 ''HE0!QZE4 <>T5 ''N%0!Q\-4 <?'5 $%H'\! 9\&B3:% :*' ;J! +M ;D' (L>R@&T0,TA<@8]!P!T ?G#'BZ.'H$!+HL6@P$NBPZ% 2Z+'LH!M$#- +M(1]R!SL&A0%T ?G#58OL5E<>#@?\BT8&)J.. (M&$":CB@"_F@#%=@BY00#H +M]_R_VP#%=@RY@0#HZ_R_B '%=A*Y00#HW_R,T":C@ FB2:" (S(CMB.T+R +M ,<&D@ ,<&D +@C-<TA+HD>O (NC :^ KJS [@C)<TAN"0US2$NB1[ +M BZ,!L("NI8#N"0ES2&T4<TA+HD>C #HU?TNQ1:\ K@C)<TA+L46P *X)"7- +M(2ZA@ ".T"Z+)H( '[@ ([ +J&2 ":C "X ".P"ZAU@(FHP +J&0 %]> +M7<M5B^Q7BWX&+HD^T &T4<TA+HD>C ".PR;$'C0 )HI' 2ZBTP$FB@$NHM(! +MN"$US2$NB1[, 2Z,!LX!'HS(CMBZV *X(27-(1]?7<L>+L46S &,V O"= FX +M(26<+O\>S $?RPJ<O0#$ E0!Q 54 <0(5 '$#U0!Q")4 <0G5 '$+%0!Q#%4 +M <0\5 '$4%0!Q%=4 <1:5 '$9E0!Q')4 <2!5 '$AE0!Q(]4 <235 '$F50! +MQ*54 <2J5 '$K50!Q+Q4 <3!5 '$Q%0!Q-)4 <3:5 '$Y%0!Q.U4 <3T5 '( +M^!0! L3^5 '% A0! LD%%@$!Q0M4 <4/%@$!Q1-4 <4C5 '%+%0!Q3M4 <5" +E5 '%3%0!Q5%4 <595 '%:%0!Q7=4 ?6@!@ " %B* @ =%0! + +end diff --git a/dmake/msdos/find.c b/dmake/msdos/find.c new file mode 100644 index 000000000000..d35cc477ec9e --- /dev/null +++ b/dmake/msdos/find.c @@ -0,0 +1,130 @@ +/* + Directory Access Library + + FIND.C taken from DIRLIB.C by M. J. Weinstein + Released to public domain 1-Jan-89 + + The author may be contacted at: + matt@cs.ucla.edu -or- POB 84524, L.A., CA 90073 + + Modified by dvadura@watdragon.edu to work with dmake. + (nuked the DOS version 2 code, since dmake needs version + 3.0 or greater to function). + */ + + +/* + * revision history: + * + * VER MM/DD/YY COMMENTS + * ---- -------- -------- + * 0.99 02/24/86 Beta release to INTERNET + */ + +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> +#include <errno.h> +#include <string.h> +#include <alloc.h> +#include <dos.h> +#include "dosdta.h" + +#ifndef MK_FP +#define MK_FP(seg,ofs) ((void far *) \ + (((unsigned long)(seg) << 16) | (unsigned)(ofs))) +#endif +#ifndef FP_SEG +#define FP_SEG(fp) ((unsigned)((unsigned long)(fp) >> 16)) +#endif +#ifndef FP_OFF +#define FP_OFF(fp) ((unsigned)(fp)) +#endif + +int find_err; + +/* + * get/set dta address + */ + +static DTA far * +_getsetdta(newdta) +DTA far *newdta; +{ + DTA far *olddta; + union REGS r; + struct SREGS s; + + /* get old dta */ + r.h.ah = 0x2f; + intdos(&r, &r); + segread(&s); + olddta = (DTA far *) MK_FP(s.es, r.x.bx); + + /* conditionally set new dta */ + if (newdta) { + r.h.ah = 0x1a; + s.ds = FP_SEG(newdta); + r.x.dx = FP_OFF(newdta); + intdosx(&r, &r, &s); + } + + return olddta; +} + +/* + * dos findfirst + */ + +DTA * +findfirst(name, dta) +char *name; +DTA *dta; +{ + union REGS r; + struct SREGS s; + DTA far *dtasave; + char far *nmp = (char far *)name; + + dtasave = _getsetdta((DTA far *)dta); + + /* do directory lookup */ + segread(&s); + r.h.ah = 0x4e; + r.x.cx = 0x10; + r.x.dx = FP_OFF(nmp); + s.ds = FP_SEG(nmp); + intdosx(&r, &r, &s); + /* restore dta */ + _getsetdta(dtasave); + find_err = r.x.ax; + if (r.x.cflag) + return(NULL); + + return dta; +} + +/* + * dos findnext + */ + +DTA * +findnext(dta) +DTA *dta; +{ + union REGS r; + DTA far *dtasave; + + dtasave = _getsetdta((DTA far *)dta); + + /* do directory lookup */ + r.h.ah = 0x4f; + intdos(&r, &r); + /* restore old dta */ + _getsetdta(dtasave); + find_err = r.x.ax; + if (r.x.cflag) + return(NULL); + + return dta; +} diff --git a/dmake/msdos/microsft/config.h b/dmake/msdos/microsft/config.h new file mode 100644 index 000000000000..ba62cfe2a353 --- /dev/null +++ b/dmake/msdos/microsft/config.h @@ -0,0 +1,77 @@ +/* RCS $Id: config.h,v 1.1.1.1 2000-09-22 15:33:29 hr Exp $ +-- +-- SYNOPSIS +-- Configurarion include file. +-- +-- DESCRIPTION +-- There is one of these for each specific machine configuration. +-- It can be used to further tweek the machine specific sources +-- so that they compile. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#if defined (_MSC_VER) +# if _MSC_VER < 500 + Force a compile-time blowup. + Do not define "#define _MSC_VER" for MSC compilers earlier than 5.0. +# endif +#endif + +/* define this for configurations that don't have the coreleft function + * so that the code compiles. To my knowledge coreleft exists only on + * Turbo C, but it is needed here since the function is used in many debug + * macros. */ +#define coreleft() 0L + +/* MSC Version 4.0 doesn't understand SIGTERM, later versions do. */ +#ifndef SIGTERM +# define SIGTERM SIGINT +#endif + +/* Fixes unimplemented line buffering for MSC 5.x and 6.0. + * MSC _IOLBF is the same as _IOFBF + */ +#if defined(MSDOS) && defined (_MSC_VER) +# undef _IOLBF +# define _IOLBF _IONBF +#endif + +/* in alloc.h: size_t is redefined + * defined in stdio.h which is included by alloc.h + */ +#if defined(MSDOS) && defined (_MSC_VER) +# define _TYPES_ +#endif + +/* in sysintf.c: SIGQUIT is used, this is not defined in MSC */ +#ifndef SIGQUIT +# define SIGQUIT SIGTERM +#endif + +/* MSC doesn't seem to care about CONST */ +#define CONST + +#ifndef MSDOS +# define MSDOS 1 +#endif + +/* a small problem with pointer to voids on some unix machines needs this */ +#define PVOID void * + +/* Have to pull this in for the standard lib defines */ +#include <io.h> diff --git a/dmake/msdos/microsft/config.mk b/dmake/msdos/microsft/config.mk new file mode 100644 index 000000000000..cd049cd471af --- /dev/null +++ b/dmake/msdos/microsft/config.mk @@ -0,0 +1,59 @@ +# This is the MSC 4.0 and higher DOS configuration file for DMAKE +# It simply modifies the values of SRC, and checks to see if +# OSENVIRONMENT is defined. If so it includes the appropriate +# config.mk file. +# +# It also sets the values of .SOURCE.c and .SOURCE.h to include the local +# directory. +# +osrdir := $(OS)$(DIRSEPSTR)$(OSRELEASE) + +TMPDIR := +.EXPORT : TMPDIR + +# Definition of macros for library, and C startup code. + +# The following sources are required for MSC +OSR_SRC = tempnam.c +.SETDIR=$(osrdir) : $(OSR_SRC) + +SRC += $(OSR_SRC) +.SOURCE.h : $(osrdir) + +SET_STACK = -stack:4096 +NDB_LDFLAGS += $(SET_STACK) + +ASFLAGS += -t -mx $(S_$(MODEL)) + +# Microsoft C doesn't need tail but needs head +LDTAIL = ; +LDHEAD = + +# Debugging libraries +DB_LDFLAGS += -co -li -map $(SET_STACK) +DB_LDLIBS += + +# NO Debug MSC flags: +# Set the environment variable MSC_VER to be one of 5.1, 6.0, 8.0 (for VC++4.0) +# to get these by default when you make dmake using 'dmake'. +# +# Setting MSC_VER to one of the above sets the variable _MSC_VER appropriately +# and sets the flags appropriately. + +CFLAGS += -I$(osrdir) $(C_$(MODEL)) -nologo +DB_CFLAGS += -Zi + +# See if we modify anything in the lower levels. +.IF $(OSENVIRONMENT) != $(NULL) + .INCLUDE .IGNORE : $(osrdir)$(DIRSEPSTR)$(OSENVIRONMENT)$(DIRSEPSTR)config.mk +.END + +C_s = +C_m = -AM +C_c = -AC +C_l = -AL + +S_s = -Dmsmall +S_m = -Dmmedium +S_c = -Dmcompact +S_l = -Dmlarge diff --git a/dmake/msdos/microsft/msc51/config.mk b/dmake/msdos/microsft/msc51/config.mk new file mode 100644 index 000000000000..beaae0dfea97 --- /dev/null +++ b/dmake/msdos/microsft/msc51/config.mk @@ -0,0 +1,11 @@ +# Definition of macros for library, and C startup code. +osedir = $(osrdir)$(DIRSEPSTR)$(OSENVIRONMENT) + +.IMPORT .IGNORE : MSC_VER +MSC_VER *= 5.1 + +CFLAGS += -I$(osedir) -D_MSC_VER=$(MSC_VER:s,.,,)0 + +NDB_CFLAGS += -Oscl -Gs +NDB_LDFLAGS += -exe -packc -batch +NDB_LDLIBS += diff --git a/dmake/msdos/microsft/msc51/lib.rsp b/dmake/msdos/microsft/msc51/lib.rsp new file mode 100644 index 000000000000..8b137891791f --- /dev/null +++ b/dmake/msdos/microsft/msc51/lib.rsp @@ -0,0 +1 @@ + diff --git a/dmake/msdos/microsft/msc51/libswp.rsp b/dmake/msdos/microsft/msc51/libswp.rsp new file mode 100644 index 000000000000..8b137891791f --- /dev/null +++ b/dmake/msdos/microsft/msc51/libswp.rsp @@ -0,0 +1 @@ + diff --git a/dmake/msdos/microsft/msc51/mk.bat b/dmake/msdos/microsft/msc51/mk.bat new file mode 100755 index 000000000000..b111d6e62f01 --- /dev/null +++ b/dmake/msdos/microsft/msc51/mk.bat @@ -0,0 +1,102 @@ +md objects +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs infer.c +copy infer.obj objects +del infer.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs make.c +copy make.obj objects +del make.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs stat.c +copy stat.obj objects +del stat.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs expand.c +copy expand.obj objects +del expand.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs dmstring.c +copy dmstring.obj objects +del dmstring.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs hash.c +copy hash.obj objects +del hash.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs dag.c +copy dag.obj objects +del dag.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs dmake.c +copy dmake.obj objects +del dmake.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs path.c +copy path.obj objects +del path.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs imacs.c +copy imacs.obj objects +del imacs.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs sysintf.c +copy sysintf.obj objects +del sysintf.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs parse.c +copy parse.obj objects +del parse.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs getinp.c +copy getinp.obj objects +del getinp.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs quit.c +copy quit.obj objects +del quit.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs state.c +copy state.obj objects +del state.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs dmdump.c +copy dmdump.obj objects +del dmdump.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs macparse.c +copy macparse.obj objects +del macparse.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs rulparse.c +copy rulparse.obj objects +del rulparse.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs percent.c +copy percent.obj objects +del percent.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs function.c +copy function.obj objects +del function.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs msdos\ruletab.c +copy ruletab.obj objects +del ruletab.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs msdos\dirbrk.c +copy dirbrk.obj objects +del dirbrk.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs msdos\runargv.c +copy runargv.obj objects +del runargv.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs msdos\arlib.c +copy arlib.obj objects +del arlib.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs msdos\dchdir.c +copy dchdir.obj objects +del dchdir.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs msdos\switchar.c +copy switchar.obj objects +del switchar.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs msdos\rmprq.c +copy rmprq.obj objects +del rmprq.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs msdos\tee.c +copy tee.obj objects +del tee.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs msdos\find.c +copy find.obj objects +del find.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs msdos\dirlib.c +copy dirlib.obj objects +del dirlib.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs msdos\dstrlwr.c +copy dstrlwr.obj objects +del dstrlwr.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs unix\dcache.c +copy dcache.obj objects +del dcache.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs msdos\microsft\tempnam.c +copy tempnam.obj objects +del tempnam.obj +link /stack:4096/exe/packc/batch @msdos\microsft\msc51\obj.rsp,dmake.exe,NUL.MAP; +copy msdos\microsft\msc51\template.mk startup\config.mk diff --git a/dmake/msdos/microsft/msc51/mkswp.bat b/dmake/msdos/microsft/msc51/mkswp.bat new file mode 100755 index 000000000000..5ab14d3517e5 --- /dev/null +++ b/dmake/msdos/microsft/msc51/mkswp.bat @@ -0,0 +1,104 @@ +md objects +masm -t -mx -Dmlarge msdos\exec.asm,,,; +mv exec.obj objects +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs infer.c +copy infer.obj objects +del infer.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs make.c +copy make.obj objects +del make.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs stat.c +copy stat.obj objects +del stat.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs expand.c +copy expand.obj objects +del expand.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs dmstring.c +copy dmstring.obj objects +del dmstring.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs hash.c +copy hash.obj objects +del hash.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs dag.c +copy dag.obj objects +del dag.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs dmake.c +copy dmake.obj objects +del dmake.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs path.c +copy path.obj objects +del path.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs imacs.c +copy imacs.obj objects +del imacs.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs sysintf.c +copy sysintf.obj objects +del sysintf.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs parse.c +copy parse.obj objects +del parse.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs getinp.c +copy getinp.obj objects +del getinp.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs quit.c +copy quit.obj objects +del quit.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs state.c +copy state.obj objects +del state.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs dmdump.c +copy dmdump.obj objects +del dmdump.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs macparse.c +copy macparse.obj objects +del macparse.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs rulparse.c +copy rulparse.obj objects +del rulparse.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs percent.c +copy percent.obj objects +del percent.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs function.c +copy function.obj objects +del function.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs msdos\ruletab.c +copy ruletab.obj objects +del ruletab.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs msdos\dirbrk.c +copy dirbrk.obj objects +del dirbrk.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs msdos\runargv.c +copy runargv.obj objects +del runargv.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs msdos\arlib.c +copy arlib.obj objects +del arlib.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs msdos\dchdir.c +copy dchdir.obj objects +del dchdir.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs msdos\switchar.c +copy switchar.obj objects +del switchar.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs msdos\rmprq.c +copy rmprq.obj objects +del rmprq.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs msdos\spawn.c +copy spawn.obj objects +del spawn.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs msdos\find.c +copy find.obj objects +del find.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs msdos\dirlib.c +copy dirlib.obj objects +del dirlib.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs msdos\dstrlwr.c +copy dstrlwr.obj objects +del dstrlwr.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs unix\dcache.c +copy dcache.obj objects +del dcache.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc51 -D_MSC_VER=510 -Oscl -Gs msdos\microsft\tempnam.c +copy tempnam.obj objects +del tempnam.obj +link /stack:4096/exe/packc/batch @msdos\microsft\msc51\objswp.rsp,dmake.exe,NUL.MAP; +copy msdos\microsft\msc51\template.mk startup\config.mk diff --git a/dmake/msdos/microsft/msc51/obj.rsp b/dmake/msdos/microsft/msc51/obj.rsp new file mode 100644 index 000000000000..8f79a32754c9 --- /dev/null +++ b/dmake/msdos/microsft/msc51/obj.rsp @@ -0,0 +1,33 @@ +objects\infer.obj+ +objects\make.obj+ +objects\stat.obj+ +objects\expand.obj+ +objects\dmstring.obj+ +objects\hash.obj+ +objects\dag.obj+ +objects\dmake.obj+ +objects\path.obj+ +objects\imacs.obj+ +objects\sysintf.obj+ +objects\parse.obj+ +objects\getinp.obj+ +objects\quit.obj+ +objects\state.obj+ +objects\dmdump.obj+ +objects\macparse.obj+ +objects\rulparse.obj+ +objects\percent.obj+ +objects\function.obj+ +objects\ruletab.obj+ +objects\dirbrk.obj+ +objects\runargv.obj+ +objects\arlib.obj+ +objects\dchdir.obj+ +objects\switchar.obj+ +objects\rmprq.obj+ +objects\tee.obj+ +objects\find.obj+ +objects\dirlib.obj+ +objects\dstrlwr.obj+ +objects\dcache.obj+ +objects\tempnam.obj diff --git a/dmake/msdos/microsft/msc51/objswp.rsp b/dmake/msdos/microsft/msc51/objswp.rsp new file mode 100644 index 000000000000..54524124d236 --- /dev/null +++ b/dmake/msdos/microsft/msc51/objswp.rsp @@ -0,0 +1,34 @@ +objects\exec.obj+ +objects\infer.obj+ +objects\make.obj+ +objects\stat.obj+ +objects\expand.obj+ +objects\dmstring.obj+ +objects\hash.obj+ +objects\dag.obj+ +objects\dmake.obj+ +objects\path.obj+ +objects\imacs.obj+ +objects\sysintf.obj+ +objects\parse.obj+ +objects\getinp.obj+ +objects\quit.obj+ +objects\state.obj+ +objects\dmdump.obj+ +objects\macparse.obj+ +objects\rulparse.obj+ +objects\percent.obj+ +objects\function.obj+ +objects\ruletab.obj+ +objects\dirbrk.obj+ +objects\runargv.obj+ +objects\arlib.obj+ +objects\dchdir.obj+ +objects\switchar.obj+ +objects\rmprq.obj+ +objects\spawn.obj+ +objects\find.obj+ +objects\dirlib.obj+ +objects\dstrlwr.obj+ +objects\dcache.obj+ +objects\tempnam.obj diff --git a/dmake/msdos/microsft/msc51/public.h b/dmake/msdos/microsft/msc51/public.h new file mode 100644 index 000000000000..3130d161c24e --- /dev/null +++ b/dmake/msdos/microsft/msc51/public.h @@ -0,0 +1,169 @@ +/* RCS $Id: public.h,v 1.1.1.1 2000-09-22 15:33:29 hr Exp $ +-- WARNING -- This file is AUTOMATICALLY GENERATED DO NOT EDIT IT +-- +-- +-- SYNOPSIS +-- Local functions exported to be visible by others. +-- +-- DESCRIPTION +-- This file is generated by 'genpub'. Function declarations +-- that appear in this file are extracted by 'genpub' from +-- source files. Any function in the source file whose definition +-- appears like: +-- +-- PUBLIC return_type +-- function( arg_list ); +-- type_expr1 arg1; +-- ... +-- +-- has its definition extracted and a line of the form: +-- +-- return_type function ANSI((type_expr1,type_expr2,...)); +-- +-- entered into the output file. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef _DMAKE_PUBLIC_h +#define _DMAKE_PUBLIC_h + +#ifdef EXTERN +#undef EXTERN +#endif +#if defined(DEFINE_DMAKE_VARIABLES) +#define EXTERN +#else +#define EXTERN extern +#endif + +/***** genpub: Begin list of generated function headers */ +void Infer_recipe ANSI((CELLPTR, CELLPTR)); +int Make_targets ANSI(()); +int Make ANSI((CELLPTR, CELLPTR)); +int Exec_commands ANSI((CELLPTR)); +void Print_cmnd ANSI((char *, int, int)); +int Push_dir ANSI((char *, char *, int)); +void Pop_dir ANSI((int)); +void Append_line ANSI((char *, int, FILE *, char *, int, int)); +void Stat_target ANSI((CELLPTR, int, int)); +char *Expand ANSI((char *)); +char *Apply_edit ANSI((char *, char *, char *, int, int)); +void Map_esc ANSI((char *)); +char* Apply_modifiers ANSI((int, char *)); +char* Tokenize ANSI((char *, char *, char, int)); +char* ScanToken ANSI((char *, char **, int)); +char *DmStrJoin ANSI((char *, char *, int, int)); +char *DmStrAdd ANSI((char *, char *, int)); +char *DmStrApp ANSI((char *, char *)); +char *DmStrDup ANSI((char *)); +char *DmStrDup2 ANSI((char *)); +char *DmStrPbrk ANSI((char *, char *)); +char *DmStrSpn ANSI((char *, char *)); +char *DmStrStr ANSI((char *, char *)); +char *DmSubStr ANSI((char *, char *)); +uint16 Hash ANSI((char *, uint32 *)); +HASHPTR Get_name ANSI((char *, HASHPTR *, int)); +HASHPTR Search_table ANSI((HASHPTR *, char *, uint16 *, uint32 *)); +HASHPTR Push_macro ANSI((HASHPTR)); +HASHPTR Pop_macro ANSI((HASHPTR)); +HASHPTR Def_macro ANSI((char *, char *, int)); +CELLPTR Def_cell ANSI((char *)); +LINKPTR Add_prerequisite ANSI((CELLPTR, CELLPTR, int, int)); +void Clear_prerequisites ANSI((CELLPTR)); +int Test_circle ANSI((CELLPTR, int)); +STRINGPTR Def_recipe ANSI((char *, STRINGPTR, int, int)); +t_attr Rcp_attribute ANSI((char *)); +void main ANSI((int, char **)); +FILE *Openfile ANSI((char *, int, int)); +FILE *Closefile ANSI(()); +FILE *Search_file ANSI((char *, char **)); +char *Filename ANSI(()); +int Nestlevel ANSI(()); +FILE *TryFiles ANSI((LINKPTR)); +void Fatal ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Error ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Warning ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void No_ram ANSI(()); +void Usage ANSI((int)); +void Version ANSI(()); +char *Get_suffix ANSI((char *)); +char *Basename ANSI((char *)); +char *Filedir ANSI((char *)); +char *Build_path ANSI((char *, char *)); +void Make_rules ANSI(()); +void Create_macro_vars ANSI(()); +time_t Do_stat ANSI((char *, char *, char **, int)); +int Do_touch ANSI((char *, char *, char **)); +void Void_lib_cache ANSI((char *, char *)); +time_t Do_time ANSI(()); +int Do_cmnd ANSI((char *, int, int, CELLPTR, int, int, int)); +char ** Pack_argv ANSI((int, int, char *)); +char *Read_env_string ANSI((char *)); +int Write_env_string ANSI((char *, char *)); +void ReadEnvironment ANSI(()); +void Catch_signals ANSI((void (*)())); +void Clear_signals ANSI(()); +void Prolog ANSI((int, char* [])); +void Epilog ANSI((int)); +char *Get_current_dir ANSI(()); +int Set_dir ANSI((char*)); +char Get_switch_char ANSI(()); +FILE* Get_temp ANSI((char **, char *, int)); +FILE *Start_temp ANSI((char *, CELLPTR, char **)); +void Open_temp_error ANSI((char *, char *)); +void Link_temp ANSI((CELLPTR, FILE *, char *)); +void Close_temp ANSI((CELLPTR, FILE *)); +void Unlink_temp_files ANSI((CELLPTR)); +void Handle_result ANSI((int, int, int, CELLPTR)); +void Update_time_stamp ANSI((CELLPTR)); +int Remove_file ANSI((char *)); +void Parse ANSI((FILE *)); +int Get_line ANSI((char *, FILE *)); +char *Do_comment ANSI((char *, char **, int)); +char *Get_token ANSI((TKSTRPTR, char *, int)); +void Quit ANSI(()); +void Read_state ANSI(()); +void Write_state ANSI(()); +int Check_state ANSI((CELLPTR, STRINGPTR *, int)); +void Dump ANSI(()); +void Dump_recipe ANSI((STRINGPTR)); +int Parse_macro ANSI((char *, int)); +int Macro_op ANSI((char *)); +int Parse_rule_def ANSI((int *)); +int Rule_op ANSI((char *)); +void Add_recipe_to_list ANSI((char *, int, int)); +void Bind_rules_to_targets ANSI((int)); +int Set_group_attributes ANSI((char *)); +DFALINKPTR Match_dfa ANSI((char *)); +void Check_circle_dfa ANSI(()); +void Add_nfa ANSI((char *)); +char *Exec_function ANSI((char *)); +int If_root_path ANSI((char *)); +int runargv ANSI((CELLPTR, int, int, int, int, char *)); +void Clean_up_processes ANSI(()); +int Wait_for_child ANSI((int, int)); +time_t seek_arch ANSI((char*, char*)); +int touch_arch ANSI((char*, char*)); +int dchdir ANSI((char *)); +void Remove_prq ANSI((CELLPTR)); +int spawnvpe ANSI((int, char *, char **, char **)); +void Hook_std_writes ANSI((char *)); +void dstrlwr ANSI((char *, char *)); +time_t CacheStat ANSI((char *, int)); + +#endif diff --git a/dmake/msdos/microsft/msc51/template.mk b/dmake/msdos/microsft/msc51/template.mk new file mode 100644 index 000000000000..7174197d6284 --- /dev/null +++ b/dmake/msdos/microsft/msc51/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= msdos + OSRELEASE *:= microsft + OSENVIRONMENT *:= msc51 diff --git a/dmake/msdos/microsft/msc60/config.mk b/dmake/msdos/microsft/msc60/config.mk new file mode 100644 index 000000000000..5b206bec34bd --- /dev/null +++ b/dmake/msdos/microsft/msc60/config.mk @@ -0,0 +1,11 @@ +# Definition of macros for library, and C startup code. +osedir = $(osrdir)$(DIRSEPSTR)$(OSENVIRONMENT) + +.IMPORT .IGNORE : MSC_VER +MSC_VER *= 6.0 + +CFLAGS += -I$(osedir) -D_MSC_VER=$(MSC_VER:s,.,,)0 + +NDB_CFLAGS += -Osecgl -Gs +NDB_LDFLAGS += -exe -packc -batch +NDB_LDLIBS += diff --git a/dmake/msdos/microsft/msc60/lib.rsp b/dmake/msdos/microsft/msc60/lib.rsp new file mode 100644 index 000000000000..8b137891791f --- /dev/null +++ b/dmake/msdos/microsft/msc60/lib.rsp @@ -0,0 +1 @@ + diff --git a/dmake/msdos/microsft/msc60/libswp.rsp b/dmake/msdos/microsft/msc60/libswp.rsp new file mode 100644 index 000000000000..8b137891791f --- /dev/null +++ b/dmake/msdos/microsft/msc60/libswp.rsp @@ -0,0 +1 @@ + diff --git a/dmake/msdos/microsft/msc60/mk.bat b/dmake/msdos/microsft/msc60/mk.bat new file mode 100755 index 000000000000..c260b6d54abd --- /dev/null +++ b/dmake/msdos/microsft/msc60/mk.bat @@ -0,0 +1,102 @@ +md objects +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs infer.c +copy infer.obj objects +del infer.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs make.c +copy make.obj objects +del make.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs stat.c +copy stat.obj objects +del stat.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs expand.c +copy expand.obj objects +del expand.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs dmstring.c +copy dmstring.obj objects +del dmstring.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs hash.c +copy hash.obj objects +del hash.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs dag.c +copy dag.obj objects +del dag.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs dmake.c +copy dmake.obj objects +del dmake.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs path.c +copy path.obj objects +del path.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs imacs.c +copy imacs.obj objects +del imacs.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs sysintf.c +copy sysintf.obj objects +del sysintf.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs parse.c +copy parse.obj objects +del parse.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs getinp.c +copy getinp.obj objects +del getinp.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs quit.c +copy quit.obj objects +del quit.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs state.c +copy state.obj objects +del state.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs dmdump.c +copy dmdump.obj objects +del dmdump.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs macparse.c +copy macparse.obj objects +del macparse.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs rulparse.c +copy rulparse.obj objects +del rulparse.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs percent.c +copy percent.obj objects +del percent.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs function.c +copy function.obj objects +del function.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs msdos\ruletab.c +copy ruletab.obj objects +del ruletab.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs msdos\dirbrk.c +copy dirbrk.obj objects +del dirbrk.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs msdos\runargv.c +copy runargv.obj objects +del runargv.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs msdos\arlib.c +copy arlib.obj objects +del arlib.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs msdos\dchdir.c +copy dchdir.obj objects +del dchdir.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs msdos\switchar.c +copy switchar.obj objects +del switchar.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs msdos\rmprq.c +copy rmprq.obj objects +del rmprq.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs msdos\tee.c +copy tee.obj objects +del tee.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs msdos\find.c +copy find.obj objects +del find.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs msdos\dirlib.c +copy dirlib.obj objects +del dirlib.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs msdos\dstrlwr.c +copy dstrlwr.obj objects +del dstrlwr.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs unix\dcache.c +copy dcache.obj objects +del dcache.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs msdos\microsft\tempnam.c +copy tempnam.obj objects +del tempnam.obj +link /stack:4096/exe/packc/batch @msdos\microsft\msc60\obj.rsp,dmake.exe,NUL.MAP; +copy msdos\microsft\msc60\template.mk startup\config.mk diff --git a/dmake/msdos/microsft/msc60/mkswp.bat b/dmake/msdos/microsft/msc60/mkswp.bat new file mode 100755 index 000000000000..6b9ed76a5085 --- /dev/null +++ b/dmake/msdos/microsft/msc60/mkswp.bat @@ -0,0 +1,104 @@ +md objects +masm -t -mx -Dmlarge msdos\exec.asm,,,; +mv exec.obj objects +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs infer.c +copy infer.obj objects +del infer.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs make.c +copy make.obj objects +del make.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs stat.c +copy stat.obj objects +del stat.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs expand.c +copy expand.obj objects +del expand.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs dmstring.c +copy dmstring.obj objects +del dmstring.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs hash.c +copy hash.obj objects +del hash.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs dag.c +copy dag.obj objects +del dag.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs dmake.c +copy dmake.obj objects +del dmake.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs path.c +copy path.obj objects +del path.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs imacs.c +copy imacs.obj objects +del imacs.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs sysintf.c +copy sysintf.obj objects +del sysintf.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs parse.c +copy parse.obj objects +del parse.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs getinp.c +copy getinp.obj objects +del getinp.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs quit.c +copy quit.obj objects +del quit.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs state.c +copy state.obj objects +del state.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs dmdump.c +copy dmdump.obj objects +del dmdump.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs macparse.c +copy macparse.obj objects +del macparse.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs rulparse.c +copy rulparse.obj objects +del rulparse.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs percent.c +copy percent.obj objects +del percent.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs function.c +copy function.obj objects +del function.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs msdos\ruletab.c +copy ruletab.obj objects +del ruletab.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs msdos\dirbrk.c +copy dirbrk.obj objects +del dirbrk.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs msdos\runargv.c +copy runargv.obj objects +del runargv.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs msdos\arlib.c +copy arlib.obj objects +del arlib.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs msdos\dchdir.c +copy dchdir.obj objects +del dchdir.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs msdos\switchar.c +copy switchar.obj objects +del switchar.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs msdos\rmprq.c +copy rmprq.obj objects +del rmprq.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs msdos\spawn.c +copy spawn.obj objects +del spawn.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs msdos\find.c +copy find.obj objects +del find.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs msdos\dirlib.c +copy dirlib.obj objects +del dirlib.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs msdos\dstrlwr.c +copy dstrlwr.obj objects +del dstrlwr.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs unix\dcache.c +copy dcache.obj objects +del dcache.obj +cl -c -I. -Imsdos -Imsdos\microsft -AL -nologo -Imsdos\microsft\msc60 -D_MSC_VER=600 -Osecgl -Gs msdos\microsft\tempnam.c +copy tempnam.obj objects +del tempnam.obj +link /stack:4096/exe/packc/batch @msdos\microsft\msc60\objswp.rsp,dmake.exe,NUL.MAP; +copy msdos\microsft\msc60\template.mk startup\config.mk diff --git a/dmake/msdos/microsft/msc60/obj.rsp b/dmake/msdos/microsft/msc60/obj.rsp new file mode 100644 index 000000000000..8f79a32754c9 --- /dev/null +++ b/dmake/msdos/microsft/msc60/obj.rsp @@ -0,0 +1,33 @@ +objects\infer.obj+ +objects\make.obj+ +objects\stat.obj+ +objects\expand.obj+ +objects\dmstring.obj+ +objects\hash.obj+ +objects\dag.obj+ +objects\dmake.obj+ +objects\path.obj+ +objects\imacs.obj+ +objects\sysintf.obj+ +objects\parse.obj+ +objects\getinp.obj+ +objects\quit.obj+ +objects\state.obj+ +objects\dmdump.obj+ +objects\macparse.obj+ +objects\rulparse.obj+ +objects\percent.obj+ +objects\function.obj+ +objects\ruletab.obj+ +objects\dirbrk.obj+ +objects\runargv.obj+ +objects\arlib.obj+ +objects\dchdir.obj+ +objects\switchar.obj+ +objects\rmprq.obj+ +objects\tee.obj+ +objects\find.obj+ +objects\dirlib.obj+ +objects\dstrlwr.obj+ +objects\dcache.obj+ +objects\tempnam.obj diff --git a/dmake/msdos/microsft/msc60/objswp.rsp b/dmake/msdos/microsft/msc60/objswp.rsp new file mode 100644 index 000000000000..54524124d236 --- /dev/null +++ b/dmake/msdos/microsft/msc60/objswp.rsp @@ -0,0 +1,34 @@ +objects\exec.obj+ +objects\infer.obj+ +objects\make.obj+ +objects\stat.obj+ +objects\expand.obj+ +objects\dmstring.obj+ +objects\hash.obj+ +objects\dag.obj+ +objects\dmake.obj+ +objects\path.obj+ +objects\imacs.obj+ +objects\sysintf.obj+ +objects\parse.obj+ +objects\getinp.obj+ +objects\quit.obj+ +objects\state.obj+ +objects\dmdump.obj+ +objects\macparse.obj+ +objects\rulparse.obj+ +objects\percent.obj+ +objects\function.obj+ +objects\ruletab.obj+ +objects\dirbrk.obj+ +objects\runargv.obj+ +objects\arlib.obj+ +objects\dchdir.obj+ +objects\switchar.obj+ +objects\rmprq.obj+ +objects\spawn.obj+ +objects\find.obj+ +objects\dirlib.obj+ +objects\dstrlwr.obj+ +objects\dcache.obj+ +objects\tempnam.obj diff --git a/dmake/msdos/microsft/msc60/public.h b/dmake/msdos/microsft/msc60/public.h new file mode 100644 index 000000000000..3130d161c24e --- /dev/null +++ b/dmake/msdos/microsft/msc60/public.h @@ -0,0 +1,169 @@ +/* RCS $Id: public.h,v 1.1.1.1 2000-09-22 15:33:29 hr Exp $ +-- WARNING -- This file is AUTOMATICALLY GENERATED DO NOT EDIT IT +-- +-- +-- SYNOPSIS +-- Local functions exported to be visible by others. +-- +-- DESCRIPTION +-- This file is generated by 'genpub'. Function declarations +-- that appear in this file are extracted by 'genpub' from +-- source files. Any function in the source file whose definition +-- appears like: +-- +-- PUBLIC return_type +-- function( arg_list ); +-- type_expr1 arg1; +-- ... +-- +-- has its definition extracted and a line of the form: +-- +-- return_type function ANSI((type_expr1,type_expr2,...)); +-- +-- entered into the output file. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef _DMAKE_PUBLIC_h +#define _DMAKE_PUBLIC_h + +#ifdef EXTERN +#undef EXTERN +#endif +#if defined(DEFINE_DMAKE_VARIABLES) +#define EXTERN +#else +#define EXTERN extern +#endif + +/***** genpub: Begin list of generated function headers */ +void Infer_recipe ANSI((CELLPTR, CELLPTR)); +int Make_targets ANSI(()); +int Make ANSI((CELLPTR, CELLPTR)); +int Exec_commands ANSI((CELLPTR)); +void Print_cmnd ANSI((char *, int, int)); +int Push_dir ANSI((char *, char *, int)); +void Pop_dir ANSI((int)); +void Append_line ANSI((char *, int, FILE *, char *, int, int)); +void Stat_target ANSI((CELLPTR, int, int)); +char *Expand ANSI((char *)); +char *Apply_edit ANSI((char *, char *, char *, int, int)); +void Map_esc ANSI((char *)); +char* Apply_modifiers ANSI((int, char *)); +char* Tokenize ANSI((char *, char *, char, int)); +char* ScanToken ANSI((char *, char **, int)); +char *DmStrJoin ANSI((char *, char *, int, int)); +char *DmStrAdd ANSI((char *, char *, int)); +char *DmStrApp ANSI((char *, char *)); +char *DmStrDup ANSI((char *)); +char *DmStrDup2 ANSI((char *)); +char *DmStrPbrk ANSI((char *, char *)); +char *DmStrSpn ANSI((char *, char *)); +char *DmStrStr ANSI((char *, char *)); +char *DmSubStr ANSI((char *, char *)); +uint16 Hash ANSI((char *, uint32 *)); +HASHPTR Get_name ANSI((char *, HASHPTR *, int)); +HASHPTR Search_table ANSI((HASHPTR *, char *, uint16 *, uint32 *)); +HASHPTR Push_macro ANSI((HASHPTR)); +HASHPTR Pop_macro ANSI((HASHPTR)); +HASHPTR Def_macro ANSI((char *, char *, int)); +CELLPTR Def_cell ANSI((char *)); +LINKPTR Add_prerequisite ANSI((CELLPTR, CELLPTR, int, int)); +void Clear_prerequisites ANSI((CELLPTR)); +int Test_circle ANSI((CELLPTR, int)); +STRINGPTR Def_recipe ANSI((char *, STRINGPTR, int, int)); +t_attr Rcp_attribute ANSI((char *)); +void main ANSI((int, char **)); +FILE *Openfile ANSI((char *, int, int)); +FILE *Closefile ANSI(()); +FILE *Search_file ANSI((char *, char **)); +char *Filename ANSI(()); +int Nestlevel ANSI(()); +FILE *TryFiles ANSI((LINKPTR)); +void Fatal ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Error ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Warning ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void No_ram ANSI(()); +void Usage ANSI((int)); +void Version ANSI(()); +char *Get_suffix ANSI((char *)); +char *Basename ANSI((char *)); +char *Filedir ANSI((char *)); +char *Build_path ANSI((char *, char *)); +void Make_rules ANSI(()); +void Create_macro_vars ANSI(()); +time_t Do_stat ANSI((char *, char *, char **, int)); +int Do_touch ANSI((char *, char *, char **)); +void Void_lib_cache ANSI((char *, char *)); +time_t Do_time ANSI(()); +int Do_cmnd ANSI((char *, int, int, CELLPTR, int, int, int)); +char ** Pack_argv ANSI((int, int, char *)); +char *Read_env_string ANSI((char *)); +int Write_env_string ANSI((char *, char *)); +void ReadEnvironment ANSI(()); +void Catch_signals ANSI((void (*)())); +void Clear_signals ANSI(()); +void Prolog ANSI((int, char* [])); +void Epilog ANSI((int)); +char *Get_current_dir ANSI(()); +int Set_dir ANSI((char*)); +char Get_switch_char ANSI(()); +FILE* Get_temp ANSI((char **, char *, int)); +FILE *Start_temp ANSI((char *, CELLPTR, char **)); +void Open_temp_error ANSI((char *, char *)); +void Link_temp ANSI((CELLPTR, FILE *, char *)); +void Close_temp ANSI((CELLPTR, FILE *)); +void Unlink_temp_files ANSI((CELLPTR)); +void Handle_result ANSI((int, int, int, CELLPTR)); +void Update_time_stamp ANSI((CELLPTR)); +int Remove_file ANSI((char *)); +void Parse ANSI((FILE *)); +int Get_line ANSI((char *, FILE *)); +char *Do_comment ANSI((char *, char **, int)); +char *Get_token ANSI((TKSTRPTR, char *, int)); +void Quit ANSI(()); +void Read_state ANSI(()); +void Write_state ANSI(()); +int Check_state ANSI((CELLPTR, STRINGPTR *, int)); +void Dump ANSI(()); +void Dump_recipe ANSI((STRINGPTR)); +int Parse_macro ANSI((char *, int)); +int Macro_op ANSI((char *)); +int Parse_rule_def ANSI((int *)); +int Rule_op ANSI((char *)); +void Add_recipe_to_list ANSI((char *, int, int)); +void Bind_rules_to_targets ANSI((int)); +int Set_group_attributes ANSI((char *)); +DFALINKPTR Match_dfa ANSI((char *)); +void Check_circle_dfa ANSI(()); +void Add_nfa ANSI((char *)); +char *Exec_function ANSI((char *)); +int If_root_path ANSI((char *)); +int runargv ANSI((CELLPTR, int, int, int, int, char *)); +void Clean_up_processes ANSI(()); +int Wait_for_child ANSI((int, int)); +time_t seek_arch ANSI((char*, char*)); +int touch_arch ANSI((char*, char*)); +int dchdir ANSI((char *)); +void Remove_prq ANSI((CELLPTR)); +int spawnvpe ANSI((int, char *, char **, char **)); +void Hook_std_writes ANSI((char *)); +void dstrlwr ANSI((char *, char *)); +time_t CacheStat ANSI((char *, int)); + +#endif diff --git a/dmake/msdos/microsft/msc60/template.mk b/dmake/msdos/microsft/msc60/template.mk new file mode 100644 index 000000000000..a147c694c5f7 --- /dev/null +++ b/dmake/msdos/microsft/msc60/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= msdos + OSRELEASE *:= microsft + OSENVIRONMENT *:= msc60 diff --git a/dmake/msdos/microsft/optoff.h b/dmake/msdos/microsft/optoff.h new file mode 100644 index 000000000000..b2426a1259ba --- /dev/null +++ b/dmake/msdos/microsft/optoff.h @@ -0,0 +1,27 @@ +/* RCS $Id: optoff.h,v 1.1.1.1 2000-09-22 15:33:29 hr Exp $ +-- +-- SYNOPSIS +-- Turn off microsoft loop optimization. +-- +-- DESCRIPTION +-- This is broken in some pre 600 compilers so just turn it off. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ +#if _MSC_VER < 600 +# pragma loop_opt(off) +#endif diff --git a/dmake/msdos/microsft/tempnam.c b/dmake/msdos/microsft/tempnam.c new file mode 100644 index 000000000000..1a105c6b0f3a --- /dev/null +++ b/dmake/msdos/microsft/tempnam.c @@ -0,0 +1,110 @@ +/* RCS $Id: tempnam.c,v 1.1.1.1 2000-09-22 15:33:29 hr Exp $ +-- +-- SYNOPSIS +-- tempnam +-- +-- DESCRIPTION +-- temp file name generation routines. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +/*LINTLIBRARY*/ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <dos.h> + +#if defined(max) +# undef max +#endif +#define max(A,B) (((A)<(B))?(B):(A)) + +extern char *mktemp(); +extern int access(); +int d_access(); + +/* MSC stdio.h defines P_tmpdir, so let's undo it here */ +/* Under DOS leave the default tmpdir pointing here! */ +#ifdef P_tmpdir +#undef P_tmpdir +#endif +static char *P_tmpdir = ""; + +char * +tempnam(dir, prefix) +char *dir; /* use this directory please (if non-NULL) */ +char *prefix; /* use this (if non-NULL) as filename prefix */ +{ + static int count = 0; + register char *p, *q, *tmpdir; + int tl=0, dl=0, pl; + char buf[30]; + + pl = strlen(P_tmpdir); + + if( (tmpdir = getenv("TMPDIR")) != NULL ) tl = strlen(tmpdir); + else if( (tmpdir = getenv("TMP")) != NULL ) tl = strlen(tmpdir); + if( dir != NULL ) dl = strlen(dir); + + if( (p = malloc((unsigned)(max(max(dl,tl),pl)+13))) == NULL ) + return(NULL); + + *p = '\0'; + + if( (tl == 0) || (d_access( strcpy(p, tmpdir), 0) != 0) ) + if( (dl == 0) || (d_access( strcpy(p, dir), 0) != 0) ) + if( d_access( strcpy(p, P_tmpdir), 0) != 0 ) + if( !prefix ) + prefix = "tp"; + + if(prefix) + { + *(p+strlen(p)+2) = '\0'; + (void)strncat(p, prefix, 2); + } + + sprintf( buf, "%08x", _psp ); + buf[6]='\0'; + (void)strcat(p, buf ); + sprintf( buf, "%04d", count++ ); + q=p+strlen(p)-6; + *q++ = buf[0]; *q++ = buf[1]; + *q++ = buf[2]; *q++ = buf[3]; + + if( (q = strrchr(p,'.')) != NULL ) *q = '\0'; + + return(p); +} + + + +d_access( name, flag ) +char *name; +int flag; +{ + extern char *DirSepStr; + char *p; + int r; + + if( name == NULL || !*name ) return(1); /* NULL dir means current dir */ + r = access( name, flag ); + p = name+strlen(name)-1; + if(*p != '/' && *p != '\\') strcat( p, DirSepStr ); + + return( r ); +} diff --git a/dmake/msdos/rmprq.c b/dmake/msdos/rmprq.c new file mode 100644 index 000000000000..f2194bced053 --- /dev/null +++ b/dmake/msdos/rmprq.c @@ -0,0 +1,38 @@ +/* RCS $Id: rmprq.c,v 1.1.1.1 2000-09-22 15:33:27 hr Exp $ +-- +-- SYNOPSIS +-- Remove prerequisites code. +-- +-- DESCRIPTION +-- This code is different for DOS and for UNIX and parallel make +-- architectures since the parallel case requires the rm's to be +-- run in parallel, whereas DOS guarantees to run them sequentially. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include "extern.h" + +PUBLIC void +Remove_prq( tcp ) +CELLPTR tcp; +{ + tcp->ce_flag &= ~(F_MADE|F_VISITED); + tcp->ce_time = 0L; + + Make( tcp, tcp ); +} diff --git a/dmake/msdos/ruletab.c b/dmake/msdos/ruletab.c new file mode 100644 index 000000000000..6d9d69f348a1 --- /dev/null +++ b/dmake/msdos/ruletab.c @@ -0,0 +1,45 @@ +/* RCS $Id: ruletab.c,v 1.1.1.1 2000-09-22 15:33:27 hr Exp $ +-- +-- SYNOPSIS +-- Default initial configuration of dmake. +-- +-- DESCRIPTION +-- Define here the initial set of rules that are defined before +-- dmake performs any processing. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +/* These are control macros for dmake that MUST be defined at some point + * if they are NOT dmake will not work! These are default definitions. They + * may be overridden inside the .STARTUP makefile, they are here + * strictly so that dmake can parse the STARTUP makefile */ + +#include <stdio.h> + +static char *_rules[] = { + "MAXLINELENGTH := 2046", + "MAXPROCESSLIMIT := 1", + "MAXPROCESS := 1", + ".IMPORT .IGNORE: ROOTDIR", + ".MAKEFILES : makefile.mk makefile", + ".SOURCE : .NULL", +#include "startup.h" + (char *)NULL }; + +char **Rule_tab = _rules; /* for sundry reasons in Get_environment() */ + diff --git a/dmake/msdos/runargv.c b/dmake/msdos/runargv.c new file mode 100644 index 000000000000..cefd5d9944b2 --- /dev/null +++ b/dmake/msdos/runargv.c @@ -0,0 +1,132 @@ +/* RCS $Id: runargv.c,v 1.1.1.1 2000-09-22 15:33:27 hr Exp $ +-- +-- SYNOPSIS +-- Run a sub process. +-- +-- DESCRIPTION +-- Use spawn to run a subprocess. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include <process.h> +#include <errno.h> +#include "extern.h" +#include "sysintf.h" + +static int _abort_flg = FALSE; +static void _add_child ANSI((CELLPTR, int)); +static void _finished_child ANSI((int)); + +PUBLIC int +runargv(target, ignore, group, last, shell, cmd) +CELLPTR target; +int ignore; +int group; +int last; +int shell; +char *cmd; +{ +#if ! defined(_MSC_VER) +#if defined(__BORLANDC__) && __BORLANDC__ >= 0x500 + extern char ** _RTLENTRY _EXPDATA environ; +#else + extern char **environ; +#endif +#endif + int status; + char **argv; + + _add_child(target, ignore); + /* return immediately for noop command */ + if (strncmp(cmd, "noop", 4) == 0 && (cmd[4] == ' ' || cmd[4] == '\0')) { + status = 0; + } + else { + argv = Pack_argv( group, shell, cmd ); + + if ( strcmp(argv[0],"echo") == 0 ) { + int i; + int first = 1; + int nl = 1; + + if (strcmp(argv[1],"-n") == 0) nl--; + + for (i=2-nl;argv[i]; i++) { + if (!first) putchar(' '); + printf("%s", argv[i]); + } + if (nl) printf("\n"); + fflush(stdout); + status = 0; + } + else { + status = spawnvpe(P_WAIT, *argv, argv, environ); + } + } + + if( status == -1 ) Error("%s: %s", argv[0], strerror(errno)); + _finished_child(status); + if( last && !Doing_bang ) Update_time_stamp( target ); + + return( 0 ); +} + + +PUBLIC void +Clean_up_processes() +{ + _abort_flg = TRUE; + _finished_child(-1); +} + + +PUBLIC int +Wait_for_child( abort_flg, pid ) +int abort_flg; +int pid; +{ + return(1); +} + + +static int _valid = -1; +static CELLPTR _tg; +static int _ignore; + +static void +_add_child( target, ignore ) +CELLPTR target; +int ignore; +{ + _tg = target; + _ignore = ignore; + _valid = 0; + + Current_target = NIL(CELL); +} + + +static void +_finished_child(status) +int status; +{ + if( _valid == -1 ) return; + Unlink_temp_files( _tg ); + _valid = -1; + Handle_result( status, _ignore, _abort_flg, _tg ); +} diff --git a/dmake/msdos/spawn.c b/dmake/msdos/spawn.c new file mode 100644 index 000000000000..e62d936ee567 --- /dev/null +++ b/dmake/msdos/spawn.c @@ -0,0 +1,414 @@ +/* RCS $Id: spawn.c,v 1.1.1.1 2000-09-22 15:33:27 hr Exp $ +-- +-- SYNOPSIS +-- Spawnvpe code to emulate spawnvpe call common to DOS compilers. +-- +-- DESCRIPTION +-- This implementation is further integrated into dmake in that it +-- determines the program to execute and if it's extension is either +-- .bat or .ksh it executes it using the appropriate shell based on the +-- setting of .MKSARGS. If .MKSARGS is set then in addition +-- to the command tail getting built the arguments are also passed in the +-- environment pursuant to the published MKS argument passing conventions. +-- If the variable Swap_on_exec is set and the DOS OS supports it +-- then the dmake executable image is swapped to secondary storage prior +-- to running the child process. This is requested by setting the +-- appropriate flag in the call to exec. +-- +-- This and the exec.asm routine are derived from work that was supplied +-- to me by Kent Williams (williams@umaxc.weeg.uiowa.edu) and by +-- Len Reed, (..!gatech!holos0!lbr or holos0!lbr@gatech.edu., Holos +-- Software, Inc., Tucker, Ga.). I sincerely acknowledge their help since +-- their Turbo C, and MSC 6.0 code lead directly to this combined +-- swapping exec that hopefully works with either compiler in all memory +-- models. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include <stdio.h> +#include <stdlib.h> + +#if defined(_MSC_VER) && _MSC_VER >= 600 + /* Ignore the MSC 6.0 library's "const"-riddled prototype + for spawnvpe. + */ +# define spawnvpe _ignore_msc_spawnvpe +# include <process.h> +# undef spawnvpe + int spawnvpe(int, char *, char **, char **); +#else +# include <process.h> +#endif + +#include <dos.h> +#include <errno.h> +#include <string.h> +#include <alloc.h> +#include <fcntl.h> +#include "extern.h" +#include "dosdta.h" +#include "exec.h" +#include "sysintf.h" + +extern int Interrupted; + +/* variables and functions local to this file */ +static char *_findexec ANSI((char *, int *)); +static char **_getpath ANSI(()); +static char far *_dos_alloc ANSI((uint16)); + +static uint16 _swap_mask; +static int _mks_args; +static char dot_com[] = ".COM", + dot_exe[] = ".EXE", + dot_bat[] = ".BAT", + dot_ksh[] = ".KSH"; + +/* Kinds of executables */ +#define SCR 1 +#define COM 2 +#define EXE 4 +#define ALL (SCR|COM|EXE) + +/* How to make a long pointer */ +#define CF(x) (char far *)x + +/* Make sure we know how to get a segment out of a long pointer */ +#ifndef FP_SEG +#define FP_SEG(fp) ((unsigned)((unsigned long)(fp) >> 16)) +#endif + + +PUBLIC int +spawnvpe(mode, program, av, ep)/* +================================= + Spawn a process using an environment and a vector of arguments. + The code computes a new environment, puts the MKS arguments into + it if need be, and calls the appropriate routines to search the + path and to invoke the process. */ +int mode; +char *program; +char **av; +char **ep; +{ + char pwd[PATH_MAX+1]; + char **envp = ep; /* Cause we are going to mess with it. */ + char **argv = av; /* Same with this one. */ + char cmdtail[129]; + char far *environment; + char *tail; + char *swptmp; + unsigned int envsize; + unsigned int cmdsize; + int cmdtailen; + int i; + int doswap; + + /* First check to see if we can find the program to execute this way we + * don't alloc the environment and other such stuff prior to figuring out + * we don't know how to run the program. */ +find_program: + if((program = _findexec(program, &i)) == NIL(char)) { + errno = ENOENT; + return( -1 ); + } + + /* i is set to TRUE in _findexec if the exec is a shell + * script (either .BAT or .KSH file), returns FALSE for all others. */ + if( i && !Packed_shell ) { + /* Restore the spaces into the command line that were erased by + * the previous call to Pack_argv. This enables us to repack the + * command as a shell command using Pack_argv again. */ + for( i=0; argv[i] != NIL(char); i++ ) { + int x = strlen(argv[i]); + if( argv[i+1] != NIL(char) ) argv[i][x] = ' '; + } + + argv = Pack_argv( FALSE, TRUE, *argv ); + + /* Go and find the program again, I hate goto's but it seems silly to + * use tail recursion here just for aesthetic purity. */ + program = *argv; + goto find_program; + } + + /* Compute size of *argv vector for passing as MKS style arguments */ + cmdsize = strlen(*argv)+2; + + /* So we have decided on a program to run, therefore pack the command tail + * and build the environment to pass to the exec code. This loop packs the + * DOS command tail, and computes the size of all arguments for the MKS + * argument passing convention. Note that we reserve one less byte in the + * command tail if we are not using MKS style argument passing. + * + * Make sure the command tail contains at leat a space. Some commands fail + * to work if the command tail is only a \r, STUPID DOS! */ + cmdtailen = ((_mks_args = ((Glob_attr & A_MKSARGS) != 0)) != 0)?3:2; + tail = cmdtail+1; + + if( argv[1] != NIL(char) ) + for( i=1; argv[i] != NIL(char); i++ ) { + int arglen = strlen(argv[i]); + + cmdsize += arglen+2; /* Compute all args size for MKS */ + + if( (cmdtailen += arglen+1) <= 128 ) { + register char *p = argv[i]; + tail[-1] = ' '; /* put in the space */ + while( *tail++ = *p++ ); /* put in the arg */ + } + else if( !_mks_args ) { + errno = E2BIG; /* unless its MKS exit if arglist */ + return(-1); /* is too long. */ + } + } + else + *tail++ = ' '; + + /* Finish the command tail set up, placing the length in the first byte, + * and the \r \n \0 at the end for DOS, MKS and us respectively. */ + *cmdtail = tail-cmdtail-2; + tail[-1] = '\r'; + if( _mks_args ) *tail++ = '\n'; + *tail = '\0'; + + /* Compute size of environment, skipping any MKS arguments passed in our + * environment */ + for(; *envp && **envp == '~'; envp++ ); + for(i=0, envsize=_mks_args?cmdsize:1; envp[i] != NIL(char); i++ ) + envsize += strlen(envp[i]) + 1; + + /* Check the DOS version number here. If it is < 3.0 then we don't + * even want to think about executing the swapping code. Permanently + * set swap to 0. */ + doswap = (_osmajor < 3) ? 0 : Swap_on_exec; + + /* Set up temporary file for swapping */ + swptmp = doswap?tempnam(NIL(char),"mk"):""; + + /* Allocate an appropriate sized environment block and align it on a + * paragraph boundary. It will later get copied to an appropriately low + * place in the executable image so that when we swap out the environment + * is still present. Use + * _dos_alloc + * to allocate the environment segment. The segment is freed by the call + * to exec. */ + environment = _dos_alloc( envsize = ((envsize+16)>>4) ); + *environment = '\0'; + + /* First copy the arguments preceeded by ~ character if we are using + * MKS style argument passing */ + if( _mks_args ) + for(; *argv; argv++) { + register char *p = *argv; + + *environment++ = '~'; + while( *environment++ = *p++ ); /* Far dest, poss near ptr */ + } + + /* Now stick in the current evironment vectors. */ + for(; *envp; envp++) { + register char *p = *envp; + while( *environment++ = *p++ ); /* Far dest, poss near ptr */ + } + + /* Clear the interrupted flag, and exec */ + Interrupted = 0; + + /* Preserve the current working directory accross a spawn call + * DOS is brain dead about this. This way we have some hope of cleaning + * up the swapping tempfiles after we return. */ + strcpy(pwd,Get_current_dir()); + i = exec(doswap,CF(program),CF(cmdtail),FP_SEG(environment),CF(swptmp)); + Set_dir(pwd); + + /* Now free the temporary file name */ + if( doswap ) FREE(swptmp); + + /* If swap was interrupted then quit properly from dmake. */ + if( Interrupted ) Quit(); + + return(i); +} + + +PUBLIC void +Hook_std_writes( file ) +char *file; +{ + if( file!= NIL(char) ) { + int mode = O_BINARY | O_WRONLY | O_CREAT | O_TRUNC; + int handle; + + if (*file == '+') { + ++file; /* -F +file means append to file */ + mode = O_BINARY | O_WRONLY | O_CREAT | O_APPEND; + } + handle = open(file, mode, S_IREAD | S_IWRITE); + if (handle < 0) { + Fatal( "Could not open -F file"); + } + (void) lseek(handle, 0L, SEEK_END); + do_hook_std_writes(handle); + } + else + do_unhook_std_writes(); +} + + +/* +** _findexec finds executables on the path. +** Note that it is pretty simple to add support for other executable types +** shell scripts, etc. +** +** This follows the command.com behavior very closely. +*/ +static char * +_findexec( s, is_shell )/* +========================== + Cloned closely from code provided by Kent Williams. Stripped his down to + a reduced search since dmake doesn't need to recompute the PATH vector + each time it does the search since it cannot alter the path vector once + it begins to make recipes. Also modified it to use findfirst and findnext + as provided for dirlib package that I got off the net. */ +char *s; +int *is_shell; +{ + unsigned found_flags; + char **pathv = NIL(char *); + char *ext = NIL(char); + char *buf = NIL(char); + char *p[2]; + char *dot_scr; + char *dot; + + p[0] = ""; p[1] = NIL(char); + if( strchr("./\\", *s) || s[1] == ':' ) + pathv = p; + else if( (pathv = _getpath()) == NIL(char *) ) + return( NIL(char) ); + + /* Compute the extension we need if any. */ + if( (dot = strrchr(s,'.')) != NIL(char) && + dot > strrchr(s,'/') && dot > strrchr(s,'\\') ) + ext = dot+1; + + dot_scr = _mks_args ? dot_ksh : dot_bat; + *is_shell = FALSE; + + for( found_flags = 0; *pathv && !found_flags; pathv++ ) { + DTA dta; + + if( !ext ) { + char *name; + buf = Build_path( *pathv, name=DmStrJoin(s, ".???", -1, FALSE) ); + FREE(name); + } + else + buf = Build_path( *pathv, s ); + + if( findfirst((char *)strupr(buf), &dta) != NIL(DTA) ) { + if( !ext ) { + char *dot; + + /* search order is .com .exe (.ksh || .bat) + * there has to be a '.' */ + do { + dot = strrchr(dta.name,'.'); + if(0 == strcmp(dot,dot_com)) + found_flags |= COM; + else if(0 == strcmp(dot,dot_exe)) + found_flags |= EXE; + else if( 0 == strcmp(dot,dot_scr) ) + found_flags |= SCR; + } while( found_flags != ALL && findnext(&dta) != NIL(DTA) ); + + if(found_flags & COM) ext = dot_com; + else if(found_flags & EXE) ext = dot_exe; + else if(found_flags & SCR) { + ext = dot_scr; + *is_shell = TRUE; + } + + if( found_flags ) { + char *name; + buf = Build_path( *pathv, name=DmStrJoin(s,ext,-1,FALSE) ); + FREE(name); + strupr(buf); + } + } + else + found_flags++; + } + } + + return( found_flags ? buf : NIL(char) ); +} + + +/* +** getpath turns the DOS path into a char *vector, It is gotten and +** transformed only once since dmake can't modify the value of PATH while +** it is making targets. +*/ +static char ** +_getpath() +{ + static char **dir = NIL(char *); + register char *p; + + if( !dir ) { + register char *t; + int i; + char *semi = NIL(char); + + if( (p = getenv("PATH")) == NIL(char) ) p = ""; + for( i=1, t=p; *t; t++ ) if( *t == ';' ) i++; + + TALLOC(dir, i+1, char *); + p = DmStrDup(p); + + for( i=0; p; p = semi ? (semi+1):NIL(char),i++ ){ + if( (semi = strchr(p,';')) != NIL(char) ) *semi = '\0'; + dir[i] = p; + } + dir[i]=NIL(char); + } + + return( dir ); +} + + +static char far * +_dos_alloc( size )/* +==================== + This routine allocates size paragraphs from DOS. It changes the memory + allocation strategy to allocate from the tail and then changes it back. + to using first fit. */ +uint16 size; +{ + union REGS r; + + r.h.ah = 0x48; + r.x.bx = size; + + intdos( &r, &r ); + if( r.x.cflag ) No_ram(); + + return( (char far *) MK_FP(r.x.ax, 0) ); +} diff --git a/dmake/msdos/startup.h b/dmake/msdos/startup.h new file mode 100644 index 000000000000..22eeb863e809 --- /dev/null +++ b/dmake/msdos/startup.h @@ -0,0 +1,26 @@ +/* RCS $Id: startup.h,v 1.1.1.1 2000-09-22 15:33:27 hr Exp $ +-- +-- SYNOPSIS +-- Dmake startup header file definition. +-- +-- DESCRIPTION +-- Where we define the default value of MAKESTARTUP. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +"MAKESTARTUP := $(MAKECMD:d)startup/startup.mk", diff --git a/dmake/msdos/switchar.c b/dmake/msdos/switchar.c new file mode 100644 index 000000000000..8879a9ad7c44 --- /dev/null +++ b/dmake/msdos/switchar.c @@ -0,0 +1,55 @@ +/* RCS $Id: switchar.c,v 1.1.1.1 2000-09-22 15:33:27 hr Exp $ +-- +-- SYNOPSIS +-- switch char query. +-- +-- DESCRIPTION +-- Get the current value of the command line switch char. Only useful +-- in a DOS environment, otherwise we #define it to be '-'. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ +#if defined(_MSC_VER) +#include <stdlib.h> +#endif +#include <dos.h> +#include <stdio.h> +#include "stdmacs.h" + +getswitchar()/* +=============== + Try the environment first. If you don't find SWITCHAR there, then use + the DOS call. The call is undocumented, and doesn't work for DOS versions + 4.0 and up, so the check of the environment will fix that. */ +{ +#if defined(__MSDOS__) || defined(M_I86) + union REGS rg; + static char *_env_switchar = NIL(char); + + if( _env_switchar != NIL(char) || + (_env_switchar = (char *)getenv("SWITCHAR")) != NIL(char) ) + return(*_env_switchar); + + rg.h.ah = 0x37; /* switch char request */ + rg.h.al = 0; /* get (not set) */ + + intdos(&rg, &rg); + return (rg.h.dl); +#endif /* M_I86 */ + + return ('-'); +} diff --git a/dmake/msdos/sysintf.h b/dmake/msdos/sysintf.h new file mode 100644 index 000000000000..2a6d92a59329 --- /dev/null +++ b/dmake/msdos/sysintf.h @@ -0,0 +1,53 @@ +/* RCS $Id: sysintf.h,v 1.1.1.1 2000-09-22 15:33:27 hr Exp $ +-- +-- SYNOPSIS +-- Interfaces for sysintf.c +-- +-- DESCRIPTION +-- Abstractions of functions in sysintf.c +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ +#define DMSTAT stat +#define VOID_LCACHE(l,m) +#define GETPID _psp +#define DMSTRLWR(A,B) dstrlwr(A,B) + +extern char * tempnam(); +extern char * getcwd(); + +/* +** standard C items +*/ + +/* +** DOS interface standard items +*/ +#define chdir(p) dchdir(p) + +/* +** make parameters +*/ +#ifdef _POSIX_NAME_MAX +#undef _POSIX_NAME_MAX +#endif +#define _POSIX_NAME_MAX 12 + +#ifdef _POSIX_PATH_MAX +#undef _POSIX_PATH_MAX +#endif +#define _POSIX_PATH_MAX 64 diff --git a/dmake/msdos/tee.c b/dmake/msdos/tee.c new file mode 100644 index 000000000000..f2c8b5de6543 --- /dev/null +++ b/dmake/msdos/tee.c @@ -0,0 +1,31 @@ +/* RCS $Id: tee.c,v 1.1.1.1 2000-09-22 15:33:27 hr Exp $ +-- +-- SYNOPSIS +-- Hook_std_writes() dummy call for non swapping MSDOS versions. +-- +-- DESCRIPTION +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include "extern.h" + +PUBLIC void +Hook_std_writes( file ) +char *file; +{ +} diff --git a/dmake/msdos/zortech/config.h b/dmake/msdos/zortech/config.h new file mode 100644 index 000000000000..096498844fc9 --- /dev/null +++ b/dmake/msdos/zortech/config.h @@ -0,0 +1,52 @@ +/* RCS $Id: config.h,v 1.1.1.1 2000-09-22 15:33:29 hr Exp $ +-- +-- SYNOPSIS +-- Configurarion include file. +-- +-- DESCRIPTION +-- There is one of these for each specific machine configuration. +-- It can be used to further tweek the machine specific sources +-- so that they compile. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +/* in sysintf.c: SIGQUIT is used, this is not defined in ZTC */ +#ifndef SIGQUIT +# define SIGQUIT SIGTERM +#endif + +/* in sysintf.c: tzset is not supported by ZTC */ +#define tzset() + +/* ZTC uses it's own swapping spawn. */ +#define spawnvpe(a,b,c,d) spawnvp(a,b,c) + +#ifndef CONST +# define CONST const +#endif + +#ifndef MSDOS +# define MSDOS 1 +#endif + +extern unsigned _psp; + +/* a small problem with pointer to voids on some unix machines needs this */ +#define PVOID void * + +#include <io.h> diff --git a/dmake/msdos/zortech/config.mk b/dmake/msdos/zortech/config.mk new file mode 100644 index 000000000000..e947dc87620b --- /dev/null +++ b/dmake/msdos/zortech/config.mk @@ -0,0 +1,73 @@ +# This is the ZTC DOS configuration file for DMAKE +# It simply modifies the values of SRC, and checks to see if +# OSENVIRONMENT is defined. If so it includes the appropriate +# config.mk file. +# +# It also sets the values of .SOURCE.c and .SOURCE.h to include the local +# directory. +# +osrdir := $(OS)$(DIRSEPSTR)$(OSRELEASE) + +TMPDIR := +.EXPORT : TMPDIR + +# Definition of macros for library, and C startup code. +# Swapping for DOS versions is enabled by default. ZTC will automatically +# perform swapping to XMS, EMS or disk by including _swapl.obj at link time. +# To be most effective, _swapl.obj should be the first file linked so we +# assign it to CSTARTUP if needed. +.IF $(SWAP) == y + CSTARTUP = _swapl.obj +.END + +# The following sources are required for ZTC +# The tempnam supplied with ZTC doesn't handle a NULL dir. +OSR_SRC = tempnam.c environ.c +.SETDIR=$(osrdir) : $(OSR_SRC) + +SRC += $(OSR_SRC) +.SOURCE.h : $(osrdir) + +# Local configuration modifications for CFLAGS +# If you have a 286, you can use -2 or appropriate to get better code, +# in that case uncomment the line below. (You can also simply set +# it in the CL environment variable.) +#CFLAGS += -2 +ASFLAGS += -t -mx $(S_$(MODEL)) + +# Redefine this, it isn't needed! +LDTAIL = ; + +# Debugging libraries +DB_LDFLAGS += -g +DB_LDLIBS += + +# NO Debug ZTC flags: +# + +CFLAGS += -I$(osrdir) $(C_$(MODEL)) +CFLAGS += -DM_I86=1 -DMSDOS +CFLAGS += -b # use large compiler +#CFLAGS += -w # no warnings +CFLAGS += -mi # integer only +CFLAGS += -p # no auto-prototyping +NDB_CFLAGS += -o +DB_CFLAGS += -g + +# Redefine rule for making our objects, we don't need mv +%$O : %.c ;% $(CC) -c $(CFLAGS) -o$@ $< + +# See if we modify anything in the lower levels. +.IF $(OSENVIRONMENT) != $(NULL) + .INCLUDE .IGNORE : $(osrdir)$(DIRSEPSTR)$(OSENVIRONMENT)$(DIRSEPSTR)config.mk +.END + +C_s = +C_m = -mM +C_c = -mC +C_l = -mL + +S_s = -Dmsmall +S_m = -Dmmedium +S_c = -Dmcompact +S_l = -Dmlarge diff --git a/dmake/msdos/zortech/environ.c b/dmake/msdos/zortech/environ.c new file mode 100644 index 000000000000..c76d9a4831a6 --- /dev/null +++ b/dmake/msdos/zortech/environ.c @@ -0,0 +1,59 @@ +/* RCS $Id: environ.c,v 1.1.1.1 2000-09-22 15:33:29 hr Exp $ +-- +-- SYNOPSIS +-- environment routines. +-- +-- DESCRIPTION +-- Someone thought that Zortech needs this. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ +/*LINTLIBRARY*/ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include "alloc.h" + +/* ZTC++ doesn't have environ, so we have to create one. */ + +extern char *_envptr; +char **environ = { NULL }; + +void +make_env() +{ + int i; + char *cp; + + for (i = 0, cp = _envptr; *cp; i++, cp += strlen(cp)+1) + ; + + TALLOC(environ, i+1, char*); + + for (i = 0, cp = _envptr; *cp; i++, cp += strlen(cp)+1) + environ[i] = cp; + + return; +} + +void +free_env() +{ + FREE(environ); + + return; +} diff --git a/dmake/msdos/zortech/lib.rsp b/dmake/msdos/zortech/lib.rsp new file mode 100644 index 000000000000..8b137891791f --- /dev/null +++ b/dmake/msdos/zortech/lib.rsp @@ -0,0 +1 @@ + diff --git a/dmake/msdos/zortech/libswp.rsp b/dmake/msdos/zortech/libswp.rsp new file mode 100644 index 000000000000..8b137891791f --- /dev/null +++ b/dmake/msdos/zortech/libswp.rsp @@ -0,0 +1 @@ + diff --git a/dmake/msdos/zortech/mkswp.bat b/dmake/msdos/zortech/mkswp.bat new file mode 100755 index 000000000000..60c12d37217e --- /dev/null +++ b/dmake/msdos/zortech/mkswp.bat @@ -0,0 +1,36 @@ +md objects +ztc -c -I. -Imsdos -Imsdos\zortech -mL -DM_I86=1 -DMSDOS -b -mi -p -o -oobjects\infer.obj infer.c +ztc -c -I. -Imsdos -Imsdos\zortech -mL -DM_I86=1 -DMSDOS -b -mi -p -o -oobjects\make.obj make.c +ztc -c -I. -Imsdos -Imsdos\zortech -mL -DM_I86=1 -DMSDOS -b -mi -p -o -oobjects\stat.obj stat.c +ztc -c -I. -Imsdos -Imsdos\zortech -mL -DM_I86=1 -DMSDOS -b -mi -p -o -oobjects\expand.obj expand.c +ztc -c -I. -Imsdos -Imsdos\zortech -mL -DM_I86=1 -DMSDOS -b -mi -p -o -oobjects\dmstring.obj dmstring.c +ztc -c -I. -Imsdos -Imsdos\zortech -mL -DM_I86=1 -DMSDOS -b -mi -p -o -oobjects\hash.obj hash.c +ztc -c -I. -Imsdos -Imsdos\zortech -mL -DM_I86=1 -DMSDOS -b -mi -p -o -oobjects\dag.obj dag.c +ztc -c -I. -Imsdos -Imsdos\zortech -mL -DM_I86=1 -DMSDOS -b -mi -p -o -oobjects\dmake.obj dmake.c +ztc -c -I. -Imsdos -Imsdos\zortech -mL -DM_I86=1 -DMSDOS -b -mi -p -o -oobjects\path.obj path.c +ztc -c -I. -Imsdos -Imsdos\zortech -mL -DM_I86=1 -DMSDOS -b -mi -p -o -oobjects\imacs.obj imacs.c +ztc -c -I. -Imsdos -Imsdos\zortech -mL -DM_I86=1 -DMSDOS -b -mi -p -o -oobjects\sysintf.obj sysintf.c +ztc -c -I. -Imsdos -Imsdos\zortech -mL -DM_I86=1 -DMSDOS -b -mi -p -o -oobjects\parse.obj parse.c +ztc -c -I. -Imsdos -Imsdos\zortech -mL -DM_I86=1 -DMSDOS -b -mi -p -o -oobjects\getinp.obj getinp.c +ztc -c -I. -Imsdos -Imsdos\zortech -mL -DM_I86=1 -DMSDOS -b -mi -p -o -oobjects\quit.obj quit.c +ztc -c -I. -Imsdos -Imsdos\zortech -mL -DM_I86=1 -DMSDOS -b -mi -p -o -oobjects\state.obj state.c +ztc -c -I. -Imsdos -Imsdos\zortech -mL -DM_I86=1 -DMSDOS -b -mi -p -o -oobjects\dmdump.obj dmdump.c +ztc -c -I. -Imsdos -Imsdos\zortech -mL -DM_I86=1 -DMSDOS -b -mi -p -o -oobjects\macparse.obj macparse.c +ztc -c -I. -Imsdos -Imsdos\zortech -mL -DM_I86=1 -DMSDOS -b -mi -p -o -oobjects\rulparse.obj rulparse.c +ztc -c -I. -Imsdos -Imsdos\zortech -mL -DM_I86=1 -DMSDOS -b -mi -p -o -oobjects\percent.obj percent.c +ztc -c -I. -Imsdos -Imsdos\zortech -mL -DM_I86=1 -DMSDOS -b -mi -p -o -oobjects\function.obj function.c +ztc -c -I. -Imsdos -Imsdos\zortech -mL -DM_I86=1 -DMSDOS -b -mi -p -o -oobjects\ruletab.obj msdos\ruletab.c +ztc -c -I. -Imsdos -Imsdos\zortech -mL -DM_I86=1 -DMSDOS -b -mi -p -o -oobjects\dirbrk.obj msdos\dirbrk.c +ztc -c -I. -Imsdos -Imsdos\zortech -mL -DM_I86=1 -DMSDOS -b -mi -p -o -oobjects\runargv.obj msdos\runargv.c +ztc -c -I. -Imsdos -Imsdos\zortech -mL -DM_I86=1 -DMSDOS -b -mi -p -o -oobjects\arlib.obj msdos\arlib.c +ztc -c -I. -Imsdos -Imsdos\zortech -mL -DM_I86=1 -DMSDOS -b -mi -p -o -oobjects\dchdir.obj msdos\dchdir.c +ztc -c -I. -Imsdos -Imsdos\zortech -mL -DM_I86=1 -DMSDOS -b -mi -p -o -oobjects\switchar.obj msdos\switchar.c +ztc -c -I. -Imsdos -Imsdos\zortech -mL -DM_I86=1 -DMSDOS -b -mi -p -o -oobjects\rmprq.obj msdos\rmprq.c +ztc -c -I. -Imsdos -Imsdos\zortech -mL -DM_I86=1 -DMSDOS -b -mi -p -o -oobjects\tee.obj msdos\tee.c +ztc -c -I. -Imsdos -Imsdos\zortech -mL -DM_I86=1 -DMSDOS -b -mi -p -o -oobjects\find.obj msdos\find.c +ztc -c -I. -Imsdos -Imsdos\zortech -mL -DM_I86=1 -DMSDOS -b -mi -p -o -oobjects\dirlib.obj msdos\dirlib.c +ztc -c -I. -Imsdos -Imsdos\zortech -mL -DM_I86=1 -DMSDOS -b -mi -p -o -oobjects\dstrlwr.obj msdos\dstrlwr.c +ztc -c -I. -Imsdos -Imsdos\zortech -mL -DM_I86=1 -DMSDOS -b -mi -p -o -oobjects\dcache.obj unix\dcache.c +ztc -c -I. -Imsdos -Imsdos\zortech -mL -DM_I86=1 -DMSDOS -b -mi -p -o -oobjects\tempnam.obj msdos\zortech\tempnam.c +ztc -c -I. -Imsdos -Imsdos\zortech -mL -DM_I86=1 -DMSDOS -b -mi -p -o -oobjects\environ.obj msdos\zortech\environ.c +blink @msdos\zortech\objswp.rsp,dmake.exe,NUL.MAP; diff --git a/dmake/msdos/zortech/obj.rsp b/dmake/msdos/zortech/obj.rsp new file mode 100644 index 000000000000..c97a42f9f0aa --- /dev/null +++ b/dmake/msdos/zortech/obj.rsp @@ -0,0 +1,34 @@ +objects\infer.obj+ +objects\make.obj+ +objects\stat.obj+ +objects\expand.obj+ +objects\dmstring.obj+ +objects\hash.obj+ +objects\dag.obj+ +objects\dmake.obj+ +objects\path.obj+ +objects\imacs.obj+ +objects\sysintf.obj+ +objects\parse.obj+ +objects\getinp.obj+ +objects\quit.obj+ +objects\state.obj+ +objects\dmdump.obj+ +objects\macparse.obj+ +objects\rulparse.obj+ +objects\percent.obj+ +objects\function.obj+ +objects\ruletab.obj+ +objects\dirbrk.obj+ +objects\runargv.obj+ +objects\arlib.obj+ +objects\dchdir.obj+ +objects\switchar.obj+ +objects\rmprq.obj+ +objects\tee.obj+ +objects\find.obj+ +objects\dirlib.obj+ +objects\dstrlwr.obj+ +objects\dcache.obj+ +objects\tempnam.obj+ +objects\environ.obj diff --git a/dmake/msdos/zortech/objswp.rsp b/dmake/msdos/zortech/objswp.rsp new file mode 100644 index 000000000000..60a33c4eb523 --- /dev/null +++ b/dmake/msdos/zortech/objswp.rsp @@ -0,0 +1,35 @@ +_swapl.obj+ +objects\infer.obj+ +objects\make.obj+ +objects\stat.obj+ +objects\expand.obj+ +objects\dmstring.obj+ +objects\hash.obj+ +objects\dag.obj+ +objects\dmake.obj+ +objects\path.obj+ +objects\imacs.obj+ +objects\sysintf.obj+ +objects\parse.obj+ +objects\getinp.obj+ +objects\quit.obj+ +objects\state.obj+ +objects\dmdump.obj+ +objects\macparse.obj+ +objects\rulparse.obj+ +objects\percent.obj+ +objects\function.obj+ +objects\ruletab.obj+ +objects\dirbrk.obj+ +objects\runargv.obj+ +objects\arlib.obj+ +objects\dchdir.obj+ +objects\switchar.obj+ +objects\rmprq.obj+ +objects\tee.obj+ +objects\find.obj+ +objects\dirlib.obj+ +objects\dstrlwr.obj+ +objects\dcache.obj+ +objects\tempnam.obj+ +objects\environ.obj diff --git a/dmake/msdos/zortech/public.h b/dmake/msdos/zortech/public.h new file mode 100644 index 000000000000..89c586b44e5a --- /dev/null +++ b/dmake/msdos/zortech/public.h @@ -0,0 +1,168 @@ +/* RCS $Id: public.h,v 1.1.1.1 2000-09-22 15:33:29 hr Exp $ +-- WARNING -- This file is AUTOMATICALLY GENERATED DO NOT EDIT IT +-- +-- +-- SYNOPSIS +-- Local functions exported to be visible by others. +-- +-- DESCRIPTION +-- This file is generated by 'genpub'. Function declarations +-- that appear in this file are extracted by 'genpub' from +-- source files. Any function in the source file whose definition +-- appears like: +-- +-- PUBLIC return_type +-- function( arg_list ); +-- type_expr1 arg1; +-- ... +-- +-- has its definition extracted and a line of the form: +-- +-- return_type function ANSI((type_expr1,type_expr2,...)); +-- +-- entered into the output file. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef _DMAKE_PUBLIC_h +#define _DMAKE_PUBLIC_h + +#ifdef EXTERN +#undef EXTERN +#endif +#if defined(DEFINE_DMAKE_VARIABLES) +#define EXTERN +#else +#define EXTERN extern +#endif + +/***** genpub: Begin list of generated function headers */ +void Infer_recipe ANSI((CELLPTR, CELLPTR)); +int Make_targets ANSI(()); +int Make ANSI((CELLPTR, CELLPTR)); +int Exec_commands ANSI((CELLPTR)); +void Print_cmnd ANSI((char *, int, int)); +int Push_dir ANSI((char *, char *, int)); +void Pop_dir ANSI((int)); +void Append_line ANSI((char *, int, FILE *, char *, int, int)); +void Stat_target ANSI((CELLPTR, int, int)); +char *Expand ANSI((char *)); +char *Apply_edit ANSI((char *, char *, char *, int, int)); +void Map_esc ANSI((char *)); +char* Apply_modifiers ANSI((int, char *)); +char* Tokenize ANSI((char *, char *, char, int)); +char* ScanToken ANSI((char *, char **, int)); +char *DmStrJoin ANSI((char *, char *, int, int)); +char *DmStrAdd ANSI((char *, char *, int)); +char *DmStrApp ANSI((char *, char *)); +char *DmStrDup ANSI((char *)); +char *DmStrDup2 ANSI((char *)); +char *DmStrPbrk ANSI((char *, char *)); +char *DmStrSpn ANSI((char *, char *)); +char *DmStrStr ANSI((char *, char *)); +char *DmSubStr ANSI((char *, char *)); +uint16 Hash ANSI((char *, uint32 *)); +HASHPTR Get_name ANSI((char *, HASHPTR *, int)); +HASHPTR Search_table ANSI((HASHPTR *, char *, uint16 *, uint32 *)); +HASHPTR Push_macro ANSI((HASHPTR)); +HASHPTR Pop_macro ANSI((HASHPTR)); +HASHPTR Def_macro ANSI((char *, char *, int)); +CELLPTR Def_cell ANSI((char *)); +LINKPTR Add_prerequisite ANSI((CELLPTR, CELLPTR, int, int)); +void Clear_prerequisites ANSI((CELLPTR)); +int Test_circle ANSI((CELLPTR, int)); +STRINGPTR Def_recipe ANSI((char *, STRINGPTR, int, int)); +t_attr Rcp_attribute ANSI((char *)); +void main ANSI((int, char **)); +FILE *Openfile ANSI((char *, int, int)); +FILE *Closefile ANSI(()); +FILE *Search_file ANSI((char *, char **)); +char *Filename ANSI(()); +int Nestlevel ANSI(()); +FILE *TryFiles ANSI((LINKPTR)); +void Fatal ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Error ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Warning ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void No_ram ANSI(()); +void Usage ANSI((int)); +void Version ANSI(()); +char *Get_suffix ANSI((char *)); +char *Basename ANSI((char *)); +char *Filedir ANSI((char *)); +char *Build_path ANSI((char *, char *)); +void Make_rules ANSI(()); +void Create_macro_vars ANSI(()); +time_t Do_stat ANSI((char *, char *, char **, int)); +int Do_touch ANSI((char *, char *, char **)); +void Void_lib_cache ANSI((char *, char *)); +time_t Do_time ANSI(()); +int Do_cmnd ANSI((char *, int, int, CELLPTR, int, int, int)); +char ** Pack_argv ANSI((int, int, char *)); +char *Read_env_string ANSI((char *)); +int Write_env_string ANSI((char *, char *)); +void ReadEnvironment ANSI(()); +void Catch_signals ANSI((void (*)())); +void Clear_signals ANSI(()); +void Prolog ANSI((int, char* [])); +void Epilog ANSI((int)); +char *Get_current_dir ANSI(()); +int Set_dir ANSI((char*)); +char Get_switch_char ANSI(()); +FILE* Get_temp ANSI((char **, char *, int)); +FILE *Start_temp ANSI((char *, CELLPTR, char **)); +void Open_temp_error ANSI((char *, char *)); +void Link_temp ANSI((CELLPTR, FILE *, char *)); +void Close_temp ANSI((CELLPTR, FILE *)); +void Unlink_temp_files ANSI((CELLPTR)); +void Handle_result ANSI((int, int, int, CELLPTR)); +void Update_time_stamp ANSI((CELLPTR)); +int Remove_file ANSI((char *)); +void Parse ANSI((FILE *)); +int Get_line ANSI((char *, FILE *)); +char *Do_comment ANSI((char *, char **, int)); +char *Get_token ANSI((TKSTRPTR, char *, int)); +void Quit ANSI(()); +void Read_state ANSI(()); +void Write_state ANSI(()); +int Check_state ANSI((CELLPTR, STRINGPTR *, int)); +void Dump ANSI(()); +void Dump_recipe ANSI((STRINGPTR)); +int Parse_macro ANSI((char *, int)); +int Macro_op ANSI((char *)); +int Parse_rule_def ANSI((int *)); +int Rule_op ANSI((char *)); +void Add_recipe_to_list ANSI((char *, int, int)); +void Bind_rules_to_targets ANSI((int)); +int Set_group_attributes ANSI((char *)); +DFALINKPTR Match_dfa ANSI((char *)); +void Check_circle_dfa ANSI(()); +void Add_nfa ANSI((char *)); +char *Exec_function ANSI((char *)); +int If_root_path ANSI((char *)); +int runargv ANSI((CELLPTR, int, int, int, int, char *)); +void Clean_up_processes ANSI(()); +int Wait_for_child ANSI((int, int)); +time_t seek_arch ANSI((char*, char*)); +int touch_arch ANSI((char*, char*)); +int dchdir ANSI((char *)); +void Remove_prq ANSI((CELLPTR)); +void Hook_std_writes ANSI((char *)); +void dstrlwr ANSI((char *, char *)); +time_t CacheStat ANSI((char *, int)); + +#endif diff --git a/dmake/msdos/zortech/startup.mk b/dmake/msdos/zortech/startup.mk new file mode 100644 index 000000000000..3c167a02e400 --- /dev/null +++ b/dmake/msdos/zortech/startup.mk @@ -0,0 +1,153 @@ +# MSDOS DMAKE startup file. Customize to suit your needs. +# Assumes MKS toolkit for the tool commands, and Zortech C. Change as req'd. +# See the documentation for a description of internally defined macros. +# +# Disable warnings for macros redefined here that were given +# on the command line. +__.SILENT !:= $(.SILENT) +.SILENT !:= yes + +# Configuration parameters for DMAKE startup.mk file +# Set these to NON-NULL if you wish to turn the parameter on. +_HAVE_RCS := yes # yes => RCS is installed. +_HAVE_SCCS := # yes => SCCS is installed. + +# Applicable suffix definitions +A := .lib # Libraries +E := .exe # Executables +F := .for # Fortran +O := .obj # Objects +P := .pas # Pascal +S := .asm # Assembler sources +V := # RCS suffix + +# See if these are defined +TMPDIR := $(ROOTDIR)/tmp +.IMPORT .IGNORE : TMPDIR SHELL COMSPEC + +# Recipe execution configurations +# First set SHELL, If it is not defined, use COMSPEC, otherwise +# it is assumed to be MKS Korn SHELL. +.IF $(SHELL) == $(NULL) +.IF $(COMSPEC) == $(NULL) + SHELL := $(ROOTDIR)/bin/sh$E +.ELSE + SHELL := $(COMSPEC) +.END +.END +GROUPSHELL := $(SHELL) + +# Now set remaining arguments depending on which SHELL we +# are going to use. COMSPEC (assumed to be command.com) or +# MKS Korn Shell. +.IF $(SHELL)==$(COMSPEC) + SHELLFLAGS := $(SWITCHAR)c + GROUPFLAGS := $(SHELLFLAGS) + SHELLMETAS := *"?<> + GROUPSUFFIX := .bat + DIRSEPSTR := \\\ + DIVFILE = $(TMPFILE:s,/,\) +.ELSE + SHELLFLAGS := -c + GROUPFLAGS := + SHELLMETAS := *"?<>|()&][$$\#`' + GROUPSUFFIX := .ksh + .MKSARGS := yes + DIVFILE = $(TMPFILE:s,/,${DIVSEP_shell_${USESHELL}}) + DIVSEP_shell_yes := \\\ + DIVSEP_shell_no := \\ +.END + +# Standard C-language command names and flags + CC := ztc # C-compiler and flags + CFLAGS += + + AS := masm # Assembler and flags + ASFLAGS += + + LD = blink # Loader and flags + LDFLAGS += + LDLIBS = + +# Definition of $(MAKE) macro for recursive makes. + MAKE = $(MAKECMD) -S $(MFLAGS) + +# Language and Parser generation Tools and their flags + YACC := yacc # standard yacc + YFLAGS += + YTAB := ytab # yacc output files name stem. + + LEX := lex # standard lex + LFLAGS += + LEXYY := lex_yy # lex output file + +# Other Compilers, Tools and their flags + PC := any_pc # pascal compiler + RC := anyf77 # ratfor compiler + FC := anyf77 # fortran compiler + + CO := co # check out for RCS + COFLAGS += -q + + AR := ar # archiver + ARFLAGS+= ruv + + RM := rm # remove a file command + RMFLAGS += + +# Implicit generation rules for making inferences. +# We don't provide .yr or .ye rules here. They're obsolete. +# Rules for making *$O + %$O : %.c ; $(CC) $(CFLAGS) -c $< + %$O : %.cpp ; $(CC) $(CFLAGS) -c $< + %$O : %$P ; $(PC) $(PFLAGS) -c $< + %$O : %$S ; $(AS) $(ASFLAGS) $(<:s,/,\); + %$O : %.cl ; class -c $< + %$O :| %.e %.r %.F %$F ; $(FC) $(RFLAGS) $(EFLAGS) $(FFLAGS) -c $< + +# Executables + %$E : %$O ; $(CC) $(LDFLAGS) -o$@ $< $(LDLIBS) + +# lex and yacc rules + %.c : %.y ; $(YACC) $(YFLAGS) $<; mv $(YTAB).c $@ + %.c : %.l ; $(LEX) $(LFLAGS) $<; mv $(LEXYY).c $@ + +# RCS support +.IF $(_HAVE_RCS) + % : $$(@:d)RCS$$(DIRSEPSTR)$$(@:f)$V;- $(CO) $(COFLAGS) $@ + .NOINFER : $$(@:d)RCS$$(DIRSEPSTR)$$(@:f)$V +.END + +# SCCS support +.IF $(_HAVE_SCCS) + % : s.% ; get $< + .NOINFER : s.% +.END + +# Recipe to make archive files. +%$A .SWAP .GROUP : + $(AR) $(ARFLAGS) $@ $? + $(RM) $(RMFLAGS) $? + +# DMAKE uses this recipe to remove intermediate targets +.REMOVE :; $(RM) -f $< + +# AUGMAKE extensions for SYSV compatibility +"@B" = $(@:b) +"@D" = $(@:d) +"@F" = $(@:f) +"*B" = $(*:b) +"*D" = $(*:d) +"*F" = $(*:f) +"<B" = $(<:b) +"<D" = $(<:d) +"<F" = $(<:f) +"?B" = $(?:b) +"?F" = $(?:f) +"?D" = $(?:d) + +# Turn warnings back to previous setting. +.SILENT !:= $(__.SILENT) + +# Local init file if any, gets parsed before user makefile +.INCLUDE .IGNORE: "_startup.mk" diff --git a/dmake/msdos/zortech/tempnam.c b/dmake/msdos/zortech/tempnam.c new file mode 100644 index 000000000000..91ce19c490ad --- /dev/null +++ b/dmake/msdos/zortech/tempnam.c @@ -0,0 +1,106 @@ +/* RCS $Id: tempnam.c,v 1.1.1.1 2000-09-22 15:33:29 hr Exp $ +-- +-- SYNOPSIS +-- temname +-- +-- DESCRIPTION +-- temp file name generation code. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ +/*LINTLIBRARY*/ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <dos.h> + +#if defined(max) +# undef max +#endif +#define max(A,B) (((A)<(B))?(B):(A)) + +extern char *mktemp(); +extern int access(); +int d_access(); + +/* Zortech C stdio.h doesn't define P_tmpdir, so let's do it here */ +/* Under DOS leave the default tmpdir pointing here! */ +static char *P_tmpdir = ""; + +char * +tempnam(dir, prefix) +const char *dir; /* use this directory please (if non-NULL) */ +const char *prefix; /* use this (if non-NULL) as filename prefix */ +{ + static int count = 0; + register char *p, *q, *tmpdir; + int tl=0, dl=0, pl; + char buf[30]; + + pl = strlen(P_tmpdir); + + if( (tmpdir = getenv("TMPDIR")) != NULL ) tl = strlen(tmpdir); + else if( (tmpdir = getenv("TMP")) != NULL ) tl = strlen(tmpdir); + if( dir != NULL ) dl = strlen(dir); + + if( (p = malloc((unsigned)(max(max(dl,tl),pl)+13))) == NULL ) + return(NULL); + + *p = '\0'; + + if( (tl == 0) || (d_access( strcpy(p, tmpdir), 0) != 0) ) + if( (dl == 0) || (d_access( strcpy(p, dir), 0) != 0) ) + if( d_access( strcpy(p, P_tmpdir), 0) != 0 ) + if( !prefix ) + prefix = "tp"; + + if(prefix) + { + *(p+strlen(p)+2) = '\0'; + (void)strncat(p, prefix, 2); + } + + sprintf( buf, "%08x", _psp ); + buf[6]='\0'; + (void)strcat(p, buf ); + sprintf( buf, "%04d", count++ ); + q=p+strlen(p)-6; + *q++ = buf[0]; *q++ = buf[1]; + *q++ = buf[2]; *q++ = buf[3]; + + if( (q = strrchr(p,'.')) != NULL ) *q = '\0'; + + return(p); +} + + + +d_access( name, flag ) +char *name; +int flag; +{ + extern char *DirSepStr; + char *p; + int r; + + if( name == NULL || !*name ) return(1); /* NULL dir means current dir */ + r = access( name, flag ); + p = name+strlen(name)-1; + if(*p != '/' && *p != '\\') strcat( p, DirSepStr ); + + return( r ); +} diff --git a/dmake/os2/config.mk b/dmake/os2/config.mk new file mode 100644 index 000000000000..5e2b7689bd82 --- /dev/null +++ b/dmake/os2/config.mk @@ -0,0 +1,54 @@ +# This is an OS specific configuration file +# It assumes that OBJDIR, TARGET and DEBUG are previously defined. +# It defines CFLAGS, LDARGS, CPPFLAGS, STARTUPFILE, LDOBJS +# It augments SRC, OBJDIR, TARGET, CFLAGS, LDLIBS +# +OSRELEASE *= ibm +- := $(SWITCHAR) + +# Memory model to compile for +# set to s - small, m - medium, c - compact, l - large +# Use only large model now. +MODEL = l + +STARTUPFILE = $(OS)/startup.mk + +CPPFLAGS = $(CFLAGS) +LDOBJS = $(CSTARTUP) $(OBJDIR)/{$(<:f)} +LDARGS = $(LDHEAD) @$(LDTMPOBJ),$(TARGET),NUL.MAP,,$(LDTAIL) +LDTAIL = $(_libs)$(LDFLAGS:s/ //) +_libs = $(!null,$(LDLIBS) ,@$(LDTMPLIB)) +LDTMPOBJ = $(mktmp,,$(DIVFILE) $(LDOBJS:s,/,\\,:t"+\n")\n) +LDTMPLIB = $(mktmp,,$(DIVFILE) $(LDLIBS)\n) + +# Debug flags +DB_CFLAGS = -DDBUG +DB_LDFLAGS = +DB_LDLIBS = + +# NO Debug flags +NDB_CFLAGS = +NDB_LDFLAGS = +NDB_LDLIBS = + +# Local configuration modifications for CFLAGS. +CFLAGS += $-I$(OS) + +# OS2 does not have a swap version. The operating system will +# handle all swapping. +# To save copying unchanged files in from elsewhere, I shall use them in situ. +OS_SRC += ruletab.c dchdir.c switchar.c +DOS_SRC += dirbrk.c arlib.c dstrlwr.c runargv.c rmprq.c + +SRC += $(OS_SRC) $(DOS_SRC) +.SETDIR=$(OS) : $(ASRC) $(OS_SRC) +.SETDIR=msdos : $(DOS_SRC) + +# Set source dirs so that we can find files named in this +# config file. +.SOURCE.h : $(OS) + +# See if we modify anything in the lower levels. +.IF $(OSRELEASE) != $(NULL) + .INCLUDE .IGNORE : $(OS)$(DIRSEPSTR)$(OSRELEASE)$(DIRSEPSTR)config.mk +.END diff --git a/dmake/os2/dchdir.c b/dmake/os2/dchdir.c new file mode 100644 index 000000000000..6244c630d2a6 --- /dev/null +++ b/dmake/os2/dchdir.c @@ -0,0 +1,41 @@ +/* RCS $Id: dchdir.c,v 1.1.1.1 2000-09-22 15:33:30 hr Exp $ +-- +-- SYNOPSIS +-- Change directory. +-- +-- DESCRIPTION +-- Under DOS change the current drive as well as the current directory. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include <os2.h> +#include "extern.h" + +PUBLIC int +_dchdir(path) +char *path; +{ + int res; + + res = _chdir(path); + + if (res == 0 && path[1] == ':') + DosSelectDisk((*path & ~0x20) - '@'); + + return (res); +} diff --git a/dmake/os2/dirent.h b/dmake/os2/dirent.h new file mode 100644 index 000000000000..eafaccbcc38a --- /dev/null +++ b/dmake/os2/dirent.h @@ -0,0 +1,36 @@ +/* DIRLIB.H by M. J. Weinstein Released to public domain 1-Jan-89 */ + +#ifndef _DIRLIB_h_ +#define _DIRLIB_h_ + +#define INCL_DOSFILEMGR +#include <os2.h> +#include <stdio.h> +#include <stdlib.h> +#include "stdmacs.h" + +#define MAXNAMLEN _MAX_FNAME + +struct dirent { + long d_ino; + unsigned short d_reclen; + unsigned short d_namlen; + char d_name[MAXNAMLEN+1]; +}; + +typedef struct { + HDIR dd_handle; /* Handle for FindFirst/Next */ + FILEFINDBUF3 dd_dta; /* Disk transfer area for this dir. */ + ULONG dd_count; /* Count for FindFirst/Next */ + APIRET dd_stat; /* Status return from last lookup */ + char dd_name[1]; /* Full name of file -- struct is extended */ +} DIR; + +extern DIR *opendir ANSI((char *)); +extern struct dirent *readdir ANSI((DIR *)); +extern long telldir ANSI((DIR *)); +extern void seekdir ANSI((DIR *, long)); +extern void closedir ANSI((DIR *)); + +#define rewinddir(dirp) seekdir(dirp,0L) +#endif diff --git a/dmake/os2/ibm/config.h b/dmake/os2/ibm/config.h new file mode 100644 index 000000000000..afff0f203845 --- /dev/null +++ b/dmake/os2/ibm/config.h @@ -0,0 +1,78 @@ +/* RCS $Id: config.h,v 1.1.1.1 2000-09-22 15:33:30 hr Exp $ +-- +-- SYNOPSIS +-- Configurarion include file. +-- +-- DESCRIPTION +-- There is one of these for each specific machine configuration. +-- It can be used to further tweek the machine specific sources +-- so that they compile. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#if defined (_MSC_VER) +# if _MSC_VER < 500 + Force a compile-time blowup. + Do not define define _MSC_VER for MSC compilers ealier than 5.0. +# endif +#endif + +/* define this for configurations that don't have the coreleft function + * so that the code compiles. To my knowledge coreleft exists only on + * Turbo C, but it is needed here since the function is used in many debug + * macros. */ +#define coreleft() 0L + +/* MSC Version 4.0 doesn't understand SIGTERM, later versions do. */ +#ifndef SIGTERM +# define SIGTERM SIGINT +#endif + +/* This should already be defined under C6.0, also for OS/2 we want buffering + * to minimise the mess during parallel makes. + */ +#ifndef _IOLBF +# define _IOLBF _IOFBF +#endif + +/* in alloc.h: size_t is redefined + * defined in stdio.h which is included by alloc.h + */ +#if defined(MSDOS) && defined (_MSC_VER) +# define _TYPES_ +#endif + +/* Don't need this one either */ +#define CONST + +/* in sysintf.c: SIGQUIT is used, this is not defined in MSC */ +#ifndef SIGQUIT +# define SIGQUIT SIGTERM +#endif + +/* a small problem with pointer to voids on some unix machines needs this */ +#define PVOID void * + +/* C-lib redefinitions... */ +#define dup _dup +#define close _close +#define utime _utime +#define tzset _tzset +#define access _access +#define getpid _getpid +#define getcwd _getcwd diff --git a/dmake/os2/ibm/config.mk b/dmake/os2/ibm/config.mk new file mode 100644 index 000000000000..716addd82abf --- /dev/null +++ b/dmake/os2/ibm/config.mk @@ -0,0 +1,54 @@ +# This is the MSC 4.0 and higher DOS configuration file for DMAKE +# It simply modifies the values of SRC, and checks to see if +# OSENVIRONMENT is defined. If so it includes the appropriate +# config.mk file. +# +# It also sets the values of .SOURCE.c and .SOURCE.h to include the local +# directory. +# +osrdir := $(OS)$(DIRSEPSTR)$(OSRELEASE) + +TMPDIR := +.EXPORT : TMPDIR + +# Definition of macros for library, and C startup code. + +# The following sources are required for MSC +OSR_SRC = tempnam.c +.SETDIR=$(osrdir) : $(OSR_SRC) + +SRC += $(OSR_SRC) +.SOURCE.h : $(osrdir) + +SET_STACK = $-stack:32768 +NDB_LDFLAGS += + +ASFLAGS += -t -mx $(S_$(MODEL)) + +# Microsoft C doesn't need tail but needs head +LDTAIL = ,; +LDHEAD = $(LDFLAGS) + +# Debugging libraries +DB_LDFLAGS += $-co $-li $-map $(SET_STACK) +DB_LDLIBS += + +# NO Debug MSC flags: +# Set the environment variable MSC_VER to be one of 5.1, 6.0, 8.0 (for VC++4.0) +# to get these by default when you make dmake using 'dmake'. +# +# Setting MSC_VER to one of the above sets the variable _MSC_VER appropriately +# and sets the flags appropriately. + +CFLAGS += $-I$(osrdir) +DB_CFLAGS += $-Ti+ + +# See if we modify anything in the lower levels. +.IF $(OSENVIRONMENT) != $(NULL) + .INCLUDE .IGNORE : $(osrdir)$(DIRSEPSTR)$(OSENVIRONMENT)$(DIRSEPSTR)config.mk +.END + +S_s = -Dmsmall +S_m = -Dmmedium +S_c = -Dmcompact +S_l = -Dmlarge diff --git a/dmake/os2/ibm/icc/config.mk b/dmake/os2/ibm/icc/config.mk new file mode 100644 index 000000000000..2042f5636262 --- /dev/null +++ b/dmake/os2/ibm/icc/config.mk @@ -0,0 +1,11 @@ +# Definition of macros for library, and C startup code. +osedir = $(osrdir)$(DIRSEPSTR)$(OSENVIRONMENT) + +.IMPORT .IGNORE : MSC_VER +MSC_VER *= 6.0 + +CFLAGS += $-I$(osedir) $-Sp1 $-Q $-Fi- + +NDB_CFLAGS += $-O +NDB_LDFLAGS += $-de $-pmtype:vio $-align:16 $-nologo $-m $-stack:32768 +NDB_LDLIBS += diff --git a/dmake/os2/ibm/icc/lib.rsp b/dmake/os2/ibm/icc/lib.rsp new file mode 100644 index 000000000000..8b137891791f --- /dev/null +++ b/dmake/os2/ibm/icc/lib.rsp @@ -0,0 +1 @@ + diff --git a/dmake/os2/ibm/icc/mk.cmd b/dmake/os2/ibm/icc/mk.cmd new file mode 100755 index 000000000000..563a88aad43c --- /dev/null +++ b/dmake/os2/ibm/icc/mk.cmd @@ -0,0 +1,96 @@ +md objects +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc /Sp1 /Q /Fi- /O infer.c +copy infer.obj objects +del infer.obj +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc /Sp1 /Q /Fi- /O make.c +copy make.obj objects +del make.obj +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc /Sp1 /Q /Fi- /O stat.c +copy stat.obj objects +del stat.obj +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc /Sp1 /Q /Fi- /O expand.c +copy expand.obj objects +del expand.obj +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc /Sp1 /Q /Fi- /O dmstring.c +copy dmstring.obj objects +del dmstring.obj +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc /Sp1 /Q /Fi- /O hash.c +copy hash.obj objects +del hash.obj +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc /Sp1 /Q /Fi- /O dag.c +copy dag.obj objects +del dag.obj +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc /Sp1 /Q /Fi- /O dmake.c +copy dmake.obj objects +del dmake.obj +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc /Sp1 /Q /Fi- /O path.c +copy path.obj objects +del path.obj +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc /Sp1 /Q /Fi- /O imacs.c +copy imacs.obj objects +del imacs.obj +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc /Sp1 /Q /Fi- /O sysintf.c +copy sysintf.obj objects +del sysintf.obj +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc /Sp1 /Q /Fi- /O parse.c +copy parse.obj objects +del parse.obj +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc /Sp1 /Q /Fi- /O getinp.c +copy getinp.obj objects +del getinp.obj +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc /Sp1 /Q /Fi- /O quit.c +copy quit.obj objects +del quit.obj +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc /Sp1 /Q /Fi- /O state.c +copy state.obj objects +del state.obj +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc /Sp1 /Q /Fi- /O dmdump.c +copy dmdump.obj objects +del dmdump.obj +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc /Sp1 /Q /Fi- /O macparse.c +copy macparse.obj objects +del macparse.obj +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc /Sp1 /Q /Fi- /O rulparse.c +copy rulparse.obj objects +del rulparse.obj +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc /Sp1 /Q /Fi- /O percent.c +copy percent.obj objects +del percent.obj +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc /Sp1 /Q /Fi- /O function.c +copy function.obj objects +del function.obj +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc /Sp1 /Q /Fi- /O os2\ruletab.c +copy ruletab.obj objects +del ruletab.obj +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc /Sp1 /Q /Fi- /O os2\dchdir.c +copy dchdir.obj objects +del dchdir.obj +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc /Sp1 /Q /Fi- /O os2\switchar.c +copy switchar.obj objects +del switchar.obj +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc /Sp1 /Q /Fi- /O os2\dirlib.c +copy dirlib.obj objects +del dirlib.obj +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc /Sp1 /Q /Fi- /O os2\runargv.c +copy runargv.obj objects +del runargv.obj +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc /Sp1 /Q /Fi- /O msdos\dirbrk.c +copy dirbrk.obj objects +del dirbrk.obj +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc /Sp1 /Q /Fi- /O msdos\arlib.c +copy arlib.obj objects +del arlib.obj +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc /Sp1 /Q /Fi- /O msdos\dstrlwr.c +copy dstrlwr.obj objects +del dstrlwr.obj +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc /Sp1 /Q /Fi- /O unix\rmprq.c +copy rmprq.obj objects +del rmprq.obj +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc /Sp1 /Q /Fi- /O unix\dcache.c +copy dcache.obj objects +del dcache.obj +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc /Sp1 /Q /Fi- /O os2\ibm\tempnam.c +copy tempnam.obj objects +del tempnam.obj +link386 /de /pmtype:vio /align:16 /nologo /m /stack:32768 @os2\ibm\icc\obj.rsp,dmake.exe,NUL.MAP,,,; +copy os2\ibm\icc\template.mk startup\config.mk diff --git a/dmake/os2/ibm/icc/obj.rsp b/dmake/os2/ibm/icc/obj.rsp new file mode 100644 index 000000000000..594535036c87 --- /dev/null +++ b/dmake/os2/ibm/icc/obj.rsp @@ -0,0 +1,31 @@ +objects\infer.obj+ +objects\make.obj+ +objects\stat.obj+ +objects\expand.obj+ +objects\dmstring.obj+ +objects\hash.obj+ +objects\dag.obj+ +objects\dmake.obj+ +objects\path.obj+ +objects\imacs.obj+ +objects\sysintf.obj+ +objects\parse.obj+ +objects\getinp.obj+ +objects\quit.obj+ +objects\state.obj+ +objects\dmdump.obj+ +objects\macparse.obj+ +objects\rulparse.obj+ +objects\percent.obj+ +objects\function.obj+ +objects\ruletab.obj+ +objects\dchdir.obj+ +objects\switchar.obj+ +objects\dirlib.obj+ +objects\runargv.obj+ +objects\dirbrk.obj+ +objects\arlib.obj+ +objects\dstrlwr.obj+ +objects\rmprq.obj+ +objects\dcache.obj+ +objects\tempnam.obj diff --git a/dmake/os2/ibm/icc/public.h b/dmake/os2/ibm/icc/public.h new file mode 100644 index 000000000000..1a9d48a358ea --- /dev/null +++ b/dmake/os2/ibm/icc/public.h @@ -0,0 +1,168 @@ +/* RCS $Id: public.h,v 1.1.1.1 2000-09-22 15:33:30 hr Exp $ +-- WARNING -- This file is AUTOMATICALLY GENERATED DO NOT EDIT IT +-- +-- +-- SYNOPSIS +-- Local functions exported to be visible by others. +-- +-- DESCRIPTION +-- This file is generated by 'genpub'. Function declarations +-- that appear in this file are extracted by 'genpub' from +-- source files. Any function in the source file whose definition +-- appears like: +-- +-- PUBLIC return_type +-- function( arg_list ); +-- type_expr1 arg1; +-- ... +-- +-- has its definition extracted and a line of the form: +-- +-- return_type function ANSI((type_expr1,type_expr2,...)); +-- +-- entered into the output file. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef _DMAKE_PUBLIC_h +#define _DMAKE_PUBLIC_h + +#ifdef EXTERN +#undef EXTERN +#endif +#if defined(DEFINE_DMAKE_VARIABLES) +#define EXTERN +#else +#define EXTERN extern +#endif + +/***** genpub: Begin list of generated function headers */ +void Infer_recipe ANSI((CELLPTR, CELLPTR)); +int Make_targets ANSI(()); +int Make ANSI((CELLPTR, CELLPTR)); +int Exec_commands ANSI((CELLPTR)); +void Print_cmnd ANSI((char *, int, int)); +int Push_dir ANSI((char *, char *, int)); +void Pop_dir ANSI((int)); +void Append_line ANSI((char *, int, FILE *, char *, int, int)); +void Stat_target ANSI((CELLPTR, int, int)); +char *Expand ANSI((char *)); +char *Apply_edit ANSI((char *, char *, char *, int, int)); +void Map_esc ANSI((char *)); +char* Apply_modifiers ANSI((int, char *)); +char* Tokenize ANSI((char *, char *, char, int)); +char* ScanToken ANSI((char *, char **, int)); +char *DmStrJoin ANSI((char *, char *, int, int)); +char *DmStrAdd ANSI((char *, char *, int)); +char *DmStrApp ANSI((char *, char *)); +char *DmStrDup ANSI((char *)); +char *DmStrDup2 ANSI((char *)); +char *DmStrPbrk ANSI((char *, char *)); +char *DmStrSpn ANSI((char *, char *)); +char *DmStrStr ANSI((char *, char *)); +char *DmSubStr ANSI((char *, char *)); +uint16 Hash ANSI((char *, uint32 *)); +HASHPTR Get_name ANSI((char *, HASHPTR *, int)); +HASHPTR Search_table ANSI((HASHPTR *, char *, uint16 *, uint32 *)); +HASHPTR Push_macro ANSI((HASHPTR)); +HASHPTR Pop_macro ANSI((HASHPTR)); +HASHPTR Def_macro ANSI((char *, char *, int)); +CELLPTR Def_cell ANSI((char *)); +LINKPTR Add_prerequisite ANSI((CELLPTR, CELLPTR, int, int)); +void Clear_prerequisites ANSI((CELLPTR)); +int Test_circle ANSI((CELLPTR, int)); +STRINGPTR Def_recipe ANSI((char *, STRINGPTR, int, int)); +t_attr Rcp_attribute ANSI((char *)); +void main ANSI((int, char **)); +FILE *Openfile ANSI((char *, int, int)); +FILE *Closefile ANSI(()); +FILE *Search_file ANSI((char *, char **)); +char *Filename ANSI(()); +int Nestlevel ANSI(()); +FILE *TryFiles ANSI((LINKPTR)); +void Fatal ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Error ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Warning ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void No_ram ANSI(()); +void Usage ANSI((int)); +void Version ANSI(()); +char *Get_suffix ANSI((char *)); +char *Basename ANSI((char *)); +char *Filedir ANSI((char *)); +char *Build_path ANSI((char *, char *)); +void Make_rules ANSI(()); +void Create_macro_vars ANSI(()); +time_t Do_stat ANSI((char *, char *, char **, int)); +int Do_touch ANSI((char *, char *, char **)); +void Void_lib_cache ANSI((char *, char *)); +time_t Do_time ANSI(()); +int Do_cmnd ANSI((char *, int, int, CELLPTR, int, int, int)); +char ** Pack_argv ANSI((int, int, char *)); +char *Read_env_string ANSI((char *)); +int Write_env_string ANSI((char *, char *)); +void ReadEnvironment ANSI(()); +void Catch_signals ANSI((void (*)())); +void Clear_signals ANSI(()); +void Prolog ANSI((int, char* [])); +void Epilog ANSI((int)); +char *Get_current_dir ANSI(()); +int Set_dir ANSI((char*)); +char Get_switch_char ANSI(()); +FILE* Get_temp ANSI((char **, char *, int)); +FILE *Start_temp ANSI((char *, CELLPTR, char **)); +void Open_temp_error ANSI((char *, char *)); +void Link_temp ANSI((CELLPTR, FILE *, char *)); +void Close_temp ANSI((CELLPTR, FILE *)); +void Unlink_temp_files ANSI((CELLPTR)); +void Handle_result ANSI((int, int, int, CELLPTR)); +void Update_time_stamp ANSI((CELLPTR)); +int Remove_file ANSI((char *)); +void Parse ANSI((FILE *)); +int Get_line ANSI((char *, FILE *)); +char *Do_comment ANSI((char *, char **, int)); +char *Get_token ANSI((TKSTRPTR, char *, int)); +void Quit ANSI(()); +void Read_state ANSI(()); +void Write_state ANSI(()); +int Check_state ANSI((CELLPTR, STRINGPTR *, int)); +void Dump ANSI(()); +void Dump_recipe ANSI((STRINGPTR)); +int Parse_macro ANSI((char *, int)); +int Macro_op ANSI((char *)); +int Parse_rule_def ANSI((int *)); +int Rule_op ANSI((char *)); +void Add_recipe_to_list ANSI((char *, int, int)); +void Bind_rules_to_targets ANSI((int)); +int Set_group_attributes ANSI((char *)); +DFALINKPTR Match_dfa ANSI((char *)); +void Check_circle_dfa ANSI(()); +void Add_nfa ANSI((char *)); +char *Exec_function ANSI((char *)); +int _dchdir ANSI((char *)); +int runargv ANSI((CELLPTR, int, int, int, int, char *)); +void SetSessionTitle ANSI((char *)); +int Wait_for_child ANSI((int, int)); +void Clean_up_processes ANSI(()); +int If_root_path ANSI((char *)); +time_t seek_arch ANSI((char*, char*)); +int touch_arch ANSI((char*, char*)); +void dstrlwr ANSI((char *, char *)); +void Remove_prq ANSI((CELLPTR)); +time_t CacheStat ANSI((char *, int)); + +#endif diff --git a/dmake/os2/ibm/icc/template.mk b/dmake/os2/ibm/icc/template.mk new file mode 100644 index 000000000000..c9c5adbf21ae --- /dev/null +++ b/dmake/os2/ibm/icc/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= os2 + OSRELEASE *:= ibm + OSENVIRONMENT *:= icc diff --git a/dmake/os2/ibm/icc3/config.mk b/dmake/os2/ibm/icc3/config.mk new file mode 100644 index 000000000000..2042f5636262 --- /dev/null +++ b/dmake/os2/ibm/icc3/config.mk @@ -0,0 +1,11 @@ +# Definition of macros for library, and C startup code. +osedir = $(osrdir)$(DIRSEPSTR)$(OSENVIRONMENT) + +.IMPORT .IGNORE : MSC_VER +MSC_VER *= 6.0 + +CFLAGS += $-I$(osedir) $-Sp1 $-Q $-Fi- + +NDB_CFLAGS += $-O +NDB_LDFLAGS += $-de $-pmtype:vio $-align:16 $-nologo $-m $-stack:32768 +NDB_LDLIBS += diff --git a/dmake/os2/ibm/icc3/lib.rsp b/dmake/os2/ibm/icc3/lib.rsp new file mode 100644 index 000000000000..8b137891791f --- /dev/null +++ b/dmake/os2/ibm/icc3/lib.rsp @@ -0,0 +1 @@ + diff --git a/dmake/os2/ibm/icc3/mk.cmd b/dmake/os2/ibm/icc3/mk.cmd new file mode 100755 index 000000000000..f45e63e64318 --- /dev/null +++ b/dmake/os2/ibm/icc3/mk.cmd @@ -0,0 +1,192 @@ +md objects + +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc3 /Sp1 /Q /Fi- /O infer.c + +copy infer.obj objects + +del infer.obj + +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc3 /Sp1 /Q /Fi- /O make.c + +copy make.obj objects + +del make.obj + +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc3 /Sp1 /Q /Fi- /O stat.c + +copy stat.obj objects + +del stat.obj + +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc3 /Sp1 /Q /Fi- /O expand.c + +copy expand.obj objects + +del expand.obj + +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc3 /Sp1 /Q /Fi- /O dmstring.c + +copy dmstring.obj objects + +del dmstring.obj + +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc3 /Sp1 /Q /Fi- /O hash.c + +copy hash.obj objects + +del hash.obj + +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc3 /Sp1 /Q /Fi- /O dag.c + +copy dag.obj objects + +del dag.obj + +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc3 /Sp1 /Q /Fi- /O dmake.c + +copy dmake.obj objects + +del dmake.obj + +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc3 /Sp1 /Q /Fi- /O path.c + +copy path.obj objects + +del path.obj + +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc3 /Sp1 /Q /Fi- /O imacs.c + +copy imacs.obj objects + +del imacs.obj + +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc3 /Sp1 /Q /Fi- /O sysintf.c + +copy sysintf.obj objects + +del sysintf.obj + +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc3 /Sp1 /Q /Fi- /O parse.c + +copy parse.obj objects + +del parse.obj + +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc3 /Sp1 /Q /Fi- /O getinp.c + +copy getinp.obj objects + +del getinp.obj + +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc3 /Sp1 /Q /Fi- /O quit.c + +copy quit.obj objects + +del quit.obj + +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc3 /Sp1 /Q /Fi- /O state.c + +copy state.obj objects + +del state.obj + +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc3 /Sp1 /Q /Fi- /O dmdump.c + +copy dmdump.obj objects + +del dmdump.obj + +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc3 /Sp1 /Q /Fi- /O macparse.c + +copy macparse.obj objects + +del macparse.obj + +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc3 /Sp1 /Q /Fi- /O rulparse.c + +copy rulparse.obj objects + +del rulparse.obj + +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc3 /Sp1 /Q /Fi- /O percent.c + +copy percent.obj objects + +del percent.obj + +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc3 /Sp1 /Q /Fi- /O function.c + +copy function.obj objects + +del function.obj + +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc3 /Sp1 /Q /Fi- /O os2\ruletab.c + +copy ruletab.obj objects + +del ruletab.obj + +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc3 /Sp1 /Q /Fi- /O os2\dchdir.c + +copy dchdir.obj objects + +del dchdir.obj + +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc3 /Sp1 /Q /Fi- /O os2\switchar.c + +copy switchar.obj objects + +del switchar.obj + +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc3 /Sp1 /Q /Fi- /O msdos\dirlib.c + +copy dirlib.obj objects + +del dirlib.obj + +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc3 /Sp1 /Q /Fi- /O msdos\runargv.c + +copy runargv.obj objects + +del runargv.obj + +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc3 /Sp1 /Q /Fi- /O msdos\dirbrk.c + +copy dirbrk.obj objects + +del dirbrk.obj + +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc3 /Sp1 /Q /Fi- /O msdos\arlib.c + +copy arlib.obj objects + +del arlib.obj + +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc3 /Sp1 /Q /Fi- /O msdos\dstrlwr.c + +copy dstrlwr.obj objects + +del dstrlwr.obj + +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc3 /Sp1 /Q /Fi- /O unix\rmprq.c + +copy rmprq.obj objects + +del rmprq.obj + +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc3 /Sp1 /Q /Fi- /O unix\dcache.c + +copy dcache.obj objects + +del dcache.obj + +icc /c /I. /Ios2 /Ios2\ibm /Ios2\ibm\icc3 /Sp1 /Q /Fi- /O tempnam.c + +copy tempnam.obj objects + +del tempnam.obj + +ilink /NOFREE /de /pmtype:vio /align:16 /nologo /m /stack:32768 @os2\ibm\icc3\obj.rsp,,,,, + +copy os2\ibm\icc3\template.mk startup\config.mk + diff --git a/dmake/os2/ibm/icc3/obj.rsp b/dmake/os2/ibm/icc3/obj.rsp new file mode 100644 index 000000000000..6309577681b9 --- /dev/null +++ b/dmake/os2/ibm/icc3/obj.rsp @@ -0,0 +1,30 @@ +objects\dmake.obj+ +objects\infer.obj+ +objects\make.obj+ +objects\stat.obj+ +objects\expand.obj+ +objects\dmstring.obj+ +objects\hash.obj+ +objects\dag.obj+ +objects\path.obj+ +objects\imacs.obj+ +objects\sysintf.obj+ +objects\parse.obj+ +objects\getinp.obj+ +objects\quit.obj+ +objects\state.obj+ +objects\dmdump.obj+ +objects\macparse.obj+ +objects\rulparse.obj+ +objects\percent.obj+ +objects\function.obj+ +objects\ruletab.obj+ +objects\dchdir.obj+ +objects\switchar.obj+ +objects\runargv.obj+ +objects\dirbrk.obj+ +objects\arlib.obj+ +objects\dstrlwr.obj+ +objects\rmprq.obj+ +objects\tempnam.obj + diff --git a/dmake/os2/ibm/icc3/public.h b/dmake/os2/ibm/icc3/public.h new file mode 100644 index 000000000000..1a9d48a358ea --- /dev/null +++ b/dmake/os2/ibm/icc3/public.h @@ -0,0 +1,168 @@ +/* RCS $Id: public.h,v 1.1.1.1 2000-09-22 15:33:30 hr Exp $ +-- WARNING -- This file is AUTOMATICALLY GENERATED DO NOT EDIT IT +-- +-- +-- SYNOPSIS +-- Local functions exported to be visible by others. +-- +-- DESCRIPTION +-- This file is generated by 'genpub'. Function declarations +-- that appear in this file are extracted by 'genpub' from +-- source files. Any function in the source file whose definition +-- appears like: +-- +-- PUBLIC return_type +-- function( arg_list ); +-- type_expr1 arg1; +-- ... +-- +-- has its definition extracted and a line of the form: +-- +-- return_type function ANSI((type_expr1,type_expr2,...)); +-- +-- entered into the output file. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef _DMAKE_PUBLIC_h +#define _DMAKE_PUBLIC_h + +#ifdef EXTERN +#undef EXTERN +#endif +#if defined(DEFINE_DMAKE_VARIABLES) +#define EXTERN +#else +#define EXTERN extern +#endif + +/***** genpub: Begin list of generated function headers */ +void Infer_recipe ANSI((CELLPTR, CELLPTR)); +int Make_targets ANSI(()); +int Make ANSI((CELLPTR, CELLPTR)); +int Exec_commands ANSI((CELLPTR)); +void Print_cmnd ANSI((char *, int, int)); +int Push_dir ANSI((char *, char *, int)); +void Pop_dir ANSI((int)); +void Append_line ANSI((char *, int, FILE *, char *, int, int)); +void Stat_target ANSI((CELLPTR, int, int)); +char *Expand ANSI((char *)); +char *Apply_edit ANSI((char *, char *, char *, int, int)); +void Map_esc ANSI((char *)); +char* Apply_modifiers ANSI((int, char *)); +char* Tokenize ANSI((char *, char *, char, int)); +char* ScanToken ANSI((char *, char **, int)); +char *DmStrJoin ANSI((char *, char *, int, int)); +char *DmStrAdd ANSI((char *, char *, int)); +char *DmStrApp ANSI((char *, char *)); +char *DmStrDup ANSI((char *)); +char *DmStrDup2 ANSI((char *)); +char *DmStrPbrk ANSI((char *, char *)); +char *DmStrSpn ANSI((char *, char *)); +char *DmStrStr ANSI((char *, char *)); +char *DmSubStr ANSI((char *, char *)); +uint16 Hash ANSI((char *, uint32 *)); +HASHPTR Get_name ANSI((char *, HASHPTR *, int)); +HASHPTR Search_table ANSI((HASHPTR *, char *, uint16 *, uint32 *)); +HASHPTR Push_macro ANSI((HASHPTR)); +HASHPTR Pop_macro ANSI((HASHPTR)); +HASHPTR Def_macro ANSI((char *, char *, int)); +CELLPTR Def_cell ANSI((char *)); +LINKPTR Add_prerequisite ANSI((CELLPTR, CELLPTR, int, int)); +void Clear_prerequisites ANSI((CELLPTR)); +int Test_circle ANSI((CELLPTR, int)); +STRINGPTR Def_recipe ANSI((char *, STRINGPTR, int, int)); +t_attr Rcp_attribute ANSI((char *)); +void main ANSI((int, char **)); +FILE *Openfile ANSI((char *, int, int)); +FILE *Closefile ANSI(()); +FILE *Search_file ANSI((char *, char **)); +char *Filename ANSI(()); +int Nestlevel ANSI(()); +FILE *TryFiles ANSI((LINKPTR)); +void Fatal ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Error ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Warning ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void No_ram ANSI(()); +void Usage ANSI((int)); +void Version ANSI(()); +char *Get_suffix ANSI((char *)); +char *Basename ANSI((char *)); +char *Filedir ANSI((char *)); +char *Build_path ANSI((char *, char *)); +void Make_rules ANSI(()); +void Create_macro_vars ANSI(()); +time_t Do_stat ANSI((char *, char *, char **, int)); +int Do_touch ANSI((char *, char *, char **)); +void Void_lib_cache ANSI((char *, char *)); +time_t Do_time ANSI(()); +int Do_cmnd ANSI((char *, int, int, CELLPTR, int, int, int)); +char ** Pack_argv ANSI((int, int, char *)); +char *Read_env_string ANSI((char *)); +int Write_env_string ANSI((char *, char *)); +void ReadEnvironment ANSI(()); +void Catch_signals ANSI((void (*)())); +void Clear_signals ANSI(()); +void Prolog ANSI((int, char* [])); +void Epilog ANSI((int)); +char *Get_current_dir ANSI(()); +int Set_dir ANSI((char*)); +char Get_switch_char ANSI(()); +FILE* Get_temp ANSI((char **, char *, int)); +FILE *Start_temp ANSI((char *, CELLPTR, char **)); +void Open_temp_error ANSI((char *, char *)); +void Link_temp ANSI((CELLPTR, FILE *, char *)); +void Close_temp ANSI((CELLPTR, FILE *)); +void Unlink_temp_files ANSI((CELLPTR)); +void Handle_result ANSI((int, int, int, CELLPTR)); +void Update_time_stamp ANSI((CELLPTR)); +int Remove_file ANSI((char *)); +void Parse ANSI((FILE *)); +int Get_line ANSI((char *, FILE *)); +char *Do_comment ANSI((char *, char **, int)); +char *Get_token ANSI((TKSTRPTR, char *, int)); +void Quit ANSI(()); +void Read_state ANSI(()); +void Write_state ANSI(()); +int Check_state ANSI((CELLPTR, STRINGPTR *, int)); +void Dump ANSI(()); +void Dump_recipe ANSI((STRINGPTR)); +int Parse_macro ANSI((char *, int)); +int Macro_op ANSI((char *)); +int Parse_rule_def ANSI((int *)); +int Rule_op ANSI((char *)); +void Add_recipe_to_list ANSI((char *, int, int)); +void Bind_rules_to_targets ANSI((int)); +int Set_group_attributes ANSI((char *)); +DFALINKPTR Match_dfa ANSI((char *)); +void Check_circle_dfa ANSI(()); +void Add_nfa ANSI((char *)); +char *Exec_function ANSI((char *)); +int _dchdir ANSI((char *)); +int runargv ANSI((CELLPTR, int, int, int, int, char *)); +void SetSessionTitle ANSI((char *)); +int Wait_for_child ANSI((int, int)); +void Clean_up_processes ANSI(()); +int If_root_path ANSI((char *)); +time_t seek_arch ANSI((char*, char*)); +int touch_arch ANSI((char*, char*)); +void dstrlwr ANSI((char *, char *)); +void Remove_prq ANSI((CELLPTR)); +time_t CacheStat ANSI((char *, int)); + +#endif diff --git a/dmake/os2/ibm/icc3/template.mk b/dmake/os2/ibm/icc3/template.mk new file mode 100644 index 000000000000..c9c5adbf21ae --- /dev/null +++ b/dmake/os2/ibm/icc3/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= os2 + OSRELEASE *:= ibm + OSENVIRONMENT *:= icc diff --git a/dmake/os2/ibm/tempnam.c b/dmake/os2/ibm/tempnam.c new file mode 100644 index 000000000000..5bf5c21b3544 --- /dev/null +++ b/dmake/os2/ibm/tempnam.c @@ -0,0 +1,111 @@ +/* RCS $Id: tempnam.c,v 1.1.1.1 2000-09-22 15:33:30 hr Exp $ +-- +-- SYNOPSIS +-- tempnam +-- +-- DESCRIPTION +-- temp file name generation routines. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +/*LINTLIBRARY*/ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include "config.h" + +#if defined(max) +# undef max +#endif +#define max(A,B) (((A)<(B))?(B):(A)) + +extern int access(); +int d_access(); + +/* MSC stdio.h defines P_tmpdir, so let's undo it here */ +/* Under DOS leave the default tmpdir pointing here! */ +#ifdef P_tmpdir +#undef P_tmpdir +#endif +static char *P_tmpdir = ""; + +char * +tempnam(dir, prefix) +char *dir; /* use this directory please (if non-NULL) */ +char *prefix; /* use this (if non-NULL) as filename prefix */ +{ + static int count = 0; + register char *p, *q, *tmpdir; + int tl=0, dl=0, pl; + char buf[30]; + + pl = strlen(P_tmpdir); + + if( (tmpdir = getenv("TMPDIR")) != NULL ) + tl = strlen(tmpdir); + else if( (tmpdir = getenv("TMP")) != NULL ) + tl = strlen(tmpdir); + if( dir != NULL ) dl = strlen(dir); + + if( (p = malloc((unsigned)(max(max(dl,tl),pl)+13))) == NULL ) + return(NULL); + + *p = '\0'; + + if( (tl == 0) || (d_access( strcpy(p, tmpdir), 0) != 0) ) + if( (dl == 0) || (d_access( strcpy(p, dir), 0) != 0) ) + if( d_access( strcpy(p, P_tmpdir), 0) != 0 ) + if( !prefix ) + prefix = "tp"; + + if(prefix) + { + *(p+strlen(p)+2) = '\0'; + (void)strncat(p, prefix, 2); + } + + sprintf( buf, "%08x", getpid() ); + buf[6]='\0'; + (void)strcat(p, buf ); + sprintf( buf, "%04d", count++ ); + q=p+strlen(p)-6; + *q++ = buf[0]; *q++ = buf[1]; + *q++ = buf[2]; *q++ = buf[3]; + + if( (q = strrchr(p,'.')) != NULL ) *q = '\0'; + + return strlwr(p); +} + + + +d_access( name, flag ) +char *name; +int flag; +{ + char *p; + int r; + + if( name == NULL || !*name ) return(1); /* NULL dir means current dir */ + p = name+strlen(name)-1; + if(*p == ':' ) strcat( p++, "\\" ); + r = access( name, flag ); + if(*p != '/' && *p != '\\') strcat( p, "\\" ); + + return( r ); +} diff --git a/dmake/os2/ruletab.c b/dmake/os2/ruletab.c new file mode 100644 index 000000000000..8620556393de --- /dev/null +++ b/dmake/os2/ruletab.c @@ -0,0 +1,46 @@ +/* RCS $Id: ruletab.c,v 1.1.1.1 2000-09-22 15:33:30 hr Exp $ +-- +-- SYNOPSIS +-- Default initial configuration of dmake. +-- +-- DESCRIPTION +-- Define here the initial set of rules that are defined before +-- dmake performs any processing. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +/* These are control macros for dmake that MUST be defined at some point + * if they are NOT dmake will not work! These are default definitions. They + * may be overridden inside the .STARTUP makefile, they are here + * strictly so that dmake can parse the STARTUP makefile */ +/* + * For OS/2 these are close to the Unix definitions in terms of limits. + * We dont need the two different cases of Makefile, so only keep the + * pretty one. + */ +static char *_rules[] = { + "MAXLINELENGTH := 2046", + "MAXPROCESSLIMIT := 16", + ".IMPORT .IGNORE: DMAKEROOT SOLARVER UPD INPATH OS UPDMINOREXT" + ".MAKEFILES : makefile.mk Makefile", + ".SOURCE : .NULL", +#include "startup.h" + 0 }; + +char **Rule_tab = _rules; /* for sundry reasons in Get_environment() */ + diff --git a/dmake/os2/startup.h b/dmake/os2/startup.h new file mode 100644 index 000000000000..bf6c94ff939f --- /dev/null +++ b/dmake/os2/startup.h @@ -0,0 +1,27 @@ +/* RCS $Id: startup.h,v 1.1.1.1 2000-09-22 15:33:30 hr Exp $ +-- +-- SYNOPSIS +-- Definition of MAKESTARTUP +-- +-- DESCRIPTION +-- Default MAKESTARTUP value defining where dmake locates the +-- startup file. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +"MAKESTARTUP := $(DMAKEROOT)\\startup.mk", diff --git a/dmake/os2/switchar.c b/dmake/os2/switchar.c new file mode 100644 index 000000000000..458030993d57 --- /dev/null +++ b/dmake/os2/switchar.c @@ -0,0 +1,43 @@ +/* RCS $Id: switchar.c,v 1.1.1.1 2000-09-22 15:33:30 hr Exp $ +-- +-- SYNOPSIS +-- switch char query. +-- +-- DESCRIPTION +-- Get the current value of the command line switch char. Only useful +-- in a DOS environment, otherwise we #define it to be '-'. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ +#include <stdlib.h> +#include <stdio.h> +#include "stdmacs.h" + +getswitchar()/* +=============== + Try the environment first. If you don't find SWITCHAR there, then use + the DOS call. The call is undocumented, and doesn't work for DOS versions + 4.0 and up, so the check of the environment will fix that. */ +{ + static char *_env_switchar = NIL(char); + + if( _env_switchar != NIL(char) || + (_env_switchar = (char *)getenv("SWITCHAR")) != NIL(char) ) + return(*_env_switchar); + + return ('/'); +} diff --git a/dmake/os2/sysintf.h b/dmake/os2/sysintf.h new file mode 100644 index 000000000000..ab842c26c34f --- /dev/null +++ b/dmake/os2/sysintf.h @@ -0,0 +1,60 @@ +/* RCS $Id: sysintf.h,v 1.1.1.1 2000-09-22 15:33:30 hr Exp $ +-- +-- SYNOPSIS +-- Interfaces for sysintf.c +-- +-- DESCRIPTION +-- Abstractions of functions in sysintf.c +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#define DMSTAT stat +#define VOID_LCACHE(l,m) +#define Hook_std_writes(A) +#define GETPID getpid() +#define DMSTRLWR(A,B) dstrlwr(A,B) +#define S_IFMT (S_IFDIR|S_IFCHR|S_IFREG) + +extern char * tempnam(); +extern char * getcwd(); + +/* for directory cache */ +/* #define CacheStat(A,B) really_dostat(A,&buf)*/ + +/* +** standard C items +*/ + +/* +** DOS interface standard items +*/ +#define chdir(p) _dchdir(p) +#define CacheStat(A,B) really_dostat(A,&buf) + +/* +** make parameters +*/ +#ifdef _POSIX_NAME_MAX +#undef _POSIX_NAME_MAX +#endif +#define _POSIX_NAME_MAX 12 + +#ifdef _POSIX_PATH_MAX +#undef _POSIX_PATH_MAX +#endif +#define _POSIX_PATH_MAX 255 diff --git a/dmake/parse.c b/dmake/parse.c new file mode 100644 index 000000000000..c7bf8bf76880 --- /dev/null +++ b/dmake/parse.c @@ -0,0 +1,168 @@ +/* RCS $Id: parse.c,v 1.1.1.1 2000-09-22 15:33:25 hr Exp $ +-- +-- SYNOPSIS +-- Parse the input, and perform semantic analysis +-- +-- DESCRIPTION +-- This file contains the routines that parse the input makefile and +-- call the appropriate routines to perform the semantic analysis and +-- build the internal dag. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include "extern.h" + + +PUBLIC void +Parse( fil )/* +============== Parse the makefile input */ +FILE *fil; +{ + int rule = FALSE; /* have seen a recipe line */ + char *p; /* termporary pointer into Buffer */ + char *pTmpBuf; + + DB_ENTER( "Parse" ); + + State = NORMAL_SCAN; + Group = FALSE; /* true if scanning a group rcpe */ + while( TRUE ) { + if( Get_line( Buffer, fil ) ) { + if( fil != NIL( FILE ) ) /* end of parsable input */ + Closefile(); + + Bind_rules_to_targets( F_DEFAULT ); + if( Group ) Fatal( "Incomplete rule recipe group detected" ); + + DB_VOID_RETURN; + } + else { + +#ifdef _MPW + if ( Buffer[0] == 10 ) + pTmpBuf = Buffer+1; + else +#endif + pTmpBuf = Buffer; + +#ifdef _MPW + p = pTmpBuf; + while ( *p ) + { + if ( *p == 10 ) + *p = '\t'; + p++; + } +#endif + + switch( State ) { + case RULE_SCAN: + + /* Check for the `[' that starts off a group rule definition. + * It must appear as the first non-white space + * character in the line. */ + + p = DmStrSpn( Buffer, " \t\r\n" ); + if( Set_group_attributes( p ) ) { + if( rule && Group ) + Fatal( "Cannot mix single and group recipe lines" ); + else + Group = TRUE; + + rule = TRUE; + + break; /* ignore the group start */ + } + + if( Group ) { + if( *p != ']' ) { + Add_recipe_to_list( pTmpBuf, TRUE, TRUE ); + rule = TRUE; + } + else + State = NORMAL_SCAN; + } + else { + if( *pTmpBuf == '\t' + || (Notabs && *pTmpBuf == ' ') ) { + Add_recipe_to_list( pTmpBuf, FALSE, FALSE ); + rule = TRUE; + } + else if( *p == ']' ) + Fatal( "Found unmatched ']'" ); + else if( *pTmpBuf && *p || (Notabs && !*pTmpBuf && !*p)) + State = NORMAL_SCAN; + } + + if( State == RULE_SCAN ) break; /* ie. keep going */ + + Bind_rules_to_targets( (Group) ? F_GROUP: F_DEFAULT ); + + rule = FALSE; + if( Group ) { + Group = FALSE; + break; + } + /*FALLTRHOUGH*/ + + /* In this case we broke out of the rule scan because we do not + * have a recipe line that begins with a <TAB>, so lets + * try to scan the thing as a macro or rule definition. */ + + + case NORMAL_SCAN: + if( !*pTmpBuf ) continue; /* we have null input line */ + + /* STUPID AUGMAKE uses "include" at the start of a line as + * a signal to include a new file, so let's look for it. + * if we see it replace it by .INCLUDE: and stick this back + * into the buffer. */ + if( !strncmp( "include", pTmpBuf, 7 ) && + (pTmpBuf[7] == ' ' || pTmpBuf[7] == '\t') ) + { + char *tmp; + + tmp = DmStrJoin( ".INCLUDE:", pTmpBuf+7, -1, FALSE ); + strcpy( pTmpBuf, tmp ); + FREE( tmp ); + } + + /* look for a macro definition, they all contain an = sign + * if we fail to recognize it as a legal macro op then try to + * parse the same line as a rule definition, it's one or the + * other */ + + if( Parse_macro(pTmpBuf, M_DEFAULT) ) break;/* it's a macro def*/ + if( Parse_rule_def( &State ) ) break;/* it's a rule def */ + + /* if just blank line then ignore it */ + if( *DmStrSpn( Buffer, " \t\r\n" ) == '\0' ) break; + + /* otherwise assume it was a line of unrecognized input, or a + * recipe line out of place so print a message */ + + Fatal( "Expecting macro or rule defn, found neither" ); + break; + + default: + Fatal( "Internal -- UNKNOWN Parser state %d", State ); + } + } + } +} + diff --git a/dmake/path.c b/dmake/path.c new file mode 100644 index 000000000000..a4c2f9af7031 --- /dev/null +++ b/dmake/path.c @@ -0,0 +1,161 @@ +/* RCS $Id: path.c,v 1.1.1.1 2000-09-22 15:33:25 hr Exp $ +-- +-- SYNOPSIS +-- Pathname manipulation code +-- +-- DESCRIPTION +-- Pathname routines to handle building and pulling appart +-- pathnames. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include "extern.h" + + +/* +** Return the suffix portion of a filename, assumed to begin with a `.'. +*/ +PUBLIC char * +Get_suffix(name) +char *name; +{ + char *suff; + + if(name == NIL(char) || (suff = strrchr(name, '.')) == NIL(char)) + suff = ".NULL"; + + return (suff); +} + + +PUBLIC char * +Basename(path) +char *path; +{ + char *p; + char *q; + + if( path && *(q = path) ) { + for(; *(p=DmStrPbrk(q, DirBrkStr)) != '\0'; q = p+1 ); + if( !*q ) { + for( p=q-1; p != path; --p ) + if( strchr( DirBrkStr, *p ) == NIL(char) ) return( p+1 ); + return( strchr(DirBrkStr, *p)?path:(p+1) ); + } + path = q; + } + return( path ); +} + + +PUBLIC char * +Filedir(path) +char *path; +{ + char *p; + char *q; + + if( path && *(q = path) ) { + for(; *(p=DmStrPbrk(q,DirBrkStr)) != '\0'; q=p+1 ); + + if (q == path) return(""); + + for(p=q-1; p!=path; --p) + if( strchr(DirBrkStr,*p) == NIL(char) ) + break; + + p[1] = '\0'; + } + + return(path); +} + + + +/* +** Take dir and name, and return a path which has dir as the directory +** and name afterwards. +** +** N.B. Assumes that the dir separator string is in DirSepStr. +** Return path is built in a static buffer, if you need to use it +** again you must strdup the result returned by Build_path. +*/ +PUBLIC char * +Build_path(dir, name) +char *dir; +char *name; +{ + register char *p; + register char *q; + static char *path = NIL(char); + static unsigned buflen = 0; + int plen = 0; + int dlen = 0; + int len; + + if( dir != NIL(char) ) dlen = strlen( dir ); + if( name != NIL(char) ) plen = strlen( name ); + len = plen+dlen+strlen(DirSepStr)+1; + + if( len > buflen ) { + buflen = (len+16) & ~0xf; /* buf is always multiple of 16 */ + + if( path == NIL(char) ) + path = MALLOC( buflen, char ); + else + path = realloc( path, (unsigned) (buflen*sizeof(char)) ); + } + + *path = '\0'; + + if( dlen ) { + strcpy( path, dir ); + if( *path && strchr(DirBrkStr, dir[dlen-1]) == NIL(char) ) + strcat( path, DirSepStr ); + } + + if ( plen ) { + while ( *name && strchr(DirBrkStr,*name) != 0 ) name++; + strcat( path, name ); + } + + q=path; + while( *q ) { + char *t; + + p=DmStrPbrk(q,DirBrkStr); + t=DmStrPbrk(p+1,DirBrkStr); + if( !*p || !*t ) break; + + if ( p-q == 1 && *q == '.' ) { + strcpy(q,DmStrSpn(p,DirBrkStr)); + q = path; + } + else if ( + !(p-q == 2 && strncmp(q,"..",2) == 0) + && (t-p-1 == 2 && strncmp(p+1,"..",2) == 0) + ) { + strcpy(q,DmStrSpn(t,DirBrkStr)); + q = path; + } + else + q = p+1; + } + + return( path ); +} diff --git a/dmake/percent.c b/dmake/percent.c new file mode 100644 index 000000000000..8ecac4ce764d --- /dev/null +++ b/dmake/percent.c @@ -0,0 +1,251 @@ +/* RCS $Id: percent.c,v 1.1.1.1 2000-09-22 15:33:25 hr Exp $ +-- +-- SYNOPSIS +-- Handle building or %-rule meta-target nfa. +-- +-- DESCRIPTION +-- Builds the NFA used by dmake to match targets against %-meta +-- rule constructs. The NFA is built as a set of DFA's. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include "extern.h" + +static DFAPTR _build_dfa ANSI((char *)); +static char _shift_dfa ANSI((DFAPTR, char *)); + + +#define NO_ACTION 0 +#define START_PERCENT 1 +#define END_PERCENT 2 +#define ACCEPT 4 +#define FAIL -1 + +static NFAPTR _nfa = NIL( NFA ); + + +PUBLIC DFALINKPTR +Match_dfa( buf )/* +================== + This routines runs all DFA's in parrallel and selects the one that best + matches the string. If no match then it returns NIL( DFA ) */ +char *buf; +{ + register NFAPTR nfa; + int adv; + DFALINKPTR dfa_list = NIL(DFALINK); + + DB_ENTER( "Match_dfa" ); + DB_PRINT( "dfa", ("Matching %s", buf) ); + + /* Run each of the DFA's on the input string in parallel, we terminate + * when all DFA's have either failed or ACCEPTED, if more than one DFA + * accepts we build a list of all accepting DFA's sorted on states with + * those matching in a higher numbered state heading the list. */ + + do { + adv = FALSE; + + for( nfa = _nfa; nfa != NIL( NFA ); nfa = nfa->next ) + if( nfa->status != (char) FAIL && nfa->status != (char) ACCEPT ) { + adv++; + nfa->status = _shift_dfa( nfa->dfa, buf ); + + /* Construct the list of matching DFA's */ + if( nfa->status == (char) ACCEPT ) { + DFALINKPTR dl; + + TALLOC( dl, 1, DFALINK ); + dl->dl_meta = nfa->dfa->node; + dl->dl_per = DmSubStr( nfa->dfa->pstart, nfa->dfa->pend ); + dl->dl_state = nfa->dfa->states - nfa->dfa->c_state; + + if( dfa_list == NIL(DFALINK) ) + dfa_list = dl; + else { + DFALINKPTR tdli = dfa_list; + DFALINKPTR tdlp = NIL(DFALINK); + + for( ; tdli != NIL(DFALINK); tdli = tdli->dl_next ) { + if( dl->dl_state >= tdli->dl_state ) + break; + tdlp = tdli; + } + + if( tdli != NIL(DFALINK) ) { + tdli->dl_prev = dl; + dl->dl_next = tdli; + } + + if( tdlp != NIL(DFALINK) ) { + tdlp->dl_next = dl; + dl->dl_prev = tdlp; + } + else + dfa_list = dl; + } + + DB_PRINT( "dfa", ("Matched [%s]", dl->dl_meta->CE_NAME) ); + } + } + + buf++; + } + while ( adv ); + + for( nfa = _nfa; nfa != NIL( NFA ); nfa = nfa->next ) { + nfa->status = 0; + nfa->dfa->c_state = nfa->dfa->states; + } + + DB_RETURN( dfa_list ); +} + + +PUBLIC void +Check_circle_dfa()/* +==================== + This function is called to test for circularities in the DFA lists + constructed from %-meta targets. */ +{ + register NFAPTR nfa; + + for( nfa = _nfa; nfa != NIL(NFA); nfa = nfa->next ) + if( Test_circle( nfa->dfa->node, FALSE ) ) + Fatal( "Detected circular dependency in inference graph at [%s]", + nfa->dfa->node->CE_NAME ); +} + + +PUBLIC void +Add_nfa( name )/* +================= + Given name, build a DFA and add it to the NFA. The NFA is maintained as + a singly linked list of DFA's. */ +char *name; +{ + NFAPTR nfa; + + TALLOC(nfa, 1, NFA); + nfa->dfa = _build_dfa(name); + + if( _nfa != NIL(NFA) ) nfa->next = _nfa; + + _nfa = nfa; +} + + +static DFAPTR +_build_dfa( name )/* +==================== + Construct a dfa for the passed in cell name. The routine returns a struct + that represents a finite state machine that can recognize a regular + expression with exactly one '%' sign in it. The '%' symbol is used as a + wildcard character that will match anything except the character that + immediately follows it or NUL. + + The Construction of DFA's is well known and can be found in Hopcroft and + Ullman or any other book discussing formal language theory. + A more practical treatise can be found in Compilers, Aho, Sethi and Ullman. +*/ +char *name; +{ + DFAPTR dfa; + int nstates; + register STATEPTR sp; + STATEPTR per_state = NIL(STATE); + int pcount=0; + int end_percent=FALSE; + + nstates = strlen(name)+2; + + /* Allocate a DFA node and the right number of states. */ + TALLOC(dfa, 1, DFA); + TALLOC(sp=dfa->c_state=dfa->states, nstates, STATE); + dfa->node = Def_cell( name ); + + /* Now construct the state table for the DFA */ + do { + if( *name == '%' ) { + if( pcount++ > 0 ) + Error( "Only one %% allowed within a %%-meta target" ); + + sp->symbol = 0; + sp->action = START_PERCENT; + sp->no_match = sp->match = per_state = sp+1; + end_percent = TRUE; + } + else { + sp->symbol = *name; + sp->no_match = per_state; + + if( *name == '\0' ) { + sp->action = ACCEPT; + sp->match = dfa->states; + } + else { + sp->action = NO_ACTION; + sp->match = sp+1; + } + + if( end_percent ) { + sp->action |= END_PERCENT; + end_percent = FALSE; + } + } + + sp++; + } + while( *name++ ); + + return(dfa); +} + + +static char +_shift_dfa( dfa, data )/* +========================= + Take a given dfa and advance it based on the current state, the shift + action in that state, and the current data value. */ +DFAPTR dfa; +char *data; +{ + register STATEPTR sp = dfa->c_state; + char c = *data; + + /* Check if it is a START_PERCENT action if so then we need to save + * a pointer to the start of the string and advance to the next state. */ + if( sp->action & START_PERCENT ) { + dfa->pstart = data; + sp++; + } + + /* Now check if the current char matches the character expected in the + * current state. If it does then perform the specified action, otherwise + * either shift it or fail. We fail if the next state on no-match is + * NIL. */ + if( sp->symbol == c ) { + if( sp->action & END_PERCENT ) dfa->pend = data; + if( sp->action & ACCEPT ) return(ACCEPT); + dfa->c_state = sp->match; + } + else if( (dfa->c_state = sp->no_match) == NIL(STATE) || !c ) + return((unsigned char) FAIL); + + return(NO_ACTION); +} diff --git a/dmake/posix.h b/dmake/posix.h new file mode 100644 index 000000000000..b28dca36f010 --- /dev/null +++ b/dmake/posix.h @@ -0,0 +1,54 @@ +/* RCS $Id: posix.h,v 1.1.1.1 2000-09-22 15:33:25 hr Exp $ +-- +-- SYNOPSIS +-- Definition for POSIX conforming defines in dmake. +-- +-- DESCRIPTION +-- This file is intended to make certain that defines used within dmake +-- for file name lengths, and number of children processes are defined. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +/* Define the minimum values that each system requires, and do so only if + * we have not defined these includes elsewhere. These should already be + * defined in <limits.h> if you have a C compiler that is POSIX compliant. + */ +#ifndef _POSIX_NAME_MAX +#define _POSIX_NAME_MAX 14 +#endif + +#ifndef _POSIX_PATH_MAX +#define _POSIX_PATH_MAX 64 +#endif + +#ifndef _POSIX_CHILD_MAX +#define _POSIX_CHILD_MAX 1 +#endif + +/* Now define the actual manifests used in the code. */ +#ifndef NAME_MAX +#define NAME_MAX _POSIX_NAME_MAX +#endif + +#ifndef PATH_MAX +#define PATH_MAX _POSIX_PATH_MAX +#endif + +#ifndef CHILD_MAX +#define CHILD_MAX _POSIX_CHILD_MAX +#endif diff --git a/dmake/qssl/config.mk b/dmake/qssl/config.mk new file mode 100644 index 000000000000..d5d1534996eb --- /dev/null +++ b/dmake/qssl/config.mk @@ -0,0 +1,43 @@ +# This is an OS specific configuration file +# It assumes that OBJDIR, TARGET and DEBUG are previously defined. +# It defines CFLAGS, LDARGS, CPPFLAGS, STARTUPFILE, LDOBJS +# PRINTER, PRINTFLAGS +# It augments SRC, OBJDIR, TARGET, CFLAGS, LDLIBS +# +PRINTER = hw +PRINTFLAGS = -P$(PRINTER) +STARTUPFILE = $(OS)/startup.mk +CPPFLAGS = $(CFLAGS) +LDOBJS = $(CSTARTUP) $(OBJDIR)/{$(<:f)} +LDARGS = $(LDFLAGS) -o $@ $(LDOBJS) $(LDLIBS) + +# Debug flags +DB_CFLAGS = -g -DDBUG +DB_LDFLAGS = -g +DB_LDLIBS = + +# NO Debug flags +NDB_CFLAGS = -O +NDB_LDFLAGS = -N 8192 +NDB_LDLIBS = + +# Local configuration modifications for CFLAGS. +CFLAGS += -I$(OS) -3 + +# Sources that must be defined for each different version +OSSRC := ruletab.c runargv.c tempnam.c +UNIXSRC := dcache.c rmprq.c dirbrk.c +DOSSRC := arlib.c +SRC += $(OSSRC) $(UNIXSRC) $(DOSSRC) +.SETDIR=$(OS) : $(OSSRC) +.SETDIR=unix : $(UNIXSRC) +.SETDIR=msdos : $(DOSSRC) + +# Set source dirs so that we can find files named in this +# config file. +.SOURCE.h : $(OS) + +# See if we modify anything in the lower levels. +.IF $(OSRELEASE) != $(NULL) + .INCLUDE .IGNORE : $(OS)$(DIRSEPSTR)$(OSRELEASE)$(DIRSEPSTR)config.mk +.END diff --git a/dmake/qssl/make.sh b/dmake/qssl/make.sh new file mode 100644 index 000000000000..042e219adde7 --- /dev/null +++ b/dmake/qssl/make.sh @@ -0,0 +1,62 @@ +mkdir objects +cc -c -I. -Iqssl -3 -O infer.c +mv infer.o objects +cc -c -I. -Iqssl -3 -O make.c +mv make.o objects +cc -c -I. -Iqssl -3 -O stat.c +mv stat.o objects +cc -c -I. -Iqssl -3 -O expand.c +mv expand.o objects +cc -c -I. -Iqssl -3 -O dmstring.c +mv dmstring.o objects +cc -c -I. -Iqssl -3 -O hash.c +mv hash.o objects +cc -c -I. -Iqssl -3 -O dag.c +mv dag.o objects +cc -c -I. -Iqssl -3 -O dmake.c +mv dmake.o objects +cc -c -I. -Iqssl -3 -O path.c +mv path.o objects +cc -c -I. -Iqssl -3 -O imacs.c +mv imacs.o objects +cc -c -I. -Iqssl -3 -O sysintf.c +mv sysintf.o objects +cc -c -I. -Iqssl -3 -O parse.c +mv parse.o objects +cc -c -I. -Iqssl -3 -O getinp.c +mv getinp.o objects +cc -c -I. -Iqssl -3 -O quit.c +mv quit.o objects +cc -c -I. -Iqssl -3 -O state.c +mv state.o objects +cc -c -I. -Iqssl -3 -O dmdump.c +mv dmdump.o objects +cc -c -I. -Iqssl -3 -O macparse.c +mv macparse.o objects +cc -c -I. -Iqssl -3 -O rulparse.c +mv rulparse.o objects +cc -c -I. -Iqssl -3 -O percent.c +mv percent.o objects +cc -c -I. -Iqssl -3 -O function.c +mv function.o objects +cc -c -I. -Iqssl -3 -O qssl/ruletab.c +mv ruletab.o objects +cc -c -I. -Iqssl -3 -O qssl/runargv.c +mv runargv.o objects +cc -c -I. -Iqssl -3 -O qssl/tempnam.c +mv tempnam.o objects +cc -c -I. -Iqssl -3 -O unix/dcache.c +mv dcache.o objects +cc -c -I. -Iqssl -3 -O unix/rmprq.c +mv rmprq.o objects +cc -c -I. -Iqssl -3 -O unix/dirbrk.c +mv dirbrk.o objects +cc -c -I. -Iqssl -3 -O msdos/arlib.c +mv arlib.o objects +cc -N 8192 -o dmake objects/infer.o objects/make.o objects/stat.o \ +objects/expand.o objects/dmstring.o objects/hash.o objects/dag.o objects/dmake.o \ +objects/path.o objects/imacs.o objects/sysintf.o objects/parse.o \ +objects/getinp.o objects/quit.o objects/state.o objects/dmdump.o \ +objects/macparse.o objects/rulparse.o objects/percent.o objects/function.o \ +objects/ruletab.o objects/runargv.o objects/tempnam.o objects/dcache.o objects/rmprq.o objects/dirbrk.o objects/arlib.o +cp qssl/template.mk startup/config.mk diff --git a/dmake/qssl/public.h b/dmake/qssl/public.h new file mode 100644 index 000000000000..2b977c4ed6b6 --- /dev/null +++ b/dmake/qssl/public.h @@ -0,0 +1,165 @@ +/* RCS $Id: public.h,v 1.1.1.1 2000-09-22 15:33:30 hr Exp $ +-- WARNING -- This file is AUTOMATICALLY GENERATED DO NOT EDIT IT +-- +-- +-- SYNOPSIS +-- Local functions exported to be visible by others. +-- +-- DESCRIPTION +-- This file is generated by 'genpub'. Function declarations +-- that appear in this file are extracted by 'genpub' from +-- source files. Any function in the source file whose definition +-- appears like: +-- +-- PUBLIC return_type +-- function( arg_list ); +-- type_expr1 arg1; +-- ... +-- +-- has its definition extracted and a line of the form: +-- +-- return_type function ANSI((type_expr1,type_expr2,...)); +-- +-- entered into the output file. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef _DMAKE_PUBLIC_h +#define _DMAKE_PUBLIC_h + +#ifdef EXTERN +#undef EXTERN +#endif +#if defined(DEFINE_DMAKE_VARIABLES) +#define EXTERN +#else +#define EXTERN extern +#endif + +/***** genpub: Begin list of generated function headers */ +void Infer_recipe ANSI((CELLPTR, CELLPTR)); +int Make_targets ANSI(()); +int Make ANSI((CELLPTR, CELLPTR)); +int Exec_commands ANSI((CELLPTR)); +void Print_cmnd ANSI((char *, int, int)); +int Push_dir ANSI((char *, char *, int)); +void Pop_dir ANSI((int)); +void Append_line ANSI((char *, int, FILE *, char *, int, int)); +void Stat_target ANSI((CELLPTR, int, int)); +char *Expand ANSI((char *)); +char *Apply_edit ANSI((char *, char *, char *, int, int)); +void Map_esc ANSI((char *)); +char* Apply_modifiers ANSI((int, char *)); +char* Tokenize ANSI((char *, char *, char, int)); +char* ScanToken ANSI((char *, char **, int)); +char *DmStrJoin ANSI((char *, char *, int, int)); +char *DmStrAdd ANSI((char *, char *, int)); +char *DmStrApp ANSI((char *, char *)); +char *DmStrDup ANSI((char *)); +char *DmStrDup2 ANSI((char *)); +char *DmStrPbrk ANSI((char *, char *)); +char *DmStrSpn ANSI((char *, char *)); +char *DmStrStr ANSI((char *, char *)); +char *DmSubStr ANSI((char *, char *)); +uint16 Hash ANSI((char *, uint32 *)); +HASHPTR Get_name ANSI((char *, HASHPTR *, int)); +HASHPTR Search_table ANSI((HASHPTR *, char *, uint16 *, uint32 *)); +HASHPTR Push_macro ANSI((HASHPTR)); +HASHPTR Pop_macro ANSI((HASHPTR)); +HASHPTR Def_macro ANSI((char *, char *, int)); +CELLPTR Def_cell ANSI((char *)); +LINKPTR Add_prerequisite ANSI((CELLPTR, CELLPTR, int, int)); +void Clear_prerequisites ANSI((CELLPTR)); +int Test_circle ANSI((CELLPTR, int)); +STRINGPTR Def_recipe ANSI((char *, STRINGPTR, int, int)); +t_attr Rcp_attribute ANSI((char *)); +void main ANSI((int, char **)); +FILE *Openfile ANSI((char *, int, int)); +FILE *Closefile ANSI(()); +FILE *Search_file ANSI((char *, char **)); +char *Filename ANSI(()); +int Nestlevel ANSI(()); +FILE *TryFiles ANSI((LINKPTR)); +void Fatal ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Error ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Warning ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void No_ram ANSI(()); +void Usage ANSI((int)); +void Version ANSI(()); +char *Get_suffix ANSI((char *)); +char *Basename ANSI((char *)); +char *Filedir ANSI((char *)); +char *Build_path ANSI((char *, char *)); +void Make_rules ANSI(()); +void Create_macro_vars ANSI(()); +time_t Do_stat ANSI((char *, char *, char **, int)); +int Do_touch ANSI((char *, char *, char **)); +void Void_lib_cache ANSI((char *, char *)); +time_t Do_time ANSI(()); +int Do_cmnd ANSI((char *, int, int, CELLPTR, int, int, int)); +char ** Pack_argv ANSI((int, int, char *)); +char *Read_env_string ANSI((char *)); +int Write_env_string ANSI((char *, char *)); +void ReadEnvironment ANSI(()); +void Catch_signals ANSI((void (*)())); +void Clear_signals ANSI(()); +void Prolog ANSI((int, char* [])); +void Epilog ANSI((int)); +char *Get_current_dir ANSI(()); +int Set_dir ANSI((char*)); +char Get_switch_char ANSI(()); +FILE* Get_temp ANSI((char **, char *, int)); +FILE *Start_temp ANSI((char *, CELLPTR, char **)); +void Open_temp_error ANSI((char *, char *)); +void Link_temp ANSI((CELLPTR, FILE *, char *)); +void Close_temp ANSI((CELLPTR, FILE *)); +void Unlink_temp_files ANSI((CELLPTR)); +void Handle_result ANSI((int, int, int, CELLPTR)); +void Update_time_stamp ANSI((CELLPTR)); +int Remove_file ANSI((char *)); +void Parse ANSI((FILE *)); +int Get_line ANSI((char *, FILE *)); +char *Do_comment ANSI((char *, char **, int)); +char *Get_token ANSI((TKSTRPTR, char *, int)); +void Quit ANSI(()); +void Read_state ANSI(()); +void Write_state ANSI(()); +int Check_state ANSI((CELLPTR, STRINGPTR *, int)); +void Dump ANSI(()); +void Dump_recipe ANSI((STRINGPTR)); +int Parse_macro ANSI((char *, int)); +int Macro_op ANSI((char *)); +int Parse_rule_def ANSI((int *)); +int Rule_op ANSI((char *)); +void Add_recipe_to_list ANSI((char *, int, int)); +void Bind_rules_to_targets ANSI((int)); +int Set_group_attributes ANSI((char *)); +DFALINKPTR Match_dfa ANSI((char *)); +void Check_circle_dfa ANSI(()); +void Add_nfa ANSI((char *)); +char *Exec_function ANSI((char *)); +int runargv ANSI((CELLPTR, int, int, int, int, char *)); +int Wait_for_child ANSI((int, int)); +void Clean_up_processes ANSI(()); +time_t CacheStat ANSI((char *, int)); +void Remove_prq ANSI((CELLPTR)); +int If_root_path ANSI((char *)); +time_t seek_arch ANSI((char*, char*)); +int touch_arch ANSI((char*, char*)); + +#endif diff --git a/dmake/qssl/ruletab.c b/dmake/qssl/ruletab.c new file mode 100644 index 000000000000..4bdd0be36314 --- /dev/null +++ b/dmake/qssl/ruletab.c @@ -0,0 +1,41 @@ +/* RCS $Id: ruletab.c,v 1.1.1.1 2000-09-22 15:33:30 hr Exp $ +-- +-- SYNOPSIS +-- Default initial configuration of dmake. +-- +-- DESCRIPTION +-- Define here the initial set of rules that are defined before +-- dmake performs any processing. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +/* These are control macros for dmake that MUST be defined at some point + * if they are NOT dmake will not work! These are default definitions. They + * may be overridden inside the .STARTUP makefile, they are here + * strictly so that dmake can parse the STARTUP makefile */ + +static char *_rules[] = { + "MAXPROCESSLIMIT := 10", + "MAXLINELENGTH := 8190", + ".IMPORT .IGNORE: ROOTDIR", + ".MAKEFILES : makefile.mk Makefile makefile", + ".SOURCE : .NULL", +#include "startup.h" + 0 }; + +char **Rule_tab = _rules; /* for sundry reasons in Get_environment() */ diff --git a/dmake/qssl/runargv.c b/dmake/qssl/runargv.c new file mode 100644 index 000000000000..552ce846c7e4 --- /dev/null +++ b/dmake/qssl/runargv.c @@ -0,0 +1,296 @@ +/* RCS $Id: runargv.c,v 1.1.1.1 2000-09-22 15:33:30 hr Exp $ +-- +-- SYNOPSIS +-- Invoke a sub process. +-- +-- DESCRIPTION +-- Use the standard methods of executing a sub process. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include <signal.h> +#include "extern.h" +#include "sysintf.h" + +typedef struct prp { + char *prp_cmd; + int prp_group; + int prp_ignore; + int prp_last; + int prp_shell; + struct prp *prp_next; +} RCP, *RCPPTR; + +typedef struct pr { + int pr_valid; + int pr_pid; + CELLPTR pr_target; + int pr_ignore; + int pr_last; + RCPPTR pr_recipe; + RCPPTR pr_recipe_end; + char *pr_dir; +} PR; + +static PR *_procs = NIL(PR); +static int _proc_cnt = 0; +static int _abort_flg= FALSE; +static int _use_i = -1; +static int _do_upd = 0; + +static void _add_child ANSI((int, CELLPTR, int, int)); +static void _attach_cmd ANSI((char *, int, int, CELLPTR, int, int)); +static void _finished_child ANSI((int, int)); +static int _running ANSI((CELLPTR)); + +PUBLIC int +runargv(target, ignore, group, last, shell, cmd) +CELLPTR target; +int ignore; +int group; +int last; +int shell; +char *cmd; +{ + extern int errno; + int pid; + char **argv; + + if( _running(target) /*&& Max_proc != 1*/ ) { + /* The command will be executed when the previous recipe + * line completes. */ + _attach_cmd( cmd, group, ignore, target, last, shell ); + return(1); + } + + while( _proc_cnt == Max_proc ) + if( Wait_for_child(FALSE, -1) == -1 ) Fatal( "Lost a child %d", errno ); + + argv = Pack_argv( group, shell, cmd ); + + switch( pid=fork() ){ + int wid; + int status; + + case -1: /* fork failed */ + Error("%s: %s", argv[0], strerror(errno)); + Handle_result(-1, ignore, _abort_flg, target); + return(-1); + + case 0: /* child */ + execvp(argv[0], argv); + Continue = TRUE; /* survive error message */ + Error("%s: %s", argv[0], strerror(errno)); + kill(getpid(), SIGTERM); + /*NOTREACHED*/ + + default: /* parent */ + _add_child(pid, target, ignore, last); + } + + return(1); +} + + +PUBLIC int +Wait_for_child( abort_flg, pid ) +int abort_flg; +int pid; +{ + int wid; + int status; + int waitchild; + + waitchild = (pid == -1)? FALSE : Wait_for_completion; + + do { + if( (wid = wait(&status)) == -1 ) return(-1); + + _abort_flg = abort_flg; + _finished_child(wid, status); + _abort_flg = FALSE; + } + while( waitchild && pid != wid ); + + return(0); +} + + +PUBLIC void +Clean_up_processes() +{ + register int i; + + if( _procs != NIL(PR) ) { + for( i=0; i<Max_proc; i++ ) + if( _procs[i].pr_valid ) + kill(_procs[i].pr_pid, SIGTERM); + + while( Wait_for_child(TRUE, -1) != -1 ); + } +} + + +static void +_add_child( pid, target, ignore, last ) +int pid; +CELLPTR target; +int ignore; +int last; +{ + register int i; + register PR *pp; + + if( _procs == NIL(PR) ) { + TALLOC( _procs, Max_proc, PR ); + } + + if( (i = _use_i) == -1 ) + for( i=0; i<Max_proc; i++ ) + if( !_procs[i].pr_valid ) + break; + + pp = _procs+i; + + pp->pr_valid = 1; + pp->pr_pid = pid; + pp->pr_target = target; + pp->pr_ignore = ignore; + pp->pr_last = last; + pp->pr_dir = DmStrDup(Get_current_dir()); + + Current_target = NIL(CELL); + + _proc_cnt++; + + if( Wait_for_completion ) Wait_for_child( FALSE, pid ); +} + + +static void +_finished_child(pid, status) +int pid; +int status; +{ + register int i; + register PR *pp; + char *dir; + + for( i=0; i<Max_proc; i++ ) + if( _procs[i].pr_valid && _procs[i].pr_pid == pid ) + break; + + /* Some children we didn't make esp true if using /bin/sh to execute a + * a pipe and feed the output as a makefile into dmake. */ + if( i == Max_proc ) return; + _procs[i].pr_valid = 0; + _proc_cnt--; + dir = DmStrDup(Get_current_dir()); + Set_dir( _procs[i].pr_dir ); + + if( _procs[i].pr_recipe != NIL(RCP) && !_abort_flg ) { + RCPPTR rp = _procs[i].pr_recipe; + + + Current_target = _procs[i].pr_target; + Handle_result( status, _procs[i].pr_ignore, FALSE, _procs[i].pr_target ); + Current_target = NIL(CELL); + + if ( _procs[i].pr_target->ce_attr & A_ERROR ) { + Unlink_temp_files( _procs[i].pr_target ); + _procs[i].pr_last = TRUE; + goto ABORT_REMAINDER_OF_RECIPE; + } + + _procs[i].pr_recipe = rp->prp_next; + + _use_i = i; + runargv( _procs[i].pr_target, rp->prp_ignore, rp->prp_group, + rp->prp_last, rp->prp_shell, rp->prp_cmd ); + _use_i = -1; + + FREE( rp->prp_cmd ); + FREE( rp ); + + if( _proc_cnt == Max_proc ) Wait_for_child( FALSE, -1 ); + } + else { + Unlink_temp_files( _procs[i].pr_target ); + Handle_result(status,_procs[i].pr_ignore,_abort_flg,_procs[i].pr_target); + + ABORT_REMAINDER_OF_RECIPE: + if( _procs[i].pr_last ) { + FREE(_procs[i].pr_dir ); + + if( !Doing_bang ) Update_time_stamp( _procs[i].pr_target ); + } + } + + Set_dir(dir); + FREE(dir); +} + + +static int +_running( cp ) +CELLPTR cp; +{ + register int i; + + if( !_procs ) return(FALSE); + + for( i=0; i<Max_proc; i++ ) + if( _procs[i].pr_valid && + _procs[i].pr_target == cp ) + break; + + return( i != Max_proc ); +} + + +static void +_attach_cmd( cmd, group, ignore, cp, last, shell ) +char *cmd; +int group; +int ignore; +CELLPTR cp; +int last; +int shell; +{ + register int i; + RCPPTR rp; + + for( i=0; i<Max_proc; i++ ) + if( _procs[i].pr_valid && + _procs[i].pr_target == cp ) + break; + + TALLOC( rp, 1, RCP ); + rp->prp_cmd = DmStrDup(cmd); + rp->prp_group = group; + rp->prp_ignore= ignore; + rp->prp_last = last; + rp->prp_shell = shell; + + if( _procs[i].pr_recipe == NIL(RCP) ) + _procs[i].pr_recipe = _procs[i].pr_recipe_end = rp; + else { + _procs[i].pr_recipe_end->prp_next = rp; + _procs[i].pr_recipe_end = rp; + } +} diff --git a/dmake/qssl/setup b/dmake/qssl/setup new file mode 100644 index 000000000000..9aa004cd604f --- /dev/null +++ b/dmake/qssl/setup @@ -0,0 +1,40 @@ +#!/bin/sh + +if [ ! -d /usr/local ]; then mkdir /usr/local ; fi +if [ ! -d /usr/local/bin ]; then mkdir /usr/local/bin ; fi +if [ ! -d /usr/local/lib ]; then mkdir /usr/local/lib ; fi +if [ ! -d /usr/local/lib/dmake-4.1 ]; then mkdir /usr/local/lib/dmake-4.1 ; fi + + +if [ -d /usr/local/lib/dmake-4.1/startup ] +then + if [ -f /usr/local/lib/dmake-4.1/startup/local.mk ]; then + cp /usr/local/lib/dmake-4.1/startup/local.mk /tmp/local$$ + elif [ -d /usr/local/lib/dmake ]; then + if [ -f /usr/local/lib/dmake/startup/local.mk ]; then + cp /usr/local/lib/dmake/startup/local.mk /tmp/local$$ + fi + fi + /bin/rm -rf /usr/local/lib/dmake-4.1/startup /usr/local/lib/dmake +fi + +mkdir /usr/local/lib/dmake-4.1/startup + +echo "Installing Dmake into /usr/local/bin" + +cp dmake-4.1g/dmake /usr/local/bin/dmake-4.1; +/bin/rm -f /usr/local/bin/dmake +(cd /usr/local/bin; ln -s dmake-4.1 dmake; chmod a+x,og-w dmake-4.1) +cp -r dmake-4.1g/startup /usr/local/lib/dmake-4.1/startup +(cd /usr/local/lib; ln -s dmake-4.1 dmake) +find /usr/local/lib/dmake-4.1 -type d -exec chmod a+x {} \; +find /usr/local/lib/dmake-4.1 -type f -exec chmod og-w,a+r {} \; + +if [ -f /tmp/local$$ ] +then + cp /tmp/local$$ /usr/local/lib/dmake/startup/local.mk +fi + +/bin/rm -rf dmake-4.1g + +echo "Dmake setup is complete" diff --git a/dmake/qssl/startup.h b/dmake/qssl/startup.h new file mode 100644 index 000000000000..051ed555774d --- /dev/null +++ b/dmake/qssl/startup.h @@ -0,0 +1,27 @@ +/* RCS $Id: startup.h,v 1.1.1.1 2000-09-22 15:33:30 hr Exp $ +-- +-- SYNOPSIS +-- Definition of MAKESTARTUP +-- +-- DESCRIPTION +-- Default MAKESTARTUP value defining where dmake locates the +-- startup file. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +"MAKESTARTUP := $(ROOTDIR)/usr/local/lib/dmake/startup/startup.mk", diff --git a/dmake/qssl/stdlib.h b/dmake/qssl/stdlib.h new file mode 100644 index 000000000000..c599d7104363 --- /dev/null +++ b/dmake/qssl/stdlib.h @@ -0,0 +1,48 @@ +/* RCS $Id: stdlib.h,v 1.1.1.1 2000-09-22 15:33:30 hr Exp $ +-- +-- SYNOPSIS +-- stdlib interface +-- +-- DESCRIPTION +-- Specially needed pieces of interface to the standard C lib. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ +#ifndef _STDLIB_INCLUDED_ +#define _STDLIB_INCLUDED_ + +extern /*GOTO*/ _exit(); +extern /*GOTO*/ exit(); +extern /*GOTO*/ abort(); +extern int system(); +extern char *getenv(); +extern char *calloc(); +extern char *malloc(); +extern char *realloc(); + +#ifndef _AIX +/* The AIX compiler dies on illegal redefinition of free */ +extern free(); +#endif + +extern int errno; + +#ifndef EIO +# include <errno.h> +#endif + +#endif /* _STDLIB_INCLUDED_ */ diff --git a/dmake/qssl/sysintf.h b/dmake/qssl/sysintf.h new file mode 100644 index 000000000000..2ab5ecb63855 --- /dev/null +++ b/dmake/qssl/sysintf.h @@ -0,0 +1,43 @@ +/* RCS $Id: sysintf.h,v 1.1.1.1 2000-09-22 15:33:30 hr Exp $ +-- +-- SYNOPSIS +-- Interfaces for sysintf.c +-- +-- DESCRIPTION +-- Abstractions of functions in sysintf.c +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#define DMSTAT stat +#define VOID_LCACHE(l,m) +#define Hook_std_writes(A) +#define GETPID getpid() +#define DMSTRLWR(A,B) + +/* +** standard C items +*/ + +/* +** DOS interface standard items +*/ +#define getswitchar() '-' + +/* +** make parameters +*/ diff --git a/dmake/qssl/template.mk b/dmake/qssl/template.mk new file mode 100644 index 000000000000..e7e9837ae671 --- /dev/null +++ b/dmake/qssl/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= qssl + OSRELEASE *:= + OSENVIRONMENT *:= diff --git a/dmake/qssl/tempnam.c b/dmake/qssl/tempnam.c new file mode 100644 index 000000000000..eb683da7ee4c --- /dev/null +++ b/dmake/qssl/tempnam.c @@ -0,0 +1,102 @@ +/* RCS $Id: tempnam.c,v 1.1.1.1 2000-09-22 15:33:30 hr Exp $ +-- +-- SYNOPSIS +-- tempnam +-- +-- DESCRIPTION +-- temp file name generation routines. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +/*LINTLIBRARY*/ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +#define max(A,B) (((A)<(B))?(B):(A)) + +extern int access(); + +static char *cpdir(); +static char seed[4]="AAA"; + +/* BSD stdio.h doesn't define P_tmpdir, so let's do it here */ +#ifndef P_tmpdir +static char *P_tmpdir = "/tmp"; +#endif + +char * +tempnam(dir, prefix) +char *dir; /* use this directory please (if non-NULL) */ +char *prefix; /* use this (if non-NULL) as filename prefix */ +{ + register char *p, *q, *tmpdir; + int tl=0, dl=0, pl; + + pl = strlen(P_tmpdir); + + if( (tmpdir = getenv("TMPDIR")) != NULL ) tl = strlen(tmpdir); + if( dir != NULL ) dl = strlen(dir); + + if( (p = malloc((unsigned)(max(max(dl,tl),pl)+16))) == NULL ) + return(NULL); + + *p = '\0'; + + if( (tl == 0) || (access( cpdir(p, tmpdir), 3) != 0) ) + if( (dl == 0) || (access( cpdir(p, dir), 3) != 0) ) + if( access( cpdir(p, P_tmpdir), 3) != 0 ) + if( access( cpdir(p, "/tmp"), 3) != 0 ) + return(NULL); + + (void) strcat(p, "/"); + if(prefix) + { + *(p+strlen(p)+5) = '\0'; + (void)strncat(p, prefix, 5); + } + + (void)strcat(p, seed); + (void)strcat(p, "XXXXXX"); + + q = seed; + while(*q == 'Z') *q++ = 'A'; + ++*q; + + if(*tmpnam(p) == '\0') return(NULL); + return(p); +} + + + +static char * +cpdir(buf, str) +char *buf; +char *str; +{ + char *p; + + if(str != NULL) + { + (void) strcpy(buf, str); + p = buf - 1 + strlen(buf); + if(*p == '/') *p = '\0'; + } + + return(buf); +} diff --git a/dmake/qssl/time.h b/dmake/qssl/time.h new file mode 100644 index 000000000000..f3ddaf7962dd --- /dev/null +++ b/dmake/qssl/time.h @@ -0,0 +1,32 @@ +/* RCS $Id: time.h,v 1.1.1.1 2000-09-22 15:33:30 hr Exp $ +-- +-- SYNOPSIS +-- time_t +-- +-- DESCRIPTION +-- Fix broken time_t definition. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef TIME_h +#define TIME_h + +typedef long time_t; /* this is the thing we use */ + +#endif TIME_h + diff --git a/dmake/quit.c b/dmake/quit.c new file mode 100644 index 000000000000..ffb4eda74d4c --- /dev/null +++ b/dmake/quit.c @@ -0,0 +1,69 @@ +/* RCS $Id: quit.c,v 1.1.1.1 2000-09-22 15:33:25 hr Exp $ +-- +-- SYNOPSIS +-- End the dmake session. +-- +-- DESCRIPTION +-- Handles dmake termination. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include "extern.h" + +static void _handle_quit ANSI((char*)); +static int _dont_quit = 0; + + +PUBLIC void +Quit()/* +======== Error or quit */ +{ + if( _dont_quit ) return; + + while( Closefile() != NIL( FILE ) ); + Clean_up_processes(); + + if( Current_target != NIL(CELL) ) + Unlink_temp_files(Current_target); + + if( _dont_quit == 0 ) _handle_quit( ".ERROR" ); + + Set_dir( Makedir ); /* No Error message if we can't do it */ + Epilog( ERROR_EXIT_VALUE ); +} + + +static void +_handle_quit( err_target )/* +============================ + Called by quit and the others to handle the execution of termination code + from within make */ +char *err_target; +{ + HASHPTR hp; + CELLPTR cp; + + if( (hp = Get_name(err_target, Defs, FALSE)) != NIL(HASH) ) { + cp = hp->CP_OWNR; + Glob_attr |= A_IGNORE; + + _dont_quit = 1; + cp->ce_flag |= F_TARGET; + Make( cp, NIL(CELL) ); + } +} diff --git a/dmake/rcsclean.awk b/dmake/rcsclean.awk new file mode 100644 index 000000000000..8fdba716bacd --- /dev/null +++ b/dmake/rcsclean.awk @@ -0,0 +1,57 @@ +/^\/\* RCS/ { print "/* RCS $Id: rcsclean.awk,v 1.1.1.1 2000-09-22 15:33:25 hr Exp $"; next } +/^-- LOG/,/^\*\// { + if( ! flag ) { + print "-- LOG"; + print "-- Use cvs log to obtain detailed change logs."; + print "*/"; + flag = 1; + } + + next; +} +/^-- SYNOPSIS --/ { + print "--"; + print "-- SYNOPSIS"; + printf "-- %s%s\n", toupper(substr($0, 16,1)), substr($0,17); + next; +} +/^-- WWW/,/^--$/ { + if( !wflag ) { + print "-- WWW"; + print "-- http://dmake.wticorp.com/"; + print "--"; + wflag = 1; + } + next; +} +/^-- AUTHOR/,/^--$/ { + if( !aflag ) { + print "-- AUTHOR"; + print "-- Dennis Vadura, dvadura@dmake.wticorp.com"; + print "--"; + aflag = 1; + } + next; +} +/^-- COPYRIGHT/,/^--$/ { + if( !wflag ) { + print "-- WWW"; + print "-- http://dmake.wticorp.com/"; + print "--"; + wflag = 1; + } + + if( !cflag ) { +print "-- COPYRIGHT"; +print "-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved."; +print "-- "; +print "-- This program is NOT free software; you can redistribute it and/or"; +print "-- modify it under the terms of the Software License Agreement Provided"; +print "-- in the file <distribution-root>/readme/license.txt."; +print "--"; +cflag = 1; + } + next; +} + +{ print; } diff --git a/dmake/readme/intro.txt b/dmake/readme/intro.txt new file mode 100644 index 000000000000..c68ef005dd23 --- /dev/null +++ b/dmake/readme/intro.txt @@ -0,0 +1,43 @@ +DMAKE 4.1 [http://dmake.wticorp.com/] +---------------------------------------------------- + +The dmake home page can be found at: + + http://dmake.wticorp.com/ + +Visit there for the latest in dmake related information. + +dmake is different from other versions of Make in that it supports significant +enhancements (See the WWW page). A short summary of the more important +features follows: + + . support for portable makefiles + . portable accross many platforms + . significantly enhanced macro facilities + . sophisticated inference algorithm supporting transitive closure + over the inference graph + . support for traversing the file sytem both during making of targets + and during inference + . %-meta rules for specifying rules to be used for inferring + prerequisites + . conditional macros + . local rule macro variables + . proper support for libraries + . parallel making of targets on architectures that support it + . attributed targets + . text diversions + . group recipes + . swapping itself to DISK under MSDOS + . supports MKS extended argument passing convention + . directory caching + . highly configurable + +Additional information pertaining to installation can be found in either the + + gold/ - sub-folder for the Dmake Gold release + public/ - sub-folder for the Damke public release + +Release notes for this release of dmake can be found in the file + + release.txt + diff --git a/dmake/readme/license.txt b/dmake/readme/license.txt new file mode 100644 index 000000000000..3c68f02bb420 --- /dev/null +++ b/dmake/readme/license.txt @@ -0,0 +1,248 @@ + GNU GENERAL PUBLIC LICENSE + Version 1, February 1989 + + Copyright (C) 1989 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The license agreements of most software companies try to keep users +at the mercy of those companies. By contrast, our General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. The +General Public License applies to the Free Software Foundation's +software and to any other program whose authors commit to using it. +You can use it for your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Specifically, the General Public License is designed to make +sure that you have the freedom to give away or sell copies of free +software, that you receive source code or can get it if you want it, +that you can change the software or use pieces of it in new free +programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of a such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must tell them their rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any program or other work which +contains a notice placed by the copyright holder saying it may be +distributed under the terms of this General Public License. The +"Program", below, refers to any such program or work, and a "work based +on the Program" means either the Program or any work containing the +Program or a portion of it, either verbatim or with modifications. Each +licensee is addressed as "you". + + 1. You may copy and distribute verbatim copies of the Program's source +code as you receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice and +disclaimer of warranty; keep intact all the notices that refer to this +General Public License and to the absence of any warranty; and give any +other recipients of the Program a copy of this General Public License +along with the Program. You may charge a fee for the physical act of +transferring a copy. + + 2. You may modify your copy or copies of the Program or any portion of +it, and copy and distribute such modifications under the terms of Paragraph +1 above, provided that you also do the following: + + a) cause the modified files to carry prominent notices stating that + you changed the files and the date of any change; and + + b) cause the whole of any work that you distribute or publish, that + in whole or in part contains the Program or any part thereof, either + with or without modifications, to be licensed at no charge to all + third parties under the terms of this General Public License (except + that you may choose to grant warranty protection to some or all + third parties, at your option). + + c) If the modified program normally reads commands interactively when + run, you must cause it, when started running for such interactive use + in the simplest and most usual way, to print or display an + announcement including an appropriate copyright notice and a notice + that there is no warranty (or else, saying that you provide a + warranty) and that users may redistribute the program under these + conditions, and telling the user how to view a copy of this General + Public License. + + d) You may charge a fee for the physical act of transferring a + copy, and you may at your option offer warranty protection in + exchange for a fee. + +Mere aggregation of another independent work with the Program (or its +derivative) on a volume of a storage or distribution medium does not bring +the other work under the scope of these terms. + + 3. You may copy and distribute the Program (or a portion or derivative of +it, under Paragraph 2) in object code or executable form under the terms of +Paragraphs 1 and 2 above provided that you also do one of the following: + + a) accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of + Paragraphs 1 and 2 above; or, + + b) accompany it with a written offer, valid for at least three + years, to give any third party free (except for a nominal charge + for the cost of distribution) a complete machine-readable copy of the + corresponding source code, to be distributed under the terms of + Paragraphs 1 and 2 above; or, + + c) accompany it with the information you received as to where the + corresponding source code may be obtained. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form alone.) + +Source code for a work means the preferred form of the work for making +modifications to it. For an executable file, complete source code means +all the source code for all modules it contains; but, as a special +exception, it need not include source code for modules which are standard +libraries that accompany the operating system on which the executable +file runs, or for standard header files or definitions files that +accompany that operating system. + + 4. You may not copy, modify, sublicense, distribute or transfer the +Program except as expressly provided under this General Public License. +Any attempt otherwise to copy, modify, sublicense, distribute or transfer +the Program is void, and will automatically terminate your rights to use +the Program under this License. However, parties who have received +copies, or rights to use copies, from you under this General Public +License will not have their licenses terminated so long as such parties +remain in full compliance. + + 5. By copying, distributing or modifying the Program (or any work based +on the Program) you indicate your acceptance of this license to do so, +and all its terms and conditions. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the original +licensor to copy, distribute or modify the Program subject to these +terms and conditions. You may not impose any further restrictions on the +recipients' exercise of the rights granted herein. + + 7. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of the license which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +the license, you may choose any version ever published by the Free Software +Foundation. + + 8. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to humanity, the best way to achieve this is to make it +free software which everyone can redistribute and change under these +terms. + + To do so, attach the following notices to the program. It is safest to +attach them to the start of each source file to most effectively convey +the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) 19yy <name of author> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 1, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19xx name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the +appropriate parts of the General Public License. Of course, the +commands you use may be called something other than `show w' and `show +c'; they could even be mouse-clicks or menu items--whatever suits your +program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + program `Gnomovision' (a program to direct compilers to make passes + at assemblers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/dmake/readme/public/install.txt b/dmake/readme/public/install.txt new file mode 100644 index 000000000000..a5ee339d2730 --- /dev/null +++ b/dmake/readme/public/install.txt @@ -0,0 +1,203 @@ + DMAKE UNPACKING AND INSTALLATION INSTRUCTIONS + + +We attempt to keep the information presented here accurate. However, the +defacto location of the most up to date information is the dmake WWW site +found at: + + http://dmake.wticorp.com/ + +DMAKE is available in several formats: a compressed tar src archive, +a pkzip src archive, a variety of executable archives. Refer to the +appropriate section below for unpacking instructions. + + +1. UNPACKING THE DISTRIBUTION FILES + + OPTION 'A' (compressed tar src archive): + -------------------------------------- + Assumption: The current directory contains the latest version of dmake in + the file 'dm41src.tgz'. + + This file is a standard GNU zip compressed tar archive. To unpack the file + issue the following command. gunzip is available for most UNIX platforms + as well as DOS. + + gunzip -c dm41src.tgz | tar xf - + + + OPTION 'B' (src zip archive): + ----------------------------- + Assumption: The current directory contains the latest version of DMAKE in + the file dm41src.zip. + + To unpack the full zip distribution simply use pkunzip with the + following command: + + pkunzip dm41src.zip + or + unzip dm41src.zip + + + Instructions for unpacking executable only versions are given on the + dmake WWW site. + + +2. BUILDING THE EXECUTABLE + + Skip this step if you have purchased a prebuilt binary distribution. + + The only supported method for building a new executable from a fresh or + patched distribution is to use the self building scripts rather than DMAKE + itself. This is necessary in order to allow for the use of new DMAKE + features and functionality in the DMAKE 'makefile' itself. Once built + the DMAKE executable can be used to rebuild DMAKE. + + To determine the set of supported environments issue the following + commands: + + cd src + make + + The output of this command will be a set of arguments representing the + supported environments that DMAKE can be compiled in. Choose the one + that most closely represents your environment and issue the command: + + make environ_tag + + where 'environ_tag' is from the previous list, for example on a Solaris + System the option is Solaris, so you would issue the command 'make Solaris'. + + The script runs the appropriate set of commands; upon completion the file + 'dmake' or 'dmake.exe' is found in the current directory. + This is the binary executable. + + Note: before issuing the build command please read Section 3 and decide + if you need or want to modify the pre-compiled value of MAKESTARTUP. + + During the build it is safe to ignore any warnings that may + be generated by your build. If you get errors from the build then + it is probably the case that you have chosen a build target that is + not compatible with your environment. + + +3. INSTALLING AND CONFIGURING THE EXECUTABLE + + To install the dmake executable place the executable into the + location where your system normally finds executables. That is + place dmake into a subdirectory that is or will be in your + executable search PATH. + + You can now issue the command 'dmake -V'; the output will be + similar to: + + dmake - Copyright (c) 1990,...,1996 by Dennis Vadura, Version 4.10, PL 0 + + Default Configuration: + MAXPROCESSLIMIT := 10 + MAXLINELENGTH := 8190 + .IMPORT .IGNORE: ROOTDIR + .MAKEFILES : makefile.mk Makefile makefile + .SOURCE : .NULL + MAKESTARTUP := $(ROOTDIR)/usr/local/lib/dmake/startup/startup.mk + + Please read the file readme/release for the latest release notes. + + + Take note of the line defining the value of MAKESTARTUP; to configure + the executable you must perform two steps: + + 1. Copy the <dmake-distdir>/startup subtree to a suitable location, + 2. Tell dmake where you put it, + + + Step 1: + ------- + The above example build of dmake assumes that the directory path (assuming + ROOTDIR is NULL) + + /usr/local/lib/dmake/ + + is a directory which contains a copy of the "<dmake-distdir>/startup" + subtree. Thus to properly configure dmake so that the precompiled + defaults would be used you would have to perform the following: + + cd <dmake-distdir> + mkdir /usr/local/lib/dmake + cp -r startup /usr/local/lib/dmake + + or if you are in the MSDOS or Windows-95/NT world: + + cd <dmake-distdir> + md \usr\local\lib\dmake + xcopy startup \usr\local\lib\dmake + + and you are done Step 1. + + + Step 2: + ------- + You must tell dmake where it is that you placed the "startup" subtree. If + the location is the directory that is pre-compiled into dmake then you + are done. If the directory where you copied the dmake subtree is not the + precompiled value you must either set the global environment variable + MAKESTARTUP to point at the new location of "startup/startup.mk" or you + must rebuild dmake with a new precompiled value of MAKESTARTUP. To do the + latter create the file: + + src/startup.h + + and make sure that it contains an entry similar to the following: + + /* This file contains the default value of the MAKESTARTUP variable. + * You must set the quoted string below to the default path to the startup + * variable, so that it gets compiled in. LEAVE ROOTDIR at the front of + * the path. This allows the user to customize his environment for dmake + * by setting up a new ROOTDIR environment variable. */ + + "MAKESTARTUP := $(ROOTDIR)/usr/local/lib/dmake/startup/startup.mk", + + (See src/msdos/startup.h for an example). Once set properly rerun your + previous build. In the rare instance that your compiler has broken + #include search rules, the shipped "startup.h" files are located in + architecture specific subdirectories as described in the file + "readme/srcorg". + + +4. DMAKE SPECIFIC ENVIRONMENT VARIABLES + + Once you have built dmake, the dmake startup directory contains the file + "config.mk". This file contains definitions corresponding to your installed + target environment for the variables: + + OS - Specifies the flavour of operating system. + OSRELEASE - Specifies the particular version of the operating + system. + OSENVIRONMENT - An optional configuration parameter for the operating + system release. + + Appropriate values for these variables are found in the + + <install-dir>/startup/templates/<OS>/<OSRELEASE>/<OSENVIRONMENT>/template.mk + + file. Select the OS, OSRELEASE, and OSENVIRONMENT that best suits your + setup (check readme.1st) for hints on selecting the most appropriate + settings. + + These three variables are used to determine the correct dmake configuration + when dmake starts up, and loads its builtin definitions from the startup + subtree hierarchy. The only time you should have a need to change these + values or the contents of the startup subtree is when you wish to supply + your own customized default environment or you are building dmake for a + new as yet unsupported target environment. + + +5. LOCALE SPECIFIC CONFIGURATION + + Locale specific macro definitions that are not part of the predefined macro + set should be placed into the file "startup/local.mk". This ensures that + future dmake releases will not overwrite your prior definitions. We + guarantee that the file "startup/local.mk" will never be part of any future + dmake distribution. + + diff --git a/dmake/readme/public/mac.txt b/dmake/readme/public/mac.txt new file mode 100644 index 000000000000..34a2dca5f820 --- /dev/null +++ b/dmake/readme/public/mac.txt @@ -0,0 +1,43 @@ +MAC specific information for dmake. This information is provided in the +hope that it makes it easier to install and recompile dmake in a MAC +environment. + + +1. ENVIRONMENT VARIABLE SETTINGS + +Only a single set of settings is available for the macintosh. There are no +sub-selections for specific OS release and/or environment. + + OS - mac + OSRELEASE - NULL + OSENVIRONMENT - NULL + + +2. IMPLEMENTATION NOTES + +This port for the Macintosh is specifically designed to be run +under MPW. + +I had to make a couple of changes to dmake in order to get it to work +on the Mac. First, MPW provides no documented way to run a +subprocess, so when you use dmake, you MUST use the -n option and +execute the output. Typically, you will probably want to write a +simple script file to do these operations for you. + +I added some code so that the Macintosh version of dmake can +use UNIX-style directories to specify include paths and target +and dependency file names. I.e., if you specify a file "/dir/file", +dmake will look at the file "dir:file". However, Mac dmake does not +do any translation from files specified by UNIX-style directories +in the recipe line that gets executed. If you need to translate, +you can use substitution commands. (For example, +":$(RELATIVEUNIXFILE:s,/,:,)".) This code was added so one could +execute dmake's makefile, and also so one would have an easier time +porting other UNIX makefiles. I would suggest you stick with +Macintosh-style directories for all other makefiles. + +In order to run dmake, you must set (and export) the environmental +variable "OS" to "mac". + +Micah Doyle +micah@leland.Stanford.EDU diff --git a/dmake/readme/public/msdos.txt b/dmake/readme/public/msdos.txt new file mode 100644 index 000000000000..72664843a644 --- /dev/null +++ b/dmake/readme/public/msdos.txt @@ -0,0 +1,124 @@ +MSDOS specific information for dmake. This information is provided in the +hope that it makes it easier to install and recompile dmake under MSDOS. +I will be happy to hear of erroneous information and will make every effort +to correct it. + +NOTE: If you are seeking information for Win32 compiles please refer to + the file "readme/winnt". + + +1. ENVIRONMENT VARIABLE SETTINGS + +There are many environment variable settings available for MSDOS. Each +option is described below. + + OS - msdos + + OSRELEASE - borland # Borland compilers + - microsft # Microsoft compilers + - zortech # zortech compilers (unsupported) + + OSENVIRONMENT - tcc20 # Borland Turbo C 2.0 + - bcc30 # Borland C++ V3.0 MSDOS compile + - bcc40 # Borland C++ V4.0 MSDOS compile + - bcc45 # Borland C++ V4.5 MSDOS compile + - bcc50 # Borland C++ V5.0 MSDOS compile + + - msc51 # Microsoft 5.1 Compiler MSDOS compile + - msc60 # Microsoft 6.0 Compiler MSDOS compile + + MSC_VER - 5.1 # Microsoft Compiler version + - 6.0 # Microsoft Compiler version + + +2. IMPLEMENTATION NOTES + +Bootstrapping the binary: +------------------------- + A make.bat file is provided to bootstrap the binary. The file contains + several targets for bootstrapping. Invoking the batch file with no + arguments lists the possibilities shown below. + + INDEX: You must specify one of: + tccswp - Turbo C 2.0 compile of swapping dmake. + bcc30swp - Borland C++ 3.0 compile of swapping dmake. + bcc40swp - Borland C++ 4.0 compile of swapping dmake. + bcc45swp - Borland C++ 4.5 compile of swapping dmake. + bcc50swp - Borland C++ 5.0 compile of swapping dmake. + + msc51 - Microsoft C 5.1 compile. + msc51swp - Microsoft C 5.1, MASM 5.1 compile of swapping dmake. + msc60 - Microsoft C 6.0 compile. + msc60swp - Microsoft C 6.0, MASM 5.1 compile of swapping dmake. + + Based on the compiler you have installed and whether or not you + want the swapping version of dmake, you should select the appropriate + target and issue 'make.bat target'. + + The batch file runs a second batch script that comes with the distribution + which compiles the sources using the appropriate compiler and flags. The + MSC Versions of the batch files should not require any further user + intervention during the build. The Borland versions, as a final step, + invoke tlink with two response files. The second of these response files, + named in msdos/borland/{bcc*,tcc20}/mk*.bat, contains absolute path names to + Borland's libraries. You likely need to edit these before getting a + successful binary linked. The reason for this is that not all of us + install the Borland compiler in the same place. + + Note that the file msdos/exec.uue is a uuencoded version of a BCC++ + compiled exec.obj (from exec.asm). If you do not have an assembler + either microsoft MASM or Borland TASM (or some other), you can uudecode + this file and put it into src/objects/exec.obj. The build will then + link against it to build your binary. + + +Using dmake to Make itself: +--------------------------- + See the file "readme/install" for information on building dmake by using + dmake itself. Once successfully built using the presupplied scripts it + should be straight forward to rebuild dmake. + + +Memory Requirements and Swapping: +--------------------------------- + The swapping code currently only swaps to DISK, there are hooks + in the code to accomodate XMS and EMS, but have not been used (and + probably never will). + + It appears that a ramdisk seems to work just fine. If anyone + wishes to fill in the hooks please do so and send us the differences. + + +^C and stopping a make: +----------------------- + Thanks to the efforts of Len Reed, appears to now work. I have been unable + to hang my machine if it's swapped out and I hit ^C a couple thousand times. + + +Other notes: +------------ + dmake does not care if you are running command.com or some other command + interpretter, you must however specify the proper values of the environment + variables SHELL, SHELLFLAGS, GROUPSHELL, and GROUPFLAGS in order for things + to work correctly. Read the man page FIRST, if you still have trouble + then send email. + + Group recipes under DOS that use command.com as the command interpretter + require you to set the GROUPSUFFIX macro. + + As shipped the startup.mk files for the DOS version try to figure out what + command interpretter you are using and set things up appropriately. + Two command interpretters are supported in the shipped startup.mk file, + command.com, and the MKS Korn shell. + + The dos version of dmake contains one builtin command. noop which + simply ignores the remainder of the line and always retuns success, + + dmake supports the MKS argument passing conventions. The facility is + enabled by setting .MKSARGS:=1. It is set by default in the startup.mk file + if an MKS Korn shell is detected as being the active command interpretter. + + At this time there are no plans to support the other popular UNIX like + argument passing conventions available under DOS. We recommend you get + a copy of the MKS Toolkit from Mortice Kern Systems in Waterloo, Ontario, + Canada [http://www.mks.com/]. diff --git a/dmake/readme/public/os2.txt b/dmake/readme/public/os2.txt new file mode 100644 index 000000000000..5acf4cc6ab0a --- /dev/null +++ b/dmake/readme/public/os2.txt @@ -0,0 +1,76 @@ +OS/2 specific information for dmake. This information is provided in the +hope that it makes it easier to install and recompile dmake in a OS/2 +environment. + +Notes on the OS/2 implementation of dmake: +========================================== + +As shipped the DOS versions of dmake will run under OS/2 protected mode. +However, support for a full OS/2 version is also provided. The OS/2 version +will run in parallel under OS/2. + +Bootstrapping the binary: +------------------------- + A make.cmd file is provided to bootstrap the binary. The file contains + several targets for bootstrapping. Invoking the batch file with no + arguments lists the possibilities shown below. + + INDEX: You must specify one of: + ibm - IBM C2 compile. + + The only supported compiler under OS/2 is the Visual Age ICC compiler. + I have tested the build using this compiler. The resulting binary + performs proper directory caching and file-name case mapping for cached + directories and is capable of parallel target builds. The only known + limitation of the OS/2 implementation is the treatment of library time + stamps. Libraries do not have time stamps on members and the timestamp + of the library is used instead. + + +OS/2 Specifics +-------------- + + There is a small number of OS/2 specific features that need to be + stated. + + 1. The environment variables TMP as well as TMPDIR are checked for the + location of the directory where dmake should place any temporary files. + TMPDIR is checked before TMP. + + 2. Appropriate limits are setup for MAXPROCESSES and buffer sizes etc. + See output of 'dmake -V'. + + 3. By default dmake will look for the startup.mk file in the path: + + $(ROOTDIR)/dmake/startup/startup.mk + + This is more in keeping with OS/2 philosophy. You may still rename + and put it anywhere else you like by defining the MAKESTARTUP + environment variable. + + 4. Swapping the dmake binary to disk is not supported under OS/2. + + +Other notes: +------------ + dmake does not care if you are running cmd.exe or some other command + interpretter, you must however specify the proper values of the environment + variables SHELL, SHELLFLAGS, GROUPSHELL, and GROUPFLAGS in order for things + to work correctly. Read the man page first. + + Group recipes under OS/2 that use cmd.exe as the command interpretter + require you to set the GROUPSUFFIX macro. + + As shipped the startup.mk files try to figure out what + command interpretter you are using and set things up appropriately. + Two command interpretters are supported in the shipped startup.mk file, + cmd.exe (via COMSPEC), and the MKS Korn shell. + + dmake does not contain any builtin commands. It gets all commands it + executes from an external file system. It is therefore most useful if it + is used in conjunction with an environment similar to that provided by + the MKS Tool kit, or equivalent. + + dmake now supports the MKS argument passing conventions. The facility is + enabled by setting .MKSARGS:=1 and is set by default in the startup.mk file + if an MKS Korn shell is detected as being the active command interpretter. diff --git a/dmake/readme/public/qssl-qnx.txt b/dmake/readme/public/qssl-qnx.txt new file mode 100644 index 000000000000..80fc8b56aa4d --- /dev/null +++ b/dmake/readme/public/qssl-qnx.txt @@ -0,0 +1,5 @@ +QNX differs from UNIX only in that the library format is that of MSDOS and +as such the normal stating of library members does not work. QNX versions of +dmake stat the library instead of the members (as does the MSDOS +implementation). Otherwise see the readme/unix file for further unix related +information. diff --git a/dmake/readme/public/srcorg.txt b/dmake/readme/public/srcorg.txt new file mode 100644 index 000000000000..89ff914eec4b --- /dev/null +++ b/dmake/readme/public/srcorg.txt @@ -0,0 +1,74 @@ +SOURCE CODE ORGANIZATION: +------------------------- +The source code is organized as follows: + + dmake [source for all common functions] + | + | + ---------------------------- + | | | | | + unix tos qnx os2 msdos [source for OS specific functions] + | | | + -------------------- | ------------------- + | | | | | | | +386ix bsd43 sysvr[134] | tccdos bccdos mscdos [source for OSRELEASE + | | | specific functions] + | --------- ------------------ + | | | | | | + | ibm mscdos bcc30 bcc32 bcc40 + | + | + | + -------- + | | + uw vf [source for OSENVIRONMENT specific functions] + + +Each of the directories (eg. bsd43, mscdos, tccdos, and sysvr3) contain source +that is specific to that release of the OS (and possibly C-library) + + +CREATING A NEW VERSION: +----------------------- +To create yet another version of dmake you should follow the following steps. + +The sysvr3 version as sent is the base version, all dmake versions must provide +the equivalent of the functions defined in the sysvr3 directory, and MUST +provide the same semantics (MSDOS archive lib searches are an exception since +we cannot search libraries for timestamps in MSDOS, Actually the MKS version +of dmake does this, I don't have the inclination to add this code though). + +1. Create a new directory for the version you will be making at the level + that is appropriate. If it is a new OS then add the dir at the top level, + if it is a new version of UNIX then add it below the unix directory. + +2. Copy the files from the unix and unix/sysvr3 directories to the new dir. + (Or from any other directory sub-tree that is more appropriate) + +3. Not all OS/OSRELEASE combinations are compatible so in order to make + dmake on each, the particular directory may contain C-source for functions + present in the SVID SysV R3 distribution which are used by dmake but are + not supplied by the C-library in the target system. For example the bsd43 + directory contains source for tempnam.c since it is not provided with + the BSD C-library. Before writing a new version of the source file + check the other directories to see if one already exists. + +4. Under some systems the standard include files may be missing or incorrect. + eg. under BSD stdarg.h and string.h. If this is the case + you should create the proper .h file in the proper directory. + This works as expected as the compile line includes the flag -Idir + where dir is the configuration dir, (bsd43 for example) and any + standard include files will be searched for in dir before the compiler + looks in the normal places (if you have a sane compiler :-). + +5. Modify dmake.sh to contain the appropriate C compiler flags and link command + and to include any specific C files that you have had to add for this + version of dmake, and run the result through the shell. + (make the same changes to config.mk so that once you have a working copy of + dmake you can use it to bring itself up to date) + +6. Send me the changes :-) so that I can incorporate them into future + distributions. + +7. This should be all that you require to create a new version of dmake. + If you have any questions send e-mail to dvadura@plg.uwaterloo.ca diff --git a/dmake/readme/public/tos.txt b/dmake/readme/public/tos.txt new file mode 100644 index 000000000000..ddcc43104483 --- /dev/null +++ b/dmake/readme/public/tos.txt @@ -0,0 +1,31 @@ +Atari TOS specific information for dmake. This information is provided in the +hope that it makes it easier to install and recompile dmake in a TOS +environment. I do not own an ST. As a result I rely on others to insure that +this version of dmake works as advertized. If you have any problems with it +please fix them and send me the differences so that I can incorporate them +into future releases and patches. + + +1. ENVIRONMENT VARIABLE SETTINGS + +Only a single set of settings is available for Atari TOS. There are no +sub-selections for specific OS release and/or environment. + + OS - tos + OSRELEASE - NULL + OSENVIRONMENT - NULL + + +2. IMPLEMENTATION NOTES + +The code to compile on an Atari-ST using GCC was supplied by Edgar Roeder +(roeder@cs.uni-sb.de). I do not have an ST on which to verify the +distribution sources but I have no reason to believe them to not work. +If there are any problems please let Edgar or myself know. + +I know of no bugs or limitation to the Atari-ST implementation. Note that +it is similar to the DOS version but it does not swap itself out. This does +not appear to be as much of a problem on the Atari as it is on MSDOS boxes :-). +See the msdos specific info file for further information. + +-dennis diff --git a/dmake/readme/public/unix.txt b/dmake/readme/public/unix.txt new file mode 100644 index 000000000000..b50ab9afad1c --- /dev/null +++ b/dmake/readme/public/unix.txt @@ -0,0 +1,171 @@ +UNIX specific information for dmake. This information is provided in the +hope that it makes it easier to install and recompile dmake under UNIX. +I will be happy to hear of erroneous information and will make every effort +to correct it. + + +1. ENVIRONMENT VARIABLE SETTINGS + +There are many environment variable settings available for UNIX. Each +option is described below. + + OS - unix + + OSRELEASE - bsd43 # generic BSD 4.3 + - solaris # Solaris environments + - sysvr1 # System V R1 + - sysvr3 # System V R3 + - sysvr4 # System V R4 + - xenix # Xenix + - 386ix # Sun IPX 386 boxen + - coherent # Coherent... + - qnx # QNX + + OSENVIRONMENT - uw # U of Waterloo mfcf environment for BSD4.3 + - vf # for environments needing vfprintf + - pwd # for environments needing new pwd + - gcc # for GCC compiles with Solaris2.3 and greater + - verxx # for specific OS versions. + + +The table below lists valid combinations for settings of OS, OSRELEASE, and +OSENVIRONMENT. + + OS OSRELEASE OSENVIRONMENT + -- --------- ------------- + unix bsd43 + unix bsd43 uw + unix bsd43 vf + unix solaris + unix solaris gcc + unix sysvr1 + unix sysvr3 + unix sysvr3 pwd + unix sysvr4 + unix xenix + unix xenix pwd + unix 386ix + unix coherent ver40 + unix coherent ver42 + +You must set OS and OSRELEASE, OSENVIRONMENT to correspond to one of the +configurations in the above table. + + +2. IMPLEMENTATION NOTES + +Bootstrapping the binary: +------------------------- + A 'makefile' file is provided to bootstrap the binary. The file contains + many targets for bootstrapping. Issuing 'make' will provide the list of + possible targets that can be built. A restricted sample is shown below: + + INDEX: You must specify 'make target' where target is one of: + ------------- + make bsd43 - Generic BSD 4.3 System + make bsd43uw - Generic BSD 4.3 at U of Waterloo + make bsd43vf - Generic BSD 4.3 that needs vfprintf + make sysvr4 - Generic SysV R4 UNIX System + make sysvr3 - Generic SysV R3 UNIX System + make sysvr3pwd - Generic SysV R3 UNIX System, our PWD + make sysvr1 - Generic SysV R1 UNIX System + make dynix - Sequent DYNIX System + make linux - Linux + make ultrix - Ultrix 3.0 System + make mips - Any MIPS System + make coherent40 - Any Coherent Version 4.0 System + make coherent42 - Any Coherent Version 4.2 or greater System + make hpux - HP Unix + make 386ix - 386/ix (SysV R3) System + make xenix - 386 Xenix System + make xenixpwd - 386 Xenix System, our PWD + make aix - IBM RS6000/AIX System + make Solaris - SUN Solaris 1.0 to 2.0 + make Solaris2.1 - SUN Solaris 2.1 or greater + make gccSolaris2.1 - SUN Solaris 2.1 or greater with gcc + + The above shows only the possible builds for UNIX like operating systems. + Choose the one that best suits your needs and issue the command + + 'make target' + + +Using dmake to Make itself: +--------------------------- + If you use dmake to make itself you must first set a number of makefile + control variables, either through the environment or on the command line. + + The following variables must be set: + + OS - defines operating system (must be set) + OSRELEASE - particular version of it. + OSENVIRNOMENT - more customization + + These three variables should be defined in your environment. Valid values + for UNIX are listed above in Section 1. You must chose one a setting from + the table that best matches your system. + + Once set simply issue the command: 'dmake' and the sources will be + automatically rebuilt. You do not need to specify a target when you + use dmake and the environment variables are correctly set. + + +.NAMEMAX and length of file names: +---------------------------------- +dmake assumes that no file name component has a name longer than .NAMEMAX +(a user-settable variable, see the man page). Files whose basename is +longer than .NAMEMAX return a timestamp of 0 when statted. The reason for +this test is to handle broken versions of stat that return non-zero times +for stating files that are longer than the legal file name length but for +which a file whose name is the legal maximum file name length and is a prefix +of the longer name exists. This used to cause infinite loops in the inference +engine. + +As a result the value of .NAMEMAX is important. dmake attempts to determine +it at from your system header files when compiled however sometimes even these +may be erroneous thus as a result as of dmake 4.0 users may set the value of +.NAMEMAX to any value they wish. + + +Library Name Length: +-------------------- +By default the maximum length of library member names is defined in the the +ar.h header file and is usually 14. Elf libraries allow for a arbitrarily +long member names, if your archiver supports the elf archiver extension for +long member names then edit the file unix/arlib.c and set the CHECKELF define +to indicate that the Elf archiver extension is to be checked for. + +If Elf is not supported and your archiver truncates member names you should +set (in unix/arlib.c) the macro AR_TRUNCATE_MEMBER_NAMES. dmake will then +also truncate member names and perform a length limitted comparison when +scanning the library for matching member names. + + +UNIX Sysv R3 and getcwd: +------------------------ +Some versions of UNIX SysV R3 and Xenix use the popen call to capture the +output of pwd when invoking the C library function getcwd(). These versions +of the function cause dmake to terminate with the "lost a child" message +due to the fact that the parent dmake process may catch the pwd and not +recognize it as a child. For systems that have this problem use the version +of dmake that supplies its own getcwd function. The settings are: + + OS = unix + OSRELEASE = sysvr3 + OSENVIRONMENT = pwd + +It is directly available through the 'makefile' by typing one of: + + make sysvr3pwd + make xenixpwd + +both include the getcwd code but the xenixpwd target compiles for a Xenix +system. + + +UNIX and "limits.h": +-------------------- +Some compilers do not yet provide the "limits.h" file, if yours is one of +these then simply copy the file "namemax.h" in the source root directory to +"limits.h". Make sure the length of a file name is correctly set in +"limits.h" as it is processed prior to "namemax.h". diff --git a/dmake/readme/read1st.txt b/dmake/readme/read1st.txt new file mode 100644 index 000000000000..4c981d5f818d --- /dev/null +++ b/dmake/readme/read1st.txt @@ -0,0 +1,41 @@ +DMAKE 4.1 [http://dmake.wticorp.com/] +------------------------------------- + +This directory tree contains a number of files. Here is a short +description of what each file contains so that you do not need to +search as much. There is also a recommended order for reading them. + + read1st.txt - index of files found in the readme directory. + intro.txt - short note describing what 'dmake' is and where to + get it from. + release.txt - changes from previous release, and release specific + notes. + ../man - directory containing DMAKE manual page. + + patchX - release notes for patchX to the current release. + + gold/install.txt - installation instructions for the Dmake Gold release + public/install.txt - installation files for the Dmake public release + +The next group of files provides additional information for specific +platforms. These are found in the appropriate gold and public release +sub-folders. + + apple.mac - information for macintosh users + atari.tos - information for ATARI TOS users + msdos - information for MSDOS users + winnt - information for Win95 and WinNT users + os2 - information for OS/2 users + unix - information for UNIX users + qssl-qnx - information for QNX users + srcorg - information on the source code organization + +You should read the information in the first group of files. The +second group of files contains platform specific configuration +information and information that may assist you in building dmake on +the related target system. You need to read the relevant file only if +you are building the dmake executable from the source distribution +using 'dmake' itself, or if you want to create a new version of dmake. + +You can also obtain relevant dmake information by checking out the +Official Dmake Web pages at "http://dmake.wticorp.com/". diff --git a/dmake/readme/release.txt b/dmake/readme/release.txt new file mode 100644 index 000000000000..65a250dee881 --- /dev/null +++ b/dmake/readme/release.txt @@ -0,0 +1,194 @@ +DMAKE Version 4.1 +================= +FINAL FREE RELEASE OF DMAKE, REPLACES VERSION 4.0 + +Nature: This distribution advances dmake to Version 4.1, patch level 0. +------- This release adds significant functionality and eliminates + bugs that were introduced with release 4.0. + + +DETAILS OF ENHANCEMENTS/TWEAKS: +=============================== + +BUG FIXES: +---------- + +1. General clean up all over to fix small incompatibilities and obvious + typos. + +2. Fixed bug in getinp.c where buffer was being erroneously overwritten, + this caused the invalidation of the return address on the stack on + DOS systems. + +3. Fixed a bug that caused the "<target> is up to date" message to be + suppressed. + +4. Fixed a bug involving the value of $@ in conjunction with dynamic + prerequisites. + +5. Relegated the warning associated with duplicate entries in prerequisite + lists to a non-essential warning. Added an option flag -Vw to display + it if you wish to check your makefile for duplicate entries. Either way + the parser ignores duplicates. + +6. Better default action on checking out RCS targets. If an RCS target has + no directory prefix of its own it is checked out into the directory + which contains the RCS subdirectory, otherwise it ends up in its directory + qualified location. + +7. Improved the speed of lookups in the directory cache; handle mixed case + file name entries on OS/2 and Win95/NT. + +8. Improved prerequisite list generation for long prerequisite lists. + +9. Rearanged startup macro files to form an architectural hierarchy. + This greatly simplifies the maintenance of the startup files. They + might even be right at some point in the future. Please let me know if + you encounter difficulties, as I don't have access to all possible + platforms, this sub-hierarchy is bound to have ommisions at this release + and hence is intended to be evolutionary over time. + +10. A build that only touches targets (-t) uses the same algorithm to decide + valid names as a normal build. + +11. Conditional macro assignments fixed, and now work for builtin macro + variables as well. + + +NEW FEATURES: +------------- + +0. Complete reorganization of Dmake STARTUP scripts. Please refer to the + installation notes for details. THIS ONE IS IMPORTANT!!! + +1. Support for long archive member names if Elf is available, plus better + support for archivers that truncate member names (see comments in + unix/arlib.c for details). + +2. Added variable MAKEVERSION which contains a string indicating the current + version of dmake. + +3. Added the .EXECUTE attribute, see man page for details. + +4. Added the .ERRREMOVE attribute, see man page for details. + +5. Added support for gmake style if/else/endif, but only if not part of + a Group recipe. + +6. Added initial build target for Coherent version 4.2 UNIX + and for Windows-NT/Windows-95 32-bit app using Borland C++ 4.0,4.5, 5.0, + and Microsoft Visual C++ 4.0. + +7. MSDOS version now supports two builtin runtime commands, noop, and echo. + +8. Added new macro $(uniq list) which returns a sorted version of the + white space separated tokens in list such that there are no repetitions. + +9. Added the function macro $(echo list) which simply returns list. + This is most useful in conjunction with the new $(foreach ...) + function macro. + +10. Added gmake style function macro + + $(foreach,var,list data) + + where var and list are expanded, and the result is the concatenation of + expanding data with var being set to each white space separated token in + list in turn. For example: + + list = a b c + all : + echo [$(foreach,i,$(list) [$i])] + + will output + + [[a] [b] [c]] + + The iterator variable is defined as a local variable to this foreach + instance. The following expression illustrates this: + + $(foreach,i,$(foreach,i,$(sort c a b) root/$i) [$i/f.h]) + + when evaluated the result is: + + [root/a/f.h] [root/b/f.h] [root/c/f.h] + + The specification of list must be a valid macro expression, such as: + + $($(assign list=a b c)) + $(sort d a b c) + $(echo a b c) + + and cannot just be the list itself. That is, the following foreach + expression: + + $(foreach,i,a b c [$i]) + + yields: + + "b c [a]" + + when evaluated. + +11. Added the macro $(and list). + +12. Added the macro $(or list). + +13. Added the macro $(not term). + +14. Added the .NOINFER attribute to the .INCLUDE directive. When specified + any prerequisite of the .INCLUDE directive which cannot be found in + the .INCLUDEDIRS search list is not automatically made. + +15. Improved the handling of internal macros for proper functioning of the *= + and *:= assignment constructs. Macros that are internally initially + defined are considered to be undefined for the purpose of *= and *:= + assignment until they are the target of an explicit assignment operation. + +16. Improved the caching of file names, and their matching on case insensitive + file systems. Two control macros help to manage the functionality: + + .DIRCACHE := yes + + Implies that the directory cache will be used. This is on by default for + systems that support the reading of directories. Setting the value of this + macro to 'no' is equivalent to supplying the '-d' command line switch. + + .DIRCACHERESPCASE := yes + + Causes dmake to respect the case of the directory entries when the cache + is enabled, thereby treating directory entries in a case sensitive manner. + Setting this to 'no' disables the matching of case. This macro has effect + only if .DIRCACHE := yes. Otherwise the facilities provided by the native + OS are used to match file names using 'stat'. + +17. Added parameterized user defined function macros. Yes it's true + you may now define your own parametized function macros. Here is + how it works. Any macro that is not a predefined function macro and + is invoked with parameters is looked up as a user defined function + macro. A new macro scope is created. The n'th argument to the + macro is then assigned to the value of the the macro $n where n is 0 + for the first argument, 1 for the second argument and so on. The + argument is expanded before it is assigned. The original macro is + then expanded. For example: + + FOO = a $0 b $1 c $2 d + echo :; $(FOO x y z) + + Will produce the result string "a z b y c z d". The + expansion of $(FOO) on it's own behaves as expected and returns the + string "a b c d" (assuming that each of $0, $1, $2 + are undefined). The only restriction when specifying function + macro arguments is as before: they cannot contain spaces + themselves. + + +ACKNOWLEDGEMENTS: +================= + Thanks to all who submitted code for new features, suggestions for + improvements, and bug fixes. I have tried to make sure no gotchas + remain, if you encounter problems installing or running dmake please + let me know. As always, I am always happy to receive e-mail. + + Many have contributed suggestions and bug fixes that make this + release possible. The NET thanks you. diff --git a/dmake/rulparse.c b/dmake/rulparse.c new file mode 100644 index 000000000000..f0e9f0cb390f --- /dev/null +++ b/dmake/rulparse.c @@ -0,0 +1,1473 @@ +/* RCS $Id: rulparse.c,v 1.1.1.1 2000-09-22 15:33:25 hr Exp $ +-- +-- SYNOPSIS +-- Perform semantic analysis on input +-- +-- DESCRIPTION +-- This code performs semantic analysis on the input, and builds +-- the complex internal datastructure that is used to represent +-- the user makefile. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include "extern.h" + +/* prototypes for local functions */ +static void _add_global_prereq ANSI((CELLPTR)); +static int _add_root ANSI((CELLPTR)); +static CELLPTR _build_graph ANSI((int, CELLPTR, CELLPTR)); +static char* _build_meta ANSI((char*)); +static int _do_magic ANSI((int, char*, CELLPTR, CELLPTR, t_attr, char*)); +static void _do_special ANSI((int, int, t_attr,char*,CELLPTR,CELLPTR,int*)); +static int _do_targets ANSI((int, t_attr, char*, CELLPTR, CELLPTR)); +static t_attr _is_attribute ANSI((char*)); +static int _is_special ANSI((char*)); +static char* _is_magic ANSI((char*)); +static int _is_percent ANSI((char*)); +static CELLPTR _make_multi ANSI((CELLPTR)); +static CELLPTR _replace_cell ANSI((CELLPTR,CELLPTR,CELLPTR)); +static void _set_attributes ANSI((t_attr, char*, CELLPTR )); +static void _stick_at_head ANSI((CELLPTR, CELLPTR)); +static void _set_global_attr ANSI((t_attr)); + + +/* static variables that must persist across invocation of Parse_rule_def */ +static CELLPTR _sv_targets = NIL(CELL); +static STRINGPTR _sv_rules = NIL(STRING); +static STRINGPTR _sv_crule = NIL(STRING); +static CELLPTR _sv_edgel = NIL(CELL); +static LINKPTR _sv_glb_prq = NIL(LINK); +static int _sp_target = FALSE; +static t_attr _sv_attr; +static int _sv_flag; +static int _sv_op; +static char *_sv_setdir; +static char _sv_globprq_only = 0; + +/* Define for global attribute mask */ +#define A_GLOB (A_PRECIOUS | A_SILENT | A_IGNORE | A_EPILOG | A_SWAP |\ + A_SHELL | A_PROLOG | A_NOINFER | A_SEQ | A_MKSARGS ) + + +PUBLIC int +Parse_rule_def( state )/* +========================= + Parse the rule definition contained in Buffer, and modify the state + if appropriate. The function returns 0, if the definition is found to + be an illegal rule definition, and it returns 1 if it is a rule definition. + */ +int *state; +{ + TKSTR input; /* input string struct for token search */ + CELLPTR targets; /* list of targets if any */ + CELLPTR prereq; /* list of prereq if any */ + CELLPTR prereqtail; /* tail of prerequisite list */ + CELLPTR cp; /* temporary cell pointer for list making */ + char *result; /* temporary storage for result */ + char *tok; /* temporary pointer for tokens */ + char *set_dir; /* value of setdir attribute */ + char *brk; /* break char list for Get_token */ + char *firstrcp; /* first recipe line, from ; in rule line */ + t_attr attr; /* sum of attribute flags for current tgts*/ + t_attr at; /* temp place to keep an attribute code */ + int op; /* rule operator */ + int special; /* indicate special targets in rule */ + int percent; /* indicate percent rule target */ + int mixed_glob_prq; /* indicate mixed %-rule prereq possible */ + + DB_ENTER( "Parse_rule_def" ); + + op = 0; + attr = 0; + special = 0; + percent = 0; + set_dir = NIL( char ); + targets = NIL(CELL); + prereq = NIL(CELL); + prereqtail = NIL(CELL); + mixed_glob_prq = 0; + + /* Check to see if the line is of the form: + * targets : prerequisites; first recipe line + * If so remember the first_recipe part of the line. */ + + firstrcp = strchr( Buffer, ';' ); + if( firstrcp != NIL( char ) ) { + *firstrcp++ = 0; + firstrcp = DmStrSpn( firstrcp, " \t" ); + } + + result = Expand( Buffer ); + for( brk=strchr(result,'\\'); brk != NIL(char); brk=strchr(brk,'\\') ) + if( brk[1] == '\n' ) + *brk = ' '; + else + brk++; + + DB_PRINT( "par", ("Scanning: [%s]", result) ); + + SET_TOKEN( &input, result ); + brk = ":-^!|"; + Def_targets = TRUE; + + /* Scan the input rule line collecting targets, the operator, and any + * prerequisites. Stop when we run out of targets and prerequisites. */ + + while( *(tok = Get_token( &input, brk, TRUE )) != '\0' ) + if( !op ) { + /* we are scanning targets and attributes + * check to see if token is an operator. */ + + op = Rule_op( tok ); + + if( !op ) { + /* define a new cell, or get old cell */ + cp = Def_cell( tok ); + DB_PRINT( "par", ("tg_cell [%s]", tok) ); + + if( (at = _is_attribute(tok)) != 0 ) { + /* Logically OR the attributes specified into one main + * ATTRIBUTE mask. */ + + if( at == A_SETDIR ) + if( set_dir != NIL( char ) ) + Warning( "Multiple .SETDIR attribute ignored" ); + else + set_dir = DmStrDup( tok ); + + attr |= at; + } + else { + int tmp; + + tmp = _is_special( tok ); + if( _is_percent( tok ) ) percent++; + + if( percent ) + cp->ce_flag |= F_PERCENT; + + if( special ) + Fatal( "Special target must appear alone", tok ); + else if( !(cp->ce_flag & F_MARK) ) { + /* Targets are kept in this list in lexically sorted order. + * This allows for easy equality comparison of target + * sets.*/ + CELLPTR prev,cur; + for(prev=NIL(CELL),cur=targets;cur;prev=cur,cur=cur->ce_link) + if(strcmp(cur->CE_NAME,cp->CE_NAME) > 0) + break; + + cp->ce_link = cur; + + if (!prev) + targets = cp; + else + prev->ce_link = cp; + + cp->ce_flag |= F_MARK | F_EXPLICIT; + special = tmp; + } + } + } + else { + /* found an operator so empty out break list + * and clear mark bits on target list, setting them all to F_USED*/ + + brk = ""; + for( cp=targets; cp != NIL(CELL); cp=cp->ce_link ) { + cp->ce_flag ^= F_MARK; + cp->ce_flag |= F_USED; + } + + Def_targets = FALSE; + } + } + else { + /* Scanning prerequisites so build the prerequisite list. We use + * F_MARK flag to make certain we have only a single copy of the + * prerequisite in the list */ + + cp = Def_cell( tok ); + + if( _is_percent( tok ) ) { + if( !percent && !attr ) + Fatal( "Syntax error in %% rule, missing %% target"); + mixed_glob_prq = 1; + } + + if( cp->ce_flag & F_USED ) { + if( cp->ce_attr & A_COMPOSITE ) + continue; + else + Fatal( "Detected circular dependency in graph at [%s]", + cp->CE_NAME ); + } + else if( !(cp->ce_flag & F_MARK) ) { + DB_PRINT( "par", ("pq_cell [%s]", tok) ); + cp->ce_flag |= F_MARK; + + if( prereqtail == NIL(CELL) ) /* keep prereq's in order */ + prereq = cp; + else + prereqtail->ce_link = cp; + + prereqtail = cp; + cp->ce_link = NIL(CELL); + } + else if( !(cp->ce_attr & A_LIBRARY) && (Verbose & V_WARNALL)) + Warning("Duplicate entry [%s] in prerequisite list",cp->CE_NAME); + } + + /* Check to see if we have a percent rule that has only global + * prerequisites. If so then set the flag so that later on, we don't issue + * an error if such targets supply an empty set of rules. */ + + if( percent && !mixed_glob_prq && (prereq != NIL(CELL)) ) + _sv_globprq_only = 1; + + /* It's ok to have targets with attributes, and no prerequisites, but it's + * not ok to have no targets and no attributes, or no operator */ + + if( !op ) { + CLEAR_TOKEN( &input ); + DB_PRINT( "par", ("Not a rule [%s]", Buffer) ); + DB_RETURN( 0 ); + } + + if( !attr && targets == NIL(CELL) ) { + Fatal( "Missing targets or attributes in rule" ); + if( set_dir != NIL( char )) FREE( set_dir ); + DB_RETURN( 0 ); + } + + /* We have established we have a legal rules line, so we must process it. + * In doing so we must handle any special targets. Special targets must + * appear alone possibly accompanied by attributes. + * NOTE: special != 0 ==> targets != NIL(CELL) */ + + if( prereqtail != NIL(CELL) ) prereqtail->ce_link = NIL(CELL); + + /* Clear out MARK bits used in duplicate checking. I originally wanted + * to do this as the lists get processed but that got too error prone + * so I bit the bullit and added these two loops. */ + + for( cp=prereq; cp != NIL(CELL); cp=cp->ce_link ) cp->ce_flag &= ~F_MARK; + for( cp=targets; cp != NIL(CELL); cp=cp->ce_link ) cp->ce_flag &= ~F_USED; + + /* Check to see if the previous rule line was bound if, not the call + * Bind_rules_to_targets to go and bind the line */ + + if( _sv_rules != NIL(STRING) ) Bind_rules_to_targets( F_DEFAULT ); + + /* Add the first recipe line to the list */ + if( firstrcp != NIL( char ) ) + Add_recipe_to_list( firstrcp, TRUE, FALSE ); + + /* Save these prior to calling _do_targets, since _build_graph needs the + * _sv_setdir value for matching edges. */ + _sv_op = op; + _sv_setdir = set_dir; + + if( special ) + _do_special( special, op, attr, set_dir, targets, prereq, state ); + else + *state = _do_targets( op, attr, set_dir, targets, prereq ); + + DB_RETURN( 1 ); +} + + +PUBLIC int +Rule_op( op )/* +================ + Check the passed in op string and map it to one of the rule operators */ +char *op; +{ + int ret = 0; + + DB_ENTER( "rule_op" ); + + if( *op == TGT_DEP_SEP ) { + ret = R_OP_CL; + op++; + + /* All rule operations begin with a :, but may include any one of the + * four modifiers. In order for the rule to be properly mapped we must + * check for each of the modifiers in turn, building up our return bit + * string. */ + + while( *op && ret ) + switch( *op ) { + case ':': ret |= R_OP_DCL; op++; break; + case '!': ret |= R_OP_BG; op++; break; + case '^': ret |= R_OP_UP; op++; break; + case '-': ret |= R_OP_MI; op++; break; + case '|': ret |= R_OP_OR; op++; break; + + default : ret = 0; /* an invalid modifier, chuck whole string */ + } + + if( *op != '\0' ) ret = 0; + } + + DB_RETURN( ret ); +} + + +PUBLIC void +Add_recipe_to_list( rule, white_too, no_check )/* +================================================= + Take the provided string and add it to the list of recipe lines + we are saving to be added to the list of targets we have built + previously. If white_too == TRUE add the rule EVEN IF it contains only + whitespace. */ +char *rule; +int white_too; +int no_check; +{ + DB_ENTER( "Add_recipe_to_list" ); + + if( rule != NIL( char ) && (*rule != '\0' || white_too) ) { + DB_PRINT( "par", ("Adding recipe [%s]", rule) ); + _sv_crule = Def_recipe( rule, _sv_crule, white_too, no_check ); + + if( _sv_rules == NIL(STRING) ) + _sv_rules = _sv_crule; + } + + DB_VOID_RETURN; +} + + +PUBLIC void +Bind_rules_to_targets( flag )/* +=============================== + Take the rules we have defined and bind them with proper attributes + to the targets that were previously defined in the parse. The + attributes that get passed here are merged with those that are were + previously defined. (namely F_SINGLE) */ +int flag; +{ + CELLPTR tg; /* pointer to current target in list */ + LINKPTR lp; /* pointer to link cell */ + int magic; /* TRUE if target is .xxx.yyy form */ + int tflag; /* TRUE if we assigned targets here */ + + DB_ENTER( "Bind_rules_to_targets" ); + + /* This line is needed since Parse may call us twice when the last + * GROUP rule appears at the end of file. In this case the rules + * have already been bound and we want to ignore them. */ + + if( _sv_targets == NIL(CELL) ) { DB_VOID_RETURN; } + + tflag = FALSE; + flag |= (_sv_flag & F_SINGLE); + flag |= ((_sv_attr & A_GROUP) ? F_GROUP : 0); + + for( tg = _sv_targets; tg != NIL(CELL); tg = tg->ce_link ) { + DB_PRINT( "par", ("Binding to %s, %04x", tg->CE_NAME, tg->ce_flag) ); + magic = tg->ce_flag & F_PERCENT; + +#if 0 + /* Check to see if we had a rule of the form '%.o : a.h b.h ; xxx' + * In which case we must build a NULL prq node to hold the recipe */ + if( _sv_globprq_only && (_sv_rules != NIL(STRING)) ) + _build_graph( _sv_op, tg, NIL(CELL) ); +#endif + + /* NOTE: For targets that are magic we ignore any previously defined + * rules. ie. We throw away the old definition and use the new.*/ + if( !(tg->ce_flag & F_MULTI) && !magic && (tg->CE_RECIPE != NIL(STRING)) + && !_sp_target && (_sv_rules != NIL(STRING)) ) + Fatal( "Multiply defined recipe for target %s", tg->CE_NAME ); + + if( (magic || _sp_target) && (_sv_rules == NIL(STRING)) && + !(tg->ce_flag & F_SPECIAL) && !_sv_globprq_only ) + Warning( "Empty recipe for special target %s", tg->CE_NAME ); + + if( magic ) { + CELLPTR ep; + + for( ep=_sv_edgel; ep != NIL(CELL); ep=ep->ce_link ) { + _set_attributes( _sv_attr, _sv_setdir, ep ); + ep->ce_flag |= (F_TARGET|flag); + + if( _sv_rules != NIL(STRING) ) { + ep->ce_recipe = _sv_rules; + ep->ce_indprq = _sv_glb_prq; + } + } + } + else { + tg->ce_attr |= _sv_attr; + tg->ce_flag |= flag; + + if( _sv_rules != NIL(STRING) ) { + tg->ce_recipe = _sv_rules; + tg->ce_flag |= F_RULES | F_TARGET; + + /* Bind the current set of prerequisites as belonging to the + * original recipe given for the target */ + for( lp=tg->ce_prq; lp != NIL(LINK); lp = lp->cl_next ) + if( !(lp->cl_flag & F_USED) ) lp->cl_flag |= F_TARGET; + } + else for( lp=tg->ce_prq; lp != NIL(LINK); lp = lp->cl_next ) + lp->cl_flag |= F_USED; + } + + tflag |= _add_root(tg); + } + + if( tflag ) Target = TRUE; + if( _sv_setdir ) FREE(_sv_setdir); + _sv_rules = NIL(STRING); + _sv_crule = NIL(STRING); + _sv_targets = NIL(CELL); + _sv_glb_prq = NIL(LINK); + _sv_edgel = NIL(CELL); + _sp_target = FALSE; + _sv_globprq_only = 0; + + DB_VOID_RETURN; +} + + + +PUBLIC int +Set_group_attributes( list )/* +============================== + Scan list looking for the standard @ and - (as in recipe line defs) + and set the flags accordingly so that they apply when we bind the + rules to the appropriate targets. */ +char *list; +{ + int res = FALSE; + + if ( !((_sv_attr|Glob_attr)&A_IGNOREGROUP) ) { + res = (*DmStrSpn(list,"@-%+ \t") == '['); + if( res ) _sv_attr |= Rcp_attribute(list); + } + + return(res); +} + + +static void +_do_special( special, op, attr, set_dir, target, prereq, state )/* +================================================================== + Process a special target. So far the only special targets we have + are those recognized by the _is_special function. + + target is always only a single special target. + + NOTE: For the cases of .IMPORT, and .INCLUDE, the cells created by the + parser are never freed. This is due to the fact that it is too much + trouble to get them out of the hash table once they are defined, and + if they are per chance used again it will be ok, anyway, since the + cell is not really used by the code below. */ + +int special; +int op; +t_attr attr; +char *set_dir; +CELLPTR target; +CELLPTR prereq; +int *state; +{ + HASHPTR hp; /* pointer to macro def cell */ + CELLPTR cp; /* temporary pointer into cells list */ + CELLPTR dp; /* pointer to directory dir cell */ + LINKPTR lp; /* pointer at prerequisite list */ + char *dir; /* current dir to prepend */ + char *path; /* resulting path to try to read */ + char *name; /* File name for processing a .INCLUDE */ + char *tmp; /* temporary string pointer */ + FILE *fil; /* File descriptor returned by Openfile */ + + DB_ENTER( "_do_special" ); + + target->ce_flag = F_SPECIAL; /* mark the target as special */ + + switch( special ) { + case ST_EXPORT: + for( ; prereq != NIL(CELL); prereq = prereq->ce_link ) { + DB_PRINT( "par", ("Exporting [%s]", prereq->CE_NAME) ); + hp = GET_MACRO( prereq->CE_NAME ); + + if( hp != NIL(HASH) ) { + char *tmpstr = hp->ht_value; + + if( tmpstr == NIL(char) ) tmpstr = ""; + + if( Write_env_string( prereq->CE_NAME, tmpstr ) != 0 ) + Warning( "Could not export %s", prereq->CE_NAME ); + } + } + break; + + /* Simply cause the parser to fail on the next input read */ + case ST_EXIT: + Skip_to_eof = TRUE; + break; + + case ST_IMPORT: + for( ; prereq != NIL(CELL); prereq = prereq->ce_link ) { + char *tmpstr; + + DB_PRINT( "par", ("Importing [%s]", prereq->CE_NAME) ); + + if( strcmp(prereq->CE_NAME, ".EVERYTHING") == 0 ) { + t_attr sattr = Glob_attr; + Glob_attr |= A_SILENT; + + ReadEnvironment(); + + Glob_attr = sattr; + } + else { + tmpstr = Read_env_string( prereq->CE_NAME ); + + if( tmpstr != NIL(char) ) + Def_macro(prereq->CE_NAME, tmpstr, M_EXPANDED|M_LITERAL); + else + if( !((Glob_attr | attr) & A_IGNORE) ) + Fatal("Imported macro `%s' not found",prereq->CE_NAME); + } + } + + attr &= ~A_IGNORE; + break; + + case ST_INCLUDE: + { + int pushed = FALSE; + int first = (attr & A_FIRST); + int ignore = (((Glob_attr | attr) & A_IGNORE) != 0); + int found = FALSE; + int noinf = (attr & A_NOINFER); + LINKPTR prqlnk = NIL(LINK); + LINKPTR prqlst = NIL(LINK); + + if( prereq == NIL(CELL) ) Fatal( "No .INCLUDE file(s) specified" ); + + dp = Def_cell( ".INCLUDEDIRS" ); + + if( (attr & A_SETDIR) && *(dir = strchr(set_dir, '=')+1) ) + pushed = Push_dir( dir, ".INCLUDE", ignore ); + + for( cp=prereq; cp != NIL(CELL); cp = cp->ce_link ) { + LINKPTR ltmp; + TALLOC(ltmp, 1, LINK); + ltmp->cl_prq = cp; + + if( prqlnk == NIL(LINK) ) + prqlst = ltmp; + else + prqlnk->cl_next = ltmp; + + prqlnk = ltmp; + } + + for( ; prqlst != NIL(LINK); FREE(prqlst), prqlst=prqlnk ) { + prqlnk = prqlst->cl_next; + cp = prqlst->cl_prq; + name = cp->CE_NAME; + + /* Leave this here, it ensures that prqlst gets propely free'd */ + if ( first && found ) + continue; + + if( *name == '<' ) { + /* We have a file name enclosed in <....> + * so get rid of the <> arround the file name */ + + name++; + if( (tmp = strrchr( name, '>' )) != NIL( char ) ) + *tmp = 0; + + if( If_root_path( name ) ) + fil = Openfile( name, FALSE, FALSE ); + else + fil = NIL(FILE); + } + else + fil = Openfile( name, FALSE, FALSE ); + + if( fil == NIL(FILE) ) { /*if true ==> not found in current dir*/ + + /* Now we must scan the list of prerequisites for .INCLUDEDIRS + * looking for the file in each of the specified directories. + * if we don't find it then we issue an error. The error + * message is suppressed if the .IGNORE attribute of attr is + * set. If a file is found we call Parse on the file to + * perform the parse and then continue on from where we left + * off. */ + + for(lp=dp->CE_PRQ; lp && fil == NIL(FILE); lp=lp->cl_next) { + dir = lp->cl_prq->CE_NAME; + if( strchr(dir, '$') ) dir = Expand(dir); + path = Build_path( dir, name ); + + DB_PRINT( "par", ("Trying to include [%s]", path) ); + + fil = Openfile( path, FALSE, FALSE ); + if( dir != lp->cl_prq->CE_NAME ) FREE(dir); + } + } + + if (!noinf && fil == NIL(FILE)) { + t_attr glob = Glob_attr; + t_attr cattr = prqlst->cl_prq->ce_attr; + + prqlst->cl_next = NIL(LINK); + Glob_attr |= ((attr&A_IGNORE)|A_SILENT); + prqlst->cl_prq->ce_attr &= ~A_FRINGE; + + fil = TryFiles(prqlst); + + Glob_attr = glob; + prqlst->cl_prq->ce_attr |= (cattr & A_FRINGE); + } + + if( fil != NIL(FILE) ) { + Parse( fil ); + found = TRUE; + } + else if( !(ignore || first) ) + Fatal( "Include file %s, not found", name ); + } + + if ( !ignore && first && !found ) + Fatal( "No include file was found" ); + + if( pushed ) Pop_dir(FALSE); + attr &= ~(A_IGNORE|A_SETDIR|A_FIRST|A_NOINFER); + } + break; + + case ST_SOURCE: + /* case ST_SUFFIXES: */ + if( prereq != NIL(CELL) ) + _do_targets( op & (R_OP_CL | R_OP_MI | R_OP_UP), attr, set_dir, + target, prereq ); + else { + /* The old semantics of .SOURCE were that an empty list of + * prerequisites clears the .SOURCE list. So we must implement + * that here as a clearout prerequisite operation. Since this is + * a standard operation with the :- opcode we can simply call the + * proper routine with the target cell and it should do the trick + */ + + if( op == R_OP_CL || (op & R_OP_MI) ) + Clear_prerequisites( target ); + } + + op &= ~(R_OP_MI | R_OP_UP); + break; + + case ST_KEEP: + if( Keep_state != NIL(char) ) break; + Def_macro( ".KEEP_STATE", "_state.mk", M_EXPANDED ); + break; + + case ST_REST: + /* The rest of the special targets can all take rules, as such they + * must be able to affect the state of the parser. */ + + { + int s_targ = Target; + + Target = TRUE; + _sp_target = TRUE; + *state = _do_targets( op, attr, set_dir, target, prereq ); + Target = s_targ; + + target->ce_flag |= F_TARGET; + + attr = A_DEFAULT; + op = R_OP_CL; + } + break; + + default:break; + } + + if( op != R_OP_CL ) Warning( "Modifier(s) for operator ignored" ); + if( attr != A_DEFAULT ) Warning( "Extra attributes ignored" ); + + DB_VOID_RETURN; +} + + + +static int +_do_targets( op, attr, set_dir, targets, prereq )/* +================================================= */ +int op; +t_attr attr; +char *set_dir; +CELLPTR targets; +CELLPTR prereq; +{ + CELLPTR tg1; /* temporary target pointer */ + CELLPTR tp1; /* temporary prerequisite pointer */ + LINKPTR prev_cell; /* pointer for .UPDATEALL processing */ + char *p; /* temporary char pointer */ + int tflag = FALSE; /* set to TRUE if we add target to root */ + + DB_ENTER( "_do_targets" ); + + if( attr & A_UPDATEALL ) { + if( targets == NIL(CELL) ) + Fatal( ".UPDATEALL attribute requires non-empty list of targets" ); + + if (targets->ce_set == NIL(CELL)) { + for( + prev_cell=CeMeToo(targets),tg1=targets->ce_link; + tg1 != NIL(CELL); + tg1=tg1->ce_link + ) { + if (tg1->ce_set) + Fatal( "Target [%s] appears on multiple .UPDATEALL lists", + tg1->CE_NAME); + tg1->ce_set = targets; + TALLOC(prev_cell->cl_next, 1, LINK); + prev_cell = prev_cell->cl_next; + prev_cell->cl_prq = tg1; + } + targets->ce_set = targets; + } + else { + LINKPTR ap; + CELLPTR tp; + + tp = targets; + ap = CeMeToo(targets); + while (ap && tp && ap->cl_prq == tp && tp->ce_set == targets) { + ap = ap->cl_next; + tp = tp->ce_link; + } + if (ap || tp) + Fatal("Inconsistent .UPDATEALL lists for target [%s]", + targets->CE_NAME); + } + targets->ce_link = NIL(CELL); + } + + for( tg1 = targets; tg1 != NIL(CELL); tg1 = tg1->ce_link ) { + /* Check each target. Check for inconsistencies between :: and : rule + * sets. :: may follow either : or :: but not the reverse. + * + * Any targets that contain :: rules are represented by a prerequisite + * list hanging off the main target cell where each of the prerequisites + * is a copy of the target cell but is not entered into the hash table. + */ + int magic = (tg1->ce_flag & F_PERCENT) && !(tg1->ce_flag & F_MAGIC); + + if( !(op & R_OP_DCL ) && (tg1->ce_flag & F_MULTI) && !magic ) + Fatal( "':' vs '::' inconsistency in rules for %s", tg1->CE_NAME ); + + if( magic ) { + if (op & R_OP_OR) + for(tp1=prereq; tp1; tp1=tp1->ce_link) { + CELLPTR tmpcell = tp1->ce_link; + tp1->ce_link = NIL(CELL); + _build_graph(op,tg1,tp1); + tp1->ce_link = tmpcell; + } + else + prereq = _build_graph(op,tg1,prereq); + } + else if( !(tg1->ce_flag & F_SPECIAL) && + (prereq == NIL(CELL)) && + (p = _is_magic( tg1->CE_NAME )) != NIL(char)) + _do_magic( op, p, tg1, prereq, attr, set_dir ); + else if( op & R_OP_DCL ) { + CELLPTR tmp_cell = _make_multi(tg1); + tflag |= _add_root(tg1); + targets = _replace_cell( targets, tg1, tmp_cell ); + tg1 = tmp_cell; + } + + if( !magic ) _set_attributes( attr, set_dir, tg1 ); + + /* Build the proper prerequisite list of the target. If the `-', + * modifier was used clear the prerequisite list before adding any + * new prerequisites. Else add them to the head/tail as appropriate. + * + * If the target has F_PERCENT set then no prerequisites are used. */ + + if( !(tg1->ce_flag & F_PERCENT) ) { + if( op & R_OP_MI ) Clear_prerequisites( tg1 ); + + if( (op & R_OP_UP) && (tg1->ce_prq != NIL(LINK)) ) + _stick_at_head( tg1, prereq ); + else for( tp1=prereq; tp1 != NIL(CELL); tp1 = tp1->ce_link ) + Add_prerequisite( tg1, tp1, FALSE, FALSE ); + } + else if( op & (R_OP_MI | R_OP_UP) ) + Warning( "Modifier(s) `^!' for %-meta target ignored" ); + } + + if(tflag) + Target = TRUE; + + /* Check to see if we have NO targets but some attributes. IF so then + * apply all of the attributes to the complete list of prerequisites. + */ + + if( (targets == NIL(CELL)) && attr ) + if( prereq != NIL(CELL) ) + for( tp1=prereq; tp1 != NIL(CELL); tp1 = tp1->ce_link ) + _set_attributes( attr, set_dir, tp1 ); + else + _set_global_attr( attr ); + + /* Now that we have built the lists of targets, the parser must parse the + * rules if there are any. However we must start the rule list with the + * rule specified as via the ; kludge, if there is one */ + _sv_targets = targets; + _sv_attr = attr; + _sv_flag = ((op & R_OP_BG) ? F_SINGLE : F_DEFAULT); + + DB_RETURN( RULE_SCAN ); +} + + +static int +_do_magic( op, dot, target, prereq, attr, set_dir )/* +===================================================== + This function takes a magic target of the form .<chars>.<chars> or + .<chars> and builds the appropriate % rules for that target. + + The function builds the % rule, `%.o : %.c' from .c.o, and + `%.a :' from .a */ + +int op; +char *dot; +CELLPTR target; +CELLPTR prereq; +t_attr attr; +char *set_dir; +{ + CELLPTR tg; + CELLPTR prq; + char *tmp, *tmp2; + + DB_ENTER( "_do_magic" ); + + if( prereq != NIL(CELL) ) + Warning( "Ignoring prerequisites of old style meta-target" ); + + if( dot == target->CE_NAME ) { /* its of the form .a */ + tg = Def_cell( "%" ); /* ==> no prerequisite */ + tmp = _build_meta( target->CE_NAME ); + prq = Def_cell( tmp ); + FREE( tmp ); + + _build_graph( op, tg, prq ); + } + else { + tmp = _build_meta( dot ); + tg = Def_cell( tmp ); + FREE( tmp ); + + tmp = _build_meta( tmp2 = DmSubStr( target->CE_NAME, dot ) ); + prq = Def_cell( tmp ); + FREE( tmp ); + FREE( tmp2 ); + + _build_graph( op, tg, prq ); + } + + tg->ce_flag |= F_PERCENT; + target->ce_flag |= (F_MAGIC|F_PERCENT); + + _set_attributes( attr, set_dir, tg ); + + DB_RETURN(1); +} + + +static CELLPTR +_replace_cell( lst, cell, rep ) +CELLPTR lst; +CELLPTR cell; +CELLPTR rep; +{ + register CELLPTR tp; + + if( lst == cell ) { + rep->ce_link = lst->ce_link; + lst = rep; + } + else { + for( tp=lst; tp->ce_link != cell; tp=tp->ce_link ); + rep->ce_link = tp->ce_link->ce_link; + tp->ce_link = rep; + } + + return(lst); +} + + +static char * +_build_meta( name )/* +===================== + Check to see if the name is of the form .c~ if so and if Augmake + translation is enabled then return s.%.c, else return %.suff, where if the + suffix ends in '~' then leave it be.*/ +char *name; +{ + char *tmp; + int test = (STOBOOL(Augmake) ? name[strlen(name)-1] == '~' : 0); + + tmp = DmStrJoin( test ? "s.%" : "%", name, -1, FALSE); + if( test ) tmp[ strlen(tmp)-1 ] = '\0'; + + return(tmp); +} + + +static CELLPTR +_build_graph( op, target, prereq )/* +==================================== + This function is called to build the graph for the % rule given by + target : prereq cell combination. This function assumes that target + is a % target and that prereq is a single % prerequisite. R_OP_CL + rules replace existing rules if any, only R_OP_CL works for meta-rules. + %.o :: %.c is meaningless. If target has ce_all set then all the cells + on the list must match in order for the match to work. If prereq->ce_link + is not nil then all prerequisites listed by the link set must match also. + This latter match is more difficult because in general the prerequisite + sets may not be listed in the same order. + + It also assumes that target cell has F_PERCENT set already. */ +int op; +CELLPTR target; +CELLPTR prereq; +{ + LINKPTR edl; + CELLPTR edge; + CELLPTR tpq,cur; + int match; + + DB_ENTER( "_build_graph" ); + DB_PRINT( "%", ("Building graph for [%s : %s]", target->CE_NAME, + (prereq == NIL(CELL)) ? "" : prereq->CE_NAME) ); + + tpq = NIL(CELL); + for(cur=prereq;cur;cur=cur->ce_link) { + char *name = cur->CE_NAME; + int len = strlen(name); + + if( *name == '\'' && name[len-1]=='\'' ){ + _add_global_prereq( cur ); + name[len-1] = '\0'; + strcpy(name,name+1); + } + else { + if (tpq) + tpq->ce_link = cur; + else + prereq = cur; + tpq = cur; + } + } + if(tpq) + tpq->ce_link=NIL(CELL); + else + prereq = NIL(CELL); + + /* Search the list of prerequisites for the current target and see if + * any of them match the current %-meta's : prereq's pair. NOTE that + * %-metas are built as if they were F_MULTI targets. */ + match = FALSE; + for(edl=target->ce_prq; !match && edl != NIL(LINK); edl=edl->cl_next) { + LINKPTR l1,l2; + edge = edl->cl_prq; + + DB_PRINT("%", ("Trying to match [%s]",edge?edge->CE_NAME:"(nil)")); + + /* First we match the target sets, if this fails then we don't have to + * bother with the prerequisite sets. The targets sets are sorted. + * this makes life very simple. */ + + l1 = CeMeToo(target); + l2 = CeMeToo(edge); + while(l1 && l2 && l1->cl_prq == l2->cl_prq) { + l1=l1->cl_next; + l2=l2->cl_next; + } + + if (l1 || l2) + continue; + + /* target sets match, so check prerequisites. */ + + if( (!edge->ce_prq && !prereq) + || ( edge->ce_prq + && ( edge->ce_dir == _sv_setdir + || ( edge->ce_dir + && _sv_setdir + && !strcmp(edge->ce_dir,strchr(_sv_setdir,'=')+1) + ) + ) + ) + ) { + LINKPTR prql; + + /* this is a really gross way to compare two sets, it's n^2 but + * since the sets are assumed to always be tiny, it should be ok. */ + for(tpq=prereq; tpq; tpq=tpq->ce_link) { + for(prql=edge->ce_prq;prql;prql=prql->cl_next) + if (prql->cl_prq == tpq) + break; + + if(prql == NIL(LINK)) + break; + + prql->cl_prq->ce_flag |= F_MARK; + } + + if (tpq == NIL(CELL)) { + for(prql=edge->ce_prq;prql;prql=prql->cl_next) + if(!(prql->cl_prq->ce_flag & F_MARK)) + break; + + if(prql == NIL(LINK)) + match = TRUE; + } + + /* clean up the mark bits. */ + for(prql=edge->ce_prq;prql;prql=prql->cl_next) + prql->cl_prq->ce_flag &= ~F_MARK; + } + } + + if( match ) { + /* match is TRUE hence, we found an edge joining the target and the + * prerequisite so reset the new edge so that new values replace it. */ + DB_PRINT( "%", ("It's an old edge") ); + + edge->ce_dir = NIL(char); + edge->ce_flag &= (F_PERCENT|F_MAGIC|F_DFA); + edge->ce_attr &= A_NOINFER; + } + else { + DB_PRINT( "%", ("Adding a new edge") ); + + edge = _make_multi(target); + + for(edl=CeMeToo(target);edl;edl=edl->cl_next) { + if( !((tpq=edl->cl_prq)->ce_flag & F_DFA) ) { + Add_nfa( tpq->CE_NAME ); + tpq->ce_flag |= F_DFA; + } + + edl->cl_prq->ce_set = edge; + } + + edge->ce_all = target->ce_all; + target->ce_all.cl_next = NIL(LINK); + target->ce_set = NIL(CELL); + + for(tpq=prereq; tpq; tpq=tpq->ce_link) + Add_prerequisite(edge, tpq, FALSE, TRUE); + } + + if( op & R_OP_DCL ) + Warning("'::' operator for meta-target '%s' ignored, ':' operator assumed.", + target->CE_NAME ); + + edge->ce_link = _sv_edgel; + _sv_edgel = edge; + _sv_globprq_only = 0; + + DB_RETURN(NIL(CELL)); +} + + +static CELLPTR +_make_multi( tg ) +CELLPTR tg; +{ + CELLPTR cp; + + /* This first handles the case when a : foo ; exists prior to seeing + * a :: fee; */ + if( !(tg->ce_flag & F_MULTI) && (tg->ce_prq || tg->ce_recipe) ) { + TALLOC(cp, 1, CELL); + *cp = *tg; + + tg->ce_prq = NIL(LINK); + tg->ce_flag |= F_RULES|F_MULTI|F_TARGET; + tg->ce_attr |= A_SEQ; + tg->ce_recipe = NIL(STRING); + tg->ce_dir = NIL(char); + cp->ce_count = ++tg->ce_index; + cp->ce_cond = NIL(STRING); + cp->ce_set = NIL(CELL); + cp->ce_all.cl_prq = cp; + CeNotMe(cp) = NIL(LINK); + + Add_prerequisite(tg, cp, FALSE, TRUE); + } + + TALLOC(cp, 1, CELL); + *cp = *tg; + + if( !(tg->ce_flag & F_MULTI) ) { + tg->ce_prq = NIL(LINK); + tg->ce_flag |= F_RULES|F_MULTI|F_TARGET; + tg->ce_attr |= A_SEQ; + tg->ce_recipe = NIL(STRING); + tg->ce_dir = NIL(char); + cp->ce_cond = NIL(STRING); + } + else { + cp->ce_flag &= ~(F_RULES|F_MULTI); + cp->ce_attr &= ~A_SEQ; + cp->ce_prq = NIL(LINK); + cp->ce_index = 0; + cp->ce_cond = NIL(STRING); + } + cp->ce_count = ++tg->ce_index; + cp->ce_flag |= F_TARGET; + cp->ce_set = NIL(CELL); + cp->ce_all.cl_prq = cp; + CeNotMe(cp) = NIL(LINK); + + Add_prerequisite(tg, cp, FALSE, TRUE); + return(cp); +} + + +static void +_add_global_prereq( pq )/* +========================== + Prerequisite is a non-% prerequisite for a %-rule target, add it to + the target's list of global prerequsites to add on match */ +CELLPTR pq; +{ + register LINKPTR ln; + + for(ln=_sv_glb_prq; ln; ln=ln->cl_next) + if(strcmp(ln->cl_prq->CE_NAME,pq->CE_NAME) == 0) + return; + + TALLOC( ln, 1, LINK ); + ln->cl_next = _sv_glb_prq; + ln->cl_prq = pq; + _sv_glb_prq = ln; +} + + + +static void +_set_attributes( attr, set_dir, cp )/* +====================================== + Set the appropriate attributes for a cell */ +t_attr attr; +char *set_dir; +CELLPTR cp; +{ + char *dir; + + DB_ENTER( "_set_attributes" ); + + /* If .SETDIR attribute is set then we have at least .SETDIR= in the + * set_dir string. So go and fishout what is at the end of the =. + * If not set and not NULL then propagate it to the target cell. */ + + if( attr & A_SETDIR ) { + char *p; + if( (p = strchr( set_dir, '=' )) != NULL ) + dir = p + 1; + + if( cp->ce_dir ) + Warning( "Multiple .SETDIR for %s ignored", cp->CE_NAME ); + else if( *dir ) + cp->ce_dir = DmStrDup(dir); + } + cp->ce_attr |= attr; /* set rest of attributes for target */ + + DB_VOID_RETURN; +} + + + +static void +_set_global_attr( attr )/* +========================== + Handle the setting of the global attribute functions based on + The attribute flags set in attr. */ +t_attr attr; +{ + t_attr flag; + + /* Some compilers can't handle a switch on a long, and t_attr is now a long + * integer on some systems. foey! */ + for( flag = MAX_ATTR; flag; flag >>= 1 ) + if( flag & attr ) + if( flag == A_PRECIOUS) Def_macro(".PRECIOUS", "y", M_EXPANDED); + else if( flag == A_SILENT) Def_macro(".SILENT", "y", M_EXPANDED); + else if( flag == A_IGNORE ) Def_macro(".IGNORE", "y", M_EXPANDED); + else if( flag == A_EPILOG ) Def_macro(".EPILOG", "y", M_EXPANDED); + else if( flag == A_PROLOG ) Def_macro(".PROLOG", "y", M_EXPANDED); + else if( flag == A_NOINFER ) Def_macro(".NOINFER", "y", M_EXPANDED); + else if( flag == A_SEQ ) Def_macro(".SEQUENTIAL","y", M_EXPANDED); + else if( flag == A_SHELL ) Def_macro(".USESHELL", "y", M_EXPANDED); + else if( flag == A_MKSARGS ) Def_macro(".MKSARGS", "y", M_EXPANDED); + else if( flag == A_SWAP ) Def_macro(".SWAP", "y", M_EXPANDED); + + attr &= ~A_GLOB; + if( attr ) Warning( "Non global attribute(s) ignored" ); +} + + + +static void +_stick_at_head( cp, pq )/* +========================== + Add the prerequisite list to the head of the existing prerequisite + list */ + +CELLPTR cp; /* cell for target node */ +CELLPTR pq; /* list of prerequisites to add */ +{ + DB_ENTER( "_stick_at_head" ); + + if( pq->ce_link != NIL(CELL) ) _stick_at_head( cp, pq->ce_link ); + Add_prerequisite( cp, pq, TRUE, FALSE ); + + DB_VOID_RETURN; +} + + + +static t_attr +_is_attribute( name )/* +======================= + Check the passed name against the list of valid attributes and return the + attribute index if it is, else return 0, indicating the name is not a valid + attribute. The present attributes are defined in dmake.h as A_xxx #defines, + with the corresponding makefile specification: (note they must be named + exactly as defined below) + + Valid attributes are: .IGNORE, .SETDIR=, .SILENT, .PRECIOUS, .LIBRARY, + .EPILOG, .PROLOG, .LIBRARYM, .SYMBOL, .UPDATEALL, + .USESHELL, .NOINFER, .PHONY, .SWAP, .SEQUENTIAL + .NOSTATE, .MKSARGS, .IGNOREGROUP, .GROUP, .FIRST + .EXECUTE, .ERRREMOVE + + NOTE: The strcmp's are OK since at most three are ever executed for any + one attribute check, and that happens only when we can be fairly + certain we have an attribute. */ +char *name; +{ + t_attr attr = 0; + + DB_ENTER( "_is_attribute" ); + + if( *name++ == '.' ) + switch( *name ) + { + case 'E': + if( !strcmp(name, "EPILOG") ) attr = A_EPILOG; + else if( !strcmp(name, "EXECUTE")) attr = A_EXECUTE; + else if( !strcmp(name, "ERRREMOVE")) attr = A_ERRREMOVE; + else attr = 0; + break; + + /* A_FIRST implies A_IGNORE, handled in ST_INCLUDE */ + case 'F': + attr = (strcmp(name, "FIRST")) ? 0 : A_FIRST; + break; + + case 'G': attr = (strcmp(name, "GROUP")) ? 0 : A_GROUP; break; + case 'L': attr = (strcmp(name, "LIBRARY")) ? 0 : A_LIBRARY; break; + case 'M': attr = (strcmp(name, "MKSARGS")) ? 0 : A_MKSARGS; break; + + case 'I': + if( !strcmp(name, "IGNORE") ) attr = A_IGNORE; + else if( !strcmp(name, "IGNOREGROUP")) attr = A_IGNOREGROUP; + else attr = 0; + break; + + case 'N': + if( !strcmp(name, "NOINFER") ) attr = A_NOINFER; + else if( !strcmp(name, "NOSTATE")) attr = A_NOSTATE; + else attr = 0; + break; + + case 'U': + if( !strcmp(name, "UPDATEALL") ) attr = A_UPDATEALL; + else if( !strcmp(name, "USESHELL")) attr = A_SHELL; + else attr = 0; + break; + + case 'P': + if( !strcmp(name, "PRECIOUS") ) attr = A_PRECIOUS; + else if( !strcmp(name, "PROLOG") ) attr = A_PROLOG; + else if( !strcmp(name, "PHONY") ) attr = A_PHONY; + else attr = 0; + break; + + case 'S': + if( !strncmp(name, "SETDIR=", 7) ) attr = A_SETDIR; + else if( !strcmp(name, "SILENT") ) attr = A_SILENT; + else if( !strcmp(name, "SYMBOL") ) attr = A_SYMBOL; + else if( !strcmp(name, "SEQUENTIAL")) attr = A_SEQ; + else if( !strcmp(name, "SWAP")) attr = A_SWAP; + else attr = 0; + break; + } + + DB_RETURN( attr ); +} + + + +static int +_is_special( tg )/* +=================== + This function returns TRUE if the name passed in represents a special + target, otherwise it returns false. A special target is one that has + a special meaning to dmake, and may require processing at the time that + it is parsed. + + Current Special targets are: + .GROUPPROLOG .GROUPEPILOG .INCLUDE .IMPORT + .EXPORT .SOURCE .SUFFIXES .ERROR .EXIT + .INCLUDEDIRS .MAKEFILES .REMOVE .KEEP_STATE +*/ +char *tg; +{ + DB_ENTER( "_is_special" ); + + if( *tg++ != '.' ) DB_RETURN( 0 ); + + switch( *tg ) + { + case 'E': + if( !strcmp( tg, "ERROR" ) ) DB_RETURN( ST_REST ); + else if( !strcmp( tg, "EXPORT" ) ) DB_RETURN( ST_EXPORT ); + else if( !strcmp( tg, "EXIT" ) ) DB_RETURN( ST_EXIT ); + break; + + case 'G': + if( !strcmp( tg, "GROUPPROLOG" )) DB_RETURN( ST_REST ); + else if( !strcmp( tg, "GROUPEPILOG" )) DB_RETURN( ST_REST ); + break; + + case 'I': + if( !strcmp( tg, "IMPORT" ) ) DB_RETURN( ST_IMPORT ); + else if( !strcmp( tg, "INCLUDE" ) ) DB_RETURN( ST_INCLUDE ); + else if( !strcmp( tg, "INCLUDEDIRS" )) DB_RETURN( ST_REST ); + break; + + case 'K': + if( !strcmp( tg, "KEEP_STATE" ) ) DB_RETURN( ST_KEEP ); + break; + + case 'M': + if( !strcmp( tg, "MAKEFILES" ) ) DB_RETURN( ST_REST ); + break; + + case 'R': + if( !strcmp( tg, "REMOVE" ) ) DB_RETURN( ST_REST ); + break; + + case 'S': + if( !strncmp( tg, "SOURCE", 6 ) ) DB_RETURN( ST_SOURCE ); + else if( !strncmp(tg, "SUFFIXES", 8 )) DB_RETURN( ST_SOURCE ); + break; + } + + DB_RETURN( 0 ); +} + + + +static int +_is_percent( np )/* +=================== + return TRUE if np points at a string containing a % sign */ +char *np; +{ + return( (strchr(np,'%') && (*np != '\'' && np[strlen(np)-1] != '\'')) ? + TRUE : FALSE ); +} + + +static char * +_is_magic( np )/* +================= + return TRUE if np points at a string of the form + .<chars>.<chars> or .<chars> + where chars are only alpha characters. + + NOTE: reject target if it begins with ./ or ../ */ +char *np; +{ + register char *n; + + n = np; + if( *n != '.' ) return( NIL(char) ); + if (strchr(DirBrkStr, *(n+1))!=NULL || *(n+1) == '.' ) + return (NIL(char)); + + for( n++; isgraph(*n) && (*n != '.'); n++ ); + + if( *n != '\0' ) { + if( *n != '.' ) return( NIL(char) ); + for( np = n++; isgraph( *n ) && (*n != '.'); n++ ); + if( *n != '\0' ) return( NIL(char) ); + } + else if( STOBOOL(Augmake) ) + return( NIL(char) ); + + /* np points at the second . of .<chars>.<chars> string. + * if the special target is of the form .<chars> then np points at the + * first . in the token. */ + + return( np ); +} + + +static int +_add_root(tg) +CELLPTR tg; +{ + int res = FALSE; + + if(tg == Targets) + return(TRUE); + + if( !Target && !(tg->ce_flag & (F_SPECIAL|F_PERCENT)) ) { + Add_prerequisite(Targets, tg, FALSE, TRUE); + + tg->ce_flag |= F_TARGET; + tg->ce_attr |= A_FRINGE; + res = TRUE; + } + + return(res); +} diff --git a/dmake/startup/mac/macros.mk b/dmake/startup/mac/macros.mk new file mode 100644 index 000000000000..ca161a8baa5c --- /dev/null +++ b/dmake/startup/mac/macros.mk @@ -0,0 +1,41 @@ +# Define MPW MAC specific macros. +# Assumes CodeWarrior for Mac 5.0 C, change as needed. +# + +A *:= .lib +S *:= .s +V *:= v +TMPDIR *:= $(TempFolder) + +# import library definitions +.IMPORT .IGNORE : CLibraries Libraries + +# Set arguments for the SHELL. Since we can't execute sub-processes, +# these variables are not important, except for some makefiles that check +# for some values to determine the platform. +SHELL *:= "{MPW}MPW Shell" +SHELLFLAGS *:= +GROUPFLAGS *:= +SHELLMETAS *:= + +# Define toolkit macros +CC *:= MWCPPC +AS *:= PPCAsm +LD *:= MWLinkPPC +AR *:= +ARFLAGS *:= +RM *:= delete +RMFLAGS *:= +MV *:= rename +YTAB *:= +LEXYY *:= + +LDLIBS *= "{SharedLibraries}StdCLib" "{SharedLibraries}InterfaceLib" \ + "{PPCLibraries}StdCRuntime.o" "{PPCLibraries}PPCCRuntime.o" \ + "{Libraries}MathLib.o" "{PPCLibraries}PPCToolLibs.o" + +# Disable the print command +PRINT *= + +# Make certain to disable defining how to make executables. +__.EXECS !:= diff --git a/dmake/startup/msdos/borland/bcc30/macros.mk b/dmake/startup/msdos/borland/bcc30/macros.mk new file mode 100644 index 000000000000..599ba52c0a61 --- /dev/null +++ b/dmake/startup/msdos/borland/bcc30/macros.mk @@ -0,0 +1,4 @@ +# MSDOS Borland-C customization. + +# Standard C-language command names and flags +CC *:= bcc # C compiler diff --git a/dmake/startup/msdos/borland/bcc40/macros.mk b/dmake/startup/msdos/borland/bcc40/macros.mk new file mode 100644 index 000000000000..599ba52c0a61 --- /dev/null +++ b/dmake/startup/msdos/borland/bcc40/macros.mk @@ -0,0 +1,4 @@ +# MSDOS Borland-C customization. + +# Standard C-language command names and flags +CC *:= bcc # C compiler diff --git a/dmake/startup/msdos/borland/bcc45/macros.mk b/dmake/startup/msdos/borland/bcc45/macros.mk new file mode 100644 index 000000000000..599ba52c0a61 --- /dev/null +++ b/dmake/startup/msdos/borland/bcc45/macros.mk @@ -0,0 +1,4 @@ +# MSDOS Borland-C customization. + +# Standard C-language command names and flags +CC *:= bcc # C compiler diff --git a/dmake/startup/msdos/borland/bcc50.32/macros.mk b/dmake/startup/msdos/borland/bcc50.32/macros.mk new file mode 100644 index 000000000000..599ba52c0a61 --- /dev/null +++ b/dmake/startup/msdos/borland/bcc50.32/macros.mk @@ -0,0 +1,4 @@ +# MSDOS Borland-C customization. + +# Standard C-language command names and flags +CC *:= bcc # C compiler diff --git a/dmake/startup/msdos/borland/bcc50/macros.mk b/dmake/startup/msdos/borland/bcc50/macros.mk new file mode 100644 index 000000000000..599ba52c0a61 --- /dev/null +++ b/dmake/startup/msdos/borland/bcc50/macros.mk @@ -0,0 +1,4 @@ +# MSDOS Borland-C customization. + +# Standard C-language command names and flags +CC *:= bcc # C compiler diff --git a/dmake/startup/msdos/borland/macros.mk b/dmake/startup/msdos/borland/macros.mk new file mode 100644 index 000000000000..1e8915171ff1 --- /dev/null +++ b/dmake/startup/msdos/borland/macros.mk @@ -0,0 +1,33 @@ +# MSDOS Borland-C environment customization. + +.IF $(OSENVIRONMENT) + .INCLUDE .IGNORE .NOINFER : $(INCFILENAME:d)$(OSENVIRONMENT)$/macros.mk +.ENDIF + +# Standard C-language command names and flags +CPP *:= # C-preprocessor +CFLAGS *= # C compiler flags +"C++" *:= # C++ Compiler +"C++FLAGS" *= # C++ Compiler flags + +AS *:= tasm # Assembler and flags +ASFLAGS *= +LD *= tlink # Loader and flags +LDFLAGS *= +LDLIBS *= # Default libraries +AR *:= tlib # archiver +ARFLAGS *= ???? + +# Definition of Print command for this system. +PRINT *= print + +# Language and Parser generation Tools and their flags +YACC *:= yacc # standard yacc +YFLAGS *= +LEX *:= lex # standard lex +LFLAGS *= + +# Other Compilers, Tools and their flags +PC *:= tpc # pascal compiler +RC *:= ??? # ratfor compiler +FC *:= ??? # fortran compiler diff --git a/dmake/startup/msdos/borland/tcc20/macros.mk b/dmake/startup/msdos/borland/tcc20/macros.mk new file mode 100644 index 000000000000..7d922e44d03a --- /dev/null +++ b/dmake/startup/msdos/borland/tcc20/macros.mk @@ -0,0 +1,4 @@ +# MSDOS Turbo-C customization. + +# Standard C-language command names and flags +CC *:= tcc # C compiler diff --git a/dmake/startup/msdos/macros.mk b/dmake/startup/msdos/macros.mk new file mode 100644 index 000000000000..320865ea94de --- /dev/null +++ b/dmake/startup/msdos/macros.mk @@ -0,0 +1,62 @@ +# Define additional MSDOS specific settings. +# + +# Execution environment configuration. +# Grab the current setting of COMSPEC. +# +.IMPORT .IGNORE : COMSPEC + +# First check if SHELL is defined to be something other than COMSPEC. +# If it is, then assume that SHELL is a Korn compatible shell like MKS's +.IF $(SHELL) == $(NULL) + .IF $(COMSPEC) == $(NULL) + SHELL *:= $(ROOTDIR)$/bin$/sh$E + .ELSE + SHELL *:= $(COMSPEC) + .END +.END +GROUPSHELL *:= $(SHELL) + +# Process release-specific refinements, if any. +.INCLUDE .NOINFER .IGNORE : $(INCFILENAME:d)$(OSRELEASE)$/macros.mk + +# Applicable suffix definitions +A *:= .lib # Libraries +E *:= .exe # Executables +F *:= .for # Fortran +O *:= .obj # Objects +P *:= .pas # Pascal +S *:= .asm # Assembler sources +V *:= # RCS suffix + +# Now set the remaining arguments depending on which SHELL we +# are going to use. COMSPEC (assumed to be command.com) or +# MKS Korn shell. +.IF $(SHELL) == $(COMSPEC) + SHELLFLAGS *:= $(SWITCHAR)c + GROUPFLAGS *:= $(SHELLFLAGS) + SHELLMETAS *:= "<>| + GROUPSUFFIX *:= .bat + DIVFILE *= $(TMPFILE:s,/,\) + RM *= del + RMFLAGS *= + MV *= rename + __.DIVSEP-sh-yes *:= \\ + __.DIVSEP-sh-no *:= \\ +.ELSE + SHELLFLAGS *:= -c + GROUPFLAGS *:= + SHELLMETAS *:= *";?<>|()&][$$\#`' + GROUPSUFFIX *:= .ksh + .MKSARGS *:= yes + RM *= $(ROOTDIR)$/bin$/rm + RMFLAGS *= -f + MV *= $(ROOTDIR)$/bin$/mv + DIVFILE *= $(TMPFILE:s,/,${__.DIVSEP-sh-${USESHELL}}) + __.DIVSEP-sh-yes *:= \\\ + __.DIVSEP-sh-no *:= \\ +.ENDIF + + +# Does not respect case of filenames. +.DIRCACHERESPCASE := no diff --git a/dmake/startup/msdos/microsft/macros.mk b/dmake/startup/msdos/microsft/macros.mk new file mode 100644 index 000000000000..3891f84fde21 --- /dev/null +++ b/dmake/startup/msdos/microsft/macros.mk @@ -0,0 +1,34 @@ +# MSDOS Microsoft-C environment customization. + +.IF $(OSENVIRONMENT) + .INCLUDE .IGNORE .NOINFER : $(INCFILENAME:d)$(OSENVIRONMENT)$/macros.mk +.ENDIF + +# Standard C-language command names and flags +CC *:= cl # C compiler +CPP *:= # C-preprocessor +CFLAGS *= # C compiler flags +"C++" *:= # C++ Compiler +"C++FLAGS" *= # C++ Compiler flags + +AS *:= masm # Assembler and flags +ASFLAGS *= +LD *= link # Loader and flags +LDFLAGS *= +LDLIBS *= # Default libraries +AR *:= lib # archiver +ARFLAGS *= ???? + +# Definition of Print command for this system. +PRINT *= print + +# Language and Parser generation Tools and their flags +YACC *:= yacc # standard yacc +YFLAGS *= +LEX *:= lex # standard lex +LFLAGS *= + +# Other Compilers, Tools and their flags +PC *:= ??? # pascal compiler +RC *:= ??? # ratfor compiler +FC *:= ??? # fortran compiler diff --git a/dmake/startup/msdos/recipes.mk b/dmake/startup/msdos/recipes.mk new file mode 100644 index 000000000000..39a5965e844c --- /dev/null +++ b/dmake/startup/msdos/recipes.mk @@ -0,0 +1,9 @@ +# Define additional MSDOS specific build recipes. +# + +# Executables + %$E .SWAP : %$O ; $(CC) $(LDFLAGS) -o$@ $< $(LDLIBS) + %$O : %$S ; $(AS) $(ASFLAGS) $(<:s,/,\) + +# Process release-specific refinements, if any. +.INCLUDE .NOINFER .IGNORE : $(INCFILENAME:d)$(OSRELEASE)$/recipes.mk diff --git a/dmake/startup/msdos/zortech/macros.mk b/dmake/startup/msdos/zortech/macros.mk new file mode 100644 index 000000000000..f9166150f13d --- /dev/null +++ b/dmake/startup/msdos/zortech/macros.mk @@ -0,0 +1,30 @@ +# MSDOS Zortech-C environment customization. + +# Standard C-language command names and flags +CC *:= ztc # C compiler +CPP *:= # C-preprocessor +CFLAGS *= # C compiler flags +"C++" *:= # C++ Compiler +"C++FLAGS" *= # C++ Compiler flags + +AS *:= masm # Assembler and flags +ASFLAGS *= +LD *= blink # Loader and flags +LDFLAGS *= +LDLIBS *= # Default libraries +AR *:= ???? # archiver +ARFLAGS *= ???? + +# Definition of Print command for this system. +PRINT *= print + +# Language and Parser generation Tools and their flags +YACC *:= yacc # standard yacc +YFLAGS *= +LEX *:= lex # standard lex +LFLAGS *= + +# Other Compilers, Tools and their flags +PC *:= ??? # pascal compiler +RC *:= ??? # ratfor compiler +FC *:= ??? # fortran compiler diff --git a/dmake/startup/os2/ibm/macros.mk b/dmake/startup/os2/ibm/macros.mk new file mode 100644 index 000000000000..4b848d93cc4c --- /dev/null +++ b/dmake/startup/os2/ibm/macros.mk @@ -0,0 +1,30 @@ +# OS/2 1.3 and 2.1 specific customization. + +# Standard C-language command names and flags +CC *:= icc # C compiler +CPP *:= # C-preprocessor +CFLAGS *= # C compiler flags +"C++" *:= # C++ Compiler +"C++FLAGS" *= # C++ Compiler flags + +AS *:= masm # Assembler and flags +ASFLAGS *= +LD *= link386 # Loader and flags +LDFLAGS *= +LDLIBS *= # Default libraries +AR *:= lib # archiver +ARFLAGS *= ???? + +# Definition of Print command for this system. +PRINT *= print + +# Language and Parser generation Tools and their flags +YACC *:= yacc # standard yacc +YFLAGS *= +LEX *:= lex # standard lex +LFLAGS *= + +# Other Compilers, Tools and their flags +PC *:= ??? # pascal compiler +RC *:= ??? # ratfor compiler +FC *:= ??? # fortran compiler diff --git a/dmake/startup/os2/macros.mk b/dmake/startup/os2/macros.mk new file mode 100644 index 000000000000..a35df6ee4b8c --- /dev/null +++ b/dmake/startup/os2/macros.mk @@ -0,0 +1,60 @@ +# Define additional OS/2 specific macros. +# + +# Process release-specific refinements, if any. +.INCLUDE .NOINFER .IGNORE : $(INCFILENAME:d)$(OSRELEASE)$/macros.mk + +# Execution environment configuration. +# Grab the current setting of COMSPEC. +# +.IMPORT .IGNORE : COMSPEC + +# First check if SHELL is defined to be something other than COMSPEC. +# If it is assume that SHELL is a Korn compatible shell like MKS's +.IF $(SHELL) == $(NULL) + .IF $(COMSPEC) == $(NULL) + SHELL *:= $(ROOTDIR)$/bin$/sh$E + .ELSE + SHELL *:= $(COMSPEC) + .END +.END +GROUPSHELL *:= $(SHELL) + +# Directory entries are case incensitive +.DIRCACHERESPCASE *:= no + +# Applicable suffix definitions +A *:= .lib # Libraries +E *:= .exe # Executables +F *:= .for # Fortran +O *:= .obj # Objects +P *:= .pas # Pascal +S *:= .asm # Assembler sources +V *:= # RCS suffix + +# Now set the remaining arguments depending on which SHELL we +# are going to use. COMSPEC (assumed to be command.com) or +# MKS Korn shell. +.IF $(SHELL) == $(COMSPEC) + SHELLFLAGS *:= $(SWITCHAR)c + GROUPFLAGS *:= $(SHELLFLAGS) + SHELLMETAS *:= *"?<> + GROUPSUFFIX *:= .bat + DIRSEPSTR *:= \\\ + DIVFILE *= $(TMPFILE:s,/,\) + RM *= del + RMFLAGS *= + MV *= rename +.ELSE + SHELLFLAGS *:= -c + GROUPFLAGS *:= + SHELLMETAS *:= *"?<>|()&][$$\#`' + GROUPSUFFIX *:= .ksh + .MKSARGS *:= yes + RM *= $(ROOTDIR)$/bin$/rm + RMFLAGS *= -f + MV *= $(ROOTDIR)$/bin$/mv + DIVFILE *= $(TMPFILE:s,/,${__.DIVSEP-sh-${USESHELL}}) + __.DIVSEP-sh-yes !:= \\\ + __.DIVSEP-sh-no !:= \\ +.ENDIF diff --git a/dmake/startup/qssl/macros.mk b/dmake/startup/qssl/macros.mk new file mode 100644 index 000000000000..de89485e8541 --- /dev/null +++ b/dmake/startup/qssl/macros.mk @@ -0,0 +1,11 @@ +# QNX Specific macro definitions +# + +# Primary suffixes in common use +A *:= .lib # Libraries + +# Standard C-language command names and flags +AS *:= # Don't have an assembler + +AR *:= wlib # archiver +ARFLAGS *= diff --git a/dmake/startup/qssl/qnx/macros.mk b/dmake/startup/qssl/qnx/macros.mk new file mode 100644 index 000000000000..de89485e8541 --- /dev/null +++ b/dmake/startup/qssl/qnx/macros.mk @@ -0,0 +1,11 @@ +# QNX Specific macro definitions +# + +# Primary suffixes in common use +A *:= .lib # Libraries + +# Standard C-language command names and flags +AS *:= # Don't have an assembler + +AR *:= wlib # archiver +ARFLAGS *= diff --git a/dmake/startup/qssl/qnx/recipes.mk b/dmake/startup/qssl/qnx/recipes.mk new file mode 100644 index 000000000000..4458b43924a7 --- /dev/null +++ b/dmake/startup/qssl/qnx/recipes.mk @@ -0,0 +1,8 @@ +# Define additional QNX specific build recipes. +# + +# Recipe to make archive files. +# --Figure out what to do about the librarian-- +%$A .GROUP : + $(AR) $(ARFLAGS) $@ $? + $(RM) $(RMFLAGS) $? diff --git a/dmake/startup/qssl/recipes.mk b/dmake/startup/qssl/recipes.mk new file mode 100644 index 000000000000..4458b43924a7 --- /dev/null +++ b/dmake/startup/qssl/recipes.mk @@ -0,0 +1,8 @@ +# Define additional QNX specific build recipes. +# + +# Recipe to make archive files. +# --Figure out what to do about the librarian-- +%$A .GROUP : + $(AR) $(ARFLAGS) $@ $? + $(RM) $(RMFLAGS) $? diff --git a/dmake/startup/startup.mk b/dmake/startup/startup.mk new file mode 100644 index 000000000000..7e8b4aec9231 --- /dev/null +++ b/dmake/startup/startup.mk @@ -0,0 +1,209 @@ +# This is the root DMAKE startup file. +# +# Definitions common to all environments are given at the root. +# Definitions parameterized at the root have their parameters specified +# in sub-makefiles which are included based on the values of the three +# make variables: +# +# OS - core operating system flavour +# OSRELEASE - specific release of the operating system +# OSENVIRONMENT - software construction environment in use +# +# See the file 'summary', found in this directory for a list of +# environments supported by this release. + +# Disable warnings for macros given on the command line but redefined here. +__.silent !:= $(.SILENT) # Preserve user's .SILENT flag +.SILENT !:= yes + +# startup.mk configuration parameters, for each, set it to non-null if you wish +# to enable the named facility. +__.HAVE_RCS !:= yes # yes => RCS is installed. +__.HAVE_SCCS !:= # yes => SCCS is installed. +__.DEFAULTS !:= yes # yes => define default construction rules. +__.EXECS !:= yes # yes => define how to build executables. + +# Grab key definitions from the environment +.IMPORT .IGNORE : OS OSRELEASE OSENVIRONMENT TMPDIR SHELL + +# Default DMAKE configuration, if not overriden by environment +.INCLUDE .NOINFER $(!null,$(OS) .IGNORE) : $(INCFILENAME:d)config.mk + +# Look for a local defaults configuration +.INCLUDE .NOINFER .IGNORE : $(INCFILENAME:d)local.mk + +# Define the directory separator string. +/ *= $(DIRSEPSTR) + +# Customize macro definitions based on setings of OS, OSRELEASE and +# OSENVIRONMENT, this must come before the default macro definitions which +# follow. +.INCLUDE .NOINFER .IGNORE : $(INCFILENAME:d)$(OS)$/macros.mk + +# ----------------- Default Control Macro definitions ----------------------- +# Select appropriate defaults for basic macros + MAKE *= $(MAKECMD) -S $(MFLAGS) + TMPDIR *:= $/tmp + DIVFILE *= $(TMPFILE) + AUGMAKE *:= no + +# Recipe execution configuration + SHELL *:= $/bin$/sh + SHELLFLAGS *:= -ce + GROUPSHELL *:= $(SHELL) + GROUPFLAGS *:= + SHELLMETAS *:= |();&<>?*][$$:\\#`'" + GROUPSUFFIX *:= + +# Intermediate target removal configuration + RM *:= $/bin$/rm + RMFLAGS *= -f + RMTARGET *= $< + +# Default recipe that is used to remove intermediate targets. +.REMOVE :; $(RM) $(RMFLAGS) $(RMTARGET) + +# Check and enable AUGMAKE extensions for SYSV compatibility +.IF $(AUGMAKE) + "@B" != $(@:b) + "@D" != $(@:d) + "@F" != $(@:f) + "*B" != $(*:b) + "*D" != $(*:d) + "*F" != $(*:f) + "<B" != $(<:b) + "<D" != $(<:d) + "<F" != $(<:f) + "?B" != $(?:b) + "?F" != $(?:f) + "?D" != $(?:d) +.ENDIF + +# Directory caching configuration. + .DIRCACHE *:= yes + .DIRCACHERESPCASE *:= yes + +# Define the special NULL Prerequisite +NULLPRQ *:= __.NULLPRQ + +# ---------- Default Construction Macro and Rule definitions -------------- +# The construction rules may be customized further in subsequent recipes.mk +# files. +.IF $(__.DEFAULTS) + # Primary suffixes in common use + A *:= .a # Libraries + E *:= # Executables + F *:= .f # Fortran + O *:= .o # Objects + P *:= .p # Pascal + S *:= .s # Assembler sources + V *:= ,v # RCS suffix + YTAB *:= y.tab # name-stem for yacc output files. + LEXYY *:= lex.yy # lex output file + + # Standard C-language command names and flags + CPP *:= $/lib$/cpp # C-preprocessor + CC *:= cc # C compiler + CFLAGS *= # C compiler flags + "C++" *:= CC # C++ Compiler + "C++FLAGS" *= # C++ Compiler flags + + AS *:= as # Assembler and flags + ASFLAGS *= + + LD *= $(CC) # Loader and flags + LDFLAGS *= + LDLIBS *= # Default libraries + + AR *:= ar # archiver + ARFLAGS *= -rv + + # Definition of Print command for this system. + PRINT *= lp + + # Language and Parser generation Tools and their flags + YACC *:= yacc # standard yacc + YFLAGS *= + LEX *:= lex # standard lex + LFLAGS *= + + # Other Compilers, Tools and their flags + PC *:= pc # pascal compiler + RC *:= f77 # ratfor compiler + FC *:= f77 # fortran compiler + MV *:= $/bin$/mv # File rename command + + # Implicit generation rules for making inferences. + # lex and yacc rules + %.c : %.y %.Y + $(YACC) $(YFLAGS) $< + $(MV) $(YTAB).c $@ + + %.c : %.l %.L + $(LEX) $(LFLAGS) $< + $(MV) $(LEXYY).c $@ + + # Rules for making *$O + %$O : %.c ; $(CC) $(CFLAGS) -c $< + %$O : %$P ; $(PC) $(PFLAGS) -c $< + %$O : %$S ; $(AS) $(ASFLAGS) -o $@ $< + %$O : %.cl ; class -c $< + %$O :| %.e %.r %.F %$F + $(FC) $(RFLAGS) $(EFLAGS) $(FFLAGS) -c $< + + # Defibe how to build simple executables + .IF $(__.EXECS) + %$E : %$O ; $(CC) $(LDFLAGS) -o $@ $< $(LDLIBS) + .ENDIF + + # Recipe to make archive files, defined only if we have + # an archiver defined. + .IF $(AR) + %$A .SWAP .GROUP : + $(AR) $(ARFLAGS) $@ $? + $(RM) $(RMFLAGS) $? + .ENDIF + + # RCS support + .IF $(__.HAVE_RCS) + CO *:= co # check out for RCS + COFLAGS !+= -q + + % : $$(@:d)RCS$$/$$(@:f)$V + -$(CO) $(COFLAGS) $(null,$(@:d) $@ $(<:d:s/RCS/)$@) + .NOINFER : $$(@:d)RCS$$/$$(@:f)$V + + .IF $V + % : %$V + -$(CO) $(COFLAGS) $(null,$(@:d) $@ $(<:d:s/RCS/)$@) + .NOINFER : %$V + .ENDIF + .END + + # SCCS support + .IF $(__.HAVE_SCCS) + GET *:= get + GFLAGS !+= + + % : "$$(null,$$(@:d) s.$$@ $$(@:d)s.$$(@:f))" + -$(GET) $(GFLAGS) $@ + .NOINFER : "$$(null,$$(@:d) s.$$@ $$(@:d)s.$$(@:f))" + .END + + # Customize default recipe definitions for OS, OSRELEASE, etc. settings. + .INCLUDE .NOINFER .IGNORE: $(INCFILENAME:d)$(OS)$/recipes.mk +.ENDIF + + +# Finally, define the default construction strategy +.ROOT .PHONY .NOSTATE .SEQUENTIAL :- .INIT .TARGETS .DONE; +.INIT .DONE .PHONY: $(NULLPRQ); + +# Define the NULL Prerequisite as having no recipe. +$(NULLPRQ) .PHONY :; + +# Reset warnings back to previous setting. +.SILENT !:= $(__.silent) + +# Check for a Local project file, gets parsed before user makefile. +.INCLUDE .IGNORE .NOINFER: "project.mk" diff --git a/dmake/startup/summary b/dmake/startup/summary new file mode 100644 index 000000000000..4ae18860da41 --- /dev/null +++ b/dmake/startup/summary @@ -0,0 +1,3 @@ +The following is a summary of the supported dmake environments. When you +issue the build command 'dmake tag' where tag is the target environment it +will build one of these by default. diff --git a/dmake/startup/template.mk b/dmake/startup/template.mk new file mode 100644 index 000000000000..58544ee35848 --- /dev/null +++ b/dmake/startup/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= xxOSxx + OSRELEASE *:= xxOSRELEASExx + OSENVIRONMENT *:= xxOSENVIRONMENTxx diff --git a/dmake/startup/templates/mac/template.mk b/dmake/startup/templates/mac/template.mk new file mode 100644 index 000000000000..0cf10289c826 --- /dev/null +++ b/dmake/startup/templates/mac/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= mac + OSRELEASE *:= + OSENVIRONMENT *:= diff --git a/dmake/startup/templates/msdos/borland/bcc30/template.mk b/dmake/startup/templates/msdos/borland/bcc30/template.mk new file mode 100644 index 000000000000..df574e09c7aa --- /dev/null +++ b/dmake/startup/templates/msdos/borland/bcc30/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= msdos + OSRELEASE *:= borland + OSENVIRONMENT *:= bcc30 diff --git a/dmake/startup/templates/msdos/borland/bcc40/template.mk b/dmake/startup/templates/msdos/borland/bcc40/template.mk new file mode 100644 index 000000000000..30a27692f3ed --- /dev/null +++ b/dmake/startup/templates/msdos/borland/bcc40/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= msdos + OSRELEASE *:= borland + OSENVIRONMENT *:= bcc40 diff --git a/dmake/startup/templates/msdos/borland/bcc45/template.mk b/dmake/startup/templates/msdos/borland/bcc45/template.mk new file mode 100644 index 000000000000..83b5e009033d --- /dev/null +++ b/dmake/startup/templates/msdos/borland/bcc45/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= msdos + OSRELEASE *:= borland + OSENVIRONMENT *:= bcc45 diff --git a/dmake/startup/templates/msdos/borland/bcc50/template.mk b/dmake/startup/templates/msdos/borland/bcc50/template.mk new file mode 100644 index 000000000000..51b575677985 --- /dev/null +++ b/dmake/startup/templates/msdos/borland/bcc50/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= msdos + OSRELEASE *:= borland + OSENVIRONMENT *:= bcc50 diff --git a/dmake/startup/templates/msdos/borland/tcc20/template.mk b/dmake/startup/templates/msdos/borland/tcc20/template.mk new file mode 100644 index 000000000000..3cac6b22a240 --- /dev/null +++ b/dmake/startup/templates/msdos/borland/tcc20/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= msdos + OSRELEASE *:= borland + OSENVIRONMENT *:= tcc20 diff --git a/dmake/startup/templates/msdos/microsft/msc51/template.mk b/dmake/startup/templates/msdos/microsft/msc51/template.mk new file mode 100644 index 000000000000..7174197d6284 --- /dev/null +++ b/dmake/startup/templates/msdos/microsft/msc51/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= msdos + OSRELEASE *:= microsft + OSENVIRONMENT *:= msc51 diff --git a/dmake/startup/templates/msdos/microsft/msc60/template.mk b/dmake/startup/templates/msdos/microsft/msc60/template.mk new file mode 100644 index 000000000000..a147c694c5f7 --- /dev/null +++ b/dmake/startup/templates/msdos/microsft/msc60/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= msdos + OSRELEASE *:= microsft + OSENVIRONMENT *:= msc60 diff --git a/dmake/startup/templates/os2/ibm/icc/template.mk b/dmake/startup/templates/os2/ibm/icc/template.mk new file mode 100644 index 000000000000..c9c5adbf21ae --- /dev/null +++ b/dmake/startup/templates/os2/ibm/icc/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= os2 + OSRELEASE *:= ibm + OSENVIRONMENT *:= icc diff --git a/dmake/startup/templates/qssl/template.mk b/dmake/startup/templates/qssl/template.mk new file mode 100644 index 000000000000..e7e9837ae671 --- /dev/null +++ b/dmake/startup/templates/qssl/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= qssl + OSRELEASE *:= + OSENVIRONMENT *:= diff --git a/dmake/startup/templates/tos/template.mk b/dmake/startup/templates/tos/template.mk new file mode 100644 index 000000000000..91ce656f14b0 --- /dev/null +++ b/dmake/startup/templates/tos/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= tos + OSRELEASE *:= + OSENVIRONMENT *:= diff --git a/dmake/startup/templates/unix/386ix/template.mk b/dmake/startup/templates/unix/386ix/template.mk new file mode 100644 index 000000000000..e59d37c7ca72 --- /dev/null +++ b/dmake/startup/templates/unix/386ix/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= unix + OSRELEASE *:= 386ix + OSENVIRONMENT *:= diff --git a/dmake/startup/templates/unix/bsd43/template.mk b/dmake/startup/templates/unix/bsd43/template.mk new file mode 100644 index 000000000000..14a7cab8ed4b --- /dev/null +++ b/dmake/startup/templates/unix/bsd43/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= unix + OSRELEASE *:= bsd43 + OSENVIRONMENT *:= diff --git a/dmake/startup/templates/unix/bsd43/uw/template.mk b/dmake/startup/templates/unix/bsd43/uw/template.mk new file mode 100644 index 000000000000..6afe91c1fc7a --- /dev/null +++ b/dmake/startup/templates/unix/bsd43/uw/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= unix + OSRELEASE *:= bsd43 + OSENVIRONMENT *:= uw diff --git a/dmake/startup/templates/unix/bsd43/vf/template.mk b/dmake/startup/templates/unix/bsd43/vf/template.mk new file mode 100644 index 000000000000..395cd4718fa0 --- /dev/null +++ b/dmake/startup/templates/unix/bsd43/vf/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= unix + OSRELEASE *:= bsd43 + OSENVIRONMENT *:= vf diff --git a/dmake/startup/templates/unix/coherent/ver40/template.mk b/dmake/startup/templates/unix/coherent/ver40/template.mk new file mode 100644 index 000000000000..ef23550cf651 --- /dev/null +++ b/dmake/startup/templates/unix/coherent/ver40/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= unix + OSRELEASE *:= coherent + OSENVIRONMENT *:= ver40 diff --git a/dmake/startup/templates/unix/coherent/ver42/template.mk b/dmake/startup/templates/unix/coherent/ver42/template.mk new file mode 100644 index 000000000000..e5dd9f99ffac --- /dev/null +++ b/dmake/startup/templates/unix/coherent/ver42/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= unix + OSRELEASE *:= coherent + OSENVIRONMENT *:= ver42 diff --git a/dmake/startup/templates/unix/linux/gnu/template.mk b/dmake/startup/templates/unix/linux/gnu/template.mk new file mode 100644 index 000000000000..a0bcef64097b --- /dev/null +++ b/dmake/startup/templates/unix/linux/gnu/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= unix + OSRELEASE *:= linux + OSENVIRONMENT *:= gnu diff --git a/dmake/startup/templates/unix/solaris/gnu/template.mk b/dmake/startup/templates/unix/solaris/gnu/template.mk new file mode 100644 index 000000000000..3f9282027c5c --- /dev/null +++ b/dmake/startup/templates/unix/solaris/gnu/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= unix + OSRELEASE *:= solaris + OSENVIRONMENT *:= gnu diff --git a/dmake/startup/templates/unix/solaris/template.mk b/dmake/startup/templates/unix/solaris/template.mk new file mode 100644 index 000000000000..233917a6ba92 --- /dev/null +++ b/dmake/startup/templates/unix/solaris/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= unix + OSRELEASE *:= solaris + OSENVIRONMENT *:= diff --git a/dmake/startup/templates/unix/sysvr1/template.mk b/dmake/startup/templates/unix/sysvr1/template.mk new file mode 100644 index 000000000000..4eb40febb3a1 --- /dev/null +++ b/dmake/startup/templates/unix/sysvr1/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= unix + OSRELEASE *:= sysvr1 + OSENVIRONMENT *:= diff --git a/dmake/startup/templates/unix/sysvr3/pwd/template.mk b/dmake/startup/templates/unix/sysvr3/pwd/template.mk new file mode 100644 index 000000000000..fa6b4aa6bd1b --- /dev/null +++ b/dmake/startup/templates/unix/sysvr3/pwd/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= unix + OSRELEASE *:= sysvr3 + OSENVIRONMENT *:= pwd diff --git a/dmake/startup/templates/unix/sysvr3/template.mk b/dmake/startup/templates/unix/sysvr3/template.mk new file mode 100644 index 000000000000..3cb518671142 --- /dev/null +++ b/dmake/startup/templates/unix/sysvr3/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= unix + OSRELEASE *:= sysvr3 + OSENVIRONMENT *:= diff --git a/dmake/startup/templates/unix/sysvr4/template.mk b/dmake/startup/templates/unix/sysvr4/template.mk new file mode 100644 index 000000000000..553878268e59 --- /dev/null +++ b/dmake/startup/templates/unix/sysvr4/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= unix + OSRELEASE *:= sysvr4 + OSENVIRONMENT *:= diff --git a/dmake/startup/templates/unix/xenix/pwd/template.mk b/dmake/startup/templates/unix/xenix/pwd/template.mk new file mode 100644 index 000000000000..abd4066c347b --- /dev/null +++ b/dmake/startup/templates/unix/xenix/pwd/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= unix + OSRELEASE *:= xenix + OSENVIRONMENT *:= pwd diff --git a/dmake/startup/templates/unix/xenix/template.mk b/dmake/startup/templates/unix/xenix/template.mk new file mode 100644 index 000000000000..7ab223fbdb9f --- /dev/null +++ b/dmake/startup/templates/unix/xenix/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= unix + OSRELEASE *:= xenix + OSENVIRONMENT *:= diff --git a/dmake/startup/templates/win95/borland/bcc50/template.mk b/dmake/startup/templates/win95/borland/bcc50/template.mk new file mode 100644 index 000000000000..b5095c40ce2a --- /dev/null +++ b/dmake/startup/templates/win95/borland/bcc50/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= win95 + OSRELEASE *:= borland + OSENVIRONMENT *:= bcc50 diff --git a/dmake/startup/templates/win95/microsft/vpp40/template.mk b/dmake/startup/templates/win95/microsft/vpp40/template.mk new file mode 100644 index 000000000000..d4e6c9eb9f40 --- /dev/null +++ b/dmake/startup/templates/win95/microsft/vpp40/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= win95 + OSRELEASE *:= microsft + OSENVIRONMENT *:= vpp40 diff --git a/dmake/startup/templates/winnt/borland/bcc50/template.mk b/dmake/startup/templates/winnt/borland/bcc50/template.mk new file mode 100644 index 000000000000..b94ac034e0a1 --- /dev/null +++ b/dmake/startup/templates/winnt/borland/bcc50/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= winnt + OSRELEASE *:= borland + OSENVIRONMENT *:= bcc50 diff --git a/dmake/startup/templates/winnt/microsft/vpp40/template.mk b/dmake/startup/templates/winnt/microsft/vpp40/template.mk new file mode 100644 index 000000000000..e53922df68c3 --- /dev/null +++ b/dmake/startup/templates/winnt/microsft/vpp40/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= winnt + OSRELEASE *:= microsft + OSENVIRONMENT *:= vpp40 diff --git a/dmake/startup/tos/macros.mk b/dmake/startup/tos/macros.mk new file mode 100644 index 000000000000..1023dfc9acd1 --- /dev/null +++ b/dmake/startup/tos/macros.mk @@ -0,0 +1,24 @@ +# Define Atari TOS specific macros. +# + +# Process environment-specific refinements, if any. +.IF $(OSENVIRONMENT) + .INCLUDE .NOINFER .IGNORE : $(INCFILENAME:d)$(OSENVIRONMENT)$/macros.mk +.ENDIF + +# Set default to GCC Compiler. +CPP *:= /gnu/lib/cpp +CC *:= gcc +"C++" *:= g++ +AS *:= gas +YACC *:= bison +LEX *:= flex +RM *:= /bin/rm + +# Common flag settings +ARFLAGS *= -rvs + +# Other appropriate macro settings. +A *:= .olb +SHELLFLAGS *:= +GROUPSUFFIX *:= .bat diff --git a/dmake/startup/unix/386ix/macros.mk b/dmake/startup/unix/386ix/macros.mk new file mode 100644 index 000000000000..a359b302f546 --- /dev/null +++ b/dmake/startup/unix/386ix/macros.mk @@ -0,0 +1,6 @@ +# We hang off the standard sysvr3'isms +# +__.incdir !:= $(INCFILENAME:d:d:d:d)/sysvr3 + +# Process environment-specific refinements, if any. +.INCLUDE .SETDIR=$(__.incdir) .NOINFER .IGNORE : macros.mk diff --git a/dmake/startup/unix/bsd43/macros.mk b/dmake/startup/unix/bsd43/macros.mk new file mode 100644 index 000000000000..be4ae5fe45e9 --- /dev/null +++ b/dmake/startup/unix/bsd43/macros.mk @@ -0,0 +1,11 @@ +# Define additional Berkely UNIX specific macros. +# + +# Process environment-specific refinements, if any. +.IF $(OSENVIRONMENT) + .INCLUDE .NOINFER .IGNORE : $(INCFILENAME:d)$(OSENVIRONMENT)$/macros.mk +.ENDIF + +# Set defaults for local OS release +RANLIB *:= ranlib +PRINT *:= lpr diff --git a/dmake/startup/unix/bsd43/recipes.mk b/dmake/startup/unix/bsd43/recipes.mk new file mode 100644 index 000000000000..557ac7c8c17b --- /dev/null +++ b/dmake/startup/unix/bsd43/recipes.mk @@ -0,0 +1,13 @@ +# Define additional Berkeley UNIX specific build rules and recipes. +# + +# Recipe to make archive files. +%$A .GROUP : + $(AR) $(ARFLAGS) $@ $? + $(RM) $(RMFLAGS) $? + $(RANLIB) $@ + +# Process environment-specific refinements, if any. +.IF $(OSENVIRONMENT) + .INCLUDE .NOINFER .IGNORE : $(INCFILENAME:d)$(OSENVIRONMENT)$/recipes.mk +.ENDIF diff --git a/dmake/startup/unix/coherent/macros.mk b/dmake/startup/unix/coherent/macros.mk new file mode 100644 index 000000000000..e0201ebd14ba --- /dev/null +++ b/dmake/startup/unix/coherent/macros.mk @@ -0,0 +1,6 @@ +# We hang off the standard BSD'isms +# +__.incdir !:= $(INCFILENAME:d:d:d:d)/bsd43 + +# Process environment-specific refinements, if any. +.INCLUDE .SETDIR=$(__.incdir) .NOINFER .IGNORE : macros.mk diff --git a/dmake/startup/unix/coherent/recipes.mk b/dmake/startup/unix/coherent/recipes.mk new file mode 100644 index 000000000000..5966640d3621 --- /dev/null +++ b/dmake/startup/unix/coherent/recipes.mk @@ -0,0 +1,6 @@ +# Use the same file as +# +__.incdir !:= $(INCFILENAME:d:d:d:d)/bsd43 + +# Process environment-specific refinements, if any. +.INCLUDE .SETDIR=$(__.incdir) .NOINFER .IGNORE : recipes.mk diff --git a/dmake/startup/unix/linux/gnu/macros.mk b/dmake/startup/unix/linux/gnu/macros.mk new file mode 100644 index 000000000000..3d9c437d9e70 --- /dev/null +++ b/dmake/startup/unix/linux/gnu/macros.mk @@ -0,0 +1,6 @@ +# We hang off the standard sysvr3'isms +# +__.incdir !:= $(INCFILENAME:d:d:d:d:d:d)/sysvr3/gnu + +# Process environment-specific refinements, if any. +.INCLUDE .SETDIR=$(__.incdir) .NOINFER .IGNORE : macros.mk diff --git a/dmake/startup/unix/linux/macros.mk b/dmake/startup/unix/linux/macros.mk new file mode 100644 index 000000000000..228dafff2992 --- /dev/null +++ b/dmake/startup/unix/linux/macros.mk @@ -0,0 +1,10 @@ +# Define additional Linux specific macros. +# + +# Process environment-specific refinements, if any. +.IF $(OSENVIRONMENT) + .INCLUDE .NOINFER .IGNORE : $(INCFILENAME:d)$(OSENVIRONMENT)$/macros.mk +.ENDIF + +# Make OS-release-specific settings +PRINT *:= lpr diff --git a/dmake/startup/unix/macosx/gnu/macros.mk b/dmake/startup/unix/macosx/gnu/macros.mk new file mode 100644 index 000000000000..3d9c437d9e70 --- /dev/null +++ b/dmake/startup/unix/macosx/gnu/macros.mk @@ -0,0 +1,6 @@ +# We hang off the standard sysvr3'isms +# +__.incdir !:= $(INCFILENAME:d:d:d:d:d:d)/sysvr3/gnu + +# Process environment-specific refinements, if any. +.INCLUDE .SETDIR=$(__.incdir) .NOINFER .IGNORE : macros.mk diff --git a/dmake/startup/unix/macosx/macros.mk b/dmake/startup/unix/macosx/macros.mk new file mode 100644 index 000000000000..b29e917ec8e1 --- /dev/null +++ b/dmake/startup/unix/macosx/macros.mk @@ -0,0 +1,10 @@ +# Define additional Mac OS X specific macros. +# + +# Process environment-specific refinements, if any. +.IF $(OSENVIRONMENT) + .INCLUDE .NOINFER .IGNORE : $(INCFILENAME:d)$(OSENVIRONMENT)$/macros.mk +.ENDIF + +# Make OS-release-specific settings +PRINT *:= lpr diff --git a/dmake/startup/unix/macros.mk b/dmake/startup/unix/macros.mk new file mode 100644 index 000000000000..362b81d2c2f6 --- /dev/null +++ b/dmake/startup/unix/macros.mk @@ -0,0 +1,5 @@ +# Define additional UNIX specific macros. +# + +# Process release-specific refinements, if any. +.INCLUDE .NOINFER .IGNORE : $(INCFILENAME:d)$(OSRELEASE)$/macros.mk diff --git a/dmake/startup/unix/recipes.mk b/dmake/startup/unix/recipes.mk new file mode 100644 index 000000000000..1650430f3ed8 --- /dev/null +++ b/dmake/startup/unix/recipes.mk @@ -0,0 +1,15 @@ +# Define additional UNIX specific build recipes. +# + +# Define additional build targets. +%$E : %.sh; cp $< $@; chmod 0777 $@ + +# This rule tells how to make a non-suffixed executable from its single +# file source. +% : %$O; $(CC) $(LDFLAGS) -o $@ $< $(LDLIBS) + +# This rule tells how to make a.out from it's immediate list of prerequisites. +%.out :; $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) + +# Process release-specific refinements, if any. +.INCLUDE .NOINFER .IGNORE : $(INCFILENAME:d)$(OSRELEASE)$/recipes.mk diff --git a/dmake/startup/unix/solaris/macros.mk b/dmake/startup/unix/solaris/macros.mk new file mode 100644 index 000000000000..a359b302f546 --- /dev/null +++ b/dmake/startup/unix/solaris/macros.mk @@ -0,0 +1,6 @@ +# We hang off the standard sysvr3'isms +# +__.incdir !:= $(INCFILENAME:d:d:d:d)/sysvr3 + +# Process environment-specific refinements, if any. +.INCLUDE .SETDIR=$(__.incdir) .NOINFER .IGNORE : macros.mk diff --git a/dmake/startup/unix/sysvr1/macros.mk b/dmake/startup/unix/sysvr1/macros.mk new file mode 100644 index 000000000000..a359b302f546 --- /dev/null +++ b/dmake/startup/unix/sysvr1/macros.mk @@ -0,0 +1,6 @@ +# We hang off the standard sysvr3'isms +# +__.incdir !:= $(INCFILENAME:d:d:d:d)/sysvr3 + +# Process environment-specific refinements, if any. +.INCLUDE .SETDIR=$(__.incdir) .NOINFER .IGNORE : macros.mk diff --git a/dmake/startup/unix/sysvr3/gnu/macros.mk b/dmake/startup/unix/sysvr3/gnu/macros.mk new file mode 100644 index 000000000000..13141971fe40 --- /dev/null +++ b/dmake/startup/unix/sysvr3/gnu/macros.mk @@ -0,0 +1,12 @@ +# System V R3 GCC compiler specific macro definitions... +# + +# Common tool renamings +CC *:= gcc +"C++" *:= g++ +AS *:= gas +YACC *:= bison +LEX *:= flex + +# Common flag settings +ARFLAGS *= -rvs diff --git a/dmake/startup/unix/sysvr3/macros.mk b/dmake/startup/unix/sysvr3/macros.mk new file mode 100644 index 000000000000..2ccd730acfc0 --- /dev/null +++ b/dmake/startup/unix/sysvr3/macros.mk @@ -0,0 +1,7 @@ +# Define additional UNIX specific macros. +# + +# Process environment-specific refinements, if any. +.IF $(OSENVIRONMENT) + .INCLUDE .NOINFER .IGNORE : $(INCFILENAME:d)$(OSENVIRONMENT)$/macros.mk +.ENDIF diff --git a/dmake/startup/unix/sysvr4/macros.mk b/dmake/startup/unix/sysvr4/macros.mk new file mode 100644 index 000000000000..a359b302f546 --- /dev/null +++ b/dmake/startup/unix/sysvr4/macros.mk @@ -0,0 +1,6 @@ +# We hang off the standard sysvr3'isms +# +__.incdir !:= $(INCFILENAME:d:d:d:d)/sysvr3 + +# Process environment-specific refinements, if any. +.INCLUDE .SETDIR=$(__.incdir) .NOINFER .IGNORE : macros.mk diff --git a/dmake/startup/unix/xenix/macros.mk b/dmake/startup/unix/xenix/macros.mk new file mode 100644 index 000000000000..a359b302f546 --- /dev/null +++ b/dmake/startup/unix/xenix/macros.mk @@ -0,0 +1,6 @@ +# We hang off the standard sysvr3'isms +# +__.incdir !:= $(INCFILENAME:d:d:d:d)/sysvr3 + +# Process environment-specific refinements, if any. +.INCLUDE .SETDIR=$(__.incdir) .NOINFER .IGNORE : macros.mk diff --git a/dmake/startup/win95/borland/macros.mk b/dmake/startup/win95/borland/macros.mk new file mode 100644 index 000000000000..2017f02d3f1f --- /dev/null +++ b/dmake/startup/win95/borland/macros.mk @@ -0,0 +1,34 @@ +# MSDOS Borland-C environment customization. + +.IF $(OSENVIRONMENT) + .INCLUDE .IGNORE .NOINFER : $(INCFILENAME:d)$(OSENVIRONMENT)$/macros.mk +.ENDIF + +# Standard C-language command names and flags +CPP *:= # C-preprocessor +CC *:= bcc32 +CFLAGS *= # C compiler flags +"C++" *:= # C++ Compiler +"C++FLAGS" *= # C++ Compiler flags + +AS *:= tasm # Assembler and flags +ASFLAGS *= +LD *= tlink32 # Loader and flags +LDFLAGS *= +LDLIBS *= # Default libraries +AR *:= tlib # archiver +ARFLAGS *= ???? + +# Definition of Print command for this system. +PRINT *= print + +# Language and Parser generation Tools and their flags +YACC *:= yacc # standard yacc +YFLAGS *= +LEX *:= lex # standard lex +LFLAGS *= + +# Other Compilers, Tools and their flags +PC *:= tpc # pascal compiler +RC *:= ??? # ratfor compiler +FC *:= ??? # fortran compiler diff --git a/dmake/startup/win95/macros.mk b/dmake/startup/win95/macros.mk new file mode 100644 index 000000000000..72707c23bbe3 --- /dev/null +++ b/dmake/startup/win95/macros.mk @@ -0,0 +1,64 @@ +# Define additional MSDOS specific settings. +# + +# Execution environment configuration. +# Grab the current setting of COMSPEC. +# +.IMPORT .IGNORE : COMSPEC + +# First check if SHELL is defined to be something other than COMSPEC. +# If it is, then assume that SHELL is a Korn compatible shell like MKS's +.IF $(SHELL) == $(NULL) + .IF $(COMSPEC) == $(NULL) + SHELL *:= $(ROOTDIR)$/bin$/sh$E + .ELSE + SHELL *:= $(COMSPEC) + .END +.END +GROUPSHELL *:= $(SHELL) + +# Process release-specific refinements, if any. +.INCLUDE .NOINFER .IGNORE : $(INCFILENAME:d)$(OSRELEASE)$/macros.mk + +# Applicable suffix definitions +A *:= .lib # Libraries +E *:= .exe # Executables +F *:= .for # Fortran +O *:= .obj # Objects +P *:= .pas # Pascal +S *:= .asm # Assembler sources +V *:= # RCS suffix + +# Now set the remaining arguments depending on which SHELL we +# are going to use. COMSPEC (assumed to be command.com) or +# MKS Korn shell. +.IF $(SHELL) == $(COMSPEC) + SHELLFLAGS *:= $(SWITCHAR)c + GROUPFLAGS *:= $(SHELLFLAGS) + SHELLMETAS *:= "<>| + GROUPSUFFIX *:= .bat + DIVFILE *= $(TMPFILE:s,/,\) + RM *= del + RMFLAGS *= + MV *= rename + __.DIVSEP-sh-yes *:= \\ + __.DIVSEP-sh-no *:= \\ +.ELSE + SHELL !:= $(SHELL:s,/,\,) + COMMAND *= $(CMNDNAME:s,/,\,) $(CMNDARGS) + SHELLFLAGS *:= -c + GROUPFLAGS *:= + SHELLMETAS *:= *";?<>|()&][$$\#`' + GROUPSUFFIX *:= .ksh + .MKSARGS *:= yes + RM *= $(ROOTDIR)$/bin$/rm + RMFLAGS *= -f + MV *= $(ROOTDIR)$/bin$/mv + DIVFILE *= $(TMPFILE:s,/,${__.DIVSEP-sh-${USESHELL}}) + __.DIVSEP-sh-yes *:= \\\ + __.DIVSEP-sh-no *:= \\ +.ENDIF + + +# Does not respect case of filenames. +.DIRCACHERESPCASE := no diff --git a/dmake/startup/win95/microsft/macros.mk b/dmake/startup/win95/microsft/macros.mk new file mode 100644 index 000000000000..f10b1fdfa69d --- /dev/null +++ b/dmake/startup/win95/microsft/macros.mk @@ -0,0 +1,38 @@ +# MSDOS Microsoft-C environment customization. + +.IF $(OSENVIRONMENT) + .INCLUDE .IGNORE .NOINFER : $(INCFILENAME:d)$(OSENVIRONMENT)$/macros.mk +.ENDIF + +# Standard C-language command names and flags +CC *:= cl # C compiler +CPP *:= # C-preprocessor +CFLAGS *= # C compiler flags +"C++" *:= # C++ Compiler +"C++FLAGS" *= # C++ Compiler flags + +AS *:= masm # Assembler and flags +ASFLAGS *= +LD *= link # Loader and flags +LDFLAGS *= +LDLIBS *= # Default libraries +AR *:= lib # archiver +ARFLAGS *= ???? + +# Definition of Print command for this system. +PRINT *= print + +# Language and Parser generation Tools and their flags +YACC *:= yacc # standard yacc +YFLAGS *= +LEX *:= lex # standard lex +LFLAGS *= + +# Other Compilers, Tools and their flags +PC *:= ??? # pascal compiler +RC *:= ??? # ratfor compiler +FC *:= ??? # fortran compiler + + +# Directory cache configuration. +.DIRCACHE *:= no diff --git a/dmake/startup/win95/recipes.mk b/dmake/startup/win95/recipes.mk new file mode 100644 index 000000000000..5a98f22b1e05 --- /dev/null +++ b/dmake/startup/win95/recipes.mk @@ -0,0 +1,9 @@ +# Define additional MSDOS specific build recipes. +# + +# Executables + %$E : %$O ; $(CC) $(LDFLAGS) -o$@ $< $(LDLIBS) + %$O : %$S ; $(AS) $(ASFLAGS) $(<:s,/,\) + +# Process release-specific refinements, if any. +.INCLUDE .NOINFER .IGNORE : $(INCFILENAME:d)$(OSRELEASE)$/recipes.mk diff --git a/dmake/startup/winnt/borland/macros.mk b/dmake/startup/winnt/borland/macros.mk new file mode 100644 index 000000000000..2017f02d3f1f --- /dev/null +++ b/dmake/startup/winnt/borland/macros.mk @@ -0,0 +1,34 @@ +# MSDOS Borland-C environment customization. + +.IF $(OSENVIRONMENT) + .INCLUDE .IGNORE .NOINFER : $(INCFILENAME:d)$(OSENVIRONMENT)$/macros.mk +.ENDIF + +# Standard C-language command names and flags +CPP *:= # C-preprocessor +CC *:= bcc32 +CFLAGS *= # C compiler flags +"C++" *:= # C++ Compiler +"C++FLAGS" *= # C++ Compiler flags + +AS *:= tasm # Assembler and flags +ASFLAGS *= +LD *= tlink32 # Loader and flags +LDFLAGS *= +LDLIBS *= # Default libraries +AR *:= tlib # archiver +ARFLAGS *= ???? + +# Definition of Print command for this system. +PRINT *= print + +# Language and Parser generation Tools and their flags +YACC *:= yacc # standard yacc +YFLAGS *= +LEX *:= lex # standard lex +LFLAGS *= + +# Other Compilers, Tools and their flags +PC *:= tpc # pascal compiler +RC *:= ??? # ratfor compiler +FC *:= ??? # fortran compiler diff --git a/dmake/startup/winnt/macros.mk b/dmake/startup/winnt/macros.mk new file mode 100644 index 000000000000..63fa7983d503 --- /dev/null +++ b/dmake/startup/winnt/macros.mk @@ -0,0 +1,64 @@ +# Define additional MSDOS specific settings. +# + +# Execution environment configuration. +# Grab the current setting of COMSPEC. +# +.IMPORT .IGNORE : COMSPEC + +# First check if SHELL is defined to be something other than COMSPEC. +# If it is, then assume that SHELL is a Korn compatible shell like MKS's +.IF $(SHELL) == $(NULL) + .IF $(COMSPEC) == $(NULL) + SHELL *:= $(ROOTDIR)$/bin$/sh$E + .ELSE + SHELL *:= $(COMSPEC) + .END +.END +GROUPSHELL *:= $(SHELL) + +# Process release-specific refinements, if any. +.INCLUDE .NOINFER .IGNORE : $(INCFILENAME:d)$(OSRELEASE)$/macros.mk + +# Applicable suffix definitions +A *:= .lib # Libraries +E *:= .exe # Executables +F *:= .for # Fortran +O *:= .obj # Objects +P *:= .pas # Pascal +S *:= .asm # Assembler sources +V *:= # RCS suffix + +# Now set the remaining arguments depending on which SHELL we +# are going to use. COMSPEC (assumed to be command.com) or +# MKS Korn shell. +.IF $(SHELL) == $(COMSPEC) + SHELLFLAGS *:= $(SWITCHAR)c + GROUPFLAGS *:= $(SHELLFLAGS) + SHELLMETAS *:= "<>| + GROUPSUFFIX *:= .cmd + DIVFILE *= $(TMPFILE:s,/,\) + RM *= del + RMFLAGS *= + MV *= rename + __.DIVSEP-sh-yes *:= \\ + __.DIVSEP-sh-no *:= \\ +.ELSE + SHELL !:= $(SHELL:s,/,\,) + COMMAND *= $(CMNDNAME:s,/,\,) $(CMNDARGS) + SHELLFLAGS *:= -c + GROUPFLAGS *:= + SHELLMETAS *:= *";?<>|()&][$$\#`' + GROUPSUFFIX *:= .ksh + .MKSARGS *:= yes + RM *= $(ROOTDIR)$/bin$/rm + RMFLAGS *= -f + MV *= $(ROOTDIR)$/bin$/mv + DIVFILE *= $(TMPFILE:s,/,${__.DIVSEP-sh-${USESHELL}}) + __.DIVSEP-sh-yes *:= \\\ + __.DIVSEP-sh-no *:= \\ +.ENDIF + + +# Does not respect case of filenames. +.DIRCACHERESPCASE := no diff --git a/dmake/startup/winnt/microsft/macros.mk b/dmake/startup/winnt/microsft/macros.mk new file mode 100644 index 000000000000..eed3fbdeeedb --- /dev/null +++ b/dmake/startup/winnt/microsft/macros.mk @@ -0,0 +1,37 @@ +# MSDOS Microsoft-C environment customization. + +.IF $(OSENVIRONMENT) + .INCLUDE .IGNORE .NOINFER : $(INCFILENAME:d)$(OSENVIRONMENT)$/macros.mk +.ENDIF + +# Standard C-language command names and flags +CC *:= cl # C compiler +CPP *:= # C-preprocessor +CFLAGS *= # C compiler flags +"C++" *:= # C++ Compiler +"C++FLAGS" *= # C++ Compiler flags + +AS *:= masm # Assembler and flags +ASFLAGS *= +LD *= link # Loader and flags +LDFLAGS *= +LDLIBS *= # Default libraries +AR *:= lib # archiver +ARFLAGS *= ???? + +# Definition of Print command for this system. +PRINT *= print + +# Language and Parser generation Tools and their flags +YACC *:= yacc # standard yacc +YFLAGS *= +LEX *:= lex # standard lex +LFLAGS *= + +# Other Compilers, Tools and their flags +PC *:= ??? # pascal compiler +RC *:= ??? # ratfor compiler +FC *:= ??? # fortran compiler + +# Directory cache configuration. +.DIRCACHE *:= no diff --git a/dmake/startup/winnt/recipes.mk b/dmake/startup/winnt/recipes.mk new file mode 100644 index 000000000000..5a98f22b1e05 --- /dev/null +++ b/dmake/startup/winnt/recipes.mk @@ -0,0 +1,9 @@ +# Define additional MSDOS specific build recipes. +# + +# Executables + %$E : %$O ; $(CC) $(LDFLAGS) -o$@ $< $(LDLIBS) + %$O : %$S ; $(AS) $(ASFLAGS) $(<:s,/,\) + +# Process release-specific refinements, if any. +.INCLUDE .NOINFER .IGNORE : $(INCFILENAME:d)$(OSRELEASE)$/recipes.mk diff --git a/dmake/stat.c b/dmake/stat.c new file mode 100644 index 000000000000..aee8a18e1c23 --- /dev/null +++ b/dmake/stat.c @@ -0,0 +1,263 @@ +/* RCS $Id: stat.c,v 1.1.1.1 2000-09-22 15:33:25 hr Exp $ +-- +-- SYNOPSIS +-- Bind a target name to a file. +-- +-- DESCRIPTION +-- This file contains the code to go and stat a target. The stat rules +-- follow a predefined order defined in the comment for Stat_target. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include "extern.h" + + +static int _check_dir_list ANSI((CELLPTR, CELLPTR, int, int)); + +#ifdef DBUG + /* Just a little ditty for debugging this thing */ + static time_t + _do_stat( name, lib, sym, force ) + char *name; + char *lib; + char **sym; + int force; + { + time_t res; + DB_ENTER( "_do_stat" ); + + res = Do_stat(name, lib, sym, force); + DB_PRINT( "stat", ("Statted [%s,%s,%d,%ld]", name, lib, sym, res) ); + + DB_RETURN( res ); + } +#define DO_STAT(A,B,C,D) _do_stat(A,B,C,D) +#else +#define DO_STAT(A,B,C,D) Do_stat(A,B,C,D) +#endif + +static char *_first; /* local storage of first attempted path */ + +PUBLIC void +Stat_target( cp, setfname, force )/* +==================================== + Stat a target. When doing so follow the following rules, suppose + that cp->CE_NAME points at a target called fred.o: + + 0. If A_SYMBOL attribute set look into the library + then do the steps 1 thru 4 on the resulting name. + 1. Try path's obtained by prepending any dirs found as + prerequisites for .SOURCE.o. + 2. If not found, do same as 2 but use .SOURCE + 3. If not found and .LIBRARYM attribute for the target is + set then look for it in the corresponding library. + 4. If found in step 0 thru 3, then ce_fname points at + file name associate with target, else ce_fname points + at a file name built by the first .SOURCE* dir that + applied. */ + +CELLPTR cp; +int setfname; +int force; +{ + register HASHPTR hp; + static HASHPTR srchp = NIL(HASH); + char *name; + char *tmp; + int res = 0; + + DB_ENTER( "Stat_target" ); + + name = cp->CE_NAME; + if( srchp == NIL(HASH) ) srchp = Get_name(".SOURCE",Defs,FALSE); + + /* Look for a symbol of the form lib((symbol)) the name of the symbol + * as entered in the hash table is (symbol) so pull out symbol and try + * to find it's module. If successful DO_STAT will return the module + * as well as the archive member name (pointed at by tmp). We then + * replace the symbol name with the archive member name so that we + * have the proper name for any future refrences. */ + + if( cp->ce_attr & A_SYMBOL ) { + DB_PRINT( "stat", ("Binding lib symbol [%s]", name) ); + + cp->ce_time = DO_STAT( name, cp->ce_lib, &tmp, force ); + + if( cp->ce_time != (time_t) 0L ) { + /* stat the new member name below note tmp must point at a string + * returned by MALLOC... ie. the Do_stat code should use DmStrDup */ + + if( Verbose & V_MAKE ) + printf( "%s: Mapped ((%s)) to %s(%s)\n", Pname, + name, cp->ce_lib, tmp ); + + FREE( name ); + name = cp->CE_NAME = tmp; + cp->ce_attr &= ~(A_FFNAME | A_SYMBOL); + } + else + { DB_VOID_RETURN; } + } + + _first = NIL(char); + tmp = DmStrJoin( ".SOURCE", Get_suffix(name), -1, FALSE); + + /* Check .SOURCE.xxx target */ + if( (hp = Get_name(tmp, Defs, FALSE)) != NIL(HASH) ) + res = _check_dir_list( cp, hp->CP_OWNR, setfname, force ); + + /* Check just .SOURCE */ + if( !res && (srchp != NIL(HASH)) ) + res = _check_dir_list( cp, srchp->CP_OWNR, setfname, force ); + + /* If libmember and we haven't found it check the library */ + if( !res && (cp->ce_attr & A_LIBRARYM) ) { + cp->ce_time = DO_STAT(name, cp->ce_lib, NIL(char *), force); + + if( !cp->ce_time && Tmd && *Tmd && cp->ce_lib ) { + char *tmplib; + tmplib=DmStrDup(Build_path(Tmd,cp->ce_lib)); + + if ((cp->ce_time = DO_STAT(name, tmplib, NIL(char *),force)) != (time_t)0L){ + cp->ce_lib=DmStrDup(tmplib); + } + } + + if( Verbose & V_MAKE ) + printf( "%s: Checking library '%s' for member [%s], time %ld\n", + Pname, cp->ce_lib, name, cp->ce_time ); + } + + FREE( tmp ); + + if( setfname == 1 || (setfname == -1 && cp->ce_time != (time_t)0L) ) { + int setlib = (cp->ce_lib == cp->ce_fname); + + if( (cp->ce_attr & A_FFNAME) && (cp->ce_fname != NIL(char)) ) + FREE( cp->ce_fname ); + + if( _first != NIL(char) ) { + cp->ce_fname = _first; + cp->ce_attr |= A_FFNAME; + } + else { + cp->ce_fname = cp->CE_NAME; + cp->ce_attr &= ~A_FFNAME; + } + + if ( setlib ) cp->ce_lib = cp->ce_fname; + } + else if( _first ) + FREE( _first ); + + /* set it as stated only if successful, this way, we shall try again + * later. */ + if( cp->ce_time != (time_t)0L ) { + cp->ce_flag |= F_STAT; + + /* If it is a whatif this changed scenario then return the current + * time, but do so only if the stat was successful. */ + if ( (cp->ce_attr & A_WHATIF) && !(cp->ce_flag & F_MADE) ) { + cp->ce_time = Do_time(); + } + } + + DB_VOID_RETURN; +} + + +static int +_check_dir_list( cp, sp, setfname, force )/* +============================================ + Check the list of dir's given by the prerequisite list of sp, for a + file pointed at by cp. Returns 0 if path not bound, else returns + 1 and replaces old name for cell with new cell name. */ + +CELLPTR cp; +CELLPTR sp; +int setfname; +int force; +{ + /* FIXME: BCC 5.0 BUG??? If lp is assigned to a register variable then + * BCC 5.0 corrupts a field of the member structure when DO_STAT + * calls the native win95 stat system call. Blech!!! + * + * Making this a static variable forces it out of a register and + * seems to avoid the problem. */ + static LINKPTR lp; + char *dir; + char *path; + char *name; + int res = 0; + int fset = 0; + + DB_ENTER( "_check_dir_list" ); + DB_PRINT( "mem", ("%s:-> mem %ld", cp->CE_NAME, (long) coreleft()) ); + + if( sp->ce_prq != NIL(LINK) ) /* check prerequisites if any */ + { + /* Use the real name instead of basename, this prevents silly + * loops in inference code, and is consistent with man page */ + name = cp->CE_NAME; + + /* Here we loop through each directory on the list, and try to stat + * the target. We always save the first pathname we try to stat in + * _first. If we subsequently get a match we then replace the value of + * _first by the matched path name. */ + + for( lp=sp->CE_PRQ; lp != NIL(LINK) && !res; lp=lp->cl_next ) { + int nodup = 0; + dir = lp->cl_prq->CE_NAME; + + if( strchr( dir, '$' ) ) dir = Expand(dir); + if( strcmp( dir, ".NULL" ) == 0 ) { + nodup = 1; + path = cp->CE_NAME; + } else { + path = DmStrDup(Build_path(dir,name)); + } + + res = ((cp->ce_time=DO_STAT(path,NIL(char),NIL(char *),force))!=(time_t)0L); + + /* Have to use DmStrDup to set _first since Build_path, builds it's + * path names inside a static buffer. */ + if( setfname ) + if( (_first == NIL(char) && !fset) || res ) { + if( _first != NIL(char) ) FREE( _first ); + if (nodup) + _first = NIL(char); + else { + _first = path; + path = NIL(char); + } + fset = 1; + } + + DB_PRINT( "stat", ("_first [%s], path [%s]", _first, path) ); + if( dir != lp->cl_prq->CE_NAME ) FREE(dir); + if( path && path != cp->CE_NAME ) FREE(path); + } + } + + DB_PRINT( "mem", ("%s:-< mem %ld", cp->CE_NAME, (long) coreleft()) ); + DB_RETURN( res ); +} + + + + diff --git a/dmake/state.c b/dmake/state.c new file mode 100644 index 000000000000..7b5a2fe79ab8 --- /dev/null +++ b/dmake/state.c @@ -0,0 +1,229 @@ +/* RCS $Id: state.c,v 1.1.1.1 2000-09-22 15:33:25 hr Exp $ +-- +-- SYNOPSIS +-- .KEEP_STATE state file management +-- +-- DESCRIPTION +-- Three routines to interface to the .KEEP_STATE state file. +-- +-- Read_state() - reads the state file if any. +-- Write_state() - writes the state file. +-- +-- Check_state(cp,how) - checks an entry returns 0 or 1 +-- and updates the entry. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include "extern.h" + +typedef struct se { + char *st_name; /* name of cell */ + uint32 st_nkey; /* name hash key */ + int st_count; /* how count for how */ + uint32 st_dkey; /* directory hash key */ + uint32 st_key; /* hash key */ + struct se *st_next; +} KSTATE, *KSTATEPTR; + +static KSTATEPTR _st_head = NIL(KSTATE); +static KSTATEPTR _st_tail = NIL(KSTATE); +static int _st_upd = FALSE; +static char *_st_file = NIL(char); + +static int _my_fgets ANSI((char *, int, FILE *)); + +PUBLIC void +Read_state() +{ + char *buf; + char sizeb[20]; + int size; + FILE *fp; + KSTATEPTR sp; + + if( (fp = Search_file(".KEEP_STATE", &_st_file)) != NIL(FILE) ) { + if( _my_fgets( sizeb, 20, fp ) ) { + size = atol(sizeb); + buf = MALLOC(size+2, char); + + while( _my_fgets(buf, size, fp) ) { + TALLOC(sp, 1, KSTATE); + sp->st_name = DmStrDup(buf); + (void) Hash(buf, &sp->st_nkey); + + if( _my_fgets(buf, size, fp) ) sp->st_count = atoi(buf); + if( _my_fgets(buf, size, fp) ) sp->st_dkey = (uint32) atol(buf); + + if( _my_fgets(buf, size, fp) ) + sp->st_key = (uint32) atol(buf); + else { + FREE(sp); + break; + } + + if( _st_head == NIL(KSTATE) ) + _st_head = sp; + else + _st_tail->st_next = sp; + + _st_tail = sp; + } + + FREE(buf); + } + + Closefile(); + } +} + + +PUBLIC void +Write_state() +{ + static int in_write = 0; + register KSTATEPTR sp; + FILE *fp; + + if( !_st_upd || !_st_file || (_st_file && !*_st_file) || + Trace || in_write ) return; + + in_write++; + if( (fp = Openfile(_st_file, TRUE, TRUE)) != NIL(FILE) ) { + int maxlen = 0; + int tmplen; + + for( sp = _st_head; sp; sp=sp->st_next ) + if( (tmplen = strlen(sp->st_name)+2) > maxlen ) + maxlen = tmplen; + + /* A nice arbitrary minimum size */ + if( maxlen < 20 ) maxlen = 20; + fprintf( fp, "%d\n", maxlen ); + + for( sp = _st_head; sp; sp=sp->st_next ) { + uint16 hv; + uint32 hk; + + if( Search_table(Defs, sp->st_name, &hv, &hk) ) { + fprintf( fp, "%s\n", sp->st_name ); + fprintf( fp, "%d\n", sp->st_count ); + fprintf( fp, "%lu\n", sp->st_dkey ); + fprintf( fp, "%lu\n", sp->st_key ); + } + } + + Closefile(); + } + else + Fatal("Cannot open STATE file %s", _st_file); + + in_write = 0; +} + + +PUBLIC int +Check_state( cp, recipes, maxrcp ) +CELLPTR cp; +STRINGPTR *recipes; +int maxrcp; +{ + KSTATEPTR st; + STRINGPTR sp; + int i; + uint32 thkey; + uint32 hkey; + uint32 nkey; + uint32 dkey; + int update = FALSE; + + if( !_st_file || (_st_file && !*_st_file) || Trace ) + return(FALSE); + + if( strcmp(cp->CE_NAME,".REMOVE") == 0 + || (cp->ce_attr & (A_PHONY|A_NOSTATE)) ) + return(FALSE); + + (void) Hash( cp->CE_NAME, &nkey ); thkey = nkey + (uint32) cp->ce_count; + (void) Hash( Pwd, &dkey ); thkey += dkey; + + Suppress_temp_file = TRUE; + for( i=0 ; i<maxrcp; i++ ) + for(sp=recipes[i]; sp != NIL(STRING); sp=sp->st_next ) { + CELLPTR svct = Current_target; + char *cmnd; + t_attr silent = (Glob_attr & A_SILENT); + + Current_target = cp; + Glob_attr |= A_SILENT; + cmnd = Expand(sp->st_string); + Glob_attr = (Glob_attr & ~A_SILENT)|silent; + Current_target = svct; + + (void) Hash(cmnd, &hkey); thkey += hkey; + FREE(cmnd); + } + Suppress_temp_file = FALSE; + + for( st=_st_head; st != NIL(KSTATE); st=st->st_next ) { + if( st->st_nkey == nkey + && st->st_dkey == dkey + && st->st_count == cp->ce_count + && !strcmp(cp->CE_NAME, st->st_name) ) + break; + } + + if( st == NIL(KSTATE) ) { + KSTATEPTR nst; + + TALLOC(nst, 1, KSTATE); + nst->st_name = cp->CE_NAME; + nst->st_nkey = nkey; + nst->st_dkey = dkey; + nst->st_key = thkey; + nst->st_count = cp->ce_count; + + if( _st_head == NIL(KSTATE) ) + _st_head = nst; + else + _st_tail->st_next = nst; + + _st_tail = nst; + _st_upd = TRUE; + } + else if( st->st_key != thkey ) { + st->st_key = thkey; + _st_upd = update = TRUE; + } + + return(st != NIL(KSTATE) && update); +} + + +static int +_my_fgets(buf, size, fp) +char *buf; +int size; +FILE *fp; +{ + char *p; + + if( fgets(buf, size, fp) == NULL ) return(0); + + if( (p=strrchr(buf,'\n')) != NIL(char) ) *p='\0'; + return(1); +} diff --git a/dmake/stdmacs.h b/dmake/stdmacs.h new file mode 100644 index 000000000000..a2b6aa3dfa9b --- /dev/null +++ b/dmake/stdmacs.h @@ -0,0 +1,56 @@ +/* RCS $Id: stdmacs.h,v 1.1.1.1 2000-09-22 15:33:25 hr Exp $ +-- +-- SYNOPSIS +-- General use macros. +-- +-- DESCRIPTION +-- ANSI macro relies on the fact that it can be replaced by (), or by +-- its value, where the value is one value due to the preprocessors +-- handling of arguments that are surrounded by ()'s as a single +-- argument. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef MACROS_h +#define MACROS_h + +/* AIX and Mac MPW define __STDC__ as special, but defined(__STDC__) is false, + * and it has no value. */ +#ifndef __STDC__ +#define __STDC__ 0 +#endif + +#if __STDC__ || defined(__TURBOC__) || defined(__IBMC__) +#define ANSI(x) x +#else +#define ANSI(x) () +#endif + +#define NIL(p) ((p*)NULL) + +#if !defined(atarist) && !defined(__STDDEF_H) +#define offsetof(type,id) ((size_t)&((type*)NULL)->id) +#endif + +#define FALSE 0 +#define TRUE 1 + +#define PUBLIC + +#endif + diff --git a/dmake/struct.h b/dmake/struct.h new file mode 100644 index 000000000000..01ac57f661ed --- /dev/null +++ b/dmake/struct.h @@ -0,0 +1,256 @@ +/* RCS $Id: struct.h,v 1.1.1.1 2000-09-22 15:33:25 hr Exp $ +-- +-- SYNOPSIS +-- Structure definitions +-- +-- DESCRIPTION +-- dmake main data structure definitions. See each of the individual +-- struct declarations for more detailed information on the defined +-- fields and their use. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef _STRUCT_INCLUDED_ +#define _STRUCT_INCLUDED_ + +typedef uint32 t_attr; + +/* The following struct is the cell used in the hash table. + * NOTE: It contains the actual hash value. This allows the hash table + * insertion to compare hash values and to do a string compare only + * for entries that have matching hash_key values. This elliminates + * 99.9999% of all extraneous string compare operations when searching + * a hash table chain for matching entries. */ + +typedef struct hcell { + struct hcell *ht_next; /* next entry in the hash table */ + struct hcell *ht_link; /* for temporary lists */ + char *ht_name; /* name of this cell */ + char *ht_value; /* cell value if any */ + uint32 ht_hash; /* actual hash_key of cell */ + int ht_flag; /* flags belonging to hash entry */ + + /* NOTE: some macros have corresponding variables defined + * that control program behaviour. For these macros a + * bit of ht_flag indicates the variable value will be set, and the + * type of the value that will be set. + * + * The struct below contains a mask for bit variables, and a + * pointer to the global STATIC location for that variable. + * String and char variables point to the same place as ht_value + * and must be updated when ht_value changes, bit variables must + * have their value recomputed. See Def_macro code for more + * details. + * + * NOTE: Macro variables and Targets are always distinct. Thus + * the value union contains pointers back at cells that own + * a particular name entry. A conflict in this can never + * arise, ie pointers at cells will never be used as + * values for a macro variable, since the cell and macro + * name spaces are completely distinct. */ + + struct { + int mv_mask; /* bit mask for bit variable */ + union { + char** mv_svar;/* ptr to string valued glob var */ + char* mv_cvar;/* ptr to char valued glob var */ + t_attr* mv_bvar;/* ptr to bit valued glob var */ + int* mv_ivar;/* ptr to int valued glob var */ + + struct { + struct tcell* ht_owner;/* ptr to CELL owning name */ + struct tcell* ht_root; /* root ptr for explode */ + } ht; + } val; + } var; /* variable's static equivalent */ +} HASH, *HASHPTR; + +#define MV_MASK var.mv_mask +#define MV_SVAR var.val.mv_svar +#define MV_CVAR var.val.mv_cvar +#define MV_BVAR var.val.mv_bvar +#define MV_IVAR var.val.mv_ivar +#define CP_OWNR var.val.ht.ht_owner +#define CP_ROOT var.val.ht.ht_root + + + +/* This struct holds the list of temporary files that have been created. + * It gets unlinked when Quit is called due to an execution error */ +typedef struct flst { + char *fl_name; /* file name */ + FILE *fl_file; /* the open file */ + struct flst *fl_next; /* pointer to next file */ +} FILELIST, *FILELISTPTR; + + +/* The next struct is used to link together prerequisite lists */ +typedef struct lcell { + struct tcell *cl_prq; /* link to a prerequisite */ + struct lcell *cl_next; /* next cell on dependency list */ + int cl_flag; /* flags for link cell */ +} LINK, *LINKPTR; + + +/* This is the structure of a target cell in the dag which represents the + * graph of dependencies. Each possible target is represented as a cell. + * + * Each cell contains a pointer to the hash table entry for this cell. + * The hash table entry records the name of the cell. */ + +typedef struct tcell { + struct hcell *ce_name; /* name of this cell */ + struct hcell *ce_pushed; /* local pushed macro definitions */ + + struct lcell ce_all; /* link for grouping UPDATEALL cells*/ + struct tcell *ce_set; /* set rep. valid if ce_all != NULL */ + struct tcell *ce_setdir; /* SETDIR ROOT pointer for this cell*/ + struct tcell *ce_link; /* link for temporary list making */ + struct tcell *ce_parent; /* used by inner loop, not a static */ + + struct lcell *ce_prq; /* list of prerequisites for cell */ + struct lcell *ce_prqorg; /* list of original prerequisites */ + struct lcell *ce_indprq; /* indirect prerequisites for % cell*/ + + struct str *ce_recipe; /* recipe for making this cell */ + FILELISTPTR ce_files; /* list of temporary files for cell */ + struct str *ce_cond; /* conditional macro assignments */ + + char *ce_per; /* value of % in %-meta expansion */ + char *ce_fname; /* file name associated with target */ + char *ce_lib; /* archive name, if A_LIBRARYM */ + char *ce_dir; /* value for .SETDIR attribute */ + + int ce_count; /* value for :: recipe set */ + int ce_index; /* value of count for next :: child */ + int ce_flag; /* all kinds of goodies */ + t_attr ce_attr; /* attributes for this target */ + time_t ce_time; /* time stamp value of target if any*/ +} CELL, *CELLPTR; + +#define CE_NAME ce_name->ht_name +#define CE_RECIPE ce_recipe +#define CE_PRQ ce_prq +#define CeMeToo(C) &((C)->ce_all) +#define CeNotMe(C) (C)->ce_all.cl_next + + +/* This struct represents that used by Get_token to return and control + * access to a token list inside a particular string. This gives the + * ability to access non overlapping tokens simultaneously from + * multiple strings. */ + +typedef struct { + char *tk_str; /* the string to search for tokens */ + char tk_cchar; /* current char under *str */ + int tk_quote; /* if we are scanning a quoted str */ +} TKSTR, *TKSTRPTR; + + + +/* Below is the struct used to represent a string. It points at possibly + * another string, since the set of rules for making a target is a collection + * of strings. */ + + +typedef struct str { + char *st_string; /* the string value */ + struct str *st_next; /* pointer to the next string */ + t_attr st_attr; /* attr for rule operations */ +} STRING, *STRINGPTR; + + + +/* These structs are used in processing of the % rules, and in building + * the NFA machine that is used to match an arbitrary target string to + * one of the % rules that is represented by each DFA */ + +typedef int16 statecnt; /* limits the max number of dfa states */ + + +/* Each state of the DFA contains four pieces of information. */ +typedef struct st { + struct st *no_match; /* state to go to if no match */ + struct st *match; /* state to go to if we do match */ + char symbol; /* symbol on which we transit */ + char action; /* action to perform if match */ +} STATE, *STATEPTR; + + +/* Each DFA machine looks like this. It must have two pointers that represent + * the value of % in the matched string, and it contains a pointer into the + * current state, as well as the array of all states. */ +typedef struct { + char *pstart; /* start of % string match */ + char *pend; /* end of % string match */ + STATEPTR c_state; /* current DFA state */ + CELLPTR node; /* % target represented by this DFA */ + STATEPTR states; /* table of states for the DFA */ +} DFA, *DFAPTR; + + +/* An NFA is a collection of DFA's. For each DFA we must know it's current + * state and where the next NFA is. */ +typedef struct nfa_machine { + DFAPTR dfa; /* The DFA for this eps transition */ + char status; /* DFA state */ + struct nfa_machine *next; /* the next DFA in NFA */ +} NFA, *NFAPTR; + + + +/* The next struct is used to link together DFA nodes for inference. */ + +typedef struct dfal { + struct tcell *dl_meta; /* link to %-meta cell */ + struct dfal *dl_next; /* next cell on matched DFA list*/ + struct dfal *dl_prev; /* prev cell on matched DFA list*/ + struct dfal *dl_member; /* used during subset calc */ + char dl_delete; /* used during subset calc */ + char *dl_per; /* value of % for matched DFA */ + statecnt dl_state; /* matched state of the DFA */ + int dl_prep; /* repetion count for the cell */ +} DFALINK, *DFALINKPTR; + + +/* This struct is used to store the stack of DFA sets during inference */ +typedef struct dfst { + DFALINKPTR df_set; /* pointer to the set */ + struct dfst *df_next; /* next element in the stack */ +} DFASET, *DFASETPTR; + + +/* We need sets of items during inference, here is the item, we form sets + * by linking them together. */ + +typedef struct ic { + CELLPTR ic_meta; /* Edge we used to make this cell*/ + DFALINKPTR ic_dfa; /* Dfa that we matched against */ + CELLPTR ic_setdirroot; /* setdir root pointer for cell */ + DFASET ic_dfastack; /* set of dfas we're working with*/ + int ic_dmax; /* max depth of cycles in graph */ + char *ic_name; /* name of the cell to insert */ + char *ic_dir; /* dir to CD to prior to recurse */ + struct ic *ic_next; /* next pointer to link */ + struct ic *ic_link; /* link all ICELL'S together */ + struct ic *ic_parent; /* pointer to post-requisite */ + char ic_flag; /* flag, used for NOINFER only */ + char ic_exists; /* TRUE if prerequisite exists */ +} ICELL, *ICELLPTR; + +#endif diff --git a/dmake/sysintf.c b/dmake/sysintf.c new file mode 100644 index 000000000000..15ddb5d96976 --- /dev/null +++ b/dmake/sysintf.c @@ -0,0 +1,753 @@ +/* RCS $Id: sysintf.c,v 1.1.1.1 2000-09-22 15:33:26 hr Exp $ +-- +-- SYNOPSIS +-- System independent interface +-- +-- DESCRIPTION +-- These are the routines constituting the system interface. +-- The system is taken to be essentially POSIX conformant. +-- The original code was extensively revised by T J Thompson at MKS, +-- and the library cacheing was added by Eric Gisin at MKS. I then +-- revised the code yet again, to improve the lib cacheing, and to +-- make it more portable. +-- +-- The following is a list of routines that are required by this file +-- in order to work. These routines are provided as functions by the +-- standard C lib of the target system or as #defines in system/sysintf.h +-- or via appropriate C code in the system/ directory for the given +-- system. +-- +-- The first group must be provided by a file in the system/ directory +-- the second group is ideally provided by the C lib. However, there +-- are instances where the C lib implementation of the specified routine +-- does not exist, or is incorrect. In these instances the routine +-- must be provided by the the user in the system/ directory of dmake. +-- (For example, the bsd/ dir contains code for putenv(), and tempnam()) +-- +-- DMAKE SPECIFIC: +-- seek_arch() +-- touch_arch() +-- void_lcache() +-- runargv() +-- DMSTAT() +-- Remove_prq() +-- +-- C-LIB SPECIFIC: (should be present in your C-lib) +-- utime() +-- time() +-- getenv() +-- putenv() +-- getcwd() +-- signal() +-- chdir() +-- tempnam() +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include "extern.h" +#include "sysintf.h" + +/* +** Tries to stat the file name. Returns 0 if the file +** does not exist. Note that if lib is not null it tries to stat +** the name found inside lib. +** +** If member is NOT nil then look for the library object which defines the +** symbol given by name. If found DmStrDup the name and return make the +** pointer pointed at by sym point at it. Not handled for now! +*/ +static time_t +really_dostat(name, buf) +char *name; +struct stat *buf; +{ + return( ( DMSTAT(name,buf)==-1 + || (STOBOOL(Augmake) && (buf->st_mode & S_IFDIR))) + ? (time_t)0L + : (time_t) buf->st_mtime + ); +} + + +PUBLIC time_t +Do_stat(name, lib, member, force) +char *name; +char *lib; +char **member; +int force; +{ + struct stat buf; + time_t seek_arch(); + + if( member != NIL(char *) ) + Fatal("Library symbol names not supported"); + + buf.st_mtime = (time_t)0L; + if( lib != NIL(char) ) + return( seek_arch(Basename(name), lib) ); + else if( STOBOOL(UseDirCache) ) + return(CacheStat(name,force)); + else if( strlen(Basename(name)) > NameMax ) + return((time_t)0L); + else + return(really_dostat(name,&buf)); +} + + +/* Touch existing file to force modify time to present. + */ +PUBLIC int +Do_touch(name, lib, member) +char *name; +char *lib; +char **member; +{ + if( member != NIL(char *) ) + Fatal("Library symbol names not supported"); + + if (lib != NIL(char)) + return( touch_arch(Basename(name), lib) ); + else if( strlen(Basename(name)) > NameMax ) + return(-1); + else + return( utime(name, NIL(time_t)) ); +} + + + +PUBLIC void +Void_lib_cache( lib_name, member_name )/* +========================================= + Void the library cache for lib lib_name, and member member_name. */ +char *lib_name; +char *member_name; +{ + VOID_LCACHE( lib_name, member_name ); +} + + + +/* +** return the current time +*/ +PUBLIC time_t +Do_time() +{ + extern time_t time(); + return (time((time_t*)0)); +} + + + +/* +** Execute the string passed in as a command and return +** the return code. The command line arguments are +** assumed to be separated by spaces or tabs. The first +** such argument is assumed to be the command. +** +** If group is true then this is a group of commands to be fed to the +** the shell as a single unit. In this case cmd is of the form +** "file" indicating the file that should be read by the shell +** in order to execute the command group. +*/ +PUBLIC int +Do_cmnd(cmd, group, do_it, target, ignore, shell, last) +char *cmd; +int group; +int do_it; +CELLPTR target; +int ignore; +int shell; +int last; +{ + int i; + + if( !do_it ) { + if( last && !Doing_bang ) { + Update_time_stamp( target ); + } + return(0); + } + + if ( target->ce_attr & A_ERROR ) { + if ( last ) { + Update_time_stamp( target ); + } + return(0); + } + + if( Max_proc == 1 ) Wait_for_completion = TRUE; + + if( (i = runargv(target, ignore, group, last, shell, cmd)) == -1 ) + Quit(); + + /* NOTE: runargv must return either 0 or 1, 0 ==> command executed, and + * we waited for it to return, 1 ==> command started and is running + * concurrently with make process. */ + return(i); +} + + +#define MINARGV 64 +/* Take a command and pack it into an argument vector to be executed. */ +PUBLIC char ** +Pack_argv( group, shell, cmd ) +int group; +int shell; +char *cmd; +{ + static char **av = NIL(char *); + static int avs = 0; + int i = 0; + + if( av == NIL(char *) ) { + TALLOC(av, MINARGV, char*); + avs = MINARGV; + } + av[0] = NIL(char); + + if (*cmd) { + Packed_shell = shell||group||(*DmStrPbrk(cmd, Shell_metas)!='\0'); + + if( Packed_shell ){ + char* sh = group ? GShell : Shell; + + if( sh != NIL(char) ) { + av[i++] = sh; + if( (av[i] = (group?GShell_flags:Shell_flags)) != NIL(char) ) i++; + + av[i++] = cmd; + av[i] = NIL(char); + } + else + Fatal("%sSHELL macro not defined", group?"GROUP":""); + } + else { + do { + while( iswhite(*cmd) ) ++cmd; + if( *cmd ) av[i++] = cmd; + + while( *cmd != '\0' && !iswhite(*cmd) ) ++cmd; + if( *cmd ) *cmd++ = '\0'; + + if( i == avs ) { + avs += MINARGV; + av = (char **) realloc( av, avs*sizeof(char *) ); + } + } while( *cmd ); + + av[i] = NIL(char); + } + } + + return(av); +} + + +/* +** Return the value of ename from the environment +** if ename is not defined in the environment then +** NIL(char) should be returned +*/ +PUBLIC char * +Read_env_string(ename) +char *ename; +{ +#if !defined(_MSC_VER) || _MSC_VER < 600 + extern char *getenv(); +#endif + return( getenv(ename) ); +} + + + +/* +** Set the value of the environment string ename to value. +** Returns 0 if success, non-zero if failure +*/ +PUBLIC int +Write_env_string(ename, value) +char *ename; +char *value; +{ + extern int putenv(); + char* p; + char* envstr = DmStrAdd(ename, value, FALSE); + + p = envstr+strlen(ename); /* Don't change this code, DmStrAdd does not */ + *p++ = '='; /* add the space if *value is 0, it does */ + if( !*value ) *p = '\0'; /* allocate enough memory for one though. */ + + return( putenv(envstr) ); +} + + + +PUBLIC void +ReadEnvironment() +{ + extern char **Rule_tab; +#if !defined(_MSC_VER) +#if defined(__BORLANDC__) && __BORLANDC__ >= 0x500 + extern char ** _RTLENTRY _EXPDATA environ; +#else + extern char **environ; +#endif +#endif + char **rsave; + +#if !defined(__ZTC__) && !defined(_MPW) +# define make_env() +# define free_env() +#else + void make_env(); + void free_env(); +#endif + + make_env(); + + rsave = Rule_tab; + Rule_tab = environ; + Readenv = TRUE; + + Parse( NIL(FILE) ); + + Readenv = FALSE; + Rule_tab = rsave; + + free_env(); +} + + + +/* +** All we have to catch is SIG_INT +*/ +PUBLIC void +Catch_signals(fn) +void (*fn)(); +{ + if( (void (*)()) signal(SIGINT, SIG_IGN) != (void (*)())SIG_IGN ) + signal( SIGINT, fn ); + if( (void (*)()) signal(SIGQUIT, SIG_IGN) != (void (*)())SIG_IGN ) + signal( SIGQUIT, fn ); +} + + + +/* +** Clear any previously set signals +*/ +PUBLIC void +Clear_signals() +{ + if( (void (*)())signal(SIGINT, SIG_IGN) != (void (*)())SIG_IGN ) + signal( SIGINT, SIG_DFL ); + if( (void (*)())signal(SIGQUIT, SIG_IGN) != (void (*)())SIG_IGN ) + signal( SIGQUIT, SIG_DFL ); +} + + + +/* +** Set program name +*/ +PUBLIC void +Prolog(argc, argv) +int argc; +char* argv[]; +{ + Pname = (argc == 0) ? DEF_MAKE_PNAME : argv[0]; + Root = Def_cell( ".ROOT" ); + Targets = Def_cell( ".TARGETS" ); + Add_prerequisite(Root, Targets, FALSE, FALSE); + + Targets->ce_flag = Root->ce_flag = F_RULES|F_TARGET|F_STAT; + Targets->ce_attr = Root->ce_attr = A_NOSTATE|A_PHONY; + + Root->ce_flag |= F_MAGIC; + Root->ce_attr |= A_SEQ; + + tzset(); +} + + + +/* +** Do any clean up for exit. +*/ +PUBLIC void +Epilog(ret_code) +int ret_code; +{ + Write_state(); + Unlink_temp_files(Root); + Hook_std_writes(NIL(char)); /* For MSDOS tee (-F option) */ + exit( ret_code ); +} + + + +/* +** Use the built-in functions of the operating system to get the current +** working directory. +*/ +PUBLIC char * +Get_current_dir() +{ + static char buf[PATH_MAX+2]; + return(getcwd(buf, sizeof(buf))); +} + + + +/* +** change working directory +*/ +PUBLIC int +Set_dir(path) +char* path; +{ + return( chdir(path) ); +} + + + +/* +** return switch char +*/ +PUBLIC char +Get_switch_char() +{ + return( getswitchar() ); +} + + + +/* +** Generate a temporary file name and open the file for writing. +** If a name cannot be generated or the file cannot be opened +** return -1, else return the fileno of the open file. +** and update the source file pointer to point at the new file name. +** Note that the new name should be freed when the file is removed. +*/ +PUBLIC FILE* +Get_temp(path, suff, op) +char **path; +char *suff; +int op; +{ + extern char *tempnam(); + + *path = DmStrJoin( tempnam(NIL(char), "mk"), suff, -1, TRUE ); + Def_macro( "TMPFILE", *path, M_MULTI|M_EXPANDED ); + + return( op?fopen(*path, "w"):NIL(FILE) ); +} + + +/* +** Open a new temporary file and set it up for writing. +*/ +PUBLIC FILE * +Start_temp( suffix, cp, fname ) +char *suffix; +CELLPTR cp; +char **fname; +{ + FILE *fp; + char *tmpname; + char *name; + + name = (cp != NIL(CELL))?cp->CE_NAME:"makefile text"; + + if( (fp = Get_temp(&tmpname, suffix, TRUE)) == NIL(FILE) ) + Open_temp_error( tmpname, name ); + + Link_temp( cp, fp, tmpname ); + *fname = tmpname; + + return( fp ); +} + + +/* +** Issue an error on failing to open a temporary file +*/ +PUBLIC void +Open_temp_error( tmpname, name ) +char *tmpname; +char *name; +{ + Fatal("Cannot open temp file `%s' while processing `%s'", tmpname, name ); +} + + +/* +** Link a temp file onto the list of files. +*/ +PUBLIC void +Link_temp( cp, fp, fname ) +CELLPTR cp; +FILE *fp; +char *fname; +{ + FILELISTPTR new; + + if( cp == NIL(CELL) ) cp = Root; + + TALLOC( new, 1, FILELIST ); + + new->fl_next = cp->ce_files; + new->fl_name = fname; + new->fl_file = fp; /* indicates temp file is open */ + + cp->ce_files = new; +} + + +/* +** Close a previously used temporary file. +*/ +PUBLIC void +Close_temp(cp, file) +CELLPTR cp; +FILE *file; +{ + FILELISTPTR fl; + if( cp == NIL(CELL) ) cp = Root; + + for( fl=cp->ce_files; fl && fl->fl_file != file; fl=fl->fl_next ); + if( fl ) { + fl->fl_file = NIL(FILE); + fclose(file); + } +} + + +/* +** Clean-up, and close all temporary files associated with a target. +*/ +PUBLIC void +Unlink_temp_files( cp )/* +========================== + Unlink the tempfiles if any exist. Make sure you close the files first + though. This ensures that under DOS there is no disk space lost. */ +CELLPTR cp; +{ + FILELISTPTR cur, next; + + if( cp == NIL(CELL) || cp->ce_files == NIL(FILELIST) ) return; + + for( cur=cp->ce_files; cur != NIL(FILELIST); cur=next ) { + next = cur->fl_next; + + if( cur->fl_file ) fclose( cur->fl_file ); + + if( Verbose & V_LEAVE_TMP ) + fprintf( stderr, "%s: Left temp file [%s]\n", Pname, cur->fl_name ); + else + (void) Remove_file( cur->fl_name ); + + FREE(cur->fl_name); + FREE(cur); + } + + cp->ce_files = NIL(FILELIST); +} + + +PUBLIC void +Handle_result(status, ignore, abort_flg, target) +int status; +int ignore; +int abort_flg; +CELLPTR target; +{ + status = ((status&0xff)==0 ? status>>8 + : (status & 0xff)==SIGTERM ? -1 + : (status & 0x7f)+128); + + if( status ) + if( !abort_flg ) { + char buf[512]; + + sprintf(buf, "%s: Error code %d, while making '%s'", + Pname, status, target->ce_fname ); + + if( ignore || Continue ) { + if (!(Glob_attr & A_SILENT)) { + strcat(buf, " (Ignored" ); + + if ( Continue ) { + strcat(buf,",Continuing"); + target->ce_attr |= A_ERROR; + } + strcat(buf,")"); + if (Verbose) + fprintf(stderr, "%s\n", buf); + } + + if( target->ce_attr & A_ERRREMOVE + && Remove_file( target->ce_fname ) == 0 + && !(Glob_attr & A_SILENT)) + fprintf(stderr,"%s: '%s' removed.\n", Pname, target->ce_fname); + } + else { + fprintf(stderr, "%s\n",buf); + + if(!(target->ce_attr & A_PRECIOUS)||(target->ce_attr & A_ERRREMOVE)) + if( Remove_file( target->ce_fname ) == 0 ) + fprintf(stderr,"%s: '%s' removed.\n", Pname, + target->ce_fname); + + Quit(); + } + } + else if(!(target->ce_attr & A_PRECIOUS)||(target->ce_attr & A_ERRREMOVE)) + Remove_file( target->ce_fname ); +} + + +PUBLIC void +Update_time_stamp( cp ) +CELLPTR cp; +{ + HASHPTR hp; + LINKPTR dp; + CELLPTR tcp; + time_t phonytime = (time_t)0L; + int phony = ((cp->ce_attr&A_PHONY) != 0); + + /* Compute phony time as either the current time, or the most recent time + * from the list of prerequisites if there are any. */ + if ( cp->ce_prq != NIL(LINK) ) { + for(dp=cp->ce_prq; dp; dp=dp->cl_next) + if ( dp->cl_prq->ce_time > phonytime ) + phonytime = dp->cl_prq->ce_time; + } + else + phonytime = Do_time(); + + for(dp=CeMeToo(cp); dp; dp=dp->cl_next) { + tcp=dp->cl_prq; + + if( tcp->ce_attr & A_LIBRARY ) + Void_lib_cache( tcp->ce_fname, NIL(char) ); + else if( !Touch && (tcp->ce_attr & A_LIBRARYM) ) + Void_lib_cache( tcp->ce_lib, tcp->ce_fname ); + + if( phony ) { + tcp->ce_time = phonytime; + } + else if (Trace) { + tcp->ce_time = Do_time(); + } + else { + Stat_target(tcp, -1, TRUE); + + if( tcp->ce_time == (time_t) 0L ) + tcp->ce_time = Do_time(); + } + + if( Trace ) { + tcp->ce_flag |= F_STAT; /* pretend we stated ok */ + } + + if( Verbose & V_MAKE ) + printf( "%s: <<<< Set [%s] time stamp to %lu\n", + Pname, tcp->CE_NAME, tcp->ce_time ); + + Unlink_temp_files( tcp ); + tcp->ce_flag |= F_MADE; + tcp->ce_attr |= A_UPDATED; + } + + /* Scan the list of prerequisites and if we find one that is + * marked as being removable, (ie. an inferred intermediate node + * then remove it. We remove a prerequisite by running the recipe + * associated with the special target .REMOVE, with $< set to + * the list of prerequisites to remove. */ + + /* Make sure we don't try to remove prerequisites for the .REMOVE + * target. */ + if( strcmp(cp->CE_NAME,".REMOVE") != 0 && + (hp = Get_name(".REMOVE", Defs, FALSE)) != NIL(HASH) ) { + register LINKPTR dp; + int flag = FALSE; + int rem; + t_attr attr; + + tcp = hp->CP_OWNR; + + tcp->ce_flag |= F_TARGET; + Clear_prerequisites( tcp ); + + for(dp=cp->ce_prq; dp != NIL(LINK); dp=dp->cl_next) { + register CELLPTR prq = dp->cl_prq; + + attr = Glob_attr | prq->ce_attr; + rem = (prq->ce_flag & F_REMOVE) && + (prq->ce_flag & F_MADE ) && + !(prq->ce_attr & A_PHONY) && + !(attr & A_PRECIOUS); + + if(rem) { + LINKPTR tdp; + + for(tdp=CeMeToo(prq); tdp; tdp=tdp->cl_next) { + CELLPTR tmpcell=tdp->cl_prq; + + (Add_prerequisite(tcp,tmpcell,FALSE,FALSE))->cl_flag|=F_TARGET; + tmpcell->ce_flag &= ~F_REMOVE; + } + flag = TRUE; + } + } + + if( flag ) { + int sv_force = Force; + + Force = FALSE; + Remove_prq( tcp ); + Force = sv_force; + + for(dp=tcp->ce_prq; dp != NIL(LINK); dp=dp->cl_next) { + register CELLPTR prq = dp->cl_prq; + + prq->ce_flag &= ~(F_MADE|F_VISITED|F_STAT); + prq->ce_flag |= F_REMOVE; + prq->ce_time = (time_t)0L; + } + } + } +} + + +PUBLIC int +Remove_file( name ) +char *name; +{ + struct stat buf; + + if( stat(name, &buf) != 0 ) + return 1; + if( (buf.st_mode & S_IFMT) == S_IFDIR ) + return 1; + return(unlink(name)); +} diff --git a/dmake/tos/config.mk b/dmake/tos/config.mk new file mode 100644 index 000000000000..65076200175a --- /dev/null +++ b/dmake/tos/config.mk @@ -0,0 +1,49 @@ +# This is an OS specific configuration file +# It assumes that OBJDIR, TARGET and DEBUG are previously defined. +# It defines CFLAGS, LDARGS, CPPFLAGS, STARTUPFILE, LDOBJS +# PRINTER, PRINTFLAGS +# It augments SRC, OBJDIR, TARGET, CFLAGS, LDLIBS +# +PRINTER = hw +PRINTFLAGS = -P$(PRINTER) +STARTUPFILE = $(OS)/startup.mk +CPPFLAGS = $(CFLAGS) +LDOBJS = $(CSTARTUP) $(OBJDIR)/{$(<:f)} +LDARGS = $(LDFLAGS) -o $@ $(OBJDIR)/*$O +LDFLAGS += -s +LD = $(CC) + +# Debug flags +DB_CFLAGS = -g -DDBUG +DB_LDFLAGS = -g +DB_LDLIBS = + +# NO Debug flags +NDB_CFLAGS = -O +NDB_LDFLAGS = +NDB_LDLIBS = + +# Local configuration modifications for CFLAGS. +CFLAGS += -I$(OS) + +# Sources that must be defined for each different version +OS_SRC += ruletab.c +DOS_SRC = rmprq.c runargv.c dirbrk.c rmprq.c +UNIX_SRC = arlib.c +BSD_SRC = putenv.c tempnam.c + +.SETDIR=$(OS) : $(OS_SRC) +.SETDIR=msdos : $(DOS_SRC) +.SETDIR=unix : $(UNIX_SRC) +.SETDIR=unix/bsd43 : $(BSD_SRC) + +SRC += $(OS_SRC) $(DOS_SRC) $(UNIX_SRC) $(BSD_SRC) + +# Set source dirs so that we can find files named in this +# config file. +.SOURCE.h : $(OS) + +# See if we modify anything in the lower levels. +.IF $(OSRELEASE) != $(NULL) + .INCLUDE .IGNORE : $(OS)$(DIRSEPSTR)$(OSRELEASE)$(DIRSEPSTR)config.mk +.END diff --git a/dmake/tos/make.sh b/dmake/tos/make.sh new file mode 100644 index 000000000000..8ecb7db9c8e3 --- /dev/null +++ b/dmake/tos/make.sh @@ -0,0 +1,57 @@ +mkdir objects +gcc -c -I. -Itos -O infer.c +mv infer.o objects +gcc -c -I. -Itos -O make.c +mv make.o objects +gcc -c -I. -Itos -O stat.c +mv stat.o objects +gcc -c -I. -Itos -O expand.c +mv expand.o objects +gcc -c -I. -Itos -O dmstring.c +mv dmstring.o objects +gcc -c -I. -Itos -O hash.c +mv hash.o objects +gcc -c -I. -Itos -O dag.c +mv dag.o objects +gcc -c -I. -Itos -O dmake.c +mv dmake.o objects +gcc -c -I. -Itos -O path.c +mv path.o objects +gcc -c -I. -Itos -O imacs.c +mv imacs.o objects +gcc -c -I. -Itos -O sysintf.c +mv sysintf.o objects +gcc -c -I. -Itos -O parse.c +mv parse.o objects +gcc -c -I. -Itos -O getinp.c +mv getinp.o objects +gcc -c -I. -Itos -O quit.c +mv quit.o objects +gcc -c -I. -Itos -O state.c +mv state.o objects +gcc -c -I. -Itos -O dmdump.c +mv dmdump.o objects +gcc -c -I. -Itos -O macparse.c +mv macparse.o objects +gcc -c -I. -Itos -O rulparse.c +mv rulparse.o objects +gcc -c -I. -Itos -O percent.c +mv percent.o objects +gcc -c -I. -Itos -O function.c +mv function.o objects +gcc -c -I. -Itos -O tos/ruletab.c +mv ruletab.o objects +gcc -c -I. -Itos -O msdos/rmprq.c +mv rmprq.o objects +gcc -c -I. -Itos -O msdos/runargv.c +mv runargv.o objects +gcc -c -I. -Itos -O msdos/dirbrk.c +mv dirbrk.o objects +gcc -c -I. -Itos -O unix/arlib.c +mv arlib.o objects +gcc -c -I. -Itos -O unix/bsd43/putenv.c +mv putenv.o objects +gcc -c -I. -Itos -O unix/bsd43/tempnam.c +mv tempnam.o objects +gcc -s -o dmake objects/*.o +cp tos/template.mk startup/config.mk diff --git a/dmake/tos/public.h b/dmake/tos/public.h new file mode 100644 index 000000000000..8302f0b29d56 --- /dev/null +++ b/dmake/tos/public.h @@ -0,0 +1,163 @@ +/* RCS $Id: public.h,v 1.1.1.1 2000-09-22 15:33:33 hr Exp $ +-- WARNING -- This file is AUTOMATICALLY GENERATED DO NOT EDIT IT +-- +-- +-- SYNOPSIS +-- Local functions exported to be visible by others. +-- +-- DESCRIPTION +-- This file is generated by 'genpub'. Function declarations +-- that appear in this file are extracted by 'genpub' from +-- source files. Any function in the source file whose definition +-- appears like: +-- +-- PUBLIC return_type +-- function( arg_list ); +-- type_expr1 arg1; +-- ... +-- +-- has its definition extracted and a line of the form: +-- +-- return_type function ANSI((type_expr1,type_expr2,...)); +-- +-- entered into the output file. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef _DMAKE_PUBLIC_h +#define _DMAKE_PUBLIC_h + +#ifdef EXTERN +#undef EXTERN +#endif +#if defined(DEFINE_DMAKE_VARIABLES) +#define EXTERN +#else +#define EXTERN extern +#endif + +/***** genpub: Begin list of generated function headers */ +void Infer_recipe ANSI((CELLPTR, CELLPTR)); +int Make_targets ANSI(()); +int Make ANSI((CELLPTR, CELLPTR)); +int Exec_commands ANSI((CELLPTR)); +void Print_cmnd ANSI((char *, int, int)); +int Push_dir ANSI((char *, char *, int)); +void Pop_dir ANSI((int)); +void Append_line ANSI((char *, int, FILE *, char *, int, int)); +void Stat_target ANSI((CELLPTR, int, int)); +char *Expand ANSI((char *)); +char *Apply_edit ANSI((char *, char *, char *, int, int)); +void Map_esc ANSI((char *)); +char* Apply_modifiers ANSI((int, char *)); +char* Tokenize ANSI((char *, char *, char, int)); +char* ScanToken ANSI((char *, char **, int)); +char *DmStrJoin ANSI((char *, char *, int, int)); +char *DmStrAdd ANSI((char *, char *, int)); +char *DmStrApp ANSI((char *, char *)); +char *DmStrDup ANSI((char *)); +char *DmStrDup2 ANSI((char *)); +char *DmStrPbrk ANSI((char *, char *)); +char *DmStrSpn ANSI((char *, char *)); +char *DmStrStr ANSI((char *, char *)); +char *DmSubStr ANSI((char *, char *)); +uint16 Hash ANSI((char *, uint32 *)); +HASHPTR Get_name ANSI((char *, HASHPTR *, int)); +HASHPTR Search_table ANSI((HASHPTR *, char *, uint16 *, uint32 *)); +HASHPTR Push_macro ANSI((HASHPTR)); +HASHPTR Pop_macro ANSI((HASHPTR)); +HASHPTR Def_macro ANSI((char *, char *, int)); +CELLPTR Def_cell ANSI((char *)); +LINKPTR Add_prerequisite ANSI((CELLPTR, CELLPTR, int, int)); +void Clear_prerequisites ANSI((CELLPTR)); +int Test_circle ANSI((CELLPTR, int)); +STRINGPTR Def_recipe ANSI((char *, STRINGPTR, int, int)); +t_attr Rcp_attribute ANSI((char *)); +void main ANSI((int, char **)); +FILE *Openfile ANSI((char *, int, int)); +FILE *Closefile ANSI(()); +FILE *Search_file ANSI((char *, char **)); +char *Filename ANSI(()); +int Nestlevel ANSI(()); +FILE *TryFiles ANSI((LINKPTR)); +void Fatal ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Error ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Warning ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void No_ram ANSI(()); +void Usage ANSI((int)); +void Version ANSI(()); +char *Get_suffix ANSI((char *)); +char *Basename ANSI((char *)); +char *Filedir ANSI((char *)); +char *Build_path ANSI((char *, char *)); +void Make_rules ANSI(()); +void Create_macro_vars ANSI(()); +time_t Do_stat ANSI((char *, char *, char **, int)); +int Do_touch ANSI((char *, char *, char **)); +void Void_lib_cache ANSI((char *, char *)); +time_t Do_time ANSI(()); +int Do_cmnd ANSI((char *, int, int, CELLPTR, int, int, int)); +char ** Pack_argv ANSI((int, int, char *)); +char *Read_env_string ANSI((char *)); +int Write_env_string ANSI((char *, char *)); +void ReadEnvironment ANSI(()); +void Catch_signals ANSI((void (*)())); +void Clear_signals ANSI(()); +void Prolog ANSI((int, char* [])); +void Epilog ANSI((int)); +char *Get_current_dir ANSI(()); +int Set_dir ANSI((char*)); +char Get_switch_char ANSI(()); +FILE* Get_temp ANSI((char **, char *, int)); +FILE *Start_temp ANSI((char *, CELLPTR, char **)); +void Open_temp_error ANSI((char *, char *)); +void Link_temp ANSI((CELLPTR, FILE *, char *)); +void Close_temp ANSI((CELLPTR, FILE *)); +void Unlink_temp_files ANSI((CELLPTR)); +void Handle_result ANSI((int, int, int, CELLPTR)); +void Update_time_stamp ANSI((CELLPTR)); +int Remove_file ANSI((char *)); +void Parse ANSI((FILE *)); +int Get_line ANSI((char *, FILE *)); +char *Do_comment ANSI((char *, char **, int)); +char *Get_token ANSI((TKSTRPTR, char *, int)); +void Quit ANSI(()); +void Read_state ANSI(()); +void Write_state ANSI(()); +int Check_state ANSI((CELLPTR, STRINGPTR *, int)); +void Dump ANSI(()); +void Dump_recipe ANSI((STRINGPTR)); +int Parse_macro ANSI((char *, int)); +int Macro_op ANSI((char *)); +int Parse_rule_def ANSI((int *)); +int Rule_op ANSI((char *)); +void Add_recipe_to_list ANSI((char *, int, int)); +void Bind_rules_to_targets ANSI((int)); +int Set_group_attributes ANSI((char *)); +DFALINKPTR Match_dfa ANSI((char *)); +void Check_circle_dfa ANSI(()); +void Add_nfa ANSI((char *)); +char *Exec_function ANSI((char *)); +void Remove_prq ANSI((CELLPTR)); +int runargv ANSI((CELLPTR, int, int, int, int, char *)); +void Clean_up_processes ANSI(()); +int Wait_for_child ANSI((int, int)); +int If_root_path ANSI((char *)); +time_t seek_arch ANSI((char *, char *)); + +#endif diff --git a/dmake/tos/putenv.c b/dmake/tos/putenv.c new file mode 100644 index 000000000000..06e914d1fa0f --- /dev/null +++ b/dmake/tos/putenv.c @@ -0,0 +1,78 @@ +/* RCS $Id: putenv.c,v 1.1.1.1 2000-09-22 15:33:33 hr Exp $ +-- +-- SYNOPSIS +-- My own putenv for BSD like systems. +-- +-- DESCRIPTION +-- This originally came from MKS, but I rewrote it to fix a bug with +-- replacing existing strings, probably never happened but the code +-- was wrong nonetheless. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include <stdio.h> +#include <string.h> + +int +putenv( str )/* +=============== + Take a string of the form NAME=value and stick it into the environment. + We do this by allocating a new set of pointers if we have to add a new + string and by replacing an existing pointer if the value replaces the value + of an existing string. */ +char *str; +{ + extern char **environ; /* The current environment. */ + static char **ourenv = NULL; /* A new environment */ + register char **p; + register char *q; + int size; + + /* First search the current environment and see if we can replace a + * string. */ + for( p=environ; *p; p++ ) { + register char *s = str; + + for( q = *p; *q && *s && *s == *q; q++, s++ ) + if( *s == '=' ) { + *p = str; + return(0); /* replaced it so go away */ + } + } + + /* Ok, can't replace a string so need to grow the environment. */ + size = p - environ + 2; /* size of new environment */ + /* size of old is size-1 */ + + /* It's the first time, so allocate a new environment since we don't know + * where the old one is comming from. */ + if( ourenv == NULL ) { + if( (ourenv = (char **) malloc( sizeof(char *)*size )) == NULL ) + return(1); + + memcpy( (char *)ourenv, (char *)environ, (size-2)*sizeof(char *) ); + } + else if( (ourenv = (char **)realloc( ourenv, size*sizeof(char *))) == NULL ) + return(1); + + ourenv[--size] = NULL; + ourenv[--size] = str; + + environ = ourenv; + return(0); +} diff --git a/dmake/tos/ruletab.c b/dmake/tos/ruletab.c new file mode 100644 index 000000000000..4e70c19621d4 --- /dev/null +++ b/dmake/tos/ruletab.c @@ -0,0 +1,42 @@ +/* RCS $Id: ruletab.c,v 1.1.1.1 2000-09-22 15:33:33 hr Exp $ +-- +-- SYNOPSIS +-- Default initial configuration of dmake. +-- +-- DESCRIPTION +-- Define here the initial set of rules that are defined before +-- dmake performs any processing. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +/* These are control macros for dmake that MUST be defined at some point + * if they are NOT dmake will not work! These are default definitions. They + * may be overridden inside the .STARTUP makefile, they are here + * strictly so that dmake can parse the STARTUP makefile */ + +static char *_rules[] = { + "MAXPROCESSLIMIT := 1", + "MAXPROCESS := 1", + "MAXLINELENGTH := 8190", + ".IMPORT .IGNORE: ROOTDIR", + ".MAKEFILES : makefile.mk Makefile makefile", + ".SOURCE : .NULL", +#include "startup.h" + 0 }; + +char **Rule_tab = _rules; /* for sundry reasons in Get_environment() */ diff --git a/dmake/tos/startup.h b/dmake/tos/startup.h new file mode 100644 index 000000000000..216f463ded56 --- /dev/null +++ b/dmake/tos/startup.h @@ -0,0 +1,27 @@ +/* RCS $Id: startup.h,v 1.1.1.1 2000-09-22 15:33:33 hr Exp $ +-- +-- SYNOPSIS +-- Definition of MAKESTARTUP +-- +-- DESCRIPTION +-- Default MAKESTARTUP value defining where dmake locates the +-- startup file. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +"MAKESTARTUP := $(ROOTDIR)/etc/startup/startup.mk", diff --git a/dmake/tos/sysintf.h b/dmake/tos/sysintf.h new file mode 100644 index 000000000000..6ac5dce2c4b2 --- /dev/null +++ b/dmake/tos/sysintf.h @@ -0,0 +1,46 @@ +/* RCS $Id: sysintf.h,v 1.1.1.1 2000-09-22 15:33:33 hr Exp $ +-- +-- SYNOPSIS +-- Interfaces for sysintf.c +-- +-- DESCRIPTION +-- Abstractions of functions in sysintf.c +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#define DMSTAT stat +#define VOID_LCACHE(l,m) (void) void_lcache(l,m) +#define Hook_std_writes(A) +#define GETPID getpid() +#define DMSTRLWR(A,B) + +/* for directory cache */ +#define CacheStat(A,B) really_dostat(A,&buf) + +/* +** standard C items +*/ + +/* +** DOS interface standard items +*/ +#define getswitchar() '-' + +/* +** make parameters +*/ diff --git a/dmake/tos/template.mk b/dmake/tos/template.mk new file mode 100644 index 000000000000..91ce656f14b0 --- /dev/null +++ b/dmake/tos/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= tos + OSRELEASE *:= + OSENVIRONMENT *:= diff --git a/dmake/tos/tempnam.c b/dmake/tos/tempnam.c new file mode 100644 index 000000000000..8c0e3077d65a --- /dev/null +++ b/dmake/tos/tempnam.c @@ -0,0 +1,104 @@ +/* RCS $Id: tempnam.c,v 1.1.1.1 2000-09-22 15:33:33 hr Exp $ +-- +-- SYNOPSIS +-- tempnam +-- +-- DESCRIPTION +-- temp file name generation routines. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + + +/*LINTLIBRARY*/ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +#define max(A,B) (((A)<(B))?(B):(A)) + +extern char *mktemp(); +extern int access(); + +static char *cpdir(); +static char *seed="AAA"; + +/* BSD stdio.h doesn't define P_tmpdir, so let's do it here */ +#ifndef P_tmpdir +static char *P_tmpdir = "/tmp"; +#endif + +char * +tempnam(dir, prefix) +char *dir; /* use this directory please (if non-NULL) */ +char *prefix; /* use this (if non-NULL) as filename prefix */ +{ + register char *p, *q, *tmpdir; + int tl=0, dl=0, pl; + + pl = strlen(P_tmpdir); + + if( (tmpdir = getenv("TMPDIR")) != NULL ) tl = strlen(tmpdir); + if( dir != NULL ) dl = strlen(dir); + + if( (p = malloc((unsigned)(max(max(dl,tl),pl)+16))) == NULL ) + return(NULL); + + *p = '\0'; + + if( (tl == 0) || (access( cpdir(p, tmpdir), 3) != 0) ) + if( (dl == 0) || (access( cpdir(p, dir), 3) != 0) ) + if( access( cpdir(p, P_tmpdir), 3) != 0 ) + if( access( cpdir(p, "/tmp"), 3) != 0 ) + return(NULL); + + (void) strcat(p, "/"); + if(prefix) + { + *(p+strlen(p)+5) = '\0'; + (void)strncat(p, prefix, 5); + } + + (void)strcat(p, seed); + (void)strcat(p, "XXXXXX"); + + q = seed; + while(*q == 'Z') *q++ = 'A'; + ++*q; + + if(*mktemp(p) == '\0') return(NULL); + return(p); +} + + + +static char * +cpdir(buf, str) +char *buf; +char *str; +{ + char *p; + + if(str != NULL) + { + (void) strcpy(buf, str); + p = buf - 1 + strlen(buf); + if(*p == '/') *p = '\0'; + } + + return(buf); +} diff --git a/dmake/unix/386ix/ar.h b/dmake/unix/386ix/ar.h new file mode 100644 index 000000000000..4c38e8944e99 --- /dev/null +++ b/dmake/unix/386ix/ar.h @@ -0,0 +1,27 @@ +/* RCS $Id: ar.h,v 1.1.1.1 2000-09-22 15:33:33 hr Exp $ +-- +-- SYNOPSIS +-- ar header +-- +-- DESCRIPTION +-- Make sure that PORTAR is defined. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#define PORTAR 1 +#include "/usr/include/ar.h" diff --git a/dmake/unix/386ix/config.mk b/dmake/unix/386ix/config.mk new file mode 100644 index 000000000000..4c1eac92b94d --- /dev/null +++ b/dmake/unix/386ix/config.mk @@ -0,0 +1,27 @@ +# This is the 386IX UNIX configuration file for DMAKE +# It simply modifies the values of SRC, and checks to see if +# OSENVIRONMENT is defined. If so it includes the appropriate +# config.mk file. +# +# It also sets the values of .SOURCE.c and .SOURCE.h to include the local +# directory. +# +osrdir := $(OS)$(DIRSEPSTR)$(OSRELEASE) + +# The following are required sources +OSDSRC := +.IF $(OSDSRC) + SRC += $(OSDSRC) + .SETDIR=$(osrdir) : $(OSDSRC) +.END + +.SOURCE.h : $(osrdir) + +# Local configuration modifications for CFLAGS, there's local SysV includes +# too. +CFLAGS += -I$(osrdir) + +# See if we modify anything in the lower levels. +.IF $(OSENVIRONMENT) != $(NULL) + .INCLUDE .IGNORE : $(osrdir)$(DIRSEPSTR)$(OSENVIRONMENT)$(DIRSEPSTR)config.mk +.END diff --git a/dmake/unix/386ix/make.sh b/dmake/unix/386ix/make.sh new file mode 100644 index 000000000000..68e0109bb576 --- /dev/null +++ b/dmake/unix/386ix/make.sh @@ -0,0 +1,60 @@ +mkdir objects +cc -c -I. -Iunix -Iunix/386ix -O infer.c +mv infer.o objects +cc -c -I. -Iunix -Iunix/386ix -O make.c +mv make.o objects +cc -c -I. -Iunix -Iunix/386ix -O stat.c +mv stat.o objects +cc -c -I. -Iunix -Iunix/386ix -O expand.c +mv expand.o objects +cc -c -I. -Iunix -Iunix/386ix -O dmstring.c +mv dmstring.o objects +cc -c -I. -Iunix -Iunix/386ix -O hash.c +mv hash.o objects +cc -c -I. -Iunix -Iunix/386ix -O dag.c +mv dag.o objects +cc -c -I. -Iunix -Iunix/386ix -O dmake.c +mv dmake.o objects +cc -c -I. -Iunix -Iunix/386ix -O path.c +mv path.o objects +cc -c -I. -Iunix -Iunix/386ix -O imacs.c +mv imacs.o objects +cc -c -I. -Iunix -Iunix/386ix -O sysintf.c +mv sysintf.o objects +cc -c -I. -Iunix -Iunix/386ix -O parse.c +mv parse.o objects +cc -c -I. -Iunix -Iunix/386ix -O getinp.c +mv getinp.o objects +cc -c -I. -Iunix -Iunix/386ix -O quit.c +mv quit.o objects +cc -c -I. -Iunix -Iunix/386ix -O state.c +mv state.o objects +cc -c -I. -Iunix -Iunix/386ix -O dmdump.c +mv dmdump.o objects +cc -c -I. -Iunix -Iunix/386ix -O macparse.c +mv macparse.o objects +cc -c -I. -Iunix -Iunix/386ix -O rulparse.c +mv rulparse.o objects +cc -c -I. -Iunix -Iunix/386ix -O percent.c +mv percent.o objects +cc -c -I. -Iunix -Iunix/386ix -O function.c +mv function.o objects +cc -c -I. -Iunix -Iunix/386ix -O unix/arlib.c +mv arlib.o objects +cc -c -I. -Iunix -Iunix/386ix -O unix/dirbrk.c +mv dirbrk.o objects +cc -c -I. -Iunix -Iunix/386ix -O unix/rmprq.c +mv rmprq.o objects +cc -c -I. -Iunix -Iunix/386ix -O unix/ruletab.c +mv ruletab.o objects +cc -c -I. -Iunix -Iunix/386ix -O unix/runargv.c +mv runargv.o objects +cc -c -I. -Iunix -Iunix/386ix -O unix/dcache.c +mv dcache.o objects +cc -O -o dmake objects/infer.o objects/make.o objects/stat.o objects/expand.o \ +objects/dmstring.o objects/hash.o objects/dag.o objects/dmake.o objects/path.o \ +objects/imacs.o objects/sysintf.o objects/parse.o objects/getinp.o \ +objects/quit.o objects/state.o objects/dmdump.o objects/macparse.o \ +objects/rulparse.o objects/percent.o objects/function.o objects/arlib.o \ +objects/dirbrk.o objects/rmprq.o objects/ruletab.o objects/runargv.o objects/dcache.o +cp unix/386ix/template.mk startup/config.mk diff --git a/dmake/unix/386ix/public.h b/dmake/unix/386ix/public.h new file mode 100644 index 000000000000..eced883f353d --- /dev/null +++ b/dmake/unix/386ix/public.h @@ -0,0 +1,164 @@ +/* RCS $Id: public.h,v 1.1.1.1 2000-09-22 15:33:33 hr Exp $ +-- WARNING -- This file is AUTOMATICALLY GENERATED DO NOT EDIT IT +-- +-- +-- SYNOPSIS +-- Local functions exported to be visible by others. +-- +-- DESCRIPTION +-- This file is generated by 'genpub'. Function declarations +-- that appear in this file are extracted by 'genpub' from +-- source files. Any function in the source file whose definition +-- appears like: +-- +-- PUBLIC return_type +-- function( arg_list ); +-- type_expr1 arg1; +-- ... +-- +-- has its definition extracted and a line of the form: +-- +-- return_type function ANSI((type_expr1,type_expr2,...)); +-- +-- entered into the output file. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef _DMAKE_PUBLIC_h +#define _DMAKE_PUBLIC_h + +#ifdef EXTERN +#undef EXTERN +#endif +#if defined(DEFINE_DMAKE_VARIABLES) +#define EXTERN +#else +#define EXTERN extern +#endif + +/***** genpub: Begin list of generated function headers */ +void Infer_recipe ANSI((CELLPTR, CELLPTR)); +int Make_targets ANSI(()); +int Make ANSI((CELLPTR, CELLPTR)); +int Exec_commands ANSI((CELLPTR)); +void Print_cmnd ANSI((char *, int, int)); +int Push_dir ANSI((char *, char *, int)); +void Pop_dir ANSI((int)); +void Append_line ANSI((char *, int, FILE *, char *, int, int)); +void Stat_target ANSI((CELLPTR, int, int)); +char *Expand ANSI((char *)); +char *Apply_edit ANSI((char *, char *, char *, int, int)); +void Map_esc ANSI((char *)); +char* Apply_modifiers ANSI((int, char *)); +char* Tokenize ANSI((char *, char *, char, int)); +char* ScanToken ANSI((char *, char **, int)); +char *DmStrJoin ANSI((char *, char *, int, int)); +char *DmStrAdd ANSI((char *, char *, int)); +char *DmStrApp ANSI((char *, char *)); +char *DmStrDup ANSI((char *)); +char *DmStrDup2 ANSI((char *)); +char *DmStrPbrk ANSI((char *, char *)); +char *DmStrSpn ANSI((char *, char *)); +char *DmStrStr ANSI((char *, char *)); +char *DmSubStr ANSI((char *, char *)); +uint16 Hash ANSI((char *, uint32 *)); +HASHPTR Get_name ANSI((char *, HASHPTR *, int)); +HASHPTR Search_table ANSI((HASHPTR *, char *, uint16 *, uint32 *)); +HASHPTR Push_macro ANSI((HASHPTR)); +HASHPTR Pop_macro ANSI((HASHPTR)); +HASHPTR Def_macro ANSI((char *, char *, int)); +CELLPTR Def_cell ANSI((char *)); +LINKPTR Add_prerequisite ANSI((CELLPTR, CELLPTR, int, int)); +void Clear_prerequisites ANSI((CELLPTR)); +int Test_circle ANSI((CELLPTR, int)); +STRINGPTR Def_recipe ANSI((char *, STRINGPTR, int, int)); +t_attr Rcp_attribute ANSI((char *)); +void main ANSI((int, char **)); +FILE *Openfile ANSI((char *, int, int)); +FILE *Closefile ANSI(()); +FILE *Search_file ANSI((char *, char **)); +char *Filename ANSI(()); +int Nestlevel ANSI(()); +FILE *TryFiles ANSI((LINKPTR)); +void Fatal ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Error ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Warning ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void No_ram ANSI(()); +void Usage ANSI((int)); +void Version ANSI(()); +char *Get_suffix ANSI((char *)); +char *Basename ANSI((char *)); +char *Filedir ANSI((char *)); +char *Build_path ANSI((char *, char *)); +void Make_rules ANSI(()); +void Create_macro_vars ANSI(()); +time_t Do_stat ANSI((char *, char *, char **, int)); +int Do_touch ANSI((char *, char *, char **)); +void Void_lib_cache ANSI((char *, char *)); +time_t Do_time ANSI(()); +int Do_cmnd ANSI((char *, int, int, CELLPTR, int, int, int)); +char ** Pack_argv ANSI((int, int, char *)); +char *Read_env_string ANSI((char *)); +int Write_env_string ANSI((char *, char *)); +void ReadEnvironment ANSI(()); +void Catch_signals ANSI((void (*)())); +void Clear_signals ANSI(()); +void Prolog ANSI((int, char* [])); +void Epilog ANSI((int)); +char *Get_current_dir ANSI(()); +int Set_dir ANSI((char*)); +char Get_switch_char ANSI(()); +FILE* Get_temp ANSI((char **, char *, int)); +FILE *Start_temp ANSI((char *, CELLPTR, char **)); +void Open_temp_error ANSI((char *, char *)); +void Link_temp ANSI((CELLPTR, FILE *, char *)); +void Close_temp ANSI((CELLPTR, FILE *)); +void Unlink_temp_files ANSI((CELLPTR)); +void Handle_result ANSI((int, int, int, CELLPTR)); +void Update_time_stamp ANSI((CELLPTR)); +int Remove_file ANSI((char *)); +void Parse ANSI((FILE *)); +int Get_line ANSI((char *, FILE *)); +char *Do_comment ANSI((char *, char **, int)); +char *Get_token ANSI((TKSTRPTR, char *, int)); +void Quit ANSI(()); +void Read_state ANSI(()); +void Write_state ANSI(()); +int Check_state ANSI((CELLPTR, STRINGPTR *, int)); +void Dump ANSI(()); +void Dump_recipe ANSI((STRINGPTR)); +int Parse_macro ANSI((char *, int)); +int Macro_op ANSI((char *)); +int Parse_rule_def ANSI((int *)); +int Rule_op ANSI((char *)); +void Add_recipe_to_list ANSI((char *, int, int)); +void Bind_rules_to_targets ANSI((int)); +int Set_group_attributes ANSI((char *)); +DFALINKPTR Match_dfa ANSI((char *)); +void Check_circle_dfa ANSI(()); +void Add_nfa ANSI((char *)); +char *Exec_function ANSI((char *)); +time_t seek_arch ANSI((char *, char *)); +int If_root_path ANSI((char *)); +void Remove_prq ANSI((CELLPTR)); +int runargv ANSI((CELLPTR, int, int, int, int, char *)); +int Wait_for_child ANSI((int, int)); +void Clean_up_processes ANSI(()); +time_t CacheStat ANSI((char *, int)); + +#endif diff --git a/dmake/unix/386ix/stdlib.h b/dmake/unix/386ix/stdlib.h new file mode 100644 index 000000000000..1ec47228432b --- /dev/null +++ b/dmake/unix/386ix/stdlib.h @@ -0,0 +1,44 @@ +/* RCS $Id: stdlib.h,v 1.1.1.1 2000-09-22 15:33:33 hr Exp $ +-- +-- SYNOPSIS +-- stdlib interface +-- +-- DESCRIPTION +-- Specially needed pieces of interface to the standard C lib. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef _STDLIB_INCLUDED_ +#define _STDLIB_INCLUDED_ + +extern /*GOTO*/ _exit(); +extern /*GOTO*/ exit(); +extern /*GOTO*/ abort(); +extern int system(); +extern char *getenv(); +extern char *calloc(); +extern char *malloc(); +extern char *realloc(); +extern free(); +extern int errno; + +#ifndef EIO +# include <errno.h> +#endif + +#endif /* _STDLIB_INCLUDED_ */ diff --git a/dmake/unix/386ix/template.mk b/dmake/unix/386ix/template.mk new file mode 100644 index 000000000000..e59d37c7ca72 --- /dev/null +++ b/dmake/unix/386ix/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= unix + OSRELEASE *:= 386ix + OSENVIRONMENT *:= diff --git a/dmake/unix/386ix/time.h b/dmake/unix/386ix/time.h new file mode 100644 index 000000000000..aff117b02ade --- /dev/null +++ b/dmake/unix/386ix/time.h @@ -0,0 +1,35 @@ +/* RCS $Id: time.h,v 1.1.1.1 2000-09-22 15:33:33 hr Exp $ +-- +-- SYNOPSIS +-- time_t +-- +-- DESCRIPTION +-- Properly define time_t. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +/* +** Berkeley get this wrong! +*/ +#ifndef TIME_h +#define TIME_h + +typedef long time_t; /* this is the thing we use */ + +#endif TIME_h + diff --git a/dmake/unix/arlib.c b/dmake/unix/arlib.c new file mode 100644 index 000000000000..22a2168cfed1 --- /dev/null +++ b/dmake/unix/arlib.c @@ -0,0 +1,609 @@ +/* RCS $Id: arlib.c,v 1.1.1.1 2000-09-22 15:33:33 hr Exp $ +-- +-- SYNOPSIS +-- Unix archive manipulation code. +-- +-- DESCRIPTION +-- Originally this code was provided by Eric Gisin of MKS. I took +-- his code and completely rewrote it adding cacheing of lib members +-- and other various optimizations. I kept the overal functional +-- idea of the library routines as they are similar to those in GNU +-- make and felt it advantageous to maintain a similar interface. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +/* Sun unix on 386i's has a broken ar.h that does not assume PORTAR format + * by default, so we fix it here. */ +#if defined(i386) || defined(__DGUX__) +#define PORTAR 1 +#endif + +#if !defined (COHERENT) && !defined(__COHERENT__) +#include <ar.h> +#else +#include <arcoff.h> +#endif /* COHERENT, __COHERENT__ */ +#include "extern.h" +#include "sysintf.h" + +/* By defining the defines below it is possible to configure the library + * code for library cacheing/non-cacheing, ASCII archive headers, and a full + * decode of the ar_hdr fields in the scan_ar function. */ + +#ifndef ASCARCH +#define ASCARCH 1 /* ASCII time stored in archive */ +#endif + +#ifndef LC +#define LC 1 /* Turn on library cacheing */ +#endif + +#ifndef CHECKELF +#define CHECKELF 1 /* Enable Elf long member names */ +#endif + +#ifndef DECODE_ALL_AR_FIELDS +#define DECODE_ALL_AR_FIELDS 0 /* decode only fields make needs*/ +#endif + +#ifndef AR_TRUNCATE_MEMBER_NAMES +#define AR_TRUNCATE_MEMBER_NAMES 0 /* truncate member names for */ +#endif /* comparison. */ + +#if LC +# define FOUND_MEMBER FALSE +#else +# define FOUND_MEMBER TRUE +# define _cache_member(a, b, c) +# define _check_cache(a, b, c, d) FALSE +#endif + +#define MAXFNAME 255 /* Max length of member name */ +#define MAXMNAME 8 /* Max module name < MAXFNAME */ + + +/* This struct is used to pass the library and member inrmation about the + * routines that perform the library seeking/cacheing */ +struct ar_args { + char *lib; + char *member; + time_t time; +}; + + +typedef struct AR { + char ar_name[MAXFNAME+1]; /* File name */ + long ar_size; /* Size in bytes */ + time_t ar_time; /* Modification time */ + +#ifdef DOS + char ar_modname[MAXMNAME+1]; /* DOS module name */ +#endif + +#if DECODE_ALL_AR_FIELDS + uint16 ar_mode; /* File mode */ + uint16 ar_uid; /* File owner */ + uint16 ar_gid; /* File group owner */ +#endif +} AR, *ARPTR; + + +static int ar_scan ANSI((FILE *, + int (*) ANSI((FILE *, struct AR *,struct ar_args *)), + struct ar_args *)); +static int ar_touch ANSI(( FILE *, time_t )); +static int time_function ANSI(( FILE *, struct AR *, struct ar_args * )); +static int touch_function ANSI(( FILE *, struct AR *, struct ar_args * )); +static int ar_name_equal ANSI((char *, char *)); + +#if LC +static int _cache_member ANSI((char *, char *, time_t)); +static int _check_cache ANSI((char *, char *, time_t *, int)); +#endif + +/* decoded archive header */ +static AR _ar; +static off_t arhdroffset; /* member seek offset */ + + +PUBLIC time_t +seek_arch(name, lib)/* +====================== + Look for module 'name' inside 'lib'. If compiled with cacheing then first + check to see if the specified lib is cached. If so then return that time + stamp instead of looking into the library. */ +char *name; +char *lib; +{ + FILE *f; + int rv; + time_t mtime; + struct ar_args args; + + /* Check the cache first (if there is a cache) */ + if( _check_cache(name, lib, &mtime, FALSE) ) return( mtime ); + + /* Open the lib file and perform the scan of the members, looking + * for our particular member. If cacheing is enabled it will be + * taken care of automatically during the scan. */ + + args.lib = lib; + args.member = name; + args.time = (time_t)0L; + + if( (f = fopen(lib, "r")) == NIL(FILE) ) return( (time_t)0L ); + rv = ar_scan(f, time_function, &args ); + fclose( f ); + + if( rv < 0 ) Fatal("(%s): Invalid library format", lib); + + return( args.time ); +} + + +int +touch_arch(name, lib)/* +======================= + Look for module 'name' inside 'lib'. If compiled with cacheing then first + check to see if the specified lib is cached. If so then set that time + stamp and write it into the library. Returns 0 on success, non-zero + on failure. */ +char *name; +char *lib; +{ + FILE *f; + int rv; + struct ar_args args; + + /* Open the lib file and perform the scan of the members, looking + * for our particular member. If cacheing is enabled it will be + * taken care of automatically during the scan. */ + + args.lib = lib; + args.member = name; + args.time = (time_t)0L; + + if( (f = fopen(lib, "r+")) == NIL(FILE) ) return( (time_t)1L ); + rv = ar_scan(f, touch_function, &args ); + fclose( f ); + + if( rv < 0 ) Fatal("(%s): Invalid library format", lib); + + return( 0 ); +} + + + +static int +time_function(f, arp, argp)/* +============================= + get library member's time, if it matches than return it in argp, if + cacheing is enabled than cache the library members also. */ +FILE *f; /* library file */ +struct AR *arp; /* library member header */ +struct ar_args *argp; +{ + int rv = _cache_member( arp->ar_name, argp->lib, arp->ar_time ); + + if( ar_name_equal (argp->member, arp->ar_name)) { + argp->time = arp->ar_time; + + if( arp->ar_time == 0 && !(Glob_attr & A_SILENT) ) + Warning( "(%s): Can't extract library member timestamp; using EPOCH", + argp->member); + + return( rv ); /* 1 => no cacheing, 0 => cacheing */ + } + + return( FALSE ); /* continue scan */ +} + + + +static int +touch_function(f, arp, argp)/* +============================== + Update library member's time stamp, and write new time value into cache + if required. */ +FILE *f; /* library file */ +struct AR *arp; /* library member header */ +struct ar_args *argp; +{ + extern time_t time ANSI(( time_t * )); + time_t now = time((time_t*) NULL); /* Current time. */ + + if( ar_name_equal(argp->member, arp->ar_name) ) { + _check_cache( argp->member, argp->lib, &now, TRUE ); + ar_touch(f, now ); + + return( TRUE ); + } + + return( FALSE ); /* continue scan */ +} + + +static int +ar_name_equal (char * name1, char * name2) +{ + int equal; + +#if AR_TRUNCATE_MEMBER_NAMES + struct ar_hdr hdr; + + equal = !strncmp (name1, name2, sizeof (hdr.ar_name)-1); +#else + equal = !strcmp (name1, name2); +#endif + + return equal; +} + + +static int +ar_scan(f, function, arg)/* +=========================== + Scan the opened archive, and call the given function for each member found. + The function will be called with the file positioned at the beginning of + the member and it can read up to arp->ar_size bytes of the archive member. + If the function returns 1, we stop and return 1. We return 0 at the end + of the archive, or -1 if the archive has invalid format. This interface + is more general than required by "make", but it can be used by other + utilities. */ +register FILE *f; +int (*function) ANSI((FILE *, struct AR *, struct ar_args *)); +struct ar_args *arg; +{ + extern long atol (); + register char *p; + struct ar_hdr arhdr; /* archive member header */ + long nsize; /* size of member name */ + long arind=0; /* archive index offset */ + int process; +#if defined(_AIX) + struct fl_hdr flhdr; /* archive file header */ + char magic[SAIAMAG]; /* size of magic string */ +#else +#if ASCARCH + char magic[SARMAG]; +#else + unsigned short word; +#endif +#endif + + fseek( f, 0L, 0 ); /* Start at the beginning of the archive file */ + +#if ASCARCH +#if defined(_AIX) + fread( (char *)&flhdr, sizeof(flhdr), 1, f ); + if( strncmp(flhdr.fl_magic,AIAMAG, SAIAMAG) != 0 ) return(-1); + fseek(f, atol(flhdr.fl_fstmoff), 0 ); /* postition to first member */ +#else + fread( magic, sizeof(magic), 1, f ); + if( strncmp(magic, ARMAG, SARMAG) != 0 ) return( -1 ); +#endif +#else + fread( (char*)&word, sizeof(word), 1, f ); + if( word != ARMAG ) return( -1 ); +#endif + + /* scan the library, calling `function' for each member + */ + while( 1 ) { + arhdroffset = ftell(f); +#if defined(_AIX) + if( fread((char*)&arhdr,sizeof(arhdr)-sizeof(arhdr._ar_name),1,f)!=1) + break; + nsize = atoi(arhdr.ar_namlen); + fseek(f, arhdroffset+(unsigned long)(((struct ar_hdr *)0)->_ar_name.ar_name), 0); + if( fread((char*)_ar.ar_name,nsize,1,f)!=1) + break; + _ar.ar_name[nsize]='\0'; +#else + if( fread((char*) &arhdr, sizeof(arhdr), 1, f) != 1 ) break; + strncpy(_ar.ar_name, arhdr.ar_name, nsize = sizeof(arhdr.ar_name)); +#endif + + for( p = &_ar.ar_name[nsize]; + --p >= _ar.ar_name && *p == ' ';); + + p[1] = '\0'; + if( *p == '/' ) *p = 0; /* SysV has trailing '/' */ + + /* check to see if this is an archive index using SsysV Index scheme. + * see ar(4) man page for more info */ +#if CHECKELF + if( _ar.ar_name[0] == '/' && _ar.ar_name[1] == '\0' ) { + arind = arhdroffset+sizeof(arhdr); + process = 0; + } + else +#endif + process = 1; + +#if !defined(_AIX) +#if ASCARCH + if( strncmp(arhdr.ar_fmag, ARFMAG, sizeof(arhdr.ar_fmag)) != 0 ) + return( -1 ); + _ar.ar_time = atol(arhdr.ar_date); + _ar.ar_size = atol(arhdr.ar_size); +#else + _ar.ar_time = arhdr.ar_date; + _ar.ar_size = arhdr.ar_size; +#endif +#if CHECKELF + /* check for names of the form /xxxx where xxxx is an offset into the + * name table pointed at by arind. */ + if(arind && _ar.ar_name[0] == '/') { + long offset = atol(_ar.ar_name+1); + long here = ftell(f); + int c; + + fseek(f, arind+offset, 0); + p = _ar.ar_name; + while((c=fgetc(f)) != EOF) { + *p++ = c; + if(c == '/') { + p[-1] = '\0'; + break; + } + } + + if (c==EOF) return(-1); /* 'c' should never be EOF */ + fseek(f, here, 0); + } +#endif +#else +#if ASCARCH + _ar.ar_time = atol(arhdr.ar_date); + _ar.ar_size = atol(arhdr.ar_nxtmem); +#else + _ar.ar_time = arhdr.ar_date; + _ar.ar_size = arhdr.ar_nxtmem; +#endif +#endif + + +#if DECODE_ALL_AR_FIELDS +#if ASCARCH + _ar.ar_mode = atoi(arhdr.ar_mode); + _ar.ar_uid = atoi(arhdr.ar_uid); + _ar.ar_gid = atoi(arhdr.ar_gid); +#else + _ar.ar_mode = arhdr.ar_mode; + _ar.ar_uid = arhdr.ar_uid; + _ar.ar_gid = arhdr.ar_gid; +#endif +#endif + if( process && (*function)(f, &_ar, arg) ) return( 1 ); + +#if defined(_AIX) + if( _ar.ar_size == 0L ) break; + fseek( f, (long) _ar.ar_size, 0 ); +#else + fseek( f, arhdroffset + sizeof(arhdr) + (_ar.ar_size+1 & ~1L), 0 ); +#endif + } + +#if !defined(_AIX) + if( !feof(f) ) return( -1 ); +#endif + return 0; +} + + + +static int +ar_touch( f, now )/* +==================== + touch module header timestamp. */ +FILE *f; +time_t now; +{ + struct ar_hdr arhdr; /* external archive header */ + + fseek(f, arhdroffset + (unsigned long)(((struct ar_hdr *)0)->ar_date), 0); + +#if ASCARCH + fprintf(f, "%lu", now); +#else + fwrite((char *)now, sizeof(now), 1, f); +#endif + + return( ferror(f) ? 0 : 1 ); +} + + +#if LC +typedef struct mem { + time_t m_time; /* modify time of member*/ + struct mem *m_next; /* next member in lib */ + char m_valid; /* valid cache entry */ + char m_name[1]; /* lib member name */ +} MEM, *MEMPTR; + +typedef struct lib { + struct lib *lb_next; /* next library in list */ + struct mem *lb_members; /* list of lib members */ + char lb_valid; /* valid cache entry */ + char *lb_name; /* library name */ +} LIB, *LIBPTR; + +static LIBPTR _cache = NIL(LIB); +static MEMPTR _find_member ANSI(( LIBPTR, char * )); + +static int +_check_cache( name, lib, pmtime, touch )/* +========================================== + Check to see if we have cached member in lib, if so return time in pmtime + and return TRUE, otherwise return FALSE, if touch is TRUE then touch + the archive member instead. */ +char *name; +char *lib; +time_t *pmtime; +int touch; +{ + register MEMPTR mp; + register LIBPTR lp; + + for( lp=_cache; lp != NIL(LIB) && lp->lb_name != lib; lp=lp->lb_next ); + if( lp == NIL(LIB) ) return( FALSE ); + + mp = _find_member( lp, name ); + if( mp == NIL(MEM) || !mp->m_valid ) return( FALSE ); + + if( touch == TRUE ) + { + mp->m_time = *pmtime; + mp->m_valid = 1; + } + else + *pmtime = mp->m_time; + + lp->lb_valid = 1; + lp->lb_members = mp; + + return( TRUE ); +} + + + +static int +_cache_member( name, lib, mtime )/* +=================================== + Cache name in lib along with it's time */ +char *name; +char *lib; +time_t mtime; +{ + register MEMPTR mp; + register LIBPTR lp; + + for( lp=_cache; + lp != NIL(LIB) && lp->lb_name != NIL(char) && lp->lb_name != lib; + lp=lp->lb_next); + + if( lp == NIL(LIB) ) + { + lp = (LIBPTR) malloc(sizeof(LIB)); + if( lp == NIL(LIB) ) No_ram(); + + lp->lb_name = lib; + lp->lb_members = NIL(MEM); + lp->lb_next = _cache; + lp->lb_valid = 0; + _cache = lp; + } + + /* On UNIX ar does not allow multiple copies of the same .o file to live + * in the same AR file. If this is not TRUE then use the commented out + * version to set the value of mp. */ + + /*mp = _find_member(lp, name);*/ + mp = NIL(MEM); + + if( mp == NIL(MEM) ) + { + mp = (MEMPTR) malloc(sizeof(char)*offsetof(MEM,m_name[strlen(name)+1])); + if( mp == NIL(MEM) ) No_ram(); + + strcpy( mp->m_name, name ); + mp->m_time = mtime; + + if( lp->lb_members == NIL(MEM) ) { + mp->m_next = mp; + lp->lb_members = mp; + } + else { + mp->m_next = lp->lb_members->m_next; + lp->lb_members->m_next = mp; + lp->lb_members = mp; + } + } + else + mp->m_time = mtime; + + mp->m_valid = 1; + + return( lp->lb_valid ); +} + + +static MEMPTR +_find_member( lp, name ) +LIBPTR lp; +char *name; +{ + register MEMPTR mp = lp->lb_members; + + if( mp == NIL(MEM) ) return(mp); + + do { + if( !strcmp(mp->m_name, name ) ) return( mp ); + mp = mp->m_next; + } + while( mp != lp->lb_members ); + + return( NIL(MEM) ); +} +#endif + + + +void +void_lcache( lib, member )/* +============================ + Void the library cache for lib. If member is NIL(char) then nuke all + of the members, if member is NOT NIL(char) then invalidate only that + member. */ +char *lib; +char *member; +{ +#if LC + register LIBPTR lp; + register MEMPTR mp; + register MEMPTR tmp; + + for( lp=_cache; lp != NIL(LIB) && lp->lb_name != lib; lp=lp->lb_next ); + if( lp == NIL(LIB) ) return; + + if( member == NIL(char) ) { + mp = lp->lb_members; + do { + tmp = mp->m_next; + (void) free( mp ); + mp = tmp; + } while( mp != lp->lb_members ); + + lp->lb_valid = 0; + lp->lb_members = NIL(MEM); + lp->lb_name = NIL(char); + } + else { + mp=lp->lb_members; + do { + if( strcmp( member, mp->m_name) == 0 ) { + lp->lb_members = mp->m_next; + mp->m_valid = 0; + } + + mp=mp->m_next; + } while( mp != lp->lb_members ); + } +#endif +} diff --git a/dmake/unix/bsd43/config.mk b/dmake/unix/bsd43/config.mk new file mode 100644 index 000000000000..e99937342e68 --- /dev/null +++ b/dmake/unix/bsd43/config.mk @@ -0,0 +1,27 @@ +# This is the BSD 4.3 UNIX configuration file for DMAKE +# It simply modifies the values of SRC, and checks to see if +# OSENVIRONMENT is defined. If so it includes the appropriate +# config.mk file. +# +# It also sets the values of .SOURCE.c and .SOURCE.h to include the local +# directory. +# +osrdir := $(OS)$(DIRSEPSTR)$(OSRELEASE) + +# The following sources are required for BSD4.3 +OSDSRC := putenv.c tempnam.c utime.c setvbuf.c +.IF $(OSDSRC) + SRC += $(OSDSRC) + .SETDIR=$(osrdir) : $(OSDSRC) +.END + +.SOURCE.h : $(osrdir) + +# Local configuration modifications for CFLAGS, there's local BSD includes +# too. +CFLAGS += -I$(osrdir) + +# See if we modify anything in the lower levels. +.IF $(OSENVIRONMENT) != $(NULL) + .INCLUDE .IGNORE : $(osrdir)$(DIRSEPSTR)$(OSENVIRONMENT)$(DIRSEPSTR)config.mk +.END diff --git a/dmake/unix/bsd43/dirent.h b/dmake/unix/bsd43/dirent.h new file mode 100644 index 000000000000..82f910ed3a7d --- /dev/null +++ b/dmake/unix/bsd43/dirent.h @@ -0,0 +1,28 @@ +/* RCS $Id: dirent.h,v 1.1.1.1 2000-09-22 15:33:33 hr Exp $ +-- +-- SYNOPSIS +-- dirent +-- +-- DESCRIPTION +-- Deal with sysV'ish dirent.h on BSD4.3 systems, which have the stuff +-- in sys/dir.h +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include <sys/dir.h> +#define dirent direct diff --git a/dmake/unix/bsd43/limits.h b/dmake/unix/bsd43/limits.h new file mode 100644 index 000000000000..a08805d00d66 --- /dev/null +++ b/dmake/unix/bsd43/limits.h @@ -0,0 +1,32 @@ +/* RCS $Id: limits.h,v 1.1.1.1 2000-09-22 15:33:33 hr Exp $ +-- +-- SYNOPSIS +-- limits +-- +-- DESCRIPTION +-- Compensate for systems that don't have a limits.h header file. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include <sys/types.h> +#include <sys/dirent.h> +#include <sys/param.h> + +#define NAME_MAX MAXNAMLEN +#define PATH_MAX MAXPATHLEN +#define CHILD_MAX 20 diff --git a/dmake/unix/bsd43/make.sh b/dmake/unix/bsd43/make.sh new file mode 100644 index 000000000000..e45d01952f46 --- /dev/null +++ b/dmake/unix/bsd43/make.sh @@ -0,0 +1,69 @@ +mkdir objects +cc -c -I. -Iunix -Iunix/bsd43 -O infer.c +mv infer.o objects +cc -c -I. -Iunix -Iunix/bsd43 -O make.c +mv make.o objects +cc -c -I. -Iunix -Iunix/bsd43 -O stat.c +mv stat.o objects +cc -c -I. -Iunix -Iunix/bsd43 -O expand.c +mv expand.o objects +cc -c -I. -Iunix -Iunix/bsd43 -O dmstring.c +mv dmstring.o objects +cc -c -I. -Iunix -Iunix/bsd43 -O hash.c +mv hash.o objects +cc -c -I. -Iunix -Iunix/bsd43 -O dag.c +mv dag.o objects +cc -c -I. -Iunix -Iunix/bsd43 -O dmake.c +mv dmake.o objects +cc -c -I. -Iunix -Iunix/bsd43 -O path.c +mv path.o objects +cc -c -I. -Iunix -Iunix/bsd43 -O imacs.c +mv imacs.o objects +cc -c -I. -Iunix -Iunix/bsd43 -O sysintf.c +mv sysintf.o objects +cc -c -I. -Iunix -Iunix/bsd43 -O parse.c +mv parse.o objects +cc -c -I. -Iunix -Iunix/bsd43 -O getinp.c +mv getinp.o objects +cc -c -I. -Iunix -Iunix/bsd43 -O quit.c +mv quit.o objects +cc -c -I. -Iunix -Iunix/bsd43 -O state.c +mv state.o objects +cc -c -I. -Iunix -Iunix/bsd43 -O dmdump.c +mv dmdump.o objects +cc -c -I. -Iunix -Iunix/bsd43 -O macparse.c +mv macparse.o objects +cc -c -I. -Iunix -Iunix/bsd43 -O rulparse.c +mv rulparse.o objects +cc -c -I. -Iunix -Iunix/bsd43 -O percent.c +mv percent.o objects +cc -c -I. -Iunix -Iunix/bsd43 -O function.c +mv function.o objects +cc -c -I. -Iunix -Iunix/bsd43 -O unix/arlib.c +mv arlib.o objects +cc -c -I. -Iunix -Iunix/bsd43 -O unix/dirbrk.c +mv dirbrk.o objects +cc -c -I. -Iunix -Iunix/bsd43 -O unix/rmprq.c +mv rmprq.o objects +cc -c -I. -Iunix -Iunix/bsd43 -O unix/ruletab.c +mv ruletab.o objects +cc -c -I. -Iunix -Iunix/bsd43 -O unix/runargv.c +mv runargv.o objects +cc -c -I. -Iunix -Iunix/bsd43 -O unix/dcache.c +mv dcache.o objects +cc -c -I. -Iunix -Iunix/bsd43 -O unix/bsd43/putenv.c +mv putenv.o objects +cc -c -I. -Iunix -Iunix/bsd43 -O unix/bsd43/tempnam.c +mv tempnam.o objects +cc -c -I. -Iunix -Iunix/bsd43 -O unix/bsd43/utime.c +mv utime.o objects +cc -c -I. -Iunix -Iunix/bsd43 -O unix/bsd43/setvbuf.c +mv setvbuf.o objects +cc -O -o dmake objects/infer.o objects/make.o objects/stat.o objects/expand.o \ +objects/dmstring.o objects/hash.o objects/dag.o objects/dmake.o objects/path.o \ +objects/imacs.o objects/sysintf.o objects/parse.o objects/getinp.o \ +objects/quit.o objects/state.o objects/dmdump.o objects/macparse.o \ +objects/rulparse.o objects/percent.o objects/function.o objects/arlib.o \ +objects/dirbrk.o objects/rmprq.o objects/ruletab.o objects/runargv.o \ +objects/dcache.o objects/putenv.o objects/tempnam.o objects/utime.o objects/setvbuf.o +cp unix/bsd43/template.mk startup/config.mk diff --git a/dmake/unix/bsd43/public.h b/dmake/unix/bsd43/public.h new file mode 100644 index 000000000000..eced883f353d --- /dev/null +++ b/dmake/unix/bsd43/public.h @@ -0,0 +1,164 @@ +/* RCS $Id: public.h,v 1.1.1.1 2000-09-22 15:33:33 hr Exp $ +-- WARNING -- This file is AUTOMATICALLY GENERATED DO NOT EDIT IT +-- +-- +-- SYNOPSIS +-- Local functions exported to be visible by others. +-- +-- DESCRIPTION +-- This file is generated by 'genpub'. Function declarations +-- that appear in this file are extracted by 'genpub' from +-- source files. Any function in the source file whose definition +-- appears like: +-- +-- PUBLIC return_type +-- function( arg_list ); +-- type_expr1 arg1; +-- ... +-- +-- has its definition extracted and a line of the form: +-- +-- return_type function ANSI((type_expr1,type_expr2,...)); +-- +-- entered into the output file. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef _DMAKE_PUBLIC_h +#define _DMAKE_PUBLIC_h + +#ifdef EXTERN +#undef EXTERN +#endif +#if defined(DEFINE_DMAKE_VARIABLES) +#define EXTERN +#else +#define EXTERN extern +#endif + +/***** genpub: Begin list of generated function headers */ +void Infer_recipe ANSI((CELLPTR, CELLPTR)); +int Make_targets ANSI(()); +int Make ANSI((CELLPTR, CELLPTR)); +int Exec_commands ANSI((CELLPTR)); +void Print_cmnd ANSI((char *, int, int)); +int Push_dir ANSI((char *, char *, int)); +void Pop_dir ANSI((int)); +void Append_line ANSI((char *, int, FILE *, char *, int, int)); +void Stat_target ANSI((CELLPTR, int, int)); +char *Expand ANSI((char *)); +char *Apply_edit ANSI((char *, char *, char *, int, int)); +void Map_esc ANSI((char *)); +char* Apply_modifiers ANSI((int, char *)); +char* Tokenize ANSI((char *, char *, char, int)); +char* ScanToken ANSI((char *, char **, int)); +char *DmStrJoin ANSI((char *, char *, int, int)); +char *DmStrAdd ANSI((char *, char *, int)); +char *DmStrApp ANSI((char *, char *)); +char *DmStrDup ANSI((char *)); +char *DmStrDup2 ANSI((char *)); +char *DmStrPbrk ANSI((char *, char *)); +char *DmStrSpn ANSI((char *, char *)); +char *DmStrStr ANSI((char *, char *)); +char *DmSubStr ANSI((char *, char *)); +uint16 Hash ANSI((char *, uint32 *)); +HASHPTR Get_name ANSI((char *, HASHPTR *, int)); +HASHPTR Search_table ANSI((HASHPTR *, char *, uint16 *, uint32 *)); +HASHPTR Push_macro ANSI((HASHPTR)); +HASHPTR Pop_macro ANSI((HASHPTR)); +HASHPTR Def_macro ANSI((char *, char *, int)); +CELLPTR Def_cell ANSI((char *)); +LINKPTR Add_prerequisite ANSI((CELLPTR, CELLPTR, int, int)); +void Clear_prerequisites ANSI((CELLPTR)); +int Test_circle ANSI((CELLPTR, int)); +STRINGPTR Def_recipe ANSI((char *, STRINGPTR, int, int)); +t_attr Rcp_attribute ANSI((char *)); +void main ANSI((int, char **)); +FILE *Openfile ANSI((char *, int, int)); +FILE *Closefile ANSI(()); +FILE *Search_file ANSI((char *, char **)); +char *Filename ANSI(()); +int Nestlevel ANSI(()); +FILE *TryFiles ANSI((LINKPTR)); +void Fatal ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Error ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Warning ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void No_ram ANSI(()); +void Usage ANSI((int)); +void Version ANSI(()); +char *Get_suffix ANSI((char *)); +char *Basename ANSI((char *)); +char *Filedir ANSI((char *)); +char *Build_path ANSI((char *, char *)); +void Make_rules ANSI(()); +void Create_macro_vars ANSI(()); +time_t Do_stat ANSI((char *, char *, char **, int)); +int Do_touch ANSI((char *, char *, char **)); +void Void_lib_cache ANSI((char *, char *)); +time_t Do_time ANSI(()); +int Do_cmnd ANSI((char *, int, int, CELLPTR, int, int, int)); +char ** Pack_argv ANSI((int, int, char *)); +char *Read_env_string ANSI((char *)); +int Write_env_string ANSI((char *, char *)); +void ReadEnvironment ANSI(()); +void Catch_signals ANSI((void (*)())); +void Clear_signals ANSI(()); +void Prolog ANSI((int, char* [])); +void Epilog ANSI((int)); +char *Get_current_dir ANSI(()); +int Set_dir ANSI((char*)); +char Get_switch_char ANSI(()); +FILE* Get_temp ANSI((char **, char *, int)); +FILE *Start_temp ANSI((char *, CELLPTR, char **)); +void Open_temp_error ANSI((char *, char *)); +void Link_temp ANSI((CELLPTR, FILE *, char *)); +void Close_temp ANSI((CELLPTR, FILE *)); +void Unlink_temp_files ANSI((CELLPTR)); +void Handle_result ANSI((int, int, int, CELLPTR)); +void Update_time_stamp ANSI((CELLPTR)); +int Remove_file ANSI((char *)); +void Parse ANSI((FILE *)); +int Get_line ANSI((char *, FILE *)); +char *Do_comment ANSI((char *, char **, int)); +char *Get_token ANSI((TKSTRPTR, char *, int)); +void Quit ANSI(()); +void Read_state ANSI(()); +void Write_state ANSI(()); +int Check_state ANSI((CELLPTR, STRINGPTR *, int)); +void Dump ANSI(()); +void Dump_recipe ANSI((STRINGPTR)); +int Parse_macro ANSI((char *, int)); +int Macro_op ANSI((char *)); +int Parse_rule_def ANSI((int *)); +int Rule_op ANSI((char *)); +void Add_recipe_to_list ANSI((char *, int, int)); +void Bind_rules_to_targets ANSI((int)); +int Set_group_attributes ANSI((char *)); +DFALINKPTR Match_dfa ANSI((char *)); +void Check_circle_dfa ANSI(()); +void Add_nfa ANSI((char *)); +char *Exec_function ANSI((char *)); +time_t seek_arch ANSI((char *, char *)); +int If_root_path ANSI((char *)); +void Remove_prq ANSI((CELLPTR)); +int runargv ANSI((CELLPTR, int, int, int, int, char *)); +int Wait_for_child ANSI((int, int)); +void Clean_up_processes ANSI(()); +time_t CacheStat ANSI((char *, int)); + +#endif diff --git a/dmake/unix/bsd43/putenv.c b/dmake/unix/bsd43/putenv.c new file mode 100644 index 000000000000..d0ed998158e0 --- /dev/null +++ b/dmake/unix/bsd43/putenv.c @@ -0,0 +1,78 @@ +/* RCS $Id: putenv.c,v 1.1.1.1 2000-09-22 15:33:34 hr Exp $ +-- +-- SYNOPSIS +-- My own putenv for BSD like systems. +-- +-- DESCRIPTION +-- This originally came from MKS, but I rewrote it to fix a bug with +-- replacing existing strings, probably never happened but the code +-- was wrong nonetheless. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include <stdio.h> +#include <string.h> + +int +putenv( str )/* +=============== + Take a string of the form NAME=value and stick it into the environment. + We do this by allocating a new set of pointers if we have to add a new + string and by replacing an existing pointer if the value replaces the value + of an existing string. */ +char *str; +{ + extern char **environ; /* The current environment. */ + static char **ourenv = NULL; /* A new environment */ + register char **p; + register char *q; + int size; + + /* First search the current environment and see if we can replace a + * string. */ + for( p=environ; *p; p++ ) { + register char *s = str; + + for( q = *p; *q && *s && *s == *q; q++, s++ ) + if( *s == '=' ) { + *p = str; + return(0); /* replaced it so go away */ + } + } + + /* Ok, can't replace a string so need to grow the environment. */ + size = p - environ + 2; /* size of new environment */ + /* size of old is size-1 */ + + /* It's the first time, so allocate a new environment since we don't know + * where the old one is comming from. */ + if( ourenv == NULL ) { + if( (ourenv = (char **) malloc( sizeof(char *)*size )) == NULL ) + return(1); + + memcpy( (char *)ourenv, (char *)environ, (size-2)*sizeof(char *) ); + } + else if( (ourenv = (char **)realloc( ourenv, size*sizeof(char *))) == NULL ) + return(1); + + ourenv[--size] = NULL; + ourenv[--size] = str; + + environ = ourenv; + return(0); +} diff --git a/dmake/unix/bsd43/setvbuf.c b/dmake/unix/bsd43/setvbuf.c new file mode 100644 index 000000000000..ce5d193fbe89 --- /dev/null +++ b/dmake/unix/bsd43/setvbuf.c @@ -0,0 +1,40 @@ +/* RCS $Id: setvbuf.c,v 1.1.1.1 2000-09-22 15:33:34 hr Exp $ +-- +-- SYNOPSIS +-- Setvbuf for BSD +-- +-- DESCRIPTION +-- A sysv call, standard BSD doesn't have this. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include <stdio.h> + +setvbuf(fp, bp, type, len_unused) +FILE* fp; +char* bp; +int type; +int len_unused; +{ + switch (type) { + case _IOLBF: setlinebuf(fp); return; + case _IONBF: setbuf(fp, NULL); return; + default: setbuf(fp, bp); return; + } +} + diff --git a/dmake/unix/bsd43/stdlib.h b/dmake/unix/bsd43/stdlib.h new file mode 100644 index 000000000000..82ab9627cd65 --- /dev/null +++ b/dmake/unix/bsd43/stdlib.h @@ -0,0 +1,44 @@ +/* RCS $Id: stdlib.h,v 1.1.1.1 2000-09-22 15:33:34 hr Exp $ +-- +-- SYNOPSIS +-- stdlib interface +-- +-- DESCRIPTION +-- Specially needed pieces of interface to the standard C lib. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef _STDLIB_INCLUDED_ +#define _STDLIB_INCLUDED_ + +extern /*GOTO*/ _exit(); +extern /*GOTO*/ exit(); +extern /*GOTO*/ abort(); +extern int system(); +extern char *getenv(); +extern char *calloc(); +extern char *malloc(); +extern char *realloc(); +extern free(); +extern int errno; + +#ifndef EIO +# include <errno.h> +#endif + +#endif /* _STDLIB_INCLUDED_ */ diff --git a/dmake/unix/bsd43/string.h b/dmake/unix/bsd43/string.h new file mode 100644 index 000000000000..862c17960a0b --- /dev/null +++ b/dmake/unix/bsd43/string.h @@ -0,0 +1,43 @@ +/* RCS $Id: string.h,v 1.1.1.1 2000-09-22 15:33:34 hr Exp $ +-- +-- SYNOPSIS +-- string function headers +-- +-- DESCRIPTION +-- Supply correct definitions for certain string functions. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ +#ifndef STRING_h +#define STRING_h + +/* +** BSD does this wrong +*/ +#include <strings.h> + +#include "stdmacs.h" +extern char* strpbrk ANSI((char* src, char* any)); + +#ifndef DBUG +#define strchr(str,c) index(str,c) +#define strrchr(str,c) rindex(str,c) +#else +char *strchr ANSI((char*, char)); +char *strrchr ANSI((char*, char)); +#endif +#endif diff --git a/dmake/unix/bsd43/template.mk b/dmake/unix/bsd43/template.mk new file mode 100644 index 000000000000..14a7cab8ed4b --- /dev/null +++ b/dmake/unix/bsd43/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= unix + OSRELEASE *:= bsd43 + OSENVIRONMENT *:= diff --git a/dmake/unix/bsd43/tempnam.c b/dmake/unix/bsd43/tempnam.c new file mode 100644 index 000000000000..12512ec9cb8b --- /dev/null +++ b/dmake/unix/bsd43/tempnam.c @@ -0,0 +1,103 @@ +/* RCS $Id: tempnam.c,v 1.1.1.1 2000-09-22 15:33:34 hr Exp $ +-- +-- SYNOPSIS +-- tempnam +-- +-- DESCRIPTION +-- temp file name generation routines. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +/*LINTLIBRARY*/ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +#define max(A,B) (((A)<(B))?(B):(A)) + +extern char *mktemp(); +extern int access(); + +static char *cpdir(); +static char seed[4]="AAA"; + +/* BSD stdio.h doesn't define P_tmpdir, so let's do it here */ +#ifndef P_tmpdir +static char *P_tmpdir = "/tmp"; +#endif + +char * +tempnam(dir, prefix) +char *dir; /* use this directory please (if non-NULL) */ +char *prefix; /* use this (if non-NULL) as filename prefix */ +{ + register char *p, *q, *tmpdir; + int tl=0, dl=0, pl; + + pl = strlen(P_tmpdir); + + if( (tmpdir = getenv("TMPDIR")) != NULL ) tl = strlen(tmpdir); + if( dir != NULL ) dl = strlen(dir); + + if( (p = malloc((unsigned)(max(max(dl,tl),pl)+16))) == NULL ) + return(NULL); + + *p = '\0'; + + if( (tl == 0) || (access( cpdir(p, tmpdir), 3) != 0) ) + if( (dl == 0) || (access( cpdir(p, dir), 3) != 0) ) + if( access( cpdir(p, P_tmpdir), 3) != 0 ) + if( access( cpdir(p, "/tmp"), 3) != 0 ) + return(NULL); + + (void) strcat(p, "/"); + if(prefix) + { + *(p+strlen(p)+5) = '\0'; + (void)strncat(p, prefix, 5); + } + + (void)strcat(p, seed); + (void)strcat(p, "XXXXXX"); + + q = seed; + while(*q == 'Z') *q++ = 'A'; + ++*q; + + if(*mktemp(p) == '\0') return(NULL); + return(p); +} + + + +static char * +cpdir(buf, str) +char *buf; +char *str; +{ + char *p; + + if(str != NULL) + { + (void) strcpy(buf, str); + p = buf - 1 + strlen(buf); + if(*p == '/') *p = '\0'; + } + + return(buf); +} diff --git a/dmake/unix/bsd43/utime.c b/dmake/unix/bsd43/utime.c new file mode 100644 index 000000000000..9d26700d8006 --- /dev/null +++ b/dmake/unix/bsd43/utime.c @@ -0,0 +1,70 @@ +/* RCS $Id: utime.c,v 1.1.1.1 2000-09-22 15:33:34 hr Exp $ +-- +-- SYNOPSIS +-- utime +-- +-- DESCRIPTION +-- Provide our own utime function. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include <sys/types.h> +#include <sys/time.h> +#include <sys/stat.h> +#include <sys/file.h> + +int +utime(name, timep) +char* name; +time_t timep[2]; +{ + struct timeval tv[2], *tvp; + struct stat buf; + int fil; + char data; + + if (timep!=0) + { + tvp = tv, tv[0].tv_sec = timep[0], tv[1].tv_sec = timep[1]; + if (utimes(name, tvp)==0) + return (0); + } + + if (stat(name, &buf) != 0) + return (-1); + if (buf.st_size != 0) { + if ((fil = open(name, O_RDWR, 0666)) < 0) + return (-1); + if (read(fil, &data, 1) < 1) { + close(fil); + return (-1); + } + lseek(fil, 0L, 0); + if (write(fil, &data, 1) < 1) { + close(fil); + return (-1); + } + close(fil); + return (0); + } else if ((fil = creat(name, 0666)) < 0) { + return (-1); + } else { + close(fil); + return (0); + } +} diff --git a/dmake/unix/bsd43/uw/config.mk b/dmake/unix/bsd43/uw/config.mk new file mode 100644 index 000000000000..1f94136f6d6e --- /dev/null +++ b/dmake/unix/bsd43/uw/config.mk @@ -0,0 +1,17 @@ +# This is the BSD 4.3 University of Waterloo (uw) UNIX configuration file +# for DMAKE +# It simply modifies the values of LDLIBS to include libuw.a +# so that vfprintf can be found. +# + +LDLIBS += -luw +osredir := $(OS)$(DIRSEPSTR)$(OSRELEASE)$(DIRSEPSTR)$(OSENVIRONMENT) +CFLAGS += -I$(osredir) + +# install script for UW's /usr/software hierarchy... +install: + mkdir ../bin; strip ./dmake; mv ./dmake ../bin + chmod a+rx ../bin/dmake ../bin + mkdir ../lib; chmod a+rx ../lib + cp $(STARTUPFILE) ../lib + chmod a+r ../lib/startup.mk diff --git a/dmake/unix/bsd43/uw/make.sh b/dmake/unix/bsd43/uw/make.sh new file mode 100644 index 000000000000..f23ecbb8ec44 --- /dev/null +++ b/dmake/unix/bsd43/uw/make.sh @@ -0,0 +1,69 @@ +mkdir objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/uw -O infer.c +mv infer.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/uw -O make.c +mv make.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/uw -O stat.c +mv stat.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/uw -O expand.c +mv expand.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/uw -O dmstring.c +mv dmstring.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/uw -O hash.c +mv hash.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/uw -O dag.c +mv dag.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/uw -O dmake.c +mv dmake.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/uw -O path.c +mv path.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/uw -O imacs.c +mv imacs.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/uw -O sysintf.c +mv sysintf.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/uw -O parse.c +mv parse.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/uw -O getinp.c +mv getinp.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/uw -O quit.c +mv quit.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/uw -O state.c +mv state.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/uw -O dmdump.c +mv dmdump.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/uw -O macparse.c +mv macparse.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/uw -O rulparse.c +mv rulparse.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/uw -O percent.c +mv percent.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/uw -O function.c +mv function.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/uw -O unix/arlib.c +mv arlib.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/uw -O unix/dirbrk.c +mv dirbrk.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/uw -O unix/rmprq.c +mv rmprq.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/uw -O unix/ruletab.c +mv ruletab.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/uw -O unix/runargv.c +mv runargv.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/uw -O unix/dcache.c +mv dcache.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/uw -O unix/bsd43/putenv.c +mv putenv.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/uw -O unix/bsd43/tempnam.c +mv tempnam.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/uw -O unix/bsd43/utime.c +mv utime.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/uw -O unix/bsd43/setvbuf.c +mv setvbuf.o objects +cc -O -o dmake objects/infer.o objects/make.o objects/stat.o objects/expand.o \ +objects/dmstring.o objects/hash.o objects/dag.o objects/dmake.o objects/path.o \ +objects/imacs.o objects/sysintf.o objects/parse.o objects/getinp.o \ +objects/quit.o objects/state.o objects/dmdump.o objects/macparse.o \ +objects/rulparse.o objects/percent.o objects/function.o objects/arlib.o \ +objects/dirbrk.o objects/rmprq.o objects/ruletab.o objects/runargv.o \ +objects/dcache.o objects/putenv.o objects/tempnam.o objects/utime.o objects/setvbuf.o -luw +cp unix/bsd43/uw/template.mk startup/config.mk diff --git a/dmake/unix/bsd43/uw/public.h b/dmake/unix/bsd43/uw/public.h new file mode 100644 index 000000000000..da4cc6c0b7c4 --- /dev/null +++ b/dmake/unix/bsd43/uw/public.h @@ -0,0 +1,164 @@ +/* RCS $Id: public.h,v 1.1.1.1 2000-09-22 15:33:34 hr Exp $ +-- WARNING -- This file is AUTOMATICALLY GENERATED DO NOT EDIT IT +-- +-- +-- SYNOPSIS +-- Local functions exported to be visible by others. +-- +-- DESCRIPTION +-- This file is generated by 'genpub'. Function declarations +-- that appear in this file are extracted by 'genpub' from +-- source files. Any function in the source file whose definition +-- appears like: +-- +-- PUBLIC return_type +-- function( arg_list ); +-- type_expr1 arg1; +-- ... +-- +-- has its definition extracted and a line of the form: +-- +-- return_type function ANSI((type_expr1,type_expr2,...)); +-- +-- entered into the output file. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef _DMAKE_PUBLIC_h +#define _DMAKE_PUBLIC_h + +#ifdef EXTERN +#undef EXTERN +#endif +#if defined(DEFINE_DMAKE_VARIABLES) +#define EXTERN +#else +#define EXTERN extern +#endif + +/***** genpub: Begin list of generated function headers */ +void Infer_recipe ANSI((CELLPTR, CELLPTR)); +int Make_targets ANSI(()); +int Make ANSI((CELLPTR, CELLPTR)); +int Exec_commands ANSI((CELLPTR)); +void Print_cmnd ANSI((char *, int, int)); +int Push_dir ANSI((char *, char *, int)); +void Pop_dir ANSI((int)); +void Append_line ANSI((char *, int, FILE *, char *, int, int)); +void Stat_target ANSI((CELLPTR, int, int)); +char *Expand ANSI((char *)); +char *Apply_edit ANSI((char *, char *, char *, int, int)); +void Map_esc ANSI((char *)); +char* Apply_modifiers ANSI((int, char *)); +char* Tokenize ANSI((char *, char *, char, int)); +char* ScanToken ANSI((char *, char **, int)); +char *DmStrJoin ANSI((char *, char *, int, int)); +char *DmStrAdd ANSI((char *, char *, int)); +char *DmStrApp ANSI((char *, char *)); +char *DmStrDup ANSI((char *)); +char *DmStrDup2 ANSI((char *)); +char *DmStrPbrk ANSI((char *, char *)); +char *DmStrSpn ANSI((char *, char *)); +char *DmStrStr ANSI((char *, char *)); +char *DmSubStr ANSI((char *, char *)); +uint16 Hash ANSI((char *, uint32 *)); +HASHPTR Get_name ANSI((char *, HASHPTR *, int)); +HASHPTR Search_table ANSI((HASHPTR *, char *, uint16 *, uint32 *)); +HASHPTR Push_macro ANSI((HASHPTR)); +HASHPTR Pop_macro ANSI((HASHPTR)); +HASHPTR Def_macro ANSI((char *, char *, int)); +CELLPTR Def_cell ANSI((char *)); +LINKPTR Add_prerequisite ANSI((CELLPTR, CELLPTR, int, int)); +void Clear_prerequisites ANSI((CELLPTR)); +int Test_circle ANSI((CELLPTR, int)); +STRINGPTR Def_recipe ANSI((char *, STRINGPTR, int, int)); +t_attr Rcp_attribute ANSI((char *)); +void main ANSI((int, char **)); +FILE *Openfile ANSI((char *, int, int)); +FILE *Closefile ANSI(()); +FILE *Search_file ANSI((char *, char **)); +char *Filename ANSI(()); +int Nestlevel ANSI(()); +FILE *TryFiles ANSI((LINKPTR)); +void Fatal ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Error ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Warning ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void No_ram ANSI(()); +void Usage ANSI((int)); +void Version ANSI(()); +char *Get_suffix ANSI((char *)); +char *Basename ANSI((char *)); +char *Filedir ANSI((char *)); +char *Build_path ANSI((char *, char *)); +void Make_rules ANSI(()); +void Create_macro_vars ANSI(()); +time_t Do_stat ANSI((char *, char *, char **, int)); +int Do_touch ANSI((char *, char *, char **)); +void Void_lib_cache ANSI((char *, char *)); +time_t Do_time ANSI(()); +int Do_cmnd ANSI((char *, int, int, CELLPTR, int, int, int)); +char ** Pack_argv ANSI((int, int, char *)); +char *Read_env_string ANSI((char *)); +int Write_env_string ANSI((char *, char *)); +void ReadEnvironment ANSI(()); +void Catch_signals ANSI((void (*)())); +void Clear_signals ANSI(()); +void Prolog ANSI((int, char* [])); +void Epilog ANSI((int)); +char *Get_current_dir ANSI(()); +int Set_dir ANSI((char*)); +char Get_switch_char ANSI(()); +FILE* Get_temp ANSI((char **, char *, int)); +FILE *Start_temp ANSI((char *, CELLPTR, char **)); +void Open_temp_error ANSI((char *, char *)); +void Link_temp ANSI((CELLPTR, FILE *, char *)); +void Close_temp ANSI((CELLPTR, FILE *)); +void Unlink_temp_files ANSI((CELLPTR)); +void Handle_result ANSI((int, int, int, CELLPTR)); +void Update_time_stamp ANSI((CELLPTR)); +int Remove_file ANSI((char *)); +void Parse ANSI((FILE *)); +int Get_line ANSI((char *, FILE *)); +char *Do_comment ANSI((char *, char **, int)); +char *Get_token ANSI((TKSTRPTR, char *, int)); +void Quit ANSI(()); +void Read_state ANSI(()); +void Write_state ANSI(()); +int Check_state ANSI((CELLPTR, STRINGPTR *, int)); +void Dump ANSI(()); +void Dump_recipe ANSI((STRINGPTR)); +int Parse_macro ANSI((char *, int)); +int Macro_op ANSI((char *)); +int Parse_rule_def ANSI((int *)); +int Rule_op ANSI((char *)); +void Add_recipe_to_list ANSI((char *, int, int)); +void Bind_rules_to_targets ANSI((int)); +int Set_group_attributes ANSI((char *)); +DFALINKPTR Match_dfa ANSI((char *)); +void Check_circle_dfa ANSI(()); +void Add_nfa ANSI((char *)); +char *Exec_function ANSI((char *)); +time_t seek_arch ANSI((char *, char *)); +int If_root_path ANSI((char *)); +void Remove_prq ANSI((CELLPTR)); +int runargv ANSI((CELLPTR, int, int, int, int, char *)); +int Wait_for_child ANSI((int, int)); +void Clean_up_processes ANSI(()); +time_t CacheStat ANSI((char *, int)); + +#endif diff --git a/dmake/unix/bsd43/uw/template.mk b/dmake/unix/bsd43/uw/template.mk new file mode 100644 index 000000000000..6afe91c1fc7a --- /dev/null +++ b/dmake/unix/bsd43/uw/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= unix + OSRELEASE *:= bsd43 + OSENVIRONMENT *:= uw diff --git a/dmake/unix/bsd43/vf/config.mk b/dmake/unix/bsd43/vf/config.mk new file mode 100644 index 000000000000..bf4e64808d6c --- /dev/null +++ b/dmake/unix/bsd43/vf/config.mk @@ -0,0 +1,11 @@ +# This config file adds vfprintf.c and memcpy.c for those systems that +# do not have it. +# + +osredir := $(OS)$(DIRSEPSTR)$(OSRELEASE)$(DIRSEPSTR)$(OSENVIRONMENT) +CFLAGS += -I$(osredir) + +# The following sources are required for BSD4.3 +OSDESRC := memcpy.c vfprintf.c +SRC += $(OSDESRC) +.SETDIR=$(osredir) : $(OSDESRC) diff --git a/dmake/unix/bsd43/vf/ctype.h b/dmake/unix/bsd43/vf/ctype.h new file mode 100644 index 000000000000..f229a9ab3967 --- /dev/null +++ b/dmake/unix/bsd43/vf/ctype.h @@ -0,0 +1,51 @@ +/* RCS $Id: ctype.h,v 1.1.1.1 2000-09-22 15:33:34 hr Exp $ +-- +-- SYNOPSIS +-- ctype +-- +-- DESCRIPTION +-- ctype.h 4.2 85/09/04 +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#define _U 01 +#define _L 02 +#define _N 04 +#define _S 010 +#define _P 020 +#define _C 040 +#define _X 0100 +#define _B 0200 + +extern char _ctype_[]; + +#define isalpha(c) ((_ctype_+1)[c]&(_U|_L)) +#define isupper(c) ((_ctype_+1)[c]&_U) +#define islower(c) ((_ctype_+1)[c]&_L) +#define isdigit(c) ((_ctype_+1)[c]&_N) +#define isxdigit(c) ((_ctype_+1)[c]&(_N|_X)) +#define isspace(c) ((_ctype_+1)[c]&_S) +#define ispunct(c) ((_ctype_+1)[c]&_P) +#define isalnum(c) ((_ctype_+1)[c]&(_U|_L|_N)) +#define isprint(c) ((_ctype_+1)[c]&(_P|_U|_L|_N|_B)) +#define isgraph(c) ((_ctype_+1)[c]&(_P|_U|_L|_N)) +#define iscntrl(c) ((_ctype_+1)[c]&_C) +#define isascii(c) ((unsigned)(c)<=0177) +#define toupper(c) ((c)-'a'+'A') +#define tolower(c) ((c)-'A'+'a') +#define toascii(c) ((c)&0177) diff --git a/dmake/unix/bsd43/vf/make.sh b/dmake/unix/bsd43/vf/make.sh new file mode 100644 index 000000000000..231b683a80e6 --- /dev/null +++ b/dmake/unix/bsd43/vf/make.sh @@ -0,0 +1,73 @@ +mkdir objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/vf -O infer.c +mv infer.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/vf -O make.c +mv make.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/vf -O stat.c +mv stat.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/vf -O expand.c +mv expand.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/vf -O dmstring.c +mv dmstring.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/vf -O hash.c +mv hash.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/vf -O dag.c +mv dag.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/vf -O dmake.c +mv dmake.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/vf -O path.c +mv path.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/vf -O imacs.c +mv imacs.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/vf -O sysintf.c +mv sysintf.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/vf -O parse.c +mv parse.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/vf -O getinp.c +mv getinp.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/vf -O quit.c +mv quit.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/vf -O state.c +mv state.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/vf -O dmdump.c +mv dmdump.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/vf -O macparse.c +mv macparse.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/vf -O rulparse.c +mv rulparse.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/vf -O percent.c +mv percent.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/vf -O function.c +mv function.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/vf -O unix/arlib.c +mv arlib.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/vf -O unix/dirbrk.c +mv dirbrk.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/vf -O unix/rmprq.c +mv rmprq.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/vf -O unix/ruletab.c +mv ruletab.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/vf -O unix/runargv.c +mv runargv.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/vf -O unix/dcache.c +mv dcache.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/vf -O unix/bsd43/putenv.c +mv putenv.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/vf -O unix/bsd43/tempnam.c +mv tempnam.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/vf -O unix/bsd43/utime.c +mv utime.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/vf -O unix/bsd43/setvbuf.c +mv setvbuf.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/vf -O unix/bsd43/vf/memcpy.c +mv memcpy.o objects +cc -c -I. -Iunix -Iunix/bsd43 -Iunix/bsd43/vf -O unix/bsd43/vf/vfprintf.c +mv vfprintf.o objects +cc -O -o dmake objects/infer.o objects/make.o objects/stat.o objects/expand.o \ +objects/dmstring.o objects/hash.o objects/dag.o objects/dmake.o objects/path.o \ +objects/imacs.o objects/sysintf.o objects/parse.o objects/getinp.o \ +objects/quit.o objects/state.o objects/dmdump.o objects/macparse.o \ +objects/rulparse.o objects/percent.o objects/function.o objects/arlib.o \ +objects/dirbrk.o objects/rmprq.o objects/ruletab.o objects/runargv.o \ +objects/dcache.o objects/putenv.o objects/tempnam.o objects/utime.o objects/setvbuf.o objects/memcpy.o objects/vfprintf.o +cp unix/bsd43/vf/template.mk startup/config.mk diff --git a/dmake/unix/bsd43/vf/memcpy.c b/dmake/unix/bsd43/vf/memcpy.c new file mode 100644 index 000000000000..4ae47722e851 --- /dev/null +++ b/dmake/unix/bsd43/vf/memcpy.c @@ -0,0 +1,36 @@ +/* RCS $Id: memcpy.c,v 1.1.1.1 2000-09-22 15:33:34 hr Exp $ +-- +-- SYNOPSIS +-- memcpy +-- +-- DESCRIPTION +-- BSD didn't have this in the library many moons ago. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +char * +memcpy(t, f, n) +register char *t, *f; +register n; +{ + register char *p = t; + + while( --n >= 0 ) *t++ = *f++; + + return (p); +} diff --git a/dmake/unix/bsd43/vf/public.h b/dmake/unix/bsd43/vf/public.h new file mode 100644 index 000000000000..da4cc6c0b7c4 --- /dev/null +++ b/dmake/unix/bsd43/vf/public.h @@ -0,0 +1,164 @@ +/* RCS $Id: public.h,v 1.1.1.1 2000-09-22 15:33:34 hr Exp $ +-- WARNING -- This file is AUTOMATICALLY GENERATED DO NOT EDIT IT +-- +-- +-- SYNOPSIS +-- Local functions exported to be visible by others. +-- +-- DESCRIPTION +-- This file is generated by 'genpub'. Function declarations +-- that appear in this file are extracted by 'genpub' from +-- source files. Any function in the source file whose definition +-- appears like: +-- +-- PUBLIC return_type +-- function( arg_list ); +-- type_expr1 arg1; +-- ... +-- +-- has its definition extracted and a line of the form: +-- +-- return_type function ANSI((type_expr1,type_expr2,...)); +-- +-- entered into the output file. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef _DMAKE_PUBLIC_h +#define _DMAKE_PUBLIC_h + +#ifdef EXTERN +#undef EXTERN +#endif +#if defined(DEFINE_DMAKE_VARIABLES) +#define EXTERN +#else +#define EXTERN extern +#endif + +/***** genpub: Begin list of generated function headers */ +void Infer_recipe ANSI((CELLPTR, CELLPTR)); +int Make_targets ANSI(()); +int Make ANSI((CELLPTR, CELLPTR)); +int Exec_commands ANSI((CELLPTR)); +void Print_cmnd ANSI((char *, int, int)); +int Push_dir ANSI((char *, char *, int)); +void Pop_dir ANSI((int)); +void Append_line ANSI((char *, int, FILE *, char *, int, int)); +void Stat_target ANSI((CELLPTR, int, int)); +char *Expand ANSI((char *)); +char *Apply_edit ANSI((char *, char *, char *, int, int)); +void Map_esc ANSI((char *)); +char* Apply_modifiers ANSI((int, char *)); +char* Tokenize ANSI((char *, char *, char, int)); +char* ScanToken ANSI((char *, char **, int)); +char *DmStrJoin ANSI((char *, char *, int, int)); +char *DmStrAdd ANSI((char *, char *, int)); +char *DmStrApp ANSI((char *, char *)); +char *DmStrDup ANSI((char *)); +char *DmStrDup2 ANSI((char *)); +char *DmStrPbrk ANSI((char *, char *)); +char *DmStrSpn ANSI((char *, char *)); +char *DmStrStr ANSI((char *, char *)); +char *DmSubStr ANSI((char *, char *)); +uint16 Hash ANSI((char *, uint32 *)); +HASHPTR Get_name ANSI((char *, HASHPTR *, int)); +HASHPTR Search_table ANSI((HASHPTR *, char *, uint16 *, uint32 *)); +HASHPTR Push_macro ANSI((HASHPTR)); +HASHPTR Pop_macro ANSI((HASHPTR)); +HASHPTR Def_macro ANSI((char *, char *, int)); +CELLPTR Def_cell ANSI((char *)); +LINKPTR Add_prerequisite ANSI((CELLPTR, CELLPTR, int, int)); +void Clear_prerequisites ANSI((CELLPTR)); +int Test_circle ANSI((CELLPTR, int)); +STRINGPTR Def_recipe ANSI((char *, STRINGPTR, int, int)); +t_attr Rcp_attribute ANSI((char *)); +void main ANSI((int, char **)); +FILE *Openfile ANSI((char *, int, int)); +FILE *Closefile ANSI(()); +FILE *Search_file ANSI((char *, char **)); +char *Filename ANSI(()); +int Nestlevel ANSI(()); +FILE *TryFiles ANSI((LINKPTR)); +void Fatal ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Error ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Warning ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void No_ram ANSI(()); +void Usage ANSI((int)); +void Version ANSI(()); +char *Get_suffix ANSI((char *)); +char *Basename ANSI((char *)); +char *Filedir ANSI((char *)); +char *Build_path ANSI((char *, char *)); +void Make_rules ANSI(()); +void Create_macro_vars ANSI(()); +time_t Do_stat ANSI((char *, char *, char **, int)); +int Do_touch ANSI((char *, char *, char **)); +void Void_lib_cache ANSI((char *, char *)); +time_t Do_time ANSI(()); +int Do_cmnd ANSI((char *, int, int, CELLPTR, int, int, int)); +char ** Pack_argv ANSI((int, int, char *)); +char *Read_env_string ANSI((char *)); +int Write_env_string ANSI((char *, char *)); +void ReadEnvironment ANSI(()); +void Catch_signals ANSI((void (*)())); +void Clear_signals ANSI(()); +void Prolog ANSI((int, char* [])); +void Epilog ANSI((int)); +char *Get_current_dir ANSI(()); +int Set_dir ANSI((char*)); +char Get_switch_char ANSI(()); +FILE* Get_temp ANSI((char **, char *, int)); +FILE *Start_temp ANSI((char *, CELLPTR, char **)); +void Open_temp_error ANSI((char *, char *)); +void Link_temp ANSI((CELLPTR, FILE *, char *)); +void Close_temp ANSI((CELLPTR, FILE *)); +void Unlink_temp_files ANSI((CELLPTR)); +void Handle_result ANSI((int, int, int, CELLPTR)); +void Update_time_stamp ANSI((CELLPTR)); +int Remove_file ANSI((char *)); +void Parse ANSI((FILE *)); +int Get_line ANSI((char *, FILE *)); +char *Do_comment ANSI((char *, char **, int)); +char *Get_token ANSI((TKSTRPTR, char *, int)); +void Quit ANSI(()); +void Read_state ANSI(()); +void Write_state ANSI(()); +int Check_state ANSI((CELLPTR, STRINGPTR *, int)); +void Dump ANSI(()); +void Dump_recipe ANSI((STRINGPTR)); +int Parse_macro ANSI((char *, int)); +int Macro_op ANSI((char *)); +int Parse_rule_def ANSI((int *)); +int Rule_op ANSI((char *)); +void Add_recipe_to_list ANSI((char *, int, int)); +void Bind_rules_to_targets ANSI((int)); +int Set_group_attributes ANSI((char *)); +DFALINKPTR Match_dfa ANSI((char *)); +void Check_circle_dfa ANSI(()); +void Add_nfa ANSI((char *)); +char *Exec_function ANSI((char *)); +time_t seek_arch ANSI((char *, char *)); +int If_root_path ANSI((char *)); +void Remove_prq ANSI((CELLPTR)); +int runargv ANSI((CELLPTR, int, int, int, int, char *)); +int Wait_for_child ANSI((int, int)); +void Clean_up_processes ANSI(()); +time_t CacheStat ANSI((char *, int)); + +#endif diff --git a/dmake/unix/bsd43/vf/template.mk b/dmake/unix/bsd43/vf/template.mk new file mode 100644 index 000000000000..395cd4718fa0 --- /dev/null +++ b/dmake/unix/bsd43/vf/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= unix + OSRELEASE *:= bsd43 + OSENVIRONMENT *:= vf diff --git a/dmake/unix/bsd43/vf/vfprintf.c b/dmake/unix/bsd43/vf/vfprintf.c new file mode 100644 index 000000000000..675e2e83e5ab --- /dev/null +++ b/dmake/unix/bsd43/vf/vfprintf.c @@ -0,0 +1,48 @@ +/* + * Copyright (c) 1988 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)vfprintf.c 5.2 (Berkeley) 6/27/88"; +#endif /* LIBC_SCCS and not lint */ + +#include <stdio.h> +#include <varargs.h> + +int +vfprintf(iop, fmt, ap) + FILE *iop; + char *fmt; + va_list ap; +{ + int len; + char localbuf[BUFSIZ]; + + if (iop->_flag & _IONBF) { + iop->_flag &= ~_IONBF; + iop->_ptr = iop->_base = localbuf; + len = _doprnt(fmt, ap, iop); + (void) fflush(iop); + iop->_flag |= _IONBF; + iop->_base = NULL; + iop->_bufsiz = 0; + iop->_cnt = 0; + } else + len = _doprnt(fmt, ap, iop); + + return (ferror(iop) ? EOF : len); +} + diff --git a/dmake/unix/bsdarm32/config.mk b/dmake/unix/bsdarm32/config.mk new file mode 100644 index 000000000000..e99937342e68 --- /dev/null +++ b/dmake/unix/bsdarm32/config.mk @@ -0,0 +1,27 @@ +# This is the BSD 4.3 UNIX configuration file for DMAKE +# It simply modifies the values of SRC, and checks to see if +# OSENVIRONMENT is defined. If so it includes the appropriate +# config.mk file. +# +# It also sets the values of .SOURCE.c and .SOURCE.h to include the local +# directory. +# +osrdir := $(OS)$(DIRSEPSTR)$(OSRELEASE) + +# The following sources are required for BSD4.3 +OSDSRC := putenv.c tempnam.c utime.c setvbuf.c +.IF $(OSDSRC) + SRC += $(OSDSRC) + .SETDIR=$(osrdir) : $(OSDSRC) +.END + +.SOURCE.h : $(osrdir) + +# Local configuration modifications for CFLAGS, there's local BSD includes +# too. +CFLAGS += -I$(osrdir) + +# See if we modify anything in the lower levels. +.IF $(OSENVIRONMENT) != $(NULL) + .INCLUDE .IGNORE : $(osrdir)$(DIRSEPSTR)$(OSENVIRONMENT)$(DIRSEPSTR)config.mk +.END diff --git a/dmake/unix/bsdarm32/dirent.h b/dmake/unix/bsdarm32/dirent.h new file mode 100644 index 000000000000..b50fa18a9d9e --- /dev/null +++ b/dmake/unix/bsdarm32/dirent.h @@ -0,0 +1,30 @@ +/* RCS $Id: dirent.h,v 1.1.1.1 2000-09-22 15:33:34 hr Exp $ +-- +-- SYNOPSIS +-- dirent +-- +-- DESCRIPTION +-- Deal with sysV'ish dirent.h on BSD4.3 systems, which have the stuff +-- in sys/dir.h +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include <sys/dir.h> +#include </usr/include/dirent.h> +#define dirent direct + diff --git a/dmake/unix/bsdarm32/limits.h b/dmake/unix/bsdarm32/limits.h new file mode 100644 index 000000000000..655d707bb4f6 --- /dev/null +++ b/dmake/unix/bsdarm32/limits.h @@ -0,0 +1,29 @@ +/* RCS $Id: limits.h,v 1.1.1.1 2000-09-22 15:33:34 hr Exp $ +-- +-- SYNOPSIS +-- limits +-- +-- DESCRIPTION +-- Compensate for systems that don't have a limits.h header file. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include <sys/types.h> +#include <sys/dirent.h> +#include <sys/param.h> + diff --git a/dmake/unix/bsdarm32/make.sh b/dmake/unix/bsdarm32/make.sh new file mode 100644 index 000000000000..f43dd9425774 --- /dev/null +++ b/dmake/unix/bsdarm32/make.sh @@ -0,0 +1,67 @@ +mkdir objects +cc -c -I. -Iunix -Iunix/bsdarm32 -O infer.c +mv infer.o objects +cc -c -I. -Iunix -Iunix/bsdarm32 -O make.c +mv make.o objects +cc -c -I. -Iunix -Iunix/bsdarm32 -O stat.c +mv stat.o objects +cc -c -I. -Iunix -Iunix/bsdarm32 -O expand.c +mv expand.o objects +cc -c -I. -Iunix -Iunix/bsdarm32 -O dmstring.c +mv dmstring.o objects +cc -c -I. -Iunix -Iunix/bsdarm32 -O hash.c +mv hash.o objects +cc -c -I. -Iunix -Iunix/bsdarm32 -O dag.c +mv dag.o objects +cc -c -I. -Iunix -Iunix/bsdarm32 -O dmake.c +mv dmake.o objects +cc -c -I. -Iunix -Iunix/bsdarm32 -O path.c +mv path.o objects +cc -c -I. -Iunix -Iunix/bsdarm32 -O imacs.c +mv imacs.o objects +cc -c -I. -Iunix -Iunix/bsdarm32 -O sysintf.c +mv sysintf.o objects +cc -c -I. -Iunix -Iunix/bsdarm32 -O parse.c +mv parse.o objects +cc -c -I. -Iunix -Iunix/bsdarm32 -O getinp.c +mv getinp.o objects +cc -c -I. -Iunix -Iunix/bsdarm32 -O quit.c +mv quit.o objects +cc -c -I. -Iunix -Iunix/bsdarm32 -O state.c +mv state.o objects +cc -c -I. -Iunix -Iunix/bsdarm32 -O dmdump.c +mv dmdump.o objects +cc -c -I. -Iunix -Iunix/bsdarm32 -O macparse.c +mv macparse.o objects +cc -c -I. -Iunix -Iunix/bsdarm32 -O rulparse.c +mv rulparse.o objects +cc -c -I. -Iunix -Iunix/bsdarm32 -O percent.c +mv percent.o objects +cc -c -I. -Iunix -Iunix/bsdarm32 -O function.c +mv function.o objects +cc -c -I. -Iunix -Iunix/bsdarm32 -O unix/arlib.c +mv arlib.o objects +cc -c -I. -Iunix -Iunix/bsdarm32 -O unix/dirbrk.c +mv dirbrk.o objects +cc -c -I. -Iunix -Iunix/bsdarm32 -O unix/rmprq.c +mv rmprq.o objects +cc -c -I. -Iunix -Iunix/bsdarm32 -O unix/ruletab.c +mv ruletab.o objects +cc -c -I. -Iunix -Iunix/bsdarm32 -O unix/runargv.c +mv runargv.o objects +cc -c -I. -Iunix -Iunix/bsdarm32 -O unix/dcache.c +mv dcache.o objects +cc -c -I. -Iunix -Iunix/bsdarm32 -O unix/bsdarm32/putenv.c +mv putenv.o objects +cc -c -I. -Iunix -Iunix/bsdarm32 -O unix/bsdarm32/tempnam.c +mv tempnam.o objects +cc -c -I. -Iunix -Iunix/bsdarm32 -O unix/bsdarm32/utime.c +mv utime.o objects +cc -O -o dmake objects/infer.o objects/make.o objects/stat.o objects/expand.o \ +objects/dmstring.o objects/hash.o objects/dag.o objects/dmake.o objects/path.o \ +objects/imacs.o objects/sysintf.o objects/parse.o objects/getinp.o \ +objects/quit.o objects/state.o objects/dmdump.o objects/macparse.o \ +objects/rulparse.o objects/percent.o objects/function.o objects/arlib.o \ +objects/dirbrk.o objects/rmprq.o objects/ruletab.o objects/runargv.o \ +objects/dcache.o objects/putenv.o objects/tempnam.o objects/utime.o objects/setvbuf.o +cp unix/bsdarm32/template.mk startup/config.mk diff --git a/dmake/unix/bsdarm32/public.h b/dmake/unix/bsdarm32/public.h new file mode 100644 index 000000000000..da4cc6c0b7c4 --- /dev/null +++ b/dmake/unix/bsdarm32/public.h @@ -0,0 +1,164 @@ +/* RCS $Id: public.h,v 1.1.1.1 2000-09-22 15:33:34 hr Exp $ +-- WARNING -- This file is AUTOMATICALLY GENERATED DO NOT EDIT IT +-- +-- +-- SYNOPSIS +-- Local functions exported to be visible by others. +-- +-- DESCRIPTION +-- This file is generated by 'genpub'. Function declarations +-- that appear in this file are extracted by 'genpub' from +-- source files. Any function in the source file whose definition +-- appears like: +-- +-- PUBLIC return_type +-- function( arg_list ); +-- type_expr1 arg1; +-- ... +-- +-- has its definition extracted and a line of the form: +-- +-- return_type function ANSI((type_expr1,type_expr2,...)); +-- +-- entered into the output file. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef _DMAKE_PUBLIC_h +#define _DMAKE_PUBLIC_h + +#ifdef EXTERN +#undef EXTERN +#endif +#if defined(DEFINE_DMAKE_VARIABLES) +#define EXTERN +#else +#define EXTERN extern +#endif + +/***** genpub: Begin list of generated function headers */ +void Infer_recipe ANSI((CELLPTR, CELLPTR)); +int Make_targets ANSI(()); +int Make ANSI((CELLPTR, CELLPTR)); +int Exec_commands ANSI((CELLPTR)); +void Print_cmnd ANSI((char *, int, int)); +int Push_dir ANSI((char *, char *, int)); +void Pop_dir ANSI((int)); +void Append_line ANSI((char *, int, FILE *, char *, int, int)); +void Stat_target ANSI((CELLPTR, int, int)); +char *Expand ANSI((char *)); +char *Apply_edit ANSI((char *, char *, char *, int, int)); +void Map_esc ANSI((char *)); +char* Apply_modifiers ANSI((int, char *)); +char* Tokenize ANSI((char *, char *, char, int)); +char* ScanToken ANSI((char *, char **, int)); +char *DmStrJoin ANSI((char *, char *, int, int)); +char *DmStrAdd ANSI((char *, char *, int)); +char *DmStrApp ANSI((char *, char *)); +char *DmStrDup ANSI((char *)); +char *DmStrDup2 ANSI((char *)); +char *DmStrPbrk ANSI((char *, char *)); +char *DmStrSpn ANSI((char *, char *)); +char *DmStrStr ANSI((char *, char *)); +char *DmSubStr ANSI((char *, char *)); +uint16 Hash ANSI((char *, uint32 *)); +HASHPTR Get_name ANSI((char *, HASHPTR *, int)); +HASHPTR Search_table ANSI((HASHPTR *, char *, uint16 *, uint32 *)); +HASHPTR Push_macro ANSI((HASHPTR)); +HASHPTR Pop_macro ANSI((HASHPTR)); +HASHPTR Def_macro ANSI((char *, char *, int)); +CELLPTR Def_cell ANSI((char *)); +LINKPTR Add_prerequisite ANSI((CELLPTR, CELLPTR, int, int)); +void Clear_prerequisites ANSI((CELLPTR)); +int Test_circle ANSI((CELLPTR, int)); +STRINGPTR Def_recipe ANSI((char *, STRINGPTR, int, int)); +t_attr Rcp_attribute ANSI((char *)); +void main ANSI((int, char **)); +FILE *Openfile ANSI((char *, int, int)); +FILE *Closefile ANSI(()); +FILE *Search_file ANSI((char *, char **)); +char *Filename ANSI(()); +int Nestlevel ANSI(()); +FILE *TryFiles ANSI((LINKPTR)); +void Fatal ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Error ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Warning ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void No_ram ANSI(()); +void Usage ANSI((int)); +void Version ANSI(()); +char *Get_suffix ANSI((char *)); +char *Basename ANSI((char *)); +char *Filedir ANSI((char *)); +char *Build_path ANSI((char *, char *)); +void Make_rules ANSI(()); +void Create_macro_vars ANSI(()); +time_t Do_stat ANSI((char *, char *, char **, int)); +int Do_touch ANSI((char *, char *, char **)); +void Void_lib_cache ANSI((char *, char *)); +time_t Do_time ANSI(()); +int Do_cmnd ANSI((char *, int, int, CELLPTR, int, int, int)); +char ** Pack_argv ANSI((int, int, char *)); +char *Read_env_string ANSI((char *)); +int Write_env_string ANSI((char *, char *)); +void ReadEnvironment ANSI(()); +void Catch_signals ANSI((void (*)())); +void Clear_signals ANSI(()); +void Prolog ANSI((int, char* [])); +void Epilog ANSI((int)); +char *Get_current_dir ANSI(()); +int Set_dir ANSI((char*)); +char Get_switch_char ANSI(()); +FILE* Get_temp ANSI((char **, char *, int)); +FILE *Start_temp ANSI((char *, CELLPTR, char **)); +void Open_temp_error ANSI((char *, char *)); +void Link_temp ANSI((CELLPTR, FILE *, char *)); +void Close_temp ANSI((CELLPTR, FILE *)); +void Unlink_temp_files ANSI((CELLPTR)); +void Handle_result ANSI((int, int, int, CELLPTR)); +void Update_time_stamp ANSI((CELLPTR)); +int Remove_file ANSI((char *)); +void Parse ANSI((FILE *)); +int Get_line ANSI((char *, FILE *)); +char *Do_comment ANSI((char *, char **, int)); +char *Get_token ANSI((TKSTRPTR, char *, int)); +void Quit ANSI(()); +void Read_state ANSI(()); +void Write_state ANSI(()); +int Check_state ANSI((CELLPTR, STRINGPTR *, int)); +void Dump ANSI(()); +void Dump_recipe ANSI((STRINGPTR)); +int Parse_macro ANSI((char *, int)); +int Macro_op ANSI((char *)); +int Parse_rule_def ANSI((int *)); +int Rule_op ANSI((char *)); +void Add_recipe_to_list ANSI((char *, int, int)); +void Bind_rules_to_targets ANSI((int)); +int Set_group_attributes ANSI((char *)); +DFALINKPTR Match_dfa ANSI((char *)); +void Check_circle_dfa ANSI(()); +void Add_nfa ANSI((char *)); +char *Exec_function ANSI((char *)); +time_t seek_arch ANSI((char *, char *)); +int If_root_path ANSI((char *)); +void Remove_prq ANSI((CELLPTR)); +int runargv ANSI((CELLPTR, int, int, int, int, char *)); +int Wait_for_child ANSI((int, int)); +void Clean_up_processes ANSI(()); +time_t CacheStat ANSI((char *, int)); + +#endif diff --git a/dmake/unix/bsdarm32/putenv.c b/dmake/unix/bsdarm32/putenv.c new file mode 100644 index 000000000000..d0ed998158e0 --- /dev/null +++ b/dmake/unix/bsdarm32/putenv.c @@ -0,0 +1,78 @@ +/* RCS $Id: putenv.c,v 1.1.1.1 2000-09-22 15:33:34 hr Exp $ +-- +-- SYNOPSIS +-- My own putenv for BSD like systems. +-- +-- DESCRIPTION +-- This originally came from MKS, but I rewrote it to fix a bug with +-- replacing existing strings, probably never happened but the code +-- was wrong nonetheless. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include <stdio.h> +#include <string.h> + +int +putenv( str )/* +=============== + Take a string of the form NAME=value and stick it into the environment. + We do this by allocating a new set of pointers if we have to add a new + string and by replacing an existing pointer if the value replaces the value + of an existing string. */ +char *str; +{ + extern char **environ; /* The current environment. */ + static char **ourenv = NULL; /* A new environment */ + register char **p; + register char *q; + int size; + + /* First search the current environment and see if we can replace a + * string. */ + for( p=environ; *p; p++ ) { + register char *s = str; + + for( q = *p; *q && *s && *s == *q; q++, s++ ) + if( *s == '=' ) { + *p = str; + return(0); /* replaced it so go away */ + } + } + + /* Ok, can't replace a string so need to grow the environment. */ + size = p - environ + 2; /* size of new environment */ + /* size of old is size-1 */ + + /* It's the first time, so allocate a new environment since we don't know + * where the old one is comming from. */ + if( ourenv == NULL ) { + if( (ourenv = (char **) malloc( sizeof(char *)*size )) == NULL ) + return(1); + + memcpy( (char *)ourenv, (char *)environ, (size-2)*sizeof(char *) ); + } + else if( (ourenv = (char **)realloc( ourenv, size*sizeof(char *))) == NULL ) + return(1); + + ourenv[--size] = NULL; + ourenv[--size] = str; + + environ = ourenv; + return(0); +} diff --git a/dmake/unix/bsdarm32/stdlib.h b/dmake/unix/bsdarm32/stdlib.h new file mode 100644 index 000000000000..82ab9627cd65 --- /dev/null +++ b/dmake/unix/bsdarm32/stdlib.h @@ -0,0 +1,44 @@ +/* RCS $Id: stdlib.h,v 1.1.1.1 2000-09-22 15:33:34 hr Exp $ +-- +-- SYNOPSIS +-- stdlib interface +-- +-- DESCRIPTION +-- Specially needed pieces of interface to the standard C lib. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef _STDLIB_INCLUDED_ +#define _STDLIB_INCLUDED_ + +extern /*GOTO*/ _exit(); +extern /*GOTO*/ exit(); +extern /*GOTO*/ abort(); +extern int system(); +extern char *getenv(); +extern char *calloc(); +extern char *malloc(); +extern char *realloc(); +extern free(); +extern int errno; + +#ifndef EIO +# include <errno.h> +#endif + +#endif /* _STDLIB_INCLUDED_ */ diff --git a/dmake/unix/bsdarm32/string.h b/dmake/unix/bsdarm32/string.h new file mode 100644 index 000000000000..c8abdf137696 --- /dev/null +++ b/dmake/unix/bsdarm32/string.h @@ -0,0 +1,42 @@ +/* RCS $Id: string.h,v 1.1.1.1 2000-09-22 15:33:34 hr Exp $ +-- +-- SYNOPSIS +-- string function headers +-- +-- DESCRIPTION +-- Supply correct definitions for certain string functions. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + + +/* +** BSD does this wrong +*/ +#include </usr/include/string.h> + +#include "stdmacs.h" +extern char* strpbrk ANSI((const char* src, const char* any)); + +#ifndef DBUG +#define strchr(str,c) index(str,c) +#define strrchr(str,c) rindex(str,c) +#else +char *strchr ANSI((char*, char)); +char *strrchr ANSI((char*, char)); +#endif + diff --git a/dmake/unix/bsdarm32/template.mk b/dmake/unix/bsdarm32/template.mk new file mode 100644 index 000000000000..830e9958394c --- /dev/null +++ b/dmake/unix/bsdarm32/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= unix + OSRELEASE *:= bsdarm32 + OSENVIRONMENT *:= diff --git a/dmake/unix/bsdarm32/tempnam.c b/dmake/unix/bsdarm32/tempnam.c new file mode 100644 index 000000000000..a645f41abcf7 --- /dev/null +++ b/dmake/unix/bsdarm32/tempnam.c @@ -0,0 +1,105 @@ +/* RCS $Id: tempnam.c,v 1.1.1.1 2000-09-22 15:33:34 hr Exp $ +-- +-- SYNOPSIS +-- tempnam +-- +-- DESCRIPTION +-- temp file name generation routines. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +/*LINTLIBRARY*/ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +#define max(A,B) (((A)<(B))?(B):(A)) + +extern char *mktemp(); +extern int access(); + +static char *cpdir(); +static char seed[4]="AAA"; + +/* BSD stdio.h doesn't define P_tmpdir, so let's do it here */ +#ifndef P_tmpdir +static char *P_tmpdir = "/tmp"; +#endif + + +char * +tempnam(dir, prefix) +const char *dir; /* use this directory please (if non-NULL) */ +const char *prefix; /* use this (if non-NULL) as filename prefix */ +{ + register char *p, *q, *tmpdir; + int tl=0, dl=0, pl; + + pl = strlen(P_tmpdir); + + if( (tmpdir = getenv("TMPDIR")) != NULL ) tl = strlen(tmpdir); + if( dir != NULL ) dl = strlen(dir); + + if( (p = malloc((unsigned)(max(max(dl,tl),pl)+16))) == NULL ) + return(NULL); + + *p = '\0'; + + if( (tl == 0) || (access( cpdir(p, tmpdir), 3) != 0) ) + if( (dl == 0) || (access( cpdir(p, dir), 3) != 0) ) + if( access( cpdir(p, P_tmpdir), 3) != 0 ) + if( access( cpdir(p, "/tmp"), 3) != 0 ) + return(NULL); + + (void) strcat(p, "/"); + if(prefix) + { + *(p+strlen(p)+5) = '\0'; + (void)strncat(p, prefix, 5); + } + + (void)strcat(p, seed); + (void)strcat(p, "XXXXXX"); + + q = seed; + while(*q == 'Z') *q++ = 'A'; + ++*q; + + if(*mktemp(p) == '\0') return(NULL); + return(p); +} + + + + +static char * +cpdir(buf, str) +char *buf; +char *str; +{ + char *p; + + if(str != NULL) + { + (void) strcpy(buf, str); + p = buf - 1 + strlen(buf); + if(*p == '/') *p = '\0'; + } + + return(buf); +} diff --git a/dmake/unix/bsdarm32/utime.c b/dmake/unix/bsdarm32/utime.c new file mode 100644 index 000000000000..9d26700d8006 --- /dev/null +++ b/dmake/unix/bsdarm32/utime.c @@ -0,0 +1,70 @@ +/* RCS $Id: utime.c,v 1.1.1.1 2000-09-22 15:33:34 hr Exp $ +-- +-- SYNOPSIS +-- utime +-- +-- DESCRIPTION +-- Provide our own utime function. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include <sys/types.h> +#include <sys/time.h> +#include <sys/stat.h> +#include <sys/file.h> + +int +utime(name, timep) +char* name; +time_t timep[2]; +{ + struct timeval tv[2], *tvp; + struct stat buf; + int fil; + char data; + + if (timep!=0) + { + tvp = tv, tv[0].tv_sec = timep[0], tv[1].tv_sec = timep[1]; + if (utimes(name, tvp)==0) + return (0); + } + + if (stat(name, &buf) != 0) + return (-1); + if (buf.st_size != 0) { + if ((fil = open(name, O_RDWR, 0666)) < 0) + return (-1); + if (read(fil, &data, 1) < 1) { + close(fil); + return (-1); + } + lseek(fil, 0L, 0); + if (write(fil, &data, 1) < 1) { + close(fil); + return (-1); + } + close(fil); + return (0); + } else if ((fil = creat(name, 0666)) < 0) { + return (-1); + } else { + close(fil); + return (0); + } +} diff --git a/dmake/unix/coherent/config.mk b/dmake/unix/coherent/config.mk new file mode 100644 index 000000000000..9c5890c8065d --- /dev/null +++ b/dmake/unix/coherent/config.mk @@ -0,0 +1,26 @@ +# This is the COHERENT configuration file for DMAKE +# It simply modifies the values of SRC, and checks to see if +# OSENVIRONMENT is defined. If so it includes the appropriate +# config.mk file. +# +# It also sets the values of .SOURCE.c and .SOURCE.h to include the local +# directory. +# +osrdir := $(OS)$(DIRSEPSTR)$(OSRELEASE) + +# The following are required sources +.IF $(OSDSRC) + SRC += $(OSDSRC) + .SETDIR=$(osrdir) : $(OSDSRC) +.END + +.SOURCE.h : $(osrdir) + +# Local configuration modifications for CFLAGS, there's local SysV includes +# too. +CFLAGS += -I$(osrdir) -Dvoid=int + +# See if we modify anything in the lower levels. +.IF $(OSENVIRONMENT) != $(NULL) + .INCLUDE .IGNORE : $(osrdir)$(DIRSEPSTR)$(OSENVIRONMENT)$(DIRSEPSTR)config.mk +.END diff --git a/dmake/unix/coherent/stdlib.h b/dmake/unix/coherent/stdlib.h new file mode 100644 index 000000000000..82ab9627cd65 --- /dev/null +++ b/dmake/unix/coherent/stdlib.h @@ -0,0 +1,44 @@ +/* RCS $Id: stdlib.h,v 1.1.1.1 2000-09-22 15:33:34 hr Exp $ +-- +-- SYNOPSIS +-- stdlib interface +-- +-- DESCRIPTION +-- Specially needed pieces of interface to the standard C lib. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef _STDLIB_INCLUDED_ +#define _STDLIB_INCLUDED_ + +extern /*GOTO*/ _exit(); +extern /*GOTO*/ exit(); +extern /*GOTO*/ abort(); +extern int system(); +extern char *getenv(); +extern char *calloc(); +extern char *malloc(); +extern char *realloc(); +extern free(); +extern int errno; + +#ifndef EIO +# include <errno.h> +#endif + +#endif /* _STDLIB_INCLUDED_ */ diff --git a/dmake/unix/coherent/time.h b/dmake/unix/coherent/time.h new file mode 100644 index 000000000000..e3509ed8ec8b --- /dev/null +++ b/dmake/unix/coherent/time.h @@ -0,0 +1,32 @@ +/* RCS $Id: time.h,v 1.1.1.1 2000-09-22 15:33:34 hr Exp $ +-- +-- SYNOPSIS +-- time_t +-- +-- DESCRIPTION +-- Properly define time_t. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef TIME_h +#define TIME_h + +typedef long time_t; /* this is the thing we use */ + +#endif TIME_h + diff --git a/dmake/unix/coherent/ver40/config.mk b/dmake/unix/coherent/ver40/config.mk new file mode 100644 index 000000000000..df2a702ea02f --- /dev/null +++ b/dmake/unix/coherent/ver40/config.mk @@ -0,0 +1,11 @@ +# This config file adds vfprintf.c and memcpy.c for those systems that +# do not have it. +# + +osredir := $(OS)$(DIRSEPSTR)$(OSRELEASE)$(DIRSEPSTR)$(OSENVIRONMENT) +CFLAGS += -I$(osredir) + +# The following sources are required for coherent version 4.0 +OSDESRC := vfprintf.c getcwd.c +SRC += $(OSDESRC) +.SETDIR=$(osredir) : $(OSDESRC) diff --git a/dmake/unix/coherent/ver40/getcwd.c b/dmake/unix/coherent/ver40/getcwd.c new file mode 100644 index 000000000000..cc2772494611 --- /dev/null +++ b/dmake/unix/coherent/ver40/getcwd.c @@ -0,0 +1,49 @@ +/* RCS $Id: getcwd.c,v 1.1.1.1 2000-09-22 15:33:34 hr Exp $ +-- +-- SYNOPSIS +-- getcwd +-- +-- DESCRIPTION +-- Wrapper for getcwd. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#if __STDC__ +char *getcwd(char *buffer, int length) +#else +char *getcwd (buffer, length) +char *buffer; +int length; +#endif +{ + extern char *getwd(); + + char *dir; + dir = getwd(); + if (dir) + { + strncpy(buffer,dir,length); + return buffer; + } + else + { + *buffer = 0; + return (char *) 0; + } +} + diff --git a/dmake/unix/coherent/ver40/make.sh b/dmake/unix/coherent/ver40/make.sh new file mode 100644 index 000000000000..1a0c850452f0 --- /dev/null +++ b/dmake/unix/coherent/ver40/make.sh @@ -0,0 +1,64 @@ +mkdir objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver40 -O infer.c +mv infer.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver40 -O make.c +mv make.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver40 -O stat.c +mv stat.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver40 -O expand.c +mv expand.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver40 -O dmstring.c +mv dmstring.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver40 -O hash.c +mv hash.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver40 -O dag.c +mv dag.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver40 -O dmake.c +mv dmake.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver40 -O path.c +mv path.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver40 -O imacs.c +mv imacs.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver40 -O sysintf.c +mv sysintf.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver40 -O parse.c +mv parse.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver40 -O getinp.c +mv getinp.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver40 -O quit.c +mv quit.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver40 -O state.c +mv state.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver40 -O dmdump.c +mv dmdump.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver40 -O macparse.c +mv macparse.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver40 -O rulparse.c +mv rulparse.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver40 -O percent.c +mv percent.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver40 -O function.c +mv function.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver40 -O unix/arlib.c +mv arlib.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver40 -O unix/dirbrk.c +mv dirbrk.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver40 -O unix/rmprq.c +mv rmprq.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver40 -O unix/ruletab.c +mv ruletab.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver40 -O unix/runargv.c +mv runargv.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver40 -O unix/dcache.c +mv dcache.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver40 -O unix/coherent/ver40/vfprintf.c +mv vfprintf.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver40 -O unix/coherent/ver40/getcwd.c +mv getcwd.o objects +cc -O -o dmake objects/infer.o objects/make.o objects/stat.o objects/expand.o \ +objects/dmstring.o objects/hash.o objects/dag.o objects/dmake.o objects/path.o \ +objects/imacs.o objects/sysintf.o objects/parse.o objects/getinp.o \ +objects/quit.o objects/state.o objects/dmdump.o objects/macparse.o \ +objects/rulparse.o objects/percent.o objects/function.o objects/arlib.o \ +objects/dirbrk.o objects/rmprq.o objects/ruletab.o objects/runargv.o objects/dcache.o objects/vfprintf.o objects/getcwd.o +cp unix/coherent/ver40/template.mk startup/config.mk diff --git a/dmake/unix/coherent/ver40/public.h b/dmake/unix/coherent/ver40/public.h new file mode 100644 index 000000000000..da4cc6c0b7c4 --- /dev/null +++ b/dmake/unix/coherent/ver40/public.h @@ -0,0 +1,164 @@ +/* RCS $Id: public.h,v 1.1.1.1 2000-09-22 15:33:34 hr Exp $ +-- WARNING -- This file is AUTOMATICALLY GENERATED DO NOT EDIT IT +-- +-- +-- SYNOPSIS +-- Local functions exported to be visible by others. +-- +-- DESCRIPTION +-- This file is generated by 'genpub'. Function declarations +-- that appear in this file are extracted by 'genpub' from +-- source files. Any function in the source file whose definition +-- appears like: +-- +-- PUBLIC return_type +-- function( arg_list ); +-- type_expr1 arg1; +-- ... +-- +-- has its definition extracted and a line of the form: +-- +-- return_type function ANSI((type_expr1,type_expr2,...)); +-- +-- entered into the output file. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef _DMAKE_PUBLIC_h +#define _DMAKE_PUBLIC_h + +#ifdef EXTERN +#undef EXTERN +#endif +#if defined(DEFINE_DMAKE_VARIABLES) +#define EXTERN +#else +#define EXTERN extern +#endif + +/***** genpub: Begin list of generated function headers */ +void Infer_recipe ANSI((CELLPTR, CELLPTR)); +int Make_targets ANSI(()); +int Make ANSI((CELLPTR, CELLPTR)); +int Exec_commands ANSI((CELLPTR)); +void Print_cmnd ANSI((char *, int, int)); +int Push_dir ANSI((char *, char *, int)); +void Pop_dir ANSI((int)); +void Append_line ANSI((char *, int, FILE *, char *, int, int)); +void Stat_target ANSI((CELLPTR, int, int)); +char *Expand ANSI((char *)); +char *Apply_edit ANSI((char *, char *, char *, int, int)); +void Map_esc ANSI((char *)); +char* Apply_modifiers ANSI((int, char *)); +char* Tokenize ANSI((char *, char *, char, int)); +char* ScanToken ANSI((char *, char **, int)); +char *DmStrJoin ANSI((char *, char *, int, int)); +char *DmStrAdd ANSI((char *, char *, int)); +char *DmStrApp ANSI((char *, char *)); +char *DmStrDup ANSI((char *)); +char *DmStrDup2 ANSI((char *)); +char *DmStrPbrk ANSI((char *, char *)); +char *DmStrSpn ANSI((char *, char *)); +char *DmStrStr ANSI((char *, char *)); +char *DmSubStr ANSI((char *, char *)); +uint16 Hash ANSI((char *, uint32 *)); +HASHPTR Get_name ANSI((char *, HASHPTR *, int)); +HASHPTR Search_table ANSI((HASHPTR *, char *, uint16 *, uint32 *)); +HASHPTR Push_macro ANSI((HASHPTR)); +HASHPTR Pop_macro ANSI((HASHPTR)); +HASHPTR Def_macro ANSI((char *, char *, int)); +CELLPTR Def_cell ANSI((char *)); +LINKPTR Add_prerequisite ANSI((CELLPTR, CELLPTR, int, int)); +void Clear_prerequisites ANSI((CELLPTR)); +int Test_circle ANSI((CELLPTR, int)); +STRINGPTR Def_recipe ANSI((char *, STRINGPTR, int, int)); +t_attr Rcp_attribute ANSI((char *)); +void main ANSI((int, char **)); +FILE *Openfile ANSI((char *, int, int)); +FILE *Closefile ANSI(()); +FILE *Search_file ANSI((char *, char **)); +char *Filename ANSI(()); +int Nestlevel ANSI(()); +FILE *TryFiles ANSI((LINKPTR)); +void Fatal ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Error ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Warning ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void No_ram ANSI(()); +void Usage ANSI((int)); +void Version ANSI(()); +char *Get_suffix ANSI((char *)); +char *Basename ANSI((char *)); +char *Filedir ANSI((char *)); +char *Build_path ANSI((char *, char *)); +void Make_rules ANSI(()); +void Create_macro_vars ANSI(()); +time_t Do_stat ANSI((char *, char *, char **, int)); +int Do_touch ANSI((char *, char *, char **)); +void Void_lib_cache ANSI((char *, char *)); +time_t Do_time ANSI(()); +int Do_cmnd ANSI((char *, int, int, CELLPTR, int, int, int)); +char ** Pack_argv ANSI((int, int, char *)); +char *Read_env_string ANSI((char *)); +int Write_env_string ANSI((char *, char *)); +void ReadEnvironment ANSI(()); +void Catch_signals ANSI((void (*)())); +void Clear_signals ANSI(()); +void Prolog ANSI((int, char* [])); +void Epilog ANSI((int)); +char *Get_current_dir ANSI(()); +int Set_dir ANSI((char*)); +char Get_switch_char ANSI(()); +FILE* Get_temp ANSI((char **, char *, int)); +FILE *Start_temp ANSI((char *, CELLPTR, char **)); +void Open_temp_error ANSI((char *, char *)); +void Link_temp ANSI((CELLPTR, FILE *, char *)); +void Close_temp ANSI((CELLPTR, FILE *)); +void Unlink_temp_files ANSI((CELLPTR)); +void Handle_result ANSI((int, int, int, CELLPTR)); +void Update_time_stamp ANSI((CELLPTR)); +int Remove_file ANSI((char *)); +void Parse ANSI((FILE *)); +int Get_line ANSI((char *, FILE *)); +char *Do_comment ANSI((char *, char **, int)); +char *Get_token ANSI((TKSTRPTR, char *, int)); +void Quit ANSI(()); +void Read_state ANSI(()); +void Write_state ANSI(()); +int Check_state ANSI((CELLPTR, STRINGPTR *, int)); +void Dump ANSI(()); +void Dump_recipe ANSI((STRINGPTR)); +int Parse_macro ANSI((char *, int)); +int Macro_op ANSI((char *)); +int Parse_rule_def ANSI((int *)); +int Rule_op ANSI((char *)); +void Add_recipe_to_list ANSI((char *, int, int)); +void Bind_rules_to_targets ANSI((int)); +int Set_group_attributes ANSI((char *)); +DFALINKPTR Match_dfa ANSI((char *)); +void Check_circle_dfa ANSI(()); +void Add_nfa ANSI((char *)); +char *Exec_function ANSI((char *)); +time_t seek_arch ANSI((char *, char *)); +int If_root_path ANSI((char *)); +void Remove_prq ANSI((CELLPTR)); +int runargv ANSI((CELLPTR, int, int, int, int, char *)); +int Wait_for_child ANSI((int, int)); +void Clean_up_processes ANSI(()); +time_t CacheStat ANSI((char *, int)); + +#endif diff --git a/dmake/unix/coherent/ver40/template.mk b/dmake/unix/coherent/ver40/template.mk new file mode 100644 index 000000000000..ef23550cf651 --- /dev/null +++ b/dmake/unix/coherent/ver40/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= unix + OSRELEASE *:= coherent + OSENVIRONMENT *:= ver40 diff --git a/dmake/unix/coherent/ver40/vfprintf.c b/dmake/unix/coherent/ver40/vfprintf.c new file mode 100644 index 000000000000..907230db2081 --- /dev/null +++ b/dmake/unix/coherent/ver40/vfprintf.c @@ -0,0 +1,190 @@ +/* Portable vfprintf and vprintf by Robert A. Larson <blarson@skat.usc.edu> */ + +/* Copyright 1989 Robert A. Larson. + * Distribution in any form is allowed as long as the author + * retains credit, changes are noted by their author and the + * copyright message remains intact. This program comes as-is + * with no warentee of fitness for any purpouse. + * + * Thanks to Doug Gwen, Chris Torek, and others who helped clarify + * the ansi printf specs. + * + * Please send any bug fixes and improvments to blarson@skat.usc.edu . + * The use of goto is NOT a bug. + */ + +/* Feb 9, 1989 blarson First usenet release */ + +/* This code implements the vfprintf function, without relying on + * the existance of _doprint or other system specific code. + * + * Define NOVOID if void * is not a supported type. + * + * Two compile options are available for efficency: + * INTSPRINTF should be defined if sprintf is int and returns + * the number of chacters formated. + * LONGINT should be defined if sizeof(long) == sizeof(int) + * + * They only make the code smaller and faster, they need not be + * defined. + * + * UNSIGNEDSPECIAL should be defined if unsigned is treated differently + * than int in argument passing. If this is definded, and LONGINT is not, + * the compiler must support the type unsingned long. + * + * Most quirks and bugs of the available fprintf fuction are duplicated, + * however * in the width and precision fields will work correctly + * even if fprintf does not support this. The %n format and the return + * count will only work if fprintf returns the number of characters + * formatted. + * + * Bad format strings, or those with very long width and precision + * fields (including expanded * fields) will cause undesired results. + */ + +#ifdef OSK /* os9/68k can take advantage of both */ +#define INTSPRINTF +#define LONGINT +#endif +#define NOVOID 1 + +/* This must be a typedef not a #define! */ +#ifdef NOVOID +typedef char *pointer; +#else +typedef void *pointer; +#endif + +#include <stdio.h> + +#ifdef INTSPRINTF +#define Sprintf(string,format,arg) (sprintf((string),(format),(arg))) +#else +#define Sprintf(string,format,arg) (\ + sprintf((string),(format),(arg)),\ + strlen(string)\ +) +#endif + +#include <stdarg.h> + +typedef int *intp; + +int vfprintf(dest, format, args) +FILE *dest; +register char *format; +va_list args; +{ + register char c; + register char *tp; + register int count = 0; + char tempfmt[64]; +#ifndef LONGINT + int longflag; +#endif + + tempfmt[0] = '%'; + while(c = *format++) { + if(c=='%') { + tp = &tempfmt[1]; +#ifndef LONGINT + longflag = 0; +#endif +continue_format: + switch(c = *format++) { + case 's': + *tp++ = c; + *tp = '\0'; + count += fprintf(dest, tempfmt, va_arg(args, char *)); + break; + case 'u': + case 'x': + case 'o': + case 'X': +#ifdef UNSIGNEDSPECIAL + *tp++ = c; + *tp = '\0'; +#ifndef LONGINT + if(longflag) + count += fprintf(dest, tempfmt, va_arg(args, unsigned long)); + else +#endif + count += fprintf(dest, tempfmt, va_arg(args, unsigned)); + break; +#endif + case 'd': + case 'c': + case 'i': + *tp++ = c; + *tp = '\0'; +#ifndef LONGINT + if(longflag) + count += fprintf(dest, tempfmt, va_arg(args, long)); + else +#endif + count += fprintf(dest, tempfmt, va_arg(args, int)); + break; + case 'f': + case 'e': + case 'E': + case 'g': + case 'G': + *tp++ = c; + *tp = '\0'; + count += fprintf(dest, tempfmt, va_arg(args, double)); + break; + case 'p': + *tp++ = c; + *tp = '\0'; + count += fprintf(dest, tempfmt, va_arg(args, pointer)); + break; + case '-': + case '+': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '.': + case ' ': + case '#': + case 'h': + *tp++ = c; + goto continue_format; + case 'l': +#ifndef LONGINT + longflag = 1; + *tp++ = c; +#endif + goto continue_format; + case '*': + tp += Sprintf(tp, "%d", va_arg(args, int)); + goto continue_format; + case 'n': + *va_arg(args, intp) = count; + break; + case '%': + default: + putc(c, dest); + count++; + break; + } + } else { + putc(c, dest); + count++; + } + } + return count; +} + +vprintf(format, args) +char *format; +va_list args; +{ + return vfprintf(stdout, format, args); +} diff --git a/dmake/unix/coherent/ver42/config.mk b/dmake/unix/coherent/ver42/config.mk new file mode 100644 index 000000000000..2ff06b6b7917 --- /dev/null +++ b/dmake/unix/coherent/ver42/config.mk @@ -0,0 +1,11 @@ +# This config file adds vfprintf.c and memcpy.c for those systems that +# do not have it. +# + +osredir := $(OS)$(DIRSEPSTR)$(OSRELEASE)$(DIRSEPSTR)$(OSENVIRONMENT) +CFLAGS += -I$(osredir) + +# The following sources are required for Coherent version 4.2 +#OSDESRC := +#SRC += $(OSDESRC) +#.SETDIR=$(osredir) : $(OSDESRC) diff --git a/dmake/unix/coherent/ver42/make.sh b/dmake/unix/coherent/ver42/make.sh new file mode 100644 index 000000000000..bfc7f8252a5d --- /dev/null +++ b/dmake/unix/coherent/ver42/make.sh @@ -0,0 +1,60 @@ +mkdir objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver42 -O infer.c +mv infer.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver42 -O make.c +mv make.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver42 -O stat.c +mv stat.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver42 -O expand.c +mv expand.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver42 -O dmstring.c +mv dmstring.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver42 -O hash.c +mv hash.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver42 -O dag.c +mv dag.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver42 -O dmake.c +mv dmake.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver42 -O path.c +mv path.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver42 -O imacs.c +mv imacs.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver42 -O sysintf.c +mv sysintf.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver42 -O parse.c +mv parse.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver42 -O getinp.c +mv getinp.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver42 -O quit.c +mv quit.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver42 -O state.c +mv state.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver42 -O dmdump.c +mv dmdump.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver42 -O macparse.c +mv macparse.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver42 -O rulparse.c +mv rulparse.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver42 -O percent.c +mv percent.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver42 -O function.c +mv function.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver42 -O unix/arlib.c +mv arlib.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver42 -O unix/dirbrk.c +mv dirbrk.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver42 -O unix/rmprq.c +mv rmprq.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver42 -O unix/ruletab.c +mv ruletab.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver42 -O unix/runargv.c +mv runargv.o objects +cc -c -I. -Iunix -Iunix/coherent -Dvoid=int -Iunix/coherent/ver42 -O unix/dcache.c +mv dcache.o objects +cc -O -o dmake objects/infer.o objects/make.o objects/stat.o objects/expand.o \ +objects/dmstring.o objects/hash.o objects/dag.o objects/dmake.o objects/path.o \ +objects/imacs.o objects/sysintf.o objects/parse.o objects/getinp.o \ +objects/quit.o objects/state.o objects/dmdump.o objects/macparse.o \ +objects/rulparse.o objects/percent.o objects/function.o objects/arlib.o \ +objects/dirbrk.o objects/rmprq.o objects/ruletab.o objects/runargv.o objects/dcache.o +cp unix/coherent/ver42/template.mk startup/config.mk diff --git a/dmake/unix/coherent/ver42/public.h b/dmake/unix/coherent/ver42/public.h new file mode 100644 index 000000000000..01e80862fbbd --- /dev/null +++ b/dmake/unix/coherent/ver42/public.h @@ -0,0 +1,164 @@ +/* RCS $Id: public.h,v 1.1.1.1 2000-09-22 15:33:35 hr Exp $ +-- WARNING -- This file is AUTOMATICALLY GENERATED DO NOT EDIT IT +-- +-- +-- SYNOPSIS +-- Local functions exported to be visible by others. +-- +-- DESCRIPTION +-- This file is generated by 'genpub'. Function declarations +-- that appear in this file are extracted by 'genpub' from +-- source files. Any function in the source file whose definition +-- appears like: +-- +-- PUBLIC return_type +-- function( arg_list ); +-- type_expr1 arg1; +-- ... +-- +-- has its definition extracted and a line of the form: +-- +-- return_type function ANSI((type_expr1,type_expr2,...)); +-- +-- entered into the output file. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef _DMAKE_PUBLIC_h +#define _DMAKE_PUBLIC_h + +#ifdef EXTERN +#undef EXTERN +#endif +#if defined(DEFINE_DMAKE_VARIABLES) +#define EXTERN +#else +#define EXTERN extern +#endif + +/***** genpub: Begin list of generated function headers */ +void Infer_recipe ANSI((CELLPTR, CELLPTR)); +int Make_targets ANSI(()); +int Make ANSI((CELLPTR, CELLPTR)); +int Exec_commands ANSI((CELLPTR)); +void Print_cmnd ANSI((char *, int, int)); +int Push_dir ANSI((char *, char *, int)); +void Pop_dir ANSI((int)); +void Append_line ANSI((char *, int, FILE *, char *, int, int)); +void Stat_target ANSI((CELLPTR, int, int)); +char *Expand ANSI((char *)); +char *Apply_edit ANSI((char *, char *, char *, int, int)); +void Map_esc ANSI((char *)); +char* Apply_modifiers ANSI((int, char *)); +char* Tokenize ANSI((char *, char *, char, int)); +char* ScanToken ANSI((char *, char **, int)); +char *DmStrJoin ANSI((char *, char *, int, int)); +char *DmStrAdd ANSI((char *, char *, int)); +char *DmStrApp ANSI((char *, char *)); +char *DmStrDup ANSI((char *)); +char *DmStrDup2 ANSI((char *)); +char *DmStrPbrk ANSI((char *, char *)); +char *DmStrSpn ANSI((char *, char *)); +char *DmStrStr ANSI((char *, char *)); +char *DmSubStr ANSI((char *, char *)); +uint16 Hash ANSI((char *, uint32 *)); +HASHPTR Get_name ANSI((char *, HASHPTR *, int)); +HASHPTR Search_table ANSI((HASHPTR *, char *, uint16 *, uint32 *)); +HASHPTR Push_macro ANSI((HASHPTR)); +HASHPTR Pop_macro ANSI((HASHPTR)); +HASHPTR Def_macro ANSI((char *, char *, int)); +CELLPTR Def_cell ANSI((char *)); +LINKPTR Add_prerequisite ANSI((CELLPTR, CELLPTR, int, int)); +void Clear_prerequisites ANSI((CELLPTR)); +int Test_circle ANSI((CELLPTR, int)); +STRINGPTR Def_recipe ANSI((char *, STRINGPTR, int, int)); +t_attr Rcp_attribute ANSI((char *)); +void main ANSI((int, char **)); +FILE *Openfile ANSI((char *, int, int)); +FILE *Closefile ANSI(()); +FILE *Search_file ANSI((char *, char **)); +char *Filename ANSI(()); +int Nestlevel ANSI(()); +FILE *TryFiles ANSI((LINKPTR)); +void Fatal ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Error ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Warning ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void No_ram ANSI(()); +void Usage ANSI((int)); +void Version ANSI(()); +char *Get_suffix ANSI((char *)); +char *Basename ANSI((char *)); +char *Filedir ANSI((char *)); +char *Build_path ANSI((char *, char *)); +void Make_rules ANSI(()); +void Create_macro_vars ANSI(()); +time_t Do_stat ANSI((char *, char *, char **, int)); +int Do_touch ANSI((char *, char *, char **)); +void Void_lib_cache ANSI((char *, char *)); +time_t Do_time ANSI(()); +int Do_cmnd ANSI((char *, int, int, CELLPTR, int, int, int)); +char ** Pack_argv ANSI((int, int, char *)); +char *Read_env_string ANSI((char *)); +int Write_env_string ANSI((char *, char *)); +void ReadEnvironment ANSI(()); +void Catch_signals ANSI((void (*)())); +void Clear_signals ANSI(()); +void Prolog ANSI((int, char* [])); +void Epilog ANSI((int)); +char *Get_current_dir ANSI(()); +int Set_dir ANSI((char*)); +char Get_switch_char ANSI(()); +FILE* Get_temp ANSI((char **, char *, int)); +FILE *Start_temp ANSI((char *, CELLPTR, char **)); +void Open_temp_error ANSI((char *, char *)); +void Link_temp ANSI((CELLPTR, FILE *, char *)); +void Close_temp ANSI((CELLPTR, FILE *)); +void Unlink_temp_files ANSI((CELLPTR)); +void Handle_result ANSI((int, int, int, CELLPTR)); +void Update_time_stamp ANSI((CELLPTR)); +int Remove_file ANSI((char *)); +void Parse ANSI((FILE *)); +int Get_line ANSI((char *, FILE *)); +char *Do_comment ANSI((char *, char **, int)); +char *Get_token ANSI((TKSTRPTR, char *, int)); +void Quit ANSI(()); +void Read_state ANSI(()); +void Write_state ANSI(()); +int Check_state ANSI((CELLPTR, STRINGPTR *, int)); +void Dump ANSI(()); +void Dump_recipe ANSI((STRINGPTR)); +int Parse_macro ANSI((char *, int)); +int Macro_op ANSI((char *)); +int Parse_rule_def ANSI((int *)); +int Rule_op ANSI((char *)); +void Add_recipe_to_list ANSI((char *, int, int)); +void Bind_rules_to_targets ANSI((int)); +int Set_group_attributes ANSI((char *)); +DFALINKPTR Match_dfa ANSI((char *)); +void Check_circle_dfa ANSI(()); +void Add_nfa ANSI((char *)); +char *Exec_function ANSI((char *)); +time_t seek_arch ANSI((char *, char *)); +int If_root_path ANSI((char *)); +void Remove_prq ANSI((CELLPTR)); +int runargv ANSI((CELLPTR, int, int, int, int, char *)); +int Wait_for_child ANSI((int, int)); +void Clean_up_processes ANSI(()); +time_t CacheStat ANSI((char *, int)); + +#endif diff --git a/dmake/unix/coherent/ver42/template.mk b/dmake/unix/coherent/ver42/template.mk new file mode 100644 index 000000000000..e5dd9f99ffac --- /dev/null +++ b/dmake/unix/coherent/ver42/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= unix + OSRELEASE *:= coherent + OSENVIRONMENT *:= ver42 diff --git a/dmake/unix/config.mk b/dmake/unix/config.mk new file mode 100644 index 000000000000..a6859ceb3c50 --- /dev/null +++ b/dmake/unix/config.mk @@ -0,0 +1,39 @@ +# This is an OS specific configuration file +# It assumes that OBJDIR, TARGET and DEBUG are previously defined. +# It defines CFLAGS, LDARGS, CPPFLAGS, STARTUPFILE, LDOBJS +# PRINTER, PRINTFLAGS +# It augments SRC, OBJDIR, TARGET, CFLAGS, LDLIBS +# +PRINTER = hw +PRINTFLAGS = -P$(PRINTER) +STARTUPFILE = $(OS)/startup.mk +CPPFLAGS = $(CFLAGS) +LDOBJS = $(CSTARTUP) $(OBJDIR)/{$(<:f)} +LDARGS = $(LDFLAGS) -o $@ $(LDOBJS) $(LDLIBS) + +# Debug flags +DB_CFLAGS = -g -DDBUG +DB_LDFLAGS = -g +DB_LDLIBS = + +# NO Debug flags +NDB_CFLAGS = -O +NDB_LDFLAGS = -O +NDB_LDLIBS = + +# Local configuration modifications for CFLAGS. +CFLAGS += -I$(OS) + +# Sources that must be defined for each different version +OSSRC := arlib.c dirbrk.c rmprq.c ruletab.c runargv.c dcache.c +SRC += $(OSSRC) +.SETDIR=$(OS) : $(OSSRC) + +# Set source dirs so that we can find files named in this +# config file. +.SOURCE.h : $(OS) + +# See if we modify anything in the lower levels. +.IF $(OSRELEASE) != $(NULL) + .INCLUDE .IGNORE : $(OS)$(DIRSEPSTR)$(OSRELEASE)$(DIRSEPSTR)config.mk +.END diff --git a/dmake/unix/dcache.c b/dmake/unix/dcache.c new file mode 100644 index 000000000000..d9ab5d987584 --- /dev/null +++ b/dmake/unix/dcache.c @@ -0,0 +1,198 @@ +/* RCS $Id: dcache.c,v 1.1.1.1 2000-09-22 15:33:33 hr Exp $ +-- +-- SYNOPSIS +-- Directory cache management routines. +-- +-- DESCRIPTION +-- This is the code that maintains a directory cache for each directory +-- that dmake visits. The entire directory is thus only read once and +-- the need for performing costly 'stat' calls when performing target +-- inference is much reduced. The improvement in performance should be +-- significant for NFS or remote mounted file systems. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +/* For Borland 5.00 compile, for some reason they seem to insist on pulling + * in the winnt.h if __WIN32__ is defined and you include <dirent.h>. This + * is, in my opinion, a BUG! on Borland's part. + */ +#if defined(__BORLANDC__) && defined(__WIN32__) +#undef __WIN32__ +#endif + +#ifdef __APPLE__ +#include <sys/types.h> +#endif +#include <dirent.h> +#include "extern.h" +#include "sysintf.h" + + +typedef struct ent { + char *name; + uint32 hkey; + time_t mtime; + int isdir; + struct ent *next; +} Entry, *EntryPtr; + + +typedef struct mydir { + char *path; + uint32 hkey; + EntryPtr entries; + struct mydir *next; +} DirEntry, *DirEntryPtr; + +static DirEntryPtr dtab[HASH_TABLE_SIZE]; + + +/* Stat a path using the directory cache. + * + * We build a cannonical representation of the path using either an absolute + * path name if that is what 'path' is or the relative path name constructed + * from 'path' and the present value of Pwd. + * + * The present value of Pwd then gives a directory path that we search for + * in our cache using a hash lookup. If the directory component is located + * then we search the basename component of the path and return the result of + * the search: 0L if the component is not in the cache and it's time stamp + * otherwise. + * + * If the directory is not in our cache we insert it into the cache by + * openning the directory and reading all of the files within. Once read + * then we return the result of the above search. + * + * Optionally, if force is TRUE, and we did NOT read the directory to provide + * the result then stat the file anyway and update the internal cache. + */ + +PUBLIC time_t +CacheStat(path, force) +char *path; +int force; +{ + struct stat stbuf; + DirEntryPtr dp; + EntryPtr ep; + uint32 hkey; + uint16 hv; + char *fpath; + char *spath; + char *comp; + char *dir; + int loaded=FALSE; + +#ifdef __APPLE__ + /* On Mac OS X, open, stat, and other system calls are case-insenstive. + Since this function keeps a case-sensitive cache, we need to force + a stat of the file if there is no match in the cache just to make sure + that we don't miss a file when only the case is different */ + force = TRUE; +#endif + + if (If_root_path(path)) + spath = path; + else + spath = Build_path(Pwd,path); + + fpath = DmStrDup(spath); + comp = Basename(fpath); + dir = Filedir(fpath); + + hv = Hash(dir,&hkey); + + for(dp=dtab[hv]; dp; dp=dp->next) + if (hkey == dp->hkey && strcmp(dp->path,dir) == 0) + break; + + if (!dp) { + DIR *dirp; + struct dirent *direntp; + + if( Verbose & V_DIR_CACHE ) + printf( "%s: Caching directory [%s]\n", Pname, dir ); + + /* Load the directory, we have the right hash position already */ + loaded = TRUE; + + TALLOC(dp,1,DirEntry); + dp->next = dtab[hv]; + dtab[hv] = dp; + dp->path = DmStrDup(dir); + dp->hkey = hkey; + + if (Set_dir(dir) == 0) { + if((dirp=opendir(".")) != NIL(DIR)) { + while((direntp=readdir(dirp)) != NULL) { + TALLOC(ep,1,Entry); + ep->name = DmStrDup(direntp->d_name); + + /* Perform case mapping of name if appropriate */ + DMSTRLWR(ep->name, comp); + Hash(ep->name, &ep->hkey); + + ep->next = dp->entries; + dp->entries = ep; + DMSTAT(direntp->d_name,&stbuf); + ep->isdir = (stbuf.st_mode & S_IFDIR); + ep->mtime = stbuf.st_mtime; + } + closedir(dirp); + } + Set_dir(Pwd); + } + } + + Hash(comp, &hkey); + + if (dp) { + for(ep=dp->entries; ep; ep=ep->next) + if(hkey == ep->hkey && strcmp(ep->name,comp) == 0) + break; + } + else + ep = NULL; + + if( force && !loaded) { + if (strlen(comp) > NameMax || DMSTAT(spath,&stbuf) != 0) { + if(ep) + ep->mtime = 0L; + } + else { + if (!ep) { + TALLOC(ep,1,Entry); + ep->name = DmStrDup(comp); + DMSTRLWR(ep->name, comp); + Hash(ep->name, &ep->hkey); + ep->next = dp->entries; + ep->isdir = (stbuf.st_mode & S_IFDIR); + dp->entries = ep; + } + + ep->mtime = stbuf.st_mtime; + } + + if( Verbose & V_DIR_CACHE ) + printf("%s: Updating dir cache entry for [%s], new time is %d\n", + Pname, spath, ep ? ep->mtime : 0L); + } + + FREE(fpath); + return(!ep ? (time_t)0L : ((STOBOOL(Augmake) && ep->isdir)?0L:ep->mtime)); +} diff --git a/dmake/unix/dirbrk.c b/dmake/unix/dirbrk.c new file mode 100644 index 000000000000..727df34f70a4 --- /dev/null +++ b/dmake/unix/dirbrk.c @@ -0,0 +1,42 @@ +/* RCS $Id: dirbrk.c,v 1.1.1.1 2000-09-22 15:33:33 hr Exp $ +-- +-- SYNOPSIS +-- Define the directory separator string. +-- +-- DESCRIPTION +-- Define this string for any character that may appear in a path name +-- and can be used as a directory separator. Also provide a function +-- to indicate if a given path begins at the root of the file system. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include "extern.h" + +/* Unix only uses / */ +char* DirBrkStr = "/"; + +/* +** Return TRUE if the name is the full specification of a path name to a file +** starting at the root of the file system, otherwise return FALSE +*/ +PUBLIC int +If_root_path(name) +char *name; +{ + return( strchr(DirBrkStr, *name) != NIL(char) ); +} diff --git a/dmake/unix/linux/config.mk b/dmake/unix/linux/config.mk new file mode 100644 index 000000000000..75bcf3c2a211 --- /dev/null +++ b/dmake/unix/linux/config.mk @@ -0,0 +1,27 @@ +# This is the SysV R3 UNIX configuration file for DMAKE +# It simply modifies the values of SRC, and checks to see if +# OSENVIRONMENT is defined. If so it includes the appropriate +# config.mk file. +# +# It also sets the values of .SOURCE.c and .SOURCE.h to include the local +# directory. +# +osrdir := $(OS)$(DIRSEPSTR)$(OSRELEASE) + +# The following are required sources +OSDSRC := +.IF $(OSDSRC) + SRC += $(OSDSRC) + .SETDIR=$(osrdir) : $(OSDSRC) +.END + +.SOURCE.h : $(osrdir) + +# Local configuration modifications for CFLAGS, there's local SysV includes +# too. +CFLAGS += -I$(osrdir) + +# See if we modify anything in the lower levels. +.IF $(OSENVIRONMENT) != $(NULL) + .INCLUDE .IGNORE : $(osrdir)$(DIRSEPSTR)$(OSENVIRONMENT)$(DIRSEPSTR)config.mk +.END diff --git a/dmake/unix/linux/gnu/config.mk b/dmake/unix/linux/gnu/config.mk new file mode 100644 index 000000000000..e351490a6b3d --- /dev/null +++ b/dmake/unix/linux/gnu/config.mk @@ -0,0 +1,4 @@ +# This is the Linux gnu configuration file for DMAKE +# It makes sure we include from the right place. +# +CFLAGS += -I$(osrdir)$(DIRSEPSTR)$(OSENVIRONMENT) diff --git a/dmake/unix/linux/gnu/make.sh b/dmake/unix/linux/gnu/make.sh new file mode 100644 index 000000000000..8e0aa400a80b --- /dev/null +++ b/dmake/unix/linux/gnu/make.sh @@ -0,0 +1,193 @@ +platform=`uname -m`; export platform; + +mkdir objects + +if test $platform = sparc -o $platform = sparc64; then +gcc -c -ansi -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O infer.c +else +gcc -c -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O infer.c +fi +mv infer.o objects + +if test $platform = sparc -o $platform = sparc64; then +gcc -c -ansi -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O make.c +else +gcc -c -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O make.c +fi +mv make.o objects + +if test $platform = sparc -o $platform = sparc64; then +gcc -c -ansi -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O stat.c +else +gcc -c -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O stat.c +fi +mv stat.o objects + +if test $platform = sparc -o $platform = sparc64; then +gcc -c -ansi -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O expand.c +else +gcc -c -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O expand.c +fi +mv expand.o objects + +if test $platform = sparc -o $platform = sparc64; then +gcc -c -ansi -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O dmstring.c +else +gcc -c -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O dmstring.c +fi +mv dmstring.o objects + +if test $platform = sparc -o $platform = sparc64; then +gcc -c -ansi -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O hash.c +else +gcc -c -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O hash.c +fi +mv hash.o objects + +if test $platform = sparc -o $platform = sparc64; then +gcc -c -ansi -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O dag.c +else +gcc -c -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O dag.c +fi +mv dag.o objects + +if test $platform = sparc -o $platform = sparc64; then +gcc -c -ansi -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O dmake.c +else +gcc -c -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O dmake.c +fi +mv dmake.o objects + +if test $platform = sparc -o $platform = sparc64; then +gcc -c -ansi -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O path.c +else +gcc -c -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O path.c +fi +mv path.o objects + +if test $platform = sparc -o $platform = sparc64; then +gcc -c -ansi -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O imacs.c +else +gcc -c -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O imacs.c +fi +mv imacs.o objects + +if test $platform = sparc -o $platform = sparc64; then +gcc -c -ansi -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O sysintf.c +else +gcc -c -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O sysintf.c +fi +mv sysintf.o objects + +if test $platform = sparc -o $platform = sparc64; then +gcc -c -ansi -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O parse.c +else +gcc -c -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O parse.c +fi +mv parse.o objects + +if test $platform = sparc -o $platform = sparc64; then +gcc -c -ansi -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O getinp.c +else +gcc -c -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O getinp.c +fi +mv getinp.o objects + +if test $platform = sparc -o $platform = sparc64; then +gcc -c -ansi -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O quit.c +else +gcc -c -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O quit.c +fi +mv quit.o objects + +if test $platform = sparc -o $platform = sparc64; then +gcc -c -ansi -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O state.c +else +gcc -c -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O state.c +fi +mv state.o objects + +if test $platform = sparc -o $platform = sparc64; then +gcc -c -ansi -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O dmdump.c +else +gcc -c -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O dmdump.c +fi +mv dmdump.o objects + +if test $platform = sparc -o $platform = sparc64; then +gcc -c -ansi -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O macparse.c +else +gcc -c -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O macparse.c +fi +mv macparse.o objects + +if test $platform = sparc -o $platform = sparc64; then +gcc -c -ansi -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O rulparse.c +else +gcc -c -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O rulparse.c +fi +mv rulparse.o objects + +if test $platform = sparc -o $platform = sparc64; then +gcc -c -ansi -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O percent.c +else +gcc -c -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O percent.c +fi +mv percent.o objects + +if test $platform = sparc -o $platform = sparc64; then +gcc -c -ansi -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O function.c +else +gcc -c -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O function.c +fi +mv function.o objects + +if test $platform = sparc -o $platform = sparc64; then +gcc -c -ansi -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O unix/arlib.c +else +gcc -c -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O unix/arlib.c +fi +mv arlib.o objects + +if test $platform = sparc -o $platform = sparc64; then +gcc -c -ansi -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O unix/dirbrk.c +else +gcc -c -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O unix/dirbrk.c +fi +mv dirbrk.o objects + +if test $platform = sparc -o $platform = sparc64; then +gcc -c -ansi -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O unix/rmprq.c +else +gcc -c -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O unix/rmprq.c +fi +mv rmprq.o objects + +if test $platform = sparc -o $platform = sparc64; then +gcc -c -ansi -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O unix/ruletab.c +else +gcc -c -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O unix/ruletab.c +fi +mv ruletab.o objects + +if test $platform = sparc -o $platform = sparc64; then +gcc -c -ansi -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O unix/runargv.c +else +gcc -c -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O unix/runargv.c +fi +mv runargv.o objects + +if test $platform = sparc -o $platform = sparc64; then +gcc -c -ansi -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O unix/dcache.c +else +gcc -c -I. -Iunix -Iunix/linux -Iunix/linux/gnu -O unix/dcache.c +fi +mv dcache.o objects + +gcc -O -o dmake objects/infer.o objects/make.o objects/stat.o objects/expand.o \ +objects/dmstring.o objects/hash.o objects/dag.o objects/dmake.o objects/path.o \ +objects/imacs.o objects/sysintf.o objects/parse.o objects/getinp.o \ +objects/quit.o objects/state.o objects/dmdump.o objects/macparse.o \ +objects/rulparse.o objects/percent.o objects/function.o objects/arlib.o \ +objects/dirbrk.o objects/rmprq.o objects/ruletab.o objects/runargv.o objects/dcache.o +cp unix/linux/gnu/template.mk startup/config.mk diff --git a/dmake/unix/linux/gnu/public.h b/dmake/unix/linux/gnu/public.h new file mode 100644 index 000000000000..01e80862fbbd --- /dev/null +++ b/dmake/unix/linux/gnu/public.h @@ -0,0 +1,164 @@ +/* RCS $Id: public.h,v 1.1.1.1 2000-09-22 15:33:35 hr Exp $ +-- WARNING -- This file is AUTOMATICALLY GENERATED DO NOT EDIT IT +-- +-- +-- SYNOPSIS +-- Local functions exported to be visible by others. +-- +-- DESCRIPTION +-- This file is generated by 'genpub'. Function declarations +-- that appear in this file are extracted by 'genpub' from +-- source files. Any function in the source file whose definition +-- appears like: +-- +-- PUBLIC return_type +-- function( arg_list ); +-- type_expr1 arg1; +-- ... +-- +-- has its definition extracted and a line of the form: +-- +-- return_type function ANSI((type_expr1,type_expr2,...)); +-- +-- entered into the output file. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef _DMAKE_PUBLIC_h +#define _DMAKE_PUBLIC_h + +#ifdef EXTERN +#undef EXTERN +#endif +#if defined(DEFINE_DMAKE_VARIABLES) +#define EXTERN +#else +#define EXTERN extern +#endif + +/***** genpub: Begin list of generated function headers */ +void Infer_recipe ANSI((CELLPTR, CELLPTR)); +int Make_targets ANSI(()); +int Make ANSI((CELLPTR, CELLPTR)); +int Exec_commands ANSI((CELLPTR)); +void Print_cmnd ANSI((char *, int, int)); +int Push_dir ANSI((char *, char *, int)); +void Pop_dir ANSI((int)); +void Append_line ANSI((char *, int, FILE *, char *, int, int)); +void Stat_target ANSI((CELLPTR, int, int)); +char *Expand ANSI((char *)); +char *Apply_edit ANSI((char *, char *, char *, int, int)); +void Map_esc ANSI((char *)); +char* Apply_modifiers ANSI((int, char *)); +char* Tokenize ANSI((char *, char *, char, int)); +char* ScanToken ANSI((char *, char **, int)); +char *DmStrJoin ANSI((char *, char *, int, int)); +char *DmStrAdd ANSI((char *, char *, int)); +char *DmStrApp ANSI((char *, char *)); +char *DmStrDup ANSI((char *)); +char *DmStrDup2 ANSI((char *)); +char *DmStrPbrk ANSI((char *, char *)); +char *DmStrSpn ANSI((char *, char *)); +char *DmStrStr ANSI((char *, char *)); +char *DmSubStr ANSI((char *, char *)); +uint16 Hash ANSI((char *, uint32 *)); +HASHPTR Get_name ANSI((char *, HASHPTR *, int)); +HASHPTR Search_table ANSI((HASHPTR *, char *, uint16 *, uint32 *)); +HASHPTR Push_macro ANSI((HASHPTR)); +HASHPTR Pop_macro ANSI((HASHPTR)); +HASHPTR Def_macro ANSI((char *, char *, int)); +CELLPTR Def_cell ANSI((char *)); +LINKPTR Add_prerequisite ANSI((CELLPTR, CELLPTR, int, int)); +void Clear_prerequisites ANSI((CELLPTR)); +int Test_circle ANSI((CELLPTR, int)); +STRINGPTR Def_recipe ANSI((char *, STRINGPTR, int, int)); +t_attr Rcp_attribute ANSI((char *)); +void main ANSI((int, char **)); +FILE *Openfile ANSI((char *, int, int)); +FILE *Closefile ANSI(()); +FILE *Search_file ANSI((char *, char **)); +char *Filename ANSI(()); +int Nestlevel ANSI(()); +FILE *TryFiles ANSI((LINKPTR)); +void Fatal ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Error ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Warning ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void No_ram ANSI(()); +void Usage ANSI((int)); +void Version ANSI(()); +char *Get_suffix ANSI((char *)); +char *Basename ANSI((char *)); +char *Filedir ANSI((char *)); +char *Build_path ANSI((char *, char *)); +void Make_rules ANSI(()); +void Create_macro_vars ANSI(()); +time_t Do_stat ANSI((char *, char *, char **, int)); +int Do_touch ANSI((char *, char *, char **)); +void Void_lib_cache ANSI((char *, char *)); +time_t Do_time ANSI(()); +int Do_cmnd ANSI((char *, int, int, CELLPTR, int, int, int)); +char ** Pack_argv ANSI((int, int, char *)); +char *Read_env_string ANSI((char *)); +int Write_env_string ANSI((char *, char *)); +void ReadEnvironment ANSI(()); +void Catch_signals ANSI((void (*)())); +void Clear_signals ANSI(()); +void Prolog ANSI((int, char* [])); +void Epilog ANSI((int)); +char *Get_current_dir ANSI(()); +int Set_dir ANSI((char*)); +char Get_switch_char ANSI(()); +FILE* Get_temp ANSI((char **, char *, int)); +FILE *Start_temp ANSI((char *, CELLPTR, char **)); +void Open_temp_error ANSI((char *, char *)); +void Link_temp ANSI((CELLPTR, FILE *, char *)); +void Close_temp ANSI((CELLPTR, FILE *)); +void Unlink_temp_files ANSI((CELLPTR)); +void Handle_result ANSI((int, int, int, CELLPTR)); +void Update_time_stamp ANSI((CELLPTR)); +int Remove_file ANSI((char *)); +void Parse ANSI((FILE *)); +int Get_line ANSI((char *, FILE *)); +char *Do_comment ANSI((char *, char **, int)); +char *Get_token ANSI((TKSTRPTR, char *, int)); +void Quit ANSI(()); +void Read_state ANSI(()); +void Write_state ANSI(()); +int Check_state ANSI((CELLPTR, STRINGPTR *, int)); +void Dump ANSI(()); +void Dump_recipe ANSI((STRINGPTR)); +int Parse_macro ANSI((char *, int)); +int Macro_op ANSI((char *)); +int Parse_rule_def ANSI((int *)); +int Rule_op ANSI((char *)); +void Add_recipe_to_list ANSI((char *, int, int)); +void Bind_rules_to_targets ANSI((int)); +int Set_group_attributes ANSI((char *)); +DFALINKPTR Match_dfa ANSI((char *)); +void Check_circle_dfa ANSI(()); +void Add_nfa ANSI((char *)); +char *Exec_function ANSI((char *)); +time_t seek_arch ANSI((char *, char *)); +int If_root_path ANSI((char *)); +void Remove_prq ANSI((CELLPTR)); +int runargv ANSI((CELLPTR, int, int, int, int, char *)); +int Wait_for_child ANSI((int, int)); +void Clean_up_processes ANSI(()); +time_t CacheStat ANSI((char *, int)); + +#endif diff --git a/dmake/unix/linux/gnu/template.mk b/dmake/unix/linux/gnu/template.mk new file mode 100644 index 000000000000..a0bcef64097b --- /dev/null +++ b/dmake/unix/linux/gnu/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= unix + OSRELEASE *:= linux + OSENVIRONMENT *:= gnu diff --git a/dmake/unix/macosx/config.mk b/dmake/unix/macosx/config.mk new file mode 100644 index 000000000000..75bcf3c2a211 --- /dev/null +++ b/dmake/unix/macosx/config.mk @@ -0,0 +1,27 @@ +# This is the SysV R3 UNIX configuration file for DMAKE +# It simply modifies the values of SRC, and checks to see if +# OSENVIRONMENT is defined. If so it includes the appropriate +# config.mk file. +# +# It also sets the values of .SOURCE.c and .SOURCE.h to include the local +# directory. +# +osrdir := $(OS)$(DIRSEPSTR)$(OSRELEASE) + +# The following are required sources +OSDSRC := +.IF $(OSDSRC) + SRC += $(OSDSRC) + .SETDIR=$(osrdir) : $(OSDSRC) +.END + +.SOURCE.h : $(osrdir) + +# Local configuration modifications for CFLAGS, there's local SysV includes +# too. +CFLAGS += -I$(osrdir) + +# See if we modify anything in the lower levels. +.IF $(OSENVIRONMENT) != $(NULL) + .INCLUDE .IGNORE : $(osrdir)$(DIRSEPSTR)$(OSENVIRONMENT)$(DIRSEPSTR)config.mk +.END diff --git a/dmake/unix/macosx/gnu/config.mk b/dmake/unix/macosx/gnu/config.mk new file mode 100644 index 000000000000..e351490a6b3d --- /dev/null +++ b/dmake/unix/macosx/gnu/config.mk @@ -0,0 +1,4 @@ +# This is the Linux gnu configuration file for DMAKE +# It makes sure we include from the right place. +# +CFLAGS += -I$(osrdir)$(DIRSEPSTR)$(OSENVIRONMENT) diff --git a/dmake/unix/macosx/gnu/make.sh b/dmake/unix/macosx/gnu/make.sh new file mode 100644 index 000000000000..b17a774defb4 --- /dev/null +++ b/dmake/unix/macosx/gnu/make.sh @@ -0,0 +1,60 @@ +mkdir objects +cc -c -I. -Iunix -Iunix/macosx -Iunix/macosx/gnu -O infer.c +mv infer.o objects +cc -c -I. -Iunix -Iunix/macosx -Iunix/macosx/gnu -O make.c +mv make.o objects +cc -c -I. -Iunix -Iunix/macosx -Iunix/macosx/gnu -O stat.c +mv stat.o objects +cc -c -I. -Iunix -Iunix/macosx -Iunix/macosx/gnu -O expand.c +mv expand.o objects +cc -c -I. -Iunix -Iunix/macosx -Iunix/macosx/gnu -O dmstring.c +mv dmstring.o objects +cc -c -I. -Iunix -Iunix/macosx -Iunix/macosx/gnu -O hash.c +mv hash.o objects +cc -c -I. -Iunix -Iunix/macosx -Iunix/macosx/gnu -O dag.c +mv dag.o objects +cc -c -I. -Iunix -Iunix/macosx -Iunix/macosx/gnu -O dmake.c +mv dmake.o objects +cc -c -I. -Iunix -Iunix/macosx -Iunix/macosx/gnu -O path.c +mv path.o objects +cc -c -I. -Iunix -Iunix/macosx -Iunix/macosx/gnu -O imacs.c +mv imacs.o objects +cc -c -I. -Iunix -Iunix/macosx -Iunix/macosx/gnu -O sysintf.c +mv sysintf.o objects +cc -c -I. -Iunix -Iunix/macosx -Iunix/macosx/gnu -O parse.c +mv parse.o objects +cc -c -I. -Iunix -Iunix/macosx -Iunix/macosx/gnu -O getinp.c +mv getinp.o objects +cc -c -I. -Iunix -Iunix/macosx -Iunix/macosx/gnu -O quit.c +mv quit.o objects +cc -c -I. -Iunix -Iunix/macosx -Iunix/macosx/gnu -O state.c +mv state.o objects +cc -c -I. -Iunix -Iunix/macosx -Iunix/macosx/gnu -O dmdump.c +mv dmdump.o objects +cc -c -I. -Iunix -Iunix/macosx -Iunix/macosx/gnu -O macparse.c +mv macparse.o objects +cc -c -I. -Iunix -Iunix/macosx -Iunix/macosx/gnu -O rulparse.c +mv rulparse.o objects +cc -c -I. -Iunix -Iunix/macosx -Iunix/macosx/gnu -O percent.c +mv percent.o objects +cc -c -I. -Iunix -Iunix/macosx -Iunix/macosx/gnu -O function.c +mv function.o objects +cc -c -I. -Iunix -Iunix/macosx -Iunix/macosx/gnu -O unix/arlib.c +mv arlib.o objects +cc -c -I. -Iunix -Iunix/macosx -Iunix/macosx/gnu -O unix/dirbrk.c +mv dirbrk.o objects +cc -c -I. -Iunix -Iunix/macosx -Iunix/macosx/gnu -O unix/rmprq.c +mv rmprq.o objects +cc -c -I. -Iunix -Iunix/macosx -Iunix/macosx/gnu -O unix/ruletab.c +mv ruletab.o objects +cc -c -I. -Iunix -Iunix/macosx -Iunix/macosx/gnu -O unix/runargv.c +mv runargv.o objects +cc -c -I. -Iunix -Iunix/macosx -Iunix/macosx/gnu -O unix/dcache.c +mv dcache.o objects +cc -O -o dmake objects/infer.o objects/make.o objects/stat.o objects/expand.o \ +objects/dmstring.o objects/hash.o objects/dag.o objects/dmake.o objects/path.o \ +objects/imacs.o objects/sysintf.o objects/parse.o objects/getinp.o \ +objects/quit.o objects/state.o objects/dmdump.o objects/macparse.o \ +objects/rulparse.o objects/percent.o objects/function.o objects/arlib.o \ +objects/dirbrk.o objects/rmprq.o objects/ruletab.o objects/runargv.o objects/dcache.o +cp unix/macosx/gnu/template.mk startup/config.mk diff --git a/dmake/unix/macosx/gnu/public.h b/dmake/unix/macosx/gnu/public.h new file mode 100644 index 000000000000..01e80862fbbd --- /dev/null +++ b/dmake/unix/macosx/gnu/public.h @@ -0,0 +1,164 @@ +/* RCS $Id: public.h,v 1.1.1.1 2000-09-22 15:33:35 hr Exp $ +-- WARNING -- This file is AUTOMATICALLY GENERATED DO NOT EDIT IT +-- +-- +-- SYNOPSIS +-- Local functions exported to be visible by others. +-- +-- DESCRIPTION +-- This file is generated by 'genpub'. Function declarations +-- that appear in this file are extracted by 'genpub' from +-- source files. Any function in the source file whose definition +-- appears like: +-- +-- PUBLIC return_type +-- function( arg_list ); +-- type_expr1 arg1; +-- ... +-- +-- has its definition extracted and a line of the form: +-- +-- return_type function ANSI((type_expr1,type_expr2,...)); +-- +-- entered into the output file. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef _DMAKE_PUBLIC_h +#define _DMAKE_PUBLIC_h + +#ifdef EXTERN +#undef EXTERN +#endif +#if defined(DEFINE_DMAKE_VARIABLES) +#define EXTERN +#else +#define EXTERN extern +#endif + +/***** genpub: Begin list of generated function headers */ +void Infer_recipe ANSI((CELLPTR, CELLPTR)); +int Make_targets ANSI(()); +int Make ANSI((CELLPTR, CELLPTR)); +int Exec_commands ANSI((CELLPTR)); +void Print_cmnd ANSI((char *, int, int)); +int Push_dir ANSI((char *, char *, int)); +void Pop_dir ANSI((int)); +void Append_line ANSI((char *, int, FILE *, char *, int, int)); +void Stat_target ANSI((CELLPTR, int, int)); +char *Expand ANSI((char *)); +char *Apply_edit ANSI((char *, char *, char *, int, int)); +void Map_esc ANSI((char *)); +char* Apply_modifiers ANSI((int, char *)); +char* Tokenize ANSI((char *, char *, char, int)); +char* ScanToken ANSI((char *, char **, int)); +char *DmStrJoin ANSI((char *, char *, int, int)); +char *DmStrAdd ANSI((char *, char *, int)); +char *DmStrApp ANSI((char *, char *)); +char *DmStrDup ANSI((char *)); +char *DmStrDup2 ANSI((char *)); +char *DmStrPbrk ANSI((char *, char *)); +char *DmStrSpn ANSI((char *, char *)); +char *DmStrStr ANSI((char *, char *)); +char *DmSubStr ANSI((char *, char *)); +uint16 Hash ANSI((char *, uint32 *)); +HASHPTR Get_name ANSI((char *, HASHPTR *, int)); +HASHPTR Search_table ANSI((HASHPTR *, char *, uint16 *, uint32 *)); +HASHPTR Push_macro ANSI((HASHPTR)); +HASHPTR Pop_macro ANSI((HASHPTR)); +HASHPTR Def_macro ANSI((char *, char *, int)); +CELLPTR Def_cell ANSI((char *)); +LINKPTR Add_prerequisite ANSI((CELLPTR, CELLPTR, int, int)); +void Clear_prerequisites ANSI((CELLPTR)); +int Test_circle ANSI((CELLPTR, int)); +STRINGPTR Def_recipe ANSI((char *, STRINGPTR, int, int)); +t_attr Rcp_attribute ANSI((char *)); +void main ANSI((int, char **)); +FILE *Openfile ANSI((char *, int, int)); +FILE *Closefile ANSI(()); +FILE *Search_file ANSI((char *, char **)); +char *Filename ANSI(()); +int Nestlevel ANSI(()); +FILE *TryFiles ANSI((LINKPTR)); +void Fatal ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Error ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Warning ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void No_ram ANSI(()); +void Usage ANSI((int)); +void Version ANSI(()); +char *Get_suffix ANSI((char *)); +char *Basename ANSI((char *)); +char *Filedir ANSI((char *)); +char *Build_path ANSI((char *, char *)); +void Make_rules ANSI(()); +void Create_macro_vars ANSI(()); +time_t Do_stat ANSI((char *, char *, char **, int)); +int Do_touch ANSI((char *, char *, char **)); +void Void_lib_cache ANSI((char *, char *)); +time_t Do_time ANSI(()); +int Do_cmnd ANSI((char *, int, int, CELLPTR, int, int, int)); +char ** Pack_argv ANSI((int, int, char *)); +char *Read_env_string ANSI((char *)); +int Write_env_string ANSI((char *, char *)); +void ReadEnvironment ANSI(()); +void Catch_signals ANSI((void (*)())); +void Clear_signals ANSI(()); +void Prolog ANSI((int, char* [])); +void Epilog ANSI((int)); +char *Get_current_dir ANSI(()); +int Set_dir ANSI((char*)); +char Get_switch_char ANSI(()); +FILE* Get_temp ANSI((char **, char *, int)); +FILE *Start_temp ANSI((char *, CELLPTR, char **)); +void Open_temp_error ANSI((char *, char *)); +void Link_temp ANSI((CELLPTR, FILE *, char *)); +void Close_temp ANSI((CELLPTR, FILE *)); +void Unlink_temp_files ANSI((CELLPTR)); +void Handle_result ANSI((int, int, int, CELLPTR)); +void Update_time_stamp ANSI((CELLPTR)); +int Remove_file ANSI((char *)); +void Parse ANSI((FILE *)); +int Get_line ANSI((char *, FILE *)); +char *Do_comment ANSI((char *, char **, int)); +char *Get_token ANSI((TKSTRPTR, char *, int)); +void Quit ANSI(()); +void Read_state ANSI(()); +void Write_state ANSI(()); +int Check_state ANSI((CELLPTR, STRINGPTR *, int)); +void Dump ANSI(()); +void Dump_recipe ANSI((STRINGPTR)); +int Parse_macro ANSI((char *, int)); +int Macro_op ANSI((char *)); +int Parse_rule_def ANSI((int *)); +int Rule_op ANSI((char *)); +void Add_recipe_to_list ANSI((char *, int, int)); +void Bind_rules_to_targets ANSI((int)); +int Set_group_attributes ANSI((char *)); +DFALINKPTR Match_dfa ANSI((char *)); +void Check_circle_dfa ANSI(()); +void Add_nfa ANSI((char *)); +char *Exec_function ANSI((char *)); +time_t seek_arch ANSI((char *, char *)); +int If_root_path ANSI((char *)); +void Remove_prq ANSI((CELLPTR)); +int runargv ANSI((CELLPTR, int, int, int, int, char *)); +int Wait_for_child ANSI((int, int)); +void Clean_up_processes ANSI(()); +time_t CacheStat ANSI((char *, int)); + +#endif diff --git a/dmake/unix/macosx/gnu/template.mk b/dmake/unix/macosx/gnu/template.mk new file mode 100644 index 000000000000..672878dfa095 --- /dev/null +++ b/dmake/unix/macosx/gnu/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= unix + OSRELEASE *:= macosx + OSENVIRONMENT *:= gnu diff --git a/dmake/unix/rmprq.c b/dmake/unix/rmprq.c new file mode 100644 index 000000000000..3b95f237b7b8 --- /dev/null +++ b/dmake/unix/rmprq.c @@ -0,0 +1,96 @@ +/* RCS $Id: rmprq.c,v 1.1.1.1 2000-09-22 15:33:33 hr Exp $ +-- +-- SYNOPSIS +-- Remove prerequisites code. +-- +-- DESCRIPTION +-- This code is different for DOS and for UNIX and parallel make +-- architectures since the parallel case requires the rm's to be +-- run in parallel, whereas DOS guarantees to run them sequentially. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include "extern.h" + +PUBLIC void +Remove_prq( tcp ) +CELLPTR tcp; +{ + static LINKPTR rlp = NIL(LINK); + static flag = 0; + static HASHPTR m_at, m_q, m_b, m_g, m_l, m_bb, m_up; + char *m_at_s, *m_g_s, *m_q_s, *m_b_s, *m_l_s, *m_bb_s, *m_up_s; + LINKPTR tlp; + + tcp->ce_flag &= ~(F_MADE|F_VISITED); + tcp->ce_time = 0L; + + for( tlp=rlp; tlp !=NIL(LINK); tlp=tlp->cl_next ) + if( (tlp->cl_prq->ce_flag & (F_VISITED|F_MADE)) != F_VISITED ) + break; + + if( tlp == NIL(LINK) ) { + TALLOC(tlp, 1, LINK); + TALLOC(tlp->cl_prq, 1, CELL); + tlp->cl_next = rlp; + rlp = tlp; + } + + *tlp->cl_prq = *tcp; + + /* We save the dynamic macro values here, as it is possible that the + * .REMOVE recipe is getting executed for a target while some other target + * is in the middle of executing it's list of recipe lines, in this case + * the values of $@ etc, must be preserved so that when we return to + * complete the other recipe we must make certain that the values of it's + * dynamic macros are unmodified. */ + + if( !flag ) { + /* Do the getting of the macros only once. */ + flag = 1; + m_at = Get_name("@", Macs, TRUE); + m_g = Get_name(">", Macs, TRUE); + m_q = Get_name("?", Macs, TRUE); + m_b = Get_name("<", Macs, TRUE); + m_l = Get_name("&", Macs, TRUE); + m_bb = Get_name("*", Macs, TRUE); + m_up = Get_name("^", Macs, TRUE); + } + + m_at_s = m_at->ht_value; m_at->ht_value = NIL(char); + m_g_s = m_g->ht_value; m_g->ht_value = NIL(char); + m_q_s = m_q->ht_value; m_q->ht_value = NIL(char); + m_b_s = m_b->ht_value; m_b->ht_value = NIL(char); + m_l_s = m_l->ht_value; m_l->ht_value = NIL(char); + m_bb_s = m_bb->ht_value; m_bb->ht_value = NIL(char); + m_up_s = m_up->ht_value; m_up->ht_value = NIL(char); + + Make( tlp->cl_prq, tcp ); + if( tlp->cl_prq->ce_dir ){ + FREE(tlp->cl_prq->ce_dir); + tlp->cl_prq->ce_dir=NIL(char); + } + + m_at->ht_value = m_at_s; + m_g->ht_value = m_g_s; + m_q->ht_value = m_q_s; + m_b->ht_value = m_b_s; + m_l->ht_value = m_l_s; + m_bb->ht_value = m_bb_s; + m_up->ht_value = m_up_s; +} diff --git a/dmake/unix/ruletab.c b/dmake/unix/ruletab.c new file mode 100644 index 000000000000..a7723ad0e8bb --- /dev/null +++ b/dmake/unix/ruletab.c @@ -0,0 +1,41 @@ +/* RCS $Id: ruletab.c,v 1.1.1.1 2000-09-22 15:33:33 hr Exp $ +-- +-- SYNOPSIS +-- Default initial configuration of dmake. +-- +-- DESCRIPTION +-- Define here the initial set of rules that are defined before +-- dmake performs any processing. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +/* These are control macros for dmake that MUST be defined at some point + * if they are NOT dmake will not work! These are default definitions. They + * may be overridden inside the .STARTUP makefile, they are here + * strictly so that dmake can parse the STARTUP makefile */ + +static char *_rules[] = { + "MAXPROCESSLIMIT := 10", + "MAXLINELENGTH := 8190", + ".IMPORT .IGNORE: DMAKEROOT SOLARVER UPD INPATH OS UPDMINOREXT", + ".MAKEFILES : makefile.mk Makefile makefile", + ".SOURCE : .NULL", +#include "startup.h" + 0 }; + +char **Rule_tab = _rules; /* for sundry reasons in Get_environment() */ diff --git a/dmake/unix/runargv.c b/dmake/unix/runargv.c new file mode 100644 index 000000000000..df795c2f6b6f --- /dev/null +++ b/dmake/unix/runargv.c @@ -0,0 +1,307 @@ +/* RCS $Id: runargv.c,v 1.1.1.1 2000-09-22 15:33:33 hr Exp $ +-- +-- SYNOPSIS +-- Invoke a sub process. +-- +-- DESCRIPTION +-- Use the standard methods of executing a sub process. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include <signal.h> +#include "extern.h" +#include "sysintf.h" + +typedef struct prp { + char *prp_cmd; + int prp_group; + int prp_ignore; + int prp_last; + int prp_shell; + struct prp *prp_next; +} RCP, *RCPPTR; + +typedef struct pr { + int pr_valid; + int pr_pid; + CELLPTR pr_target; + int pr_ignore; + int pr_last; + RCPPTR pr_recipe; + RCPPTR pr_recipe_end; + char *pr_dir; +} PR; + +static PR *_procs = NIL(PR); +static int _proc_cnt = 0; +static int _abort_flg= FALSE; +static int _use_i = -1; +static int _do_upd = 0; + +static void _add_child ANSI((int, CELLPTR, int, int)); +static void _attach_cmd ANSI((char *, int, int, CELLPTR, int, int)); +static void _finished_child ANSI((int, int)); +static int _running ANSI((CELLPTR)); + +PUBLIC int +runargv(target, ignore, group, last, shell, cmd) +CELLPTR target; +int ignore; +int group; +int last; +int shell; +char *cmd; +{ + extern int errno; +#ifndef __APPLE__ +#ifdef arm32 + extern const char * const sys_errlist[]; +#else +#ifdef linux + extern const char * const sys_errlist[]; +#else + extern char *sys_errlist[]; +#endif +#endif +#endif + int pid; + char **argv; + + if( _running(target) /*&& Max_proc != 1*/ ) { + /* The command will be executed when the previous recipe + * line completes. */ + _attach_cmd( cmd, group, ignore, target, last, shell ); + return(1); + } + + while( _proc_cnt == Max_proc ) + if( Wait_for_child(FALSE, -1) == -1 ) Fatal( "Lost a child %d", errno ); + + argv = Pack_argv( group, shell, cmd ); + + switch( pid=fork() ){ + int wid; + int status; + + case -1: /* fork failed */ + Error("%s: %s", argv[0], sys_errlist[errno]); + Handle_result(-1, ignore, _abort_flg, target); + return(-1); + + case 0: /* child */ + execvp(argv[0], argv); + Continue = TRUE; /* survive error message */ + Error("%s: %s", argv[0], sys_errlist[errno]); + kill(getpid(), SIGTERM); + /*NOTREACHED*/ + + default: /* parent */ + _add_child(pid, target, ignore, last); + } + + return(1); +} + + +PUBLIC int +Wait_for_child( abort_flg, pid ) +int abort_flg; +int pid; +{ + int wid; + int status; + int waitchild; + + waitchild = (pid == -1)? FALSE : Wait_for_completion; + + do { + if( (wid = wait(&status)) == -1 ) return(-1); + + _abort_flg = abort_flg; + _finished_child(wid, status); + _abort_flg = FALSE; + } + while( waitchild && pid != wid ); + + return(0); +} + + +PUBLIC void +Clean_up_processes() +{ + register int i; + + if( _procs != NIL(PR) ) { + for( i=0; i<Max_proc; i++ ) + if( _procs[i].pr_valid ) + kill(_procs[i].pr_pid, SIGTERM); + + while( Wait_for_child(TRUE, -1) != -1 ); + } +} + + +static void +_add_child( pid, target, ignore, last ) +int pid; +CELLPTR target; +int ignore; +int last; +{ + register int i; + register PR *pp; + + if( _procs == NIL(PR) ) { + TALLOC( _procs, Max_proc, PR ); + } + + if( (i = _use_i) == -1 ) + for( i=0; i<Max_proc; i++ ) + if( !_procs[i].pr_valid ) + break; + + pp = _procs+i; + + pp->pr_valid = 1; + pp->pr_pid = pid; + pp->pr_target = target; + pp->pr_ignore = ignore; + pp->pr_last = last; + pp->pr_dir = DmStrDup(Get_current_dir()); + + Current_target = NIL(CELL); + + _proc_cnt++; + + if( Wait_for_completion ) Wait_for_child( FALSE, pid ); +} + + +static void +_finished_child(pid, status) +int pid; +int status; +{ + register int i; + register PR *pp; + char *dir; + + for( i=0; i<Max_proc; i++ ) + if( _procs[i].pr_valid && _procs[i].pr_pid == pid ) + break; + + /* Some children we didn't make esp true if using /bin/sh to execute a + * a pipe and feed the output as a makefile into dmake. */ + if( i == Max_proc ) return; + _procs[i].pr_valid = 0; + _proc_cnt--; + dir = DmStrDup(Get_current_dir()); + Set_dir( _procs[i].pr_dir ); + + if( _procs[i].pr_recipe != NIL(RCP) && !_abort_flg ) { + RCPPTR rp = _procs[i].pr_recipe; + + + Current_target = _procs[i].pr_target; + Handle_result( status, _procs[i].pr_ignore, FALSE, _procs[i].pr_target ); + Current_target = NIL(CELL); + + if ( _procs[i].pr_target->ce_attr & A_ERROR ) { + Unlink_temp_files( _procs[i].pr_target ); + _procs[i].pr_last = TRUE; + goto ABORT_REMAINDER_OF_RECIPE; + } + + _procs[i].pr_recipe = rp->prp_next; + + _use_i = i; + runargv( _procs[i].pr_target, rp->prp_ignore, rp->prp_group, + rp->prp_last, rp->prp_shell, rp->prp_cmd ); + _use_i = -1; + + FREE( rp->prp_cmd ); + FREE( rp ); + + if( _proc_cnt == Max_proc ) Wait_for_child( FALSE, -1 ); + } + else { + Unlink_temp_files( _procs[i].pr_target ); + Handle_result(status,_procs[i].pr_ignore,_abort_flg,_procs[i].pr_target); + + ABORT_REMAINDER_OF_RECIPE: + if( _procs[i].pr_last ) { + FREE(_procs[i].pr_dir ); + + if( !Doing_bang ) Update_time_stamp( _procs[i].pr_target ); + } + } + + Set_dir(dir); + FREE(dir); +} + + +static int +_running( cp ) +CELLPTR cp; +{ + register int i; + + if( !_procs ) return(FALSE); + + for( i=0; i<Max_proc; i++ ) + if( _procs[i].pr_valid && + _procs[i].pr_target == cp ) + break; + + return( i != Max_proc ); +} + + +static void +_attach_cmd( cmd, group, ignore, cp, last, shell ) +char *cmd; +int group; +int ignore; +CELLPTR cp; +int last; +int shell; +{ + register int i; + RCPPTR rp; + + for( i=0; i<Max_proc; i++ ) + if( _procs[i].pr_valid && + _procs[i].pr_target == cp ) + break; + + TALLOC( rp, 1, RCP ); + rp->prp_cmd = DmStrDup(cmd); + rp->prp_group = group; + rp->prp_ignore= ignore; + rp->prp_last = last; + rp->prp_shell = shell; + + if( _procs[i].pr_recipe == NIL(RCP) ) + _procs[i].pr_recipe = _procs[i].pr_recipe_end = rp; + else { + _procs[i].pr_recipe_end->prp_next = rp; + _procs[i].pr_recipe_end = rp; + } +} diff --git a/dmake/unix/solaris/config.mk b/dmake/unix/solaris/config.mk new file mode 100644 index 000000000000..bc2364a33260 --- /dev/null +++ b/dmake/unix/solaris/config.mk @@ -0,0 +1,27 @@ +# This is the BSD 4.3 UNIX configuration file for DMAKE +# It simply modifies the values of SRC, and checks to see if +# OSENVIRONMENT is defined. If so it includes the appropriate +# config.mk file. +# +# It also sets the values of .SOURCE.c and .SOURCE.h to include the local +# directory. +# +osrdir := $(OS)$(DIRSEPSTR)$(OSRELEASE) + +# The following sources are required for Solaris 2.1 or greater +OSDSRC := tempnam.c getcwd.c +.IF $(OSDSRC) + SRC += $(OSDSRC) + .SETDIR=$(osrdir) : $(OSDSRC) +.END + +.SOURCE.h : $(osrdir) + +# Local configuration modifications for CFLAGS, there's local BSD includes +# too. +CFLAGS += -I$(osrdir) -DSolaris + +# See if we modify anything in the lower levels. +.IF $(OSENVIRONMENT) != $(NULL) + .INCLUDE .IGNORE : $(osrdir)$(DIRSEPSTR)$(OSENVIRONMENT)$(DIRSEPSTR)config.mk +.END diff --git a/dmake/unix/solaris/getcwd.c b/dmake/unix/solaris/getcwd.c new file mode 100644 index 000000000000..f2359bcc795b --- /dev/null +++ b/dmake/unix/solaris/getcwd.c @@ -0,0 +1,231 @@ +/* + getcwd -- get pathname of current working directory + + public-domain implementation + + last edit: 03-Nov-1990 Gwyn@BRL.MIL + + complies with the following standards: + IEEE Std 1003.1-1988 + SVID Issue 3 + X/Open Portability Guide Issue 2 (when "XPG2" is defined) + X/Open Portability Guide Issue 3 + + This implementation of getcwd() can be used to replace the UNIX + System V library routine (which uses popen() to capture the output of + the "pwd" command). Once that is done, "pwd" can be reimplemented as + just puts(getcwd((char*)0,0)), assuming "XPG2" is defined below. + + This implementation depends on every directory having entries for + "." and "..". It also depends on the internals of the <dirent.h> + data structures to some degree. + + I considered using chdir() to ascend the hierarchy, followed by a + final chdir() to the path being returned by getcwd() to restore the + location, but decided that error recovery was too difficult that way. + The algorithm I settled on was inspired by my rewrite of the "pwd" + utility, combined with the dotdots[] array trick from the SVR2 shell. +*/ +#define XPG2 /* define to support obsolete XPG2-mandated feature */ + + +#include <sys/types.h> +#include <sys/stat.h> + +#ifdef M_XENIX +# include <sys/ndir.h> +# define dirent direct +#else +# include <dirent.h> +#endif + +#include <errno.h> +#include <string.h> + +typedef char *pointer; /* (void *) if you have it */ + +extern void free(); +extern pointer malloc(); +extern int fstat(), stat(); + +extern int errno; /* normally done by <errno.h> */ + +#ifndef NULL +#define NULL 0 /* amorphous null pointer constant */ +#endif + +#ifndef NAME_MAX +#define NAME_MAX 255 /* maximum directory entry size */ +#endif + + +char * +getcwd( buf, size ) /* returns pointer to CWD pathname */ + char *buf; /* where to put name (NULL to malloc) */ + int size; /* size of buf[] or malloc()ed memory */ + { + static char dotdots[] = +"../../../../../../../../../../../../../../../../../../../../../../../../../.."; + char *dotdot; /* -> dotdots[.], right to left */ + DIR *dirp; /* -> parent directory stream */ + struct dirent *dir; /* -> directory entry */ + struct stat stat1, + stat2; /* info from stat() */ + struct stat *d = &stat1; /* -> info about "." */ + struct stat *dd = &stat2; /* -> info about ".." */ + register char *buffer; /* local copy of buf, or malloc()ed */ + char *bufend; /* -> buffer[size] */ + register char *endp; /* -> end of reversed string */ + register char *dname; /* entry name ("" for root) */ + int serrno = errno; /* save entry errno */ + + if ( buf != NULL && size <= 0 +#ifndef XPG2 + || buf == NULL +#endif + ) { + errno = EINVAL; /* invalid argument */ + return NULL; + } + + buffer = buf; +#ifdef XPG2 + if ( buf == NULL /* wants us to malloc() the string */ + && (buffer = (char *) malloc( (unsigned) size )) == NULL + /* XXX -- actually should probably not pay attention to "size" arg */ + ) { + errno = ENOMEM; /* cannot malloc() specified size */ + return NULL; + } +#endif + + if ( stat( ".", dd ) != 0 ) /* prime the pump */ + goto error; /* errno already set */ + + endp = buffer; /* initially, empty string */ + bufend = &buffer[size]; + + for ( dotdot = &dotdots[sizeof dotdots]; dotdot != dotdots; ) + { + dotdot -= 3; /* include one more "/.." section */ + /* (first time is actually "..") */ + + /* swap stat() info buffers */ + { + register struct stat *temp = d; + + d = dd; /* new current dir is old parent dir */ + dd = temp; + } + + if ( (dirp = opendir( dotdot )) == NULL ) /* new parent */ + goto error; /* errno already set */ + + if ( fstat( dirp->dd_fd, dd ) != 0 ) + { + serrno = errno; /* set by fstat() */ + (void)closedir( dirp ); + errno = serrno; /* in case closedir() clobbered it */ + goto error; + } + + if ( d->st_dev == dd->st_dev ) + { /* not crossing a mount point */ + if ( d->st_ino == dd->st_ino ) + { /* root directory */ + dname = ""; + goto append; + } + + do + if ( (dir = readdir( dirp )) == NULL ) + { + (void)closedir( dirp ); + errno = ENOENT; /* missing entry */ + goto error; + } + while ( dir->d_ino != d->st_ino ); + } + else { /* crossing a mount point */ + struct stat t; /* info re. test entry */ + char name[sizeof dotdots + 1 + NAME_MAX]; + + (void)strcpy( name, dotdot ); + dname = &name[strlen( name )]; + *dname++ = '/'; + + do { + if ( (dir = readdir( dirp )) == NULL ) + { + (void)closedir( dirp ); + errno = ENOENT; /* missing entry */ + goto error; + } + + (void)strcpy( dname, dir->d_name ); + /* must fit if NAME_MAX is not a lie */ + } + while ( stat( name, &t ) != 0 + || t.st_ino != d->st_ino + || t.st_dev != d->st_dev + ); + } + + dname = dir->d_name; + + /* append "/" and reversed dname string onto buffer */ + append: + if ( endp != buffer /* avoid trailing / in final name */ + || dname[0] == '\0' /* but allow "/" when CWD is root */ + ) + *endp++ = '/'; + + { + register char *app; /* traverses dname string */ + + for ( app = dname; *app != '\0'; ++app ) + ; + + if ( app - dname >= bufend - endp ) + { + (void)closedir( dirp ); + errno = ERANGE; /* won't fit allotted space */ + goto error; + } + + while ( app != dname ) + *endp++ = *--app; + } + + (void)closedir( dirp ); + + if ( dname[0] == '\0' ) /* reached root; wrap it up */ + { + register char *startp; /* -> buffer[.] */ + + *endp = '\0'; /* plant null terminator */ + + /* straighten out reversed pathname string */ + for ( startp = buffer; --endp > startp; ++startp ) + { + char temp = *endp; + + *endp = *startp; + *startp = temp; + } + + errno = serrno; /* restore entry errno */ + /* XXX -- if buf==NULL, realloc here? */ + return buffer; + } + } + + errno = ENOMEM; /* actually, algorithm failure */ + + error: + if ( buf == NULL ) + free( (pointer)buffer ); + + return NULL; + } + diff --git a/dmake/unix/solaris/gnu/config.mk b/dmake/unix/solaris/gnu/config.mk new file mode 100644 index 000000000000..f6f4f2c68cbc --- /dev/null +++ b/dmake/unix/solaris/gnu/config.mk @@ -0,0 +1,8 @@ +# This is the Solaris gcc configuration file for DMAKE +# It modifies the value of CC to be gcc +# + +CC = gcc + +# disable a gcc bug when compiling runargv.c +runargv.o ?= CFLAGS += -g diff --git a/dmake/unix/solaris/gnu/make.sh b/dmake/unix/solaris/gnu/make.sh new file mode 100644 index 000000000000..10a50a837dfa --- /dev/null +++ b/dmake/unix/solaris/gnu/make.sh @@ -0,0 +1,64 @@ +mkdir objects +gcc -c -I. -Iunix -Iunix/solaris -DSolaris -O infer.c +mv infer.o objects +gcc -c -I. -Iunix -Iunix/solaris -DSolaris -O make.c +mv make.o objects +gcc -c -I. -Iunix -Iunix/solaris -DSolaris -O stat.c +mv stat.o objects +gcc -c -I. -Iunix -Iunix/solaris -DSolaris -O expand.c +mv expand.o objects +gcc -c -I. -Iunix -Iunix/solaris -DSolaris -O dmstring.c +mv dmstring.o objects +gcc -c -I. -Iunix -Iunix/solaris -DSolaris -O hash.c +mv hash.o objects +gcc -c -I. -Iunix -Iunix/solaris -DSolaris -O dag.c +mv dag.o objects +gcc -c -I. -Iunix -Iunix/solaris -DSolaris -O dmake.c +mv dmake.o objects +gcc -c -I. -Iunix -Iunix/solaris -DSolaris -O path.c +mv path.o objects +gcc -c -I. -Iunix -Iunix/solaris -DSolaris -O imacs.c +mv imacs.o objects +gcc -c -I. -Iunix -Iunix/solaris -DSolaris -O sysintf.c +mv sysintf.o objects +gcc -c -I. -Iunix -Iunix/solaris -DSolaris -O parse.c +mv parse.o objects +gcc -c -I. -Iunix -Iunix/solaris -DSolaris -O getinp.c +mv getinp.o objects +gcc -c -I. -Iunix -Iunix/solaris -DSolaris -O quit.c +mv quit.o objects +gcc -c -I. -Iunix -Iunix/solaris -DSolaris -O state.c +mv state.o objects +gcc -c -I. -Iunix -Iunix/solaris -DSolaris -O dmdump.c +mv dmdump.o objects +gcc -c -I. -Iunix -Iunix/solaris -DSolaris -O macparse.c +mv macparse.o objects +gcc -c -I. -Iunix -Iunix/solaris -DSolaris -O rulparse.c +mv rulparse.o objects +gcc -c -I. -Iunix -Iunix/solaris -DSolaris -O percent.c +mv percent.o objects +gcc -c -I. -Iunix -Iunix/solaris -DSolaris -O function.c +mv function.o objects +gcc -c -I. -Iunix -Iunix/solaris -DSolaris -O unix/arlib.c +mv arlib.o objects +gcc -c -I. -Iunix -Iunix/solaris -DSolaris -O unix/dirbrk.c +mv dirbrk.o objects +gcc -c -I. -Iunix -Iunix/solaris -DSolaris -O unix/rmprq.c +mv rmprq.o objects +gcc -c -I. -Iunix -Iunix/solaris -DSolaris -O unix/ruletab.c +mv ruletab.o objects +gcc -c -I. -Iunix -Iunix/solaris -DSolaris -O -g unix/runargv.c +mv runargv.o objects +gcc -c -I. -Iunix -Iunix/solaris -DSolaris -O unix/dcache.c +mv dcache.o objects +gcc -c -I. -Iunix -Iunix/solaris -DSolaris -O unix/solaris/tempnam.c +mv tempnam.o objects +gcc -c -I. -Iunix -Iunix/solaris -DSolaris -O unix/solaris/getcwd.c +mv getcwd.o objects +gcc -O -o dmake objects/infer.o objects/make.o objects/stat.o objects/expand.o \ +objects/dmstring.o objects/hash.o objects/dag.o objects/dmake.o objects/path.o \ +objects/imacs.o objects/sysintf.o objects/parse.o objects/getinp.o \ +objects/quit.o objects/state.o objects/dmdump.o objects/macparse.o \ +objects/rulparse.o objects/percent.o objects/function.o objects/arlib.o \ +objects/dirbrk.o objects/rmprq.o objects/ruletab.o objects/runargv.o objects/dcache.o objects/tempnam.o objects/getcwd.o +cp unix/solaris/gnu/template.mk startup/config.mk diff --git a/dmake/unix/solaris/gnu/public.h b/dmake/unix/solaris/gnu/public.h new file mode 100644 index 000000000000..01e80862fbbd --- /dev/null +++ b/dmake/unix/solaris/gnu/public.h @@ -0,0 +1,164 @@ +/* RCS $Id: public.h,v 1.1.1.1 2000-09-22 15:33:35 hr Exp $ +-- WARNING -- This file is AUTOMATICALLY GENERATED DO NOT EDIT IT +-- +-- +-- SYNOPSIS +-- Local functions exported to be visible by others. +-- +-- DESCRIPTION +-- This file is generated by 'genpub'. Function declarations +-- that appear in this file are extracted by 'genpub' from +-- source files. Any function in the source file whose definition +-- appears like: +-- +-- PUBLIC return_type +-- function( arg_list ); +-- type_expr1 arg1; +-- ... +-- +-- has its definition extracted and a line of the form: +-- +-- return_type function ANSI((type_expr1,type_expr2,...)); +-- +-- entered into the output file. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef _DMAKE_PUBLIC_h +#define _DMAKE_PUBLIC_h + +#ifdef EXTERN +#undef EXTERN +#endif +#if defined(DEFINE_DMAKE_VARIABLES) +#define EXTERN +#else +#define EXTERN extern +#endif + +/***** genpub: Begin list of generated function headers */ +void Infer_recipe ANSI((CELLPTR, CELLPTR)); +int Make_targets ANSI(()); +int Make ANSI((CELLPTR, CELLPTR)); +int Exec_commands ANSI((CELLPTR)); +void Print_cmnd ANSI((char *, int, int)); +int Push_dir ANSI((char *, char *, int)); +void Pop_dir ANSI((int)); +void Append_line ANSI((char *, int, FILE *, char *, int, int)); +void Stat_target ANSI((CELLPTR, int, int)); +char *Expand ANSI((char *)); +char *Apply_edit ANSI((char *, char *, char *, int, int)); +void Map_esc ANSI((char *)); +char* Apply_modifiers ANSI((int, char *)); +char* Tokenize ANSI((char *, char *, char, int)); +char* ScanToken ANSI((char *, char **, int)); +char *DmStrJoin ANSI((char *, char *, int, int)); +char *DmStrAdd ANSI((char *, char *, int)); +char *DmStrApp ANSI((char *, char *)); +char *DmStrDup ANSI((char *)); +char *DmStrDup2 ANSI((char *)); +char *DmStrPbrk ANSI((char *, char *)); +char *DmStrSpn ANSI((char *, char *)); +char *DmStrStr ANSI((char *, char *)); +char *DmSubStr ANSI((char *, char *)); +uint16 Hash ANSI((char *, uint32 *)); +HASHPTR Get_name ANSI((char *, HASHPTR *, int)); +HASHPTR Search_table ANSI((HASHPTR *, char *, uint16 *, uint32 *)); +HASHPTR Push_macro ANSI((HASHPTR)); +HASHPTR Pop_macro ANSI((HASHPTR)); +HASHPTR Def_macro ANSI((char *, char *, int)); +CELLPTR Def_cell ANSI((char *)); +LINKPTR Add_prerequisite ANSI((CELLPTR, CELLPTR, int, int)); +void Clear_prerequisites ANSI((CELLPTR)); +int Test_circle ANSI((CELLPTR, int)); +STRINGPTR Def_recipe ANSI((char *, STRINGPTR, int, int)); +t_attr Rcp_attribute ANSI((char *)); +void main ANSI((int, char **)); +FILE *Openfile ANSI((char *, int, int)); +FILE *Closefile ANSI(()); +FILE *Search_file ANSI((char *, char **)); +char *Filename ANSI(()); +int Nestlevel ANSI(()); +FILE *TryFiles ANSI((LINKPTR)); +void Fatal ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Error ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Warning ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void No_ram ANSI(()); +void Usage ANSI((int)); +void Version ANSI(()); +char *Get_suffix ANSI((char *)); +char *Basename ANSI((char *)); +char *Filedir ANSI((char *)); +char *Build_path ANSI((char *, char *)); +void Make_rules ANSI(()); +void Create_macro_vars ANSI(()); +time_t Do_stat ANSI((char *, char *, char **, int)); +int Do_touch ANSI((char *, char *, char **)); +void Void_lib_cache ANSI((char *, char *)); +time_t Do_time ANSI(()); +int Do_cmnd ANSI((char *, int, int, CELLPTR, int, int, int)); +char ** Pack_argv ANSI((int, int, char *)); +char *Read_env_string ANSI((char *)); +int Write_env_string ANSI((char *, char *)); +void ReadEnvironment ANSI(()); +void Catch_signals ANSI((void (*)())); +void Clear_signals ANSI(()); +void Prolog ANSI((int, char* [])); +void Epilog ANSI((int)); +char *Get_current_dir ANSI(()); +int Set_dir ANSI((char*)); +char Get_switch_char ANSI(()); +FILE* Get_temp ANSI((char **, char *, int)); +FILE *Start_temp ANSI((char *, CELLPTR, char **)); +void Open_temp_error ANSI((char *, char *)); +void Link_temp ANSI((CELLPTR, FILE *, char *)); +void Close_temp ANSI((CELLPTR, FILE *)); +void Unlink_temp_files ANSI((CELLPTR)); +void Handle_result ANSI((int, int, int, CELLPTR)); +void Update_time_stamp ANSI((CELLPTR)); +int Remove_file ANSI((char *)); +void Parse ANSI((FILE *)); +int Get_line ANSI((char *, FILE *)); +char *Do_comment ANSI((char *, char **, int)); +char *Get_token ANSI((TKSTRPTR, char *, int)); +void Quit ANSI(()); +void Read_state ANSI(()); +void Write_state ANSI(()); +int Check_state ANSI((CELLPTR, STRINGPTR *, int)); +void Dump ANSI(()); +void Dump_recipe ANSI((STRINGPTR)); +int Parse_macro ANSI((char *, int)); +int Macro_op ANSI((char *)); +int Parse_rule_def ANSI((int *)); +int Rule_op ANSI((char *)); +void Add_recipe_to_list ANSI((char *, int, int)); +void Bind_rules_to_targets ANSI((int)); +int Set_group_attributes ANSI((char *)); +DFALINKPTR Match_dfa ANSI((char *)); +void Check_circle_dfa ANSI(()); +void Add_nfa ANSI((char *)); +char *Exec_function ANSI((char *)); +time_t seek_arch ANSI((char *, char *)); +int If_root_path ANSI((char *)); +void Remove_prq ANSI((CELLPTR)); +int runargv ANSI((CELLPTR, int, int, int, int, char *)); +int Wait_for_child ANSI((int, int)); +void Clean_up_processes ANSI(()); +time_t CacheStat ANSI((char *, int)); + +#endif diff --git a/dmake/unix/solaris/gnu/template.mk b/dmake/unix/solaris/gnu/template.mk new file mode 100644 index 000000000000..3f9282027c5c --- /dev/null +++ b/dmake/unix/solaris/gnu/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= unix + OSRELEASE *:= solaris + OSENVIRONMENT *:= gnu diff --git a/dmake/unix/solaris/make.sh b/dmake/unix/solaris/make.sh new file mode 100644 index 000000000000..21894778a642 --- /dev/null +++ b/dmake/unix/solaris/make.sh @@ -0,0 +1,64 @@ +mkdir objects +cc -c -I. -Iunix -Iunix/solaris -DSolaris -O infer.c +mv infer.o objects +cc -c -I. -Iunix -Iunix/solaris -DSolaris -O make.c +mv make.o objects +cc -c -I. -Iunix -Iunix/solaris -DSolaris -O stat.c +mv stat.o objects +cc -c -I. -Iunix -Iunix/solaris -DSolaris -O expand.c +mv expand.o objects +cc -c -I. -Iunix -Iunix/solaris -DSolaris -O dmstring.c +mv dmstring.o objects +cc -c -I. -Iunix -Iunix/solaris -DSolaris -O hash.c +mv hash.o objects +cc -c -I. -Iunix -Iunix/solaris -DSolaris -O dag.c +mv dag.o objects +cc -c -I. -Iunix -Iunix/solaris -DSolaris -O dmake.c +mv dmake.o objects +cc -c -I. -Iunix -Iunix/solaris -DSolaris -O path.c +mv path.o objects +cc -c -I. -Iunix -Iunix/solaris -DSolaris -O imacs.c +mv imacs.o objects +cc -c -I. -Iunix -Iunix/solaris -DSolaris -O sysintf.c +mv sysintf.o objects +cc -c -I. -Iunix -Iunix/solaris -DSolaris -O parse.c +mv parse.o objects +cc -c -I. -Iunix -Iunix/solaris -DSolaris -O getinp.c +mv getinp.o objects +cc -c -I. -Iunix -Iunix/solaris -DSolaris -O quit.c +mv quit.o objects +cc -c -I. -Iunix -Iunix/solaris -DSolaris -O state.c +mv state.o objects +cc -c -I. -Iunix -Iunix/solaris -DSolaris -O dmdump.c +mv dmdump.o objects +cc -c -I. -Iunix -Iunix/solaris -DSolaris -O macparse.c +mv macparse.o objects +cc -c -I. -Iunix -Iunix/solaris -DSolaris -O rulparse.c +mv rulparse.o objects +cc -c -I. -Iunix -Iunix/solaris -DSolaris -O percent.c +mv percent.o objects +cc -c -I. -Iunix -Iunix/solaris -DSolaris -O function.c +mv function.o objects +cc -c -I. -Iunix -Iunix/solaris -DSolaris -O unix/arlib.c +mv arlib.o objects +cc -c -I. -Iunix -Iunix/solaris -DSolaris -O unix/dirbrk.c +mv dirbrk.o objects +cc -c -I. -Iunix -Iunix/solaris -DSolaris -O unix/rmprq.c +mv rmprq.o objects +cc -c -I. -Iunix -Iunix/solaris -DSolaris -O unix/ruletab.c +mv ruletab.o objects +cc -c -I. -Iunix -Iunix/solaris -DSolaris -O unix/runargv.c +mv runargv.o objects +cc -c -I. -Iunix -Iunix/solaris -DSolaris -O unix/dcache.c +mv dcache.o objects +cc -c -I. -Iunix -Iunix/solaris -DSolaris -O unix/solaris/tempnam.c +mv tempnam.o objects +cc -c -I. -Iunix -Iunix/solaris -DSolaris -O unix/solaris/getcwd.c +mv getcwd.o objects +cc -O -o dmake objects/infer.o objects/make.o objects/stat.o objects/expand.o \ +objects/dmstring.o objects/hash.o objects/dag.o objects/dmake.o objects/path.o \ +objects/imacs.o objects/sysintf.o objects/parse.o objects/getinp.o \ +objects/quit.o objects/state.o objects/dmdump.o objects/macparse.o \ +objects/rulparse.o objects/percent.o objects/function.o objects/arlib.o \ +objects/dirbrk.o objects/rmprq.o objects/ruletab.o objects/runargv.o objects/dcache.o objects/tempnam.o objects/getcwd.o +cp unix/solaris/template.mk startup/config.mk diff --git a/dmake/unix/solaris/public.h b/dmake/unix/solaris/public.h new file mode 100644 index 000000000000..01e80862fbbd --- /dev/null +++ b/dmake/unix/solaris/public.h @@ -0,0 +1,164 @@ +/* RCS $Id: public.h,v 1.1.1.1 2000-09-22 15:33:35 hr Exp $ +-- WARNING -- This file is AUTOMATICALLY GENERATED DO NOT EDIT IT +-- +-- +-- SYNOPSIS +-- Local functions exported to be visible by others. +-- +-- DESCRIPTION +-- This file is generated by 'genpub'. Function declarations +-- that appear in this file are extracted by 'genpub' from +-- source files. Any function in the source file whose definition +-- appears like: +-- +-- PUBLIC return_type +-- function( arg_list ); +-- type_expr1 arg1; +-- ... +-- +-- has its definition extracted and a line of the form: +-- +-- return_type function ANSI((type_expr1,type_expr2,...)); +-- +-- entered into the output file. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef _DMAKE_PUBLIC_h +#define _DMAKE_PUBLIC_h + +#ifdef EXTERN +#undef EXTERN +#endif +#if defined(DEFINE_DMAKE_VARIABLES) +#define EXTERN +#else +#define EXTERN extern +#endif + +/***** genpub: Begin list of generated function headers */ +void Infer_recipe ANSI((CELLPTR, CELLPTR)); +int Make_targets ANSI(()); +int Make ANSI((CELLPTR, CELLPTR)); +int Exec_commands ANSI((CELLPTR)); +void Print_cmnd ANSI((char *, int, int)); +int Push_dir ANSI((char *, char *, int)); +void Pop_dir ANSI((int)); +void Append_line ANSI((char *, int, FILE *, char *, int, int)); +void Stat_target ANSI((CELLPTR, int, int)); +char *Expand ANSI((char *)); +char *Apply_edit ANSI((char *, char *, char *, int, int)); +void Map_esc ANSI((char *)); +char* Apply_modifiers ANSI((int, char *)); +char* Tokenize ANSI((char *, char *, char, int)); +char* ScanToken ANSI((char *, char **, int)); +char *DmStrJoin ANSI((char *, char *, int, int)); +char *DmStrAdd ANSI((char *, char *, int)); +char *DmStrApp ANSI((char *, char *)); +char *DmStrDup ANSI((char *)); +char *DmStrDup2 ANSI((char *)); +char *DmStrPbrk ANSI((char *, char *)); +char *DmStrSpn ANSI((char *, char *)); +char *DmStrStr ANSI((char *, char *)); +char *DmSubStr ANSI((char *, char *)); +uint16 Hash ANSI((char *, uint32 *)); +HASHPTR Get_name ANSI((char *, HASHPTR *, int)); +HASHPTR Search_table ANSI((HASHPTR *, char *, uint16 *, uint32 *)); +HASHPTR Push_macro ANSI((HASHPTR)); +HASHPTR Pop_macro ANSI((HASHPTR)); +HASHPTR Def_macro ANSI((char *, char *, int)); +CELLPTR Def_cell ANSI((char *)); +LINKPTR Add_prerequisite ANSI((CELLPTR, CELLPTR, int, int)); +void Clear_prerequisites ANSI((CELLPTR)); +int Test_circle ANSI((CELLPTR, int)); +STRINGPTR Def_recipe ANSI((char *, STRINGPTR, int, int)); +t_attr Rcp_attribute ANSI((char *)); +void main ANSI((int, char **)); +FILE *Openfile ANSI((char *, int, int)); +FILE *Closefile ANSI(()); +FILE *Search_file ANSI((char *, char **)); +char *Filename ANSI(()); +int Nestlevel ANSI(()); +FILE *TryFiles ANSI((LINKPTR)); +void Fatal ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Error ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Warning ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void No_ram ANSI(()); +void Usage ANSI((int)); +void Version ANSI(()); +char *Get_suffix ANSI((char *)); +char *Basename ANSI((char *)); +char *Filedir ANSI((char *)); +char *Build_path ANSI((char *, char *)); +void Make_rules ANSI(()); +void Create_macro_vars ANSI(()); +time_t Do_stat ANSI((char *, char *, char **, int)); +int Do_touch ANSI((char *, char *, char **)); +void Void_lib_cache ANSI((char *, char *)); +time_t Do_time ANSI(()); +int Do_cmnd ANSI((char *, int, int, CELLPTR, int, int, int)); +char ** Pack_argv ANSI((int, int, char *)); +char *Read_env_string ANSI((char *)); +int Write_env_string ANSI((char *, char *)); +void ReadEnvironment ANSI(()); +void Catch_signals ANSI((void (*)())); +void Clear_signals ANSI(()); +void Prolog ANSI((int, char* [])); +void Epilog ANSI((int)); +char *Get_current_dir ANSI(()); +int Set_dir ANSI((char*)); +char Get_switch_char ANSI(()); +FILE* Get_temp ANSI((char **, char *, int)); +FILE *Start_temp ANSI((char *, CELLPTR, char **)); +void Open_temp_error ANSI((char *, char *)); +void Link_temp ANSI((CELLPTR, FILE *, char *)); +void Close_temp ANSI((CELLPTR, FILE *)); +void Unlink_temp_files ANSI((CELLPTR)); +void Handle_result ANSI((int, int, int, CELLPTR)); +void Update_time_stamp ANSI((CELLPTR)); +int Remove_file ANSI((char *)); +void Parse ANSI((FILE *)); +int Get_line ANSI((char *, FILE *)); +char *Do_comment ANSI((char *, char **, int)); +char *Get_token ANSI((TKSTRPTR, char *, int)); +void Quit ANSI(()); +void Read_state ANSI(()); +void Write_state ANSI(()); +int Check_state ANSI((CELLPTR, STRINGPTR *, int)); +void Dump ANSI(()); +void Dump_recipe ANSI((STRINGPTR)); +int Parse_macro ANSI((char *, int)); +int Macro_op ANSI((char *)); +int Parse_rule_def ANSI((int *)); +int Rule_op ANSI((char *)); +void Add_recipe_to_list ANSI((char *, int, int)); +void Bind_rules_to_targets ANSI((int)); +int Set_group_attributes ANSI((char *)); +DFALINKPTR Match_dfa ANSI((char *)); +void Check_circle_dfa ANSI(()); +void Add_nfa ANSI((char *)); +char *Exec_function ANSI((char *)); +time_t seek_arch ANSI((char *, char *)); +int If_root_path ANSI((char *)); +void Remove_prq ANSI((CELLPTR)); +int runargv ANSI((CELLPTR, int, int, int, int, char *)); +int Wait_for_child ANSI((int, int)); +void Clean_up_processes ANSI(()); +time_t CacheStat ANSI((char *, int)); + +#endif diff --git a/dmake/unix/solaris/template.mk b/dmake/unix/solaris/template.mk new file mode 100644 index 000000000000..233917a6ba92 --- /dev/null +++ b/dmake/unix/solaris/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= unix + OSRELEASE *:= solaris + OSENVIRONMENT *:= diff --git a/dmake/unix/solaris/tempnam.c b/dmake/unix/solaris/tempnam.c new file mode 100644 index 000000000000..56f23fbe21d4 --- /dev/null +++ b/dmake/unix/solaris/tempnam.c @@ -0,0 +1,103 @@ +/* RCS $Id: tempnam.c,v 1.1.1.1 2000-09-22 15:33:35 hr Exp $ +-- +-- SYNOPSIS +-- tempnam +-- +-- DESCRIPTION +-- temp file name generation routines. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +/*LINTLIBRARY*/ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +#define max(A,B) (((A)<(B))?(B):(A)) + +extern char *mktemp(); +extern int access(); + +static char *cpdir(); +static char seed[4]="AAA"; + +/* BSD stdio.h doesn't define P_tmpdir, so let's do it here */ +#ifndef P_tmpdir +static char *P_tmpdir = "/tmp"; +#endif + +char * +tempnam(dir, prefix) +const char *dir; /* use this directory please (if non-NULL) */ +const char *prefix; /* use this (if non-NULL) as filename prefix */ +{ + register char *p, *q, *tmpdir; + int tl=0, dl=0, pl; + + pl = strlen(P_tmpdir); + + if( (tmpdir = getenv("TMPDIR")) != NULL ) tl = strlen(tmpdir); + if( dir != NULL ) dl = strlen(dir); + + if( (p = malloc((unsigned)(max(max(dl,tl),pl)+16))) == NULL ) + return(NULL); + + *p = '\0'; + + if( (tl == 0) || (access( cpdir(p, tmpdir), 3) != 0) ) + if( (dl == 0) || (access( cpdir(p, dir), 3) != 0) ) + if( access( cpdir(p, P_tmpdir), 3) != 0 ) + if( access( cpdir(p, "/tmp"), 3) != 0 ) + return(NULL); + + (void) strcat(p, "/"); + if(prefix) + { + *(p+strlen(p)+5) = '\0'; + (void)strncat(p, prefix, 5); + } + + (void)strcat(p, seed); + (void)strcat(p, "XXXXXX"); + + q = seed; + while(*q == 'Z') *q++ = 'A'; + ++*q; + + if(*mktemp(p) == '\0') return(NULL); + return(p); +} + + + +static char * +cpdir(buf, str) +char *buf; +char *str; +{ + char *p; + + if(str != NULL) + { + (void) strcpy(buf, str); + p = buf - 1 + strlen(buf); + if(*p == '/') *p = '\0'; + } + + return(buf); +} diff --git a/dmake/unix/startup.h b/dmake/unix/startup.h new file mode 100644 index 000000000000..b445a86cecef --- /dev/null +++ b/dmake/unix/startup.h @@ -0,0 +1,27 @@ +/* RCS $Id: startup.h,v 1.1.1.1 2000-09-22 15:33:33 hr Exp $ +-- +-- SYNOPSIS +-- Definition of MAKESTARTUP +-- +-- DESCRIPTION +-- Default MAKESTARTUP value defining where dmake locates the +-- startup file. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +"MAKESTARTUP := $(DMAKEROOT)/startup.mk", diff --git a/dmake/unix/sysintf.h b/dmake/unix/sysintf.h new file mode 100644 index 000000000000..36bf60c559ee --- /dev/null +++ b/dmake/unix/sysintf.h @@ -0,0 +1,51 @@ +/* RCS $Id: sysintf.h,v 1.1.1.1 2000-09-22 15:33:33 hr Exp $ +-- +-- SYNOPSIS +-- Interfaces for sysintf.c +-- +-- DESCRIPTION +-- Abstractions of functions in sysintf.c +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#define DMSTAT stat +#define VOID_LCACHE(l,m) (void) void_lcache(l,m) +#define Hook_std_writes(A) +#define GETPID getpid() +#define DMSTRLWR(A,B) + +#ifndef S_IFDIR +#define S_IFDIR 0040000 +#endif + +#ifndef S_IFMT +#define S_IFMT 0170000 +#endif + +/* +** standard C items +*/ + +/* +** DOS interface standard items +*/ +#define getswitchar() '-' + +/* +** Make parameters +*/ diff --git a/dmake/unix/sysvr1/config.mk b/dmake/unix/sysvr1/config.mk new file mode 100644 index 000000000000..d1cd2d8810f5 --- /dev/null +++ b/dmake/unix/sysvr1/config.mk @@ -0,0 +1,28 @@ +# This is the SysV R3 UNIX configuration file for DMAKE +# It simply modifies the values of SRC, and checks to see if +# OSENVIRONMENT is defined. If so it includes the appropriate +# config.mk file. +# +# It also sets the values of .SOURCE.c and .SOURCE.h to include the local +# directory. +# +osrdir := $(OS)$(DIRSEPSTR)$(OSRELEASE) + +# The following are required sources +OSDSRC := vfprintf.c + +.IF $(OSDSRC) + SRC += $(OSDSRC) + .SETDIR=$(osrdir) : $(OSDSRC) +.END + +.SOURCE.h : $(osrdir) + +# Local configuration modifications for CFLAGS, there's local SysV includes +# too. +CFLAGS += -I$(osrdir) + +# See if we modify anything in the lower levels. +.IF $(OSENVIRONMENT) != $(NULL) + .INCLUDE .IGNORE : $(osrdir)$(DIRSEPSTR)$(OSENVIRONMENT)$(DIRSEPSTR)config.mk +.END diff --git a/dmake/unix/sysvr1/make.sh b/dmake/unix/sysvr1/make.sh new file mode 100644 index 000000000000..1db251f3361e --- /dev/null +++ b/dmake/unix/sysvr1/make.sh @@ -0,0 +1,62 @@ +mkdir objects +cc -c -I. -Iunix -Iunix/sysvr1 -O infer.c +mv infer.o objects +cc -c -I. -Iunix -Iunix/sysvr1 -O make.c +mv make.o objects +cc -c -I. -Iunix -Iunix/sysvr1 -O stat.c +mv stat.o objects +cc -c -I. -Iunix -Iunix/sysvr1 -O expand.c +mv expand.o objects +cc -c -I. -Iunix -Iunix/sysvr1 -O dmstring.c +mv dmstring.o objects +cc -c -I. -Iunix -Iunix/sysvr1 -O hash.c +mv hash.o objects +cc -c -I. -Iunix -Iunix/sysvr1 -O dag.c +mv dag.o objects +cc -c -I. -Iunix -Iunix/sysvr1 -O dmake.c +mv dmake.o objects +cc -c -I. -Iunix -Iunix/sysvr1 -O path.c +mv path.o objects +cc -c -I. -Iunix -Iunix/sysvr1 -O imacs.c +mv imacs.o objects +cc -c -I. -Iunix -Iunix/sysvr1 -O sysintf.c +mv sysintf.o objects +cc -c -I. -Iunix -Iunix/sysvr1 -O parse.c +mv parse.o objects +cc -c -I. -Iunix -Iunix/sysvr1 -O getinp.c +mv getinp.o objects +cc -c -I. -Iunix -Iunix/sysvr1 -O quit.c +mv quit.o objects +cc -c -I. -Iunix -Iunix/sysvr1 -O state.c +mv state.o objects +cc -c -I. -Iunix -Iunix/sysvr1 -O dmdump.c +mv dmdump.o objects +cc -c -I. -Iunix -Iunix/sysvr1 -O macparse.c +mv macparse.o objects +cc -c -I. -Iunix -Iunix/sysvr1 -O rulparse.c +mv rulparse.o objects +cc -c -I. -Iunix -Iunix/sysvr1 -O percent.c +mv percent.o objects +cc -c -I. -Iunix -Iunix/sysvr1 -O function.c +mv function.o objects +cc -c -I. -Iunix -Iunix/sysvr1 -O unix/arlib.c +mv arlib.o objects +cc -c -I. -Iunix -Iunix/sysvr1 -O unix/dirbrk.c +mv dirbrk.o objects +cc -c -I. -Iunix -Iunix/sysvr1 -O unix/rmprq.c +mv rmprq.o objects +cc -c -I. -Iunix -Iunix/sysvr1 -O unix/ruletab.c +mv ruletab.o objects +cc -c -I. -Iunix -Iunix/sysvr1 -O unix/runargv.c +mv runargv.o objects +cc -c -I. -Iunix -Iunix/sysvr1 -O unix/dcache.c +mv dcache.o objects +cc -c -I. -Iunix -Iunix/sysvr1 -O unix/sysvr1/vfprintf.c +mv vfprintf.o objects +cc -O -o dmake objects/infer.o objects/make.o objects/stat.o objects/expand.o \ +objects/dmstring.o objects/hash.o objects/dag.o objects/dmake.o objects/path.o \ +objects/imacs.o objects/sysintf.o objects/parse.o objects/getinp.o \ +objects/quit.o objects/state.o objects/dmdump.o objects/macparse.o \ +objects/rulparse.o objects/percent.o objects/function.o objects/arlib.o \ +objects/dirbrk.o objects/rmprq.o objects/ruletab.o objects/runargv.o objects/dcache.o objects/vfprintf.o +cp unix/sysvr1/template.mk startup/config.mk diff --git a/dmake/unix/sysvr1/public.h b/dmake/unix/sysvr1/public.h new file mode 100644 index 000000000000..01e80862fbbd --- /dev/null +++ b/dmake/unix/sysvr1/public.h @@ -0,0 +1,164 @@ +/* RCS $Id: public.h,v 1.1.1.1 2000-09-22 15:33:35 hr Exp $ +-- WARNING -- This file is AUTOMATICALLY GENERATED DO NOT EDIT IT +-- +-- +-- SYNOPSIS +-- Local functions exported to be visible by others. +-- +-- DESCRIPTION +-- This file is generated by 'genpub'. Function declarations +-- that appear in this file are extracted by 'genpub' from +-- source files. Any function in the source file whose definition +-- appears like: +-- +-- PUBLIC return_type +-- function( arg_list ); +-- type_expr1 arg1; +-- ... +-- +-- has its definition extracted and a line of the form: +-- +-- return_type function ANSI((type_expr1,type_expr2,...)); +-- +-- entered into the output file. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef _DMAKE_PUBLIC_h +#define _DMAKE_PUBLIC_h + +#ifdef EXTERN +#undef EXTERN +#endif +#if defined(DEFINE_DMAKE_VARIABLES) +#define EXTERN +#else +#define EXTERN extern +#endif + +/***** genpub: Begin list of generated function headers */ +void Infer_recipe ANSI((CELLPTR, CELLPTR)); +int Make_targets ANSI(()); +int Make ANSI((CELLPTR, CELLPTR)); +int Exec_commands ANSI((CELLPTR)); +void Print_cmnd ANSI((char *, int, int)); +int Push_dir ANSI((char *, char *, int)); +void Pop_dir ANSI((int)); +void Append_line ANSI((char *, int, FILE *, char *, int, int)); +void Stat_target ANSI((CELLPTR, int, int)); +char *Expand ANSI((char *)); +char *Apply_edit ANSI((char *, char *, char *, int, int)); +void Map_esc ANSI((char *)); +char* Apply_modifiers ANSI((int, char *)); +char* Tokenize ANSI((char *, char *, char, int)); +char* ScanToken ANSI((char *, char **, int)); +char *DmStrJoin ANSI((char *, char *, int, int)); +char *DmStrAdd ANSI((char *, char *, int)); +char *DmStrApp ANSI((char *, char *)); +char *DmStrDup ANSI((char *)); +char *DmStrDup2 ANSI((char *)); +char *DmStrPbrk ANSI((char *, char *)); +char *DmStrSpn ANSI((char *, char *)); +char *DmStrStr ANSI((char *, char *)); +char *DmSubStr ANSI((char *, char *)); +uint16 Hash ANSI((char *, uint32 *)); +HASHPTR Get_name ANSI((char *, HASHPTR *, int)); +HASHPTR Search_table ANSI((HASHPTR *, char *, uint16 *, uint32 *)); +HASHPTR Push_macro ANSI((HASHPTR)); +HASHPTR Pop_macro ANSI((HASHPTR)); +HASHPTR Def_macro ANSI((char *, char *, int)); +CELLPTR Def_cell ANSI((char *)); +LINKPTR Add_prerequisite ANSI((CELLPTR, CELLPTR, int, int)); +void Clear_prerequisites ANSI((CELLPTR)); +int Test_circle ANSI((CELLPTR, int)); +STRINGPTR Def_recipe ANSI((char *, STRINGPTR, int, int)); +t_attr Rcp_attribute ANSI((char *)); +void main ANSI((int, char **)); +FILE *Openfile ANSI((char *, int, int)); +FILE *Closefile ANSI(()); +FILE *Search_file ANSI((char *, char **)); +char *Filename ANSI(()); +int Nestlevel ANSI(()); +FILE *TryFiles ANSI((LINKPTR)); +void Fatal ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Error ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Warning ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void No_ram ANSI(()); +void Usage ANSI((int)); +void Version ANSI(()); +char *Get_suffix ANSI((char *)); +char *Basename ANSI((char *)); +char *Filedir ANSI((char *)); +char *Build_path ANSI((char *, char *)); +void Make_rules ANSI(()); +void Create_macro_vars ANSI(()); +time_t Do_stat ANSI((char *, char *, char **, int)); +int Do_touch ANSI((char *, char *, char **)); +void Void_lib_cache ANSI((char *, char *)); +time_t Do_time ANSI(()); +int Do_cmnd ANSI((char *, int, int, CELLPTR, int, int, int)); +char ** Pack_argv ANSI((int, int, char *)); +char *Read_env_string ANSI((char *)); +int Write_env_string ANSI((char *, char *)); +void ReadEnvironment ANSI(()); +void Catch_signals ANSI((void (*)())); +void Clear_signals ANSI(()); +void Prolog ANSI((int, char* [])); +void Epilog ANSI((int)); +char *Get_current_dir ANSI(()); +int Set_dir ANSI((char*)); +char Get_switch_char ANSI(()); +FILE* Get_temp ANSI((char **, char *, int)); +FILE *Start_temp ANSI((char *, CELLPTR, char **)); +void Open_temp_error ANSI((char *, char *)); +void Link_temp ANSI((CELLPTR, FILE *, char *)); +void Close_temp ANSI((CELLPTR, FILE *)); +void Unlink_temp_files ANSI((CELLPTR)); +void Handle_result ANSI((int, int, int, CELLPTR)); +void Update_time_stamp ANSI((CELLPTR)); +int Remove_file ANSI((char *)); +void Parse ANSI((FILE *)); +int Get_line ANSI((char *, FILE *)); +char *Do_comment ANSI((char *, char **, int)); +char *Get_token ANSI((TKSTRPTR, char *, int)); +void Quit ANSI(()); +void Read_state ANSI(()); +void Write_state ANSI(()); +int Check_state ANSI((CELLPTR, STRINGPTR *, int)); +void Dump ANSI(()); +void Dump_recipe ANSI((STRINGPTR)); +int Parse_macro ANSI((char *, int)); +int Macro_op ANSI((char *)); +int Parse_rule_def ANSI((int *)); +int Rule_op ANSI((char *)); +void Add_recipe_to_list ANSI((char *, int, int)); +void Bind_rules_to_targets ANSI((int)); +int Set_group_attributes ANSI((char *)); +DFALINKPTR Match_dfa ANSI((char *)); +void Check_circle_dfa ANSI(()); +void Add_nfa ANSI((char *)); +char *Exec_function ANSI((char *)); +time_t seek_arch ANSI((char *, char *)); +int If_root_path ANSI((char *)); +void Remove_prq ANSI((CELLPTR)); +int runargv ANSI((CELLPTR, int, int, int, int, char *)); +int Wait_for_child ANSI((int, int)); +void Clean_up_processes ANSI(()); +time_t CacheStat ANSI((char *, int)); + +#endif diff --git a/dmake/unix/sysvr1/putenv.c b/dmake/unix/sysvr1/putenv.c new file mode 100644 index 000000000000..1453852710c2 --- /dev/null +++ b/dmake/unix/sysvr1/putenv.c @@ -0,0 +1,78 @@ +/* RCS $Id: putenv.c,v 1.1.1.1 2000-09-22 15:33:35 hr Exp $ +-- +-- SYNOPSIS +-- My own putenv for BSD like systems. +-- +-- DESCRIPTION +-- This originally came from MKS, but I rewrote it to fix a bug with +-- replacing existing strings, probably never happened but the code +-- was wrong nonetheless. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include <stdio.h> +#include <string.h> + +int +putenv( str )/* +=============== + Take a string of the form NAME=value and stick it into the environment. + We do this by allocating a new set of pointers if we have to add a new + string and by replacing an existing pointer if the value replaces the value + of an existing string. */ +char *str; +{ + extern char **environ; /* The current environment. */ + static char **ourenv = NULL; /* A new environment */ + register char **p; + register char *q; + int size; + + /* First search the current environment and see if we can replace a + * string. */ + for( p=environ; *p; p++ ) { + register char *s = str; + + for( q = *p; *q && *s && *s == *q; q++, s++ ) + if( *s == '=' ) { + *p = str; + return(0); /* replaced it so go away */ + } + } + + /* Ok, can't replace a string so need to grow the environment. */ + size = p - environ + 2; /* size of new environment */ + /* size of old is size-1 */ + + /* It's the first time, so allocate a new environment since we don't know + * where the old one is comming from. */ + if( ourenv == NULL ) { + if( (ourenv = (char **) malloc( sizeof(char *)*size )) == NULL ) + return(1); + + memcpy( (char *)ourenv, (char *)environ, (size-2)*sizeof(char *) ); + } + else if( (ourenv = (char **)realloc( ourenv, size*sizeof(char *))) == NULL ) + return(1); + + ourenv[--size] = NULL; + ourenv[--size] = str; + + environ = ourenv; + return(0); +} diff --git a/dmake/unix/sysvr1/stdlib.h b/dmake/unix/sysvr1/stdlib.h new file mode 100644 index 000000000000..3b612c2fd601 --- /dev/null +++ b/dmake/unix/sysvr1/stdlib.h @@ -0,0 +1,44 @@ +/* RCS $Id: stdlib.h,v 1.1.1.1 2000-09-22 15:33:35 hr Exp $ +-- +-- SYNOPSIS +-- stdlib interface +-- +-- DESCRIPTION +-- Specially needed pieces of interface to the standard C lib. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef _STDLIB_INCLUDED_ +#define _STDLIB_INCLUDED_ + +extern /*GOTO*/ _exit(); +extern /*GOTO*/ exit(); +extern /*GOTO*/ abort(); +extern int system(); +extern char *getenv(); +extern char *calloc(); +extern char *malloc(); +extern char *realloc(); +extern free(); +extern int errno; + +#ifndef EIO +# include <errno.h> +#endif + +#endif /* _STDLIB_INCLUDED_ */ diff --git a/dmake/unix/sysvr1/template.mk b/dmake/unix/sysvr1/template.mk new file mode 100644 index 000000000000..4eb40febb3a1 --- /dev/null +++ b/dmake/unix/sysvr1/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= unix + OSRELEASE *:= sysvr1 + OSENVIRONMENT *:= diff --git a/dmake/unix/sysvr1/time.h b/dmake/unix/sysvr1/time.h new file mode 100644 index 000000000000..3b3dfac5684f --- /dev/null +++ b/dmake/unix/sysvr1/time.h @@ -0,0 +1,32 @@ +/* RCS $Id: time.h,v 1.1.1.1 2000-09-22 15:33:35 hr Exp $ +-- +-- SYNOPSIS +-- time_t +-- +-- DESCRIPTION +-- Properly define time_t. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef TIME_h +#define TIME_h + +typedef long time_t; /* this is the thing we use */ + +#endif TIME_h + diff --git a/dmake/unix/sysvr1/vfprintf.c b/dmake/unix/sysvr1/vfprintf.c new file mode 100644 index 000000000000..1d24a1c19b08 --- /dev/null +++ b/dmake/unix/sysvr1/vfprintf.c @@ -0,0 +1,58 @@ +/* From: + * John Limpert johnl@gronk.UUCP uunet!n3dmc!gronk!johnl + */ + +#include <stdio.h> +#include <varargs.h> + +#ifndef BUFSIZ +#include <stdio.h> +#endif + +#ifndef va_dcl +#include <varargs.h> +#endif + +int +vsprintf(str, fmt, ap) + char *str, *fmt; + va_list ap; +{ + FILE f; + int len; + + f._flag = _IOWRT+_IOMYBUF; + f._ptr = (char *)str; /* My copy of BSD stdio.h has this as (char *) + * with a comment that it should be + * (unsigned char *). Since this code is + * intended for use on a vanilla BSD system, + * we'll stick with (char *) for now. + */ + f._cnt = 32767; + len = _doprnt(fmt, ap, &f); + *f._ptr = 0; + return (len); +} + +int +vfprintf(iop, fmt, ap) + FILE *iop; + char *fmt; + va_list ap; +{ + int len; + + len = _doprnt(fmt, ap, iop); + return (ferror(iop) ? EOF : len); +} + +int +vprintf(fmt, ap) + char *fmt; + va_list ap; +{ + int len; + + len = _doprnt(fmt, ap, stdout); + return (ferror(stdout) ? EOF : len); +} diff --git a/dmake/unix/sysvr3/config.mk b/dmake/unix/sysvr3/config.mk new file mode 100644 index 000000000000..75bcf3c2a211 --- /dev/null +++ b/dmake/unix/sysvr3/config.mk @@ -0,0 +1,27 @@ +# This is the SysV R3 UNIX configuration file for DMAKE +# It simply modifies the values of SRC, and checks to see if +# OSENVIRONMENT is defined. If so it includes the appropriate +# config.mk file. +# +# It also sets the values of .SOURCE.c and .SOURCE.h to include the local +# directory. +# +osrdir := $(OS)$(DIRSEPSTR)$(OSRELEASE) + +# The following are required sources +OSDSRC := +.IF $(OSDSRC) + SRC += $(OSDSRC) + .SETDIR=$(osrdir) : $(OSDSRC) +.END + +.SOURCE.h : $(osrdir) + +# Local configuration modifications for CFLAGS, there's local SysV includes +# too. +CFLAGS += -I$(osrdir) + +# See if we modify anything in the lower levels. +.IF $(OSENVIRONMENT) != $(NULL) + .INCLUDE .IGNORE : $(osrdir)$(DIRSEPSTR)$(OSENVIRONMENT)$(DIRSEPSTR)config.mk +.END diff --git a/dmake/unix/sysvr3/gnu/public.h b/dmake/unix/sysvr3/gnu/public.h new file mode 100644 index 000000000000..d5c3111d1345 --- /dev/null +++ b/dmake/unix/sysvr3/gnu/public.h @@ -0,0 +1,162 @@ +/* RCS $Id: public.h,v 1.1.1.1 2000-09-22 15:33:35 hr Exp $ +-- WARNING -- This file is AUTOMATICALLY GENERATED DO NOT EDIT IT +-- +-- +-- SYNOPSIS +-- Local functions exported to be visible by others. +-- +-- DESCRIPTION +-- This file is generated by 'genpub'. Function declarations +-- that appear in this file are extracted by 'genpub' from +-- source files. Any function in the source file whose definition +-- appears like: +-- +-- PUBLIC return_type +-- function( arg_list ); +-- type_expr1 arg1; +-- ... +-- +-- has its definition extracted and a line of the form: +-- +-- return_type function ANSI((type_expr1,type_expr2,...)); +-- +-- entered into the output file. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef _DMAKE_PUBLIC_h +#define _DMAKE_PUBLIC_h + +#ifdef EXTERN +#undef EXTERN +#endif +#if defined(DEFINE_DMAKE_VARIABLES) +#define EXTERN +#else +#define EXTERN extern +#endif + +/***** genpub: Begin list of generated function headers */ +void Infer_recipe ANSI((CELLPTR, CELLPTR)); +int Make_targets ANSI(()); +int Exec_commands ANSI((CELLPTR)); +void Print_cmnd ANSI((char *, int, int)); +void Pop_dir ANSI((int)); +void Append_line ANSI((char *, int, FILE *, char *, int, int)); +void Stat_target ANSI((CELLPTR, int, int)); +char *Expand ANSI((char *)); +char *Apply_edit ANSI((char *, char *, char *, int, int)); +void Map_esc ANSI((char *)); +char* Apply_modifiers ANSI((int, char *)); +char* Tokenize ANSI((char *, char *, char, int)); +char* ScanToken ANSI((char *, char **, int)); +char *DmStrJoin ANSI((char *, char *, int, int)); +char *DmStrAdd ANSI((char *, char *, int)); +char *DmStrApp ANSI((char *, char *)); +char *DmStrDup ANSI((char *)); +char *DmStrDup2 ANSI((char *)); +char *DmStrPbrk ANSI((char *, char *)); +char *DmStrSpn ANSI((char *, char *)); +char *DmStrStr ANSI((char *, char *)); +char *DmSubStr ANSI((char *, char *)); +uint16 Hash ANSI((char *, uint32 *)); +HASHPTR Get_name ANSI((char *, HASHPTR *, int)); +HASHPTR Search_table ANSI((HASHPTR *, char *, uint16 *, uint32 *)); +HASHPTR Push_macro ANSI((HASHPTR)); +HASHPTR Pop_macro ANSI((HASHPTR)); +HASHPTR Def_macro ANSI((char *, char *, int)); +CELLPTR Def_cell ANSI((char *)); +LINKPTR Add_prerequisite ANSI((CELLPTR, CELLPTR, int, int)); +void Clear_prerequisites ANSI((CELLPTR)); +int Test_circle ANSI((CELLPTR, int)); +STRINGPTR Def_recipe ANSI((char *, STRINGPTR, int, int)); +t_attr Rcp_attribute ANSI((char *)); +void main ANSI((int, char **)); +FILE *Openfile ANSI((char *, int, int)); +FILE *Closefile ANSI(()); +FILE *Search_file ANSI((char *, char **)); +char *Filename ANSI(()); +int Nestlevel ANSI(()); +FILE *TryFiles ANSI((LINKPTR)); +void Fatal ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +int Error ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +int Warning ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void No_ram ANSI(()); +void Usage ANSI((int)); +void Version ANSI(()); +char *Get_suffix ANSI((char *)); +char *Basename ANSI((char *)); +char *Filedir ANSI((char *)); +char *Build_path ANSI((char *, char *)); +void Make_rules ANSI(()); +void Create_macro_vars ANSI(()); +time_t Do_stat ANSI((char *, char *, char **, int)); +int Do_touch ANSI((char *, char *, char **)); +void Void_lib_cache ANSI((char *, char *)); +time_t Do_time ANSI(()); +int Do_cmnd ANSI((char *, int, int, CELLPTR, int, int, int)); +char ** Pack_argv ANSI((int, int, char *)); +char *Read_env_string ANSI((char *)); +int Write_env_string ANSI((char *, char *)); +void ReadEnvironment ANSI(()); +void Catch_signals ANSI((void (*)())); +void Clear_signals ANSI(()); +void Prolog ANSI((int, char* [])); +void Epilog ANSI((int)); +char *Get_current_dir ANSI(()); +int Set_dir ANSI((char*)); +char Get_switch_char ANSI(()); +FILE* Get_temp ANSI((char **, char *, int)); +FILE *Start_temp ANSI((char *, CELLPTR, char **)); +void Open_temp_error ANSI((char *, char *)); +void Link_temp ANSI((CELLPTR, FILE *, char *)); +void Close_temp ANSI((CELLPTR, FILE *)); +void Unlink_temp_files ANSI((CELLPTR)); +void Handle_result ANSI((int, int, int, CELLPTR)); +void Update_time_stamp ANSI((CELLPTR)); +int Remove_file ANSI((char *)); +void Parse ANSI((FILE *)); +int Get_line ANSI((char *, FILE *)); +char *Do_comment ANSI((char *, char **, int)); +char *Get_token ANSI((TKSTRPTR, char *, int)); +void Quit ANSI(()); +void Read_state ANSI(()); +void Write_state ANSI(()); +int Check_state ANSI((CELLPTR, STRINGPTR *, int)); +void Dump ANSI(()); +void Dump_recipe ANSI((STRINGPTR)); +int Parse_macro ANSI((char *, int)); +int Macro_op ANSI((char *)); +int Parse_rule_def ANSI((int *)); +int Rule_op ANSI((char *)); +void Add_recipe_to_list ANSI((char *, int, int)); +void Bind_rules_to_targets ANSI((int)); +int Set_group_attributes ANSI((char *)); +DFALINKPTR Match_dfa ANSI((char *)); +void Check_circle_dfa ANSI(()); +void Add_nfa ANSI((char *)); +char *Exec_function ANSI((char *)); +time_t seek_arch ANSI((char *, char *)); +int If_root_path ANSI((char *)); +void Remove_prq ANSI((CELLPTR)); +int runargv ANSI((CELLPTR, int, int, int, int, char *)); +int Wait_for_child ANSI((int, int)); +void Clean_up_processes ANSI(()); +time_t CacheStat ANSI((char *, int)); + +#endif diff --git a/dmake/unix/sysvr3/make.sh b/dmake/unix/sysvr3/make.sh new file mode 100644 index 000000000000..505670f8b708 --- /dev/null +++ b/dmake/unix/sysvr3/make.sh @@ -0,0 +1,60 @@ +mkdir objects +gcc -c -I. -Iunix -Iunix/sysvr3 -O infer.c +mv infer.o objects +gcc -c -I. -Iunix -Iunix/sysvr3 -O make.c +mv make.o objects +gcc -c -I. -Iunix -Iunix/sysvr3 -O stat.c +mv stat.o objects +gcc -c -I. -Iunix -Iunix/sysvr3 -O expand.c +mv expand.o objects +gcc -c -I. -Iunix -Iunix/sysvr3 -O dmstring.c +mv dmstring.o objects +gcc -c -I. -Iunix -Iunix/sysvr3 -O hash.c +mv hash.o objects +gcc -c -I. -Iunix -Iunix/sysvr3 -O dag.c +mv dag.o objects +gcc -c -I. -Iunix -Iunix/sysvr3 -O dmake.c +mv dmake.o objects +gcc -c -I. -Iunix -Iunix/sysvr3 -O path.c +mv path.o objects +gcc -c -I. -Iunix -Iunix/sysvr3 -O imacs.c +mv imacs.o objects +gcc -c -I. -Iunix -Iunix/sysvr3 -O sysintf.c +mv sysintf.o objects +gcc -c -I. -Iunix -Iunix/sysvr3 -O parse.c +mv parse.o objects +gcc -c -I. -Iunix -Iunix/sysvr3 -O getinp.c +mv getinp.o objects +gcc -c -I. -Iunix -Iunix/sysvr3 -O quit.c +mv quit.o objects +gcc -c -I. -Iunix -Iunix/sysvr3 -O state.c +mv state.o objects +gcc -c -I. -Iunix -Iunix/sysvr3 -O dmdump.c +mv dmdump.o objects +gcc -c -I. -Iunix -Iunix/sysvr3 -O macparse.c +mv macparse.o objects +gcc -c -I. -Iunix -Iunix/sysvr3 -O rulparse.c +mv rulparse.o objects +gcc -c -I. -Iunix -Iunix/sysvr3 -O percent.c +mv percent.o objects +gcc -c -I. -Iunix -Iunix/sysvr3 -O function.c +mv function.o objects +gcc -c -I. -Iunix -Iunix/sysvr3 -O unix/arlib.c +mv arlib.o objects +gcc -c -I. -Iunix -Iunix/sysvr3 -O unix/dirbrk.c +mv dirbrk.o objects +gcc -c -I. -Iunix -Iunix/sysvr3 -O unix/rmprq.c +mv rmprq.o objects +gcc -c -I. -Iunix -Iunix/sysvr3 -O unix/ruletab.c +mv ruletab.o objects +gcc -c -I. -Iunix -Iunix/sysvr3 -O unix/runargv.c +mv runargv.o objects +gcc -c -I. -Iunix -Iunix/sysvr3 -O unix/dcache.c +mv dcache.o objects +gcc -O -o dmake objects/infer.o objects/make.o objects/stat.o objects/expand.o \ +objects/dmstring.o objects/hash.o objects/dag.o objects/dmake.o objects/path.o \ +objects/imacs.o objects/sysintf.o objects/parse.o objects/getinp.o \ +objects/quit.o objects/state.o objects/dmdump.o objects/macparse.o \ +objects/rulparse.o objects/percent.o objects/function.o objects/arlib.o \ +objects/dirbrk.o objects/rmprq.o objects/ruletab.o objects/runargv.o objects/dcache.o +cp unix/sysvr3/template.mk startup/config.mk diff --git a/dmake/unix/sysvr3/public.h b/dmake/unix/sysvr3/public.h new file mode 100644 index 000000000000..01e80862fbbd --- /dev/null +++ b/dmake/unix/sysvr3/public.h @@ -0,0 +1,164 @@ +/* RCS $Id: public.h,v 1.1.1.1 2000-09-22 15:33:35 hr Exp $ +-- WARNING -- This file is AUTOMATICALLY GENERATED DO NOT EDIT IT +-- +-- +-- SYNOPSIS +-- Local functions exported to be visible by others. +-- +-- DESCRIPTION +-- This file is generated by 'genpub'. Function declarations +-- that appear in this file are extracted by 'genpub' from +-- source files. Any function in the source file whose definition +-- appears like: +-- +-- PUBLIC return_type +-- function( arg_list ); +-- type_expr1 arg1; +-- ... +-- +-- has its definition extracted and a line of the form: +-- +-- return_type function ANSI((type_expr1,type_expr2,...)); +-- +-- entered into the output file. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef _DMAKE_PUBLIC_h +#define _DMAKE_PUBLIC_h + +#ifdef EXTERN +#undef EXTERN +#endif +#if defined(DEFINE_DMAKE_VARIABLES) +#define EXTERN +#else +#define EXTERN extern +#endif + +/***** genpub: Begin list of generated function headers */ +void Infer_recipe ANSI((CELLPTR, CELLPTR)); +int Make_targets ANSI(()); +int Make ANSI((CELLPTR, CELLPTR)); +int Exec_commands ANSI((CELLPTR)); +void Print_cmnd ANSI((char *, int, int)); +int Push_dir ANSI((char *, char *, int)); +void Pop_dir ANSI((int)); +void Append_line ANSI((char *, int, FILE *, char *, int, int)); +void Stat_target ANSI((CELLPTR, int, int)); +char *Expand ANSI((char *)); +char *Apply_edit ANSI((char *, char *, char *, int, int)); +void Map_esc ANSI((char *)); +char* Apply_modifiers ANSI((int, char *)); +char* Tokenize ANSI((char *, char *, char, int)); +char* ScanToken ANSI((char *, char **, int)); +char *DmStrJoin ANSI((char *, char *, int, int)); +char *DmStrAdd ANSI((char *, char *, int)); +char *DmStrApp ANSI((char *, char *)); +char *DmStrDup ANSI((char *)); +char *DmStrDup2 ANSI((char *)); +char *DmStrPbrk ANSI((char *, char *)); +char *DmStrSpn ANSI((char *, char *)); +char *DmStrStr ANSI((char *, char *)); +char *DmSubStr ANSI((char *, char *)); +uint16 Hash ANSI((char *, uint32 *)); +HASHPTR Get_name ANSI((char *, HASHPTR *, int)); +HASHPTR Search_table ANSI((HASHPTR *, char *, uint16 *, uint32 *)); +HASHPTR Push_macro ANSI((HASHPTR)); +HASHPTR Pop_macro ANSI((HASHPTR)); +HASHPTR Def_macro ANSI((char *, char *, int)); +CELLPTR Def_cell ANSI((char *)); +LINKPTR Add_prerequisite ANSI((CELLPTR, CELLPTR, int, int)); +void Clear_prerequisites ANSI((CELLPTR)); +int Test_circle ANSI((CELLPTR, int)); +STRINGPTR Def_recipe ANSI((char *, STRINGPTR, int, int)); +t_attr Rcp_attribute ANSI((char *)); +void main ANSI((int, char **)); +FILE *Openfile ANSI((char *, int, int)); +FILE *Closefile ANSI(()); +FILE *Search_file ANSI((char *, char **)); +char *Filename ANSI(()); +int Nestlevel ANSI(()); +FILE *TryFiles ANSI((LINKPTR)); +void Fatal ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Error ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Warning ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void No_ram ANSI(()); +void Usage ANSI((int)); +void Version ANSI(()); +char *Get_suffix ANSI((char *)); +char *Basename ANSI((char *)); +char *Filedir ANSI((char *)); +char *Build_path ANSI((char *, char *)); +void Make_rules ANSI(()); +void Create_macro_vars ANSI(()); +time_t Do_stat ANSI((char *, char *, char **, int)); +int Do_touch ANSI((char *, char *, char **)); +void Void_lib_cache ANSI((char *, char *)); +time_t Do_time ANSI(()); +int Do_cmnd ANSI((char *, int, int, CELLPTR, int, int, int)); +char ** Pack_argv ANSI((int, int, char *)); +char *Read_env_string ANSI((char *)); +int Write_env_string ANSI((char *, char *)); +void ReadEnvironment ANSI(()); +void Catch_signals ANSI((void (*)())); +void Clear_signals ANSI(()); +void Prolog ANSI((int, char* [])); +void Epilog ANSI((int)); +char *Get_current_dir ANSI(()); +int Set_dir ANSI((char*)); +char Get_switch_char ANSI(()); +FILE* Get_temp ANSI((char **, char *, int)); +FILE *Start_temp ANSI((char *, CELLPTR, char **)); +void Open_temp_error ANSI((char *, char *)); +void Link_temp ANSI((CELLPTR, FILE *, char *)); +void Close_temp ANSI((CELLPTR, FILE *)); +void Unlink_temp_files ANSI((CELLPTR)); +void Handle_result ANSI((int, int, int, CELLPTR)); +void Update_time_stamp ANSI((CELLPTR)); +int Remove_file ANSI((char *)); +void Parse ANSI((FILE *)); +int Get_line ANSI((char *, FILE *)); +char *Do_comment ANSI((char *, char **, int)); +char *Get_token ANSI((TKSTRPTR, char *, int)); +void Quit ANSI(()); +void Read_state ANSI(()); +void Write_state ANSI(()); +int Check_state ANSI((CELLPTR, STRINGPTR *, int)); +void Dump ANSI(()); +void Dump_recipe ANSI((STRINGPTR)); +int Parse_macro ANSI((char *, int)); +int Macro_op ANSI((char *)); +int Parse_rule_def ANSI((int *)); +int Rule_op ANSI((char *)); +void Add_recipe_to_list ANSI((char *, int, int)); +void Bind_rules_to_targets ANSI((int)); +int Set_group_attributes ANSI((char *)); +DFALINKPTR Match_dfa ANSI((char *)); +void Check_circle_dfa ANSI(()); +void Add_nfa ANSI((char *)); +char *Exec_function ANSI((char *)); +time_t seek_arch ANSI((char *, char *)); +int If_root_path ANSI((char *)); +void Remove_prq ANSI((CELLPTR)); +int runargv ANSI((CELLPTR, int, int, int, int, char *)); +int Wait_for_child ANSI((int, int)); +void Clean_up_processes ANSI(()); +time_t CacheStat ANSI((char *, int)); + +#endif diff --git a/dmake/unix/sysvr3/pwd/config.mk b/dmake/unix/sysvr3/pwd/config.mk new file mode 100644 index 000000000000..86c535a64c1d --- /dev/null +++ b/dmake/unix/sysvr3/pwd/config.mk @@ -0,0 +1,20 @@ +# This is the Sys VR3 PWD configuration file. It configures SysvR3 unix +# versions of dmake to use a provided version of getcwd rather than the +# standard library version that uses popen to capture the output of pwd. +# + +osredir := $(OS)$(DIRSEPSTR)$(OSRELEASE)$(DIRSEPSTR)$(OSENVIRONMENT) + +# The following are required sources +OSRESRC := getcwd.c + +.IF $(OSRESRC) + SRC += $(OSRESRC) + .SETDIR=$(osredir) : $(OSRESRC) +.END + +.SOURCE.h : $(osredir) + +# Local configuration modifications for CFLAGS, there's local SysV includes +# too. +CFLAGS += -I$(osredir) diff --git a/dmake/unix/sysvr3/pwd/getcwd.c b/dmake/unix/sysvr3/pwd/getcwd.c new file mode 100644 index 000000000000..f2359bcc795b --- /dev/null +++ b/dmake/unix/sysvr3/pwd/getcwd.c @@ -0,0 +1,231 @@ +/* + getcwd -- get pathname of current working directory + + public-domain implementation + + last edit: 03-Nov-1990 Gwyn@BRL.MIL + + complies with the following standards: + IEEE Std 1003.1-1988 + SVID Issue 3 + X/Open Portability Guide Issue 2 (when "XPG2" is defined) + X/Open Portability Guide Issue 3 + + This implementation of getcwd() can be used to replace the UNIX + System V library routine (which uses popen() to capture the output of + the "pwd" command). Once that is done, "pwd" can be reimplemented as + just puts(getcwd((char*)0,0)), assuming "XPG2" is defined below. + + This implementation depends on every directory having entries for + "." and "..". It also depends on the internals of the <dirent.h> + data structures to some degree. + + I considered using chdir() to ascend the hierarchy, followed by a + final chdir() to the path being returned by getcwd() to restore the + location, but decided that error recovery was too difficult that way. + The algorithm I settled on was inspired by my rewrite of the "pwd" + utility, combined with the dotdots[] array trick from the SVR2 shell. +*/ +#define XPG2 /* define to support obsolete XPG2-mandated feature */ + + +#include <sys/types.h> +#include <sys/stat.h> + +#ifdef M_XENIX +# include <sys/ndir.h> +# define dirent direct +#else +# include <dirent.h> +#endif + +#include <errno.h> +#include <string.h> + +typedef char *pointer; /* (void *) if you have it */ + +extern void free(); +extern pointer malloc(); +extern int fstat(), stat(); + +extern int errno; /* normally done by <errno.h> */ + +#ifndef NULL +#define NULL 0 /* amorphous null pointer constant */ +#endif + +#ifndef NAME_MAX +#define NAME_MAX 255 /* maximum directory entry size */ +#endif + + +char * +getcwd( buf, size ) /* returns pointer to CWD pathname */ + char *buf; /* where to put name (NULL to malloc) */ + int size; /* size of buf[] or malloc()ed memory */ + { + static char dotdots[] = +"../../../../../../../../../../../../../../../../../../../../../../../../../.."; + char *dotdot; /* -> dotdots[.], right to left */ + DIR *dirp; /* -> parent directory stream */ + struct dirent *dir; /* -> directory entry */ + struct stat stat1, + stat2; /* info from stat() */ + struct stat *d = &stat1; /* -> info about "." */ + struct stat *dd = &stat2; /* -> info about ".." */ + register char *buffer; /* local copy of buf, or malloc()ed */ + char *bufend; /* -> buffer[size] */ + register char *endp; /* -> end of reversed string */ + register char *dname; /* entry name ("" for root) */ + int serrno = errno; /* save entry errno */ + + if ( buf != NULL && size <= 0 +#ifndef XPG2 + || buf == NULL +#endif + ) { + errno = EINVAL; /* invalid argument */ + return NULL; + } + + buffer = buf; +#ifdef XPG2 + if ( buf == NULL /* wants us to malloc() the string */ + && (buffer = (char *) malloc( (unsigned) size )) == NULL + /* XXX -- actually should probably not pay attention to "size" arg */ + ) { + errno = ENOMEM; /* cannot malloc() specified size */ + return NULL; + } +#endif + + if ( stat( ".", dd ) != 0 ) /* prime the pump */ + goto error; /* errno already set */ + + endp = buffer; /* initially, empty string */ + bufend = &buffer[size]; + + for ( dotdot = &dotdots[sizeof dotdots]; dotdot != dotdots; ) + { + dotdot -= 3; /* include one more "/.." section */ + /* (first time is actually "..") */ + + /* swap stat() info buffers */ + { + register struct stat *temp = d; + + d = dd; /* new current dir is old parent dir */ + dd = temp; + } + + if ( (dirp = opendir( dotdot )) == NULL ) /* new parent */ + goto error; /* errno already set */ + + if ( fstat( dirp->dd_fd, dd ) != 0 ) + { + serrno = errno; /* set by fstat() */ + (void)closedir( dirp ); + errno = serrno; /* in case closedir() clobbered it */ + goto error; + } + + if ( d->st_dev == dd->st_dev ) + { /* not crossing a mount point */ + if ( d->st_ino == dd->st_ino ) + { /* root directory */ + dname = ""; + goto append; + } + + do + if ( (dir = readdir( dirp )) == NULL ) + { + (void)closedir( dirp ); + errno = ENOENT; /* missing entry */ + goto error; + } + while ( dir->d_ino != d->st_ino ); + } + else { /* crossing a mount point */ + struct stat t; /* info re. test entry */ + char name[sizeof dotdots + 1 + NAME_MAX]; + + (void)strcpy( name, dotdot ); + dname = &name[strlen( name )]; + *dname++ = '/'; + + do { + if ( (dir = readdir( dirp )) == NULL ) + { + (void)closedir( dirp ); + errno = ENOENT; /* missing entry */ + goto error; + } + + (void)strcpy( dname, dir->d_name ); + /* must fit if NAME_MAX is not a lie */ + } + while ( stat( name, &t ) != 0 + || t.st_ino != d->st_ino + || t.st_dev != d->st_dev + ); + } + + dname = dir->d_name; + + /* append "/" and reversed dname string onto buffer */ + append: + if ( endp != buffer /* avoid trailing / in final name */ + || dname[0] == '\0' /* but allow "/" when CWD is root */ + ) + *endp++ = '/'; + + { + register char *app; /* traverses dname string */ + + for ( app = dname; *app != '\0'; ++app ) + ; + + if ( app - dname >= bufend - endp ) + { + (void)closedir( dirp ); + errno = ERANGE; /* won't fit allotted space */ + goto error; + } + + while ( app != dname ) + *endp++ = *--app; + } + + (void)closedir( dirp ); + + if ( dname[0] == '\0' ) /* reached root; wrap it up */ + { + register char *startp; /* -> buffer[.] */ + + *endp = '\0'; /* plant null terminator */ + + /* straighten out reversed pathname string */ + for ( startp = buffer; --endp > startp; ++startp ) + { + char temp = *endp; + + *endp = *startp; + *startp = temp; + } + + errno = serrno; /* restore entry errno */ + /* XXX -- if buf==NULL, realloc here? */ + return buffer; + } + } + + errno = ENOMEM; /* actually, algorithm failure */ + + error: + if ( buf == NULL ) + free( (pointer)buffer ); + + return NULL; + } + diff --git a/dmake/unix/sysvr3/pwd/make.sh b/dmake/unix/sysvr3/pwd/make.sh new file mode 100644 index 000000000000..1f57569f61df --- /dev/null +++ b/dmake/unix/sysvr3/pwd/make.sh @@ -0,0 +1,62 @@ +mkdir objects +cc -c -I. -Iunix -Iunix/sysvr3 -Iunix/sysvr3/pwd -O infer.c +mv infer.o objects +cc -c -I. -Iunix -Iunix/sysvr3 -Iunix/sysvr3/pwd -O make.c +mv make.o objects +cc -c -I. -Iunix -Iunix/sysvr3 -Iunix/sysvr3/pwd -O stat.c +mv stat.o objects +cc -c -I. -Iunix -Iunix/sysvr3 -Iunix/sysvr3/pwd -O expand.c +mv expand.o objects +cc -c -I. -Iunix -Iunix/sysvr3 -Iunix/sysvr3/pwd -O dmstring.c +mv dmstring.o objects +cc -c -I. -Iunix -Iunix/sysvr3 -Iunix/sysvr3/pwd -O hash.c +mv hash.o objects +cc -c -I. -Iunix -Iunix/sysvr3 -Iunix/sysvr3/pwd -O dag.c +mv dag.o objects +cc -c -I. -Iunix -Iunix/sysvr3 -Iunix/sysvr3/pwd -O dmake.c +mv dmake.o objects +cc -c -I. -Iunix -Iunix/sysvr3 -Iunix/sysvr3/pwd -O path.c +mv path.o objects +cc -c -I. -Iunix -Iunix/sysvr3 -Iunix/sysvr3/pwd -O imacs.c +mv imacs.o objects +cc -c -I. -Iunix -Iunix/sysvr3 -Iunix/sysvr3/pwd -O sysintf.c +mv sysintf.o objects +cc -c -I. -Iunix -Iunix/sysvr3 -Iunix/sysvr3/pwd -O parse.c +mv parse.o objects +cc -c -I. -Iunix -Iunix/sysvr3 -Iunix/sysvr3/pwd -O getinp.c +mv getinp.o objects +cc -c -I. -Iunix -Iunix/sysvr3 -Iunix/sysvr3/pwd -O quit.c +mv quit.o objects +cc -c -I. -Iunix -Iunix/sysvr3 -Iunix/sysvr3/pwd -O state.c +mv state.o objects +cc -c -I. -Iunix -Iunix/sysvr3 -Iunix/sysvr3/pwd -O dmdump.c +mv dmdump.o objects +cc -c -I. -Iunix -Iunix/sysvr3 -Iunix/sysvr3/pwd -O macparse.c +mv macparse.o objects +cc -c -I. -Iunix -Iunix/sysvr3 -Iunix/sysvr3/pwd -O rulparse.c +mv rulparse.o objects +cc -c -I. -Iunix -Iunix/sysvr3 -Iunix/sysvr3/pwd -O percent.c +mv percent.o objects +cc -c -I. -Iunix -Iunix/sysvr3 -Iunix/sysvr3/pwd -O function.c +mv function.o objects +cc -c -I. -Iunix -Iunix/sysvr3 -Iunix/sysvr3/pwd -O unix/arlib.c +mv arlib.o objects +cc -c -I. -Iunix -Iunix/sysvr3 -Iunix/sysvr3/pwd -O unix/dirbrk.c +mv dirbrk.o objects +cc -c -I. -Iunix -Iunix/sysvr3 -Iunix/sysvr3/pwd -O unix/rmprq.c +mv rmprq.o objects +cc -c -I. -Iunix -Iunix/sysvr3 -Iunix/sysvr3/pwd -O unix/ruletab.c +mv ruletab.o objects +cc -c -I. -Iunix -Iunix/sysvr3 -Iunix/sysvr3/pwd -O unix/runargv.c +mv runargv.o objects +cc -c -I. -Iunix -Iunix/sysvr3 -Iunix/sysvr3/pwd -O unix/dcache.c +mv dcache.o objects +cc -c -I. -Iunix -Iunix/sysvr3 -Iunix/sysvr3/pwd -O unix/sysvr3/pwd/getcwd.c +mv getcwd.o objects +cc -O -o dmake objects/infer.o objects/make.o objects/stat.o objects/expand.o \ +objects/dmstring.o objects/hash.o objects/dag.o objects/dmake.o objects/path.o \ +objects/imacs.o objects/sysintf.o objects/parse.o objects/getinp.o \ +objects/quit.o objects/state.o objects/dmdump.o objects/macparse.o \ +objects/rulparse.o objects/percent.o objects/function.o objects/arlib.o \ +objects/dirbrk.o objects/rmprq.o objects/ruletab.o objects/runargv.o objects/dcache.o objects/getcwd.o +cp unix/sysvr3/pwd/template.mk startup/config.mk diff --git a/dmake/unix/sysvr3/pwd/public.h b/dmake/unix/sysvr3/pwd/public.h new file mode 100644 index 000000000000..ea923dad37d1 --- /dev/null +++ b/dmake/unix/sysvr3/pwd/public.h @@ -0,0 +1,164 @@ +/* RCS $Id: public.h,v 1.1.1.1 2000-09-22 15:33:36 hr Exp $ +-- WARNING -- This file is AUTOMATICALLY GENERATED DO NOT EDIT IT +-- +-- +-- SYNOPSIS +-- Local functions exported to be visible by others. +-- +-- DESCRIPTION +-- This file is generated by 'genpub'. Function declarations +-- that appear in this file are extracted by 'genpub' from +-- source files. Any function in the source file whose definition +-- appears like: +-- +-- PUBLIC return_type +-- function( arg_list ); +-- type_expr1 arg1; +-- ... +-- +-- has its definition extracted and a line of the form: +-- +-- return_type function ANSI((type_expr1,type_expr2,...)); +-- +-- entered into the output file. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef _DMAKE_PUBLIC_h +#define _DMAKE_PUBLIC_h + +#ifdef EXTERN +#undef EXTERN +#endif +#if defined(DEFINE_DMAKE_VARIABLES) +#define EXTERN +#else +#define EXTERN extern +#endif + +/***** genpub: Begin list of generated function headers */ +void Infer_recipe ANSI((CELLPTR, CELLPTR)); +int Make_targets ANSI(()); +int Make ANSI((CELLPTR, CELLPTR)); +int Exec_commands ANSI((CELLPTR)); +void Print_cmnd ANSI((char *, int, int)); +int Push_dir ANSI((char *, char *, int)); +void Pop_dir ANSI((int)); +void Append_line ANSI((char *, int, FILE *, char *, int, int)); +void Stat_target ANSI((CELLPTR, int, int)); +char *Expand ANSI((char *)); +char *Apply_edit ANSI((char *, char *, char *, int, int)); +void Map_esc ANSI((char *)); +char* Apply_modifiers ANSI((int, char *)); +char* Tokenize ANSI((char *, char *, char, int)); +char* ScanToken ANSI((char *, char **, int)); +char *DmStrJoin ANSI((char *, char *, int, int)); +char *DmStrAdd ANSI((char *, char *, int)); +char *DmStrApp ANSI((char *, char *)); +char *DmStrDup ANSI((char *)); +char *DmStrDup2 ANSI((char *)); +char *DmStrPbrk ANSI((char *, char *)); +char *DmStrSpn ANSI((char *, char *)); +char *DmStrStr ANSI((char *, char *)); +char *DmSubStr ANSI((char *, char *)); +uint16 Hash ANSI((char *, uint32 *)); +HASHPTR Get_name ANSI((char *, HASHPTR *, int)); +HASHPTR Search_table ANSI((HASHPTR *, char *, uint16 *, uint32 *)); +HASHPTR Push_macro ANSI((HASHPTR)); +HASHPTR Pop_macro ANSI((HASHPTR)); +HASHPTR Def_macro ANSI((char *, char *, int)); +CELLPTR Def_cell ANSI((char *)); +LINKPTR Add_prerequisite ANSI((CELLPTR, CELLPTR, int, int)); +void Clear_prerequisites ANSI((CELLPTR)); +int Test_circle ANSI((CELLPTR, int)); +STRINGPTR Def_recipe ANSI((char *, STRINGPTR, int, int)); +t_attr Rcp_attribute ANSI((char *)); +void main ANSI((int, char **)); +FILE *Openfile ANSI((char *, int, int)); +FILE *Closefile ANSI(()); +FILE *Search_file ANSI((char *, char **)); +char *Filename ANSI(()); +int Nestlevel ANSI(()); +FILE *TryFiles ANSI((LINKPTR)); +void Fatal ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Error ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Warning ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void No_ram ANSI(()); +void Usage ANSI((int)); +void Version ANSI(()); +char *Get_suffix ANSI((char *)); +char *Basename ANSI((char *)); +char *Filedir ANSI((char *)); +char *Build_path ANSI((char *, char *)); +void Make_rules ANSI(()); +void Create_macro_vars ANSI(()); +time_t Do_stat ANSI((char *, char *, char **, int)); +int Do_touch ANSI((char *, char *, char **)); +void Void_lib_cache ANSI((char *, char *)); +time_t Do_time ANSI(()); +int Do_cmnd ANSI((char *, int, int, CELLPTR, int, int, int)); +char ** Pack_argv ANSI((int, int, char *)); +char *Read_env_string ANSI((char *)); +int Write_env_string ANSI((char *, char *)); +void ReadEnvironment ANSI(()); +void Catch_signals ANSI((void (*)())); +void Clear_signals ANSI(()); +void Prolog ANSI((int, char* [])); +void Epilog ANSI((int)); +char *Get_current_dir ANSI(()); +int Set_dir ANSI((char*)); +char Get_switch_char ANSI(()); +FILE* Get_temp ANSI((char **, char *, int)); +FILE *Start_temp ANSI((char *, CELLPTR, char **)); +void Open_temp_error ANSI((char *, char *)); +void Link_temp ANSI((CELLPTR, FILE *, char *)); +void Close_temp ANSI((CELLPTR, FILE *)); +void Unlink_temp_files ANSI((CELLPTR)); +void Handle_result ANSI((int, int, int, CELLPTR)); +void Update_time_stamp ANSI((CELLPTR)); +int Remove_file ANSI((char *)); +void Parse ANSI((FILE *)); +int Get_line ANSI((char *, FILE *)); +char *Do_comment ANSI((char *, char **, int)); +char *Get_token ANSI((TKSTRPTR, char *, int)); +void Quit ANSI(()); +void Read_state ANSI(()); +void Write_state ANSI(()); +int Check_state ANSI((CELLPTR, STRINGPTR *, int)); +void Dump ANSI(()); +void Dump_recipe ANSI((STRINGPTR)); +int Parse_macro ANSI((char *, int)); +int Macro_op ANSI((char *)); +int Parse_rule_def ANSI((int *)); +int Rule_op ANSI((char *)); +void Add_recipe_to_list ANSI((char *, int, int)); +void Bind_rules_to_targets ANSI((int)); +int Set_group_attributes ANSI((char *)); +DFALINKPTR Match_dfa ANSI((char *)); +void Check_circle_dfa ANSI(()); +void Add_nfa ANSI((char *)); +char *Exec_function ANSI((char *)); +time_t seek_arch ANSI((char *, char *)); +int If_root_path ANSI((char *)); +void Remove_prq ANSI((CELLPTR)); +int runargv ANSI((CELLPTR, int, int, int, int, char *)); +int Wait_for_child ANSI((int, int)); +void Clean_up_processes ANSI(()); +time_t CacheStat ANSI((char *, int)); + +#endif diff --git a/dmake/unix/sysvr3/pwd/template.mk b/dmake/unix/sysvr3/pwd/template.mk new file mode 100644 index 000000000000..fa6b4aa6bd1b --- /dev/null +++ b/dmake/unix/sysvr3/pwd/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= unix + OSRELEASE *:= sysvr3 + OSENVIRONMENT *:= pwd diff --git a/dmake/unix/sysvr3/stdlib.h b/dmake/unix/sysvr3/stdlib.h new file mode 100644 index 000000000000..077123d5494f --- /dev/null +++ b/dmake/unix/sysvr3/stdlib.h @@ -0,0 +1,55 @@ +/* RCS $Id: stdlib.h,v 1.1.1.1 2000-09-22 15:33:35 hr Exp $ +-- +-- SYNOPSIS +-- stdlib interface +-- +-- DESCRIPTION +-- Specially needed pieces of interface to the standard C lib. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef _STDLIB_INCLUDED_ +#define _STDLIB_INCLUDED_ + +#ifndef _AIX +extern /*GOTO*/ _exit(); +extern /*GOTO*/ exit(); +extern /*GOTO*/ abort(); +extern int system(); +extern char *getenv(); +extern char *calloc(); +extern char *malloc(); +extern char *realloc(); + +/* The AIX compiler dies on illegal redefinition of free */ +extern free(); +#endif + +/* AIX doesn't use NAME_MAX anylonger... */ +#ifdef _AIX +#include <unistd.h> +#define NAME_MAX pathconf("/dev/null",_PC_NAME_MAX) +#endif + +extern int errno; + +#ifndef EIO +# include <errno.h> +#endif + +#endif /* _STDLIB_INCLUDED_ */ diff --git a/dmake/unix/sysvr3/template.mk b/dmake/unix/sysvr3/template.mk new file mode 100644 index 000000000000..3cb518671142 --- /dev/null +++ b/dmake/unix/sysvr3/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= unix + OSRELEASE *:= sysvr3 + OSENVIRONMENT *:= diff --git a/dmake/unix/sysvr3/time.h b/dmake/unix/sysvr3/time.h new file mode 100644 index 000000000000..3b3dfac5684f --- /dev/null +++ b/dmake/unix/sysvr3/time.h @@ -0,0 +1,32 @@ +/* RCS $Id: time.h,v 1.1.1.1 2000-09-22 15:33:35 hr Exp $ +-- +-- SYNOPSIS +-- time_t +-- +-- DESCRIPTION +-- Properly define time_t. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef TIME_h +#define TIME_h + +typedef long time_t; /* this is the thing we use */ + +#endif TIME_h + diff --git a/dmake/unix/sysvr4/config.mk b/dmake/unix/sysvr4/config.mk new file mode 100644 index 000000000000..6443ff6a91c9 --- /dev/null +++ b/dmake/unix/sysvr4/config.mk @@ -0,0 +1,27 @@ +# This is the SysV R4 UNIX configuration file for DMAKE +# It simply modifies the values of SRC, and checks to see if +# OSENVIRONMENT is defined. If so it includes the appropriate +# config.mk file. +# +# It also sets the values of .SOURCE.c and .SOURCE.h to include the local +# directory. +# +osrdir := $(OS)$(DIRSEPSTR)$(OSRELEASE) + +# The following are required sources +OSDSRC := +.IF $(OSDSRC) + SRC += $(OSDSRC) + .SETDIR=$(osrdir) : $(OSDSRC) +.END + +.SOURCE.h : $(osrdir) + +# Local configuration modifications for CFLAGS, there's local SysV includes +# too. +CFLAGS += -I$(osrdir) + +# See if we modify anything in the lower levels. +.IF $(OSENVIRONMENT) != $(NULL) + .INCLUDE .IGNORE : $(osrdir)$(DIRSEPSTR)$(OSENVIRONMENT)$(DIRSEPSTR)config.mk +.END diff --git a/dmake/unix/sysvr4/make.sh b/dmake/unix/sysvr4/make.sh new file mode 100644 index 000000000000..9ab5904422f0 --- /dev/null +++ b/dmake/unix/sysvr4/make.sh @@ -0,0 +1,60 @@ +mkdir objects +cc -c -I. -Iunix -Iunix/sysvr4 -O infer.c +mv infer.o objects +cc -c -I. -Iunix -Iunix/sysvr4 -O make.c +mv make.o objects +cc -c -I. -Iunix -Iunix/sysvr4 -O stat.c +mv stat.o objects +cc -c -I. -Iunix -Iunix/sysvr4 -O expand.c +mv expand.o objects +cc -c -I. -Iunix -Iunix/sysvr4 -O dmstring.c +mv dmstring.o objects +cc -c -I. -Iunix -Iunix/sysvr4 -O hash.c +mv hash.o objects +cc -c -I. -Iunix -Iunix/sysvr4 -O dag.c +mv dag.o objects +cc -c -I. -Iunix -Iunix/sysvr4 -O dmake.c +mv dmake.o objects +cc -c -I. -Iunix -Iunix/sysvr4 -O path.c +mv path.o objects +cc -c -I. -Iunix -Iunix/sysvr4 -O imacs.c +mv imacs.o objects +cc -c -I. -Iunix -Iunix/sysvr4 -O sysintf.c +mv sysintf.o objects +cc -c -I. -Iunix -Iunix/sysvr4 -O parse.c +mv parse.o objects +cc -c -I. -Iunix -Iunix/sysvr4 -O getinp.c +mv getinp.o objects +cc -c -I. -Iunix -Iunix/sysvr4 -O quit.c +mv quit.o objects +cc -c -I. -Iunix -Iunix/sysvr4 -O state.c +mv state.o objects +cc -c -I. -Iunix -Iunix/sysvr4 -O dmdump.c +mv dmdump.o objects +cc -c -I. -Iunix -Iunix/sysvr4 -O macparse.c +mv macparse.o objects +cc -c -I. -Iunix -Iunix/sysvr4 -O rulparse.c +mv rulparse.o objects +cc -c -I. -Iunix -Iunix/sysvr4 -O percent.c +mv percent.o objects +cc -c -I. -Iunix -Iunix/sysvr4 -O function.c +mv function.o objects +cc -c -I. -Iunix -Iunix/sysvr4 -O unix/arlib.c +mv arlib.o objects +cc -c -I. -Iunix -Iunix/sysvr4 -O unix/dirbrk.c +mv dirbrk.o objects +cc -c -I. -Iunix -Iunix/sysvr4 -O unix/rmprq.c +mv rmprq.o objects +cc -c -I. -Iunix -Iunix/sysvr4 -O unix/ruletab.c +mv ruletab.o objects +cc -c -I. -Iunix -Iunix/sysvr4 -O unix/runargv.c +mv runargv.o objects +cc -c -I. -Iunix -Iunix/sysvr4 -O unix/dcache.c +mv dcache.o objects +cc -O -o dmake objects/infer.o objects/make.o objects/stat.o objects/expand.o \ +objects/dmstring.o objects/hash.o objects/dag.o objects/dmake.o objects/path.o \ +objects/imacs.o objects/sysintf.o objects/parse.o objects/getinp.o \ +objects/quit.o objects/state.o objects/dmdump.o objects/macparse.o \ +objects/rulparse.o objects/percent.o objects/function.o objects/arlib.o \ +objects/dirbrk.o objects/rmprq.o objects/ruletab.o objects/runargv.o objects/dcache.o +cp unix/sysvr4/template.mk startup/config.mk diff --git a/dmake/unix/sysvr4/public.h b/dmake/unix/sysvr4/public.h new file mode 100644 index 000000000000..ea923dad37d1 --- /dev/null +++ b/dmake/unix/sysvr4/public.h @@ -0,0 +1,164 @@ +/* RCS $Id: public.h,v 1.1.1.1 2000-09-22 15:33:36 hr Exp $ +-- WARNING -- This file is AUTOMATICALLY GENERATED DO NOT EDIT IT +-- +-- +-- SYNOPSIS +-- Local functions exported to be visible by others. +-- +-- DESCRIPTION +-- This file is generated by 'genpub'. Function declarations +-- that appear in this file are extracted by 'genpub' from +-- source files. Any function in the source file whose definition +-- appears like: +-- +-- PUBLIC return_type +-- function( arg_list ); +-- type_expr1 arg1; +-- ... +-- +-- has its definition extracted and a line of the form: +-- +-- return_type function ANSI((type_expr1,type_expr2,...)); +-- +-- entered into the output file. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef _DMAKE_PUBLIC_h +#define _DMAKE_PUBLIC_h + +#ifdef EXTERN +#undef EXTERN +#endif +#if defined(DEFINE_DMAKE_VARIABLES) +#define EXTERN +#else +#define EXTERN extern +#endif + +/***** genpub: Begin list of generated function headers */ +void Infer_recipe ANSI((CELLPTR, CELLPTR)); +int Make_targets ANSI(()); +int Make ANSI((CELLPTR, CELLPTR)); +int Exec_commands ANSI((CELLPTR)); +void Print_cmnd ANSI((char *, int, int)); +int Push_dir ANSI((char *, char *, int)); +void Pop_dir ANSI((int)); +void Append_line ANSI((char *, int, FILE *, char *, int, int)); +void Stat_target ANSI((CELLPTR, int, int)); +char *Expand ANSI((char *)); +char *Apply_edit ANSI((char *, char *, char *, int, int)); +void Map_esc ANSI((char *)); +char* Apply_modifiers ANSI((int, char *)); +char* Tokenize ANSI((char *, char *, char, int)); +char* ScanToken ANSI((char *, char **, int)); +char *DmStrJoin ANSI((char *, char *, int, int)); +char *DmStrAdd ANSI((char *, char *, int)); +char *DmStrApp ANSI((char *, char *)); +char *DmStrDup ANSI((char *)); +char *DmStrDup2 ANSI((char *)); +char *DmStrPbrk ANSI((char *, char *)); +char *DmStrSpn ANSI((char *, char *)); +char *DmStrStr ANSI((char *, char *)); +char *DmSubStr ANSI((char *, char *)); +uint16 Hash ANSI((char *, uint32 *)); +HASHPTR Get_name ANSI((char *, HASHPTR *, int)); +HASHPTR Search_table ANSI((HASHPTR *, char *, uint16 *, uint32 *)); +HASHPTR Push_macro ANSI((HASHPTR)); +HASHPTR Pop_macro ANSI((HASHPTR)); +HASHPTR Def_macro ANSI((char *, char *, int)); +CELLPTR Def_cell ANSI((char *)); +LINKPTR Add_prerequisite ANSI((CELLPTR, CELLPTR, int, int)); +void Clear_prerequisites ANSI((CELLPTR)); +int Test_circle ANSI((CELLPTR, int)); +STRINGPTR Def_recipe ANSI((char *, STRINGPTR, int, int)); +t_attr Rcp_attribute ANSI((char *)); +void main ANSI((int, char **)); +FILE *Openfile ANSI((char *, int, int)); +FILE *Closefile ANSI(()); +FILE *Search_file ANSI((char *, char **)); +char *Filename ANSI(()); +int Nestlevel ANSI(()); +FILE *TryFiles ANSI((LINKPTR)); +void Fatal ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Error ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Warning ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void No_ram ANSI(()); +void Usage ANSI((int)); +void Version ANSI(()); +char *Get_suffix ANSI((char *)); +char *Basename ANSI((char *)); +char *Filedir ANSI((char *)); +char *Build_path ANSI((char *, char *)); +void Make_rules ANSI(()); +void Create_macro_vars ANSI(()); +time_t Do_stat ANSI((char *, char *, char **, int)); +int Do_touch ANSI((char *, char *, char **)); +void Void_lib_cache ANSI((char *, char *)); +time_t Do_time ANSI(()); +int Do_cmnd ANSI((char *, int, int, CELLPTR, int, int, int)); +char ** Pack_argv ANSI((int, int, char *)); +char *Read_env_string ANSI((char *)); +int Write_env_string ANSI((char *, char *)); +void ReadEnvironment ANSI(()); +void Catch_signals ANSI((void (*)())); +void Clear_signals ANSI(()); +void Prolog ANSI((int, char* [])); +void Epilog ANSI((int)); +char *Get_current_dir ANSI(()); +int Set_dir ANSI((char*)); +char Get_switch_char ANSI(()); +FILE* Get_temp ANSI((char **, char *, int)); +FILE *Start_temp ANSI((char *, CELLPTR, char **)); +void Open_temp_error ANSI((char *, char *)); +void Link_temp ANSI((CELLPTR, FILE *, char *)); +void Close_temp ANSI((CELLPTR, FILE *)); +void Unlink_temp_files ANSI((CELLPTR)); +void Handle_result ANSI((int, int, int, CELLPTR)); +void Update_time_stamp ANSI((CELLPTR)); +int Remove_file ANSI((char *)); +void Parse ANSI((FILE *)); +int Get_line ANSI((char *, FILE *)); +char *Do_comment ANSI((char *, char **, int)); +char *Get_token ANSI((TKSTRPTR, char *, int)); +void Quit ANSI(()); +void Read_state ANSI(()); +void Write_state ANSI(()); +int Check_state ANSI((CELLPTR, STRINGPTR *, int)); +void Dump ANSI(()); +void Dump_recipe ANSI((STRINGPTR)); +int Parse_macro ANSI((char *, int)); +int Macro_op ANSI((char *)); +int Parse_rule_def ANSI((int *)); +int Rule_op ANSI((char *)); +void Add_recipe_to_list ANSI((char *, int, int)); +void Bind_rules_to_targets ANSI((int)); +int Set_group_attributes ANSI((char *)); +DFALINKPTR Match_dfa ANSI((char *)); +void Check_circle_dfa ANSI(()); +void Add_nfa ANSI((char *)); +char *Exec_function ANSI((char *)); +time_t seek_arch ANSI((char *, char *)); +int If_root_path ANSI((char *)); +void Remove_prq ANSI((CELLPTR)); +int runargv ANSI((CELLPTR, int, int, int, int, char *)); +int Wait_for_child ANSI((int, int)); +void Clean_up_processes ANSI(()); +time_t CacheStat ANSI((char *, int)); + +#endif diff --git a/dmake/unix/sysvr4/template.mk b/dmake/unix/sysvr4/template.mk new file mode 100644 index 000000000000..553878268e59 --- /dev/null +++ b/dmake/unix/sysvr4/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= unix + OSRELEASE *:= sysvr4 + OSENVIRONMENT *:= diff --git a/dmake/unix/xenix/config.mk b/dmake/unix/xenix/config.mk new file mode 100644 index 000000000000..a4f8f78f3ee1 --- /dev/null +++ b/dmake/unix/xenix/config.mk @@ -0,0 +1,27 @@ +# This is the SysV R3 UNIX configuration file for DMAKE +# It simply modifies the values of SRC, and checks to see if +# OSENVIRONMENT is defined. If so it includes the appropriate +# config.mk file. +# +# It also sets the values of .SOURCE.c and .SOURCE.h to include the local +# directory. +# +osrdir := $(OS)$(DIRSEPSTR)$(OSRELEASE) + +# The following are required sources +OSDSRC := +.IF $(OSDSRC) + SRC += $(OSDSRC) + .SETDIR=$(osrdir) : $(OSDSRC) +.END + +.SOURCE.h : $(osrdir) + +# Local configuration modifications for CFLAGS, there's local SysV includes +# too. +CFLAGS += -I$(osrdir) -DM_XENIX + +# See if we modify anything in the lower levels. +.IF $(OSENVIRONMENT) != $(NULL) + .INCLUDE .IGNORE : $(osrdir)$(DIRSEPSTR)$(OSENVIRONMENT)$(DIRSEPSTR)config.mk +.END diff --git a/dmake/unix/xenix/make.sh b/dmake/unix/xenix/make.sh new file mode 100644 index 000000000000..597936f38061 --- /dev/null +++ b/dmake/unix/xenix/make.sh @@ -0,0 +1,60 @@ +mkdir objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -O infer.c +mv infer.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -O make.c +mv make.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -O stat.c +mv stat.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -O expand.c +mv expand.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -O dmstring.c +mv dmstring.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -O hash.c +mv hash.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -O dag.c +mv dag.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -O dmake.c +mv dmake.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -O path.c +mv path.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -O imacs.c +mv imacs.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -O sysintf.c +mv sysintf.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -O parse.c +mv parse.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -O getinp.c +mv getinp.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -O quit.c +mv quit.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -O state.c +mv state.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -O dmdump.c +mv dmdump.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -O macparse.c +mv macparse.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -O rulparse.c +mv rulparse.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -O percent.c +mv percent.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -O function.c +mv function.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -O unix/arlib.c +mv arlib.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -O unix/dirbrk.c +mv dirbrk.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -O unix/rmprq.c +mv rmprq.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -O unix/ruletab.c +mv ruletab.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -O unix/runargv.c +mv runargv.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -O unix/dcache.c +mv dcache.o objects +cc -O -o dmake objects/infer.o objects/make.o objects/stat.o objects/expand.o \ +objects/dmstring.o objects/hash.o objects/dag.o objects/dmake.o objects/path.o \ +objects/imacs.o objects/sysintf.o objects/parse.o objects/getinp.o \ +objects/quit.o objects/state.o objects/dmdump.o objects/macparse.o \ +objects/rulparse.o objects/percent.o objects/function.o objects/arlib.o \ +objects/dirbrk.o objects/rmprq.o objects/ruletab.o objects/runargv.o objects/dcache.o +cp unix/xenix/template.mk startup/config.mk diff --git a/dmake/unix/xenix/public.h b/dmake/unix/xenix/public.h new file mode 100644 index 000000000000..ea923dad37d1 --- /dev/null +++ b/dmake/unix/xenix/public.h @@ -0,0 +1,164 @@ +/* RCS $Id: public.h,v 1.1.1.1 2000-09-22 15:33:36 hr Exp $ +-- WARNING -- This file is AUTOMATICALLY GENERATED DO NOT EDIT IT +-- +-- +-- SYNOPSIS +-- Local functions exported to be visible by others. +-- +-- DESCRIPTION +-- This file is generated by 'genpub'. Function declarations +-- that appear in this file are extracted by 'genpub' from +-- source files. Any function in the source file whose definition +-- appears like: +-- +-- PUBLIC return_type +-- function( arg_list ); +-- type_expr1 arg1; +-- ... +-- +-- has its definition extracted and a line of the form: +-- +-- return_type function ANSI((type_expr1,type_expr2,...)); +-- +-- entered into the output file. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef _DMAKE_PUBLIC_h +#define _DMAKE_PUBLIC_h + +#ifdef EXTERN +#undef EXTERN +#endif +#if defined(DEFINE_DMAKE_VARIABLES) +#define EXTERN +#else +#define EXTERN extern +#endif + +/***** genpub: Begin list of generated function headers */ +void Infer_recipe ANSI((CELLPTR, CELLPTR)); +int Make_targets ANSI(()); +int Make ANSI((CELLPTR, CELLPTR)); +int Exec_commands ANSI((CELLPTR)); +void Print_cmnd ANSI((char *, int, int)); +int Push_dir ANSI((char *, char *, int)); +void Pop_dir ANSI((int)); +void Append_line ANSI((char *, int, FILE *, char *, int, int)); +void Stat_target ANSI((CELLPTR, int, int)); +char *Expand ANSI((char *)); +char *Apply_edit ANSI((char *, char *, char *, int, int)); +void Map_esc ANSI((char *)); +char* Apply_modifiers ANSI((int, char *)); +char* Tokenize ANSI((char *, char *, char, int)); +char* ScanToken ANSI((char *, char **, int)); +char *DmStrJoin ANSI((char *, char *, int, int)); +char *DmStrAdd ANSI((char *, char *, int)); +char *DmStrApp ANSI((char *, char *)); +char *DmStrDup ANSI((char *)); +char *DmStrDup2 ANSI((char *)); +char *DmStrPbrk ANSI((char *, char *)); +char *DmStrSpn ANSI((char *, char *)); +char *DmStrStr ANSI((char *, char *)); +char *DmSubStr ANSI((char *, char *)); +uint16 Hash ANSI((char *, uint32 *)); +HASHPTR Get_name ANSI((char *, HASHPTR *, int)); +HASHPTR Search_table ANSI((HASHPTR *, char *, uint16 *, uint32 *)); +HASHPTR Push_macro ANSI((HASHPTR)); +HASHPTR Pop_macro ANSI((HASHPTR)); +HASHPTR Def_macro ANSI((char *, char *, int)); +CELLPTR Def_cell ANSI((char *)); +LINKPTR Add_prerequisite ANSI((CELLPTR, CELLPTR, int, int)); +void Clear_prerequisites ANSI((CELLPTR)); +int Test_circle ANSI((CELLPTR, int)); +STRINGPTR Def_recipe ANSI((char *, STRINGPTR, int, int)); +t_attr Rcp_attribute ANSI((char *)); +void main ANSI((int, char **)); +FILE *Openfile ANSI((char *, int, int)); +FILE *Closefile ANSI(()); +FILE *Search_file ANSI((char *, char **)); +char *Filename ANSI(()); +int Nestlevel ANSI(()); +FILE *TryFiles ANSI((LINKPTR)); +void Fatal ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Error ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Warning ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void No_ram ANSI(()); +void Usage ANSI((int)); +void Version ANSI(()); +char *Get_suffix ANSI((char *)); +char *Basename ANSI((char *)); +char *Filedir ANSI((char *)); +char *Build_path ANSI((char *, char *)); +void Make_rules ANSI(()); +void Create_macro_vars ANSI(()); +time_t Do_stat ANSI((char *, char *, char **, int)); +int Do_touch ANSI((char *, char *, char **)); +void Void_lib_cache ANSI((char *, char *)); +time_t Do_time ANSI(()); +int Do_cmnd ANSI((char *, int, int, CELLPTR, int, int, int)); +char ** Pack_argv ANSI((int, int, char *)); +char *Read_env_string ANSI((char *)); +int Write_env_string ANSI((char *, char *)); +void ReadEnvironment ANSI(()); +void Catch_signals ANSI((void (*)())); +void Clear_signals ANSI(()); +void Prolog ANSI((int, char* [])); +void Epilog ANSI((int)); +char *Get_current_dir ANSI(()); +int Set_dir ANSI((char*)); +char Get_switch_char ANSI(()); +FILE* Get_temp ANSI((char **, char *, int)); +FILE *Start_temp ANSI((char *, CELLPTR, char **)); +void Open_temp_error ANSI((char *, char *)); +void Link_temp ANSI((CELLPTR, FILE *, char *)); +void Close_temp ANSI((CELLPTR, FILE *)); +void Unlink_temp_files ANSI((CELLPTR)); +void Handle_result ANSI((int, int, int, CELLPTR)); +void Update_time_stamp ANSI((CELLPTR)); +int Remove_file ANSI((char *)); +void Parse ANSI((FILE *)); +int Get_line ANSI((char *, FILE *)); +char *Do_comment ANSI((char *, char **, int)); +char *Get_token ANSI((TKSTRPTR, char *, int)); +void Quit ANSI(()); +void Read_state ANSI(()); +void Write_state ANSI(()); +int Check_state ANSI((CELLPTR, STRINGPTR *, int)); +void Dump ANSI(()); +void Dump_recipe ANSI((STRINGPTR)); +int Parse_macro ANSI((char *, int)); +int Macro_op ANSI((char *)); +int Parse_rule_def ANSI((int *)); +int Rule_op ANSI((char *)); +void Add_recipe_to_list ANSI((char *, int, int)); +void Bind_rules_to_targets ANSI((int)); +int Set_group_attributes ANSI((char *)); +DFALINKPTR Match_dfa ANSI((char *)); +void Check_circle_dfa ANSI(()); +void Add_nfa ANSI((char *)); +char *Exec_function ANSI((char *)); +time_t seek_arch ANSI((char *, char *)); +int If_root_path ANSI((char *)); +void Remove_prq ANSI((CELLPTR)); +int runargv ANSI((CELLPTR, int, int, int, int, char *)); +int Wait_for_child ANSI((int, int)); +void Clean_up_processes ANSI(()); +time_t CacheStat ANSI((char *, int)); + +#endif diff --git a/dmake/unix/xenix/pwd/config.mk b/dmake/unix/xenix/pwd/config.mk new file mode 100644 index 000000000000..095ff3587a68 --- /dev/null +++ b/dmake/unix/xenix/pwd/config.mk @@ -0,0 +1,23 @@ +# This is the Sys VR3 PWD configuration file. It configures SysvR3 unix +# versions of dmake to use a provided version of getcwd rather than the +# standard library version that uses popen to capture the output of pwd. +# + +osredir := $(OS)$(DIRSEPSTR)$(OSRELEASE)$(DIRSEPSTR)$(OSENVIRONMENT) + +# The following are required sources +OSRESRC := getcwd.c + +.IF $(OSRESRC) + SRC += $(OSRESRC) + .SETDIR=$(osredir) : $(OSRESRC) +.END + +.SOURCE.h : $(osredir) + +# Local configuration modifications for CFLAGS, there's local SysV includes +# too. +CFLAGS += -I$(osredir) + +# Xenix needs -lx in order to link successfully. +LDLIBS += -lx diff --git a/dmake/unix/xenix/pwd/getcwd.c b/dmake/unix/xenix/pwd/getcwd.c new file mode 100644 index 000000000000..f2359bcc795b --- /dev/null +++ b/dmake/unix/xenix/pwd/getcwd.c @@ -0,0 +1,231 @@ +/* + getcwd -- get pathname of current working directory + + public-domain implementation + + last edit: 03-Nov-1990 Gwyn@BRL.MIL + + complies with the following standards: + IEEE Std 1003.1-1988 + SVID Issue 3 + X/Open Portability Guide Issue 2 (when "XPG2" is defined) + X/Open Portability Guide Issue 3 + + This implementation of getcwd() can be used to replace the UNIX + System V library routine (which uses popen() to capture the output of + the "pwd" command). Once that is done, "pwd" can be reimplemented as + just puts(getcwd((char*)0,0)), assuming "XPG2" is defined below. + + This implementation depends on every directory having entries for + "." and "..". It also depends on the internals of the <dirent.h> + data structures to some degree. + + I considered using chdir() to ascend the hierarchy, followed by a + final chdir() to the path being returned by getcwd() to restore the + location, but decided that error recovery was too difficult that way. + The algorithm I settled on was inspired by my rewrite of the "pwd" + utility, combined with the dotdots[] array trick from the SVR2 shell. +*/ +#define XPG2 /* define to support obsolete XPG2-mandated feature */ + + +#include <sys/types.h> +#include <sys/stat.h> + +#ifdef M_XENIX +# include <sys/ndir.h> +# define dirent direct +#else +# include <dirent.h> +#endif + +#include <errno.h> +#include <string.h> + +typedef char *pointer; /* (void *) if you have it */ + +extern void free(); +extern pointer malloc(); +extern int fstat(), stat(); + +extern int errno; /* normally done by <errno.h> */ + +#ifndef NULL +#define NULL 0 /* amorphous null pointer constant */ +#endif + +#ifndef NAME_MAX +#define NAME_MAX 255 /* maximum directory entry size */ +#endif + + +char * +getcwd( buf, size ) /* returns pointer to CWD pathname */ + char *buf; /* where to put name (NULL to malloc) */ + int size; /* size of buf[] or malloc()ed memory */ + { + static char dotdots[] = +"../../../../../../../../../../../../../../../../../../../../../../../../../.."; + char *dotdot; /* -> dotdots[.], right to left */ + DIR *dirp; /* -> parent directory stream */ + struct dirent *dir; /* -> directory entry */ + struct stat stat1, + stat2; /* info from stat() */ + struct stat *d = &stat1; /* -> info about "." */ + struct stat *dd = &stat2; /* -> info about ".." */ + register char *buffer; /* local copy of buf, or malloc()ed */ + char *bufend; /* -> buffer[size] */ + register char *endp; /* -> end of reversed string */ + register char *dname; /* entry name ("" for root) */ + int serrno = errno; /* save entry errno */ + + if ( buf != NULL && size <= 0 +#ifndef XPG2 + || buf == NULL +#endif + ) { + errno = EINVAL; /* invalid argument */ + return NULL; + } + + buffer = buf; +#ifdef XPG2 + if ( buf == NULL /* wants us to malloc() the string */ + && (buffer = (char *) malloc( (unsigned) size )) == NULL + /* XXX -- actually should probably not pay attention to "size" arg */ + ) { + errno = ENOMEM; /* cannot malloc() specified size */ + return NULL; + } +#endif + + if ( stat( ".", dd ) != 0 ) /* prime the pump */ + goto error; /* errno already set */ + + endp = buffer; /* initially, empty string */ + bufend = &buffer[size]; + + for ( dotdot = &dotdots[sizeof dotdots]; dotdot != dotdots; ) + { + dotdot -= 3; /* include one more "/.." section */ + /* (first time is actually "..") */ + + /* swap stat() info buffers */ + { + register struct stat *temp = d; + + d = dd; /* new current dir is old parent dir */ + dd = temp; + } + + if ( (dirp = opendir( dotdot )) == NULL ) /* new parent */ + goto error; /* errno already set */ + + if ( fstat( dirp->dd_fd, dd ) != 0 ) + { + serrno = errno; /* set by fstat() */ + (void)closedir( dirp ); + errno = serrno; /* in case closedir() clobbered it */ + goto error; + } + + if ( d->st_dev == dd->st_dev ) + { /* not crossing a mount point */ + if ( d->st_ino == dd->st_ino ) + { /* root directory */ + dname = ""; + goto append; + } + + do + if ( (dir = readdir( dirp )) == NULL ) + { + (void)closedir( dirp ); + errno = ENOENT; /* missing entry */ + goto error; + } + while ( dir->d_ino != d->st_ino ); + } + else { /* crossing a mount point */ + struct stat t; /* info re. test entry */ + char name[sizeof dotdots + 1 + NAME_MAX]; + + (void)strcpy( name, dotdot ); + dname = &name[strlen( name )]; + *dname++ = '/'; + + do { + if ( (dir = readdir( dirp )) == NULL ) + { + (void)closedir( dirp ); + errno = ENOENT; /* missing entry */ + goto error; + } + + (void)strcpy( dname, dir->d_name ); + /* must fit if NAME_MAX is not a lie */ + } + while ( stat( name, &t ) != 0 + || t.st_ino != d->st_ino + || t.st_dev != d->st_dev + ); + } + + dname = dir->d_name; + + /* append "/" and reversed dname string onto buffer */ + append: + if ( endp != buffer /* avoid trailing / in final name */ + || dname[0] == '\0' /* but allow "/" when CWD is root */ + ) + *endp++ = '/'; + + { + register char *app; /* traverses dname string */ + + for ( app = dname; *app != '\0'; ++app ) + ; + + if ( app - dname >= bufend - endp ) + { + (void)closedir( dirp ); + errno = ERANGE; /* won't fit allotted space */ + goto error; + } + + while ( app != dname ) + *endp++ = *--app; + } + + (void)closedir( dirp ); + + if ( dname[0] == '\0' ) /* reached root; wrap it up */ + { + register char *startp; /* -> buffer[.] */ + + *endp = '\0'; /* plant null terminator */ + + /* straighten out reversed pathname string */ + for ( startp = buffer; --endp > startp; ++startp ) + { + char temp = *endp; + + *endp = *startp; + *startp = temp; + } + + errno = serrno; /* restore entry errno */ + /* XXX -- if buf==NULL, realloc here? */ + return buffer; + } + } + + errno = ENOMEM; /* actually, algorithm failure */ + + error: + if ( buf == NULL ) + free( (pointer)buffer ); + + return NULL; + } + diff --git a/dmake/unix/xenix/pwd/make.sh b/dmake/unix/xenix/pwd/make.sh new file mode 100644 index 000000000000..e7c02e53ace6 --- /dev/null +++ b/dmake/unix/xenix/pwd/make.sh @@ -0,0 +1,62 @@ +mkdir objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -Iunix/xenix/pwd -O infer.c +mv infer.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -Iunix/xenix/pwd -O make.c +mv make.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -Iunix/xenix/pwd -O stat.c +mv stat.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -Iunix/xenix/pwd -O expand.c +mv expand.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -Iunix/xenix/pwd -O dmstring.c +mv dmstring.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -Iunix/xenix/pwd -O hash.c +mv hash.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -Iunix/xenix/pwd -O dag.c +mv dag.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -Iunix/xenix/pwd -O dmake.c +mv dmake.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -Iunix/xenix/pwd -O path.c +mv path.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -Iunix/xenix/pwd -O imacs.c +mv imacs.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -Iunix/xenix/pwd -O sysintf.c +mv sysintf.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -Iunix/xenix/pwd -O parse.c +mv parse.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -Iunix/xenix/pwd -O getinp.c +mv getinp.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -Iunix/xenix/pwd -O quit.c +mv quit.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -Iunix/xenix/pwd -O state.c +mv state.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -Iunix/xenix/pwd -O dmdump.c +mv dmdump.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -Iunix/xenix/pwd -O macparse.c +mv macparse.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -Iunix/xenix/pwd -O rulparse.c +mv rulparse.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -Iunix/xenix/pwd -O percent.c +mv percent.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -Iunix/xenix/pwd -O function.c +mv function.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -Iunix/xenix/pwd -O unix/arlib.c +mv arlib.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -Iunix/xenix/pwd -O unix/dirbrk.c +mv dirbrk.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -Iunix/xenix/pwd -O unix/rmprq.c +mv rmprq.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -Iunix/xenix/pwd -O unix/ruletab.c +mv ruletab.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -Iunix/xenix/pwd -O unix/runargv.c +mv runargv.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -Iunix/xenix/pwd -O unix/dcache.c +mv dcache.o objects +cc -c -I. -Iunix -Iunix/xenix -DM_XENIX -Iunix/xenix/pwd -O unix/xenix/pwd/getcwd.c +mv getcwd.o objects +cc -O -o dmake objects/infer.o objects/make.o objects/stat.o objects/expand.o \ +objects/dmstring.o objects/hash.o objects/dag.o objects/dmake.o objects/path.o \ +objects/imacs.o objects/sysintf.o objects/parse.o objects/getinp.o \ +objects/quit.o objects/state.o objects/dmdump.o objects/macparse.o \ +objects/rulparse.o objects/percent.o objects/function.o objects/arlib.o \ +objects/dirbrk.o objects/rmprq.o objects/ruletab.o objects/runargv.o objects/dcache.o objects/getcwd.o -lx +cp unix/xenix/pwd/template.mk startup/config.mk diff --git a/dmake/unix/xenix/pwd/public.h b/dmake/unix/xenix/pwd/public.h new file mode 100644 index 000000000000..ea923dad37d1 --- /dev/null +++ b/dmake/unix/xenix/pwd/public.h @@ -0,0 +1,164 @@ +/* RCS $Id: public.h,v 1.1.1.1 2000-09-22 15:33:36 hr Exp $ +-- WARNING -- This file is AUTOMATICALLY GENERATED DO NOT EDIT IT +-- +-- +-- SYNOPSIS +-- Local functions exported to be visible by others. +-- +-- DESCRIPTION +-- This file is generated by 'genpub'. Function declarations +-- that appear in this file are extracted by 'genpub' from +-- source files. Any function in the source file whose definition +-- appears like: +-- +-- PUBLIC return_type +-- function( arg_list ); +-- type_expr1 arg1; +-- ... +-- +-- has its definition extracted and a line of the form: +-- +-- return_type function ANSI((type_expr1,type_expr2,...)); +-- +-- entered into the output file. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef _DMAKE_PUBLIC_h +#define _DMAKE_PUBLIC_h + +#ifdef EXTERN +#undef EXTERN +#endif +#if defined(DEFINE_DMAKE_VARIABLES) +#define EXTERN +#else +#define EXTERN extern +#endif + +/***** genpub: Begin list of generated function headers */ +void Infer_recipe ANSI((CELLPTR, CELLPTR)); +int Make_targets ANSI(()); +int Make ANSI((CELLPTR, CELLPTR)); +int Exec_commands ANSI((CELLPTR)); +void Print_cmnd ANSI((char *, int, int)); +int Push_dir ANSI((char *, char *, int)); +void Pop_dir ANSI((int)); +void Append_line ANSI((char *, int, FILE *, char *, int, int)); +void Stat_target ANSI((CELLPTR, int, int)); +char *Expand ANSI((char *)); +char *Apply_edit ANSI((char *, char *, char *, int, int)); +void Map_esc ANSI((char *)); +char* Apply_modifiers ANSI((int, char *)); +char* Tokenize ANSI((char *, char *, char, int)); +char* ScanToken ANSI((char *, char **, int)); +char *DmStrJoin ANSI((char *, char *, int, int)); +char *DmStrAdd ANSI((char *, char *, int)); +char *DmStrApp ANSI((char *, char *)); +char *DmStrDup ANSI((char *)); +char *DmStrDup2 ANSI((char *)); +char *DmStrPbrk ANSI((char *, char *)); +char *DmStrSpn ANSI((char *, char *)); +char *DmStrStr ANSI((char *, char *)); +char *DmSubStr ANSI((char *, char *)); +uint16 Hash ANSI((char *, uint32 *)); +HASHPTR Get_name ANSI((char *, HASHPTR *, int)); +HASHPTR Search_table ANSI((HASHPTR *, char *, uint16 *, uint32 *)); +HASHPTR Push_macro ANSI((HASHPTR)); +HASHPTR Pop_macro ANSI((HASHPTR)); +HASHPTR Def_macro ANSI((char *, char *, int)); +CELLPTR Def_cell ANSI((char *)); +LINKPTR Add_prerequisite ANSI((CELLPTR, CELLPTR, int, int)); +void Clear_prerequisites ANSI((CELLPTR)); +int Test_circle ANSI((CELLPTR, int)); +STRINGPTR Def_recipe ANSI((char *, STRINGPTR, int, int)); +t_attr Rcp_attribute ANSI((char *)); +void main ANSI((int, char **)); +FILE *Openfile ANSI((char *, int, int)); +FILE *Closefile ANSI(()); +FILE *Search_file ANSI((char *, char **)); +char *Filename ANSI(()); +int Nestlevel ANSI(()); +FILE *TryFiles ANSI((LINKPTR)); +void Fatal ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Error ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Warning ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void No_ram ANSI(()); +void Usage ANSI((int)); +void Version ANSI(()); +char *Get_suffix ANSI((char *)); +char *Basename ANSI((char *)); +char *Filedir ANSI((char *)); +char *Build_path ANSI((char *, char *)); +void Make_rules ANSI(()); +void Create_macro_vars ANSI(()); +time_t Do_stat ANSI((char *, char *, char **, int)); +int Do_touch ANSI((char *, char *, char **)); +void Void_lib_cache ANSI((char *, char *)); +time_t Do_time ANSI(()); +int Do_cmnd ANSI((char *, int, int, CELLPTR, int, int, int)); +char ** Pack_argv ANSI((int, int, char *)); +char *Read_env_string ANSI((char *)); +int Write_env_string ANSI((char *, char *)); +void ReadEnvironment ANSI(()); +void Catch_signals ANSI((void (*)())); +void Clear_signals ANSI(()); +void Prolog ANSI((int, char* [])); +void Epilog ANSI((int)); +char *Get_current_dir ANSI(()); +int Set_dir ANSI((char*)); +char Get_switch_char ANSI(()); +FILE* Get_temp ANSI((char **, char *, int)); +FILE *Start_temp ANSI((char *, CELLPTR, char **)); +void Open_temp_error ANSI((char *, char *)); +void Link_temp ANSI((CELLPTR, FILE *, char *)); +void Close_temp ANSI((CELLPTR, FILE *)); +void Unlink_temp_files ANSI((CELLPTR)); +void Handle_result ANSI((int, int, int, CELLPTR)); +void Update_time_stamp ANSI((CELLPTR)); +int Remove_file ANSI((char *)); +void Parse ANSI((FILE *)); +int Get_line ANSI((char *, FILE *)); +char *Do_comment ANSI((char *, char **, int)); +char *Get_token ANSI((TKSTRPTR, char *, int)); +void Quit ANSI(()); +void Read_state ANSI(()); +void Write_state ANSI(()); +int Check_state ANSI((CELLPTR, STRINGPTR *, int)); +void Dump ANSI(()); +void Dump_recipe ANSI((STRINGPTR)); +int Parse_macro ANSI((char *, int)); +int Macro_op ANSI((char *)); +int Parse_rule_def ANSI((int *)); +int Rule_op ANSI((char *)); +void Add_recipe_to_list ANSI((char *, int, int)); +void Bind_rules_to_targets ANSI((int)); +int Set_group_attributes ANSI((char *)); +DFALINKPTR Match_dfa ANSI((char *)); +void Check_circle_dfa ANSI(()); +void Add_nfa ANSI((char *)); +char *Exec_function ANSI((char *)); +time_t seek_arch ANSI((char *, char *)); +int If_root_path ANSI((char *)); +void Remove_prq ANSI((CELLPTR)); +int runargv ANSI((CELLPTR, int, int, int, int, char *)); +int Wait_for_child ANSI((int, int)); +void Clean_up_processes ANSI(()); +time_t CacheStat ANSI((char *, int)); + +#endif diff --git a/dmake/unix/xenix/pwd/template.mk b/dmake/unix/xenix/pwd/template.mk new file mode 100644 index 000000000000..abd4066c347b --- /dev/null +++ b/dmake/unix/xenix/pwd/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= unix + OSRELEASE *:= xenix + OSENVIRONMENT *:= pwd diff --git a/dmake/unix/xenix/stdlib.h b/dmake/unix/xenix/stdlib.h new file mode 100644 index 000000000000..fe814c798a0b --- /dev/null +++ b/dmake/unix/xenix/stdlib.h @@ -0,0 +1,50 @@ +/* RCS $Id: stdlib.h,v 1.1.1.1 2000-09-22 15:33:36 hr Exp $ +-- +-- SYNOPSIS +-- stdlib interface +-- +-- DESCRIPTION +-- Specially needed pieces of interface to the standard C lib. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + + +#ifndef _STDLIB_INCLUDED_ +#define _STDLIB_INCLUDED_ + +extern /*GOTO*/ _exit(); +extern /*GOTO*/ exit(); +extern /*GOTO*/ abort(); +extern int system(); +extern char *getenv(); +extern char *calloc(); +extern char *malloc(); +extern char *realloc(); + +#ifndef _AIX +/* The AIX compiler dies on illegal redefinition of free */ +extern free(); +#endif + +extern int errno; + +#ifndef EIO +# include <errno.h> +#endif + +#endif /* _STDLIB_INCLUDED_ */ diff --git a/dmake/unix/xenix/template.mk b/dmake/unix/xenix/template.mk new file mode 100644 index 000000000000..7ab223fbdb9f --- /dev/null +++ b/dmake/unix/xenix/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= unix + OSRELEASE *:= xenix + OSENVIRONMENT *:= diff --git a/dmake/unix/xenix/time.h b/dmake/unix/xenix/time.h new file mode 100644 index 000000000000..c7102cfc18cb --- /dev/null +++ b/dmake/unix/xenix/time.h @@ -0,0 +1,32 @@ +/* RCS $Id: time.h,v 1.1.1.1 2000-09-22 15:33:36 hr Exp $ +-- +-- SYNOPSIS +-- time_t +-- +-- DESCRIPTION +-- Properly define time_t. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef TIME_h +#define TIME_h + +typedef long time_t; /* this is the thing we use */ + +#endif TIME_h + diff --git a/dmake/vextern.h b/dmake/vextern.h new file mode 100644 index 000000000000..84ded883d4c7 --- /dev/null +++ b/dmake/vextern.h @@ -0,0 +1,107 @@ +/* RCS $Id: vextern.h,v 1.1.1.1 2000-09-22 15:33:26 hr Exp $ +-- +-- SYNOPSIS +-- Global variable declarations. +-- +-- DESCRIPTION +-- Leave _DEFINE_GLOBALS_ undefined and the following declarations +-- will be defined as global variables, otherwise you get the +-- external declarations to the same global variables. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +/* These two are defined in dir/ruletab.c and dir/dirbrk.c, and are always + * imported as externals by the other code. Their defining modules do not + * #include this file. */ +extern char* DirBrkStr; /* pointer to value of macro DIRBRKSTR */ +extern char** Rule_tab; /* Builtin rules */ + +#ifndef _DEFINE_GLOBALS_ +#define EXTERN extern +#else +#define EXTERN +#endif + +EXTERN int Line_number; /* Current line number in make file parse */ +EXTERN t_attr Glob_attr; /* Global attrs to control global ops */ +EXTERN char* Makedir; /* pointer to macro value for MAKEDIR */ +EXTERN char* Shell; /* pointer to macro value for SHELL */ +EXTERN char* Shell_flags; /* pointer to macro value for SHELLFLAGS */ +EXTERN char* GShell; /* pointer to macro value for GROUPSHELL */ +EXTERN char* GShell_flags; /* pointer to macro value for GROUPFLAGS */ +EXTERN char* Shell_metas; /* pointer to macro value for SHELLMETAS */ +EXTERN char* Grp_suff; /* pointer to macro value for GROUPSUFFIX */ +EXTERN char* DirSepStr; /* pointer to macro value for DIRSEPSTR */ +EXTERN char* Pname; /* dmake process invoke name */ +EXTERN char* Pwd; /* current working dir, value of PWD */ +EXTERN char* Tmd; /* path to directory where dmake started */ +EXTERN char* Keep_state; /* current .KEEP_STATE file */ +EXTERN char* Escape_char; /* Current escape character */ +EXTERN char* LastMacName; /* Last macro successfully parsed */ +EXTERN char* UseDirCache; /* The value of .DIRCACHE */ +EXTERN char* DcacheRespCase; /* TRUE if we are to respect dcache case */ +EXTERN int Target; /* TRUE if target found in makefile */ +EXTERN int If_expand; /* TRUE if calling Expand from getinp.c */ +EXTERN int Suppress_temp_file;/* TRUE if doing a test in _exec_recipe*/ +EXTERN int Readenv; /* TRUE if defining macro from environment*/ +EXTERN int Makemkf; /* TRUE if making makefile(s) */ +EXTERN int Nest_level; /* Nesting level for .IF .ELSE .END ... */ +EXTERN int Prep; /* Value of macro PREP */ +EXTERN int Def_targets; /* TRUE if defining targets */ +EXTERN int Skip_to_eof; /* TRUE if asked to skip to eof on input */ +EXTERN int DynamicNestLevel;/* Value of DYNAMICNESTINGLEVEL macro */ +EXTERN int NameMax; /* The value of NAMEMAX */ + + +EXTERN CELLPTR Root; /* Root of the make graph */ +EXTERN CELLPTR Targets; /* Targets in makefile */ + +EXTERN CELLPTR Current_target; /* cell of current target being made */ +EXTERN int Wait_for_completion; +EXTERN int Doing_bang; +EXTERN int Packed_shell; /* TRUE if packed args to use a shell */ +EXTERN int Swap_on_exec; /* TRUE if going to swap on exec call */ +EXTERN int State; /* parser state */ +EXTERN int Group; /* parsing a group recipe ==> TRUE */ + +/* Command line option flags are defined here. They correspond one-for one + * with the flags defined in dmake.c */ + +EXTERN char *Augmake; /* -A */ +EXTERN char Comment; /* -c */ +EXTERN char Get_env; /* -e or -E */ +EXTERN char* Notabs; /* -B */ +EXTERN int Continue; /* -k */ +EXTERN int Force; /* -u */ +EXTERN int Listing; /* -p */ +EXTERN int Rules; /* -r */ +EXTERN int Trace; /* -n */ +EXTERN int Touch; /* -t */ +EXTERN int Check; /* -q */ +EXTERN uint16 Verbose; /* -v */ +EXTERN int Microsoft; /* -M */ +EXTERN int Transitive; /* -T */ +EXTERN int No_exec; /* -X */ + +EXTERN HASHPTR Defs[HASH_TABLE_SIZE]; +EXTERN HASHPTR Macs[HASH_TABLE_SIZE]; + +EXTERN char *Buffer; /* a general purpose buffer */ +EXTERN int Buffer_size; +EXTERN int Max_proclmt; /* limit of max # of conc procs */ +EXTERN int Max_proc; /* max # of conc procs */ diff --git a/dmake/win95/borland/bcc50/config.h b/dmake/win95/borland/bcc50/config.h new file mode 100644 index 000000000000..c39a4816f54f --- /dev/null +++ b/dmake/win95/borland/bcc50/config.h @@ -0,0 +1,44 @@ +/* RCS $Id: config.h,v 1.1.1.1 2000-09-22 15:33:36 hr Exp $ +-- +-- SYNOPSIS +-- Configurarion include file. +-- +-- DESCRIPTION +-- There is one of these for each specific machine configuration. +-- It can be used to further tweek the machine specific sources +-- so that they compile. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +/* define this for configurations that don't have the coreleft function + * so that the code compiles. To my knowledge coreleft exists only on + * Turbo C, but it is needed here since the function is used in many debug + * macros. */ +/*#define coreleft() 0L*/ +extern unsigned int coreleft(); + +#define SIGQUIT SIGBREAK /* turbo C doesn't understand SIGQUIT */ + +/* Turbo-C understands const declarations. */ +#define CONST const + +/* a small problem with pointer to voids on some unix machines needs this */ +#define PVOID void * + +/* Borland redefined the environment variable, sigh */ +#define environ _environ diff --git a/dmake/win95/borland/bcc50/config.mk b/dmake/win95/borland/bcc50/config.mk new file mode 100644 index 000000000000..b63cae1c1977 --- /dev/null +++ b/dmake/win95/borland/bcc50/config.mk @@ -0,0 +1,14 @@ +# Definition of macros for library, and C startup code. +osedir = $(osrdir)$(DIRSEPSTR)$(OSENVIRONMENT) + +# Change the CCROOT variable to reflect the installation directory of your +# C++ compiler. +.IMPORT .IGNORE : CCVER + +CCVER *:= c:/cc/borland/$(OSENVIRONMENT) + +# Definitions for compiles and links +CSTARTUP = $(CCVER)/lib/c0x32.obj +LDLIBS = $(CCVER)/lib/cw32 $(CCVER)/lib/import32 + +CFLAGS += -A- -w-pro -I$(osedir) diff --git a/dmake/win95/borland/bcc50/lib.rsp b/dmake/win95/borland/bcc50/lib.rsp new file mode 100644 index 000000000000..6b6ffb39dc4e --- /dev/null +++ b/dmake/win95/borland/bcc50/lib.rsp @@ -0,0 +1,2 @@ +c:\cc\borland\bcc50\lib\cw32+ +c:\cc\borland\bcc50\lib\import32 diff --git a/dmake/win95/borland/bcc50/mk.bat b/dmake/win95/borland/bcc50/mk.bat new file mode 100755 index 000000000000..1c77b3799df5 --- /dev/null +++ b/dmake/win95/borland/bcc50/mk.bat @@ -0,0 +1,96 @@ +md objects +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 infer.c +copy infer.obj objects +del infer.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 make.c +copy make.obj objects +del make.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 stat.c +copy stat.obj objects +del stat.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 expand.c +copy expand.obj objects +del expand.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 dmstring.c +copy dmstring.obj objects +del dmstring.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 hash.c +copy hash.obj objects +del hash.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 dag.c +copy dag.obj objects +del dag.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 dmake.c +copy dmake.obj objects +del dmake.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 path.c +copy path.obj objects +del path.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 imacs.c +copy imacs.obj objects +del imacs.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 sysintf.c +copy sysintf.obj objects +del sysintf.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 parse.c +copy parse.obj objects +del parse.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 getinp.c +copy getinp.obj objects +del getinp.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 quit.c +copy quit.obj objects +del quit.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 state.c +copy state.obj objects +del state.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 dmdump.c +copy dmdump.obj objects +del dmdump.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 macparse.c +copy macparse.obj objects +del macparse.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 rulparse.c +copy rulparse.obj objects +del rulparse.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 percent.c +copy percent.obj objects +del percent.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 function.c +copy function.obj objects +del function.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 win95\dchdir.c +copy dchdir.obj objects +del dchdir.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 win95\switchar.c +copy switchar.obj objects +del switchar.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 msdos\dstrlwr.c +copy dstrlwr.obj objects +del dstrlwr.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 msdos\arlib.c +copy arlib.obj objects +del arlib.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 msdos\dirbrk.c +copy dirbrk.obj objects +del dirbrk.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 win95\borland\tempnam.c +copy tempnam.obj objects +del tempnam.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 win95\borland\ruletab.c +copy ruletab.obj objects +del ruletab.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 win95\borland\utime.c +copy utime.obj objects +del utime.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 win95\borland\runargv.c +copy runargv.obj objects +del runargv.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 unix\dcache.c +copy dcache.obj objects +del dcache.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 unix\rmprq.c +copy rmprq.obj objects +del rmprq.obj +tlink32 @win95\borland\bcc50\obj.rsp,dmake.exe,NUL.MAP,@win95\borland\bcc50\lib.rsp +copy win95\borland\bcc50\template.mk startup\config.mk diff --git a/dmake/win95/borland/bcc50/obj.rsp b/dmake/win95/borland/bcc50/obj.rsp new file mode 100644 index 000000000000..0301270860f0 --- /dev/null +++ b/dmake/win95/borland/bcc50/obj.rsp @@ -0,0 +1,32 @@ +c:\cc\borland\bcc50\lib\c0x32.obj+ +objects\infer.obj+ +objects\make.obj+ +objects\stat.obj+ +objects\expand.obj+ +objects\dmstring.obj+ +objects\hash.obj+ +objects\dag.obj+ +objects\dmake.obj+ +objects\path.obj+ +objects\imacs.obj+ +objects\sysintf.obj+ +objects\parse.obj+ +objects\getinp.obj+ +objects\quit.obj+ +objects\state.obj+ +objects\dmdump.obj+ +objects\macparse.obj+ +objects\rulparse.obj+ +objects\percent.obj+ +objects\function.obj+ +objects\dchdir.obj+ +objects\switchar.obj+ +objects\dstrlwr.obj+ +objects\arlib.obj+ +objects\dirbrk.obj+ +objects\tempnam.obj+ +objects\ruletab.obj+ +objects\utime.obj+ +objects\runargv.obj+ +objects\dcache.obj+ +objects\rmprq.obj diff --git a/dmake/win95/borland/bcc50/public.h b/dmake/win95/borland/bcc50/public.h new file mode 100644 index 000000000000..26d5871102a4 --- /dev/null +++ b/dmake/win95/borland/bcc50/public.h @@ -0,0 +1,167 @@ +/* RCS $Id: public.h,v 1.1.1.1 2000-09-22 15:33:36 hr Exp $ +-- WARNING -- This file is AUTOMATICALLY GENERATED DO NOT EDIT IT +-- +-- +-- SYNOPSIS +-- Local functions exported to be visible by others. +-- +-- DESCRIPTION +-- This file is generated by 'genpub'. Function declarations +-- that appear in this file are extracted by 'genpub' from +-- source files. Any function in the source file whose definition +-- appears like: +-- +-- PUBLIC return_type +-- function( arg_list ); +-- type_expr1 arg1; +-- ... +-- +-- has its definition extracted and a line of the form: +-- +-- return_type function ANSI((type_expr1,type_expr2,...)); +-- +-- entered into the output file. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef _DMAKE_PUBLIC_h +#define _DMAKE_PUBLIC_h + +#ifdef EXTERN +#undef EXTERN +#endif +#if defined(DEFINE_DMAKE_VARIABLES) +#define EXTERN +#else +#define EXTERN extern +#endif + +/***** genpub: Begin list of generated function headers */ +void Infer_recipe ANSI((CELLPTR, CELLPTR)); +int Make_targets ANSI(()); +int Make ANSI((CELLPTR, CELLPTR)); +int Exec_commands ANSI((CELLPTR)); +void Print_cmnd ANSI((char *, int, int)); +int Push_dir ANSI((char *, char *, int)); +void Pop_dir ANSI((int)); +void Append_line ANSI((char *, int, FILE *, char *, int, int)); +void Stat_target ANSI((CELLPTR, int, int)); +char *Expand ANSI((char *)); +char *Apply_edit ANSI((char *, char *, char *, int, int)); +void Map_esc ANSI((char *)); +char* Apply_modifiers ANSI((int, char *)); +char* Tokenize ANSI((char *, char *, char, int)); +char* ScanToken ANSI((char *, char **, int)); +char *DmStrJoin ANSI((char *, char *, int, int)); +char *DmStrAdd ANSI((char *, char *, int)); +char *DmStrApp ANSI((char *, char *)); +char *DmStrDup ANSI((char *)); +char *DmStrDup2 ANSI((char *)); +char *DmStrPbrk ANSI((char *, char *)); +char *DmStrSpn ANSI((char *, char *)); +char *DmStrStr ANSI((char *, char *)); +char *DmSubStr ANSI((char *, char *)); +uint16 Hash ANSI((char *, uint32 *)); +HASHPTR Get_name ANSI((char *, HASHPTR *, int)); +HASHPTR Search_table ANSI((HASHPTR *, char *, uint16 *, uint32 *)); +HASHPTR Push_macro ANSI((HASHPTR)); +HASHPTR Pop_macro ANSI((HASHPTR)); +HASHPTR Def_macro ANSI((char *, char *, int)); +CELLPTR Def_cell ANSI((char *)); +LINKPTR Add_prerequisite ANSI((CELLPTR, CELLPTR, int, int)); +void Clear_prerequisites ANSI((CELLPTR)); +int Test_circle ANSI((CELLPTR, int)); +STRINGPTR Def_recipe ANSI((char *, STRINGPTR, int, int)); +t_attr Rcp_attribute ANSI((char *)); +void main ANSI((int, char **)); +FILE *Openfile ANSI((char *, int, int)); +FILE *Closefile ANSI(()); +FILE *Search_file ANSI((char *, char **)); +char *Filename ANSI(()); +int Nestlevel ANSI(()); +FILE *TryFiles ANSI((LINKPTR)); +void Fatal ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Error ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Warning ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void No_ram ANSI(()); +void Usage ANSI((int)); +void Version ANSI(()); +char *Get_suffix ANSI((char *)); +char *Basename ANSI((char *)); +char *Filedir ANSI((char *)); +char *Build_path ANSI((char *, char *)); +void Make_rules ANSI(()); +void Create_macro_vars ANSI(()); +time_t Do_stat ANSI((char *, char *, char **, int)); +int Do_touch ANSI((char *, char *, char **)); +void Void_lib_cache ANSI((char *, char *)); +time_t Do_time ANSI(()); +int Do_cmnd ANSI((char *, int, int, CELLPTR, int, int, int)); +char ** Pack_argv ANSI((int, int, char *)); +char *Read_env_string ANSI((char *)); +int Write_env_string ANSI((char *, char *)); +void ReadEnvironment ANSI(()); +void Catch_signals ANSI((void (*)())); +void Clear_signals ANSI(()); +void Prolog ANSI((int, char* [])); +void Epilog ANSI((int)); +char *Get_current_dir ANSI(()); +int Set_dir ANSI((char*)); +char Get_switch_char ANSI(()); +FILE* Get_temp ANSI((char **, char *, int)); +FILE *Start_temp ANSI((char *, CELLPTR, char **)); +void Open_temp_error ANSI((char *, char *)); +void Link_temp ANSI((CELLPTR, FILE *, char *)); +void Close_temp ANSI((CELLPTR, FILE *)); +void Unlink_temp_files ANSI((CELLPTR)); +void Handle_result ANSI((int, int, int, CELLPTR)); +void Update_time_stamp ANSI((CELLPTR)); +int Remove_file ANSI((char *)); +void Parse ANSI((FILE *)); +int Get_line ANSI((char *, FILE *)); +char *Do_comment ANSI((char *, char **, int)); +char *Get_token ANSI((TKSTRPTR, char *, int)); +void Quit ANSI(()); +void Read_state ANSI(()); +void Write_state ANSI(()); +int Check_state ANSI((CELLPTR, STRINGPTR *, int)); +void Dump ANSI(()); +void Dump_recipe ANSI((STRINGPTR)); +int Parse_macro ANSI((char *, int)); +int Macro_op ANSI((char *)); +int Parse_rule_def ANSI((int *)); +int Rule_op ANSI((char *)); +void Add_recipe_to_list ANSI((char *, int, int)); +void Bind_rules_to_targets ANSI((int)); +int Set_group_attributes ANSI((char *)); +DFALINKPTR Match_dfa ANSI((char *)); +void Check_circle_dfa ANSI(()); +void Add_nfa ANSI((char *)); +char *Exec_function ANSI((char *)); +int dchdir ANSI((char *)); +void dstrlwr ANSI((char *, char *)); +time_t seek_arch ANSI((char*, char*)); +int touch_arch ANSI((char*, char*)); +int If_root_path ANSI((char *)); +int runargv ANSI((CELLPTR, int, int, int, int, char *)); +int Wait_for_child ANSI((int, int)); +void Clean_up_processes ANSI(()); +time_t CacheStat ANSI((char *, int)); +void Remove_prq ANSI((CELLPTR)); + +#endif diff --git a/dmake/win95/borland/bcc50/template.mk b/dmake/win95/borland/bcc50/template.mk new file mode 100644 index 000000000000..b5095c40ce2a --- /dev/null +++ b/dmake/win95/borland/bcc50/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= win95 + OSRELEASE *:= borland + OSENVIRONMENT *:= bcc50 diff --git a/dmake/win95/borland/config.mk b/dmake/win95/borland/config.mk new file mode 100644 index 000000000000..8d5d69df5bd7 --- /dev/null +++ b/dmake/win95/borland/config.mk @@ -0,0 +1,51 @@ +# This is the Turbo C++ 2.0 DOS configuration file for DMAKE +# It simply modifies the values of SRC, and checks to see if +# OSENVIRONMENT is defined. If so it includes the appropriate +# config.mk file. +# +# It also sets the values of .SOURCE.c and .SOURCE.h to include the local +# directory. +# +osrdir := $(OS)$(DIRSEPSTR)$(OSRELEASE) + +# OS specific sources +OSR_SRC += tempnam.c ruletab.c +DOS_SRC += runargv.c rmprq.c + +SRC += $(OSR_SRC) $(DOS_SRC) +.SOURCE.h : $(osrdir) + +# Local configuration modifications for CFLAGS. Make sure your turboc.cfg +# file contains a -D__STDC__=1 and -DM_I86=1, if not then uncomment the line +# below! +#CFLAGS += -DM_I86=1 -D__STDC__=1 + +# You can get a smaller executable still, buy adding a -1 to the list of +# flags below, but then you can't run this on an 8086/88 cpu. +#CFLAGS += -1 +CFLAGS += -I$(osrdir) -d -O -N- -w-nod +ASFLAGS += -t -mx $(S_$(MODEL)) + +LDOBJS = $(CSTARTUP) $(OBJDIR)/{$(<:f)} +LDARGS = $(LDHEAD) @$(LDTMPOBJ),$(TARGET),NUL.MAP$(LDTAIL) +LDTAIL = $(_libs)$(LDFLAGS:s/ //) +_libs = $(!null,$(LDLIBS) ,@$(LDTMPLIB)) +LDTMPOBJ = $(mktmp,,$(DIVFILE) $(LDOBJS:s,/,\\,:t"+\n")\n) +LDTMPLIB = $(mktmp,,$(DIVFILE) $(LDLIBS:s,/,\\,:t"+\n")\n) + +# Debugging information for Turbo-C +DB_CFLAGS += -v +DB_LDFLAGS += /v + +# See if we modify anything in the lower levels. +.IF $(OSENVIRONMENT) != $(NULL) + .INCLUDE .IGNORE : $(osrdir)$(DIRSEPSTR)$(OSENVIRONMENT)$(DIRSEPSTR)config.mk +.END + +.SETDIR=$(osrdir) : $(OSR_SRC) +.SETDIR=msdos : $(DOS_SRC) + +S_s = -dmsmall +S_m = -dmmedium +S_c = -dmcompact +S_l = -dmlarge diff --git a/dmake/win95/borland/ruletab.c b/dmake/win95/borland/ruletab.c new file mode 100644 index 000000000000..04aab804b587 --- /dev/null +++ b/dmake/win95/borland/ruletab.c @@ -0,0 +1,44 @@ +/* RCS $Id: ruletab.c,v 1.1.1.1 2000-09-22 15:33:36 hr Exp $ +-- +-- SYNOPSIS +-- Default initial configuration of dmake. +-- +-- DESCRIPTION +-- Define here the initial set of rules that are defined before +-- dmake performs any processing. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +/* These are control macros for dmake that MUST be defined at some point + * if they are NOT dmake will not work! These are default definitions. They + * may be overridden inside the .STARTUP makefile, they are here + * strictly so that dmake can parse the STARTUP makefile */ + +#include <stdio.h> + +static char *_rules[] = { + "MAXLINELENGTH := 2046", + "MAXPROCESSLIMIT := 4", + ".IMPORT .IGNORE: ROOTDIR", + ".MAKEFILES : makefile.mk makefile", + ".SOURCE : .NULL", +#include "startup.h" + (char *)NULL }; + +char **Rule_tab = _rules; /* for sundry reasons in Get_environment() */ + diff --git a/dmake/win95/borland/sysintf.h b/dmake/win95/borland/sysintf.h new file mode 100644 index 000000000000..bae67b65e967 --- /dev/null +++ b/dmake/win95/borland/sysintf.h @@ -0,0 +1,56 @@ +/* RCS $Id: sysintf.h,v 1.1.1.1 2000-09-22 15:33:36 hr Exp $ +-- +-- SYNOPSIS +-- Interfaces for sysintf.c +-- +-- DESCRIPTION +-- Abstractions of functions in sysintf.c +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#define DMSTAT stat +#define VOID_LCACHE(l,m) +#define GETPID _psp +#define Hook_std_writes(A) +#define DMSTRLWR(A,B) dstrlwr((A),(B)) + +extern char * tempnam(); +extern char * getcwd(); + +/* +** standard C items +*/ + +/* +** DOS interface standard items +*/ +#define chdir(p) dchdir(p) +#define CacheStat(A,B) really_dostat(A,&buf) + +/* +** make parameters +*/ +#ifdef _POSIX_NAME_MAX +#undef _POSIX_NAME_MAX +#endif +#define _POSIX_NAME_MAX 12 + +#ifdef _POSIX_PATH_MAX +#undef _POSIX_PATH_MAX +#endif +#define _POSIX_PATH_MAX 64 diff --git a/dmake/win95/borland/tempnam.c b/dmake/win95/borland/tempnam.c new file mode 100644 index 000000000000..cb1bd9f5eb53 --- /dev/null +++ b/dmake/win95/borland/tempnam.c @@ -0,0 +1,114 @@ +/* RCS $Id: tempnam.c,v 1.1.1.1 2000-09-22 15:33:36 hr Exp $ +-- +-- SYNOPSIS +-- tempnam +-- +-- DESCRIPTION +-- temp file name generation routines. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +/*LINTLIBRARY*/ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <dos.h> + +#if defined(max) +# undef max +#endif +#define max(A,B) (((A)<(B))?(B):(A)) + +extern char *mktemp(); +extern int access(); +int d_access(); + +/* Turbo C stdio.h doesn't define P_tmpdir, so let's do it here */ +/* Under DOS leave the default tmpdir pointing here! */ +#ifndef P_tmpdir +static char *P_tmpdir = ""; +#endif + +char * +tempnam(dir, prefix) +char *dir; /* use this directory please (if non-NULL) */ +char *prefix; /* use this (if non-NULL) as filename prefix */ +{ + static int count = 0; + register char *p, *q, *tmpdir; + int tl=0, dl=0, pl; + char buf[30]; + +#if defined(__WIN32__) + unsigned int _psp = rand(); +#endif + + pl = strlen(P_tmpdir); + + if( (tmpdir = getenv("TMPDIR")) != NULL ) tl = strlen(tmpdir); + else if( (tmpdir = getenv("TMP")) != NULL ) tl = strlen(tmpdir); + if( dir != NULL ) dl = strlen(dir); + + if( (p = malloc((unsigned)(max(max(dl,tl),pl)+13))) == NULL ) + return(NULL); + + *p = '\0'; + + if( (tl == 0) || (d_access( strcpy(p, tmpdir), 0) != 0) ) + if( (dl == 0) || (d_access( strcpy(p, dir), 0) != 0) ) + if( d_access( strcpy(p, P_tmpdir), 0) != 0 ) + if( !prefix ) + prefix = "tp"; + + if(prefix) + { + *(p+strlen(p)+2) = '\0'; + (void)strncat(p, prefix, 2); + } + + sprintf( buf, "%08x", _psp ); + buf[6]='\0'; + (void)strcat(p, buf ); + sprintf( buf, "%04d", count++ ); + q=p+strlen(p)-6; + *q++ = buf[0]; *q++ = buf[1]; + *q++ = buf[2]; *q = buf[3]; + + if( (q = strrchr(p,'.')) != NULL ) *q = '\0'; + + return(p); +} + + + +d_access( name, flag ) +char *name; +int flag; +{ + extern char *DirSepStr; + char *p; + int r; + + if( name == NULL || !*name ) return(1); /* NULL dir means current dir */ + r = access( name, flag ); + p = name+strlen(name)-1; + + if(*p != '/' && *p != '\\') strcat( p, DirSepStr ); + + return( r ); +} diff --git a/dmake/win95/config.mk b/dmake/win95/config.mk new file mode 100644 index 000000000000..721be05b00f4 --- /dev/null +++ b/dmake/win95/config.mk @@ -0,0 +1,53 @@ +# This is an OS specific configuration file +# It assumes that OBJDIR, TARGET and DEBUG are previously defined. +# It defines CFLAGS, LDARGS, CPPFLAGS, STARTUPFILE, LDOBJS +# It augments SRC, OBJDIR, TARGET, CFLAGS, LDLIBS +# + +# Memory model to compile for +# set to s - small, m - medium, c - compact, l - large +# Need large model now, dmake has grown up :-) +MODEL = l + +STARTUPFILE = startup/startup.mk + +CPPFLAGS = $(CFLAGS) + +# Debug flags +DB_CFLAGS = -DDBUG +DB_LDFLAGS = +DB_LDLIBS = + +# NO Debug flags +NDB_CFLAGS = +NDB_LDFLAGS = +NDB_LDLIBS = + +# Local configuration modifications for CFLAGS. +CFLAGS += -I$(OS) + +# Common Win32 source files. +OS_SRC += dchdir.c switchar.c + +# Imported MSDOS Files. +DOSSRC += dstrlwr.c arlib.c dirbrk.c + +SRC += $(OS_SRC) $(UNIXSRC) $(DOSSRC) + +# Provide our own %$O : %$S rule. +%$O : %$S + +$(AS) $(ASFLAGS) \ + $(<:s,\,${__.DIVSEP-sh-${USESHELL}},:s,/,${__.DIVSEP-sh-${USESHELL}},); + mv $(@:f) $(OBJDIR) + +# Set source dirs so that we can find files named in this +# config file. +.SOURCE.h : $(OS) + +# See if we modify anything in the lower levels. +.IF $(OSRELEASE) != $(NULL) + .INCLUDE : $(OS)$(DIRSEPSTR)$(OSRELEASE)$(DIRSEPSTR)config.mk +.END + +.SETDIR=msdos : $(DOSSRC) +.SETDIR=$(OS) : $(ASRC) $(OS_SRC) diff --git a/dmake/win95/dchdir.c b/dmake/win95/dchdir.c new file mode 100644 index 000000000000..dab1d7163ede --- /dev/null +++ b/dmake/win95/dchdir.c @@ -0,0 +1,49 @@ +/* RCS $Id: dchdir.c,v 1.1.1.1 2000-09-22 15:33:36 hr Exp $ +-- +-- SYNOPSIS +-- Change directory. +-- +-- DESCRIPTION +-- Under DOS change the current drive as well as the current directory. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#if 0 +#include <dir.h> +#endif +#include <direct.h> +#include "extern.h" + +PUBLIC int +dchdir(path) +char *path; +{ + int res; + + res = chdir(path); + + if (res != -1 && path[1] == ':') { + unsigned new_drive; + + /* for WIN32 just use the _chdrive library call */ + new_drive = (*path & ~0x20) - 'A' + 1; + _chdrive(new_drive); + } + + return (res); +} diff --git a/dmake/win95/microsft/config.h b/dmake/win95/microsft/config.h new file mode 100644 index 000000000000..862b1d5b181c --- /dev/null +++ b/dmake/win95/microsft/config.h @@ -0,0 +1,78 @@ +/* RCS $Id: config.h,v 1.1.1.1 2000-09-22 15:33:36 hr Exp $ +-- +-- SYNOPSIS +-- Configurarion include file. +-- +-- DESCRIPTION +-- There is one of these for each specific machine configuration. +-- It can be used to further tweek the machine specific sources +-- so that they compile. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#if defined (_MSC_VER) +# if _MSC_VER < 500 + Force a compile-time blowup. + Do not define "#define _MSC_VER" for MSC compilers earlier than 5.0. +# endif +#endif + +/* define this for configurations that don't have the coreleft function + * so that the code compiles. To my knowledge coreleft exists only on + * Turbo C, but it is needed here since the function is used in many debug + * macros. */ +#define coreleft() 0L + +/* MSC Version 4.0 doesn't understand SIGTERM, later versions do. */ +#ifndef SIGTERM +# define SIGTERM SIGINT +#endif + +/* Fixes unimplemented line buffering for MSC 5.x and 6.0. + * MSC _IOLBF is the same as _IOFBF + */ +#if defined(MSDOS) && defined (_MSC_VER) +# undef _IOLBF +# define _IOLBF _IONBF +#endif + +/* in alloc.h: size_t is redefined + * defined in stdio.h which is included by alloc.h + */ +#if defined(MSDOS) && defined (_MSC_VER) +# define _TYPES_ +#endif + +/* in sysintf.c: SIGQUIT is used, this is not defined in MSC */ +#ifndef SIGQUIT +# define SIGQUIT SIGTERM +#endif + +/* MSC doesn't seem to care about CONST */ +#define CONST + +#ifndef MSDOS +# define MSDOS 1 +#endif + +/* a small problem with pointer to voids on some unix machines needs this */ +#define PVOID void * + +/* Use my own tempnam */ +#define tempnam dtempnam + diff --git a/dmake/win95/microsft/config.mk b/dmake/win95/microsft/config.mk new file mode 100644 index 000000000000..352eed716d2f --- /dev/null +++ b/dmake/win95/microsft/config.mk @@ -0,0 +1,61 @@ +# This is the MSC 4.0 and higher DOS configuration file for DMAKE +# It simply modifies the values of SRC, and checks to see if +# OSENVIRONMENT is defined. If so it includes the appropriate +# config.mk file. +# +# It also sets the values of .SOURCE.c and .SOURCE.h to include the local +# directory. +# +osrdir := $(OS)$(DIRSEPSTR)$(OSRELEASE) + +TMPDIR := +.EXPORT : TMPDIR + +# Definition of macros for library, and C startup code. + +# The following sources are required for MSC +OSR_SRC += tempnam.c ruletab.c +DOS_SRC += runargv.c rmprq.c + +.SETDIR=$(osrdir) : $(OSR_SRC) +.SETDIR=msdos : $(DOS_SRC) + +SRC += $(OSR_SRC) $(DOS_SRC) +.SOURCE.h : $(osrdir) + +SET_STACK = /stack:4096 +ASFLAGS += -t -mx $(S_$(MODEL)) + +# Microsoft C doesn't need tail but needs head +LDTAIL != +LDHEAD != $(LDFLAGS) +LDARGS != $(LDHEAD) -out:$(TARGET) @$(LDTMPOBJ) $(LDTAIL) +LDTAIL != $(_libs) +_libs != $(!null,$(LDLIBS) ,@$(LDTMPLIB)) +LDTMPOBJ != $(mktmp,,$(DIVFILE) $(LDOBJS:s,/,\\,:t"\n")\n) +LDTMPLIB != $(mktmp,,$(DIVFILE) $(LDLIBS:s,/,\\,:t"\n")\n) + +# Debugging libraries and flags +DB_LDFLAGS += /nologo /co /li /map +DB_LDLIBS += +DB_CFLAGS += -Zi + +# NO Debug MSC flags: +# Set the environment variable MSC_VER to be one of 5.1, 6.0, 8.0 (for VC++4.0) +# to get these by default when you make dmake using 'dmake'. +# + +NDB_LDFLAGS += /nologo +CFLAGS += -I$(osrdir) + +# See if we modify anything in the lower levels. +.IF $(OSENVIRONMENT) != $(NULL) + .INCLUDE .IGNORE : $(osrdir)$(DIRSEPSTR)$(OSENVIRONMENT)$(DIRSEPSTR)config.mk +.END + +CFLAGS += /nologo + +S_s = -Dmsmall +S_m = -Dmmedium +S_c = -Dmcompact +S_l = -Dmlarge diff --git a/dmake/win95/microsft/optoff.h b/dmake/win95/microsft/optoff.h new file mode 100644 index 000000000000..019605931851 --- /dev/null +++ b/dmake/win95/microsft/optoff.h @@ -0,0 +1,27 @@ +/* RCS $Id: optoff.h,v 1.1.1.1 2000-09-22 15:33:36 hr Exp $ +-- +-- SYNOPSIS +-- Turn off microsoft loop optimization. +-- +-- DESCRIPTION +-- This is broken in some pre 600 compilers so just turn it off. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ +#if _MSC_VER < 600 +# pragma loop_opt(off) +#endif diff --git a/dmake/win95/microsft/ruletab.c b/dmake/win95/microsft/ruletab.c new file mode 100644 index 000000000000..353e1eb7802e --- /dev/null +++ b/dmake/win95/microsft/ruletab.c @@ -0,0 +1,45 @@ +/* RCS $Id: ruletab.c,v 1.1.1.1 2000-09-22 15:33:36 hr Exp $ +-- +-- SYNOPSIS +-- Default initial configuration of dmake. +-- +-- DESCRIPTION +-- Define here the initial set of rules that are defined before +-- dmake performs any processing. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +/* These are control macros for dmake that MUST be defined at some point + * if they are NOT dmake will not work! These are default definitions. They + * may be overridden inside the .STARTUP makefile, they are here + * strictly so that dmake can parse the STARTUP makefile */ + +#include <stdio.h> + +static char *_rules[] = { + "MAXLINELENGTH := 2046", + "MAXPROCESSLIMIT := 4", + "MAXPROCESS := 1", + ".IMPORT .IGNORE: DMAKEROOT SOLARVER UPD INPATH OS UPDMINOREXT", + ".MAKEFILES : makefile.mk makefile", + ".SOURCE : .NULL", +#include "startup.h" + (char *)NULL }; + +char **Rule_tab = _rules; /* for sundry reasons in Get_environment() */ + diff --git a/dmake/win95/microsft/sysintf.h b/dmake/win95/microsft/sysintf.h new file mode 100644 index 000000000000..426be8c6059d --- /dev/null +++ b/dmake/win95/microsft/sysintf.h @@ -0,0 +1,58 @@ +/* RCS $Id: sysintf.h,v 1.1.1.1 2000-09-22 15:33:37 hr Exp $ +-- +-- SYNOPSIS +-- Interfaces for sysintf.c +-- +-- DESCRIPTION +-- Abstractions of functions in sysintf.c +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#define DMSTAT stat +#define VOID_LCACHE(l,m) +#define GETPID _psp +#define Hook_std_writes(A) +#define DMSTRLWR(A,B) dstrlwr((A),(B)) + +extern char * tempnam(); +extern char * getcwd(); + +/* for directory cache */ +#define CacheStat(A,B) really_dostat(A,&buf) + +/* +** standard C items +*/ + +/* +** DOS interface standard items +*/ +#define chdir(p) dchdir(p) + +/* +** make parameters +*/ +#ifdef _POSIX_NAME_MAX +#undef _POSIX_NAME_MAX +#endif +#define _POSIX_NAME_MAX 12 + +#ifdef _POSIX_PATH_MAX +#undef _POSIX_PATH_MAX +#endif +#define _POSIX_PATH_MAX _MAX_PATH diff --git a/dmake/win95/microsft/tempnam.c b/dmake/win95/microsft/tempnam.c new file mode 100644 index 000000000000..c3a8fa140f29 --- /dev/null +++ b/dmake/win95/microsft/tempnam.c @@ -0,0 +1,110 @@ +/* RCS $Id: tempnam.c,v 1.1.1.1 2000-09-22 15:33:37 hr Exp $ +-- +-- SYNOPSIS +-- tempnam +-- +-- DESCRIPTION +-- temp file name generation routines. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +/*LINTLIBRARY*/ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <process.h> + +#if defined(max) +# undef max +#endif +#define max(A,B) (((A)<(B))?(B):(A)) + +extern char *mktemp(); +extern int access(); +int d_access(); + +/* MSC stdio.h defines P_tmpdir, so let's undo it here */ +/* Under DOS leave the default tmpdir pointing here! */ +#ifdef P_tmpdir +#undef P_tmpdir +#endif +static char *P_tmpdir = ""; + +char * +dtempnam(dir, prefix) +char *dir; /* use this directory please (if non-NULL) */ +char *prefix; /* use this (if non-NULL) as filename prefix */ +{ + static int count = 0; + register char *p, *q, *tmpdir; + int tl=0, dl=0, pl; + char buf[30]; + + pl = strlen(P_tmpdir); + + if( (tmpdir = getenv("TMPDIR")) != NULL ) tl = strlen(tmpdir); + else if( (tmpdir = getenv("TMP")) != NULL ) tl = strlen(tmpdir); + if( dir != NULL ) dl = strlen(dir); + + if( (p = malloc((unsigned)(max(max(dl,tl),pl)+13))) == NULL ) + return(NULL); + + *p = '\0'; + + if( (tl == 0) || (d_access( strcpy(p, tmpdir), 0) != 0) ) + if( (dl == 0) || (d_access( strcpy(p, dir), 0) != 0) ) + if( d_access( strcpy(p, P_tmpdir), 0) != 0 ) + if( !prefix ) + prefix = "tp"; + + if(prefix) + { + *(p+strlen(p)+2) = '\0'; + (void)strncat(p, prefix, 2); + } + + sprintf( buf, "%08x", getpid() ); + buf[6]='\0'; + (void)strcat(p, buf ); + sprintf( buf, "%04d", count++ ); + q=p+strlen(p)-6; + *q++ = buf[0]; *q++ = buf[1]; + *q++ = buf[2]; *q++ = buf[3]; + + if( (q = strrchr(p,'.')) != NULL ) *q = '\0'; + + return(p); +} + + + +d_access( name, flag ) +char *name; +int flag; +{ + extern char *DirSepStr; + char *p; + int r; + + if( name == NULL || !*name ) return(1); /* NULL dir means current dir */ + r = access( name, flag ); + p = name+strlen(name)-1; + if(*p != '/' && *p != '\\') strcat( p, DirSepStr ); + + return( r ); +} diff --git a/dmake/win95/microsft/vpp40/config.mk b/dmake/win95/microsft/vpp40/config.mk new file mode 100644 index 000000000000..14fe952eac00 --- /dev/null +++ b/dmake/win95/microsft/vpp40/config.mk @@ -0,0 +1,14 @@ +# Definition of macros for library, and C startup code. +osedir = $(osrdir)$(DIRSEPSTR)$(OSENVIRONMENT) + +.IMPORT .IGNORE : MSC_VER +MSC_VER *= 8.0 + +CFLAGS += -I$(osedir) + +NDB_CFLAGS += -Od -GF -Ge +NDB_LDFLAGS += +NDB_LDLIBS += + +# Redefine rule for making our objects, we don't need mv +%$O : %.c ;% $(CC) -c $(CFLAGS) -Fo$@ $< diff --git a/dmake/win95/microsft/vpp40/lib.rsp b/dmake/win95/microsft/vpp40/lib.rsp new file mode 100644 index 000000000000..8b137891791f --- /dev/null +++ b/dmake/win95/microsft/vpp40/lib.rsp @@ -0,0 +1 @@ + diff --git a/dmake/win95/microsft/vpp40/mk.bat b/dmake/win95/microsft/vpp40/mk.bat new file mode 100755 index 000000000000..b1f73ba7e18f --- /dev/null +++ b/dmake/win95/microsft/vpp40/mk.bat @@ -0,0 +1,37 @@ +if "%1" != "" goto link +md objects +cl -c %c_flg -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\infer.obj infer.c +cl -c %c_flg -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\make.obj make.c +cl -c %c_flg -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\stat.obj stat.c +cl -c %c_flg -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\expand.obj expand.c +cl -c %c_flg -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\dmstring.obj dmstring.c +cl -c %c_flg -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\hash.obj hash.c +cl -c %c_flg -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\dag.obj dag.c +cl -c %c_flg -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\dmake.obj dmake.c +cl -c %c_flg -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\path.obj path.c +cl -c %c_flg -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\imacs.obj imacs.c +cl -c %c_flg -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\sysintf.obj sysintf.c +cl -c %c_flg -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\parse.obj parse.c +cl -c %c_flg -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\getinp.obj getinp.c +cl -c %c_flg -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\quit.obj quit.c +cl -c %c_flg -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\state.obj state.c +cl -c %c_flg -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\dmdump.obj dmdump.c +cl -c %c_flg -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\macparse.obj macparse.c +cl -c %c_flg -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\rulparse.obj rulparse.c +cl -c %c_flg -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\percent.obj percent.c +cl -c %c_flg -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\function.obj function.c +cl -c %c_flg -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\dchdir.obj win95\dchdir.c +cl -c %c_flg -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\switchar.obj win95\switchar.c +cl -c %c_flg -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\dstrlwr.obj msdos\dstrlwr.c +cl -c %c_flg -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\arlib.obj msdos\arlib.c +cl -c %c_flg -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\dirbrk.obj msdos\dirbrk.c +cl -c %c_flg -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\tempnam.obj tempnam.c +cl -c %c_flg -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\ruletab.obj win95\microsft\ruletab.c +cl -c %c_flg -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\runargv.obj msdos\runargv.c +cl -c %c_flg -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\rmprq.obj msdos\rmprq.c + +:link +rem link /nologo /out:dmake.exe @fix95nt\win95\microsft\vpp40\obj.rsp +if "%c_flg" == "" link /out:dmake.exe @.\win95\microsft\vpp40\obj.rsp +if "%c_flg" != "" link /DEBUG:notmapped,full /DEBUGTYPE:cv /PDB:NONE /out:dmake.exe @.\win95\microsft\vpp40\obj.rsp +copy win95\microsft\vpp40\template.mk startup\config.mk diff --git a/dmake/win95/microsft/vpp40/obj.rsp b/dmake/win95/microsft/vpp40/obj.rsp new file mode 100644 index 000000000000..e9e03972b791 --- /dev/null +++ b/dmake/win95/microsft/vpp40/obj.rsp @@ -0,0 +1,29 @@ +objects\infer.obj +objects\make.obj +objects\stat.obj +objects\expand.obj +objects\dmstring.obj +objects\hash.obj +objects\dag.obj +objects\dmake.obj +objects\path.obj +objects\imacs.obj +objects\sysintf.obj +objects\parse.obj +objects\getinp.obj +objects\quit.obj +objects\state.obj +objects\dmdump.obj +objects\macparse.obj +objects\rulparse.obj +objects\percent.obj +objects\function.obj +objects\dchdir.obj +objects\switchar.obj +objects\dstrlwr.obj +objects\arlib.obj +objects\dirbrk.obj +objects\tempnam.obj +objects\ruletab.obj +objects\runargv.obj +objects\rmprq.obj diff --git a/dmake/win95/microsft/vpp40/public.h b/dmake/win95/microsft/vpp40/public.h new file mode 100644 index 000000000000..f867838344c5 --- /dev/null +++ b/dmake/win95/microsft/vpp40/public.h @@ -0,0 +1,166 @@ +/* RCS $Id: public.h,v 1.1.1.1 2000-09-22 15:33:37 hr Exp $ +-- WARNING -- This file is AUTOMATICALLY GENERATED DO NOT EDIT IT +-- +-- +-- SYNOPSIS +-- Local functions exported to be visible by others. +-- +-- DESCRIPTION +-- This file is generated by 'genpub'. Function declarations +-- that appear in this file are extracted by 'genpub' from +-- source files. Any function in the source file whose definition +-- appears like: +-- +-- PUBLIC return_type +-- function( arg_list ); +-- type_expr1 arg1; +-- ... +-- +-- has its definition extracted and a line of the form: +-- +-- return_type function ANSI((type_expr1,type_expr2,...)); +-- +-- entered into the output file. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef _DMAKE_PUBLIC_h +#define _DMAKE_PUBLIC_h + +#ifdef EXTERN +#undef EXTERN +#endif +#if defined(DEFINE_DMAKE_VARIABLES) +#define EXTERN +#else +#define EXTERN extern +#endif + +/***** genpub: Begin list of generated function headers */ +void Infer_recipe ANSI((CELLPTR, CELLPTR)); +int Make_targets ANSI(()); +int Make ANSI((CELLPTR, CELLPTR)); +int Exec_commands ANSI((CELLPTR)); +void Print_cmnd ANSI((char *, int, int)); +int Push_dir ANSI((char *, char *, int)); +void Pop_dir ANSI((int)); +void Append_line ANSI((char *, int, FILE *, char *, int, int)); +void Stat_target ANSI((CELLPTR, int, int)); +char *Expand ANSI((char *)); +char *Apply_edit ANSI((char *, char *, char *, int, int)); +void Map_esc ANSI((char *)); +char* Apply_modifiers ANSI((int, char *)); +char* Tokenize ANSI((char *, char *, char, int)); +char* ScanToken ANSI((char *, char **, int)); +char *DmStrJoin ANSI((char *, char *, int, int)); +char *DmStrAdd ANSI((char *, char *, int)); +char *DmStrApp ANSI((char *, char *)); +char *DmStrDup ANSI((char *)); +char *DmStrDup2 ANSI((char *)); +char *DmStrPbrk ANSI((char *, char *)); +char *DmStrSpn ANSI((char *, char *)); +char *DmStrStr ANSI((char *, char *)); +char *DmSubStr ANSI((char *, char *)); +uint16 Hash ANSI((char *, uint32 *)); +HASHPTR Get_name ANSI((char *, HASHPTR *, int)); +HASHPTR Search_table ANSI((HASHPTR *, char *, uint16 *, uint32 *)); +HASHPTR Push_macro ANSI((HASHPTR)); +HASHPTR Pop_macro ANSI((HASHPTR)); +HASHPTR Def_macro ANSI((char *, char *, int)); +CELLPTR Def_cell ANSI((char *)); +LINKPTR Add_prerequisite ANSI((CELLPTR, CELLPTR, int, int)); +void Clear_prerequisites ANSI((CELLPTR)); +int Test_circle ANSI((CELLPTR, int)); +STRINGPTR Def_recipe ANSI((char *, STRINGPTR, int, int)); +t_attr Rcp_attribute ANSI((char *)); +void main ANSI((int, char **)); +FILE *Openfile ANSI((char *, int, int)); +FILE *Closefile ANSI(()); +FILE *Search_file ANSI((char *, char **)); +char *Filename ANSI(()); +int Nestlevel ANSI(()); +FILE *TryFiles ANSI((LINKPTR)); +void Fatal ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Error ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Warning ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void No_ram ANSI(()); +void Usage ANSI((int)); +void Version ANSI(()); +char *Get_suffix ANSI((char *)); +char *Basename ANSI((char *)); +char *Filedir ANSI((char *)); +char *Build_path ANSI((char *, char *)); +void Make_rules ANSI(()); +void Create_macro_vars ANSI(()); +time_t Do_stat ANSI((char *, char *, char **, int)); +int Do_touch ANSI((char *, char *, char **)); +void Void_lib_cache ANSI((char *, char *)); +time_t Do_time ANSI(()); +int Do_cmnd ANSI((char *, int, int, CELLPTR, int, int, int)); +char ** Pack_argv ANSI((int, int, char *)); +char *Read_env_string ANSI((char *)); +int Write_env_string ANSI((char *, char *)); +void ReadEnvironment ANSI(()); +void Catch_signals ANSI((void (*)())); +void Clear_signals ANSI(()); +void Prolog ANSI((int, char* [])); +void Epilog ANSI((int)); +char *Get_current_dir ANSI(()); +int Set_dir ANSI((char*)); +char Get_switch_char ANSI(()); +FILE* Get_temp ANSI((char **, char *, int)); +FILE *Start_temp ANSI((char *, CELLPTR, char **)); +void Open_temp_error ANSI((char *, char *)); +void Link_temp ANSI((CELLPTR, FILE *, char *)); +void Close_temp ANSI((CELLPTR, FILE *)); +void Unlink_temp_files ANSI((CELLPTR)); +void Handle_result ANSI((int, int, int, CELLPTR)); +void Update_time_stamp ANSI((CELLPTR)); +int Remove_file ANSI((char *)); +void Parse ANSI((FILE *)); +int Get_line ANSI((char *, FILE *)); +char *Do_comment ANSI((char *, char **, int)); +char *Get_token ANSI((TKSTRPTR, char *, int)); +void Quit ANSI(()); +void Read_state ANSI(()); +void Write_state ANSI(()); +int Check_state ANSI((CELLPTR, STRINGPTR *, int)); +void Dump ANSI(()); +void Dump_recipe ANSI((STRINGPTR)); +int Parse_macro ANSI((char *, int)); +int Macro_op ANSI((char *)); +int Parse_rule_def ANSI((int *)); +int Rule_op ANSI((char *)); +void Add_recipe_to_list ANSI((char *, int, int)); +void Bind_rules_to_targets ANSI((int)); +int Set_group_attributes ANSI((char *)); +DFALINKPTR Match_dfa ANSI((char *)); +void Check_circle_dfa ANSI(()); +void Add_nfa ANSI((char *)); +char *Exec_function ANSI((char *)); +int dchdir ANSI((char *)); +void dstrlwr ANSI((char *, char *)); +time_t seek_arch ANSI((char*, char*)); +int touch_arch ANSI((char*, char*)); +int If_root_path ANSI((char *)); +int runargv ANSI((CELLPTR, int, int, int, int, char *)); +void Clean_up_processes ANSI(()); +int Wait_for_child ANSI((int, int)); +void Remove_prq ANSI((CELLPTR)); + +#endif diff --git a/dmake/win95/microsft/vpp40/runargv.c b/dmake/win95/microsft/vpp40/runargv.c new file mode 100644 index 000000000000..fd0cbe355109 --- /dev/null +++ b/dmake/win95/microsft/vpp40/runargv.c @@ -0,0 +1,290 @@ +Blake sent me the wrong one. + +/* RCS $Id: runargv.c,v 1.1.1.1 2000-09-22 15:33:37 hr Exp $ +-- +-- SYNOPSIS +-- Invoke a sub process. +-- +-- DESCRIPTION +-- Use the standard methods of executing a sub process. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include <process.h> +#include <errno.h> +#include <signal.h> +#include "extern.h" +#include "sysintf.h" + +extern char **environ; + +typedef struct prp { + char *prp_cmd; + int prp_group; + int prp_ignore; + int prp_last; + int prp_shell; + struct prp *prp_next; +} RCP, *RCPPTR; + +typedef struct pr { + int pr_valid; + int pr_pid; + CELLPTR pr_target; + int pr_ignore; + int pr_last; + RCPPTR pr_recipe; + RCPPTR pr_recipe_end; + char *pr_dir; +} PR; + +static PR *_procs = NIL(PR); +static int _proc_cnt = 0; +static int _abort_flg= FALSE; +static int _use_i = -1; +static int _do_upd = 0; + +static void _add_child ANSI((int, CELLPTR, int, int)); +static void _attach_cmd ANSI((char *, int, int, CELLPTR, int, int)); +static void _finished_child ANSI((int, int)); +static int _running ANSI((CELLPTR)); + +PUBLIC int +runargv(target, ignore, group, last, shell, cmd) +CELLPTR target; +int ignore; +int group; +int last; +int shell; +char *cmd; +{ + extern int errno; + extern char *sys_errlist[]; + int pid; + char **argv; + + if( _running(target) /*&& Max_proc != 1*/ ) { + /* The command will be executed when the previous recipe + * line completes. */ + _attach_cmd( cmd, group, ignore, target, last, shell ); + return(1); + } + + while( _proc_cnt == Max_proc ) + if( Wait_for_child(FALSE, -1) == -1 ) Fatal( "Lost a child %d", errno ); + + argv = Pack_argv( group, shell, cmd ); + + pid = _spawnvpe(_P_NOWAIT, argv[0], argv, environ); + if (pid == -1) { /* failed */ + Error("%s: %s", argv[0], sys_errlist[errno]); + Handle_result(-1, ignore, _abort_flg, target); + return(-1); + } else + _add_child(pid, target, ignore, last); + + return(1); +} + + +PUBLIC int +Wait_for_child( abort_flg, pid ) +int abort_flg; +int pid; +{ + int wid; + int status; + int waitchild; + + waitchild = (pid == -1)? FALSE : Wait_for_completion; + + do { + if( (wid = wait(&status)) == -1 ) return(-1); + + _abort_flg = abort_flg; + _finished_child(wid, status); + _abort_flg = FALSE; + } while( waitchild && pid != wid ); + + return(0); +} + + +PUBLIC void +Clean_up_processes() +{ + register int i; + + if( _procs != NIL(PR) ) { + for( i=0; i<Max_proc; i++ ) + if( _procs[i].pr_valid ) + kill(_procs[i].pr_pid, SIGTERM); + + while( Wait_for_child(TRUE, -1) != -1 ); + } +} + + +static void +_add_child( pid, target, ignore, last ) +int pid; +CELLPTR target; +int ignore; +int last; +{ + register int i; + register PR *pp; + + if( _procs == NIL(PR) ) { + TALLOC( _procs, Max_proc, PR ); + } + + if( (i = _use_i) == -1 ) + for( i=0; i<Max_proc; i++ ) + if( !_procs[i].pr_valid ) + break; + + pp = _procs+i; + + pp->pr_valid = 1; + pp->pr_pid = pid; + pp->pr_target = target; + pp->pr_ignore = ignore; + pp->pr_last = last; + pp->pr_dir = DmStrDup(Get_current_dir()); + + Current_target = NIL(CELL); + + _proc_cnt++; + + if( Wait_for_completion ) Wait_for_child( FALSE, pid ); +} + + +static void +_finished_child(pid, status) +int pid; +int status; +{ + register int i; + register PR *pp; + char *dir; + + for( i=0; i<Max_proc; i++ ) + if( _procs[i].pr_valid && _procs[i].pr_pid == pid ) + break; + + /* Some children we didn't make esp true if using /bin/sh to execute a + * a pipe and feed the output as a makefile into dmake. */ + if( i == Max_proc ) return; + _procs[i].pr_valid = 0; + _proc_cnt--; + dir = DmStrDup(Get_current_dir()); + Set_dir( _procs[i].pr_dir ); + + if( _procs[i].pr_recipe != NIL(RCP) && !_abort_flg ) { + RCPPTR rp = _procs[i].pr_recipe; + + + Current_target = _procs[i].pr_target; + Handle_result( status, _procs[i].pr_ignore, FALSE, _procs[i].pr_target ); + Current_target = NIL(CELL); + + if ( _procs[i].pr_target->ce_attr & A_ERROR ) { + Unlink_temp_files( _procs[i].pr_target ); + _procs[i].pr_last = TRUE; + goto ABORT_REMAINDER_OF_RECIPE; + } + + _procs[i].pr_recipe = rp->prp_next; + + _use_i = i; + runargv( _procs[i].pr_target, rp->prp_ignore, rp->prp_group, + rp->prp_last, rp->prp_shell, rp->prp_cmd ); + _use_i = -1; + + FREE( rp->prp_cmd ); + FREE( rp ); + + if( _proc_cnt == Max_proc ) Wait_for_child( FALSE, -1 ); + } + else { + Unlink_temp_files( _procs[i].pr_target ); + Handle_result(status,_procs[i].pr_ignore,_abort_flg,_procs[i].pr_target); + + ABORT_REMAINDER_OF_RECIPE: + if( _procs[i].pr_last ) { + FREE(_procs[i].pr_dir ); + + if( !Doing_bang ) Update_time_stamp( _procs[i].pr_target ); + } + } + + Set_dir(dir); + FREE(dir); +} + + +static int +_running( cp ) +CELLPTR cp; +{ + register int i; + + if( !_procs ) return(FALSE); + + for( i=0; i<Max_proc; i++ ) + if( _procs[i].pr_valid && + _procs[i].pr_target == cp ) + break; + + return( i != Max_proc ); +} + + +static void +_attach_cmd( cmd, group, ignore, cp, last, shell ) +char *cmd; +int group; +int ignore; +CELLPTR cp; +int last; +int shell; +{ + register int i; + RCPPTR rp; + + for( i=0; i<Max_proc; i++ ) + if( _procs[i].pr_valid && + _procs[i].pr_target == cp ) + break; + + TALLOC( rp, 1, RCP ); + rp->prp_cmd = DmStrDup(cmd); + rp->prp_group = group; + rp->prp_ignore= ignore; + rp->prp_last = last; + rp->prp_shell = shell; + + if( _procs[i].pr_recipe == NIL(RCP) ) + _procs[i].pr_recipe = _procs[i].pr_recipe_end = rp; + else { + _procs[i].pr_recipe_end->prp_next = rp; + _procs[i].pr_recipe_end = rp; + } +} diff --git a/dmake/win95/microsft/vpp40/template.mk b/dmake/win95/microsft/vpp40/template.mk new file mode 100644 index 000000000000..d4e6c9eb9f40 --- /dev/null +++ b/dmake/win95/microsft/vpp40/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= win95 + OSRELEASE *:= microsft + OSENVIRONMENT *:= vpp40 diff --git a/dmake/win95/microsft/vpp40/tempnam.c b/dmake/win95/microsft/vpp40/tempnam.c new file mode 100644 index 000000000000..c27da47c7602 --- /dev/null +++ b/dmake/win95/microsft/vpp40/tempnam.c @@ -0,0 +1,110 @@ +/* RCS $Id: tempnam.c,v 1.1.1.1 2000-09-22 15:33:37 hr Exp $ +-- +-- SYNOPSIS +-- tempnam +-- +-- DESCRIPTION +-- temp file name generation routines. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +/*LINTLIBRARY*/ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <dos.h> + +#if defined(max) +# undef max +#endif +#define max(A,B) (((A)<(B))?(B):(A)) + +extern char *mktemp(); +extern int access(); +int d_access(); + +/* MSC stdio.h defines P_tmpdir, so let's undo it here */ +/* Under DOS leave the default tmpdir pointing here! */ +#ifdef P_tmpdir +#undef P_tmpdir +#endif +static char *P_tmpdir = ""; + +char * +tempnam(dir, prefix) +char *dir; /* use this directory please (if non-NULL) */ +char *prefix; /* use this (if non-NULL) as filename prefix */ +{ + static int count = 0; + register char *p, *q, *tmpdir; + int tl=0, dl=0, pl; + char buf[30]; + + pl = strlen(P_tmpdir); + + if( (tmpdir = getenv("TMPDIR")) != NULL ) tl = strlen(tmpdir); + else if( (tmpdir = getenv("TMP")) != NULL ) tl = strlen(tmpdir); + if( dir != NULL ) dl = strlen(dir); + + if( (p = malloc((unsigned)(max(max(dl,tl),pl)+13))) == NULL ) + return(NULL); + + *p = '\0'; + + if( (tl == 0) || (d_access( strcpy(p, tmpdir), 0) != 0) ) + if( (dl == 0) || (d_access( strcpy(p, dir), 0) != 0) ) + if( d_access( strcpy(p, P_tmpdir), 0) != 0 ) + if( !prefix ) + prefix = "tp"; + + if(prefix) + { + *(p+strlen(p)+2) = '\0'; + (void)strncat(p, prefix, 2); + } + + sprintf( buf, "%08x", _psp ); + buf[6]='\0'; + (void)strcat(p, buf ); + sprintf( buf, "%04d", count++ ); + q=p+strlen(p)-6; + *q++ = buf[0]; *q++ = buf[1]; + *q++ = buf[2]; *q++ = buf[3]; + + if( (q = strrchr(p,'.')) != NULL ) *q = '\0'; + + return(p); +} + + + +d_access( name, flag ) +char *name; +int flag; +{ + extern char *DirSepStr; + char *p; + int r; + + if( name == NULL || !*name ) return(1); /* NULL dir means current dir */ + r = access( name, flag ); + p = name+strlen(name)-1; + if(*p != '/' && *p != '\\') strcat( p, DirSepStr ); + + return( r ); +} diff --git a/dmake/win95/startup.h b/dmake/win95/startup.h new file mode 100644 index 000000000000..b2731353c6b5 --- /dev/null +++ b/dmake/win95/startup.h @@ -0,0 +1,28 @@ +/* RCS $Id: startup.h,v 1.1.1.1 2000-09-22 15:33:36 hr Exp $ +-- +-- SYNOPSIS +-- Definition of MAKESTARTUP +-- +-- DESCRIPTION +-- Default MAKESTARTUP value defining where dmake locates the +-- startup file. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +/*"MAKESTARTUP := $(MAKECMD:d)startup/startup.mk",*/ +"MAKESTARTUP := $(DMAKEROOT)\\startup.mk", diff --git a/dmake/win95/switchar.c b/dmake/win95/switchar.c new file mode 100644 index 000000000000..783d02cefe77 --- /dev/null +++ b/dmake/win95/switchar.c @@ -0,0 +1,43 @@ +/* RCS $Id: switchar.c,v 1.1.1.1 2000-09-22 15:33:36 hr Exp $ +-- +-- SYNOPSIS +-- switchar settings +-- +-- DESCRIPTION +-- Figure out the value of switchar. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include <stdlib.h> +#include <stdio.h> +#include "stdmacs.h" + +getswitchar()/* +=============== + Try the environment first. If you don't find SWITCHAR there, then use + the DOS call. The call is undocumented, and doesn't work for DOS versions + 4.0 and up, so the check of the environment will fix that. */ +{ + static char *_env_switchar = NIL(char); + + if( _env_switchar != NIL(char) || + (_env_switchar = (char *)getenv("SWITCHAR")) != NIL(char) ) + return(*_env_switchar); + + return ('/'); +} diff --git a/dmake/winnt/borland/bcc50/config.h b/dmake/winnt/borland/bcc50/config.h new file mode 100644 index 000000000000..dc9f72b439bd --- /dev/null +++ b/dmake/winnt/borland/bcc50/config.h @@ -0,0 +1,44 @@ +/* RCS $Id: config.h,v 1.1.1.1 2000-09-22 15:33:37 hr Exp $ +-- +-- SYNOPSIS +-- Configurarion include file. +-- +-- DESCRIPTION +-- There is one of these for each specific machine configuration. +-- It can be used to further tweek the machine specific sources +-- so that they compile. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +/* define this for configurations that don't have the coreleft function + * so that the code compiles. To my knowledge coreleft exists only on + * Turbo C, but it is needed here since the function is used in many debug + * macros. */ +/*#define coreleft() 0L*/ +extern unsigned int coreleft(); + +#define SIGQUIT SIGBREAK /* turbo C doesn't understand SIGQUIT */ + +/* Turbo-C understands const declarations. */ +#define CONST const + +/* a small problem with pointer to voids on some unix machines needs this */ +#define PVOID void * + +/* Borland redefined the environment variable, sigh */ +#define environ _environ diff --git a/dmake/winnt/borland/bcc50/config.mk b/dmake/winnt/borland/bcc50/config.mk new file mode 100644 index 000000000000..6e4fbd89e368 --- /dev/null +++ b/dmake/winnt/borland/bcc50/config.mk @@ -0,0 +1,12 @@ +# Definition of macros for library, and C startup code. +osedir = $(osrdir)$(DIRSEPSTR)$(OSENVIRONMENT) + +# Change the CCROOT variable to reflect the installation directory of your +# C++ compiler. +CCVER *:= c:/cc/borland/$(OSENVIRONMENT) + +# Definitions for compiles and links +CSTARTUP = $(CCVER)/lib/c0x32.obj +LDLIBS = $(CCVER)/lib/cw32 $(CCVER)/lib/import32 + +CFLAGS += -A- -w-pro -I$(osedir) diff --git a/dmake/winnt/borland/bcc50/lib.rsp b/dmake/winnt/borland/bcc50/lib.rsp new file mode 100644 index 000000000000..0bad32e7128d --- /dev/null +++ b/dmake/winnt/borland/bcc50/lib.rsp @@ -0,0 +1,2 @@ +c:\cc\borland\bcc50\lib\cw32 +c:\cc\borland\bcc50\lib\import32 diff --git a/dmake/winnt/borland/bcc50/mk.bat b/dmake/winnt/borland/bcc50/mk.bat new file mode 100755 index 000000000000..f6e3c75fce78 --- /dev/null +++ b/dmake/winnt/borland/bcc50/mk.bat @@ -0,0 +1,95 @@ +md objects +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 infer.c +copy infer.obj objects +del infer.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 make.c +copy make.obj objects +del make.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 stat.c +copy stat.obj objects +del stat.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 expand.c +copy expand.obj objects +del expand.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 dmstring.c +copy dmstring.obj objects +del dmstring.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 hash.c +copy hash.obj objects +del hash.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 dag.c +copy dag.obj objects +del dag.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 dmake.c +copy dmake.obj objects +del dmake.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 path.c +copy path.obj objects +del path.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 imacs.c +copy imacs.obj objects +del imacs.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 sysintf.c +copy sysintf.obj objects +del sysintf.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 parse.c +copy parse.obj objects +del parse.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 getinp.c +copy getinp.obj objects +del getinp.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 quit.c +copy quit.obj objects +del quit.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 state.c +copy state.obj objects +del state.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 dmdump.c +copy dmdump.obj objects +del dmdump.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 macparse.c +copy macparse.obj objects +del macparse.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 rulparse.c +copy rulparse.obj objects +del rulparse.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 percent.c +copy percent.obj objects +del percent.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 function.c +copy function.obj objects +del function.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 win95\dchdir.c +copy dchdir.obj objects +del dchdir.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 win95\switchar.c +copy switchar.obj objects +del switchar.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 msdos\dstrlwr.c +copy dstrlwr.obj objects +del dstrlwr.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 msdos\arlib.c +copy arlib.obj objects +del arlib.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 msdos\dirbrk.c +copy dirbrk.obj objects +del dirbrk.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 win95\borland\tempnam.c +copy tempnam.obj objects +del tempnam.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 win95\borland\utime.c +copy utime.obj objects +del utime.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 win95\borland\ruletab.c +copy ruletab.obj objects +del ruletab.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 win95\borland\runargv.c +copy runargv.obj objects +del runargv.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 unix\dcache.c +copy dcache.obj objects +del dcache.obj +bcc32 -c -I. -Iwin95 -Iwin95\borland -d -O -N- -w-nod -A- -w-pro -Iwin95\borland\bcc50 unix\rmprq.c +copy rmprq.obj objects +del rmprq.obj +tlink32 @win95\borland\bcc50\obj.rsp,dmake.exe,NUL.MAP,@win95\borland\bcc50\lib.rsp diff --git a/dmake/winnt/borland/bcc50/mk.cmd b/dmake/winnt/borland/bcc50/mk.cmd new file mode 100755 index 000000000000..7f212e9c4f09 --- /dev/null +++ b/dmake/winnt/borland/bcc50/mk.cmd @@ -0,0 +1,93 @@ +md objects +bcc32 -c -I. -Iwinnt -Iwinnt\borland -d -O -N- -w-nod -A- -w-pro -Iwinnt\borland\bcc50 infer.c +copy infer.obj objects +del infer.obj +bcc32 -c -I. -Iwinnt -Iwinnt\borland -d -O -N- -w-nod -A- -w-pro -Iwinnt\borland\bcc50 make.c +copy make.obj objects +del make.obj +bcc32 -c -I. -Iwinnt -Iwinnt\borland -d -O -N- -w-nod -A- -w-pro -Iwinnt\borland\bcc50 stat.c +copy stat.obj objects +del stat.obj +bcc32 -c -I. -Iwinnt -Iwinnt\borland -d -O -N- -w-nod -A- -w-pro -Iwinnt\borland\bcc50 expand.c +copy expand.obj objects +del expand.obj +bcc32 -c -I. -Iwinnt -Iwinnt\borland -d -O -N- -w-nod -A- -w-pro -Iwinnt\borland\bcc50 dmstring.c +copy dmstring.obj objects +del dmstring.obj +bcc32 -c -I. -Iwinnt -Iwinnt\borland -d -O -N- -w-nod -A- -w-pro -Iwinnt\borland\bcc50 hash.c +copy hash.obj objects +del hash.obj +bcc32 -c -I. -Iwinnt -Iwinnt\borland -d -O -N- -w-nod -A- -w-pro -Iwinnt\borland\bcc50 dag.c +copy dag.obj objects +del dag.obj +bcc32 -c -I. -Iwinnt -Iwinnt\borland -d -O -N- -w-nod -A- -w-pro -Iwinnt\borland\bcc50 dmake.c +copy dmake.obj objects +del dmake.obj +bcc32 -c -I. -Iwinnt -Iwinnt\borland -d -O -N- -w-nod -A- -w-pro -Iwinnt\borland\bcc50 path.c +copy path.obj objects +del path.obj +bcc32 -c -I. -Iwinnt -Iwinnt\borland -d -O -N- -w-nod -A- -w-pro -Iwinnt\borland\bcc50 imacs.c +copy imacs.obj objects +del imacs.obj +bcc32 -c -I. -Iwinnt -Iwinnt\borland -d -O -N- -w-nod -A- -w-pro -Iwinnt\borland\bcc50 sysintf.c +copy sysintf.obj objects +del sysintf.obj +bcc32 -c -I. -Iwinnt -Iwinnt\borland -d -O -N- -w-nod -A- -w-pro -Iwinnt\borland\bcc50 parse.c +copy parse.obj objects +del parse.obj +bcc32 -c -I. -Iwinnt -Iwinnt\borland -d -O -N- -w-nod -A- -w-pro -Iwinnt\borland\bcc50 getinp.c +copy getinp.obj objects +del getinp.obj +bcc32 -c -I. -Iwinnt -Iwinnt\borland -d -O -N- -w-nod -A- -w-pro -Iwinnt\borland\bcc50 quit.c +copy quit.obj objects +del quit.obj +bcc32 -c -I. -Iwinnt -Iwinnt\borland -d -O -N- -w-nod -A- -w-pro -Iwinnt\borland\bcc50 state.c +copy state.obj objects +del state.obj +bcc32 -c -I. -Iwinnt -Iwinnt\borland -d -O -N- -w-nod -A- -w-pro -Iwinnt\borland\bcc50 dmdump.c +copy dmdump.obj objects +del dmdump.obj +bcc32 -c -I. -Iwinnt -Iwinnt\borland -d -O -N- -w-nod -A- -w-pro -Iwinnt\borland\bcc50 macparse.c +copy macparse.obj objects +del macparse.obj +bcc32 -c -I. -Iwinnt -Iwinnt\borland -d -O -N- -w-nod -A- -w-pro -Iwinnt\borland\bcc50 rulparse.c +copy rulparse.obj objects +del rulparse.obj +bcc32 -c -I. -Iwinnt -Iwinnt\borland -d -O -N- -w-nod -A- -w-pro -Iwinnt\borland\bcc50 percent.c +copy percent.obj objects +del percent.obj +bcc32 -c -I. -Iwinnt -Iwinnt\borland -d -O -N- -w-nod -A- -w-pro -Iwinnt\borland\bcc50 function.c +copy function.obj objects +del function.obj +bcc32 -c -I. -Iwinnt -Iwinnt\borland -d -O -N- -w-nod -A- -w-pro -Iwinnt\borland\bcc50 winnt\dchdir.c +copy dchdir.obj objects +del dchdir.obj +bcc32 -c -I. -Iwinnt -Iwinnt\borland -d -O -N- -w-nod -A- -w-pro -Iwinnt\borland\bcc50 msdos\dstrlwr.c +copy dstrlwr.obj objects +del dstrlwr.obj +bcc32 -c -I. -Iwinnt -Iwinnt\borland -d -O -N- -w-nod -A- -w-pro -Iwinnt\borland\bcc50 msdos\arlib.c +copy arlib.obj objects +del arlib.obj +bcc32 -c -I. -Iwinnt -Iwinnt\borland -d -O -N- -w-nod -A- -w-pro -Iwinnt\borland\bcc50 msdos\dirbrk.c +copy dirbrk.obj objects +del dirbrk.obj +bcc32 -c -I. -Iwinnt -Iwinnt\borland -d -O -N- -w-nod -A- -w-pro -Iwinnt\borland\bcc50 winnt\borland\tempnam.c +copy tempnam.obj objects +del tempnam.obj +bcc32 -c -I. -Iwinnt -Iwinnt\borland -d -O -N- -w-nod -A- -w-pro -Iwinnt\borland\bcc50 winnt\borland\ruletab.c +copy ruletab.obj objects +del ruletab.obj +bcc32 -c -I. -Iwinnt -Iwinnt\borland -d -O -N- -w-nod -A- -w-pro -Iwinnt\borland\bcc50 winnt\borland\utime.c +copy utime.obj objects +del utime.obj +bcc32 -c -I. -Iwinnt -Iwinnt\borland -d -O -N- -w-nod -A- -w-pro -Iwinnt\borland\bcc50 winnt\borland\runargv.c +copy runargv.obj objects +del runargv.obj +bcc32 -c -I. -Iwinnt -Iwinnt\borland -d -O -N- -w-nod -A- -w-pro -Iwinnt\borland\bcc50 unix\dcache.c +copy dcache.obj objects +del dcache.obj +bcc32 -c -I. -Iwinnt -Iwinnt\borland -d -O -N- -w-nod -A- -w-pro -Iwinnt\borland\bcc50 unix\rmprq.c +copy rmprq.obj objects +del rmprq.obj +tlink32 @fix95nt\winnt\borland\bcc50\obj.rsp,dmake.exe,NUL.MAP,@fix95nt\winnt\borland\bcc50\lib.rsp +copy winnt\borland\bcc50\template.mk startup\config.mk diff --git a/dmake/winnt/borland/bcc50/obj.rsp b/dmake/winnt/borland/bcc50/obj.rsp new file mode 100644 index 000000000000..9cf59afdedd2 --- /dev/null +++ b/dmake/winnt/borland/bcc50/obj.rsp @@ -0,0 +1,31 @@ +c:\cc\borland\bcc50\lib\c0x32.obj +objects\infer.obj +objects\make.obj +objects\stat.obj +objects\expand.obj +objects\dmstring.obj +objects\hash.obj +objects\dag.obj +objects\dmake.obj +objects\path.obj +objects\imacs.obj +objects\sysintf.obj +objects\parse.obj +objects\getinp.obj +objects\quit.obj +objects\state.obj +objects\dmdump.obj +objects\macparse.obj +objects\rulparse.obj +objects\percent.obj +objects\function.obj +objects\dchdir.obj +objects\dstrlwr.obj +objects\arlib.obj +objects\dirbrk.obj +objects\tempnam.obj +objects\ruletab.obj +objects\utime.obj +objects\runargv.obj +objects\dcache.obj +objects\rmprq.obj diff --git a/dmake/winnt/borland/bcc50/public.h b/dmake/winnt/borland/bcc50/public.h new file mode 100644 index 000000000000..8e9567e016a3 --- /dev/null +++ b/dmake/winnt/borland/bcc50/public.h @@ -0,0 +1,167 @@ +/* RCS $Id: public.h,v 1.1.1.1 2000-09-22 15:33:37 hr Exp $ +-- WARNING -- This file is AUTOMATICALLY GENERATED DO NOT EDIT IT +-- +-- +-- SYNOPSIS +-- Local functions exported to be visible by others. +-- +-- DESCRIPTION +-- This file is generated by 'genpub'. Function declarations +-- that appear in this file are extracted by 'genpub' from +-- source files. Any function in the source file whose definition +-- appears like: +-- +-- PUBLIC return_type +-- function( arg_list ); +-- type_expr1 arg1; +-- ... +-- +-- has its definition extracted and a line of the form: +-- +-- return_type function ANSI((type_expr1,type_expr2,...)); +-- +-- entered into the output file. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef _DMAKE_PUBLIC_h +#define _DMAKE_PUBLIC_h + +#ifdef EXTERN +#undef EXTERN +#endif +#if defined(DEFINE_DMAKE_VARIABLES) +#define EXTERN +#else +#define EXTERN extern +#endif + +/***** genpub: Begin list of generated function headers */ +void Infer_recipe ANSI((CELLPTR, CELLPTR)); +int Make_targets ANSI(()); +int Make ANSI((CELLPTR, CELLPTR)); +int Exec_commands ANSI((CELLPTR)); +void Print_cmnd ANSI((char *, int, int)); +int Push_dir ANSI((char *, char *, int)); +void Pop_dir ANSI((int)); +void Append_line ANSI((char *, int, FILE *, char *, int, int)); +void Stat_target ANSI((CELLPTR, int, int)); +char *Expand ANSI((char *)); +char *Apply_edit ANSI((char *, char *, char *, int, int)); +void Map_esc ANSI((char *)); +char* Apply_modifiers ANSI((int, char *)); +char* Tokenize ANSI((char *, char *, char, int)); +char* ScanToken ANSI((char *, char **, int)); +char *DmStrJoin ANSI((char *, char *, int, int)); +char *DmStrAdd ANSI((char *, char *, int)); +char *DmStrApp ANSI((char *, char *)); +char *DmStrDup ANSI((char *)); +char *DmStrDup2 ANSI((char *)); +char *DmStrPbrk ANSI((char *, char *)); +char *DmStrSpn ANSI((char *, char *)); +char *DmStrStr ANSI((char *, char *)); +char *DmSubStr ANSI((char *, char *)); +uint16 Hash ANSI((char *, uint32 *)); +HASHPTR Get_name ANSI((char *, HASHPTR *, int)); +HASHPTR Search_table ANSI((HASHPTR *, char *, uint16 *, uint32 *)); +HASHPTR Push_macro ANSI((HASHPTR)); +HASHPTR Pop_macro ANSI((HASHPTR)); +HASHPTR Def_macro ANSI((char *, char *, int)); +CELLPTR Def_cell ANSI((char *)); +LINKPTR Add_prerequisite ANSI((CELLPTR, CELLPTR, int, int)); +void Clear_prerequisites ANSI((CELLPTR)); +int Test_circle ANSI((CELLPTR, int)); +STRINGPTR Def_recipe ANSI((char *, STRINGPTR, int, int)); +t_attr Rcp_attribute ANSI((char *)); +void main ANSI((int, char **)); +FILE *Openfile ANSI((char *, int, int)); +FILE *Closefile ANSI(()); +FILE *Search_file ANSI((char *, char **)); +char *Filename ANSI(()); +int Nestlevel ANSI(()); +FILE *TryFiles ANSI((LINKPTR)); +void Fatal ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Error ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Warning ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void No_ram ANSI(()); +void Usage ANSI((int)); +void Version ANSI(()); +char *Get_suffix ANSI((char *)); +char *Basename ANSI((char *)); +char *Filedir ANSI((char *)); +char *Build_path ANSI((char *, char *)); +void Make_rules ANSI(()); +void Create_macro_vars ANSI(()); +time_t Do_stat ANSI((char *, char *, char **, int)); +int Do_touch ANSI((char *, char *, char **)); +void Void_lib_cache ANSI((char *, char *)); +time_t Do_time ANSI(()); +int Do_cmnd ANSI((char *, int, int, CELLPTR, int, int, int)); +char ** Pack_argv ANSI((int, int, char *)); +char *Read_env_string ANSI((char *)); +int Write_env_string ANSI((char *, char *)); +void ReadEnvironment ANSI(()); +void Catch_signals ANSI((void (*)())); +void Clear_signals ANSI(()); +void Prolog ANSI((int, char* [])); +void Epilog ANSI((int)); +char *Get_current_dir ANSI(()); +int Set_dir ANSI((char*)); +char Get_switch_char ANSI(()); +FILE* Get_temp ANSI((char **, char *, int)); +FILE *Start_temp ANSI((char *, CELLPTR, char **)); +void Open_temp_error ANSI((char *, char *)); +void Link_temp ANSI((CELLPTR, FILE *, char *)); +void Close_temp ANSI((CELLPTR, FILE *)); +void Unlink_temp_files ANSI((CELLPTR)); +void Handle_result ANSI((int, int, int, CELLPTR)); +void Update_time_stamp ANSI((CELLPTR)); +int Remove_file ANSI((char *)); +void Parse ANSI((FILE *)); +int Get_line ANSI((char *, FILE *)); +char *Do_comment ANSI((char *, char **, int)); +char *Get_token ANSI((TKSTRPTR, char *, int)); +void Quit ANSI(()); +void Read_state ANSI(()); +void Write_state ANSI(()); +int Check_state ANSI((CELLPTR, STRINGPTR *, int)); +void Dump ANSI(()); +void Dump_recipe ANSI((STRINGPTR)); +int Parse_macro ANSI((char *, int)); +int Macro_op ANSI((char *)); +int Parse_rule_def ANSI((int *)); +int Rule_op ANSI((char *)); +void Add_recipe_to_list ANSI((char *, int, int)); +void Bind_rules_to_targets ANSI((int)); +int Set_group_attributes ANSI((char *)); +DFALINKPTR Match_dfa ANSI((char *)); +void Check_circle_dfa ANSI(()); +void Add_nfa ANSI((char *)); +char *Exec_function ANSI((char *)); +int dchdir ANSI((char *)); +void dstrlwr ANSI((char *, char *)); +time_t seek_arch ANSI((char*, char*)); +int touch_arch ANSI((char*, char*)); +int If_root_path ANSI((char *)); +int runargv ANSI((CELLPTR, int, int, int, int, char *)); +int Wait_for_child ANSI((int, int)); +void Clean_up_processes ANSI(()); +time_t CacheStat ANSI((char *, int)); +void Remove_prq ANSI((CELLPTR)); + +#endif diff --git a/dmake/winnt/borland/bcc50/template.mk b/dmake/winnt/borland/bcc50/template.mk new file mode 100644 index 000000000000..b94ac034e0a1 --- /dev/null +++ b/dmake/winnt/borland/bcc50/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= winnt + OSRELEASE *:= borland + OSENVIRONMENT *:= bcc50 diff --git a/dmake/winnt/borland/config.mk b/dmake/winnt/borland/config.mk new file mode 100644 index 000000000000..85c929b4163e --- /dev/null +++ b/dmake/winnt/borland/config.mk @@ -0,0 +1,51 @@ +# This is the Turbo C++ 2.0 DOS configuration file for DMAKE +# It simply modifies the values of SRC, and checks to see if +# OSENVIRONMENT is defined. If so it includes the appropriate +# config.mk file. +# +# It also sets the values of .SOURCE.c and .SOURCE.h to include the local +# directory. +# +osrdir := $(OS)$(DIRSEPSTR)$(OSRELEASE) + +# OS specific sources +OSR_SRC += tempnam.c ruletab.c +DOS_SRC += runargv.c rmprq.c + +SRC += $(OSR_SRC) $(DOS_SRC) +.SOURCE.h : $(osrdir) + +# Local configuration modifications for CFLAGS. Make sure your turboc.cfg +# file contains a -D__STDC__=1 and -DM_I86=1, if not then uncomment the line +# below! +#CFLAGS += -DM_I86=1 -D__STDC__=1 + +# You can get a smaller executable still, buy adding a -1 to the list of +# flags below, but then you can't run this on an 8086/88 cpu. +#CFLAGS += -1 +CFLAGS += -I$(osrdir) -d -O -N- -w-nod +ASFLAGS += -t -mx $(S_$(MODEL)) + +LDOBJS = $(CSTARTUP) $(OBJDIR)/{$(<:f)} +LDARGS = $(LDHEAD) @$(LDTMPOBJ),$(TARGET),NUL.MAP$(LDTAIL) +LDTAIL = $(_libs)$(LDFLAGS:s/ //) +_libs = $(!null,$(LDLIBS) ,@$(LDTMPLIB)) +LDTMPOBJ = $(mktmp,,$(DIVFILE) $(LDOBJS:s,/,\\,:t"+\n")\n) +LDTMPLIB = $(mktmp,,$(DIVFILE) $(LDLIBS:s,/,\\,:t"+\n")\n) + +# Debugging information for Turbo-C +DB_CFLAGS += -v +DB_LDFLAGS += /v + +# See if we modify anything in the lower levels. +.IF $(OSENVIRONMENT) != $(NULL) + .INCLUDE .IGNORE : $(osrdir)$(DIRSEPSTR)$(OSENVIRONMENT)$(DIRSEPSTR)config.mk +.END + +.SETDIR=$(osrdir) : $(OSR_SRC) +.SETDIR=msdos : $(DOS_SRC) + +S_s = -dmsmall +S_m = -dmmedium +S_c = -dmcompact +S_l = -dmlarge diff --git a/dmake/winnt/borland/ruletab.c b/dmake/winnt/borland/ruletab.c new file mode 100644 index 000000000000..8522d617363c --- /dev/null +++ b/dmake/winnt/borland/ruletab.c @@ -0,0 +1,44 @@ +/* RCS $Id: ruletab.c,v 1.1.1.1 2000-09-22 15:33:37 hr Exp $ +-- +-- SYNOPSIS +-- Default initial configuration of dmake. +-- +-- DESCRIPTION +-- Define here the initial set of rules that are defined before +-- dmake performs any processing. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +/* These are control macros for dmake that MUST be defined at some point + * if they are NOT dmake will not work! These are default definitions. They + * may be overridden inside the .STARTUP makefile, they are here + * strictly so that dmake can parse the STARTUP makefile */ + +#include <stdio.h> + +static char *_rules[] = { + "MAXLINELENGTH := 2046", + "MAXPROCESSLIMIT := 4", + ".IMPORT .IGNORE: ROOTDIR", + ".MAKEFILES : makefile.mk makefile", + ".SOURCE : .NULL", +#include "startup.h" + (char *)NULL }; + +char **Rule_tab = _rules; /* for sundry reasons in Get_environment() */ + diff --git a/dmake/winnt/borland/sysintf.h b/dmake/winnt/borland/sysintf.h new file mode 100644 index 000000000000..6a24a5f0c04e --- /dev/null +++ b/dmake/winnt/borland/sysintf.h @@ -0,0 +1,56 @@ +/* RCS $Id: sysintf.h,v 1.1.1.1 2000-09-22 15:33:37 hr Exp $ +-- +-- SYNOPSIS +-- Interfaces for sysintf.c +-- +-- DESCRIPTION +-- Abstractions of functions in sysintf.c +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#define DMSTAT stat +#define VOID_LCACHE(l,m) +#define GETPID _psp +#define Hook_std_writes(A) +#define DMSTRLWR(A,B) dstrlwr((A),(B)) + +extern char * tempnam(); +extern char * getcwd(); + +/* +** standard C items +*/ + +/* +** DOS interface standard items +*/ +#define chdir(p) dchdir(p) +#define CacheStat(A,B) really_dostat(A,&buf) + +/* +** make parameters +*/ +#ifdef _POSIX_NAME_MAX +#undef _POSIX_NAME_MAX +#endif +#define _POSIX_NAME_MAX 12 + +#ifdef _POSIX_PATH_MAX +#undef _POSIX_PATH_MAX +#endif +#define _POSIX_PATH_MAX 64 diff --git a/dmake/winnt/borland/tempnam.c b/dmake/winnt/borland/tempnam.c new file mode 100644 index 000000000000..a7d0df8d962b --- /dev/null +++ b/dmake/winnt/borland/tempnam.c @@ -0,0 +1,114 @@ +/* RCS $Id: tempnam.c,v 1.1.1.1 2000-09-22 15:33:37 hr Exp $ +-- +-- SYNOPSIS +-- tempnam +-- +-- DESCRIPTION +-- temp file name generation routines. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +/*LINTLIBRARY*/ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <dos.h> + +#if defined(max) +# undef max +#endif +#define max(A,B) (((A)<(B))?(B):(A)) + +extern char *mktemp(); +extern int access(); +int d_access(); + +/* Turbo C stdio.h doesn't define P_tmpdir, so let's do it here */ +/* Under DOS leave the default tmpdir pointing here! */ +#ifndef P_tmpdir +static char *P_tmpdir = ""; +#endif + +char * +tempnam(dir, prefix) +char *dir; /* use this directory please (if non-NULL) */ +char *prefix; /* use this (if non-NULL) as filename prefix */ +{ + static int count = 0; + register char *p, *q, *tmpdir; + int tl=0, dl=0, pl; + char buf[30]; + +#if defined(__WIN32__) + unsigned int _psp = rand(); +#endif + + pl = strlen(P_tmpdir); + + if( (tmpdir = getenv("TMPDIR")) != NULL ) tl = strlen(tmpdir); + else if( (tmpdir = getenv("TMP")) != NULL ) tl = strlen(tmpdir); + if( dir != NULL ) dl = strlen(dir); + + if( (p = malloc((unsigned)(max(max(dl,tl),pl)+13))) == NULL ) + return(NULL); + + *p = '\0'; + + if( (tl == 0) || (d_access( strcpy(p, tmpdir), 0) != 0) ) + if( (dl == 0) || (d_access( strcpy(p, dir), 0) != 0) ) + if( d_access( strcpy(p, P_tmpdir), 0) != 0 ) + if( !prefix ) + prefix = "tp"; + + if(prefix) + { + *(p+strlen(p)+2) = '\0'; + (void)strncat(p, prefix, 2); + } + + sprintf( buf, "%08x", _psp ); + buf[6]='\0'; + (void)strcat(p, buf ); + sprintf( buf, "%04d", count++ ); + q=p+strlen(p)-6; + *q++ = buf[0]; *q++ = buf[1]; + *q++ = buf[2]; *q = buf[3]; + + if( (q = strrchr(p,'.')) != NULL ) *q = '\0'; + + return(p); +} + + + +d_access( name, flag ) +char *name; +int flag; +{ + extern char *DirSepStr; + char *p; + int r; + + if( name == NULL || !*name ) return(1); /* NULL dir means current dir */ + r = access( name, flag ); + p = name+strlen(name)-1; + + if(*p != '/' && *p != '\\') strcat( p, DirSepStr ); + + return( r ); +} diff --git a/dmake/winnt/config.mk b/dmake/winnt/config.mk new file mode 100644 index 000000000000..2abcb8ad66c6 --- /dev/null +++ b/dmake/winnt/config.mk @@ -0,0 +1,57 @@ +# This is an OS specific configuration file +# It assumes that OBJDIR, TARGET and DEBUG are previously defined. +# It defines CFLAGS, LDARGS, CPPFLAGS, STARTUPFILE, LDOBJS +# It augments SRC, OBJDIR, TARGET, CFLAGS, LDLIBS +# + +# Memory model to compile for +# set to s - small, m - medium, c - compact, l - large +# Need large model now, dmake has grown up :-) +MODEL = l + +STARTUPFILE = startup/startup.mk + +CPPFLAGS = $(CFLAGS) + +# Debug flags +DB_CFLAGS = -DDBUG +DB_LDFLAGS = +DB_LDLIBS = + +# NO Debug flags +NDB_CFLAGS = +NDB_LDFLAGS = +NDB_LDLIBS = + +# Local configuration modifications for CFLAGS. +CFLAGS += -I$(OS) + +# Common Win32 source files. +OS_SRC += dchdir.c + +# Imported Win95 files. +WIN95SRC += switchar.c + +# Imported MSDOS Files. +DOSSRC += dstrlwr.c arlib.c dirbrk.c + +SRC += $(OS_SRC) $(UNIXSRC) $(DOSSRC) + +# Provide our own %$O : %$S rule. +%$O : %$S + +$(AS) $(ASFLAGS) \ + $(<:s,\,${__.DIVSEP-sh-${USESHELL}},:s,/,${__.DIVSEP-sh-${USESHELL}},); + mv $(@:f) $(OBJDIR) + +# Set source dirs so that we can find files named in this +# config file. +.SOURCE.h : $(OS) + +# See if we modify anything in the lower levels. +.IF $(OSRELEASE) != $(NULL) + .INCLUDE : $(OS)$(DIRSEPSTR)$(OSRELEASE)$(DIRSEPSTR)config.mk +.END + +.SETDIR=msdos : $(DOSSRC) +.SETDIR=win95 : $(WIN95SRC) +.SETDIR=$(OS) : $(ASRC) $(OS_SRC) diff --git a/dmake/winnt/dchdir.c b/dmake/winnt/dchdir.c new file mode 100644 index 000000000000..de2cf18041a8 --- /dev/null +++ b/dmake/winnt/dchdir.c @@ -0,0 +1,47 @@ +/* RCS $Id: dchdir.c,v 1.1.1.1 2000-09-22 15:33:37 hr Exp $ +-- +-- SYNOPSIS +-- Change directory. +-- +-- DESCRIPTION +-- Under DOS change the current drive as well as the current directory. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include <dir.h> +#include <direct.h> +#include "extern.h" + +PUBLIC int +dchdir(path) +char *path; +{ + int res; + + res = chdir(path); + + if (res != -1 && path[1] == ':') { + unsigned new_drive; + + /* for WIN32 just use the _chdrive library call */ + new_drive = (*path & ~0x20) - 'A' + 1; + _chdrive(new_drive); + } + + return (res); +} diff --git a/dmake/winnt/microsft/config.h b/dmake/winnt/microsft/config.h new file mode 100644 index 000000000000..9ecc029a51ef --- /dev/null +++ b/dmake/winnt/microsft/config.h @@ -0,0 +1,78 @@ +/* RCS $Id: config.h,v 1.1.1.1 2000-09-22 15:33:37 hr Exp $ +-- +-- SYNOPSIS +-- Configurarion include file. +-- +-- DESCRIPTION +-- There is one of these for each specific machine configuration. +-- It can be used to further tweek the machine specific sources +-- so that they compile. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#if defined (_MSC_VER) +# if _MSC_VER < 500 + Force a compile-time blowup. + Do not define "#define _MSC_VER" for MSC compilers earlier than 5.0. +# endif +#endif + +/* define this for configurations that don't have the coreleft function + * so that the code compiles. To my knowledge coreleft exists only on + * Turbo C, but it is needed here since the function is used in many debug + * macros. */ +#define coreleft() 0L + +/* MSC Version 4.0 doesn't understand SIGTERM, later versions do. */ +#ifndef SIGTERM +# define SIGTERM SIGINT +#endif + +/* Fixes unimplemented line buffering for MSC 5.x and 6.0. + * MSC _IOLBF is the same as _IOFBF + */ +#if defined(MSDOS) && defined (_MSC_VER) +# undef _IOLBF +# define _IOLBF _IONBF +#endif + +/* in alloc.h: size_t is redefined + * defined in stdio.h which is included by alloc.h + */ +#if defined(MSDOS) && defined (_MSC_VER) +# define _TYPES_ +#endif + +/* in sysintf.c: SIGQUIT is used, this is not defined in MSC */ +#ifndef SIGQUIT +# define SIGQUIT SIGTERM +#endif + +/* MSC doesn't seem to care about CONST */ +#define CONST + +#ifndef MSDOS +# define MSDOS 1 +#endif + +/* a small problem with pointer to voids on some unix machines needs this */ +#define PVOID void * + +/* Use my own tempnam */ +#define tempnam dtempnam + diff --git a/dmake/winnt/microsft/config.mk b/dmake/winnt/microsft/config.mk new file mode 100644 index 000000000000..352eed716d2f --- /dev/null +++ b/dmake/winnt/microsft/config.mk @@ -0,0 +1,61 @@ +# This is the MSC 4.0 and higher DOS configuration file for DMAKE +# It simply modifies the values of SRC, and checks to see if +# OSENVIRONMENT is defined. If so it includes the appropriate +# config.mk file. +# +# It also sets the values of .SOURCE.c and .SOURCE.h to include the local +# directory. +# +osrdir := $(OS)$(DIRSEPSTR)$(OSRELEASE) + +TMPDIR := +.EXPORT : TMPDIR + +# Definition of macros for library, and C startup code. + +# The following sources are required for MSC +OSR_SRC += tempnam.c ruletab.c +DOS_SRC += runargv.c rmprq.c + +.SETDIR=$(osrdir) : $(OSR_SRC) +.SETDIR=msdos : $(DOS_SRC) + +SRC += $(OSR_SRC) $(DOS_SRC) +.SOURCE.h : $(osrdir) + +SET_STACK = /stack:4096 +ASFLAGS += -t -mx $(S_$(MODEL)) + +# Microsoft C doesn't need tail but needs head +LDTAIL != +LDHEAD != $(LDFLAGS) +LDARGS != $(LDHEAD) -out:$(TARGET) @$(LDTMPOBJ) $(LDTAIL) +LDTAIL != $(_libs) +_libs != $(!null,$(LDLIBS) ,@$(LDTMPLIB)) +LDTMPOBJ != $(mktmp,,$(DIVFILE) $(LDOBJS:s,/,\\,:t"\n")\n) +LDTMPLIB != $(mktmp,,$(DIVFILE) $(LDLIBS:s,/,\\,:t"\n")\n) + +# Debugging libraries and flags +DB_LDFLAGS += /nologo /co /li /map +DB_LDLIBS += +DB_CFLAGS += -Zi + +# NO Debug MSC flags: +# Set the environment variable MSC_VER to be one of 5.1, 6.0, 8.0 (for VC++4.0) +# to get these by default when you make dmake using 'dmake'. +# + +NDB_LDFLAGS += /nologo +CFLAGS += -I$(osrdir) + +# See if we modify anything in the lower levels. +.IF $(OSENVIRONMENT) != $(NULL) + .INCLUDE .IGNORE : $(osrdir)$(DIRSEPSTR)$(OSENVIRONMENT)$(DIRSEPSTR)config.mk +.END + +CFLAGS += /nologo + +S_s = -Dmsmall +S_m = -Dmmedium +S_c = -Dmcompact +S_l = -Dmlarge diff --git a/dmake/winnt/microsft/optoff.h b/dmake/winnt/microsft/optoff.h new file mode 100644 index 000000000000..7dd3cb839572 --- /dev/null +++ b/dmake/winnt/microsft/optoff.h @@ -0,0 +1,27 @@ +/* RCS $Id: optoff.h,v 1.1.1.1 2000-09-22 15:33:37 hr Exp $ +-- +-- SYNOPSIS +-- Turn off microsoft loop optimization. +-- +-- DESCRIPTION +-- This is broken in some pre 600 compilers so just turn it off. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ +#if _MSC_VER < 600 +# pragma loop_opt(off) +#endif diff --git a/dmake/winnt/microsft/ruletab.c b/dmake/winnt/microsft/ruletab.c new file mode 100644 index 000000000000..6c7febfddf64 --- /dev/null +++ b/dmake/winnt/microsft/ruletab.c @@ -0,0 +1,45 @@ +/* RCS $Id: ruletab.c,v 1.1.1.1 2000-09-22 15:33:37 hr Exp $ +-- +-- SYNOPSIS +-- Default initial configuration of dmake. +-- +-- DESCRIPTION +-- Define here the initial set of rules that are defined before +-- dmake performs any processing. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +/* These are control macros for dmake that MUST be defined at some point + * if they are NOT dmake will not work! These are default definitions. They + * may be overridden inside the .STARTUP makefile, they are here + * strictly so that dmake can parse the STARTUP makefile */ + +#include <stdio.h> + +static char *_rules[] = { + "MAXLINELENGTH := 2046", + "MAXPROCESSLIMIT := 4", + "MAXPROCESS := 1", + ".IMPORT .IGNORE: DMAKEROOT SOLARVER UPD INPATH OS UPDMINOREXT" + ".MAKEFILES : makefile.mk makefile", + ".SOURCE : .NULL", +#include "startup.h" + (char *)NULL }; + +char **Rule_tab = _rules; /* for sundry reasons in Get_environment() */ + diff --git a/dmake/winnt/microsft/sysintf.h b/dmake/winnt/microsft/sysintf.h new file mode 100644 index 000000000000..86607fd6d7dc --- /dev/null +++ b/dmake/winnt/microsft/sysintf.h @@ -0,0 +1,58 @@ +/* RCS $Id: sysintf.h,v 1.1.1.1 2000-09-22 15:33:37 hr Exp $ +-- +-- SYNOPSIS +-- Interfaces for sysintf.c +-- +-- DESCRIPTION +-- Abstractions of functions in sysintf.c +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#define DMSTAT stat +#define VOID_LCACHE(l,m) +#define GETPID _psp +#define Hook_std_writes(A) +#define DMSTRLWR(A,B) dstrlwr((A),(B)) + +extern char * tempnam(); +extern char * getcwd(); + +/* for directory cache */ +#define CacheStat(A,B) really_dostat(A,&buf) + +/* +** standard C items +*/ + +/* +** DOS interface standard items +*/ +#define chdir(p) dchdir(p) + +/* +** make parameters +*/ +#ifdef _POSIX_NAME_MAX +#undef _POSIX_NAME_MAX +#endif +#define _POSIX_NAME_MAX 12 + +#ifdef _POSIX_PATH_MAX +#undef _POSIX_PATH_MAX +#endif +#define _POSIX_PATH_MAX 64 diff --git a/dmake/winnt/microsft/tempnam.c b/dmake/winnt/microsft/tempnam.c new file mode 100644 index 000000000000..c3a8fa140f29 --- /dev/null +++ b/dmake/winnt/microsft/tempnam.c @@ -0,0 +1,110 @@ +/* RCS $Id: tempnam.c,v 1.1.1.1 2000-09-22 15:33:37 hr Exp $ +-- +-- SYNOPSIS +-- tempnam +-- +-- DESCRIPTION +-- temp file name generation routines. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +/*LINTLIBRARY*/ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <process.h> + +#if defined(max) +# undef max +#endif +#define max(A,B) (((A)<(B))?(B):(A)) + +extern char *mktemp(); +extern int access(); +int d_access(); + +/* MSC stdio.h defines P_tmpdir, so let's undo it here */ +/* Under DOS leave the default tmpdir pointing here! */ +#ifdef P_tmpdir +#undef P_tmpdir +#endif +static char *P_tmpdir = ""; + +char * +dtempnam(dir, prefix) +char *dir; /* use this directory please (if non-NULL) */ +char *prefix; /* use this (if non-NULL) as filename prefix */ +{ + static int count = 0; + register char *p, *q, *tmpdir; + int tl=0, dl=0, pl; + char buf[30]; + + pl = strlen(P_tmpdir); + + if( (tmpdir = getenv("TMPDIR")) != NULL ) tl = strlen(tmpdir); + else if( (tmpdir = getenv("TMP")) != NULL ) tl = strlen(tmpdir); + if( dir != NULL ) dl = strlen(dir); + + if( (p = malloc((unsigned)(max(max(dl,tl),pl)+13))) == NULL ) + return(NULL); + + *p = '\0'; + + if( (tl == 0) || (d_access( strcpy(p, tmpdir), 0) != 0) ) + if( (dl == 0) || (d_access( strcpy(p, dir), 0) != 0) ) + if( d_access( strcpy(p, P_tmpdir), 0) != 0 ) + if( !prefix ) + prefix = "tp"; + + if(prefix) + { + *(p+strlen(p)+2) = '\0'; + (void)strncat(p, prefix, 2); + } + + sprintf( buf, "%08x", getpid() ); + buf[6]='\0'; + (void)strcat(p, buf ); + sprintf( buf, "%04d", count++ ); + q=p+strlen(p)-6; + *q++ = buf[0]; *q++ = buf[1]; + *q++ = buf[2]; *q++ = buf[3]; + + if( (q = strrchr(p,'.')) != NULL ) *q = '\0'; + + return(p); +} + + + +d_access( name, flag ) +char *name; +int flag; +{ + extern char *DirSepStr; + char *p; + int r; + + if( name == NULL || !*name ) return(1); /* NULL dir means current dir */ + r = access( name, flag ); + p = name+strlen(name)-1; + if(*p != '/' && *p != '\\') strcat( p, DirSepStr ); + + return( r ); +} diff --git a/dmake/winnt/microsft/vpp40/config.mk b/dmake/winnt/microsft/vpp40/config.mk new file mode 100644 index 000000000000..14fe952eac00 --- /dev/null +++ b/dmake/winnt/microsft/vpp40/config.mk @@ -0,0 +1,14 @@ +# Definition of macros for library, and C startup code. +osedir = $(osrdir)$(DIRSEPSTR)$(OSENVIRONMENT) + +.IMPORT .IGNORE : MSC_VER +MSC_VER *= 8.0 + +CFLAGS += -I$(osedir) + +NDB_CFLAGS += -Od -GF -Ge +NDB_LDFLAGS += +NDB_LDLIBS += + +# Redefine rule for making our objects, we don't need mv +%$O : %.c ;% $(CC) -c $(CFLAGS) -Fo$@ $< diff --git a/dmake/winnt/microsft/vpp40/lib.rsp b/dmake/winnt/microsft/vpp40/lib.rsp new file mode 100644 index 000000000000..8b137891791f --- /dev/null +++ b/dmake/winnt/microsft/vpp40/lib.rsp @@ -0,0 +1 @@ + diff --git a/dmake/winnt/microsft/vpp40/mk.bat b/dmake/winnt/microsft/vpp40/mk.bat new file mode 100755 index 000000000000..22917df5eaee --- /dev/null +++ b/dmake/winnt/microsft/vpp40/mk.bat @@ -0,0 +1,32 @@ +md objects +cl -c -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 \nologo -Od -GF -Ge -Foobjects\infer.obj infer.c +cl -c -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 \nologo -Od -GF -Ge -Foobjects\make.obj make.c +cl -c -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 \nologo -Od -GF -Ge -Foobjects\stat.obj stat.c +cl -c -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 \nologo -Od -GF -Ge -Foobjects\expand.obj expand.c +cl -c -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 \nologo -Od -GF -Ge -Foobjects\dmstring.obj dmstring.c +cl -c -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 \nologo -Od -GF -Ge -Foobjects\hash.obj hash.c +cl -c -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 \nologo -Od -GF -Ge -Foobjects\dag.obj dag.c +cl -c -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 \nologo -Od -GF -Ge -Foobjects\dmake.obj dmake.c +cl -c -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 \nologo -Od -GF -Ge -Foobjects\path.obj path.c +cl -c -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 \nologo -Od -GF -Ge -Foobjects\imacs.obj imacs.c +cl -c -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 \nologo -Od -GF -Ge -Foobjects\sysintf.obj sysintf.c +cl -c -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 \nologo -Od -GF -Ge -Foobjects\parse.obj parse.c +cl -c -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 \nologo -Od -GF -Ge -Foobjects\getinp.obj getinp.c +cl -c -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 \nologo -Od -GF -Ge -Foobjects\quit.obj quit.c +cl -c -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 \nologo -Od -GF -Ge -Foobjects\state.obj state.c +cl -c -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 \nologo -Od -GF -Ge -Foobjects\dmdump.obj dmdump.c +cl -c -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 \nologo -Od -GF -Ge -Foobjects\macparse.obj macparse.c +cl -c -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 \nologo -Od -GF -Ge -Foobjects\rulparse.obj rulparse.c +cl -c -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 \nologo -Od -GF -Ge -Foobjects\percent.obj percent.c +cl -c -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 \nologo -Od -GF -Ge -Foobjects\function.obj function.c +cl -c -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 \nologo -Od -GF -Ge -Foobjects\dchdir.obj win95\dchdir.c +cl -c -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 \nologo -Od -GF -Ge -Foobjects\switchar.obj win95\switchar.c +cl -c -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 \nologo -Od -GF -Ge -Foobjects\dstrlwr.obj msdos\dstrlwr.c +cl -c -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 \nologo -Od -GF -Ge -Foobjects\arlib.obj msdos\arlib.c +cl -c -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 \nologo -Od -GF -Ge -Foobjects\dirbrk.obj msdos\dirbrk.c +cl -c -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 \nologo -Od -GF -Ge -Foobjects\tempnam.obj tempnam.c +cl -c -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 \nologo -Od -GF -Ge -Foobjects\ruletab.obj win95\microsft\ruletab.c +cl -c -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 \nologo -Od -GF -Ge -Foobjects\runargv.obj msdos\runargv.c +cl -c -I. -Iwin95 -Iwin95\microsft -Iwin95\microsft\vpp40 \nologo -Od -GF -Ge -Foobjects\rmprq.obj msdos\rmprq.c +rem link /nologo @win95\microsft\vpp40\obj.rsp,dmake.exe,NUL.MAP; +link /out:dmake.exe @.\win95\microsft\vpp40\obj.rsp diff --git a/dmake/winnt/microsft/vpp40/mk.cmd b/dmake/winnt/microsft/vpp40/mk.cmd new file mode 100755 index 000000000000..5fcc801fae91 --- /dev/null +++ b/dmake/winnt/microsft/vpp40/mk.cmd @@ -0,0 +1,31 @@ +md objects +cl -c -I. -Iwinnt -Iwinnt\microsft -Iwinnt\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\infer.obj infer.c +cl -c -I. -Iwinnt -Iwinnt\microsft -Iwinnt\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\make.obj make.c +cl -c -I. -Iwinnt -Iwinnt\microsft -Iwinnt\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\stat.obj stat.c +cl -c -I. -Iwinnt -Iwinnt\microsft -Iwinnt\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\expand.obj expand.c +cl -c -I. -Iwinnt -Iwinnt\microsft -Iwinnt\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\dmstring.obj dmstring.c +cl -c -I. -Iwinnt -Iwinnt\microsft -Iwinnt\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\hash.obj hash.c +cl -c -I. -Iwinnt -Iwinnt\microsft -Iwinnt\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\dag.obj dag.c +cl -c -I. -Iwinnt -Iwinnt\microsft -Iwinnt\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\dmake.obj dmake.c +cl -c -I. -Iwinnt -Iwinnt\microsft -Iwinnt\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\path.obj path.c +cl -c -I. -Iwinnt -Iwinnt\microsft -Iwinnt\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\imacs.obj imacs.c +cl -c -I. -Iwinnt -Iwinnt\microsft -Iwinnt\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\sysintf.obj sysintf.c +cl -c -I. -Iwinnt -Iwinnt\microsft -Iwinnt\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\parse.obj parse.c +cl -c -I. -Iwinnt -Iwinnt\microsft -Iwinnt\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\getinp.obj getinp.c +cl -c -I. -Iwinnt -Iwinnt\microsft -Iwinnt\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\quit.obj quit.c +cl -c -I. -Iwinnt -Iwinnt\microsft -Iwinnt\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\state.obj state.c +cl -c -I. -Iwinnt -Iwinnt\microsft -Iwinnt\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\dmdump.obj dmdump.c +cl -c -I. -Iwinnt -Iwinnt\microsft -Iwinnt\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\macparse.obj macparse.c +cl -c -I. -Iwinnt -Iwinnt\microsft -Iwinnt\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\rulparse.obj rulparse.c +cl -c -I. -Iwinnt -Iwinnt\microsft -Iwinnt\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\percent.obj percent.c +cl -c -I. -Iwinnt -Iwinnt\microsft -Iwinnt\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\function.obj function.c +cl -c -I. -Iwinnt -Iwinnt\microsft -Iwinnt\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\dchdir.obj winnt\dchdir.c +cl -c -I. -Iwinnt -Iwinnt\microsft -Iwinnt\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\dstrlwr.obj msdos\dstrlwr.c +cl -c -I. -Iwinnt -Iwinnt\microsft -Iwinnt\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\arlib.obj msdos\arlib.c +cl -c -I. -Iwinnt -Iwinnt\microsft -Iwinnt\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\dirbrk.obj msdos\dirbrk.c +cl -c -I. -Iwinnt -Iwinnt\microsft -Iwinnt\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\tempnam.obj winnt\microsft\tempnam.c +cl -c -I. -Iwinnt -Iwinnt\microsft -Iwinnt\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\ruletab.obj winnt\microsft\ruletab.c +cl -c -I. -Iwinnt -Iwinnt\microsft -Iwinnt\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\runargv.obj msdos\runargv.c +cl -c -I. -Iwinnt -Iwinnt\microsft -Iwinnt\microsft\vpp40 /nologo -Od -GF -Ge -Foobjects\rmprq.obj msdos\rmprq.c +link /nologo /out:dmake.exe @fix95nt\winnt\microsft\vpp40\obj.rsp +copy winnt\microsft\vpp40\template.mk startup\config.mk diff --git a/dmake/winnt/microsft/vpp40/obj.rsp b/dmake/winnt/microsft/vpp40/obj.rsp new file mode 100644 index 000000000000..5c00dab6c29c --- /dev/null +++ b/dmake/winnt/microsft/vpp40/obj.rsp @@ -0,0 +1,28 @@ +objects\infer.obj +objects\make.obj +objects\stat.obj +objects\expand.obj +objects\dmstring.obj +objects\hash.obj +objects\dag.obj +objects\dmake.obj +objects\path.obj +objects\imacs.obj +objects\sysintf.obj +objects\parse.obj +objects\getinp.obj +objects\quit.obj +objects\state.obj +objects\dmdump.obj +objects\macparse.obj +objects\rulparse.obj +objects\percent.obj +objects\function.obj +objects\dchdir.obj +objects\dstrlwr.obj +objects\arlib.obj +objects\dirbrk.obj +objects\tempnam.obj +objects\ruletab.obj +objects\runargv.obj +objects\rmprq.obj diff --git a/dmake/winnt/microsft/vpp40/public.h b/dmake/winnt/microsft/vpp40/public.h new file mode 100644 index 000000000000..f867838344c5 --- /dev/null +++ b/dmake/winnt/microsft/vpp40/public.h @@ -0,0 +1,166 @@ +/* RCS $Id: public.h,v 1.1.1.1 2000-09-22 15:33:37 hr Exp $ +-- WARNING -- This file is AUTOMATICALLY GENERATED DO NOT EDIT IT +-- +-- +-- SYNOPSIS +-- Local functions exported to be visible by others. +-- +-- DESCRIPTION +-- This file is generated by 'genpub'. Function declarations +-- that appear in this file are extracted by 'genpub' from +-- source files. Any function in the source file whose definition +-- appears like: +-- +-- PUBLIC return_type +-- function( arg_list ); +-- type_expr1 arg1; +-- ... +-- +-- has its definition extracted and a line of the form: +-- +-- return_type function ANSI((type_expr1,type_expr2,...)); +-- +-- entered into the output file. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#ifndef _DMAKE_PUBLIC_h +#define _DMAKE_PUBLIC_h + +#ifdef EXTERN +#undef EXTERN +#endif +#if defined(DEFINE_DMAKE_VARIABLES) +#define EXTERN +#else +#define EXTERN extern +#endif + +/***** genpub: Begin list of generated function headers */ +void Infer_recipe ANSI((CELLPTR, CELLPTR)); +int Make_targets ANSI(()); +int Make ANSI((CELLPTR, CELLPTR)); +int Exec_commands ANSI((CELLPTR)); +void Print_cmnd ANSI((char *, int, int)); +int Push_dir ANSI((char *, char *, int)); +void Pop_dir ANSI((int)); +void Append_line ANSI((char *, int, FILE *, char *, int, int)); +void Stat_target ANSI((CELLPTR, int, int)); +char *Expand ANSI((char *)); +char *Apply_edit ANSI((char *, char *, char *, int, int)); +void Map_esc ANSI((char *)); +char* Apply_modifiers ANSI((int, char *)); +char* Tokenize ANSI((char *, char *, char, int)); +char* ScanToken ANSI((char *, char **, int)); +char *DmStrJoin ANSI((char *, char *, int, int)); +char *DmStrAdd ANSI((char *, char *, int)); +char *DmStrApp ANSI((char *, char *)); +char *DmStrDup ANSI((char *)); +char *DmStrDup2 ANSI((char *)); +char *DmStrPbrk ANSI((char *, char *)); +char *DmStrSpn ANSI((char *, char *)); +char *DmStrStr ANSI((char *, char *)); +char *DmSubStr ANSI((char *, char *)); +uint16 Hash ANSI((char *, uint32 *)); +HASHPTR Get_name ANSI((char *, HASHPTR *, int)); +HASHPTR Search_table ANSI((HASHPTR *, char *, uint16 *, uint32 *)); +HASHPTR Push_macro ANSI((HASHPTR)); +HASHPTR Pop_macro ANSI((HASHPTR)); +HASHPTR Def_macro ANSI((char *, char *, int)); +CELLPTR Def_cell ANSI((char *)); +LINKPTR Add_prerequisite ANSI((CELLPTR, CELLPTR, int, int)); +void Clear_prerequisites ANSI((CELLPTR)); +int Test_circle ANSI((CELLPTR, int)); +STRINGPTR Def_recipe ANSI((char *, STRINGPTR, int, int)); +t_attr Rcp_attribute ANSI((char *)); +void main ANSI((int, char **)); +FILE *Openfile ANSI((char *, int, int)); +FILE *Closefile ANSI(()); +FILE *Search_file ANSI((char *, char **)); +char *Filename ANSI(()); +int Nestlevel ANSI(()); +FILE *TryFiles ANSI((LINKPTR)); +void Fatal ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Error ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void Warning ANSI((ARG (char *,fmt),ARG (va_alist_type, va_alist))); +void No_ram ANSI(()); +void Usage ANSI((int)); +void Version ANSI(()); +char *Get_suffix ANSI((char *)); +char *Basename ANSI((char *)); +char *Filedir ANSI((char *)); +char *Build_path ANSI((char *, char *)); +void Make_rules ANSI(()); +void Create_macro_vars ANSI(()); +time_t Do_stat ANSI((char *, char *, char **, int)); +int Do_touch ANSI((char *, char *, char **)); +void Void_lib_cache ANSI((char *, char *)); +time_t Do_time ANSI(()); +int Do_cmnd ANSI((char *, int, int, CELLPTR, int, int, int)); +char ** Pack_argv ANSI((int, int, char *)); +char *Read_env_string ANSI((char *)); +int Write_env_string ANSI((char *, char *)); +void ReadEnvironment ANSI(()); +void Catch_signals ANSI((void (*)())); +void Clear_signals ANSI(()); +void Prolog ANSI((int, char* [])); +void Epilog ANSI((int)); +char *Get_current_dir ANSI(()); +int Set_dir ANSI((char*)); +char Get_switch_char ANSI(()); +FILE* Get_temp ANSI((char **, char *, int)); +FILE *Start_temp ANSI((char *, CELLPTR, char **)); +void Open_temp_error ANSI((char *, char *)); +void Link_temp ANSI((CELLPTR, FILE *, char *)); +void Close_temp ANSI((CELLPTR, FILE *)); +void Unlink_temp_files ANSI((CELLPTR)); +void Handle_result ANSI((int, int, int, CELLPTR)); +void Update_time_stamp ANSI((CELLPTR)); +int Remove_file ANSI((char *)); +void Parse ANSI((FILE *)); +int Get_line ANSI((char *, FILE *)); +char *Do_comment ANSI((char *, char **, int)); +char *Get_token ANSI((TKSTRPTR, char *, int)); +void Quit ANSI(()); +void Read_state ANSI(()); +void Write_state ANSI(()); +int Check_state ANSI((CELLPTR, STRINGPTR *, int)); +void Dump ANSI(()); +void Dump_recipe ANSI((STRINGPTR)); +int Parse_macro ANSI((char *, int)); +int Macro_op ANSI((char *)); +int Parse_rule_def ANSI((int *)); +int Rule_op ANSI((char *)); +void Add_recipe_to_list ANSI((char *, int, int)); +void Bind_rules_to_targets ANSI((int)); +int Set_group_attributes ANSI((char *)); +DFALINKPTR Match_dfa ANSI((char *)); +void Check_circle_dfa ANSI(()); +void Add_nfa ANSI((char *)); +char *Exec_function ANSI((char *)); +int dchdir ANSI((char *)); +void dstrlwr ANSI((char *, char *)); +time_t seek_arch ANSI((char*, char*)); +int touch_arch ANSI((char*, char*)); +int If_root_path ANSI((char *)); +int runargv ANSI((CELLPTR, int, int, int, int, char *)); +void Clean_up_processes ANSI(()); +int Wait_for_child ANSI((int, int)); +void Remove_prq ANSI((CELLPTR)); + +#endif diff --git a/dmake/winnt/microsft/vpp40/runargv.c b/dmake/winnt/microsft/vpp40/runargv.c new file mode 100644 index 000000000000..fd0cbe355109 --- /dev/null +++ b/dmake/winnt/microsft/vpp40/runargv.c @@ -0,0 +1,290 @@ +Blake sent me the wrong one. + +/* RCS $Id: runargv.c,v 1.1.1.1 2000-09-22 15:33:37 hr Exp $ +-- +-- SYNOPSIS +-- Invoke a sub process. +-- +-- DESCRIPTION +-- Use the standard methods of executing a sub process. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +#include <process.h> +#include <errno.h> +#include <signal.h> +#include "extern.h" +#include "sysintf.h" + +extern char **environ; + +typedef struct prp { + char *prp_cmd; + int prp_group; + int prp_ignore; + int prp_last; + int prp_shell; + struct prp *prp_next; +} RCP, *RCPPTR; + +typedef struct pr { + int pr_valid; + int pr_pid; + CELLPTR pr_target; + int pr_ignore; + int pr_last; + RCPPTR pr_recipe; + RCPPTR pr_recipe_end; + char *pr_dir; +} PR; + +static PR *_procs = NIL(PR); +static int _proc_cnt = 0; +static int _abort_flg= FALSE; +static int _use_i = -1; +static int _do_upd = 0; + +static void _add_child ANSI((int, CELLPTR, int, int)); +static void _attach_cmd ANSI((char *, int, int, CELLPTR, int, int)); +static void _finished_child ANSI((int, int)); +static int _running ANSI((CELLPTR)); + +PUBLIC int +runargv(target, ignore, group, last, shell, cmd) +CELLPTR target; +int ignore; +int group; +int last; +int shell; +char *cmd; +{ + extern int errno; + extern char *sys_errlist[]; + int pid; + char **argv; + + if( _running(target) /*&& Max_proc != 1*/ ) { + /* The command will be executed when the previous recipe + * line completes. */ + _attach_cmd( cmd, group, ignore, target, last, shell ); + return(1); + } + + while( _proc_cnt == Max_proc ) + if( Wait_for_child(FALSE, -1) == -1 ) Fatal( "Lost a child %d", errno ); + + argv = Pack_argv( group, shell, cmd ); + + pid = _spawnvpe(_P_NOWAIT, argv[0], argv, environ); + if (pid == -1) { /* failed */ + Error("%s: %s", argv[0], sys_errlist[errno]); + Handle_result(-1, ignore, _abort_flg, target); + return(-1); + } else + _add_child(pid, target, ignore, last); + + return(1); +} + + +PUBLIC int +Wait_for_child( abort_flg, pid ) +int abort_flg; +int pid; +{ + int wid; + int status; + int waitchild; + + waitchild = (pid == -1)? FALSE : Wait_for_completion; + + do { + if( (wid = wait(&status)) == -1 ) return(-1); + + _abort_flg = abort_flg; + _finished_child(wid, status); + _abort_flg = FALSE; + } while( waitchild && pid != wid ); + + return(0); +} + + +PUBLIC void +Clean_up_processes() +{ + register int i; + + if( _procs != NIL(PR) ) { + for( i=0; i<Max_proc; i++ ) + if( _procs[i].pr_valid ) + kill(_procs[i].pr_pid, SIGTERM); + + while( Wait_for_child(TRUE, -1) != -1 ); + } +} + + +static void +_add_child( pid, target, ignore, last ) +int pid; +CELLPTR target; +int ignore; +int last; +{ + register int i; + register PR *pp; + + if( _procs == NIL(PR) ) { + TALLOC( _procs, Max_proc, PR ); + } + + if( (i = _use_i) == -1 ) + for( i=0; i<Max_proc; i++ ) + if( !_procs[i].pr_valid ) + break; + + pp = _procs+i; + + pp->pr_valid = 1; + pp->pr_pid = pid; + pp->pr_target = target; + pp->pr_ignore = ignore; + pp->pr_last = last; + pp->pr_dir = DmStrDup(Get_current_dir()); + + Current_target = NIL(CELL); + + _proc_cnt++; + + if( Wait_for_completion ) Wait_for_child( FALSE, pid ); +} + + +static void +_finished_child(pid, status) +int pid; +int status; +{ + register int i; + register PR *pp; + char *dir; + + for( i=0; i<Max_proc; i++ ) + if( _procs[i].pr_valid && _procs[i].pr_pid == pid ) + break; + + /* Some children we didn't make esp true if using /bin/sh to execute a + * a pipe and feed the output as a makefile into dmake. */ + if( i == Max_proc ) return; + _procs[i].pr_valid = 0; + _proc_cnt--; + dir = DmStrDup(Get_current_dir()); + Set_dir( _procs[i].pr_dir ); + + if( _procs[i].pr_recipe != NIL(RCP) && !_abort_flg ) { + RCPPTR rp = _procs[i].pr_recipe; + + + Current_target = _procs[i].pr_target; + Handle_result( status, _procs[i].pr_ignore, FALSE, _procs[i].pr_target ); + Current_target = NIL(CELL); + + if ( _procs[i].pr_target->ce_attr & A_ERROR ) { + Unlink_temp_files( _procs[i].pr_target ); + _procs[i].pr_last = TRUE; + goto ABORT_REMAINDER_OF_RECIPE; + } + + _procs[i].pr_recipe = rp->prp_next; + + _use_i = i; + runargv( _procs[i].pr_target, rp->prp_ignore, rp->prp_group, + rp->prp_last, rp->prp_shell, rp->prp_cmd ); + _use_i = -1; + + FREE( rp->prp_cmd ); + FREE( rp ); + + if( _proc_cnt == Max_proc ) Wait_for_child( FALSE, -1 ); + } + else { + Unlink_temp_files( _procs[i].pr_target ); + Handle_result(status,_procs[i].pr_ignore,_abort_flg,_procs[i].pr_target); + + ABORT_REMAINDER_OF_RECIPE: + if( _procs[i].pr_last ) { + FREE(_procs[i].pr_dir ); + + if( !Doing_bang ) Update_time_stamp( _procs[i].pr_target ); + } + } + + Set_dir(dir); + FREE(dir); +} + + +static int +_running( cp ) +CELLPTR cp; +{ + register int i; + + if( !_procs ) return(FALSE); + + for( i=0; i<Max_proc; i++ ) + if( _procs[i].pr_valid && + _procs[i].pr_target == cp ) + break; + + return( i != Max_proc ); +} + + +static void +_attach_cmd( cmd, group, ignore, cp, last, shell ) +char *cmd; +int group; +int ignore; +CELLPTR cp; +int last; +int shell; +{ + register int i; + RCPPTR rp; + + for( i=0; i<Max_proc; i++ ) + if( _procs[i].pr_valid && + _procs[i].pr_target == cp ) + break; + + TALLOC( rp, 1, RCP ); + rp->prp_cmd = DmStrDup(cmd); + rp->prp_group = group; + rp->prp_ignore= ignore; + rp->prp_last = last; + rp->prp_shell = shell; + + if( _procs[i].pr_recipe == NIL(RCP) ) + _procs[i].pr_recipe = _procs[i].pr_recipe_end = rp; + else { + _procs[i].pr_recipe_end->prp_next = rp; + _procs[i].pr_recipe_end = rp; + } +} diff --git a/dmake/winnt/microsft/vpp40/template.mk b/dmake/winnt/microsft/vpp40/template.mk new file mode 100644 index 000000000000..e53922df68c3 --- /dev/null +++ b/dmake/winnt/microsft/vpp40/template.mk @@ -0,0 +1,7 @@ +# ** Default build configuration for dmake. +# ** DO NOT PLACE LOCAL DEFINITIONS INTO THIS FILE IT IS AUTO GENERATED +# ** USE "startup/local.mk" for those. + + OS *:= winnt + OSRELEASE *:= microsft + OSENVIRONMENT *:= vpp40 diff --git a/dmake/winnt/microsft/vpp40/tempnam.c b/dmake/winnt/microsft/vpp40/tempnam.c new file mode 100644 index 000000000000..c27da47c7602 --- /dev/null +++ b/dmake/winnt/microsft/vpp40/tempnam.c @@ -0,0 +1,110 @@ +/* RCS $Id: tempnam.c,v 1.1.1.1 2000-09-22 15:33:37 hr Exp $ +-- +-- SYNOPSIS +-- tempnam +-- +-- DESCRIPTION +-- temp file name generation routines. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +/*LINTLIBRARY*/ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <dos.h> + +#if defined(max) +# undef max +#endif +#define max(A,B) (((A)<(B))?(B):(A)) + +extern char *mktemp(); +extern int access(); +int d_access(); + +/* MSC stdio.h defines P_tmpdir, so let's undo it here */ +/* Under DOS leave the default tmpdir pointing here! */ +#ifdef P_tmpdir +#undef P_tmpdir +#endif +static char *P_tmpdir = ""; + +char * +tempnam(dir, prefix) +char *dir; /* use this directory please (if non-NULL) */ +char *prefix; /* use this (if non-NULL) as filename prefix */ +{ + static int count = 0; + register char *p, *q, *tmpdir; + int tl=0, dl=0, pl; + char buf[30]; + + pl = strlen(P_tmpdir); + + if( (tmpdir = getenv("TMPDIR")) != NULL ) tl = strlen(tmpdir); + else if( (tmpdir = getenv("TMP")) != NULL ) tl = strlen(tmpdir); + if( dir != NULL ) dl = strlen(dir); + + if( (p = malloc((unsigned)(max(max(dl,tl),pl)+13))) == NULL ) + return(NULL); + + *p = '\0'; + + if( (tl == 0) || (d_access( strcpy(p, tmpdir), 0) != 0) ) + if( (dl == 0) || (d_access( strcpy(p, dir), 0) != 0) ) + if( d_access( strcpy(p, P_tmpdir), 0) != 0 ) + if( !prefix ) + prefix = "tp"; + + if(prefix) + { + *(p+strlen(p)+2) = '\0'; + (void)strncat(p, prefix, 2); + } + + sprintf( buf, "%08x", _psp ); + buf[6]='\0'; + (void)strcat(p, buf ); + sprintf( buf, "%04d", count++ ); + q=p+strlen(p)-6; + *q++ = buf[0]; *q++ = buf[1]; + *q++ = buf[2]; *q++ = buf[3]; + + if( (q = strrchr(p,'.')) != NULL ) *q = '\0'; + + return(p); +} + + + +d_access( name, flag ) +char *name; +int flag; +{ + extern char *DirSepStr; + char *p; + int r; + + if( name == NULL || !*name ) return(1); /* NULL dir means current dir */ + r = access( name, flag ); + p = name+strlen(name)-1; + if(*p != '/' && *p != '\\') strcat( p, DirSepStr ); + + return( r ); +} diff --git a/dmake/winnt/startup.h b/dmake/winnt/startup.h new file mode 100644 index 000000000000..d1bfdb5688e4 --- /dev/null +++ b/dmake/winnt/startup.h @@ -0,0 +1,29 @@ +/* RCS $Id: startup.h,v 1.1.1.1 2000-09-22 15:33:37 hr Exp $ +-- +-- SYNOPSIS +-- Definition of MAKESTARTUP +-- +-- DESCRIPTION +-- Default MAKESTARTUP value defining where dmake locates the +-- startup file. +-- +-- AUTHOR +-- Dennis Vadura, dvadura@dmake.wticorp.com +-- +-- WWW +-- http://dmake.wticorp.com/ +-- +-- COPYRIGHT +-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. +-- +-- This program is NOT free software; you can redistribute it and/or +-- modify it under the terms of the Software License Agreement Provided +-- in the file <distribution-root>/readme/license.txt. +-- +-- LOG +-- Use cvs log to obtain detailed change logs. +*/ + +/*"MAKESTARTUP := $(MAKECMD:d)startup/startup.mk",*/ +"MAKESTARTUP := $(DMAKEROOT)\\startup.mk", + |