home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-01-29 | 40.0 KB | 1,474 lines |
- Newsgroups: comp.sources.misc
- From: dvadura@plg.waterloo.edu (Dennis Vadura)
- Subject: v27i133: dmake - dmake Version 3.8, Part32/41
- Message-ID: <1992Jan29.164849.1352@sparky.imd.sterling.com>
- X-Md4-Signature: 26404e9c6416b5207ceb89bdb00110db
- Date: Wed, 29 Jan 1992 16:48:49 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: dvadura@plg.waterloo.edu (Dennis Vadura)
- Posting-number: Volume 27, Issue 133
- Archive-name: dmake/part32
- Environment: Atari-ST, Coherent, Mac, MSDOS, OS/2, UNIX
- Supersedes: dmake: Volume 19, Issue 22-58
-
- ---- Cut Here and feed the following to sh ----
- # this is dmake.shar.32 (part 32 of a multipart archive)
- # do not concatenate these parts, unpack them in order with /bin/sh
- # file dmake/state.c continued
- #
- if test ! -r _shar_seq_.tmp; then
- echo 'Please unpack part 1 first!'
- exit 1
- fi
- (read Scheck
- if test "$Scheck" != 32; then
- echo Please unpack part "$Scheck" next!
- exit 1
- else
- exit 0
- fi
- ) < _shar_seq_.tmp || exit 1
- if test -f _shar_wnt_.tmp; then
- sed 's/^X//' << 'SHAR_EOF' >> 'dmake/state.c' &&
- }
- X
- X
- static int
- _my_fgets(buf, size, fp)
- char *buf;
- int size;
- FILE *fp;
- {
- X char *p;
- X
- X if( fgets(buf, size, fp) == NULL ) return(0);
- X
- X if( (p=strrchr(buf,'\n')) != NIL(char) ) *p='\0';
- X return(1);
- }
- SHAR_EOF
- chmod 0640 dmake/state.c ||
- echo 'restore of dmake/state.c failed'
- Wc_c="`wc -c < 'dmake/state.c'`"
- test 5527 -eq "$Wc_c" ||
- echo 'dmake/state.c: original size 5527, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= dmake/stdmacs.h ==============
- if test -f 'dmake/stdmacs.h' -a X"$1" != X"-c"; then
- echo 'x - skipping dmake/stdmacs.h (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- sed 's/^X//' << 'SHAR_EOF' > 'dmake/stdmacs.h' &&
- /* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/stdmacs.h,v 1.1 1992/01/24 03:29:36 dvadura 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@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.
- --
- -- LOG
- -- $Log: stdmacs.h,v $
- X * Revision 1.1 1992/01/24 03:29:36 dvadura
- X * dmake Version 3.8, Initial revision
- X *
- */
- X
- #ifndef MACROS_h
- #define MACROS_h
- X
- /* stupid AIX and Mac MPW define __STDC__ as special, but defined(__STDC__) is false, and
- X * it's value is nothing */
- #if !defined(__STDC__) && !defined(_AIX) && !defined(_MPW)
- #define __STDC__ 0
- #endif
- X
- #if __STDC__ || defined(__TURBOC__)
- #define ANSI(x) x
- #else
- #define ANSI(x) ()
- #endif
- X
- #define NIL(p) ((p*)NULL)
- X
- #if !defined(atarist)
- #define offsetof(type,id) ((size_t)&((type*)NULL)->id)
- #endif
- X
- #define FALSE 0
- #define TRUE 1
- X
- #define PUBLIC
- X
- #endif
- X
- SHAR_EOF
- chmod 0640 dmake/stdmacs.h ||
- echo 'restore of dmake/stdmacs.h failed'
- Wc_c="`wc -c < 'dmake/stdmacs.h'`"
- test 1985 -eq "$Wc_c" ||
- echo 'dmake/stdmacs.h: original size 1985, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= dmake/struct.h ==============
- if test -f 'dmake/struct.h' -a X"$1" != X"-c"; then
- echo 'x - skipping dmake/struct.h (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- sed 's/^X//' << 'SHAR_EOF' > 'dmake/struct.h' &&
- /* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/struct.h,v 1.1 1992/01/24 03:29:32 dvadura 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@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.
- --
- -- LOG
- -- $Log: struct.h,v $
- X * Revision 1.1 1992/01/24 03:29:32 dvadura
- X * dmake Version 3.8, Initial revision
- X *
- */
- X
- #ifndef _STRUCT_INCLUDED_
- #define _STRUCT_INCLUDED_
- X
- typedef uint32 t_attr;
- X
- /* The following struct is the cell used in the hash table.
- X * NOTE: It contains the actual hash value. This allows the hash table
- X * insertion to compare hash values and to do a string compare only
- X * for entries that have matching hash_key values. This elliminates
- X * 99.9999% of all extraneous string compare operations when searching
- X * a hash table chain for matching entries. */
- X
- typedef struct hcell {
- X struct hcell *ht_next; /* next entry in the hash table */
- X char *ht_name; /* name of this cell */
- X char *ht_value; /* cell value if and */
- X uint32 ht_hash; /* actual hash_value of cell */
- X int ht_flag; /* flags belonging to hash entry */
- X
- X /* NOTE: some macros have corresponding variables defined
- X * that control program behaviour. For these macros a
- X * bit of ht_flag indicates the variable value will be set, and the
- X * type of the value that will be set.
- X *
- X * The struct below contains a mask for bit variables, and a
- X * pointer to the global STATIC location for that variable.
- X * String and char variables point to the same place as ht_value
- X * and must be updated when ht_value changes, bit variables must
- X * have their value recomputed. See Def_macro code for more
- X * details.
- X *
- X * NOTE: Macro variables and Targets are always distinct. Thus
- X * the value union contains pointers back at cells that own
- X * a particular name entry. A conflict in this can never
- X * arise, ie pointers at cells will never be used as
- X * values for a macro variable, since the cell and macro
- X * name spaces are completely distinct. */
- X
- X struct {
- X int mv_mask; /* bit mask for bit variable */
- X union {
- X char** mv_svar;/* ptr to string valued glob var */
- X char* mv_cvar;/* ptr to char valued glob var */
- X t_attr* mv_bvar;/* ptr to bit valued glob var */
- X int* mv_ivar;/* ptr to int valued glob var */
- X
- X struct {
- X struct tcell* ht_owner;/* ptr to CELL owning name */
- X struct tcell* ht_root; /* root ptr for explode */
- X } ht;
- X } val;
- X } var; /* variable's static equivalent */
- } HASH, *HASHPTR;
- X
- #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
- X
- X
- X
- /* This struct holds the list of temporary files that have been created.
- X * It gets unlinked when Quit is called due to an execution error */
- typedef struct flst {
- X char *fl_name; /* file name */
- X FILE *fl_file; /* the open file */
- X struct flst *fl_next; /* pointer to next file */
- } FILELIST, *FILELISTPTR;
- X
- X
- X
- /* This is the structure of a target cell in the dag which represents the
- X * graph of dependencies. Each possible target is represented as a cell.
- X *
- X * Each cell contains a pointer to the hash table entry for this cell.
- X * The hash table entry records the name of the cell. */
- X
- typedef struct tcell {
- X struct hcell *ce_name; /* name of this cell */
- X
- X struct tcell *ce_all; /* link for grouping UPDATEALL cells*/
- X struct tcell *ce_setdir; /* SETDIR ROOT pointer for this cell*/
- X struct tcell *ce_link; /* link for temporary list making */
- X
- X struct lcell *ce_prq; /* list of prerequisites for cell */
- X struct lcell *ce_indprq; /* indirect prerequisites for % cell*/
- X
- X struct str *ce_recipe; /* recipe for making this cell */
- X FILELISTPTR ce_files; /* list of temporary files for cell */
- X
- X char *ce_per; /* value of % in %-meta expansion */
- X char *ce_fname; /* file name associated with target */
- X char *ce_lib; /* archive name, if A_LIBRARYM */
- X char *ce_dir; /* value for .SETDIR attribute */
- X
- X int ce_count; /* value for :: recipe set */
- X int ce_index; /* value of count for next :: child */
- X int ce_flag; /* all kinds of goodies */
- X t_attr ce_attr; /* attributes for this target */
- X time_t ce_time; /* time stamp value of target if any*/
- } CELL, *CELLPTR;
- X
- #define CE_NAME ce_name->ht_name
- #define CE_RECIPE ce_recipe
- #define CE_PRQ ce_prq
- X
- X
- /* This struct represents that used by Get_token to return and control
- X * access to a token list inside a particular string. This gives the
- X * ability to access non overlapping tokens simultaneously from
- X * multiple strings. */
- X
- typedef struct {
- X char *tk_str; /* the string to search for tokens */
- X char tk_cchar; /* current char under *str */
- X int tk_quote; /* if we are scanning a quoted str */
- } TKSTR, *TKSTRPTR;
- X
- X
- X
- /* Below is the struct used to represent a string. It points at possibly
- X * another string, since the set of rules for making a target is a collection
- X * of strings. */
- X
- X
- typedef struct str {
- X char *st_string; /* the string value */
- X struct str *st_next; /* pointer to the next string */
- X t_attr st_attr; /* attr for rule operations */
- } STRING, *STRINGPTR;
- X
- X
- /* The next struct is used to link together prerequisite lists */
- X
- typedef struct lcell {
- X struct tcell *cl_prq; /* link to a prerequisite */
- X struct lcell *cl_next; /* next cell on dependency list */
- X int cl_flag; /* flags for link cell */
- } LINK, *LINKPTR;
- X
- X
- X
- /* These structs are used in processing of the % rules, and in building
- X * the NFA machine that is used to match an arbitrary target string to
- X * one of the % rules that is represented by each DFA */
- X
- typedef int16 statecnt; /* limits the max number of dfa states */
- X
- X
- /* Each state of the DFA contains four pieces of information. */
- typedef struct st {
- X struct st *no_match; /* state to go to if no match */
- X struct st *match; /* state to go to if we do match */
- X char symbol; /* symbol on which we transit */
- X char action; /* action to perform if match */
- } STATE, *STATEPTR;
- X
- X
- /* Each DFA machine looks like this. It must have two pointers that represent
- X * the value of % in the matched string, and it contains a pointer into the
- X * current state, as well as the array of all states. */
- typedef struct {
- X char *pstart; /* start of % string match */
- X char *pend; /* end of % string match */
- X STATEPTR c_state; /* current DFA state */
- X CELLPTR node; /* % target represented by this DFA */
- X STATEPTR states; /* table of states for the DFA */
- } DFA, *DFAPTR;
- X
- X
- /* An NFA is a collection of DFA's. For each DFA we must know it's current
- X * state and where the next NFA is. */
- typedef struct nfa_machine {
- X DFAPTR dfa; /* The DFA for this eps transition */
- X char status; /* DFA state */
- X struct nfa_machine *next; /* the next DFA in NFA */
- } NFA, *NFAPTR;
- X
- X
- X
- /* The next struct is used to link together DFA nodes for inference. */
- X
- typedef struct dfal {
- X struct tcell *dl_meta; /* link to %-meta cell */
- X struct dfal *dl_next; /* next cell on matched DFA list*/
- X struct dfal *dl_prev; /* prev cell on matched DFA list*/
- X struct dfal *dl_member; /* used during subset calc */
- X char dl_delete; /* used during subset calc */
- X char *dl_per; /* value of % for matched DFA */
- X statecnt dl_state; /* matched state of the DFA */
- X int dl_prep; /* repetion count for the cell */
- } DFALINK, *DFALINKPTR;
- X
- X
- /* This struct is used to store the stack of DFA sets during inference */
- typedef struct dfst {
- X DFALINKPTR df_set; /* pointer to the set */
- X struct dfst *df_next; /* next element in the stack */
- } DFASET, *DFASETPTR;
- X
- X
- /* We need sets of items during inference, here is the item, we form sets
- X * by linking them together. */
- X
- typedef struct ic {
- X CELLPTR ic_meta; /* Edge we used to make this cell*/
- X DFALINKPTR ic_dfa; /* Dfa that we matched against */
- X CELLPTR ic_setdirroot; /* setdir root pointer for cell */
- X DFASET ic_dfastack; /* set of dfas we're working with*/
- X int ic_dmax; /* max depth of cycles in graph */
- X char *ic_name; /* name of the cell to insert */
- X char *ic_dir; /* dir to CD to prior to recurse */
- X struct ic *ic_next; /* next pointer to link */
- X struct ic *ic_link; /* link all ICELL'S together */
- X struct ic *ic_parent; /* pointer to post-requisite */
- X char ic_flag; /* flag, used for NOINFER only */
- X char ic_exists; /* TRUE if prerequisite exists */
- } ICELL, *ICELLPTR;
- X
- #endif
- SHAR_EOF
- chmod 0640 dmake/struct.h ||
- echo 'restore of dmake/struct.h failed'
- Wc_c="`wc -c < 'dmake/struct.h'`"
- test 9761 -eq "$Wc_c" ||
- echo 'dmake/struct.h: original size 9761, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= dmake/sysintf.c ==============
- if test -f 'dmake/sysintf.c' -a X"$1" != X"-c"; then
- echo 'x - skipping dmake/sysintf.c (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- sed 's/^X//' << 'SHAR_EOF' > 'dmake/sysintf.c' &&
- /* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/sysintf.c,v 1.1 1992/01/24 03:27:08 dvadura 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()
- -- STAT()
- -- Remove_prq()
- --
- -- C-LIB SPECIFIC: (should be present in your C-lib)
- -- utime()
- -- time()
- -- getenv()
- -- putenv()
- -- getcwd()
- -- signal()
- -- chdir()
- -- tempnam()
- --
- -- 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.
- --
- -- LOG
- -- $Log: sysintf.c,v $
- X * Revision 1.1 1992/01/24 03:27:08 dvadura
- X * dmake Version 3.8, Initial revision
- X *
- */
- X
- #include "extern.h"
- #include "sysintf.h"
- X
- /*
- ** 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 _strdup the name and return make the
- ** pointer pointed at by sym point at it. Not handled for now!
- */
- PUBLIC time_t
- Do_stat(name, lib, member)
- char *name;
- char *lib;
- char **member;
- {
- X struct stat buf;
- X time_t seek_arch();
- X
- X if( member != NIL(char *) )
- X Fatal("Library symbol names not supported");
- X
- X buf.st_mtime = (time_t)0L;
- X if( lib != NIL(char) )
- X return( seek_arch(basename(name), lib) );
- X else if( strlen(basename(name)) > _POSIX_NAME_MAX )
- X return((time_t)0L);
- X else
- X return( (STAT(name,&buf)==-1 || (Augmake && (buf.st_mode & S_IFDIR)))
- X ? (time_t)0L
- X : (time_t) buf.st_mtime
- X );
- }
- X
- X
- X
- /* Touch existing file to force modify time to present.
- X */
- PUBLIC int
- Do_touch(name, lib, member)
- char *name;
- char *lib;
- char **member;
- {
- X if( member != NIL(char *) )
- X Fatal("Library symbol names not supported");
- X
- X if (lib != NIL(char))
- X return( touch_arch(basename(name), lib) );
- X else
- X return( utime(name, NIL(time_t)) );
- }
- X
- X
- X
- PUBLIC void
- Void_lib_cache( lib_name, member_name )/*
- =========================================
- X Void the library cache for lib lib_name, and member member_name. */
- char *lib_name;
- char *member_name;
- {
- X VOID_LCACHE( lib_name, member_name );
- }
- X
- X
- X
- /*
- ** return the current time
- */
- PUBLIC time_t
- Do_time()
- {
- X extern time_t time();
- X return (time((time_t*)0));
- }
- X
- X
- X
- /*
- ** 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;
- {
- X int i;
- X
- X if( !do_it ) {
- X if( last && !Doing_bang ) {
- X Update_time_stamp( target );
- X }
- X return(0);
- X }
- X
- X if( Max_proc == 1 ) Wait_for_completion = TRUE;
- X
- X if( (i = runargv(target, ignore, group, last, shell, cmd)) == -1 )
- X Quit();
- X
- X /* NOTE: runargv must return either 0 or 1, 0 ==> command executed, and
- X * we waited for it to return, 1 ==> command started and is running
- X * concurrently with make process. */
- X return(i);
- }
- X
- X
- #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;
- {
- X static char **av = NIL(char *);
- X static int avs = 0;
- X int i = 0;
- X
- X if( av == NIL(char *) ) {
- X TALLOC(av, MINARGV, char*);
- X avs = MINARGV;
- X }
- X
- X if( (Packed_shell = shell||group||(*_strpbrk(cmd, Shell_metas)!='\0')) ) {
- X char* sh = group ? GShell : Shell;
- X
- X if( sh != NIL(char) ) {
- X av[i++] = sh;
- X if( (av[i] = (group?GShell_flags:Shell_flags)) != NIL(char) ) i++;
- X
- X av[i++] = cmd;
- X av[i] = NIL(char);
- X }
- X else
- X Fatal("%sSHELL macro not defined", group?"GROUP":"");
- X }
- X else {
- X do {
- X while( iswhite(*cmd) ) ++cmd;
- X if( *cmd ) av[i++] = cmd;
- X
- X while( *cmd != '\0' && !iswhite(*cmd) ) ++cmd;
- X if( *cmd ) *cmd++ = '\0';
- X
- X if( i == avs ) {
- X avs += MINARGV;
- X av = (char **) realloc( av, avs*sizeof(char *) );
- X }
- X } while( *cmd );
- X
- X av[i] = NIL(char);
- X }
- X
- X return(av);
- }
- X
- X
- /*
- ** 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
- X extern char *getenv();
- #endif
- X return( getenv(ename) );
- }
- X
- X
- X
- /*
- ** 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;
- {
- X extern int putenv();
- X char* p;
- X char* envstr = _stradd(ename, value, FALSE);
- X
- X p = envstr+strlen(ename); /* Don't change this code, _stradd does not */
- X *p++ = '='; /* add the space if *value is 0, it does */
- X if( !*value ) *p = '\0'; /* allocate enough memory for one though. */
- X
- X return( putenv(envstr) );
- }
- X
- X
- X
- PUBLIC void
- ReadEnvironment()
- {
- X extern char **Rule_tab;
- #if !defined(_MSC_VER)
- X extern char **environ;
- #endif
- X char **rsave;
- X
- #if !defined(__ZTC__) && !defined(_MPW)
- # define make_env()
- # define free_env()
- #else
- X void make_env();
- X void free_env();
- #endif
- X
- X make_env();
- X
- X rsave = Rule_tab;
- X Rule_tab = environ;
- X Readenv = TRUE;
- X
- X Parse( NIL(FILE) );
- X
- X Readenv = FALSE;
- X Rule_tab = rsave;
- X
- X free_env();
- }
- X
- X
- X
- /*
- ** All we have to catch is SIG_INT
- */
- PUBLIC void
- Catch_signals(fn)
- void (*fn)();
- {
- X if( signal(SIGINT, SIG_IGN) != SIG_IGN )
- X signal( SIGINT, fn );
- X if( signal(SIGQUIT, SIG_IGN) != SIG_IGN )
- X signal( SIGQUIT, fn );
- }
- X
- X
- X
- /*
- ** Clear any previously set signals
- */
- PUBLIC void
- Clear_signals()
- {
- X if( signal(SIGINT, SIG_IGN) != SIG_IGN )
- X signal( SIGINT, SIG_DFL );
- X if( signal(SIGQUIT, SIG_IGN) != SIG_IGN )
- X signal( SIGQUIT, SIG_DFL );
- }
- X
- X
- X
- /*
- ** Set program name
- */
- PUBLIC void
- Prolog(argc, argv)
- int argc;
- char* argv[];
- {
- X char buf[50];
- X
- X Pname = (argc == 0) ? DEF_MAKE_PNAME : argv[0];
- X sprintf( buf, "dmake-%d-root", GETPID );
- X Root = Def_cell( buf );
- X tzset();
- }
- X
- X
- X
- /*
- ** Do any clean up for exit.
- */
- PUBLIC void
- Epilog(ret_code)
- int ret_code;
- {
- X Write_state();
- X Unlink_temp_files(Root);
- X Hook_std_writes(NIL(char)); /* For MSDOS tee (-F option) */
- X exit( ret_code );
- }
- X
- X
- X
- /*
- ** Use the built-in functions of the operating system to get the current
- ** working directory.
- */
- PUBLIC char *
- Get_current_dir()
- {
- X static char buf[MAX_PATH_LEN+2];
- X return(getcwd(buf, sizeof(buf)));
- }
- X
- X
- X
- /*
- ** change working directory
- */
- PUBLIC int
- Set_dir(path)
- char* path;
- {
- X return( chdir(path) );
- }
- X
- X
- X
- /*
- ** return switch char
- */
- PUBLIC char
- Get_switch_char()
- {
- X return( getswitchar() );
- }
- X
- X
- X
- /*
- ** 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;
- {
- X extern char *tempnam();
- X
- X *path = _strjoin( tempnam(NIL(char), "mk"), suff, -1, TRUE );
- X Def_macro( "TMPFILE", *path, M_MULTI|M_EXPANDED );
- X
- X return( op?fopen(*path, "w"):NIL(FILE) );
- }
- X
- X
- /*
- ** Open a new temporary file and set it up for writing.
- */
- PUBLIC FILE *
- Start_temp( suffix, cp, fname )
- char *suffix;
- CELLPTR cp;
- char **fname;
- {
- X FILE *fp;
- X char *tmpname;
- X char *name;
- X
- X name = (cp != NIL(CELL))?cp->CE_NAME:"makefile text";
- X
- X if( (fp = Get_temp(&tmpname, suffix, TRUE)) == NIL(FILE) )
- X Open_temp_error( tmpname, name );
- X
- X Link_temp( cp, fp, tmpname );
- X *fname = tmpname;
- X
- X return( fp );
- }
- X
- X
- /*
- ** Issue an error on failing to open a temporary file
- */
- PUBLIC void
- Open_temp_error( tmpname, name )
- char *tmpname;
- char *name;
- {
- X Fatal("Cannot open temp file `%s' while processing `%s'", tmpname, name );
- }
- X
- X
- /*
- ** Link a temp file onto the list of files.
- */
- PUBLIC void
- Link_temp( cp, fp, fname )
- CELLPTR cp;
- FILE *fp;
- char *fname;
- {
- X FILELISTPTR new;
- X
- X if( cp == NIL(CELL) ) cp = Root;
- X
- X TALLOC( new, 1, FILELIST );
- X
- X new->fl_next = cp->ce_files;
- X new->fl_name = fname;
- X new->fl_file = fp; /* indicates temp file is open */
- X
- X cp->ce_files = new;
- }
- X
- X
- /*
- ** Close a previously used temporary file.
- */
- PUBLIC void
- Close_temp(cp, file)
- CELLPTR cp;
- FILE *file;
- {
- X FILELISTPTR fl;
- X if( cp == NIL(CELL) ) cp = Root;
- X
- X for( fl=cp->ce_files; fl && fl->fl_file != file; fl=fl->fl_next );
- X if( fl ) {
- X fl->fl_file = NIL(FILE);
- X fclose(file);
- X }
- }
- X
- X
- /*
- ** Clean-up, and close all temporary files associated with a target.
- */
- PUBLIC void
- Unlink_temp_files( cp )/*
- ==========================
- X Unlink the tempfiles if any exist. Make sure you close the files first
- X though. This ensures that under DOS there is no disk space lost. */
- CELLPTR cp;
- {
- X FILELISTPTR cur, next;
- X
- X if( cp == NIL(CELL) || cp->ce_files == NIL(FILELIST) ) return;
- X
- X for( cur=cp->ce_files; cur != NIL(FILELIST); cur=next ) {
- X next = cur->fl_next;
- X
- X if( cur->fl_file ) fclose( cur->fl_file );
- X
- X if( Verbose & V_LEAVE_TMP )
- X printf( "%s: Left temp file [%s]\n", Pname, cur->fl_name );
- X else
- X (void) Remove_file( cur->fl_name );
- X
- X FREE(cur->fl_name);
- X FREE(cur);
- X }
- X
- X cp->ce_files = NIL(FILELIST);
- }
- X
- X
- PUBLIC void
- Handle_result(status, ignore, abort_flg, target)
- int status;
- int ignore;
- int abort_flg;
- CELLPTR target;
- {
- X status = ((status&0xff)==0 ? status>>8
- X : (status & 0xff)==SIGTERM ? -1
- X : (status & 0x7f)+128);
- X
- X if( status )
- X if( !abort_flg ) {
- X fprintf( stderr, "%s: Error code %d, while making '%s'",
- X Pname, status, target->ce_fname );
- X
- X if( ignore || Continue ) {
- X fputs( " (Ignored)\n", stderr );
- X }
- X else {
- X fputc( '\n', stderr );
- X
- X if( !(target->ce_attr & A_PRECIOUS) )
- X if( Remove_file( target->ce_fname ) == 0 )
- X fprintf(stderr,"%s: '%s' removed.\n",Pname,target->ce_fname);
- X
- X Quit();
- X }
- X }
- X else if( !(target->ce_attr & A_PRECIOUS) )
- X Remove_file( target->ce_fname );
- }
- X
- X
- PUBLIC void
- Update_time_stamp( cp )
- CELLPTR cp;
- {
- X HASHPTR hp;
- X CELLPTR tcp;
- X int tmpflg;
- X int phony = ((cp->ce_attr&A_PHONY) != 0);
- X
- X tcp = cp;
- X do {
- X if( tcp->ce_attr & A_LIBRARY )
- X Void_lib_cache( tcp->ce_fname, NIL(char) );
- X else if( !Touch && (tcp->ce_attr & A_LIBRARYM) )
- X Void_lib_cache( tcp->ce_lib, tcp->ce_fname );
- X
- X if( !phony )
- X Stat_target(tcp, -1);
- X
- X if( tcp->ce_time == (time_t) 0L )
- X tcp->ce_time = Do_time();
- X
- X if( Trace )
- X tcp->ce_flag |= F_STAT; /* pretend we stated ok */
- X
- X if( Verbose & V_MAKE )
- X printf( "%s: <<<< Set [%s] time stamp to %ld\n",
- X Pname, tcp->CE_NAME, tcp->ce_time );
- X
- X Unlink_temp_files( tcp );
- X tcp->ce_flag |= F_MADE;
- X tcp->ce_attr |= A_UPDATED;
- X tcp = tcp->ce_all;
- X }
- X while( tcp != NIL(CELL) && tcp != cp );
- X
- X
- X /* Scan the list of prerequisites and if we find one that is
- X * marked as being removable, (ie. an inferred intermediate node
- X * then remove it. We remove a prerequisite by running the recipe
- X * associated with the special target .REMOVE, with $< set to
- X * the list of prerequisites to remove. */
- X
- X /* Make sure we don't try to remove prerequisites for the .REMOVE
- X * target. */
- X if( strcmp(cp->CE_NAME,".REMOVE") != 0 &&
- X (hp = Get_name( ".REMOVE", Defs, FALSE )) != NIL(HASH) ) {
- X register LINKPTR dp;
- X int flag = FALSE;
- X int rem;
- X t_attr attr;
- X
- X tcp = hp->CP_OWNR;
- X
- X tcp->ce_flag |= F_TARGET;
- X Clear_prerequisites( tcp );
- X
- X for( dp = cp->ce_prq; dp != NIL(LINK); dp = dp->cl_next ) {
- X register CELLPTR prq = dp->cl_prq;
- X
- X attr = Glob_attr | prq->ce_attr;
- X rem = (prq->ce_flag & F_REMOVE) &&
- X (prq->ce_flag & F_MADE ) &&
- X !(prq->ce_attr & A_PHONY) &&
- X !(attr & A_PRECIOUS) &&
- X !Force;
- X
- X if( rem ) {
- X CELLPTR tmp = prq;
- X do {
- X (Add_prerequisite(tcp,prq,FALSE,FALSE))->cl_flag |= F_TARGET;
- X prq->ce_flag &= ~F_REMOVE;
- X prq = prq->ce_all;
- X }
- X while( prq != NIL(CELL) && prq != tmp );
- X flag = TRUE;
- X }
- X }
- X
- X if( flag ) {
- X Remove_prq( tcp );
- X
- X for( dp=tcp->ce_prq; dp != NIL(LINK); dp=dp->cl_next ) {
- X register CELLPTR prq = dp->cl_prq;
- X
- X prq->ce_flag &= ~(F_MADE|F_VISITED|F_STAT);
- X prq->ce_flag |= F_REMOVE;
- X prq->ce_time = (time_t)0L;
- X }
- X }
- X }
- }
- X
- X
- PUBLIC int
- Remove_file( name )
- char *name;
- {
- X struct stat buf;
- X
- X if( stat(name, &buf) != 0 )
- X return 1;
- X if( (buf.st_mode & S_IFMT) == S_IFDIR )
- X return 1;
- X return(unlink(name));
- }
- SHAR_EOF
- chmod 0640 dmake/sysintf.c ||
- echo 'restore of dmake/sysintf.c failed'
- Wc_c="`wc -c < 'dmake/sysintf.c'`"
- test 15102 -eq "$Wc_c" ||
- echo 'dmake/sysintf.c: original size 15102, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= dmake/tos/arlib.c ==============
- if test ! -d 'dmake/tos'; then
- mkdir 'dmake/tos'
- fi
- if test -f 'dmake/tos/arlib.c' -a X"$1" != X"-c"; then
- echo 'x - skipping dmake/tos/arlib.c (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- sed 's/^X//' << 'SHAR_EOF' > 'dmake/tos/arlib.c' &&
- /* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/tos/arlib.c,v 1.1 1992/01/24 03:27:09 dvadura 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@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.
- --
- -- LOG
- -- $Log: arlib.c,v $
- X * Revision 1.1 1992/01/24 03:27:09 dvadura
- X * dmake Version 3.8, Initial revision
- X *
- */
- X
- #include <ar.h>
- #include "extern.h"
- #include "sysintf.h"
- X
- /* By defining the defines below it is possible to configure the library
- X * code for library cacheing/non-cacheing, ASCII archive headers, and a full
- X * decode of the ar_hdr fields in the scan_ar function. */
- X
- #define ASCARCH 1 /* ASCII time stored in archive */
- #define LC 1 /* Turn on library cacheing */
- #define DECODE_ALL_AR_FIELDS 0 /* decode only fields make needs*/
- X
- #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
- X
- #define MAXFNAME 32 /* Longest file name in archive */
- #define MAXMNAME 8 /* Max module name < MAXFNAME */
- X
- X
- /* This struct is used to pass the library and member information about the
- X * routines that perform the library seeking/cacheing */
- struct ar_args {
- X char *lib;
- X char *member;
- X time_t time;
- };
- X
- X
- typedef struct AR {
- X char ar_name[MAXFNAME+1]; /* File name */
- X long ar_size; /* Size in bytes */
- X time_t ar_time; /* Modification time */
- X
- #ifdef DOS
- X char ar_modname[MAXMNAME+1]; /* DOS module name */
- #endif
- X
- #if DECODE_ALL_AR_FIELDS
- X uint16 ar_mode; /* File mode */
- X uint16 ar_uid; /* File owner */
- X uint16 ar_gid; /* File group owner */
- #endif
- } AR, *ARPTR;
- X
- X
- static int ar_scan ANSI((FILE *,
- X int (*) ANSI((FILE *, struct AR *, struct ar_args *)),
- X 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 * ));
- X
- #if LC
- static int _cache_member ANSI((char *, char *, time_t));
- static int _check_cache ANSI((char *, char *, time_t *, int));
- #endif
- X
- /* decoded archive header */
- static AR _ar;
- X
- X
- PUBLIC time_t
- seek_arch(name, lib)/*
- ======================
- X Look for module 'name' inside 'lib'. If compiled with cacheing then first
- X check to see if the specified lib is cached. If so then return that time
- X stamp instead of looking into the library. */
- char *name;
- char *lib;
- {
- X FILE *f;
- X int rv;
- X time_t mtime;
- X struct ar_args args;
- X
- X /* Check the cache first (if there is a cache) */
- X if( _check_cache(name, lib, &mtime, FALSE) ) return( mtime );
- X
- X /* Open the lib file and perform the scan of the members, looking
- X * for our particular member. If cacheing is enabled it will be
- X * taken care of automatically during the scan. */
- X
- X args.lib = lib;
- X args.member = name;
- X args.time = (time_t)0L;
- X
- X if( (f = fopen(lib, "rb")) == NIL(FILE) ) return( (time_t)0L );
- X rv = ar_scan(f, time_function, &args );
- X fclose( f );
- X
- X if( rv < 0 ) Fatal("(%s): Invalid library format", lib);
- X
- X return( args.time );
- }
- X
- X
- PUBLIC int
- touch_arch(name, lib)/*
- =======================
- X Look for module 'name' inside 'lib'. If compiled with cacheing then first
- X check to see if the specified lib is cached. If so then set that time
- X stamp and write it into the library. Returns 0 on success, non-zero
- X on failure. */
- char *name;
- char *lib;
- {
- X FILE *f;
- X int rv;
- X struct ar_args args;
- X
- X /* Open the lib file and perform the scan of the members, looking
- X * for our particular member. If cacheing is enabled it will be
- X * taken care of automatically during the scan. */
- X
- X args.lib = lib;
- X args.member = name;
- X args.time = (time_t)0L;
- X
- X if( (f = fopen(lib, "rb+")) == NIL(FILE) ) return( (time_t)1L );
- X rv = ar_scan(f, touch_function, &args );
- X fclose( f );
- X
- X if( rv < 0 ) Fatal("(%s): Invalid library format", lib);
- X
- X return( 0 );
- }
- X
- X
- X
- static int
- time_function(f, arp, argp)/*
- =============================
- X get library member's time, if it matches than return it in argp, if
- X cacheing is enabled than cache the library members also. */
- FILE *f; /* library file */
- struct AR *arp; /* library member header */
- struct ar_args *argp;
- {
- X int rv = _cache_member( arp->ar_name, argp->lib, arp->ar_time );
- X
- X if( strcmp(argp->member, arp->ar_name) == 0 ) {
- X argp->time = arp->ar_time;
- X
- X if( arp->ar_time == 0 && !(Glob_attr & A_SILENT) )
- X Warning( "(%s): Can't extract library member timestamp; using EPOCH",
- X argp->member);
- X
- X return( rv ); /* 1 => no cacheing, 0 => cacheing */
- X }
- X
- X return( FALSE ); /* continue scan */
- }
- X
- X
- X
- static int
- touch_function(f, arp, argp)/*
- ==============================
- X Update library member's time stamp, and write new time value into cache
- X if required. */
- FILE *f; /* library file */
- struct AR *arp; /* library member header */
- struct ar_args *argp;
- {
- X extern time_t time ANSI(( time_t * ));
- X time_t now = time((time_t*) NULL); /* Current time. */
- X
- X if( strcmp(argp->member, arp->ar_name) == 0 ) {
- X _check_cache( argp->member, argp->lib, &now, TRUE );
- X ar_touch(f, now );
- X
- X return( TRUE );
- X }
- X
- X return( FALSE ); /* continue scan */
- }
- X
- X
- X
- X
- static int
- ar_scan(f, function, arg)/*
- ===========================
- X Scan the opened archive, and call the given function for each member found.
- X The function will be called with the file positioned at the beginning of
- X the member and it can read up to arp->ar_size bytes of the archive member.
- X If the function returns 1, we stop and return 1. We return 0 at the end
- X of the archive, or -1 if the archive has invalid format. This interface
- X is more general than required by "make", but it can be used by other
- X utilities. */
- register FILE *f;
- int (*function) ANSI((FILE *, struct AR *, struct ar_args *));
- struct ar_args *arg;
- {
- X extern long atol ANSI((char *));
- X register char *p;
- X struct ar_hdr arhdr; /* external archive header */
- X off_t offset; /* member seek offset */
- X
- #if ASCARCH
- X char magic[SARMAG];
- #else
- X unsigned short word;
- #endif
- X
- X fseek( f, 0L, 0 ); /* Start at the beginning of the archive file */
- X
- #if ASCARCH
- X fread( magic, sizeof(magic), 1, f );
- X if( strncmp(magic, ARMAG, SARMAG) != 0 ) return( -1 );
- #else
- X fread( (char*)&word, sizeof(word), 1, f );
- X if( word != ARMAG ) return( -1 );
- #endif
- X
- X /* scan the library, calling `function' for each member
- X */
- X while( 1 ) {
- X if( fread((char*) &arhdr, sizeof(arhdr), 1, f) != 1 ) break;
- X offset = ftell(f);
- X strncpy(_ar.ar_name, arhdr.ar_name, sizeof(arhdr.ar_name));
- X
- X for( p = &_ar.ar_name[sizeof(arhdr.ar_name)];
- X --p >= _ar.ar_name && *p == ' ';);
- X
- X p[1] = '\0';
- X if( *p == '/' ) *p = 0; /* Only SysV has trailing '/' */
- X
- #if ASCARCH
- X if( strncmp(arhdr.ar_fmag, ARFMAG, sizeof(arhdr.ar_fmag)) != 0 )
- X return( -1 );
- X _ar.ar_time = atol(arhdr.ar_date);
- X _ar.ar_size = atol(arhdr.ar_size);
- #else
- X _ar.ar_time = arhdr.ar_date;
- X _ar.ar_size = arhdr.ar_size;
- #endif
- X
- X
- #if DECODE_ALL_AR_FIELDS
- #if ASCARCH
- X _ar.ar_mode = atoi(arhdr.ar_mode);
- X _ar.ar_uid = atoi(arhdr.ar_uid);
- X _ar.ar_gid = atoi(arhdr.ar_gid);
- #else
- X _ar.ar_mode = arhdr.ar_mode;
- X _ar.ar_size = arhdr.ar_size;
- X _ar.ar_uid = arhdr.ar_uid;
- X _ar.ar_gid = arhdr.ar_gid;
- #endif
- #endif
- X
- X if( (*function)(f, &_ar, arg) ) return( 1 );
- X fseek( f, offset + (_ar.ar_size+1 & ~1L), 0 );
- X }
- X
- X if( !feof(f) ) return( -1 );
- X return 0;
- }
- X
- X
- X
- static int
- ar_touch( f, now )/*
- ====================
- X touch module header timestamp. */
- FILE *f;
- time_t now;
- {
- X struct ar_hdr arhdr; /* external archive header */
- X
- X fseek(f, - (off_t) (sizeof(arhdr) - sizeof(arhdr.ar_name)), 1);
- X
- #if ASCARCH
- X fprintf(f, "%lu", now);
- #else
- X fwrite((char *)now, sizeof(now), 1, f);
- #endif
- X
- X return( ferror(f) ? 0 : 1 );
- }
- X
- X
- #if LC
- typedef struct mem {
- X time_t m_time; /* modify time of member*/
- X struct mem *m_next; /* next member in lib */
- X char m_valid; /* valid cache entry */
- X char m_name[1]; /* lib member name */
- } MEM, *MEMPTR;
- X
- typedef struct lib {
- X struct lib *lb_next; /* next library in list */
- X struct mem *lb_members; /* list of lib members */
- X char lb_valid; /* valid cache entry */
- X char *lb_name; /* library name */
- } LIB, *LIBPTR;
- X
- static LIBPTR _cache = NIL(LIB);
- static MEMPTR _find_member ANSI(( LIBPTR, char * ));
- SHAR_EOF
- true || echo 'restore of dmake/tos/arlib.c failed'
- fi
- echo 'End of part 32, continue with part 33'
- echo 33 > _shar_seq_.tmp
- exit 0
- exit 0 # Just in case...
-