1/* 2 * Copyright 1993, 2000 Christopher Seiwald. 3 * 4 * This file is part of Jam - see jam.c for Copyright information. 5 */ 6 7/* 8 * headers.c - handle #includes in source files 9 * 10 * Using regular expressions provided as the variable $(HDRSCAN), 11 * headers() searches a file for #include files and phonies up a 12 * rule invocation: 13 * 14 * $(HDRRULE) <target> : <include files> ; 15 * 16 * External routines: 17 * headers() - scan a target for include files and call HDRRULE 18 * 19 * Internal routines: 20 * headers1() - using regexp, scan a file and build include LIST 21 * 22 * 04/13/94 (seiwald) - added shorthand L0 for null list pointer 23 * 09/10/00 (seiwald) - replaced call to compile_rule with evaluate_rule, 24 * so that headers() doesn't have to mock up a parse structure 25 * just to invoke a rule. 26 * 03/02/02 (seiwald) - rules can be invoked via variable names 27 * 10/22/02 (seiwald) - list_new() now does its own newstr()/copystr() 28 * 11/04/02 (seiwald) - const-ing for string literals 29 * 12/09/02 (seiwald) - push regexp creation down to headers1(). 30 */ 31 32# include "jam.h" 33# include "lists.h" 34# include "parse.h" 35# include "compile.h" 36# include "rules.h" 37# include "variable.h" 38# include "regexp.h" 39# include "headers.h" 40# include "newstr.h" 41 42#ifdef OPT_HEADER_CACHE_EXT 43# include "hcache.h" 44#endif 45 46#ifndef OPT_HEADER_CACHE_EXT 47static LIST *headers1( const char *file, LIST *hdrscan ); 48#endif 49 50/* 51 * headers() - scan a target for include files and call HDRRULE 52 */ 53 54# define MAXINC 10 55 56void 57headers( TARGET *t ) 58{ 59 LIST *hdrscan; 60 LIST *hdrrule; 61 LIST *hdrcache; 62 LOL lol; 63 64 if( !( hdrscan = var_get( "HDRSCAN" ) ) || 65 !( hdrrule = var_get( "HDRRULE" ) ) ) 66 return; 67 68 /* Doctor up call to HDRRULE rule */ 69 /* Call headers1() to get LIST of included files. */ 70 71 if( DEBUG_HEADER ) 72 printf( "header scan %s\n", t->name ); 73 74 lol_init( &lol ); 75 76 lol_add( &lol, list_new( L0, t->name, 1 ) ); 77#ifdef OPT_HEADER_CACHE_EXT 78 lol_add( &lol, hcache( t, hdrscan ) ); 79#else 80 lol_add( &lol, headers1( t->boundname, hdrscan ) ); 81#endif 82 83 if( lol_get( &lol, 1 ) ) 84 { 85 int jmp = JMP_NONE; 86 list_free( evaluate_rule( hdrrule->string, &lol, L0, &jmp ) ); 87 } 88 89 /* Clean up */ 90 91 lol_free( &lol ); 92} 93 94/* 95 * headers1() - using regexp, scan a file and build include LIST 96 */ 97 98#ifdef OPT_HEADER_CACHE_EXT 99LIST * 100#else 101static LIST * 102#endif 103headers1( 104 const char *file, 105 LIST *hdrscan ) 106{ 107 FILE *f; 108 int i; 109 int rec = 0; 110 LIST *result = 0; 111 regexp *re[ MAXINC ]; 112 char buf[ 1024 ]; 113 114 if( !( f = fopen( file, "r" ) ) ) 115 return result; 116 117 while( rec < MAXINC && hdrscan ) 118 { 119 re[rec++] = regcomp( hdrscan->string ); 120 hdrscan = list_next( hdrscan ); 121 } 122 123 while( fgets( buf, sizeof( buf ), f ) ) 124 { 125 for( i = 0; i < rec; i++ ) 126 if( regexec( re[i], buf ) && re[i]->startp[1] ) 127 { 128 /* Copy and terminate extracted string. */ 129 130 char buf2[ MAXSYM ]; 131 int l = re[i]->endp[1] - re[i]->startp[1]; 132 if (l > MAXSYM) { 133 printf("MAXSYM is too low! Need at least %d\n", l); 134 exit(-1); 135 } 136 memcpy( buf2, re[i]->startp[1], l ); 137 buf2[ l ] = 0; 138 result = list_new( result, buf2, 0 ); 139 140 if( DEBUG_HEADER ) 141 printf( "header found: %s\n", buf2 ); 142 } 143 } 144 145 while( rec ) 146 free( (char *)re[--rec] ); 147 148 fclose( f ); 149 150 return result; 151} 152