v15i056: dmake version 3.6 (part 04/25)

Dennis Vadura dvadura at watdragon.waterloo.edu
Mon Oct 15 11:37:48 AEST 1990


Posting-number: Volume 15, Issue 56
Submitted-by: Dennis Vadura <dvadura at watdragon.waterloo.edu>
Archive-name: dmake-3.6/part04

#!/bin/sh
# this is part 4 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file unix/arlib.c continued
#
CurArch=4
if test ! -r s2_seq_.tmp
then echo "Please unpack part 1 first!"
     exit 1; fi
( read Scheck
  if test "$Scheck" != $CurArch
  then echo "Please unpack part $Scheck next!"
       exit 1;
  else exit 0; fi
) < s2_seq_.tmp || exit 1
echo "x - Continuing file unix/arlib.c"
sed 's/^X//' << 'SHAR_EOF' >> unix/arlib.c
X   fread( (char*)&word, sizeof(word), 1, f );
X   if( word != ARMAG ) return( -1 );
X#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
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);
X#else
X      _ar.ar_time = arhdr.ar_date;
X      _ar.ar_size = arhdr.ar_size;
X#endif
X
X
X#if DECODE_ALL_AR_FIELDS
X#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);
X#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;
X#endif
X#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
X
Xstatic int
Xar_touch( f, now )/*
X====================
X   touch module header timestamp. */
XFILE   *f;
Xtime_t now;
X{
X   struct ar_hdr arhdr;                /* external archive header */
X
X   fseek(f, - (off_t) (sizeof(arhdr) - sizeof(arhdr.ar_name)), 1);
X
X#if ASCARCH
X   fprintf(f, "%lu", now);
X#else
X   fwrite((char *)now, sizeof(now), 1, f);
X#endif
X
X   return( ferror(f) ? 0 : 1 );
X}
X
X
X#if LC
Xtypedef 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	*/
X} MEM, *MEMPTR;
X
Xtypedef 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		*/
X} LIB, *LIBPTR;
X
Xstatic LIBPTR _cache = NIL(LIB);
Xstatic MEMPTR _find_member ANSI(( LIBPTR, char * ));
X
Xstatic int
X_check_cache( name, lib, pmtime, touch )/*
X==========================================
X   Check to see if we have cached member in lib, if so return time in pmtime
X   and return TRUE, otherwise return FALSE, if touch is TRUE then touch
X   the archive member instead. */
Xchar   *name;
Xchar   *lib;
Xtime_t *pmtime;
Xint    touch;
X{
X   register MEMPTR mp;
X   register LIBPTR lp;
X
X   for( lp=_cache; lp != NIL(LIB) && lp->lb_name != lib; lp=lp->lb_next );
X   if( lp == NIL(LIB) ) return( FALSE );
X
X   mp = _find_member( lp, name );
X   if( mp == NIL(MEM) || !mp->m_valid ) return( FALSE );
X
X   if( touch == TRUE )
X   {
X      mp->m_time = *pmtime;
X      mp->m_valid = 1;
X   }
X   else
X      *pmtime = mp->m_time;
X
X   lp->lb_valid   = 1;
X   lp->lb_members = mp;
X
X   return( TRUE );
X}
X
X
X
Xstatic int
X_cache_member( name, lib, mtime )/*
X===================================
X   Cache name in lib along with it's time */
Xchar   *name;
Xchar   *lib;
Xtime_t mtime;
X{
X   register MEMPTR mp;
X   register LIBPTR lp;
X
X   for( lp=_cache;
X	lp != NIL(LIB) && lp->lb_name != NIL(char) && lp->lb_name != lib;
X	lp=lp->lb_next);
X
X   if( lp == NIL(LIB) )
X   {
X      lp = (LIBPTR) malloc(sizeof(LIB));
X      if( lp == NIL(LIB) ) No_ram();
X
X      lp->lb_name    = lib;
X      lp->lb_members = NIL(MEM);
X      lp->lb_next    = _cache;
X      lp->lb_valid   = 0;
X      _cache = lp;
X   }
X
X   /* On UNIX ar does not allow multiple copies of the same .o file to live
X    * in the same AR file.  If this is not TRUE then use the commented out
X    * version to set the value of mp. */
X
X   /*mp = _find_member(lp, name);*/
X   mp = NIL(MEM);
X
X   if( mp == NIL(MEM) )
X   {
X      mp = (MEMPTR) malloc(sizeof(char)*offsetof(MEM,m_name[strlen(name)+1]));
X      if( mp == NIL(MEM) ) No_ram();
X
X      strcpy( mp->m_name, name );
X      mp->m_time     = mtime;
X
X      if( lp->lb_members == NIL(MEM) ) {
X	 mp->m_next     = mp;
X	 lp->lb_members = mp;
X      }
X      else {
X	 mp->m_next = lp->lb_members->m_next;
X	 lp->lb_members->m_next = mp;
X	 lp->lb_members = mp;
X      }
X   }
X   else
X      mp->m_time = mtime;
X
X   mp->m_valid = 1;
X
X   return( lp->lb_valid );
X}
X
X
Xstatic MEMPTR
X_find_member( lp, name )
XLIBPTR lp;
Xchar   *name;
X{
X   register MEMPTR mp = lp->lb_members;
X
X   if( mp == NIL(MEM) ) return(mp);
X
X   do {
X      if( !strcmp(mp->m_name, name ) ) return( mp );
X      mp = mp->m_next;
X   }
X   while( mp != lp->lb_members );
X
X   return( NIL(MEM) );
X}
X#endif
X
X
X
Xvoid
Xvoid_lcache( lib, member )/*
X============================
X   Void the library cache for lib.  If member is NIL(char) then nuke all
X   of the members, if member is NOT NIL(char) then invalidate only that
X   member. */
Xchar *lib;
Xchar *member;
X{
X#if LC
X   register LIBPTR lp;
X   register MEMPTR mp;
X   register MEMPTR tmp;
X
X   for( lp=_cache; lp != NIL(LIB) && lp->lb_name != lib; lp=lp->lb_next );
X   if( lp == NIL(LIB) ) return;
X
X   if( member == NIL(char) ) {
X      mp = lp->lb_members;
X      do {
X	 tmp = mp->m_next;
X	 (void) free( mp );
X	 mp = tmp;
X      } while( mp != lp->lb_members );
X
X      lp->lb_valid   = 0;
X      lp->lb_members = NIL(MEM);
X      lp->lb_name    = NIL(char);
X   }
X   else {
X      mp=lp->lb_members;
X      do {
X	 if( strcmp( member, mp->m_name) == 0 ) {
X	    lp->lb_members = mp->m_next;
X	    mp->m_valid = 0;
X	 }
X	   
X	 mp=mp->m_next;
X      } while( mp != lp->lb_members );
X   }
X#endif
X}
SHAR_EOF
echo "File unix/arlib.c is complete"
chmod 0440 unix/arlib.c || echo "restore of unix/arlib.c fails"
echo mkdir - unix/386ix
mkdir unix/386ix
echo "x - extracting unix/386ix/time.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > unix/386ix/time.h &&
X/*
X** Berkeley get this wrong!
X*/
X#ifndef	TIME_h
X#define	TIME_h
X
Xtypedef	long	time_t;	/* this is the thing we use */
X
X#endif	TIME_h
X
SHAR_EOF
chmod 0440 unix/386ix/time.h || echo "restore of unix/386ix/time.h fails"
echo "x - extracting unix/386ix/stdlib.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > unix/386ix/stdlib.h &&
X#ifndef _STDLIB_INCLUDED_
X#define _STDLIB_INCLUDED_
X
Xextern /*GOTO*/ _exit();
Xextern /*GOTO*/ exit();
Xextern /*GOTO*/ abort();
Xextern int system();
Xextern char *getenv();
Xextern char *calloc();
Xextern char *malloc();
Xextern char *realloc();
Xextern free();
Xextern int errno;
X
X#ifndef EIO
X#	include <errno.h>
X#endif
X
X#endif /* _STDLIB_INCLUDED_ */
SHAR_EOF
chmod 0440 unix/386ix/stdlib.h || echo "restore of unix/386ix/stdlib.h fails"
echo "x - extracting unix/386ix/stdarg.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > unix/386ix/stdarg.h &&
X/*
X * stdarg.h
X *
X * defines ANSI style macros for accessing arguments of a function which takes
X * a variable number of arguments
X *
X */
X
X#if !defined(__STDARG)
X#define __STDARG
X
Xtypedef char *va_list;
X
X#define va_dcl int va_alist
X#define va_start(ap,v)  ap = (va_list)&va_alist
X#define va_arg(ap,t)    ((t*)(ap += sizeof(t)))[-1]
X#define va_end(ap)      ap = NULL
X#endif
SHAR_EOF
chmod 0440 unix/386ix/stdarg.h || echo "restore of unix/386ix/stdarg.h fails"
echo "x - extracting unix/386ix/startup.mk (Text)"
sed 's/^X//' << 'SHAR_EOF' > unix/386ix/startup.mk &&
X# Generic UNIX DMAKE startup file.  Customize to suit your needs.
X# Should work for both SYSV, and BSD 4.3
X# See the documentation for a description of internally defined macros.
X#
X# Disable warnings for macros redefined here that were given
X# on the command line.
X__.SILENT := $(.SILENT)
X.SILENT   := yes
X
X# Configuration parameters for DMAKE startup.mk file
X# Set these to NON-NULL if you wish to turn the parameter on.
X_HAVE_RCS	:= yes		# yes => RCS  is installed.
X_HAVE_SCCS	:= yes		# yes => SCCS is installed.
X
X# Applicable suffix definitions
XA := .a		# Libraries
XE :=		# Executables
XF := .f		# Fortran
XO := .o		# Objects
XP := .p		# Pascal
XS := .s		# Assembler sources
XV := ,v		# RCS suffix
X
X# Recipe execution configurations
XSHELL		:= /bin/sh
XSHELLFLAGS	:= -ce
XGROUPSHELL	:= $(SHELL)
XGROUPFLAGS	:= 
XSHELLMETAS	:= |();&<>?*][$$:\\#`'"
XGROUPSUFFIX	:=
XDIVFILE		 = $(TMPFILE)
X
X# Standard C-language command names and flags
X   CPP	   := /lib/cpp		# C-preprocessor
X   CC      := cc		# C-compiler and flags
X   CFLAGS  +=
X
X   AS      := as		# Assembler and flags
X   ASFLAGS += 
X
X   LD       = $(CC)		# Loader and flags
X   LDFLAGS +=
X   LDLIBS   =
X
X# Definition of $(MAKE) macro for recursive makes.
X   MAKE = $(MAKECMD) $(MFLAGS)
X
X# Definition of Print command for this system.
X   PRINT = lpr
X
X# Language and Parser generation Tools and their flags
X   YACC	  := yacc		# standard yacc
X   YFLAGS +=
X   YTAB	  := y.tab		# yacc output files name stem.
X
X   LEX	  := lex		# standard lex
X   LFLAGS +=
X   LEXYY  := lex.yy		# lex output file
X
X# Other Compilers, Tools and their flags
X   PC	:= pc			# pascal compiler
X   RC	:= f77			# ratfor compiler
X   FC	:= f77			# fortran compiler
X
X   CO	   := co		# check out for RCS
X   COFLAGS += -q
X
X   AR     := ar			# archiver
X   ARFLAGS+= ruv
X
X   RM	   := /bin/rm		# remove a file command
X   RMFLAGS +=
X
X# Implicit generation rules for making inferences.
X# We don't provide .yr or .ye rules here.  They're obsolete.
X# Rules for making *$O
X   %$O : %.c ; $(CC) $(CFLAGS) -c $<
X   %$O : %$P ; $(PC) $(PFLAGS) -c $<
X   %$O : %$S ; $(AS) $(ASFLAGS) $<
X   %$O : %.cl ; class -c $<
X   %$O : %.e %.r %.F %$F
X	$(FC) $(RFLAGS) $(EFLAGS) $(FFLAGS) -c $<
X
X# Executables
X   %$E : %$O ; $(LD) $(LDFLAGS) -o $@ $< $(LDLIBES)
X
X# lex and yacc rules
X   %.c : %.y ; $(YACC)  $(YFLAGS) $<; mv $(YTAB).c $@
X   %.c : %.l ; $(LEX)   $(LFLAGS) $<; mv $(LEXYY).c $@
X
X# This rule tells how to make *.out from it's immediate list of prerequisites
X# UNIX only.
X   %.out :; $(LD) $(LDFLAGS) -o $@ $^ $(LDLIBS)
X
X# RCS support
X.IF $(_HAVE_RCS)
X   % : %$V $$(@:d)RCS/$$(@:f)$V;- $(CO) $(COFLAGS) $@
X   .NOINFER : %$V $$(@:d)RCS/$$(@:f)$V
X.END
X
X# SCCS support
X.IF $(_HAVE_SCCS)
X   % : s.% ; get $@
X   .NOINFER : s.%
X.END
X
X# Recipe to make archive files.
X%$A :
X[
X   $(AR) $(ARFLAGS) $@ $?
X   $(RM) $(RMFLAGS) $?
X   ranlib $@
X]
X
X# DMAKE uses this recipe to remove intermediate targets
X.REMOVE :; $(RM) -f $<
X
X# AUGMAKE extensions for SYSV compatibility
X at B = $(@:b)
X at D = $(@:d)
X at F = $(@:f)
X*B = $(*:b)
X*D = $(*:d)
X*F = $(*:f)
X<B = $(<:b)
X<D = $(<:d)
X<F = $(<:f)
X?B = $(?:b)
X?F = $(?:f)
X?D = $(?:d)
X
X# Turn warnings back to previous setting.
X.SILENT := $(__.SILENT)
X
X# Local startup file if any
X.INCLUDE .IGNORE: "_startup.mk"
SHAR_EOF
chmod 0640 unix/386ix/startup.mk || echo "restore of unix/386ix/startup.mk fails"
echo "x - extracting unix/386ix/runargv.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > unix/386ix/runargv.c &&
X/* RCS      -- $Header: /u2/dvadura/src/generic/dmake/src/unix/386ix/RCS/runargv.c,v 1.1 90/10/06 12:05:59 dvadura Exp $
X-- SYNOPSIS -- invoke a sub process.
X-- 
X-- DESCRIPTION
X-- 	Use the standard methods of executing a sub process.
X--
X-- AUTHOR
X--      Dennis Vadura, dvadura at watdragon.uwaterloo.ca
X--      CS DEPT, University of Waterloo, Waterloo, Ont., Canada
X--
X-- COPYRIGHT
X--      Copyright (c) 1990 by Dennis Vadura.  All rights reserved.
X-- 
X--      This program is free software; you can redistribute it and/or
X--      modify it under the terms of the GNU General Public License
X--      (version 1), as published by the Free Software Foundation, and
X--      found in the file 'LICENSE' included with this distribution.
X-- 
X--      This program is distributed in the hope that it will be useful,
X--      but WITHOUT ANY WARRANTY; without even the implied warrant of
X--      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
X--      GNU General Public License for more details.
X-- 
X--      You should have received a copy of the GNU General Public License
X--      along with this program;  if not, write to the Free Software
X--      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
X--
X-- LOG
X--     $Log:	runargv.c,v $
X * Revision 1.1  90/10/06  12:05:59  dvadura
X * dmake Release, Version 3.6
X * 
X*/
X
X#include <signal.h>
X#include "extern.h"
X#include "sysintf.h"
X#include "alloc.h"
X
Xtypedef struct prp {
X   char *prp_cmd;
X   int   prp_group;
X   int   prp_ignore;
X   int   prp_last;
X   int	 prp_shell;
X   struct prp *prp_next;
X   char  *prp_dir;
X} RCP, *RCPPTR;
X
Xtypedef struct pr {
X   int		pr_valid;
X   int		pr_pid;
X   CELLPTR	pr_target;
X   HOWPTR	pr_how;
X   int		pr_ignore;
X   int		pr_last;
X   RCPPTR  	pr_recipe;
X   RCPPTR  	pr_recipe_end;
X} PR;
X
Xstatic PR  *_procs    = NIL(PR);
Xstatic int  _proc_cnt = 0;
Xstatic int  _abort_flg= FALSE;
Xstatic int  _use_i    = -1;
Xstatic int  _do_upd   = 0;
X
Xstatic  void	_add_child ANSI((int, CELLPTR, HOWPTR, int, int));
Xstatic  void	_attach_cmd ANSI((char *, int, int, CELLPTR, HOWPTR, int, int));
Xstatic  void    _finished_child ANSI((int, int));
Xstatic  int     _running ANSI((CELLPTR, HOWPTR));
X
Xint
Xrunargv(target, how, ignore, group, last, shell, cmd)
XCELLPTR target;
XHOWPTR  how;
Xint     ignore;
Xint	group;
Xint	last;
Xint     shell;
Xchar	*cmd;
X{
X   extern  int  errno;
X   extern  char *sys_errlist[];
X   int          pid;
X   char         **argv;
X
X   if( _running(target, how) /*&& Max_proc != 1*/ ) {
X      /* The command will be executed when the previous recipe
X       * line completes. */
X      _attach_cmd( cmd, group, ignore, target, how, last, shell );
X      return(1);
X   }
X
X   while( _proc_cnt == Max_proc )
X      if( Wait_for_child(FALSE, -1) == -1 )  Fatal( "Lost a child" );
X
X   argv = Pack_argv( group, shell, cmd );
X
X   switch( pid=fork() ){
X      int   wid;
X      int   status;
X
X   case -1: /* fork failed */
X      Error("%s: %s", argv[0], sys_errlist[errno]);
X      Handle_result(-1, ignore, _abort_flg, target);
X      return(-1);
X
X   case 0:  /* child */
X      execvp(argv[0], argv);
X      Continue = TRUE;   /* survive error message */
X      Error("%s: %s", argv[0], sys_errlist[errno]);
X      kill(getpid(), SIGTERM);
X      /*NOTREACHED*/
X
X   default: /* parent */
X      _add_child(pid, target, how, ignore, last);
X   }
X
X   return(1);
X}
X
X
Xint
XWait_for_child( abort_flg, pid )
Xint abort_flg;
Xint pid;
X{
X   int wid;
X   int status;
X   int waitchild;
X
X   waitchild = (pid == -1)? FALSE : Wait_for_completion;
X
X   do {
X      if( (wid = wait(&status)) == -1 ) return(-1);
X
X      _abort_flg = abort_flg;
X      _finished_child(wid, status);
X      _abort_flg = FALSE;
X   }
X   while( waitchild && pid != wid );
X
X   return(0);
X}
X
X
Xvoid
XClean_up_processes()
X{
X   register int i;
X
X   if( _procs != NIL(PR) ) {
X      for( i=0; i<Max_proc; i++ )
X	 if( _procs[i].pr_valid )
X	    kill(_procs[i].pr_pid, SIGTERM);
X
X      while( Wait_for_child(TRUE, -1) != -1 );
X   }
X}
X
X
Xstatic void
X_add_child( pid, target, how, ignore, last )
Xint	pid;
XCELLPTR target;
XHOWPTR  how;
Xint	ignore;
Xint     last;
X{
X   register int i;
X   register PR *pp;
X
X   if( _procs == NIL(PR) ) {
X      TALLOC( _procs, Max_proc, PR );
X   }
X
X   if( (i = _use_i) == -1 )
X      for( i=0; i<Max_proc; i++ )
X	 if( !_procs[i].pr_valid )
X	    break;
X
X   pp = _procs+i;
X
X   pp->pr_valid  = 1;
X   pp->pr_pid    = pid;
X   pp->pr_target = target;
X   pp->pr_how    = how;
X   pp->pr_ignore = ignore;
X   pp->pr_last   = last;
X
X   Current_target = NIL(HOW);
X
X   _proc_cnt++;
X
X   if( Wait_for_completion ) Wait_for_child( FALSE, pid );
X}
X
X
Xstatic void
X_finished_child(pid, status)
Xint	pid;
Xint	status;
X{
X   register int i;
X   register PR *pp;
X
X   for( i=0; i<Max_proc; i++ )
X      if( _procs[i].pr_valid && _procs[i].pr_pid == pid )
X	 break;
X
X   _procs[i].pr_valid = 0;
X   _proc_cnt--;
X
X   if( _procs[i].pr_recipe != NIL(RCP) && !_abort_flg ) {
X      RCPPTR rp = _procs[i].pr_recipe;
X      char   *dir;
X
X      Current_target = _procs[i].pr_how;
X      Handle_result( status, _procs[i].pr_ignore, FALSE, _procs[i].pr_target );
X      Current_target = NIL(HOW);
X
X      _procs[i].pr_recipe = rp->prp_next;
X
X      _use_i = i;
X      dir = _strdup(Get_current_dir());
X      Set_dir( rp->prp_dir );
X      runargv( _procs[i].pr_target, _procs[i].pr_how, rp->prp_ignore,
X      	       rp->prp_group, rp->prp_last, rp->prp_shell, rp->prp_cmd );
X      Set_dir(dir);
X      FREE(dir);
X      FREE(rp->prp_dir);
X      _use_i = -1;
X
X      FREE( rp->prp_cmd );
X      FREE( rp );
X
X      if( _proc_cnt == Max_proc ) Wait_for_child( FALSE, -1 );
X   }
X   else {
X      Unlink_temp_files( _procs[i].pr_how );
X      Handle_result(status,_procs[i].pr_ignore,_abort_flg,_procs[i].pr_target);
X
X      if( _procs[i].pr_last && !Doing_bang )
X	 Update_time_stamp( _procs[i].pr_target, _procs[i].pr_how );
X   }
X}
X
X
Xstatic int
X_running( cp, how )
XCELLPTR cp;
XHOWPTR  how;
X{
X   register int i;
X
X   if( !_procs ) return(FALSE);
X
X   for( i=0; i<Max_proc; i++ )
X      if( _procs[i].pr_valid &&
X	  _procs[i].pr_how == how &&
X	  _procs[i].pr_target == cp  )
X	 break;
X	 
X   return( i != Max_proc );
X}
X
X
Xstatic void
X_attach_cmd( cmd, group, ignore, cp, how, last, shell )
Xchar    *cmd;
Xint	group;
Xint     ignore;
XCELLPTR cp;
XHOWPTR  how;
Xint     last;
Xint     shell;
X{
X   register int i;
X   RCPPTR rp;
X
X   for( i=0; i<Max_proc; i++ )
X      if( _procs[i].pr_valid &&
X	  _procs[i].pr_how == how &&
X	  _procs[i].pr_target == cp  )
X	 break;
X
X   TALLOC( rp, 1, RCP );
X   rp->prp_cmd   = _strdup(cmd);
X   rp->prp_group = group;
X   rp->prp_ignore= ignore;
X   rp->prp_last  = last;
X   rp->prp_shell = shell;
X   rp->prp_dir   = _strdup(Get_current_dir());
X
X   if( _procs[i].pr_recipe == NIL(RCP) )
X      _procs[i].pr_recipe = _procs[i].pr_recipe_end = rp;
X   else {
X      _procs[i].pr_recipe_end->prp_next = rp;
X      _procs[i].pr_recipe_end = rp;
X   }
X}
SHAR_EOF
chmod 0440 unix/386ix/runargv.c || echo "restore of unix/386ix/runargv.c fails"
echo "x - extracting unix/386ix/make.sh (Text)"
sed 's/^X//' << 'SHAR_EOF' > unix/386ix/make.sh &&
Xmkdir objects
Xcc -c -DHELP -I. -Icommon -Iunix -Iunix/386ix -O infer.c
Xmv infer.o objects
Xcc -c -DHELP -I. -Icommon -Iunix -Iunix/386ix -O make.c
Xmv make.o objects
Xcc -c -DHELP -I. -Icommon -Iunix -Iunix/386ix -O stat.c
Xmv stat.o objects
Xcc -c -DHELP -I. -Icommon -Iunix -Iunix/386ix -O expand.c
Xmv expand.o objects
Xcc -c -DHELP -I. -Icommon -Iunix -Iunix/386ix -O string.c
Xmv string.o objects
Xcc -c -DHELP -I. -Icommon -Iunix -Iunix/386ix -O hash.c
Xmv hash.o objects
Xcc -c -DHELP -I. -Icommon -Iunix -Iunix/386ix -O dag.c
Xmv dag.o objects
Xcc -c -DHELP -I. -Icommon -Iunix -Iunix/386ix -O dmake.c
Xmv dmake.o objects
Xcc -c -DHELP -I. -Icommon -Iunix -Iunix/386ix -O path.c
Xmv path.o objects
Xcc -c -DHELP -I. -Icommon -Iunix -Iunix/386ix -O imacs.c
Xmv imacs.o objects
Xcc -c -DHELP -I. -Icommon -Iunix -Iunix/386ix -O sysintf.c
Xmv sysintf.o objects
Xcc -c -DHELP -I. -Icommon -Iunix -Iunix/386ix -O parse.c
Xmv parse.o objects
Xcc -c -DHELP -I. -Icommon -Iunix -Iunix/386ix -O getinp.c
Xmv getinp.o objects
Xcc -c -DHELP -I. -Icommon -Iunix -Iunix/386ix -O quit.c
Xmv quit.o objects
Xcc -c -DHELP -I. -Icommon -Iunix -Iunix/386ix -O basename.c
Xmv basename.o objects
Xcc -c -DHELP -I. -Icommon -Iunix -Iunix/386ix -O dump.c
Xmv dump.o objects
Xcc -c -DHELP -I. -Icommon -Iunix -Iunix/386ix -O macparse.c
Xmv macparse.o objects
Xcc -c -DHELP -I. -Icommon -Iunix -Iunix/386ix -O rulparse.c
Xmv rulparse.o objects
Xcc -c -DHELP -I. -Icommon -Iunix -Iunix/386ix -O percent.c
Xmv percent.o objects
Xcc -c -DHELP -I. -Icommon -Iunix -Iunix/386ix -O function.c
Xmv function.o objects
Xcc -c -DHELP -I. -Icommon -Iunix -Iunix/386ix -O unix/arlib.c
Xmv arlib.o objects
Xcc -c -DHELP -I. -Icommon -Iunix -Iunix/386ix -O unix/dirbrk.c
Xmv dirbrk.o objects
Xcc -c -DHELP -I. -Icommon -Iunix -Iunix/386ix -O unix/explode.c
Xmv explode.o objects
Xcc -c -DHELP -I. -Icommon -Iunix -Iunix/386ix -O unix/rmprq.c
Xmv rmprq.o objects
Xcc -c -DHELP -I. -Icommon -Iunix -Iunix/386ix -O unix/ruletab.c
Xmv ruletab.o objects
Xcc -c -DHELP -I. -Icommon -Iunix -Iunix/386ix -O unix/386ix/runargv.c
Xmv runargv.o objects
Xcc  -o dmake  objects/infer.o objects/make.o objects/stat.o objects/expand.o objects/string.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/basename.o objects/dump.o objects/macparse.o objects/rulparse.o objects/percent.o objects/function.o objects/arlib.o objects/dirbrk.o objects/explode.o objects/rmprq.o objects/ruletab.o objects/runargv.o 
SHAR_EOF
chmod 0640 unix/386ix/make.sh || echo "restore of unix/386ix/make.sh fails"
echo "x - extracting unix/386ix/config.mk (Text)"
sed 's/^X//' << 'SHAR_EOF' > unix/386ix/config.mk &&
X# This is the 386IX UNIX configuration file for DMAKE
X#	It simply modifies the values of SRC, and checks to see if
X#	OSENVIRONMENT is defined.  If so it includes the appropriate
X#	config.mk file.
X#
X# It also sets the values of .SOURCE.c and .SOURCE.h to include the local
X# directory.
X#
Xosrdir := $(OS)$(DIRSEPSTR)$(OSRELEASE)
X
X# The following are required sources
XOSDSRC := runargv.c
XSRC    += $(OSDSRC)
X.SETDIR=$(osrdir) : $(OSDSRC)
X
X.SOURCE.h : $(osrdir)
X
X# Local configuration modifications for CFLAGS, there's local SysV includes
X# too.
XCFLAGS += -I$(osrdir)
X
X# See if we modify anything in the lower levels.
X.IF $(OSENVIRONMENT) != $(NULL)
X   .INCLUDE .IGNORE : $(osrdir)$(DIRSEPSTR)$(OSENVIRONMENT)$(DIRSEPSTR)config.mk
X.END
SHAR_EOF
chmod 0640 unix/386ix/config.mk || echo "restore of unix/386ix/config.mk fails"
echo "x - extracting unix/386ix/config.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > unix/386ix/config.h &&
X/* RCS      -- $Header: /u2/dvadura/src/generic/dmake/src/unix/386ix/RCS/config.h,v 1.1 90/10/06 12:05:52 dvadura Exp $
X-- SYNOPSIS -- Configurarion include file.
X-- 
X-- DESCRIPTION
X-- 	There is one of these for each specific machine configuration.
X--	It can be used to further tweek the machine specific sources
X--	so that they compile.
X--
X-- AUTHOR
X--      Dennis Vadura, dvadura at watdragon.uwaterloo.ca
X--      CS DEPT, University of Waterloo, Waterloo, Ont., Canada
X--
X-- COPYRIGHT
X--      Copyright (c) 1990 by Dennis Vadura.  All rights reserved.
X-- 
X--      This program is free software; you can redistribute it and/or
X--      modify it under the terms of the GNU General Public License
X--      (version 1), as published by the Free Software Foundation, and
X--      found in the file 'LICENSE' included with this distribution.
X-- 
X--      This program is distributed in the hope that it will be useful,
X--      but WITHOUT ANY WARRANTY; without even the implied warrant of
X--      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
X--      GNU General Public License for more details.
X-- 
X--      You should have received a copy of the GNU General Public License
X--      along with this program;  if not, write to the Free Software
X--      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
X--
X-- LOG
X--     $Log:	config.h,v $
X * Revision 1.1  90/10/06  12:05:52  dvadura
X * dmake Release, Version 3.6
X * 
X*/
X
X/* define this for configurations that don't have the coreleft function
X * so that the code compiles.  To my knowledge coreleft exists only on
X * Turbo C, but it is needed here since the function is used in many debug
X * macros. */
X#define coreleft() 0L
X
X/* Define the getcwd function that is used in the code, since BSD does
X * not have getcwd, but call it getwd instead. */
Xextern char *getcwd ANSI((char *, int));
X
X/* Define setvbuf, SysV doesn't have one */
X#define setvbuf(fp, bp, type, len) setbuf( fp, NULL );
X
X/* NCR Tower's don't define size_t */
X#ifdef tower
Xtypedef long size_t;
X#endif
SHAR_EOF
chmod 0440 unix/386ix/config.h || echo "restore of unix/386ix/config.h fails"
echo "x - extracting unix/386ix/ar.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > unix/386ix/ar.h &&
X#define PORTAR 1
X#include "/usr/include/ar.h"
SHAR_EOF
chmod 0440 unix/386ix/ar.h || echo "restore of unix/386ix/ar.h fails"
echo "x - extracting sysintf.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > sysintf.c &&
X/* RCS      -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/sysintf.c,v 1.1 90/10/06 12:04:17 dvadura Exp $
X-- SYNOPSIS -- system independent interface
X-- 
X-- DESCRIPTION
X--	These are the routines constituting the system interface.
X--	The system is taken to be essentially POSIX conformant.
X--	The original code was extensively revised by T J Thompson at MKS,
X--	and the library cacheing was added by Eric Gisin at MKS.  I then
X--	revised the code yet again, to improve the lib cacheing, and to
X--	make it more portable.
X--
X--	The following is a list of routines that are required by this file
X--	in order to work.  These routines are provided as functions by the
X--	standard C lib of the target system or as #defines in system/sysintf.h
X--	or via appropriate C code in the system/ directory for the given
X--	system.
X--
X--	The first group must be provided by a file in the system/ directory
X--	the second group is ideally provided by the C lib.  However, there
X--	are instances where the C lib implementation of the specified routine
X--	does not exist, or is incorrect.  In these instances the routine
X--	must be provided by the the user in the system/ directory of dmake.
X--	(For example, the bsd/ dir contains code for putenv(), and tempnam())
X--
X--	DMAKE SPECIFIC:
X--		seek_arch()
X--		touch_arch()
X--		void_lcache()
X--		runargv()
X--		STAT()
X--		Remove_prq()
X--
X--	C-LIB SPECIFIC:  (should be present in your C-lib)
X--		utime()
X--		time()
X--		getenv()
X--		putenv()
X--		getcwd()
X--		signal()
X--		chdir()
X--		tempnam()
X-- 
X-- AUTHOR
X--      Dennis Vadura, dvadura at watdragon.uwaterloo.ca
X--      CS DEPT, University of Waterloo, Waterloo, Ont., Canada
X--
X-- COPYRIGHT
X--      Copyright (c) 1990 by Dennis Vadura.  All rights reserved.
X-- 
X--      This program is free software; you can redistribute it and/or
X--      modify it under the terms of the GNU General Public License
X--      (version 1), as published by the Free Software Foundation, and
X--      found in the file 'LICENSE' included with this distribution.
X-- 
X--      This program is distributed in the hope that it will be useful,
X--      but WITHOUT ANY WARRANTY; without even the implied warrant of
X--      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
X--      GNU General Public License for more details.
X-- 
X--      You should have received a copy of the GNU General Public License
X--      along with this program;  if not, write to the Free Software
X--      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
X--
X-- LOG
X--     $Log:	sysintf.c,v $
X * Revision 1.1  90/10/06  12:04:17  dvadura
X * dmake Release, Version 3.6
X * 
X*/
X
X#include <stdio.h>
X#include "extern.h"
X#include "sysintf.h"
X#include "alloc.h"
X
X/*
X** Tries to stat the file name.  Returns 0 if the file
X** does not exist.  Note that if lib is not null it tries to stat
X** the name found inside lib.
X**
X** If member is NOT nil then look for the library object which defines the
X** symbol given by name.  If found _strdup the name and return make the
X** pointer pointed at by sym point at it.  Not handled for now!
X*/
Xtime_t
XDo_stat(name, lib, member)
Xchar *name;
Xchar *lib;
Xchar **member;
X{
X   struct stat buf;
X   time_t seek_arch();
X
X   if( member != NIL(char *) )
X      Fatal("Library symbol names not supported");
X
X   if( lib != NIL(char) )
X      return( seek_arch(basename(name), lib) );
X   else
X      return( (STAT(name, &buf) == -1) ? (time_t)0 : buf.st_mtime );
X}
X
X
X
X/* Touch existing file to force modify time to present.
X */
Xint
XDo_touch(name, lib, member)
Xchar *name;
Xchar *lib;
Xchar **member;
X{
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
X
Xvoid
XVoid_lib_cache( lib_name, member_name )/*
X=========================================
X   Void the library cache for lib lib_name, and member member_name. */
Xchar *lib_name;
Xchar *member_name;
X{
X   VOID_LCACHE( lib_name, member_name );
X}
X
X
X
X/*
X** return the current time
X*/
Xtime_t
XDo_time()
X{
X   extern time_t time();
X   return (time((time_t*)0));
X}
X
X
X
X/*
X** Execute the string passed in as a command and return
X** the return code. The command line arguments are
X** assumed to be separated by spaces or tabs.  The first
X** such argument is assumed to be the command.
X**
X** If group is true then this is a group of commands to be fed to the
X** the shell as a single unit.  In this case cmd is of the form
X** "file" indicating the file that should be read by the shell
X** in order to execute the command group.
X*/
Xint
XDo_cmnd(cmd, group, do_it, target, how, ignore, shell, last)
Xchar   *cmd;
Xint     group;
Xint	do_it;
XCELLPTR target;
XHOWPTR  how;
Xint     ignore;
Xint     shell;
Xint	last;
X{
X   int  i;
X
X   if( !do_it ) {
X      if( last && !Doing_bang ) Update_time_stamp( target, how );
X      return(0);
X   }
X
X   if( Max_proc == 1 ) Wait_for_completion = TRUE;
X   if( (i = runargv(target, how, 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
X
X#define MINARGV 64
X/* Take a command and pack it into an argument vector to be executed. */
Xchar **
XPack_argv( group, shell, cmd )
Xint    group;
Xint    shell;
Xchar  *cmd;
X{
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
X
X/*
X** Return the value of ename from the environment
X** if ename is not defined in the environment then
X** NIL(char) should be returned
X*/
Xchar *
XRead_env_string(ename)
Xchar *ename;
X{
X   extern char *getenv();
X   return( getenv(ename) );
X}
X
X
X
X/*
X** Set the value of the environment string ename to value.
X**  Returns 0 if success, non-zero if failure
X*/
Xint
XWrite_env_string(ename, value)
Xchar *ename;
Xchar *value;
X{
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
X
Xvoid
XReadEnvironment()
X{
X   extern char **Rule_tab;
X   extern char **environ;
X   char **rsave;
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
X
X
X/*
X** All we have to catch is SIG_INT
X*/
Xvoid
XCatch_signals(fn)
Xvoid (*fn)();
X{
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
X
X/*
X** Clear any previously set signals
X*/
Xvoid
XClear_signals()
X{
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
X
X/*
X** Set program name
X*/
Xvoid
XProlog(argc, argv)
Xint   argc;
Xchar* argv[];
X{
X   Pname = (argc == 0) ? DEF_MAKE_PNAME : argv[0];
X   Root_how.hw_files = NIL(FILELIST);
X}
X
X
X
X/*
X** Do any clean up for exit.
X*/
Xvoid
XEpilog(ret_code)
Xint ret_code;
X{
X   Unlink_temp_files(&Root_how);
X   exit( ret_code );
X}
X
X
X
X/*
X** Use the built-in functions of the operating system to get the current
X** working directory.
X*/
Xchar *
XGet_current_dir()
X{
X   static char buf[MAX_PATH_LEN+1];
X
X   return( getcwd(buf, sizeof(buf)) );
X}
X
X
X
X/*
X** change working directory
X*/
Xint
XSet_dir(path)
Xchar*   path;
X{
X   return( chdir(path) );
X}
X
X
X
X/*
X** return switch char
X*/
Xchar
XGet_switch_char()
X{
X   return( getswitchar() );
X}
X
X
X
X/*
X** Generate a temporary file name and open the file for writing.
X** If a name cannot be generated or the file cannot be opened
X** return -1, else return the fileno of the open file.
X** and update the source file pointer to point at the new file name.
X** Note that the new name should be freed when the file is removed.
X*/
XFILE*
XOpen_temp(path, suff)
Xchar **path;
Xchar *suff;
X{
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( fopen(*path, "w") );
X}
X
X
X/*
X** Open a new temporary file and set it up for writing.
X*/
XFILE *
XStart_temp( suffix, cp, how, fname )
Xchar     *suffix;
XCELLPTR   cp;
XHOWPTR    how;
Xchar    **fname;
X{
X   FILE	       *fp;
X   char        *tmpname;
X   char	       *name;
X   FILELISTPTR new;
X
X   name = (cp != NIL(CELL))?cp->CE_NAME:"makefile text";
X   if( how == NIL(HOW) ) how = &Root_how;
X
X   if( (fp = Open_temp( &tmpname, suffix)) == NIL(FILE) )
X      Fatal("Cannot open temp file `%s' while processing `%s'", tmpname, name );
X
X   TALLOC( new, 1, FILELIST );
X
X   new->fl_next = how->hw_files;
X   new->fl_name = tmpname;
X   new->fl_file = fp;		/* indicates temp file is open */
X
X   how->hw_files = new;
X   *fname = tmpname;
X
X   return( fp );
X}
X
X
X/*
X** Close a previously used temporary file.
X*/
Xvoid
XClose_temp(how, file)
XHOWPTR  how;
XFILE    *file;
X{
X   FILELISTPTR fl;
X   if( how == NIL(HOW) ) how = &Root_how;
X
X   for( fl=how->hw_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
X
X/*
X** Clean-up, and close all temporary files associated with a target.
X*/
Xvoid
XUnlink_temp_files( how )/*
X==========================
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. */
XHOWPTR how;
X{
X   FILELISTPTR next;
X
X   while( how->hw_files != NIL(FILELIST) ) {
X      if( how->hw_files->fl_file ) fclose( how->hw_files->fl_file );
X
X      if( Verbose )
X         printf( "%s:  Left temp file [%s]\n", Pname, how->hw_files->fl_name );
X      else
X         (void) unlink( how->hw_files->fl_name );
X
X      FREE( how->hw_files->fl_name );
X      next = how->hw_files->fl_next;
X      FREE(how->hw_files);
X      how->hw_files = next;
X   }
X}
X
X
Xvoid
XHandle_result(status, ignore, abort_flg, target)
Xint	status;
Xint	ignore;
Xint	abort_flg;
XCELLPTR target;
X{
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( unlink( 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	 unlink( target->ce_fname );
X}
X
X
Xvoid
XUpdate_time_stamp( cp, how )
XCELLPTR cp;
XHOWPTR  how;
X{
X   HASHPTR hp;
X   CELLPTR tcp;
X   int     tmpflg; 
X
X   how->hw_flag |= F_MADE;
X   Unlink_temp_files( how );
X
X   /* do the time only at end, of MULTI recipe targets, or immediately
X    * for non-MULTI recipe targets. */
X   tmpflg = cp->ce_flag & F_MULTI;
X
X   if( (tmpflg && cp->CE_HOW == how) || !tmpflg ) {
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( Trace ) {
X	    tcp->ce_time  = Do_time();
X	    tcp->ce_flag |= F_STAT;		/* pretend we stated ok */
X
X	    if( tcp->ce_fname == NIL(char) )
X	       tcp->ce_fname = tcp->CE_NAME;
X	 }
X	 else {
X	    Stat_target( tcp, TRUE );
X	    if( tcp->ce_time == (time_t) 0L )
X	       tcp->ce_time = Do_time();
X	 }
X
X	 if( Verbose )
X	    printf( "%s:  <<<< Set [%s] time stamp to %ld\n",
X		    Pname, tcp->CE_NAME, tcp->ce_time );
X
X	 tcp->ce_flag |= F_MADE;
X	 tcp = tcp->ce_all;
X      }
X      while( tcp != NIL(CELL) && tcp != cp );
X   }
X   else if( tmpflg )
X      cp->ce_flag |= F_STAT;
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   if( (hp = Get_name( ".REMOVE", Defs, FALSE, NIL(CELL) )) != NIL(HASH) ) {
X      register LINKPTR dp;
X      int flag = FALSE;
X      int rem;
X      t_attr attr;
X
X      tcp = hp->CP_OWNR;
X      tcp->ce_flag |= F_TARGET;
X      Clear_prerequisites( tcp->CE_HOW );
X
X      for( dp = how->hw_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		!(attr & A_PRECIOUS) &&
X		!Force;
X
X	 if( rem ) {
X	    CELLPTR tmp = prq;
X	    do {
X	       (Add_prerequisite(tcp->CE_HOW, prq, 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 ) Remove_prq( tcp );
SHAR_EOF
echo "End of part 4"
echo "File sysintf.c is continued in part 5"
echo "5" > s2_seq_.tmp
exit 0



More information about the Comp.sources.misc mailing list