headers.c #8

  • //
  • guest/
  • miklos_fazekas/
  • jam/
  • src/
  • headers.c
  • View
  • Commits
  • Open Download .zip Download (5 KB)
/*
 * 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