Indentation fix, cleanup.
[AROS.git] / tools / cxref / func.c
blobcd3c7385311e0e45bcacd98edb2003afa762c028
1 /***************************************
2 $Header$
4 C Cross Referencing & Documentation tool. Version 1.5f.
6 Handle Function stuff.
7 ******************/ /******************
8 Written by Andrew M. Bishop
10 This file Copyright 1995,96,97,99,2001 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 debugging information from this file. +*/
17 #define DEBUG 0
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <string.h>
23 #include "memory.h"
24 #include "datatype.h"
25 #include "parse-yy.h"
26 #include "cxref.h"
28 /*+ The current parsing options. +*/
29 extern int option_xref;
31 /*+ The current file that is being processed. +*/
32 extern File CurFile;
34 /*+ When in a header file include functions from that file (except inline functions). +*/
35 extern int in_header;
37 /*+ The current function, this is initialised by the start of a possible declaration and maintained until all of the
38 arguments have been added and confirmation that it is a definition and not a prototype is seen. +*/
39 static Function cur_func=NULL;
41 /*+ The list of function prototypes and the files that they are defined in. +*/
42 static StringList2 prototypes=NULL;
44 static Function NewFunctionType(char *name,char *type);
47 /*++++++++++++++++++++++++++++++++++++++
48 Function that is called when a function prototype is seen.
50 char* name The name of the function.
52 int in_a_function Whether the reference is from within a function or at the top level of the file.
53 ++++++++++++++++++++++++++++++++++++++*/
55 void SeenFunctionProto(char* name,int in_a_function)
57 if(!(option_xref&XREF_FUNC))
58 return;
60 #if DEBUG
61 printf("#Func.c# Function prototype '%s'\n",name);
62 #endif
64 if(!in_a_function)
66 if(!prototypes)
67 prototypes=NewStringList2();
68 AddToStringList2(prototypes,name,parse_file,0,1);
70 else
71 AddToStringList(cur_func->protos,name,0,1);
75 /*++++++++++++++++++++++++++++++++++++++
76 Function that is called when a function declaration is seen.
77 This may or may not be a function defintion, we will need to wait and see.
79 char* name The name of the function.
81 int scope The scope of the function definition.
82 ++++++++++++++++++++++++++++++++++++++*/
84 void SeenFunctionDeclaration(char* name,int scope)
86 #if DEBUG
87 printf("#Func.c# Function declaration for '%s()'\n",name);
88 #endif
90 if(cur_func)
91 DeleteFunctionType(cur_func);
93 cur_func=NewFunctionType(name,NULL);
95 cur_func->comment=MallocString(GetCurrentComment());
96 cur_func->scope=scope;
98 cur_func->lineno=parse_line;
100 if(in_header)
101 cur_func->incfrom=MallocString(parse_file);
105 /*++++++++++++++++++++++++++++++++++++++
106 Called when a possible function definition is confirmed.
108 char* type The type of the function, or NULL at the end of a definition.
109 ++++++++++++++++++++++++++++++++++++++*/
111 void SeenFunctionDefinition(char* type)
113 Function *func=&CurFile->functions;
114 int i;
116 if(cur_func->scope&INLINED && cur_func->incfrom)
117 return;
119 #if DEBUG
120 printf("#Func.c# Function definition %s for '%s()'\n",type?"start":"end",cur_func->name);
121 #endif
123 if(!type)
124 {cur_func=NULL;return;}
126 cur_func->type=MallocString(type);
128 cur_func->cret=MallocString(SplitComment(&cur_func->comment,type));
129 if(!cur_func->cret)
130 cur_func->cret=MallocString(GetCurrentComment());
132 if(option_xref&XREF_FUNC)
133 if(prototypes)
134 for(i=0;i<prototypes->n;i++)
135 if(!strcmp(cur_func->name,prototypes->s1[i]))
136 {cur_func->protofile=MallocString(prototypes->s2[i]); break;}
138 for(i=0;i<cur_func->args->n;i++)
139 if(strcmp(cur_func->args->s1[i],"void") && strcmp(cur_func->args->s1[i],"...") && !strchr(cur_func->args->s1[i],' '))
141 char *old=cur_func->args->s1[i];
142 cur_func->args->s1[i]=MallocString(ConcatStrings(2,"int ",old));
143 cur_func->args->s2[i]=MallocString(SplitComment(&cur_func->comment,cur_func->args->s1[i]));
144 Free(old);
147 while(*func)
149 if(strcmp(cur_func->name,(*func)->name)<0)
151 Function temp=*func;
152 *func=cur_func;
153 cur_func->next=temp;
154 break;
156 func=&(*func)->next;
159 if(!cur_func->next)
160 *func=cur_func;
163 /*++++++++++++++++++++++++++++++++++++++
164 Function that is called when a function argument is seen in the current function declaration.
166 char* name The name of the argument.
168 char* type The type of the argument, or NULL if a traditional style function definition.
169 ++++++++++++++++++++++++++++++++++++++*/
171 void SeenFunctionArg(char* name,char *type)
173 #if DEBUG
174 printf("#Func.c# Function arg %s '%s' in %s()\n",name?name:"K&R",type?type:"K&R",cur_func->name);
175 #endif
177 if(name)
179 if(type && strcmp(type,"void"))
181 int i;
183 for(i=0;i<cur_func->args->n;i++)
184 if(!strcmp(cur_func->args->s1[i],name))
186 Free(cur_func->args->s1[i]);
187 cur_func->args->s1[i]=MallocString(type);
188 cur_func->args->s2[i]=MallocString(SplitComment(&cur_func->comment,type));
189 break;
191 if(i==cur_func->args->n)
192 AddToStringList2(cur_func->args,type,SplitComment(&cur_func->comment,type),0,0);
194 if(!cur_func->args->s2[i])
195 cur_func->args->s2[i]=MallocString(GetCurrentComment());
197 else
198 AddToStringList2(cur_func->args,name,NULL,0,0);
203 /*++++++++++++++++++++++++++++++++++++++
204 Function that is called when a comment is seen, that may be in a function body.
206 int SeenFuncIntComment Returns a true value if the comment was accepted as an function internal comment.
208 char* comment The comment that has been seen.
209 ++++++++++++++++++++++++++++++++++++++*/
211 int SeenFuncIntComment(char* comment)
213 if(!cur_func || !cur_func->type)
214 return(0);
216 #if DEBUG
217 printf("#Func.c# Function internal comment '%s' in %s()\n",comment,cur_func->name);
218 #endif
220 if(cur_func->comment)
222 char* c=cur_func->comment;
224 cur_func->comment=MallocString(ConcatStrings(3,c,"\n\n",comment));
225 Free(c);
227 else
228 cur_func->comment=MallocString(comment);
230 return(1);
234 /*++++++++++++++++++++++++++++++++++++++
235 Function that is called when a function call is seen in the current function.
237 char* name The name of the function that is called.
238 ++++++++++++++++++++++++++++++++++++++*/
240 void SeenFunctionCall(char* name)
242 if(!(option_xref&XREF_FUNC))
243 return;
245 #if DEBUG
246 printf("#Func.c# Function call for '%s()' in %s()\n",name,cur_func->name);
247 #endif
249 AddToStringList2(cur_func->calls,name,NULL,1,1);
253 /*++++++++++++++++++++++++++++++++++++++
254 Function that is called when a function or variable is referenced in the current function.
256 char* name The name of the function or variable that is referenced.
258 int in_a_function Whether the reference is from within a function or at the top level of the file.
259 ++++++++++++++++++++++++++++++++++++++*/
261 void CheckFunctionVariableRef(char* name,int in_a_function)
263 Variable var =CurFile->variables;
264 Function func=CurFile->functions;
265 StringList2 sl=NULL;
267 if(!(option_xref&(XREF_VAR|XREF_FUNC)))
268 return;
270 if(IsAScopeVariable(name))
271 return;
273 #if DEBUG
274 printf("#Func.c# Function/Variable reference for '%s' in %s\n",name,in_a_function?cur_func->name:CurFile->name);
275 #endif
277 if(option_xref&XREF_VAR)
278 while(var)
280 if(!strcmp(var->name,name))
282 if(in_a_function)
283 sl=cur_func->v_refs;
284 else
285 sl=CurFile->v_refs;
286 break;
288 var=var->next;
291 if(!sl && option_xref&XREF_FUNC)
292 while(func)
294 if(!strcmp(func->name,name))
296 if(in_a_function)
297 sl=cur_func->f_refs;
298 else
299 sl=CurFile->f_refs;
300 break;
302 func=func->next;
305 if(!sl && option_xref&XREF_FUNC)
307 int i;
308 if(in_a_function)
309 for(i=0;i<cur_func->protos->n;i++)
310 if(!strcmp(name,cur_func->protos->s[i]))
312 sl=cur_func->f_refs;
313 break;
316 if(!sl && prototypes)
317 for(i=0;i<prototypes->n;i++)
318 if(!strcmp(name,prototypes->s1[i]))
320 if(in_a_function)
321 sl=cur_func->f_refs;
322 else
323 sl=CurFile->f_refs;
324 break;
328 /* Now add the function or variable to the Function / File structure. */
330 if(sl)
331 AddToStringList2(sl,name,NULL,1,1);
335 /*++++++++++++++++++++++++++++++++++++++
336 Tidy up all of the local variables in case of a problem and abnormal parser termination.
337 ++++++++++++++++++++++++++++++++++++++*/
339 void ResetFunctionAnalyser(void)
341 if(prototypes) DeleteStringList2(prototypes);
342 prototypes=NULL;
344 if(cur_func)
346 Function func=CurFile->functions;
347 int delete_cur_func=1;
349 while(func)
351 if(func==cur_func)
352 delete_cur_func=0;
354 func=func->next;
357 if(delete_cur_func)
358 DeleteFunctionType(cur_func);
360 cur_func=NULL;
365 /*++++++++++++++++++++++++++++++++++++++
366 Create a new Function Type variable.
368 Function NewFunctionType Returns the new Function variable.
370 char *name The name of the function.
372 char *type The type of the function.
373 ++++++++++++++++++++++++++++++++++++++*/
375 static Function NewFunctionType(char *name,char *type)
377 Function func=(Function)Calloc(1,sizeof(struct _Function)); /* clear unused pointers */
379 func->name =MallocString(name);
380 func->type =MallocString(type);
381 func->args =NewStringList2();
382 func->protos=NewStringList();
383 func->calls =NewStringList2();
384 func->called=NewStringList2();
385 func->used =NewStringList2();
386 func->v_refs=NewStringList2();
387 func->f_refs=NewStringList2();
389 return(func);
393 /*++++++++++++++++++++++++++++++++++++++
394 Delete the specified Function type.
396 Function func The Function type to be deleted.
397 ++++++++++++++++++++++++++++++++++++++*/
399 void DeleteFunctionType(Function func)
401 if(func->comment) Free(func->comment);
402 if(func->name) Free(func->name);
403 if(func->type) Free(func->type);
404 if(func->cret) Free(func->cret);
405 if(func->protofile) Free(func->protofile);
406 if(func->incfrom) Free(func->incfrom);
407 if(func->args) DeleteStringList2(func->args);
408 if(func->protos) DeleteStringList(func->protos);
409 if(func->calls) DeleteStringList2(func->calls);
410 if(func->called) DeleteStringList2(func->called);
411 if(func->used) DeleteStringList2(func->used);
412 if(func->v_refs) DeleteStringList2(func->v_refs);
413 if(func->f_refs) DeleteStringList2(func->f_refs);
414 Free(func);