dvadura@watdragon.waterloo.edu (Dennis Vadura) (05/13/91)
Submitted-by: Dennis Vadura <dvadura@watdragon.waterloo.edu> Posting-number: Volume 19, Issue 48 Archive-name: dmake/part27 Supersedes: dmake-3.6: Volume 15, Issue 52-77 ---- Cut Here and feed the following to sh ---- #!/bin/sh # this is dmake.shar.27 (part 27 of a multipart archive) # do not concatenate these parts, unpack them in order with /bin/sh # file dmake/os2/mscdos/public.h continued # if test ! -r _shar_seq_.tmp; then echo 'Please unpack part 1 first!' exit 1 fi (read Scheck if test "$Scheck" != 27; 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/os2/mscdos/public.h' && 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)); 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)); char* basename ANSI((char *)); 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 *)); void SetSessionTitle ANSI(()); int Wait_for_child ANSI((int, int)); void Clean_up_processes ANSI(()); int _chdir ANSI((char *)); int If_root_path ANSI((char *)); time_t seek_arch ANSI((char*, char*)); int touch_arch ANSI((char*, char*)); void Remove_prq ANSI((CELLPTR)); X #endif SHAR_EOF chmod 0640 dmake/os2/mscdos/public.h || echo 'restore of dmake/os2/mscdos/public.h failed' Wc_c="`wc -c < 'dmake/os2/mscdos/public.h'`" test 5614 -eq "$Wc_c" || echo 'dmake/os2/mscdos/public.h: original size 5614, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= dmake/os2/mscdos/startup.mk ============== if test -f 'dmake/os2/mscdos/startup.mk' -a X"$1" != X"-c"; then echo 'x - skipping dmake/os2/mscdos/startup.mk (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp sed 's/^X//' << 'SHAR_EOF' > 'dmake/os2/mscdos/startup.mk' && #NOTE: startup.mk file is called dmake.ini for OS/2 # and is found in os2/mscdos/dmake.ini .INCLUDE : "os2/mscdos/dmake.ini" SHAR_EOF chmod 0640 dmake/os2/mscdos/startup.mk || echo 'restore of dmake/os2/mscdos/startup.mk failed' Wc_c="`wc -c < 'dmake/os2/mscdos/startup.mk'`" test 132 -eq "$Wc_c" || echo 'dmake/os2/mscdos/startup.mk: original size 132, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= dmake/os2/mscdos/tempnam.c ============== if test -f 'dmake/os2/mscdos/tempnam.c' -a X"$1" != X"-c"; then echo 'x - skipping dmake/os2/mscdos/tempnam.c (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp sed 's/^X//' << 'SHAR_EOF' > 'dmake/os2/mscdos/tempnam.c' && /*LINTLIBRARY*/ #include <stdio.h> #include <string.h> #include <stdlib.h> #include <dos.h> X #if defined(max) # undef max #endif #define max(A,B) (((A)<(B))?(B):(A)) X extern int access(); int _access(); X /* 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 = ""; X char * tempnam(dir, prefix) char *dir; /* use this directory please (if non-NULL) */ char *prefix; /* use this (if non-NULL) as filename prefix */ { X static int count = 0; X register char *p, *q, *tmpdir; X int tl=0, dl=0, pl; X char buf[30]; X X pl = strlen(P_tmpdir); X X if( (tmpdir = getenv("TMPDIR")) != NULL ) X tl = strlen(tmpdir); X else if( (tmpdir = getenv("TMP")) != NULL ) X tl = strlen(tmpdir); X if( dir != NULL ) dl = strlen(dir); X X if( (p = malloc((unsigned)(max(max(dl,tl),pl)+13))) == NULL ) X return(NULL); X X *p = '\0'; X X if( (tl == 0) || (_access( strcpy(p, tmpdir), 0) != 0) ) X if( (dl == 0) || (_access( strcpy(p, dir), 0) != 0) ) X if( _access( strcpy(p, P_tmpdir), 0) != 0 ) X if( !prefix ) X prefix = "tp"; X X if(prefix) X { X *(p+strlen(p)+2) = '\0'; X (void)strncat(p, prefix, 2); X } X #ifdef OS2 X sprintf( buf, "%08x", getpid() ); #else X sprintf( buf, "%08x", _psp ); #endif X buf[6]='\0'; X (void)strcat(p, buf ); X sprintf( buf, "%04d", count++ ); X q=p+strlen(p)-6; X *q++ = buf[0]; *q++ = buf[1]; X *q++ = buf[2]; *q++ = buf[3]; X X if( (q = strrchr(p,'.')) != NULL ) *q = '\0'; X X return strlwr(p); } X X X _access( name, flag ) char *name; int flag; { X char *p; X int r; X X if( name == NULL || !*name ) return(1); /* NULL dir means current dir */ X p = name+strlen(name)-1; X if(*p == ':' ) strcat( p++, "\\" ); X r = access( name, flag ); X if(*p != '/' && *p != '\\') strcat( p, "\\" ); X X return( r ); } SHAR_EOF chmod 0640 dmake/os2/mscdos/tempnam.c || echo 'restore of dmake/os2/mscdos/tempnam.c failed' Wc_c="`wc -c < 'dmake/os2/mscdos/tempnam.c'`" test 1919 -eq "$Wc_c" || echo 'dmake/os2/mscdos/tempnam.c: original size 1919, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= dmake/os2/ruletab.c ============== if test -f 'dmake/os2/ruletab.c' -a X"$1" != X"-c"; then echo 'x - skipping dmake/os2/ruletab.c (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp sed 's/^X//' << 'SHAR_EOF' > 'dmake/os2/ruletab.c' && /* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/os2/RCS/ruletab.c,v 1.1 91/05/06 15:33:22 dvadura 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@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: ruletab.c,v $ X * Revision 1.1 91/05/06 15:33:22 dvadura X * dmake Release Version 3.7 X * */ X /* These are control macros for dmake that MUST be defined at some point X * if they are NOT dmake will not work! These are default definitions. They X * may be overridden inside the .STARTUP makefile, they are here X * strictly so that dmake can parse the STARTUP makefile */ /* X * For OS/2 these are close to the Unix definitions in terms of limits. X * We dont need the two different cases of Makefile, so only keep the X * pretty one. X */ static char *_rules[] = { X "MAXLINELENGTH := 2046", X "MAXPROCESSLIMIT := 16", X ".IMPORT .IGNORE: ROOTDIR INIT", X ".MAKEFILES : makefile.mk Makefile", X ".SOURCE : .NULL", #include "startup.h" X 0 }; X char **Rule_tab = _rules; /* for sundry reasons in Get_environment() */ X SHAR_EOF chmod 0640 dmake/os2/ruletab.c || echo 'restore of dmake/os2/ruletab.c failed' Wc_c="`wc -c < 'dmake/os2/ruletab.c'`" test 2098 -eq "$Wc_c" || echo 'dmake/os2/ruletab.c: original size 2098, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= dmake/os2/runargv.c ============== if test -f 'dmake/os2/runargv.c' -a X"$1" != X"-c"; then echo 'x - skipping dmake/os2/runargv.c (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp sed 's/^X//' << 'SHAR_EOF' > 'dmake/os2/runargv.c' && /* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/os2/RCS/runargv.c,v 1.1 91/05/06 15:33:22 dvadura Exp $ -- SYNOPSIS -- invoke a sub process, modified unix/runargv.c for OS/2. -- -- DESCRIPTION -- Use the standard methods of executing a sub process. -- -- 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: runargv.c,v $ X * Revision 1.1 91/05/06 15:33:22 dvadura X * dmake Release Version 3.7 X * */ X #define INCL_DOSPROCESS #include <os2.h> X #include <process.h> #include <stdlib.h> #include <signal.h> #include "extern.h" #include "sysintf.h" X typedef 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; } RCP, *RCPPTR; X typedef struct pr { X int pr_valid; X int pr_pid; X CELLPTR pr_target; X int pr_ignore; X int pr_last; X RCPPTR pr_recipe; X RCPPTR pr_recipe_end; X char *pr_dir; } PR; X 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; X extern unsigned int _far _pascal DosSmSetTitle(char _far *s); static void SetSessionTitle (char *s); 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)); X PUBLIC int runargv(target, ignore, group, last, shell, cmd) CELLPTR target; int ignore; int group; int last; int shell; char *cmd; { X int pid; X char **argv; X X if( _running(target) /*&& Max_proc != 1*/ ) { X /* The command will be executed when the previous recipe X * line completes. */ X _attach_cmd( cmd, group, ignore, target, 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 #ifdef SESSTITLE X SetSessionTitle(target->CE_NAME); #endif X argv = Pack_argv( group, shell, cmd ); X X if((pid=spawnvp((_osmode == DOS_MODE)?P_WAIT:P_NOWAIT,argv[0],argv)) == -1){ X Error("%s: %s", argv[0], sys_errlist[errno]); X Handle_result(-1, ignore, _abort_flg, target); X return(-1); X } X else if( _osmode == DOS_MODE ) { X _add_child(4711, target, ignore, last); X _finished_child(4711, pid); X } X else X _add_child(pid, target, ignore, last); X X return(1); } X X #ifdef SESSTITLE /* N.B. The system call used below is undocumented and therefore possibly X * subject to change. It sets the session title even from a full screen X * session, so you can see which target is being built. X * If dubious about undocumented calls simply remove it. X */ PUBLIC void SetSessionTitle(char *s) { X char buff[128]; X strncpy(buff, Pname, sizeof(buff)); X buff[sizeof(buff)-1] = 0; X strncat(buff, " - ", sizeof(buff)); X strncat(buff, s, sizeof(buff)); X buff[sizeof(buff)-1] = 0; X DosSmSetTitle(buff); } #endif X X PUBLIC int Wait_for_child( abort_flg, pid ) int abort_flg; int pid; { X int wid; X int status; X int waitchild; X X if( _osmode == DOS_MODE ) return(1); 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 PUBLIC void Clean_up_processes() { X register int i; X X if( _osmode == DOS_MODE ) { X _abort_flg = TRUE; X _finished_child(4711, -1); X return; X } X X if( _procs != NIL(PR) ) { X for( i=0; i<Max_proc; i++ ) X if( _procs[i].pr_valid ) X DosKillProcess(DKP_PROCESSTREE, _procs[i].pr_pid); X X while( Wait_for_child(TRUE, -1) != -1 ); X } } X X static void _add_child( pid, target, ignore, last ) int pid; CELLPTR target; int ignore; int last; { 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_ignore = ignore; X pp->pr_last = last; X pp->pr_dir = _strdup(Get_current_dir()); X X Current_target = NIL(CELL); X X _proc_cnt++; X X if( Wait_for_completion ) Wait_for_child( FALSE, pid ); } X X static void _finished_child(pid, status) int pid; int status; { X register int i; X register PR *pp; X char *dir; X X for( i=0; i<Max_proc; i++ ) X if( _procs[i].pr_valid && _procs[i].pr_pid == pid ) X break; X X /* Some children we didn't make esp true if using /bin/sh to execute a X * a pipe and feed the output as a makefile into dmake. */ X if( i == Max_proc ) return; X _procs[i].pr_valid = 0; X _proc_cnt--; X dir = _strdup(Get_current_dir()); X Set_dir( _procs[i].pr_dir ); X X if( _procs[i].pr_recipe != NIL(RCP) && !_abort_flg ) { X RCPPTR rp = _procs[i].pr_recipe; X X X Current_target = _procs[i].pr_target; X Handle_result( status, _procs[i].pr_ignore, FALSE, _procs[i].pr_target ); X Current_target = NIL(CELL); X X _procs[i].pr_recipe = rp->prp_next; X X _use_i = i; X runargv( _procs[i].pr_target, rp->prp_ignore, rp->prp_group, X rp->prp_last, rp->prp_shell, rp->prp_cmd ); 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_target ); X Handle_result(status,_procs[i].pr_ignore,_abort_flg,_procs[i].pr_target); X X if( _procs[i].pr_last ) { X FREE(_procs[i].pr_dir ); X X if( !Doing_bang ) Update_time_stamp( _procs[i].pr_target ); X } X } X X Set_dir(dir); X FREE(dir); } X X static int _running( cp ) CELLPTR cp; { 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_target == cp ) X break; X X return( i != Max_proc ); } X X static void _attach_cmd( cmd, group, ignore, cp, last, shell ) char *cmd; int group; int ignore; CELLPTR cp; int last; int shell; { 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_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 } } SHAR_EOF chmod 0640 dmake/os2/runargv.c || echo 'restore of dmake/os2/runargv.c failed' Wc_c="`wc -c < 'dmake/os2/runargv.c'`" test 7611 -eq "$Wc_c" || echo 'dmake/os2/runargv.c: original size 7611, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= dmake/os2/startup.h ============== if test -f 'dmake/os2/startup.h' -a X"$1" != X"-c"; then echo 'x - skipping dmake/os2/startup.h (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp sed 's/^X//' << 'SHAR_EOF' > 'dmake/os2/startup.h' && /* This file contains the default value of the MAKESTARTUP variable. X * You must set the quoted string below to the default path to the startup X * variable, so that it gets compiled in. LEAVE ROOTDIR at the front of X * the path. This allows the user to customize his environment for dmake X * by setting up a new ROOTDIR environment variable. */ X "MAKESTARTUP := $(INIT)/dmake.ini", SHAR_EOF chmod 0640 dmake/os2/startup.h || echo 'restore of dmake/os2/startup.h failed' Wc_c="`wc -c < 'dmake/os2/startup.h'`" test 384 -eq "$Wc_c" || echo 'dmake/os2/startup.h: original size 384, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= dmake/os2/stdarg.h ============== if test -f 'dmake/os2/stdarg.h' -a X"$1" != X"-c"; then echo 'x - skipping dmake/os2/stdarg.h (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp sed 's/^X//' << 'SHAR_EOF' > 'dmake/os2/stdarg.h' && /* 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 #if !defined(__STDARG) #define __STDARG X typedef char *va_list; X #define va_dcl int va_alist #define va_start(ap,v) ap = (va_list)&va_alist #define va_arg(ap,t) ((t*)(ap += sizeof(t)))[-1] #define va_end(ap) ap = NULL #endif SHAR_EOF chmod 0640 dmake/os2/stdarg.h || echo 'restore of dmake/os2/stdarg.h failed' Wc_c="`wc -c < 'dmake/os2/stdarg.h'`" test 373 -eq "$Wc_c" || echo 'dmake/os2/stdarg.h: original size 373, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= dmake/os2/switchar.c ============== if test -f 'dmake/os2/switchar.c' -a X"$1" != X"-c"; then echo 'x - skipping dmake/os2/switchar.c (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp sed 's/^X//' << 'SHAR_EOF' > 'dmake/os2/switchar.c' && /* ** return switch char */ #if defined(OS2) || defined(_MSC_VER) #include <stdlib.h> #endif #if !defined(OS2) #include <dos.h> #endif /* !OS2 */ #include <stdio.h> #include "stdmacs.h" X getswitchar()/* =============== X Try the environment first. If you don't find SWITCHAR there, then use X the DOS call. The call is undocumented, and doesn't work for DOS versions X 4.0 and up, so the check of the environment will fix that. */ { #if defined(M_I86) #if !defined(OS2) X union REGS rg; #endif /* ! OS2 */ X static char *_env_switchar = NIL(char); X X if( _env_switchar != NIL(char) || X (_env_switchar = (char *)getenv("SWITCHAR")) != NIL(char) ) X return(*_env_switchar); X #if !defined(OS2) X rg.h.ah = 0x37; /* switch char request */ X rg.h.al = 0; /* get (not set) */ X X intdos(&rg, &rg); X return (rg.h.dl); #endif /* ! OS2 */ #endif /* M_I86 */ X X return ('/'); } SHAR_EOF chmod 0640 dmake/os2/switchar.c || echo 'restore of dmake/os2/switchar.c failed' Wc_c="`wc -c < 'dmake/os2/switchar.c'`" test 904 -eq "$Wc_c" || echo 'dmake/os2/switchar.c: original size 904, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= dmake/os2/sysintf.h ============== if test -f 'dmake/os2/sysintf.h' -a X"$1" != X"-c"; then echo 'x - skipping dmake/os2/sysintf.h (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp sed 's/^X//' << 'SHAR_EOF' > 'dmake/os2/sysintf.h' && /* ** assorted bits of system interface */ X #define STAT stat #define VOID_LCACHE(l,m) #define Hook_std_writes(A) #define GETPID getpid() X extern char * tempnam(); extern char * getcwd(); X /* ** standard C items */ X /* ** DOS interface standard items */ #define chdir(p) _chdir(p) X /* ** make parameters */ #define MAX_PATH_LEN 256 X SHAR_EOF chmod 0640 dmake/os2/sysintf.h || echo 'restore of dmake/os2/sysintf.h failed' Wc_c="`wc -c < 'dmake/os2/sysintf.h'`" test 333 -eq "$Wc_c" || echo 'dmake/os2/sysintf.h: original size 333, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= dmake/parse.c ============== if test -f 'dmake/parse.c' -a X"$1" != X"-c"; then echo 'x - skipping dmake/parse.c (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp sed 's/^X//' << 'SHAR_EOF' > 'dmake/parse.c' && /* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/parse.c,v 1.1 91/05/06 15:23:20 dvadura 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@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: parse.c,v $ X * Revision 1.1 91/05/06 15:23:20 dvadura X * dmake Release Version 3.7 X * */ X #include "extern.h" X X PUBLIC void Parse( fil )/* ============== Parse the makefile input */ FILE *fil; { X int rule = FALSE; /* have seen a recipe line */ X char *p; /* termporary pointer into Buffer */ X X DB_ENTER( "Parse" ); X X State = NORMAL_SCAN; X Group = FALSE; /* true if scanning a group rcpe */ X while( TRUE ) { X if( Get_line( Buffer, fil ) ) { X if( fil != NIL( FILE ) ) /* end of parsable input */ X Closefile(); X X Bind_rules_to_targets( F_DEFAULT ); X if( Group ) Fatal( "Incomplete rule recipe group detected" ); X X DB_VOID_RETURN; X } X else { X switch( State ) { X case RULE_SCAN: X X /* Check for the `[' that starts off a group rule definition. It X * must appear as the first non-white space X * character in the line. */ X X p = _strspn( Buffer, " \t\r\n" ); X if( Set_group_attributes( p ) ) { X if( rule && Group ) X Fatal( "Cannot mix single and group recipe lines" ); X else X Group = TRUE; X X rule = TRUE; X X break; /* ignore the group start */ X } X X if( Group ) { X if( *p != ']' ) { X Add_recipe_to_list( Buffer, TRUE, TRUE ); X rule = TRUE; X } X else X State = NORMAL_SCAN; X } X else { X if( *Buffer == '\t' ) { X Add_recipe_to_list( Buffer, FALSE, FALSE ); X rule = TRUE; X } X else if( *p == ']' ) X Fatal( "Found unmatched ']'" ); X else if( *Buffer && *p ) X State = NORMAL_SCAN; X } X X if( State == RULE_SCAN ) break; /* ie. keep going */ X X Bind_rules_to_targets( (Group) ? F_GROUP: F_DEFAULT ); X X rule = FALSE; X if( Group ) { X Group = FALSE; X break; X } X /*FALLTRHOUGH*/ X X /* In this case we broke out of the rule scan because we do not X * have a recipe line that begins with a <TAB>, so lets X * try to scan the thing as a macro or rule definition. */ X X X case NORMAL_SCAN: X if( !*Buffer ) continue; /* we have null input line */ X X /* STUPID AUGMAKE uses "include" at the start of a line as X * a signal to include a new file, so let's look for it. X * if we see it replace it by .INCLUDE: and stick this back X * into the buffer. */ X if( !strncmp( "include", Buffer, 7 ) && X (Buffer[7] == ' ' || Buffer[7] == '\t') ) X { X char *tmp; X X tmp = _strjoin( ".INCLUDE:", Buffer+7, -1, FALSE ); X strcpy( Buffer, tmp ); X FREE( tmp ); X } X X /* look for a macro definition, they all contain an = sign X * if we fail to recognize it as a legal macro op then try to X * parse the same line as a rule definition, it's one or the X * other */ X X if( Parse_macro(Buffer, M_DEFAULT) ) break;/* it's a macro def */ X if( Parse_rule_def( &State ) ) break;/* it's a rule def */ X X /* if just blank line then ignore it */ X if( *_strspn( Buffer, " \t\r\n" ) == '\0' ) break; X X /* otherwise assume it was a line of unrecognized input, or a X * recipe line out of place so print a message */ X X Fatal( "Expecting macro or rule defn, found neither" ); X break; X X default: X Fatal( "Internal -- UNKNOWN Parser state %d", State ); X } X } X } } X SHAR_EOF chmod 0640 dmake/parse.c || echo 'restore of dmake/parse.c failed' Wc_c="`wc -c < 'dmake/parse.c'`" test 5207 -eq "$Wc_c" || echo 'dmake/parse.c: original size 5207, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= dmake/patchlvl.h ============== if test -f 'dmake/patchlvl.h' -a X"$1" != X"-c"; then echo 'x - skipping dmake/patchlvl.h (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp sed 's/^X//' << 'SHAR_EOF' > 'dmake/patchlvl.h' && /* dmake patch level, reset to 0 for each new version release. */ X #define PATCHLEVEL 0 SHAR_EOF chmod 0640 dmake/patchlvl.h || echo 'restore of dmake/patchlvl.h failed' Wc_c="`wc -c < 'dmake/patchlvl.h'`" test 88 -eq "$Wc_c" || echo 'dmake/patchlvl.h: original size 88, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= dmake/path.c ============== if test -f 'dmake/path.c' -a X"$1" != X"-c"; then echo 'x - skipping dmake/path.c (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp sed 's/^X//' << 'SHAR_EOF' > 'dmake/path.c' && /* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/path.c,v 1.1 91/05/06 15:23:23 dvadura Exp $ -- SYNOPSIS -- pathname manipulation code -- -- DESCRIPTION -- Pathname routines to handle building and pulling appart -- pathnames. -- -- 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: path.c,v $ X * Revision 1.1 91/05/06 15:23:23 dvadura X * dmake Release Version 3.7 X * */ X #include "extern.h" X /* ** Return the suffix portion of a filename, assumed to begin with a `.'. */ PUBLIC char * Get_suffix(name) char *name; { X char *suff; X X if(name == NIL(char) || (suff = strrchr(name, '.')) == NIL(char)) X suff = ".NULL"; X X return (suff); } X X X /* ** 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; { X register char *p; X register char *q; X static char *path = NIL(char); X static unsigned buflen = 0; X int plen = 0; X int dlen = 0; X int len; X X if( dir != NIL(char) ) dlen = strlen( dir ); X if( name != NIL(char) ) plen = strlen( name ); X len = plen+dlen+strlen(DirSepStr)+1; X X if( len > buflen ) { X buflen = (len+16) & ~0xf; /* buf is always multiple of 16 */ X X if( path == NIL(char) ) X path = MALLOC( buflen, char ); X else X path = realloc( path, (unsigned) (buflen*sizeof(char)) ); X } X X *path = '\0'; X X if( dlen ) { X strcpy( path, dir ); X if( *path && strchr(DirBrkStr, dir[dlen-1]) == NIL(char) ) X strcat( path, DirSepStr ); X } X strcat( path, name ); X X q=path; X while( *q ) { X char *t; X X p=_strpbrk(q,DirBrkStr); X t=_strpbrk(p+1,DirBrkStr); X if( !*p || !*t ) break; X X if( !(p-q == 2 && strncmp(q,"..",2) == 0) X && t-p-1 == 2 && strncmp(p+1,"..",2) == 0 ) { X t = _strspn(t,DirBrkStr); X strcpy(q,t); X } X else X q = p+1; X } X X return( path ); } SHAR_EOF chmod 0640 dmake/path.c || echo 'restore of dmake/path.c failed' Wc_c="`wc -c < 'dmake/path.c'`" test 3063 -eq "$Wc_c" || echo 'dmake/path.c: original size 3063, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= dmake/percent.c ============== if test -f 'dmake/percent.c' -a X"$1" != X"-c"; then echo 'x - skipping dmake/percent.c (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp sed 's/^X//' << 'SHAR_EOF' > 'dmake/percent.c' && /* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/percent.c,v 1.1 91/05/06 15:23:24 dvadura 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@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: percent.c,v $ X * Revision 1.1 91/05/06 15:23:24 dvadura X * dmake Release Version 3.7 X * */ X #include "extern.h" X static DFAPTR _build_dfa ANSI((char *)); static char _shift_dfa ANSI((DFAPTR, char *)); X X #define NO_ACTION 0 #define START_PERCENT 1 #define END_PERCENT 2 #define ACCEPT 4 #define FAIL -1 X static NFAPTR _nfa = NIL( NFA ); X X PUBLIC DFALINKPTR Match_dfa( buf )/* ================== X This routines runs all DFA's in parrallel and selects the one that best X matches the string. If no match then it returns NIL( DFA ) */ char *buf; { X register NFAPTR nfa; X int adv; X DFALINKPTR dfa_list = NIL(DFALINK); X X DB_ENTER( "Match_dfa" ); X DB_PRINT( "dfa", ("Matching %s", buf) ); X X /* Run each of the DFA's on the input string in parallel, we terminate X * when all DFA's have either failed or ACCEPTED, if more than one DFA X * accepts we build a list of all accepting DFA's sorted on states with X * those matching in a higher numbered state heading the list. */ X X do { X adv = FALSE; X X for( nfa = _nfa; nfa != NIL( NFA ); nfa = nfa->next ) X if( nfa->status != (char) FAIL && nfa->status != (char) ACCEPT ) { X adv++; X nfa->status = _shift_dfa( nfa->dfa, buf ); X X /* Construct the list of matching DFA's */ X if( nfa->status == (char) ACCEPT ) { X DFALINKPTR dl; X X TALLOC( dl, 1, DFALINK ); X dl->dl_meta = nfa->dfa->node; X dl->dl_per = _substr( nfa->dfa->pstart, nfa->dfa->pend ); X dl->dl_state = nfa->dfa->states - nfa->dfa->c_state; X X if( dfa_list == NIL(DFALINK) ) X dfa_list = dl; X else { X DFALINKPTR tdli = dfa_list; X DFALINKPTR tdlp = NIL(DFALINK); X X for( ; tdli != NIL(DFALINK); tdli = tdli->dl_next ) { X if( dl->dl_state >= tdli->dl_state ) X break; X tdlp = tdli; X } X X if( tdli != NIL(DFALINK) ) { X tdli->dl_prev = dl; X dl->dl_next = tdli; X } X X if( tdlp != NIL(DFALINK) ) { X tdlp->dl_next = dl; X dl->dl_prev = tdlp; X } X else X dfa_list = dl; X } X X DB_PRINT( "dfa", ("Matched [%s]", dl->dl_meta->CE_NAME) ); X } X } X X buf++; X } X while ( adv ); X X for( nfa = _nfa; nfa != NIL( NFA ); nfa = nfa->next ) { X nfa->status = 0; X nfa->dfa->c_state = nfa->dfa->states; X } X X DB_RETURN( dfa_list ); } X X PUBLIC void Check_circle_dfa()/* ==================== X This function is called to test for circularities in the DFA lists X constructed from %-meta targets. */ { X register NFAPTR nfa; X X for( nfa = _nfa; nfa != NIL(NFA); nfa = nfa->next ) X if( Test_circle( nfa->dfa->node, FALSE ) ) X Fatal( "Detected circular dependency in inference graph at [%s]", X nfa->dfa->node->CE_NAME ); } X X PUBLIC void Add_nfa( name )/* ================= X Given name, build a DFA and add it to the NFA. The NFA is maintained as X a singly linked list of DFA's. */ char *name; { X NFAPTR nfa; X X TALLOC(nfa, 1, NFA); X nfa->dfa = _build_dfa(name); X X if( _nfa != NIL(NFA) ) nfa->next = _nfa; X X _nfa = nfa; } X X static DFAPTR _build_dfa( name )/* ==================== X Construct a dfa for the passed in cell name. The routine returns a struct X that represents a finite state machine that can recognize a regular X expression with exactly one '%' sign in it. The '%' symbol is used as a X wildcard character that will match anything except the character that X immediately follows it or NUL. X X The Construction of DFA's is well know and can be found in Hopcroft and X Ullman or any other book discussing formal language theory. X A more practical treatise can be found in Compilers, Aho, Sethi and Ullman. */ char *name; { X DFAPTR dfa; X int nstates; X register STATEPTR sp; X STATEPTR per_state = NIL(STATE); X int pcount=0; X int end_percent=FALSE; X X nstates = strlen(name)+2; X X /* Allocate a DFA node and the right number of states. */ X TALLOC(dfa, 1, DFA); X TALLOC(sp=dfa->c_state=dfa->states, nstates, STATE); X dfa->node = Def_cell( name ); X X /* Now construct the state table for the DFA */ X do { X if( *name == '%' ) { X if( pcount++ > 0 ) X Error( "Only one %% allowed within a %%-meta target" ); X X sp->symbol = 0; X sp->action = START_PERCENT; X sp->no_match = sp->match = per_state = sp+1; X end_percent = TRUE; X } X else { X sp->symbol = *name; X sp->no_match = per_state; X X if( *name == '\0' ) { X sp->action = ACCEPT; X sp->match = dfa->states; X } X else { X sp->action = NO_ACTION; X sp->match = sp+1; X } X X if( end_percent ) { X sp->action |= END_PERCENT; X end_percent = FALSE; X } X } X X sp++; X } X while( *name++ ); X X return(dfa); } X X static char _shift_dfa( dfa, data )/* ========================= X Take a given dfa and advance it based on the current state, the shift X action in that state, and the current data value. */ DFAPTR dfa; char *data; { X register STATEPTR sp = dfa->c_state; X char c = *data; X X /* Check if it is a START_PERCENT action if so then we need to save X * a pointer to the start of the string and advance to the next state. */ X if( sp->action & START_PERCENT ) { X dfa->pstart = data; X sp++; X } X X /* Now check if the current char matches the character expected in the X * current state. If it does then perform the specified action, otherwise X * either shift it or fail. We fail if the next state on no-match is X * NIL. */ X if( sp->symbol == c ) { X if( sp->action & END_PERCENT ) dfa->pend = data; X if( sp->action & ACCEPT ) return(ACCEPT); X dfa->c_state = sp->match; X } X else if( (dfa->c_state = sp->no_match) == NIL(STATE) || !c ) X return(FAIL); X X return(NO_ACTION); } SHAR_EOF chmod 0640 dmake/percent.c || echo 'restore of dmake/percent.c failed' Wc_c="`wc -c < 'dmake/percent.c'`" test 7050 -eq "$Wc_c" || echo 'dmake/percent.c: original size 7050, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= dmake/quit.c ============== if test -f 'dmake/quit.c' -a X"$1" != X"-c"; then echo 'x - skipping dmake/quit.c (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp sed 's/^X//' << 'SHAR_EOF' > 'dmake/quit.c' && /* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/quit.c,v 1.1 91/05/06 15:23:25 dvadura Exp $ -- SYNOPSIS -- end the dmake session. -- -- DESCRIPTION -- Handles dmake termination. -- -- 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: quit.c,v $ X * Revision 1.1 91/05/06 15:23:25 dvadura X * dmake Release Version 3.7 X * */ X #include "extern.h" X static void _handle_quit ANSI((char*)); static int _dont_quit = 0; X X PUBLIC void Quit()/* ======== Error or quit */ { X if( _dont_quit ) return; SHAR_EOF true || echo 'restore of dmake/quit.c failed' fi echo 'End of part 27, continue with part 28' echo 28 > _shar_seq_.tmp exit 0 exit 0 # Just in case... -- Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM Sterling Software, IMD UUCP: uunet!sparky!kent Phone: (402) 291-8300 FAX: (402) 291-4362 Please send comp.sources.misc-related mail to kent@uunet.uu.net.