File: hdrmacro.c

package info (click to toggle)
ftjam 2.3.5-1
  • links: PTS
  • area: main
  • in suites: woody
  • size: 800 kB
  • ctags: 1,022
  • sloc: ansic: 7,951; yacc: 365; sh: 95; makefile: 57
file content (133 lines) | stat: -rw-r--r-- 3,531 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/*
 * Copyright 1993, 2000 Christopher Seiwald.
 *
 * This file is part of Jam - see jam.c for Copyright information.
 */

# include "jam.h"
# include "lists.h"
# include "parse.h"
# include "compile.h"
# include "rules.h"
# include "variable.h"
# include "regexp.h"
# include "hdrmacro.h"
# include "hash.h"
# include "newstr.h"

/*
 * hdrmacro.c - handle header files that define macros used in
 *              #include statements.
 *
 *  we look for lines like "#define MACRO  <....>" or '#define MACRO  "    "'
 *  in the target file. When found, we 
 *
 *  we then phony up a rule invocation like:
 *
 *	$(HDRRULE) <target> : <resolved included files> ;
 *
 * External routines:
 *    headers1() - scan a target for "#include MACRO" lines and try
 *                 to resolve them when needed
 *
 * 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.
 */

static LIST *header_macros1( LIST *l, char *file, int rec, regexp *re[] );

/* this type is used to store a dictionary of file header macros */
typedef struct header_macro
{
  char*  symbol;
  char*  filename;  /* we could maybe use a LIST here ?? */
  
} HEADER_MACRO;
 
static struct hash*   header_macros_hash = 0;

/*
 * headers() - scan a target for include files and call HDRRULE
 */

# define MAXINC 10

void
macro_headers( TARGET *t )
{
	LIST	*hdrrule;
	regexp	*re;
	FILE	*f;
	char	buf[ 1024 ];
	int	i;

    if ( DEBUG_HEADER )
      printf( "macro header scan for %s\n", t->name );

    /* this regexp is used to detect lines of the form       */
    /* "#define  MACRO  <....>" or "#define  MACRO  "....."  */
    /* in the header macro files..                           */
    re = regcomp(
       "^[ 	]*#[ 	]*define[ 	]*([A-Za-z][A-Za-z0-9_]*)[ 	]*"
       "[<\"]([^\">]*)[\">].*$" );

	if( !( f = fopen( t->boundname, "r" ) ) )
          return;

	while( fgets( buf, sizeof( buf ), f ) )
	{
      HEADER_MACRO  var, *v = &var;
      
      if ( regexec( re, buf ) && re->startp[1] )
      {
        /* we detected a line that looks like "#define  MACRO  filename */
        re->endp[1][0] = '\0';
        re->endp[2][0] = '\0';
        
        if ( DEBUG_HEADER )
          printf( "macro '%s' used to define filename '%s' in '%s'\n",
                   re->startp[1], re->startp[2], t->boundname );

        /* add macro definition to hash table */
        if ( !header_macros_hash )
          header_macros_hash = hashinit( sizeof( HEADER_MACRO ), "hdrmacros" );

        v->symbol   = re->startp[1];
        v->filename = 0;
        if ( hashenter( header_macros_hash, (HASHDATA **)&v ) )
        {
          v->symbol   = newstr( re->startp[1] );  /* never freed */
          v->filename = newstr( re->startp[2] );  /* never freed */
        }
        /* XXXX: FOR NOW, WE IGNORE MULTIPLE MACRO DEFINITIONS !! */
        /*       WE MIGHT AS WELL USE A LIST TO STORE THEM..      */
      }
    }

	fclose( f );

    free( re );
}


char*
macro_header_get( const char*  macro_name )
{
  HEADER_MACRO  var, *v = &var;

  v->symbol = (char*)macro_name;

  if( header_macros_hash && hashcheck( header_macros_hash, (HASHDATA **)&v ) )
  {
    if ( DEBUG_HEADER )
      printf( "### macro '%s' evaluated to '%s'\n", macro_name, v->filename );
    return v->filename;
  }
  return 0;  
}