office-gobmx/dmake/dmdump.c
Oliver Bolte 8de2d7bf21 INTEGRATION: CWS dmake48 (1.3.16); FILE MERGED
2007/03/17 19:00:37 vq 1.3.16.1: #i73499# Add new .WINPATH attribute to generate Windows style paths
(with regular slashes) instead of the default cygwin style (POSIX)
paths for dmake's dynamic macros.

This attribute is specific for cygwin dmake executables and non-cygwin
environments ignore this attribute.

The windows style paths use regular slashes ('/') instead of the
usual windows backslash ('\') as directory separator to avoid quoting
problems (It still is a cygwin dmake!) and cygwin as well as native
windows programs should have no problems using this (c:/foo/bar) path
representation.

The affected macros are $@, $*, $>, $?, $<, $&, $^ and $(PWD),
$(MAKEDIR) and $(TMD).

Examples:

Content of $(PWD) without .WINPATH (default):  /cygdrive/c/temp

Content of $(PWD) with .WINPATH set:           c:/temp
2007-06-12 05:05:11 +00:00

287 lines
7.4 KiB
C

/* RCS $Id: dmdump.c,v 1.4 2007-06-12 06:05:11 obo Exp $
--
-- SYNOPSIS
-- Dump the internal dag to stdout.
--
-- DESCRIPTION
-- This file contains the routine that is called to dump a version of
-- the digested makefile to the standard output. May be useful perhaps
-- to the ordinary user, and invaluable for debugging make.
--
-- AUTHOR
-- Dennis Vadura, dvadura@dmake.wticorp.com
--
-- WWW
-- http://dmake.wticorp.com/
--
-- COPYRIGHT
-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved.
--
-- This program is NOT free software; you can redistribute it and/or
-- modify it under the terms of the Software License Agreement Provided
-- in the file <distribution-root>/readme/license.txt.
--
-- LOG
-- Use cvs log to obtain detailed change logs.
*/
#include "extern.h"
#define M_TEST (M_PRECIOUS | M_VAR_MASK)
static void dump_name ANSI((CELLPTR, int, int));
static void dump_normal_target ANSI((CELLPTR, CELLPTR, int));
static void dump_prerequisites ANSI((LINKPTR, CELLPTR, int, int, int));
static void dump_conditionals ANSI((CELLPTR,STRINGPTR,int,int));
static void dump_macro ANSI((HASHPTR, int));
PUBLIC void
Dump()/*
======== Dump onto standard output the digested makefile. Note that
the form of the dump is not representative of the contents
of the original makefile contents at all */
{
HASHPTR hp;
int i;
DB_ENTER( "Dump" );
puts( "# Dump of dmake macro variables:" );
for( i=0; i<HASH_TABLE_SIZE; i++)
for( hp=Macs[i]; hp != NIL(HASH); hp = hp->ht_next ) {
int flag = hp->ht_flag;
dump_macro(hp, flag);
}
puts( "\n#====================================" );
puts( "# Dump of targets:\n" );
for( i=0; i<HASH_TABLE_SIZE; i++ )
for( hp = Defs[i]; hp != NIL(HASH); hp = hp->ht_next )
if( !(hp->CP_OWNR->ce_flag & F_PERCENT) ) {
if( hp->CP_OWNR == Root )
puts( "# ******* ROOT TARGET ********" );
if (Targets->ce_prq && hp->CP_OWNR == Targets->ce_prq->cl_prq)
puts( "# ******* FIRST USER DEFINED TARGET ******" );
dump_normal_target( hp->CP_OWNR,NIL(CELL),hp->CP_OWNR->ce_flag);
}
puts( "\n#====================================" );
puts( "# Dump of inference graph\n" );
for( i=0; i<HASH_TABLE_SIZE; i++ )
for( hp = Defs[i]; hp != NIL(HASH); hp = hp->ht_next )
if( (hp->CP_OWNR->ce_flag & F_PERCENT) &&
!(hp->CP_OWNR->ce_flag & F_MAGIC) )
dump_normal_target(hp->CP_OWNR,NIL(CELL),hp->CP_OWNR->ce_flag);
DB_VOID_RETURN;
}
PUBLIC void
Dump_recipe( sp )/*
===================
Given a string pointer print the recipe line out */
STRINGPTR sp;
{
char *st;
char *nl;
if( sp == NIL(STRING) ) return;
putchar( '\t' );
if( sp->st_attr & A_SILENT ) putchar( '@' );
if( sp->st_attr & A_IGNORE ) putchar( '-' );
if( sp->st_attr & A_SHELL ) putchar( '+' );
if( sp->st_attr & A_SWAP ) putchar( '%' );
st = sp->st_string;
for( nl=strchr(st,'\n'); nl != NIL( char); nl=strchr(st,'\n') ) {
*nl = '\0';
printf( "%s\\\n", st );
*nl = '\n';
st = nl+1;
}
printf( "%s\n", st );
}
static char *_attrs[] = { ".PRECIOUS", ".SILENT", ".LIBRARY",
".EPILOG", ".PROLOG", ".IGNORE", ".SYMBOL", ".NOINFER",
".UPDATEALL", ".SEQUENTIAL", ".SETDIR=", ".USESHELL",
#if defined(MSDOS)
".SWAP",
#else
# if defined(__CYGWIN__)
".WINPATH",
# else
"- unused -",
# endif
#endif
".MKSARGS",
".PHONY", ".NOSTATE", ".IGNOREGROUP", ".EXECUTE", ".ERRREMOVE" };
static void
dump_normal_target( cp, namecp, flag )/*
========================================
Dump in makefile like format the dag information */
CELLPTR cp;
CELLPTR namecp;
int flag;
{
register STRINGPTR sp;
t_attr attr;
unsigned int k;
DB_ENTER( "dump_normal_target" );
if(!(cp->ce_flag & F_TARGET) && !cp->ce_attr && !cp->ce_prq) {
DB_VOID_RETURN;
}
if(cp->ce_set && cp->ce_set != cp) {
DB_VOID_RETURN;
}
if( cp->ce_flag & F_MULTI ) {
/* recursively print multi or %-targets. */
int tflag = cp->ce_prq->cl_prq->ce_flag;
if( !(cp->ce_flag & F_PERCENT) ) tflag |= F_MULTI;
dump_conditionals(cp, cp->ce_cond, TRUE, TRUE);
putchar('\n');
#ifdef DBUG
/* Output also master targtet. (Only in debug builds) */
printf("Master name(s) (DBUG build): ");
dump_name(cp, FALSE, TRUE );
putchar('\n');
#endif
/* %-targets set namecp (3rd parameter) to NULL so that the next
* recursive dump_normal_target() prints the name of cp->ce_prq->cl_prq
* instead of cp. This should be the same unless CeMeToo(cp) points
* to a cell that is the head of an .UPDATEALL list. */
dump_prerequisites(cp->ce_prq,(cp->ce_flag&F_PERCENT)?NIL(CELL):cp,
FALSE, TRUE, tflag);
}
else {
dump_name(namecp?namecp:cp, FALSE, TRUE );
for( k=0, attr=1; attr <= MAX_ATTR; attr <<= 1, k++ )
if( cp->ce_attr & attr ) {
printf( "%s%s ", _attrs[k],
(attr != A_SETDIR) ? "" : (cp->ce_dir?cp->ce_dir:"") );
}
putchar( ':' );
if( flag & F_MULTI ) putchar( ':' );
if( flag & F_SINGLE ) putchar( '!' );
putchar( ' ' );
dump_prerequisites( cp->ce_prq, NIL(CELL), FALSE, FALSE, F_DEFAULT);
dump_prerequisites( cp->ce_indprq, NIL(CELL),TRUE, FALSE, F_DEFAULT);
putchar( '\n' );
if( cp->ce_flag & F_GROUP ) puts( "[" );
for( sp = cp->ce_recipe; sp != NIL(STRING); sp = sp->st_next )
Dump_recipe( sp );
if( cp->ce_flag & F_GROUP ) {
puts( "]" );
putchar( '\n' );
}
dump_conditionals(cp, cp->ce_cond, flag&F_MULTI, FALSE);
putchar('\n');
}
DB_VOID_RETURN;
}
static void
dump_conditionals( cp, sp, multi, global )
CELLPTR cp;
STRINGPTR sp;
int multi;
int global;
{
if (sp) {
dump_name(cp, FALSE, TRUE);
printf(".%sCONDITIONALS %s\n", global?"GLOBAL":"",multi?"::":":");
while(sp) {
printf("\t%s\n",sp->st_string);
sp=sp->st_next;
}
}
}
static void
dump_macro(hp, flag)
HASHPTR hp;
int flag;
{
printf( "%s ", hp->ht_name );
if(flag & M_EXPANDED)
putchar( ':' );
printf( "= " );
if(hp->ht_value != NIL(char))
printf( "%s",hp->ht_value );
if(flag & M_PRECIOUS)
printf( "\t # PRECIOUS " );
putchar( '\n' );
}
static void
dump_prerequisites( lp, namecp, quote, recurse, flag )/*
========================================================
Dump as prerequisites if recurse is FALSE or as targets
if recurse is TRUE. (For F_MULTI/F_PERCENT targets.) */
LINKPTR lp;
CELLPTR namecp;
int quote;
int recurse;
int flag;
{
for( ; lp; lp=lp->cl_next )
if( recurse )
dump_normal_target(lp->cl_prq, namecp, flag);
else if( lp->cl_prq )
dump_name(lp->cl_prq, quote, FALSE);
}
static void
dump_name( cp, quote, all )/*
=============================
Prints out the first or all (if all is TRUE) names of an lcell list.
If quote is true enclose in ' quotes, if quote
is FALSE and the name includes a space enclose in " quotes. */
CELLPTR cp;
int quote;
int all;
{
LINKPTR lp;
char qc = '\'';
for(lp=CeMeToo(cp);lp;lp=lp->cl_next) {
if( !quote && strchr(lp->cl_prq->CE_NAME,' ') != NIL(char)) {
quote = TRUE;
qc = '"';
}
if (quote) putchar(qc);
printf( "%s", lp->cl_prq->CE_NAME );
if (quote) putchar(qc);
putchar(' ');
if (!all) break;
}
}