home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-07-26 | 39.3 KB | 1,331 lines |
- Newsgroups: comp.sources.misc
- subject: v14i027: dmake version 3.5 part 17/21
- From: dvadura@watdragon.waterloo.edu (Dennis Vadura)
- Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
-
- Posting-number: Volume 14, Issue 27
- Submitted-by: dvadura@watdragon.waterloo.edu (Dennis Vadura)
- Archive-name: dmake/part17
-
- #!/bin/sh
- # this is part 17 of a multipart archive
- # do not concatenate these parts, unpack them in order with /bin/sh
- # file expand.c continued
- #
- CurArch=17
- 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 expand.c"
- sed 's/^X//' << 'SHAR_EOF' >> expand.c
- X }
- X}
- X
- X
- X
- Xstatic char*
- X_scan_token( s, ps )/*
- X======================
- X This routine scans the token characters one at a time and identifies
- X macros starting with $( and ${ and calls _scan_macro to expand their
- X value. the string1{ token_list }string2 expansion is also handled.
- X In this case a temporary result is maintained so that we can take it's
- X cross product with any other token_lists that may possibly appear. */
- X
- Xchar *s; /* pointer to start of src string */
- Xchar **ps; /* pointer to start pointer */
- X{
- X char *res; /* pointer to result */
- X char *start; /* pointer to start of prefix */
- X int crossproduct = 0; /* if 1 then computing X-prod */
- X
- X start = s;
- X res = _strdup( "" );
- X while( 1 )
- X switch( *s ) {
- X /* Termination, We halt at seeing a space or a tab or end of string.
- X * We return the value of the result with any new macro's we scanned
- X * or if we were computing cross_products then we return the new
- X * cross_product.
- X * NOTE: Once we start computing cross products it is impossible to
- X * stop. ie. the semantics are such that once a {} pair is
- X * seen we compute cross products until termination. */
- X
- X case ' ':
- X case '\t':
- X case '\n':
- X case '\0':
- X {
- X char *tmp;
- X
- X *ps = s;
- X if( !crossproduct )
- X tmp = _strjoin( res, start, (s-start), TRUE );
- X else
- X {
- X tmp = _substr( start, s );
- X tmp = _cross_prod( res, tmp );
- X }
- X return( tmp );
- X }
- X
- X case '$':
- X case '{':
- X {
- X /* Handle if it's a macro or if it's a {} construct.
- X * The results of a macro expansion are handled differently based
- X * on whether we have seen a {} beforehand. */
- X
- X char *tmp;
- X tmp = _substr( start, s ); /* save the prefix */
- X
- X if( *s == '$' ) {
- X start = _scan_macro( s+1, &s );
- X
- X if( crossproduct )
- X res = _cross_prod( res, _strjoin( tmp, start, -1, TRUE ) );
- X else {
- X res = _strjoin(res,tmp = _strjoin(tmp,start,-1,TRUE),-1,TRUE);
- X FREE( tmp );
- X }
- X FREE( start );
- X }
- X else if( s[1] != '{' ) {
- X int ok;
- X start = _scan_brace( s+1, &s, &ok );
- X
- X if( ok ) {
- X res = _cross_prod( res, _cross_prod(tmp, start) );
- X crossproduct = TRUE;
- X }
- X else {
- X res =_strjoin(res,tmp=_strjoin(tmp,start,-1,TRUE),-1,TRUE);
- X FREE( start );
- X FREE( tmp );
- X }
- X }
- X else { /* handle the {{ case */
- X res = _strjoin( res, start, (s-start+1), TRUE );
- X s += 2;
- X FREE( tmp );
- X }
- X
- X start = s;
- X }
- X break;
- X
- X case '}':
- X if( s[1] != '}' ) {
- X /* error malformed macro expansion */
- X s++;
- X }
- X else { /* handle the }} case */
- X res = _strjoin( res, start, (s-start+1), TRUE );
- X s += 2;
- X start = s;
- X }
- X break;
- X
- X default: s++;
- X }
- X}
- X
- X
- X
- Xstatic char*
- X_scan_macro( s, ps )/*
- X======================
- X This routine scans a macro use and expands it to the value. It
- X returns the macro's expanded value and modifies the pointer into the
- X src string to point at the first character after the macro use.
- X The types of uses recognized are:
- X
- X $$ - expands to $
- X $(name) - expands to value of name
- X ${name} - same as above
- X $($(name)) - recurses on macro names (any level)
- X and
- X $(name:modifier_list:modifier_list:...)
- X
- X see comment for Expand for description of valid modifiers.
- X
- X NOTE that once a macro name bounded by ( or { is found only
- X the appropriate terminator (ie. ( or } is searched for. */
- X
- Xchar *s; /* pointer to start of src string */
- Xchar **ps; /* pointer to start pointer */
- X{
- X char sdelim; /* start of macro delimiter */
- X char edelim; /* corresponding end macro delim */
- X char *start; /* start of prefix */
- X char *macro_name; /* temporary macro name */
- X char *recurse_name; /* recursive macro name */
- X char *result; /* result for macro expansion */
- X int bflag = 0; /* brace flag, ==0 => $A type macro */
- X int done = 0; /* != 0 => done macro search */
- X int lev = 0; /* brace level */
- X int mflag = 0; /* != 0 => modifiers present in mac */
- X HASHPTR hp; /* hash table pointer for macros */
- X
- X DB_ENTER( "_scan_macro" );
- X
- X /* Check for the simple $ at end of line case */
- X if( !*s ) {
- X *ps = s;
- X DB_RETURN( _strdup("") );
- X }
- X
- X if( *s == '$' ) { /* Take care of the simple $$ case. */
- X *ps = s+1;
- X DB_RETURN( _strdup("$") );
- X }
- X
- X sdelim = *s; /* set and remember start/end delim */
- X if( sdelim == '(' )
- X edelim = ')';
- X else
- X edelim = '}';
- X
- X start = s; /* build up macro name, find its end*/
- X while( !done ) {
- X switch( *s ) {
- X case '(': /* open macro brace */
- X case '{':
- X if( *s == sdelim ) {
- X lev++;
- X bflag++;
- X }
- X break;
- X
- X case ':': /* halt at modifier */
- X if( lev == 1 ) {
- X done = TRUE;
- X mflag = 1;
- X }
- X break;
- X
- X case '\0': /* check for EOLN and spaces */
- X case ' ': /* inside a macro name */
- X case '\t':
- X case '\n':
- X *ps = s;
- X if( lev ) {
- X done = TRUE;
- X bflag = 0;
- X s = start;
- X }
- X break;
- X
- X case ')': /* close macro brace */
- X case '}':
- X if( *s == edelim && lev ) --lev;
- X /*FALLTHROUGH*/
- X
- X default:
- X done = !lev;
- X }
- X s++;
- X }
- X
- X /* Check if this is a $A type macro. If so then we have to
- X * handle it a little differently. */
- X
- X if( bflag )
- X macro_name = _substr( start+1, s-1 );
- X else
- X macro_name = _substr( start, s );
- X
- X
- X /* Check if the macro is a recursive macro name, if so then
- X * EXPAND the name before expanding the value */
- X
- X if( strchr( macro_name, '$' ) != NIL(char) ) {
- X recurse_name = Expand( macro_name );
- X FREE( macro_name );
- X macro_name = recurse_name;
- X }
- X
- X /* Code to do value expansion goes here, NOTE: macros whose assign bit
- X is one have been evaluated and assigned, they contain no further
- X expansions and thus do not need their values expanded again. */
- X
- X if( (hp = GET_MACRO( macro_name )) != NIL(HASH) ) {
- X if( hp->ht_flag & M_MARK )
- X Fatal( "Detected circular macro [%s]", hp->ht_name );
- X
- X /* for M_MULTI macro variable assignments */
- X If_multi = hp->ht_flag & M_MULTI;
- X
- X if( !(hp->ht_flag & M_EXPANDED) ) {
- X hp->ht_flag |= M_MARK;
- X result = Expand( hp->ht_value );
- X hp->ht_flag ^= M_MARK;
- X }
- X else if( hp->ht_value != NIL(char) )
- X result = _strdup( hp->ht_value );
- X else
- X result = _strdup( "" );
- X
- X /*
- X * Mark macros as used only if we are not expanding them for
- X * the purpose of a .IF test, so we can warn about redef after use*/
- X
- X if( !If_expand ) hp->ht_flag |= M_USED;
- X }
- X else
- X result = _strdup( "" );
- X
- X if( mflag ) {
- X char separator;
- X int modifier_list = 0;
- X int aug_mod = FALSE;
- X char *pat1;
- X char *pat2;
- X char *p;
- X
- X /* Yet another brain damaged AUGMAKE kludge. We should accept the
- X * AUGMAKE bullshit of $(f:pat=sub) form of macro expansion. In
- X * order to do this we will forgo the normal processing if the
- X * AUGMAKE solution pans out, otherwise we will try to process the
- X * modifiers ala dmake.
- X *
- X * So we look for = in modifier string.
- X * If found we process it and not do the normal stuff */
- X
- X for( p=s; *p && *p != '=' && *p != edelim; p++ );
- X
- X if( *p == '=' ) {
- X pat1 = _substr( s, p );
- X for( s=p=p+1; (*p != edelim); p++ );
- X
- X pat2 = _substr( s, p );
- X result = Apply_edit( result, pat1, pat2, TRUE, TRUE );
- X FREE( pat1 );
- X FREE( pat2 );
- X s = p;
- X aug_mod = TRUE;
- X }
- X
- X if( !aug_mod )
- X while( *s && *s != edelim ) { /* while not at end of macro */
- X switch( *s++ ) {
- X case 'b':
- X case 'B': modifier_list |= FILE_FLAG; break;
- X
- X case 'd':
- X case 'D': modifier_list |= DIRECTORY_FLAG; break;
- X
- X case 'f':
- X case 'F': modifier_list |= FILE_FLAG | SUFFIX_FLAG; break;
- X
- X case 'S':
- X case 's':
- X if( modifier_list ) {
- X Warning( "Edit modifier must appear alone, ignored");
- X modifier_list = 0;
- X }
- X else {
- X separator = *s++;
- X for( p=s; *p != separator && *p != edelim; p++ );
- X
- X if( *p == edelim )
- X Warning("Syntax error in edit pattern, ignored");
- X else {
- X char *t1, *t2;
- X pat1 = _substr( s, p );
- X for(s=p=p+1; (*p != separator) && (*p != edelim); p++ );
- X pat2 = _substr( s, p );
- X t1 = Expand(pat1); FREE(pat1);
- X t2 = Expand(pat2); FREE(pat2);
- X result = Apply_edit( result, t1, t2, TRUE, FALSE );
- X FREE( t1 );
- X FREE( t2 );
- X }
- X s = p;
- X }
- X /* find the end of the macro spec, or the start of a new
- X * modifier list for further processing of the result */
- X
- X for( ; (*s != edelim) && (*s != ':'); s++ );
- X if( *s == ':' ) s++;
- X break;
- X
- X case 'T':
- X case 't':
- X if( modifier_list ) {
- X Warning( "Tokenize modifier must appear alone, ignored");
- X modifier_list = 0;
- X }
- X else {
- X char *msg = "Separator string must be quoted";
- X
- X separator = *s++;
- X
- X if( separator != '\"' )
- X Warning( msg );
- X else {
- X /* we change the semantics to allow $(v:t")") */
- X for (p = s; *p && *p != separator; p++)
- X if (*p == '\\')
- X if (p[1] == '\\' || p[1] == '"')
- X p++;
- X if( *p == 0 )
- X Fatal( "Unterminated separator string" );
- X else {
- X pat1 = _substr( s, p );
- X result = _tokenize( result, pat1 );
- X FREE( pat1 );
- X }
- X s = p;
- X }
- X
- X /* find the end of the macro spec, or the start of a new
- X * modifier list for further processing of the result */
- X
- X for( ; (*s != edelim) && (*s != ':'); s++ );
- X if( *s == ':' ) s++;
- X }
- X break;
- X
- X case ':':
- X if( modifier_list ) {
- X result = _apply_modifiers( modifier_list, result );
- X modifier_list = 0;
- X }
- X break;
- X
- X default:
- X Warning( "Illegal modifier in macro, ignored" );
- X break;
- X }
- X }
- X
- X if( modifier_list ) /* apply modifier */
- X result = _apply_modifiers( modifier_list, result );
- X
- X s++;
- X }
- X
- X *ps = s;
- X FREE( macro_name );
- X DB_RETURN( result );
- X}
- X
- X
- X
- Xstatic char*
- X_scan_brace( s, ps, flag )/*
- X============================
- X This routine scans for { token_list } pairs. It expands the value of
- X token_list by calling Expand on it. Token_list may be anything at all.
- X Note that the routine count's ballanced parentheses. This means you
- X cannot have something like { fred { joe }, if that is what you really
- X need the write it as { fred {{ joe }, flag is set to 1 if all ok
- X and to 0 if the braces were unballanced. */
- X
- Xchar *s;
- Xchar **ps;
- Xint *flag;
- X{
- X char *t;
- X char *start;
- X char *res;
- X int lev = 1;
- X int done = 0;
- X
- X DB_ENTER( "_scan_brace" );
- X
- X start = s;
- X while( !done )
- X switch( *s++ ) {
- X case '{':
- X if( *s == '{' ) break; /* ignore {{ */
- X lev++;
- X break;
- X
- X case '}':
- X if( *s == '}' ) break; /* ignore }} */
- X if( lev )
- X if( --lev == 0 ) done = TRUE;
- X break;
- X
- X case '$':
- X if( *s == '{' || *s == '}' ) {
- X if( (t = strchr(s,'}')) != NIL(char) )
- X s = t;
- X s++;
- X }
- X break;
- X
- X case '\0':
- X if( lev ) {
- X done = TRUE;
- X s--;
- X /* error malformed macro expansion */
- X }
- X break;
- X }
- X
- X start = _substr( start, (lev) ? s : s-1 );
- X
- X if( lev ) {
- X /* Braces were not ballanced so just return the string.
- X * Do not expand it. */
- X
- X res = _strjoin( "{", start, -1, FALSE );
- X *flag = 0;
- X }
- X else {
- X *flag = 1;
- X res = Expand( start );
- X
- X if( (t = _strspn( res, " \t" )) != res ) strcpy( res, t );
- X }
- X
- X FREE( start ); /* this is ok! start is assigned a _substr above */
- X *ps = s;
- X
- X DB_RETURN( res );
- X}
- X
- X
- X
- Xstatic char*
- X_cross_prod( x, y )/*
- X=====================
- X Given two strings x and y compute the cross-product of the tokens found
- X in each string. ie. if x = "a b" and y = "c d" return "ac ad bc bd".
- X
- X NOTE: buf will continue to grow until it is big enough to handle
- X all cross product requests. It is never freed! (maybe I
- X will fix this someday) */
- X
- Xchar *x;
- Xchar *y;
- X{
- X static char *buf;
- X static int buf_siz = 0;
- X char *brkx;
- X char *brky;
- X char *cy;
- X char *cx;
- X char *res;
- X int i;
- X
- X if( *x && *y ) {
- X res = _strdup( "" ); cx = x;
- X while( *cx ) {
- X cy = y;
- X brkx = _strpbrk( cx, " \t\n" );
- X if( (brkx-cx == 2) && *cx == '\"' && *(cx+1) == '\"' ) cx = brkx;
- X
- X while( *cy ) {
- X brky = _strpbrk( cy, " \t\n" );
- X if( (brky-cy == 2) && *cy == '\"' && *(cy+1) == '\"' ) cy = brky;
- X i = brkx-cx + brky-cy + 2;
- X
- X if( i > buf_siz ) { /* grow buf to the correct size */
- X if( buf != NIL(char) ) FREE( buf );
- X if( (buf = MALLOC( i, char )) == NIL(char)) No_ram();
- X buf_siz = i;
- X }
- X
- X strncpy( buf, cx, (i = brkx-cx) );
- X buf[i] = '\0';
- X if (brky-cy > 0) strncat( buf, cy, brky-cy );
- X strcat( buf, " " );
- X res = _strjoin( res, buf, -1, TRUE );
- X cy = _strspn( brky, " \t\n" );
- X }
- X cx = _strspn( brkx, " \t\n" );
- X }
- X
- X FREE( x );
- X res[ strlen(res)-1 ] = '\0';
- X }
- X else
- X res = _strjoin( x, y, -1, TRUE );
- X
- X FREE( y );
- X return( res );
- X}
- X
- X
- X
- Xstatic char*
- X_apply_modifiers( mod, src )/*
- X==============================
- X This routine applies the appropriate modifiers to the string src
- X and returns the proper result string */
- X
- Xint mod;
- Xchar *src;
- X{
- X char *s;
- X char *e;
- X TKSTR str;
- X
- X DB_ENTER( "_apply_modifiers" );
- X
- X if( mod == (SUFFIX_FLAG | DIRECTORY_FLAG | FILE_FLAG) )
- X DB_RETURN( src );
- X
- X SET_TOKEN( &str, src );
- X DB_PRINT( "mod", ("Source string [%s]", src) );
- X
- X while( *(s = Get_token( &str, "", FALSE )) != '\0' ) {
- X /* search for the directory portion of the filename. If the
- X * DIRECTORY_FLAG is set, then we want to keep the directory portion
- X * othewise throw it away and blank out to the end of the token */
- X
- X if( (e = basename(s)) != s)
- X if( !(mod & DIRECTORY_FLAG) ) {
- X strcpy(s, e);
- X e = s+(str.tk_str-e);
- X for(; e != str.tk_str; e++)
- X *e = ' ';
- X }
- X else
- X s = e;
- X
- X /* search for the suffix, if there is none, treat it as a NULL suffix.
- X * if no file name treat it as a NULL file name. same copy op as
- X * for directory case above */
- X
- X e = strrchr( s, '.' ); /* NULL suffix if e=0 */
- X if( e == NIL(char) ) e = s+strlen(s);
- X
- X if( !(mod & FILE_FLAG) ) {
- X strcpy( s, e );
- X e = s+(str.tk_str-e);
- X for( ; e != str.tk_str; e++ ) *e = ' ';
- X }
- X else
- X s = e;
- X
- X /* The last and final part. This is the suffix case, if we don't want
- X * it then just erase to the end of the token. */
- X
- X if( s != NIL(char) )
- X if( !(mod & SUFFIX_FLAG) )
- X for( ; s != str.tk_str; s++ ) *s = ' ';
- X }
- X
- X /* delete the extra white space, it looks ugly */
- X for( s = src, e = NIL(char); *s; s++ )
- X if( *s == ' ' || *s == '\t' || *s == '\n' ) {
- X if( e == NIL(char) )
- X e = s;
- X }
- X else {
- X if( e != NIL(char) ) {
- X if( e+1 < s ) {
- X strcpy( e+1, s );
- X s = e+1;
- X *e = ' ';
- X }
- X e = NIL(char);
- X }
- X }
- X
- X if( e != NIL(char) )
- X if( e < s )
- X strcpy( e, s );
- X
- X DB_PRINT( "mod", ("Result string [%s]", src) );
- X DB_RETURN( src );
- X}
- X
- X
- X
- Xstatic char*
- X_tokenize( src, separator )/*
- X=============================
- X Tokenize the input of src and join each token found together with
- X the next token separated by the separator string.
- X
- X When doing the tokenization, <sp>, <tab>, <nl>, and \<nl> all
- X constitute white space. */
- X
- Xchar *src;
- Xchar *separator;
- X{
- X TKSTR tokens;
- X char *tok;
- X char *res;
- X int first = TRUE;
- X
- X DB_ENTER( "_tokenize" );
- X
- X SET_TOKEN( &tokens, src );
- X
- X
- X /* map the escape codes in the separator string first */
- X
- X for(tok=separator; (tok = strchr(tok,CONTINUATION_CHAR)) != NIL(char); tok++)
- X Map_esc( tok );
- X
- X DB_PRINT( "exp", ("Separator [%s]", separator) );
- X
- X /* Build the token list */
- X res = _strdup( "" );
- X while( *(tok = Get_token( &tokens, "", FALSE )) != '\0' ) {
- X DB_PRINT( "exp", ("Tokenizing [%s]", tok) );
- X
- X if( first ) {
- X FREE( res );
- X res = _strdup( tok );
- X first = FALSE;
- X }
- X else {
- X char *x;
- X res = _strjoin(res, x =_strjoin(separator, tok, -1, FALSE), -1, TRUE);
- X FREE( x );
- X }
- X }
- X
- X FREE( src );
- X DB_RETURN( res );
- X}
- SHAR_EOF
- echo "File expand.c is complete"
- chmod 0440 expand.c || echo "restore of expand.c fails"
- echo "x - extracting dump.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > dump.c &&
- X/* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/dump.c,v 1.1 90/07/21 11:06:32 dvadura Exp $
- X-- SYNOPSIS -- dump the internal dag to stdout.
- X--
- X-- DESCRIPTION
- X-- This file contains the routine that is called to dump a version of
- X-- the digested makefile to the standard output. May be useful perhaps
- X-- to the ordinary user, and invaluable for debugging make.
- X--
- X-- AUTHOR
- X-- Dennis Vadura, dvadura@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: dump.c,v $
- X * Revision 1.1 90/07/21 11:06:32 dvadura
- X * Initial Revision Version 3.5
- X *
- X*/
- X
- X#include "db.h"
- X#include "extern.h"
- X
- X#define M_TEST (M_PRECIOUS | M_VAR_MASK)
- X
- Xstatic void dump_normal_target ANSI((CELLPTR, HOWPTR, CELLPTR));
- Xstatic void dump_graph_node ANSI((CELLPTR));
- Xstatic void dump_name ANSI((HASHPTR, int));
- X
- X
- Xvoid
- XDump()/*
- X======== Dump onto standard output the digested makefile. Note that
- X the form of the dump is not representative of the contents
- X of the original makefile contents at all */
- X{
- X HASHPTR hp;
- X int i;
- X
- X DB_ENTER( "Dump" );
- X
- X puts( "# Dump of dmake macro variables:" );
- X for( i=0; i<HASH_TABLE_SIZE; i++)
- X for( hp=Macs[i]; hp != NIL(HASH); hp = hp->ht_next ) {
- X int flag = hp->ht_flag;
- X
- X printf( "%s ", hp->ht_name );
- X if( flag & M_EXPANDED ) putchar( ':' );
- X printf( "= " );
- X if( hp->ht_value != NIL(char) ) printf( hp->ht_value );
- X if( flag & M_PRECIOUS )
- X printf( "\t # PRECIOUS " );
- X putchar( '\n' );
- X }
- X
- X puts( "\n#====================================" );
- X puts( "# Dump of targets:\n" );
- X
- X for( i=0; i<HASH_TABLE_SIZE; i++ )
- X for( hp = Defs[i]; hp != NIL(HASH); hp = hp->ht_next )
- X if( !(hp->CP_OWNR->ce_flag & F_PERCENT) ) {
- X if( hp->CP_OWNR == Fringe_hd->cl_prq )
- X puts( "# ******* FIRST TARGET ********" );
- X dump_normal_target( hp->CP_OWNR, hp->CP_OWNR->CE_HOW, NIL(CELL) );
- X }
- X
- X puts( "\n#====================================" );
- X puts( "# Dump of inference graph\n" );
- X
- X for( i=0; i<HASH_TABLE_SIZE; i++ )
- X for( hp = Defs[i]; hp != NIL(HASH); hp = hp->ht_next )
- X if( (hp->CP_OWNR->ce_flag & F_PERCENT) &&
- X !(hp->CP_OWNR->ce_flag & F_MAGIC) )
- X dump_graph_node( hp->CP_OWNR );
- X
- X DB_VOID_RETURN;
- X}
- X
- X
- X
- Xvoid
- XDump_recipe( sp )/*
- X===================
- X Given a string pointer print the recipe line out */
- XSTRINGPTR sp;
- X{
- X char *st;
- X char *nl;
- X
- X if( sp == NIL(STRING) ) return;
- X
- X putchar( '\t' );
- X if( sp->st_attr & A_SILENT ) putchar( '@' );
- X if( sp->st_attr & A_IGNORE ) putchar( '-' );
- X
- X st = sp->st_string;
- X for( nl=strchr(st,'\n'); nl != NIL( char); nl=strchr(st,'\n') ) {
- X *nl = '\0';
- X printf( "%s\\\n", st );
- X *nl = '\n';
- X st = nl+1;
- X }
- X printf( "%s\n", st );
- X}
- X
- X
- Xstatic char *_attrs[] = { ".PRECIOUS ", ".SILENT ", ".LIBRARY ",
- X ".EPILOG ", ".PROLOG ", ".IGNORE ", ".SYMBOL ", ".NOINFER ",
- X ".UPDATEALL ", ".SEQUENTIAL " };
- X
- Xstatic void
- Xdump_normal_target( cp, hw, prq )/*
- X===================================
- X Dump in makefile like format the dag information */
- XCELLPTR cp;
- XHOWPTR hw;
- XCELLPTR prq;
- X{
- X register LINKPTR lp;
- X register STRINGPTR sp;
- X unsigned int attr, k;
- X
- X DB_ENTER( "dump_normal_target" );
- X
- X if( hw == NIL(HOW) ) { DB_VOID_RETURN; }
- X if( hw->hw_next != NIL(HOW) ) dump_normal_target( cp, hw->hw_next, prq );
- X
- X dump_name( cp->ce_name, FALSE );
- X
- X for( k=0, attr=1; attr < MAX_ATTR; attr <<= 1, k++ )
- X if( cp->ce_attr & attr )
- X printf( _attrs[k] );
- X
- X if( cp->ce_attr & A_SETDIR )
- X printf( ".SETDIR=%s ", cp->ce_dir ? cp->ce_dir : "" );
- X
- X putchar( ':' );
- X
- X if( cp->ce_flag & F_MULTI ) putchar( ':' );
- X if( hw->hw_flag & F_SINGLE ) putchar( '!' );
- X putchar( ' ' );
- X
- X if( prq != NIL(CELL) ) dump_name( prq->ce_name, FALSE );
- X for( lp = hw->hw_prq; lp != NIL(LINK); lp = lp->cl_next )
- X dump_name( lp->cl_prq->ce_name, FALSE );
- X
- X if( (lp = hw->hw_indprq) != NIL(LINK) ) {
- X for( ; lp != NIL(LINK); lp = lp->cl_next )
- X dump_name( lp->cl_prq->ce_name, TRUE );
- X }
- X
- X putchar( '\n' );
- X if( hw->hw_flag & F_GROUP ) {
- X if( hw->hw_attr & A_IGNORE ) putchar( '-' );
- X if( hw->hw_attr & A_SILENT ) putchar( '@' );
- X puts( "[" );
- X }
- X
- X for( sp = hw->hw_recipe; sp != NIL(STRING); sp = sp->st_next )
- X Dump_recipe( sp );
- X if( hw->hw_flag & F_GROUP ) puts( "]" );
- X
- X putchar( '\n' );
- X DB_VOID_RETURN;
- X}
- X
- X
- Xstatic void
- Xdump_name( hp, quote )/*
- X========================
- X print out a name */
- XHASHPTR hp;
- Xint quote;
- X{
- X if( quote ) putchar('\'');
- X printf( "%s", hp->ht_name );
- X if( quote ) putchar('\'');
- X putchar(' ');
- X}
- X
- X
- X
- Xstatic void
- Xdump_graph_node( cp )/*
- X=======================*/
- XCELLPTR cp;
- X{
- X EDGEPTR pe;
- X
- X pe = cp->CE_EDGES;
- X
- X if( pe != NIL(EDGE) )
- X do {
- X dump_normal_target( cp, pe->ed_how, pe->ed_prq );
- X pe = pe->ed_next;
- X }
- X while( pe != cp->CE_EDGES );
- X}
- SHAR_EOF
- chmod 0440 dump.c || echo "restore of dump.c fails"
- echo "x - extracting dmake.h (Text)"
- sed 's/^X//' << 'SHAR_EOF' > dmake.h &&
- X/* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/dmake.h,v 1.1 90/07/19 13:55:27 dvadura Exp $
- X-- SYNOPSIS -- global defines for dmake.
- X--
- X-- DESCRIPTION
- X-- All the interesting bits and flags that dmake uses are defined here.
- X--
- X-- AUTHOR
- X-- Dennis Vadura, dvadura@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: dmake.h,v $
- X * Revision 1.1 90/07/19 13:55:27 dvadura
- X * Initial Revision of Version 3.5
- X *
- X*/
- X
- X#ifndef _DMAKE_INCLUDED_
- X#define _DMAKE_INCLUDED_
- X
- X#define MAX_INC_DEPTH 10 /* max of ten nested include files */
- X#define MAX_COND_DEPTH 20 /* max nesting level of conditionals */
- X#define ERROR_EXIT_VALUE 255 /* return code of aborted make */
- X#define CONTINUATION_CHAR '\\' /* line continuation \<nl> */
- X#define ESCAPE_CHAR '\\' /* escape char for used chars */
- X#define COMMENT_CHAR '#' /* start of comment chars */
- X#define TGT_DEP_SEP ':' /* separator for targets and dependents */
- X#define CONDSTART '.' /* start of conditional token eg .IF */
- X#define DEF_MAKE_PNAME "dmake"/* default name to use as name of make */
- X
- X
- X/* ............... Hashing function constants ......................... */
- X#define HASH_TABLE_SIZE 200 /* See hash.c for description */
- X
- X
- X/* Bit flags for cells and macro definitions. */
- X#define M_DEFAULT 0x0000 /* default flag value */
- X#define M_MARK 0x0001 /* mark for circularity checks */
- X#define M_PRECIOUS 0x0002 /* keep macro, same as A_PRE... */
- X#define M_MULTI 0x0004 /* multiple redefinitions ok! */
- X#define M_EXPANDED 0x0008 /* macro has been assigned */
- X#define M_USED 0x0010 /* macro has been expanded */
- X#define M_LITERAL 0x0020 /* don't strip w/s on macro def */
- X#define M_NOEXPORT 0x0040 /* don't export macro for -x */
- X#define M_FORCE 0x0080 /* Force a macro redefinition */
- X#define M_VAR_BIT 0x1000 /* macro bit variable */
- X#define M_VAR_CHAR 0x2000 /* macro char variable */
- X#define M_VAR_STRING 0x4000 /* macro string variable */
- X#define M_VAR_INT 0x8000 /* macro integer variable */
- X
- X#define M_VAR_MASK 0xf000 /* macro variable mask */
- X
- X
- X
- X/* Global and target attribute flag definitions.
- X * If you change the values of these or re-order them make appropriate changes
- X * in dump.c so that the output of dmake -p matches the attribute info for a
- X * target. */
- X
- X#define A_DEFAULT 0x0000 /* default flag value */
- X#define A_PRECIOUS 0x0001 /* object is precious */
- X#define A_SILENT 0x0002 /* don't echo commands */
- X#define A_LIBRARY 0x0004 /* target is an archive */
- X#define A_EPILOG 0x0008 /* insert shell epilog code */
- X#define A_PROLOG 0x0010 /* insert shell prolog code */
- X#define A_IGNORE 0x0020 /* ignore errors */
- X#define A_SYMBOL 0x0040 /* lib member is a symbol */
- X#define A_NOINFER 0x0080 /* no trans closure from cell */
- X#define A_UPDATEALL 0x0100 /* all targets of rule modified */
- X#define A_SEQ 0x0200 /* sequential make attribute */
- X#define A_SETDIR 0x0400 /* cd to dir when making target */
- X#define MAX_ATTR A_SETDIR /* highest valid attribute */
- X#define A_LIBRARYM 0x0800 /* target is an archive member */
- X#define A_FRINGE 0x1000 /* cell is on the fringe */
- X#define A_COMPOSITE 0x2000 /* member of lib(targ) name */
- X#define A_FFNAME 0x4000 /* if set, free ce_fname in stat*/
- X#define A_UPDATED 0x8000 /* Used to mark cell as updated */
- X
- X
- X/* Global and target bit flag definitions */
- X
- X#define F_DEFAULT 0x0000 /* default flag value */
- X#define F_MARK 0x0001 /* circularity check mark */
- X#define F_MULTI 0x0002 /* multiple rules for target */
- X#define F_SINGLE 0x0004 /* exec rules one/prerequisite */
- X#define F_TARGET 0x0008 /* marks a target */
- X#define F_RULES 0x0010 /* indicates target has rules */
- X#define F_GROUP 0x0020 /* indicates that rules are to */
- X /* fed to the shell as a group */
- X
- X#define F_TRANS 0x0040 /* same as F_STAT not used tgthr*/
- X#define F_STAT 0x0040 /* target already stated */
- X#define F_VISITED 0x0080 /* target scheduled for make */
- X#define F_USED 0x0080 /* used in releparse.c */
- X#define F_SPECIAL 0x0100 /* marks a special target */
- X#define F_DFA 0x0200 /* bit for marking added DFA */
- X#define F_EXPLICIT 0x0400 /* explicit target in makefile */
- X#define F_PERCENT 0x0800 /* marks a target as a % rule */
- X#define F_REMOVE 0x1000 /* marks an intermediate target */
- X#define F_MAGIC 0x2000 /* marks a magic target */
- X#define F_INFER 0x4000 /* target is result of inference*/
- X#define F_MADE 0x8000 /* target is manufactured */
- X
- X
- X/* Definitions for the Parser states */
- X#define NORMAL_SCAN 0 /* normal processing state */
- X#define RULE_SCAN 1 /* scan of rule text */
- X
- X/* definitions for macro operator types */
- X#define M_OP_EQ 1 /* macro operation is '=' */
- X#define M_OP_CL 2 /* macro operation is ':=' */
- X#define M_OP_PL 4 /* macro operation is '+=' */
- X#define M_OP_PLCL 8 /* macro operation is '+:='*/
- X
- X/* definitions for rule operator types */
- X#define R_OP_CL 1 /* rule operation is ':' */
- X#define R_OP_DCL 2 /* rule operation is '::' */
- X#define R_OP_BG 4 /* rule operation is ':!' */
- X#define R_OP_UP 8 /* rule operation is ':^' */
- X#define R_OP_MI 16 /* rule operation is ':-' */
- X
- X
- X/* special target definitions for use inside dmake */
- X#define ST_IF 1
- X#define ST_ELSE 2
- X#define ST_END 3
- X#define ST_REST 4 /* remaining special targets */
- X#define ST_INCLUDE 5
- X#define ST_SOURCE 7
- X#define ST_EXPORT 8
- X#define ST_IMPORT 9
- X
- X/* Macro definitions for use inside dmake */
- X#define SET_TOKEN(A, B) (A)->tk_str = (B); (A)->tk_cchar = *(B);\
- X (A)->tk_quote = 1;
- X#define CLEAR_TOKEN(A) *(A)->tk_str = (A)->tk_cchar
- X#define GET_MACRO(A) Get_name(A, Macs, FALSE, NIL(CELL))
- X#define iswhite(C) ((C == ' ') || (C == '\t'))
- X
- X#endif
- X
- SHAR_EOF
- chmod 0440 dmake.h || echo "restore of dmake.h fails"
- echo "x - extracting dmake.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > dmake.c &&
- X/* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/dmake.c,v 1.1 90/07/19 13:53:05 dvadura Exp $
- X-- SYNOPSIS -- The main program.
- X--
- X-- DESCRIPTION
- X--
- X-- dmake [-#dbug_string] [ options ]
- X-- [ macro definitions ] [ target ... ]
- X--
- X-- This file contains the main command line parser for the
- X-- make utility. The valid flags recognized are as follows:
- X--
- X-- -f file - use file as the makefile
- X-- -#dbug_string - dump out debugging info, see below
- X--
- X-- options: (can be catenated, ie -irn == -i -r -n)
- X--
- X-- -A - enable AUGMAKE special target mapping
- X-- -i - ignore errors
- X-- -n - trace and print, do not execute commands
- X-- -t - touch, update dates without executing commands
- X-- -T - do not apply transitive closure
- X-- -r - don't use internal rules
- X-- -s - do your work silently
- X-- -S - force Sequential make, overrides -P
- X-- -q - check if target is up to date. Does not
- X-- do anything. Returns 0 if up to date, -1
- X-- otherwise.
- X-- -p - print out a version of the makefile
- X-- -P# - set value of MAXPROCESS
- X-- -e - define environment strings as macros
- X-- -E - as -e but done after parsing makefile
- X-- -u - force unconditional update of target
- X-- -k - make all independent targets even if errors
- X-- -V - print out this make version number
- X-- -v - verbose, print what we are doing, as we do it.
- X-- -M - Microsoft make compatibility, (* disabled *)
- X-- -h - print out usage info
- X-- -x - export macro defs to environment
- X--
- X-- NOTE: - #ddbug_string is only availabe for versions of dmake that
- X-- have been compiled with -DDBUG switch on. Not the case for
- X-- distributed versions. Any such versions must be linked
- X-- together with a version of Fred Fish's debug code.
- X--
- X-- NOTE: - in order to compile the code the include file stddef.h
- X-- must be shipped with the bundled code.
- X--
- X-- AUTHOR
- X-- Dennis Vadura, dvadura@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: dmake.c,v $
- X * Revision 1.1 90/07/19 13:53:05 dvadura
- X * Initial Revision of Version 3.5
- X *
- X*/
- X
- X/* Set this flag to one, and the global variables in vextern.h will not
- X * be defined as 'extern', instead they will be defined as global vars
- X * when this module is compiled. */
- X#define _DEFINE_GLOBALS_ 1
- X
- X#include <ctype.h>
- X#include <stdarg.h>
- X#include "extern.h"
- X#include "alloc.h"
- X#include "db.h"
- X#include "patchlvl.h"
- X#include "version.h"
- X
- X#ifdef HELP
- X#define USAGE \
- X"Usage: %s [-AeEhiknpqrsStTuvVx] [-P#] [-f file] [macro=value ...] [target ...]\n"
- X#define COPYRIGHT "Copyright (c) 1990 by Dennis Vadura"
- X#endif
- X
- Xstatic char *sccid = COPYRIGHT;
- Xstatic char _warn = TRUE; /* warnings on by default */
- X
- Xstatic void _do_VPATH();
- Xstatic void _do_ReadEnvironment();
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar **argv;
- X{
- X char* fil_name = NIL(char);
- X char* cmdmacs;
- X FILE* mkfil;
- X int ex_val;
- X int m_export;
- X HASHPTR hp;
- X
- X DB_ENTER("main");
- X
- X /* Initialize Global variables to their default values */
- X Prolog(argc, argv);
- X Create_macro_vars();
- X Catch_signals(Quit);
- X
- X Def_macro( "MAKECMD", Pname, M_PRECIOUS|M_NOEXPORT );
- X Pname = basename(Pname);
- X
- X DB_PROCESS(Pname);
- X (void) setvbuf(stdout, NULL, _IOLBF, BUFSIZ); /* stdout line buffered */
- X
- X Continue = FALSE;
- X Get_env = FALSE;
- X Force = FALSE;
- X Target = FALSE;
- X If_expand = FALSE;
- X Listing = FALSE;
- X Readenv = FALSE;
- X Rules = TRUE;
- X Trace = FALSE;
- X Touch = FALSE;
- X Check = FALSE;
- X Microsoft = FALSE;
- X Verbose = FALSE;
- X Makemkf = FALSE;
- X m_export = FALSE;
- X cmdmacs = NIL(char);
- X
- X Transitive = TRUE;
- X Nest_level = 0;
- X Line_number = 0;
- X
- X while( --argc > 0 ) {
- X register char *p;
- X char *q;
- X
- X if( *(p = *++argv) == '-' ) {
- X if( p[1] == '\0' ) Fatal("Missing option letter");
- X
- X /* copy options to Buffer for $(MFLAGS), strip 'f' */
- X q = strchr(Buffer, 0);
- X while (*p != 0)
- X if( (*q++ = *p++) == 'f' ) q--;
- X
- X if( *(q-1) == '-' )
- X q--;
- X else
- X *q++ = ' ';
- X
- X *q = 0;
- X
- X for( p = *argv+1; *p; p++) switch (*p) {
- X case 'f':
- X if( fil_name == NIL(char) ) {
- X if( *++argv != NIL(char) ) {
- X fil_name = *argv;
- X argc--;
- X } else
- X Fatal("No file name for -f");
- X } else
- X Fatal("Only one `-f file' allowed");
- X break;
- X
- X case 'k': Continue = TRUE; break;
- X case 'p': Listing = TRUE; break;
- X case 'r': Rules = FALSE; break;
- X case 'n': Trace = TRUE; break;
- X case 't': Touch = TRUE; break;
- X case 'q': Check = TRUE; break;
- X case 'u': Force = TRUE; break;
- X case 'v': Verbose = TRUE; break;
- X case 'x': m_export = TRUE; break;
- X case 'T': Transitive = FALSE; break;
- X case 'e': Get_env = 'e'; break;
- X case 'E': Get_env = 'E'; break;
- X
- X case 'V': Version(); Quit(NIL(CELL)); break;
- X case 'A': Def_macro("AUGMAKE", "y", M_EXPANDED); break;
- X case 'i': Def_macro(".IGNORE", "y", M_EXPANDED); break;
- X case 's': Def_macro(".SILENT", "y", M_EXPANDED); break;
- X case 'S': Def_macro(".SEQUENTIAL", "y", M_EXPANDED); break;
- X
- X case 'P':
- X if( p[1] ) {
- X Def_macro( "MAXPROCESS", p+1, M_MULTI|M_EXPANDED );
- X p += strlen(p)-1;
- X }
- X else
- X Fatal( "Missing number for -P flag" );
- X break;
- X
- X#if 0 /*** disabled */
- X case 'M': Microsoft = TRUE; break;
- X#endif
- X#ifdef HELP
- X case 'h': Usage(); Quit(NIL(CELL)); break;
- X#endif
- X#ifdef DBUG
- X case '#':
- X DB_PUSH(p+1);
- X p += strlen(p)-1;
- X break;
- X#endif
- X
- X default:
- X fprintf(stderr, USAGE, Pname);
- X Quit(NIL(CELL));
- X break;
- X }
- X }
- X else if( (q = strchr(p, '=')) != NIL(char) ) {
- X cmdmacs = _stradd( cmdmacs, _strdup(p), FALSE );
- X Parse_macro( p, M_PRECIOUS );
- X }
- X else {
- X register CELLPTR cp;
- X Add_fringe(cp = Def_cell(p, NIL(CELL)));
- X cp->ce_flag |= F_TARGET;
- X Target = TRUE;
- X }
- X }
- X
- X Def_macro( "MAKEMACROS", cmdmacs, M_PRECIOUS|M_NOEXPORT );
- X if( cmdmacs != NIL(char) ) FREE(cmdmacs);
- X
- X Def_macro( "MFLAGS", Buffer, M_PRECIOUS|M_NOEXPORT );
- X Def_macro( "%", "$@", M_PRECIOUS|M_NOEXPORT );
- X
- X if( *Buffer ) Def_macro( "MAKEFLAGS", Buffer+1, M_PRECIOUS|M_NOEXPORT );
- X
- X _warn = FALSE; /* disable warnings for builtin rules */
- SHAR_EOF
- echo "End of part 17"
- echo "File dmake.c is continued in part 18"
- echo "18" > s2_seq_.tmp
- exit 0
-
-