/*
* Copyright 1993, 2000 Christopher Seiwald.
*
* This file is part of Jam - see jam.c for Copyright information.
*/
/*
* headers.c - handle #includes in source files
*
* Using regular expressions provided as the variable $(HDRSCAN),
* headers() searches a file for #include files and phonies up a
* rule invocation:
*
* $(HDRRULE) <target> : <include files> ;
*
* External routines:
* headers() - scan a target for include files and call HDRRULE
*
* Internal routines:
* headers1() - using regexp, scan a file and build include LIST
*
* 04/13/94 (seiwald) - added shorthand L0 for null list pointer
* 09/10/00 (seiwald) - replaced call to compile_rule with evaluate_rule,
* so that headers() doesn't have to mock up a parse structure
* just to invoke a rule.
* 03/02/02 (seiwald) - rules can be invoked via variable names
* 10/22/02 (seiwald) - list_new() now does its own newstr()/copystr()
* 11/04/02 (seiwald) - const-ing for string literals
* 12/09/02 (seiwald) - push regexp creation down to headers1().
*/
# include "jam.h"
# include "lists.h"
# include "parse.h"
# include "compile.h"
# include "rules.h"
# include "variable.h"
# include "regexp.h"
# include "headers.h"
# include "newstr.h"
#ifdef GRAPHISOFT_MPW_FIX
#if defined (macintosh)
# include "cursorctl.h"
#endif
#endif
static LIST *headers1( const char *file, LIST *hdrscan );
/*
* headers() - scan a target for include files and call HDRRULE
*/
# define MAXINC 10
void
headers( TARGET *t )
{
LIST *hdrscan;
LIST *hdrrule;
LIST *hdrcache;
LOL lol;
if( !( hdrscan = var_get( "HDRSCAN" ) ) ||
!( hdrrule = var_get( "HDRRULE" ) ) )
return;
/* Doctor up call to HDRRULE rule */
/* Call headers1() to get LIST of included files. */
if( DEBUG_HEADER )
printf( "header scan %s\n", t->name );
lol_init( &lol );
lol_add( &lol, list_new( L0, t->name, 1 ) );
lol_add( &lol, headers1( t->boundname, hdrscan ) );
if( lol_get( &lol, 1 ) )
list_free( evaluate_rule( hdrrule->string, &lol, L0 ) );
/* Clean up */
lol_free( &lol );
}
#ifdef GRAPHISOFT_FIX_NONNATIVENEWLINE
#define XFILEBUFSIZE 4096
typedef struct XFILE {
char buffer [XFILEBUFSIZE];
size_t start;
size_t end;
FILE* f;
} XFILE;
static
XFILE* xfopen ( const char* file, const char* mode)
{
FILE* f = fopen (file, mode);
if (f == NULL)
return NULL;
XFILE* result = (XFILE*)(malloc (sizeof (XFILE)));
if (result == NULL) {
fclose (f);
return NULL;
}
result->f = f;
result->start = 0;
result->end = 0;
return result;
}
static char* xfgets (char* buf, size_t size, XFILE* f)
{
size_t remaining = size;
while (remaining > 0) {
if (f->start == f->end) {
/* read to buffer */
f->start = 0;
f->end = fread (f->buffer, sizeof(char), XFILEBUFSIZE, f->f);
if (f->end == 0)
return NULL; /* EOF */
}
int i = f->start;
int end = (f->end > (f->start+size-1)) ? (f->start+size-1) : f->end ;
char* bufd = buf-(f->start);
char* bufs = f->buffer;
while (i < end) {
if (bufs[i] == '\n' || bufs[i] == '\r') {
bufd[i] = '\n';
bufd[i+1] = 0;
const char first = ('\n' == 0x0D) ? '\n' : '\r' ;
const char second = ('\r' == 0x0D) ? '\r' : '\n' ;
if (first == bufs[i]) {
if (i+1 >= f->end) {
f->start = 0;
f->end = fread (f->buffer, sizeof(char), XFILEBUFSIZE, f->f);
i = f->start-1;
}
if ((i+1 < f->end) && (second == bufs[i+1]))
i++;
}
f->start = i+1;
return buf;
} else {
bufd[i] = bufs[i];
}
i++;
}
remaining -= end-f->start;
f->start = end;
}
return buf;
}
static void xfclose (XFILE* f)
{
fclose (f->f);
free ((void*)f);
}
#endif
/*
* headers1() - using regexp, scan a file and build include LIST
*/
static LIST *
headers1(
const char *file,
LIST *hdrscan )
{
#ifdef GRAPHISOFT_FIX_NONNATIVENEWLINE
XFILE *f;
#else
FILE *f;
#endif
int i;
int rec = 0;
LIST *result = 0;
regexp *re[ MAXINC ];
char buf[ 1024 ];
#ifdef GRAPHISOFT_MPW_FIX
#if defined (macintosh)
SpinCursor (1);
#endif
#endif
#ifdef GRAPHISOFT_FIX_NONNATIVENEWLINE
if( !( f = xfopen( file, "r" ) ) )
#else
if( !( f = fopen( file, "r" ) ) )
#endif
return result;
while( rec < MAXINC && hdrscan )
{
re[rec++] = regcomp( hdrscan->string );
hdrscan = list_next( hdrscan );
}
#ifdef GRAPHISOFT_FIX_NONNATIVENEWLINE
while( xfgets( buf, sizeof( buf ), f ) )
#else
while( fgets( buf, sizeof( buf ), f ) )
#endif
{
for( i = 0; i < rec; i++ )
if( regexec( re[i], buf ) && re[i]->startp[1] )
{
/* Copy and terminate extracted string. */
char buf2[ MAXSYM ];
int l = re[i]->endp[1] - re[i]->startp[1];
memcpy( buf2, re[i]->startp[1], l );
buf2[ l ] = 0;
result = list_new( result, buf2, 0 );
if( DEBUG_HEADER )
printf( "header found: %s\n", buf2 );
}
}
while( rec )
free( (char *)re[--rec] );
#ifdef GRAPHISOFT_FIX_NONNATIVENEWLINE
xfclose( f );
#else
fclose( f );
#endif
return result;
}
| # | Change | User | Description | Committed | |
|---|---|---|---|---|---|
| #9 | 2521 | Miklos Fazekas | Compile error fixes after merge | ||
| #8 | 2520 | Miklos Fazekas | Integration error fixes | ||
| #7 | 2519 | Miklos Fazekas | Sync to 2.5rc1 | ||
| #6 | 1635 | Miklos Fazekas | OS-X version with CodeWarrior, fix for header scan with non-native lineendings | ||
| #5 | 1597 | Miklos Fazekas | Merge to 2.4rc1, headers can cointain non native linefeeds. | ||
| #4 | 1573 | Miklos Fazekas | Merge to jam mainline. | ||
| #3 | 1569 | Miklos Fazekas | Integrate with lates mainline | ||
| #2 | 1398 | Miklos Fazekas | Cleanup. | ||
| #1 | 1212 | Miklos Fazekas | Created a Jam branch | ||
| //guest/perforce_software/jam/src/headers.c | |||||
| #2 | 486 | Perforce staff |
Jam 2.3. See RELNOTES for a list of changes from 2.2.x. Just about every source file was touched when jam got ANSI-fied. |
||
| #1 | 2 | laura | Add Jam/MR 2.2 source | ||