1 /***************************************
4 C Cross Referencing & Documentation tool. Version 1.5f.
6 Collects the pre-processing instruction stuff.
7 ******************/ /******************
8 Written by Andrew M. Bishop
10 This file Copyright 1995,96,97,99,2000,01,02,03,04 Andrew M. Bishop
11 It may be distributed under the GNU Public License, version 2, or
12 any higher version. See section COPYING of the GNU Public license
13 for conditions under which this file may be redistributed.
14 ***************************************/
16 /*+ Control the output of debugging information for this file. +*/
32 /*+ The file that is currently being processed. +*/
35 /*+ The name of the include directories specified on the command line. +*/
36 extern char **option_incdirs
;
38 /*+ The number of include directories on the command line. +*/
39 extern int option_nincdirs
;
41 /*+ When in a header file, this is set to 1, to allow most of the stuff to be skipped. +*/
44 /*+ The current #include we are looking at. +*/
45 static Include cur_inc
=NULL
;
47 /*+ The current #define we are looking at. +*/
48 static Define cur_def
=NULL
;
50 /*+ The depth of includes. +*/
51 static int inc_depth
=0;
53 /*+ The type of include at this depth. +*/
54 static char *inc_type
=NULL
;
56 /*+ The name of the include file at this depth. +*/
57 static char **inc_name
=NULL
;
59 /*+ The working directory. +*/
60 static char *cwd
=NULL
;
63 static Include
NewIncludeType(char *name
);
64 static Define
NewDefineType(char *name
);
67 /*++++++++++++++++++++++++++++++++++++++
68 Function that is called when an included file is seen in the current file.
70 char *name The name of the file from the source code.
71 ++++++++++++++++++++++++++++++++++++++*/
73 void SeenInclude(char *name
)
76 printf("#Preproc.c# #include %s\n",name
);
79 if(!inc_type
|| inc_depth
==0 || (inc_depth
> 0 && inc_type
[inc_depth
-1]==LOCAL
))
81 Include inc
,*t
=&CurFile
->includes
;
82 int inc_scope
=(*name
=='"')?LOCAL
:GLOBAL
;
86 name
[strlen(name
)-1]=0;
88 if(inc_scope
==LOCAL
&& option_nincdirs
)
89 for(i
=0;i
<option_nincdirs
;i
++)
91 char *newname
=CanonicaliseName(ConcatStrings(3,option_incdirs
[i
],"/",name
));
94 if(!lstat(newname
,&buf
))
98 for(i
=0;i
<inc_depth
;i
++)
100 while(*t
&& (*t
)->next
)
105 inc
=NewIncludeType(name
);
107 inc
->comment
=MallocString(GetCurrentComment());
108 inc
->scope
=inc_scope
;
110 AddToLinkedList(*t
,Include
,inc
);
119 /*++++++++++++++++++++++++++++++++++++++
120 Function that is called when a comment is seen following a #include.
121 ++++++++++++++++++++++++++++++++++++++*/
123 void SeenIncludeComment(void)
125 char* comment
=GetCurrentComment();
128 printf("#Preproc.c# #include trailing comment '%s' for %s\n",comment
,cur_inc
->name
);
131 if(!cur_inc
->comment
)
132 cur_inc
->comment
=MallocString(comment
);
136 /*++++++++++++++++++++++++++++++++++++++
137 Function that is called when a change in current file is seen.
139 char *SeenFileChange Returns the filename that we are now in.
141 char *name The pathname of the included file as determined by gcc.
143 int flag The flags that GCC leaves in the file
144 ++++++++++++++++++++++++++++++++++++++*/
146 char *SeenFileChange(char *name
,int flag
)
150 cwd
=(char*)Malloc(PATH_MAX
+1);
151 if(!getcwd(cwd
,PATH_MAX
))
155 /* Special gcc-3.x fake names for built-in #defines. */
157 /* jmj: the fake names differ from locale to locale, but are always bracketed like this */
158 /* old: if(!strcmp(name,"<built-in>") || !strcmp(name,"<command line>"))*/
159 if (*name
== '<' && name
[strlen(name
) - 1] == '>')
167 return(CurFile
->name
);
170 name
=CanonicaliseName(name
);
172 if(!strncmp(name
,cwd
,strlen(cwd
)))
173 name
=name
+strlen(cwd
);
178 name
=inc_name
[inc_depth
-2];
184 printf("#Preproc.c# FileChange - %s %s (flag=%d)\n",flag
&2?"Included ":"Return to",name
,flag
);
187 /* Store the information. */
189 if(flag
&2 && (!inc_type
|| inc_depth
==0 || (inc_depth
> 0 && inc_type
[inc_depth
-1]==LOCAL
)))
194 SeenInclude(ConcatStrings(3,"<",name
,">"));
196 SeenInclude(ConcatStrings(3,"\"",name
,"\""));
201 cur_inc
->name
=MallocString(name
);
211 inc_type
=(char*)Malloc(16);
212 inc_name
=(char**)Malloc(16*sizeof(char*));
217 inc_type
=(char*)Realloc(inc_type
,(unsigned)(inc_depth
+16));
218 inc_name
=(char**)Realloc(inc_name
,(unsigned)(sizeof(char*)*(inc_depth
+16)));
221 if(inc_depth
>1 && inc_type
[inc_depth
-2]==GLOBAL
)
222 inc_type
[inc_depth
-1]=GLOBAL
;
223 else if (inc_depth
> 0)
224 inc_type
[inc_depth
-1]=cur_inc
?cur_inc
->scope
:(flag
&8)?GLOBAL
:LOCAL
;
226 inc_name
[inc_depth
-1]=CopyString(name
);
231 if(inc_type
&& inc_depth
>0)
232 in_header
=inc_type
[inc_depth
-1];
236 SetCurrentComment(NULL
);
244 /*++++++++++++++++++++++++++++++++++++++
245 Function that is called when a #define is seen in the current file.
247 char* name The name of the #defined symbol.
248 ++++++++++++++++++++++++++++++++++++++*/
250 void SeenDefine(char* name
)
255 printf("#Preproc.c# Defined name '%s'\n",name
);
258 def
=NewDefineType(name
);
260 def
->comment
=MallocString(GetCurrentComment());
262 def
->lineno
=parse_line
;
264 AddToLinkedList(CurFile
->defines
,Define
,def
);
270 /*++++++++++++++++++++++++++++++++++++++
271 Function that is called when a comment is seen in a #define definition.
272 ++++++++++++++++++++++++++++++++++++++*/
274 void SeenDefineComment(void)
276 char* comment
=GetCurrentComment();
279 printf("#Preproc.c# #define inline comment '%s' in %s\n",comment
,cur_def
->name
);
282 if(!cur_def
->comment
)
283 cur_def
->comment
=MallocString(comment
);
287 /*++++++++++++++++++++++++++++++++++++++
288 Function that is called when a #define value is seen in the current file.
290 char* value The value of the #defined symbol.
291 ++++++++++++++++++++++++++++++++++++++*/
293 void SeenDefineValue(char* value
)
296 printf("#Preproc.c# #define value '%s' for %s\n",value
,cur_def
->name
);
299 cur_def
->value
=MallocString(value
);
303 /*++++++++++++++++++++++++++++++++++++++
304 Function that is called when a #define function argument is seen in the current definition.
306 char* name The argument.
307 ++++++++++++++++++++++++++++++++++++++*/
309 void SeenDefineFunctionArg(char* name
)
312 printf("#Preproc.c# #define Function arg '%s' in %s()\n",name
,cur_def
->name
);
315 AddToStringList2(cur_def
->args
,name
,SplitComment(&cur_def
->comment
,name
),0,0);
319 /*++++++++++++++++++++++++++++++++++++++
320 Function that is called when a comment is seen in a #define function definition.
321 ++++++++++++++++++++++++++++++++++++++*/
323 void SeenDefineFuncArgComment(void)
325 char* comment
=GetCurrentComment();
328 printf("#Preproc.c# #define Function arg comment '%s' in %s()\n",comment
,cur_def
->name
);
331 if(!cur_def
->args
->s2
[cur_def
->args
->n
-1])
332 cur_def
->args
->s2
[cur_def
->args
->n
-1]=MallocString(comment
);
336 /*++++++++++++++++++++++++++++++++++++++
337 Tidy up all of the local variables in case of a problem and abnormal parser termination.
338 ++++++++++++++++++++++++++++++++++++++*/
340 void ResetPreProcAnalyser(void)
349 if(inc_type
) Free(inc_type
);
351 if(inc_name
) Free(inc_name
);
359 /*++++++++++++++++++++++++++++++++++++++
360 Create a new Include datatype.
362 Include NewIncludeType Return the new Include type.
364 char *name The name of the new include.
365 ++++++++++++++++++++++++++++++++++++++*/
367 static Include
NewIncludeType(char *name
)
369 Include inc
=(Include
)Calloc(1,sizeof(struct _Include
));
371 inc
->name
=MallocString(name
);
377 /*++++++++++++++++++++++++++++++++++++++
378 Delete the specified Include type.
380 Include inc The Include type to be deleted.
381 ++++++++++++++++++++++++++++++++++++++*/
383 void DeleteIncludeType(Include inc
)
385 if(inc
->comment
) Free(inc
->comment
);
386 if(inc
->name
) Free(inc
->name
);
389 Include p
=inc
->includes
;
392 DeleteIncludeType(p
);
401 /*++++++++++++++++++++++++++++++++++++++
402 Create a new Define datatype.
404 Define NewDefineType Return the new Define type.
406 char *name The name of the new define.
407 ++++++++++++++++++++++++++++++++++++++*/
409 static Define
NewDefineType(char *name
)
411 Define def
=(Define
)Calloc(1,sizeof(struct _Define
)); /* clear unused pointers */
413 def
->name
=MallocString(name
);
414 def
->args
=NewStringList2();
420 /*++++++++++++++++++++++++++++++++++++++
421 Delete the specified Define type.
423 Define def The Define type to be deleted.
424 ++++++++++++++++++++++++++++++++++++++*/
426 void DeleteDefineType(Define def
)
428 if(def
->comment
) Free(def
->comment
);
429 if(def
->name
) Free(def
->name
);
430 if(def
->value
) Free(def
->value
);
431 if(def
->args
) DeleteStringList2(def
->args
);