| 61 | #define MAXINC 10 |
| 62 | |
| 63 | void macro_headers( TARGET * t ) |
| 64 | { |
| 65 | static regexp * re = 0; |
| 66 | FILE * f; |
| 67 | char buf[ 1024 ]; |
| 68 | |
| 69 | if ( DEBUG_HEADER ) |
| 70 | out_printf( "macro header scan for %s\n", object_str( t->name ) ); |
| 71 | |
| 72 | /* This regexp is used to detect lines of the form |
| 73 | * "#define MACRO <....>" or "#define MACRO "....." |
| 74 | * in the header macro files. |
| 75 | */ |
| 76 | if ( !re ) |
| 77 | { |
| 78 | OBJECT * const re_str = object_new( |
| 79 | "^[ ]*#[ ]*define[ ]*([A-Za-z][A-Za-z0-9_]*)[ ]*" |
| 80 | "[<\"]([^\">]*)[\">].*$" ); |
| 81 | re = regex_compile( re_str ); |
| 82 | object_free( re_str ); |
| 83 | } |
| 84 | |
| 85 | if ( !( f = fopen( object_str( t->boundname ), "r" ) ) ) |
| 86 | { |
| 87 | err_printf( "[errno %d] failed to scan include file '%s': %s", |
| 88 | errno, object_str( t->boundname ), strerror(errno) ); |
| 89 | return; |
| 90 | } |
| 91 | |
| 92 | while ( fgets( buf, sizeof( buf ), f ) ) |
| 93 | { |
| 94 | HEADER_MACRO var; |
| 95 | HEADER_MACRO * v = &var; |
| 96 | |
| 97 | if ( regexec( re, buf ) && re->startp[ 1 ] ) |
| 98 | { |
| 99 | OBJECT * symbol; |
| 100 | int found; |
| 101 | /* we detected a line that looks like "#define MACRO filename */ |
| 102 | ( (char *)re->endp[ 1 ] )[ 0 ] = '\0'; |
| 103 | ( (char *)re->endp[ 2 ] )[ 0 ] = '\0'; |
| 104 | |
| 105 | if ( DEBUG_HEADER ) |
| 106 | out_printf( "macro '%s' used to define filename '%s' in '%s'\n", |
| 107 | re->startp[ 1 ], re->startp[ 2 ], object_str( t->boundname ) |
| 108 | ); |
| 109 | |
| 110 | /* add macro definition to hash table */ |
| 111 | if ( !header_macros_hash ) |
| 112 | header_macros_hash = hashinit( sizeof( HEADER_MACRO ), |
| 113 | "hdrmacros" ); |
| 114 | |
| 115 | symbol = object_new( re->startp[ 1 ] ); |
| 116 | v = (HEADER_MACRO *)hash_insert( header_macros_hash, symbol, &found |
| 117 | ); |
| 118 | if ( !found ) |
| 119 | { |
| 120 | v->symbol = symbol; |
no test coverage detected