1 | /***************************************
2 | C Cross Referencing & Documentation tool. Version 1.6e.
3 |
4 | Collects the variable definition stuff.
5 | ******************/ /******************
6 | Written by Andrew M. Bishop
7 |
8 | This file Copyright 1995-2013 Andrew M. Bishop
9 | It may be distributed under the GNU Public License, version 2, or
10 | any higher version. See section COPYING of the GNU Public license
11 | for conditions under which this file may be redistributed.
12 | ***************************************/
13 |
14 | /*+ Control the output of debugging information from this file. +*/
15 | #define DEBUG 0
16 |
17 | #include <stdlib.h>
18 | #include <stdio.h>
19 | #include <string.h>
20 |
21 | #include "memory.h"
22 | #include "datatype.h"
23 | #include "parse-yy.h"
24 | #include "cxref.h"
25 |
26 | /*+ The file that is currently being documented. +*/
27 | extern File CurFile;
28 |
29 | /*+ When in a header file make a note of which one for the included variables. +*/
30 | extern int in_header;
31 |
32 | /*+ A list of the variables found at each level of the scope. +*/
33 | static StringList2 *variable;
34 |
35 | /*+ The number of levels of scope depth allocated. +*/
36 | static int max_scope=0;
37 |
38 | /*+ The current scope depth. +*/
39 | static int cur_scope=-1;
40 |
41 |
42 | static Variable NewVariableType(char *name,char *type);
43 |
44 |
45 | /*++++++++++++++++++++++++++++++++++++++
46 | Function that is called when a variable definition is seen.
47 |
48 | char* name The name of the variable.
49 |
50 | char* type The type of the variable.
51 |
52 | int scope The scope of variable that has been seen.
53 | ++++++++++++++++++++++++++++++++++++++*/
54 |
55 | void SeenVariableDefinition(char* name,char* type,int scope)
56 | {
57 | Variable var;
58 | int seen=0;
59 |
60 | #if DEBUG
61 | printf("#Var.c# Variable definition for '%s'\n",name);
62 | #endif
63 |
64 | for(var=CurFile->variables;var;var=var->next)
65 | if(!strcmp(var->name,name))
66 | {
67 | var->scope|=scope;
68 | seen=1;
69 | if(!in_header && var->scope&EXTERN_H)
70 | {
71 | if(var->comment)
72 | Free(var->comment);
73 | var->comment=MallocString(GetCurrentComment());
74 | var->lineno=parse_line;
75 | }
76 | break;
77 | }
78 |
79 | if(!seen)
80 | {
81 | var=NewVariableType(name,type);
82 |
83 | var->comment=MallocString(GetCurrentComment());
84 | var->scope=scope;
85 |
86 | var->lineno=parse_line;
87 |
88 | if(in_header && !(scope&EXTERN_H))
89 | var->incfrom=MallocString(parse_file);
90 |
91 | AddToLinkedList(CurFile->variables,Variable,var);
92 | }
93 | }
94 |
95 | /*++++++++++++++++++++++++++++++++++++++
96 | Called when a new scope is entered.
97 | ++++++++++++++++++++++++++++++++++++++*/
98 |
99 | void UpScope(void)
100 | {
101 | cur_scope++;
102 |
103 | #if DEBUG
104 | printf("#Var.c# Scope ++ (%2d)\n",cur_scope);
105 | #endif
106 |
107 | if(cur_scope>=max_scope)
108 | {
109 | if(max_scope==0)
110 | variable=Malloc(16*sizeof(StringList2));
111 | else
112 | variable=Realloc(variable,(max_scope+16)*sizeof(StringList2));
113 | max_scope+=16;
114 | }
115 |
116 | variable[cur_scope]=NewStringList2();
117 | }
118 |
119 |
120 | /*++++++++++++++++++++++++++++++++++++++
121 | Called when an old scope is exited.
122 | ++++++++++++++++++++++++++++++++++++++*/
123 |
124 | void DownScope(void)
125 | {
126 | #if DEBUG
127 | printf("#Var.c# Scope -- (%2d)\n",cur_scope);
128 | #endif
129 |
130 | if(cur_scope==-1)
131 | {
132 | fprintf(stderr,"cxref: Error a parsing problem has been encountered.\n");
133 | fprintf(stderr," This may be a known problem with the inability to parse an old style\n");
134 | fprintf(stderr," function declaration that contains a function pointer.\n");
135 | fprintf(stderr," Replace: int g(f) int (*f)(int); { ... }\n");
136 | fprintf(stderr," With: int g(int (*f)(int)) { ... }\n");
137 | exit(1);
138 | }
139 |
140 | DeleteStringList2(variable[cur_scope]);
141 |
142 | cur_scope--;
143 | }
144 |
145 |
146 | /*++++++++++++++++++++++++++++++++++++++
147 | Add a variable to the list of known variables.
148 |
149 | char* name The name of the variable.
150 | ++++++++++++++++++++++++++++++++++++++*/
151 |
152 | void SeenScopeVariable(char* name)
153 | {
154 | #if DEBUG
155 | printf("#Var.c# Scope Variable depth %2d '%s'\n",cur_scope,name);
156 | #endif
157 |
158 | AddToStringList2(variable[cur_scope],name,NULL,0,0);
159 | }
160 |
161 |
162 | /*++++++++++++++++++++++++++++++++++++++
163 | Check through the scope variables to look for the named one.
164 |
165 | int IsAScopeVariable Returns 1 if the name does refer to a variable that is scoped.
166 |
167 | char* name The name of the variable to search for.
168 | ++++++++++++++++++++++++++++++++++++++*/
169 |
170 | int IsAScopeVariable(char* name)
171 | {
172 | int i,scope;
173 |
174 | #if DEBUG
175 | printf("#Var.c# Lookup variable '%s'\n",name);
176 | #endif
177 |
178 | for(scope=cur_scope;scope>=0;scope--)
179 | for(i=0;i<variable[scope]->n;i++)
180 | if(!strcmp(variable[scope]->s1[i],name))
181 | return(1);
182 |
183 | return(0);
184 | }
185 |
186 |
187 | /*++++++++++++++++++++++++++++++++++++++
188 | Tidy up all of the local variables in case of a problem and abnormal parser termination.
189 | ++++++++++++++++++++++++++++++++++++++*/
190 |
191 | void ResetVariableAnalyser(void)
192 | {
193 | while(cur_scope>=0)
194 | {
195 | DeleteStringList2(variable[cur_scope]);
196 | cur_scope--;
197 | }
198 |
199 | if(variable) Free(variable);
200 | variable=NULL;
201 |
202 | max_scope=0;
203 | cur_scope=-1;
204 | }
205 |
206 |
207 | /*++++++++++++++++++++++++++++++++++++++
208 | Create a new variable type.
209 |
210 | Variable NewVariableType Returns a new Variable type.
211 |
212 | char *name The name of the variable.
213 |
214 | char *type The type of the variable.
215 | ++++++++++++++++++++++++++++++++++++++*/
216 |
217 | static Variable NewVariableType(char *name,char *type)
218 | {
219 | Variable var=(Variable)Calloc(1,sizeof(struct _Variable)); /* clear unused pointers */
220 |
221 | var->name =MallocString(name);
222 | var->type =MallocString(type);
223 | var->visible=NewStringList2();
224 | var->used =NewStringList2();
225 |
226 | return(var);
227 | }
228 |
229 |
230 | /*++++++++++++++++++++++++++++++++++++++
231 | Delete the specified Variable type.
232 |
233 | Variable var The Variable type to be deleted.
234 | ++++++++++++++++++++++++++++++++++++++*/
235 |
236 | void DeleteVariableType(Variable var)
237 | {
238 | if(var->comment) Free(var->comment);
239 | if(var->name) Free(var->name);
240 | if(var->type) Free(var->type);
241 | if(var->defined) Free(var->defined);
242 | if(var->incfrom) Free(var->incfrom);
243 | if(var->visible) DeleteStringList2(var->visible);
244 | if(var->used) DeleteStringList2(var->used);
245 | Free(var);
246 | }