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  | }