1 message in com.perforce.jammingInclude lists of files
FromSent OnAttachments
Step...@alum.mit.edu17 Jul 1998 04:13 
Subject:Include lists of files
From:Step...@alum.mit.edu (Step@alum.mit.edu)
Date:07/17/1998 04:13:28 AM
List:com.perforce.jamming

I coded up the change I needed to support including a straight file list, and am posting it here in case anyone else might find it useful.

The syntax is:

include filename!MacroName ;

This includes the file at path filename, and defines a new macro MacroName whose value is all the strings in the file. I don't have a copy of yacc handy, so instead of changing the grammar I just hacked in the change in scan.c. I realize bang is a legal file character for jam (and many file systems) so this is probably not the best way to do this.

Stephen Ng

<underline><color><param>FF00,0000,FF00</param><FontFamily><param>Fixedsys</param><smaller>@@
-9,11 +9,11 @@

</underline></color> # include "parse.h"

# include "scan.h"

# include "jamgram.h"

# include "jambase.h"

# include "newstr.h"

<color><param>FF00,0000,0000</param><<

<color><param>0000,0000,FF00</param>-> # include "string.h"

</color> /*

* scan.c - the jam yacc scanner

*

* 12/26/93 (seiwald) - bump buf in yylex to 10240 - yuk.

* 09/16/94 (seiwald) - check for overflows, unmatched {}'s, etc.

<underline><color><param>FF00,0000,FF00</param>@@ -42,10 +42,12 @@

</underline></color> char *string; /* pointer into current line */

char **strings; /* for yyfparse() -- text to parse */

FILE *file; /* for yyfparse() -- file being read */

char *fname; /* for yyfparse() -- file name */

int line; /* line counter for error messages */

<color><param>0000,0000,FF00</param>-> char *macro; /* macro name if scanning
macro text file, null otherwise */

- -> int macrostate;

</color> char buf[ 512 ]; /* for yyfparse() -- line buffer */

} ;

static struct include *incp = 0; /* current file; head of chain */

<underline><color><param>FF00,0000,FF00</param>@@ -96,10 +98,12 @@

</underline></color> i->strings = 0;

i->file = 0;

i->fname = copystr( s );

i->line = 0;

i->next = incp;

<color><param>0000,0000,FF00</param>-> i->macro = NULL;

- -> i->macrostate = 0;

</color> incp = i;

/* If the filename is "+", it means use the internal jambase. */

if( !strcmp( s, "+" ) )

<underline><color><param>FF00,0000,FF00</param>@@ -145,27 +149,59 @@

</underline></color>

/* If necessary, open the file */

if( !i->file )

{

<color><param>0000,0000,FF00</param>-> char *macro;

</color> FILE *f = stdin;

<color><param>0000,0000,FF00</param>-> macro = strchr( i->fname, '!' );

- -> if( macro )

- -> {

- -> char fname[512];

- -> i->macro = malloc(strlen(macro) + 4 /* 1 for null and 3 for ' =\n' */);

- -> strcpy(i->macro, macro+1);

- -> strcat(i->macro, " =\n");

- -> i->macrostate = 1;

- -> strncpy(fname, i->fname, macro - i->fname);

- -> fname[macro - i->fname] = '\0';

- -> if( !( f = fopen( fname, "r" ) ) )

- -> perror( i->fname );

- -> }

- -> else

- -> if( strcmp( i->fname, "-" ) && !( f = fopen( i->fname, "r" ) ) )

- -> perror( i->fname );

</color>

<color><param>FF00,0000,0000</param><< if( strcmp( i->fname, "-" ) && !( f
= fopen( i->fname, "r" ) ) )

<< perror( i->fname );

<color><param>0000,0000,FF00</param>-> i->file = f;

- -> }

</color>

<color><param>FF00,0000,0000</param><< i->file = f;

<color><param>0000,0000,FF00</param>-> if ( i->macrostate == 1 )

- -> {

- -> i->line++;

- -> i->string = i->macro;

- -> i->macrostate = 2;

- -> if( DEBUG_SCAN )

- -> printf("Macro: %s", i->string);

- -> return *i->string++;

</color> }

/* If there's another line in this file, start it. */

<color><param>0000,0000,FF00</param>-> else if( i->file && fgets( i->buf,
sizeof( i->buf ), i->file ) )

- -> {

- -> i->string = i->buf;

- -> i->line++;

- -> return *i->string++;

- -> }

</color>

<color><param>FF00,0000,0000</param><< if( i->file && fgets( i->buf, sizeof(
i-

buf ), i->file ) )

<< {

<color><param>0000,0000,FF00</param>-> /* Run out of lines, do we need macro
termination? */

- -> if ( i->macro && i->macrostate == 2 )

- -> { i->macrostate = 0;

- -> i->string = " ;\n";

</color> i->line++;

<color><param>FF00,0000,0000</param><< i->string = i->buf;

</color> return *i->string++;

}

<color><param>0000,0000,FF00</param>-> // Fall through...

</color> next:

/* This include is done. */

/* Free it up and return EOF so yyparse() returns to parse_file(). */

incp = i->next;

<underline><color><param>FF00,0000,FF00</param>@@ -173,12 +209,13 @@

</underline></color> /* Close file, free name */

if( i->file && i->file != stdin )

fclose( i->file );

freestr( i->fname );

<color><param>0000,0000,FF00</param>-> if (i->macro)

- -> free(i->macro);

</color> free( (char *)i );

<color><param>FF00,0000,0000</param><<

</color> return EOF;

}

/*

* yylex() - set yylval to current token; return its type

<underline><color><param>FF00,0000,FF00</param>@@ -270,11 +307,11 @@

</underline></color> while( c != EOF && isspace( c ) )

c = yychar();

/* Not a comment? Swallow up comment line. */

<color><param>FF00,0000,0000</param><< if( c != '#' )

<color><param>0000,0000,FF00</param>-> if( ! (c == '#' || (incp && incp->macro
&& c == '!')) )

</color> break;

while( ( c = yychar() ) != EOF && c != '\n' )

;

}

<nofill>