1 /*
2 FuncOut -> extractor for function prototypes
3 from ANSI c programs.
4
5
6 */
7
8 #define TRUE 1
9 #define FALSE 0
10 #define LINELENGTH 4096 /* max line length*/
11
12
13 #include <stdio.h>
14 #include <string.h>
15
16 void Extract_Prototypes(FILE *in,FILE *out, int eflag);
17 char *External_Prototype(char *string);
18 void Find_Next_Line(FILE *in);
19
20
21
22 void main(int argc, char *argv[])
23 {
24 FILE *in;
25 char *fn;
26 int eflag=0;
27
28 if (argc<2)
29 {
30 printf("/* FUNCOUT - ANSI C PROTOTYPE EXTRACTOR. sam 1995 */\n");
31 printf(" Syntax : funcount [-e = generate external prototypes] <ip-file> \n");
32 exit(-1);
33 }
34
35 if (strcmp(argv[1],"-e")==0)
36 {
37 fn = argv[2];
38 eflag=1;
39 }
40 else
41 {
42 fn=argv[1];
43 }
44
45 in = fopen(fn,"rb");
46 if (in==NULL)
47 {
48 fprintf(stderr, "funcout: unable to open file %s \n", argv[1]);
49 exit(-1);
50 }
51
52 Extract_Prototypes(in,stdout,eflag);
53
54 fclose(in);
55 }
56
57
58
59 void Extract_Prototypes(FILE *in, FILE *out, int eflag)
60 {
61 char ip_buff[2];
62 char op_buff[LINELENGTH];
63 int i;
64
65 int comments, brace_level, fill_op, opb_count, bracket;
66 int dont_copy_flag, start_param_flag,quotes,single_quotes,start;
67
68 /* just a simple filter. include the following :
69
70 (1) skip comments /star and star/ and //
71 (2) skip lines with # start
72 (2.1) skip every thing within braces
73 (3) start storing text when next char is >32.
74 (4) reset text store when you find a ;
75 (5) output textstore when you find a {
76
77 done!.
78 */
79
80 /* initialise the vars */
81 for (i=0;i<2;i++)
82 ip_buff[i]=0;
83 comments = 0;
84 brace_level =0;
85 fill_op=0;
86 opb_count=0;
87 bracket=0;
88 dont_copy_flag=0;
89 start_param_flag=0;
90 quotes=0;
91 single_quotes=0;
92
93 fread(&ip_buff[1], 1, sizeof(char), in);
94 start=1;
95 ip_buff[0]=0;
96
97 do {
98
99 /* read a character */
100 if (!start)
101 {
102 ip_buff[0]=ip_buff[1];
103 fread( &ip_buff[1], 1, sizeof(char), in);
104 }
105 else
106 start=0;
107
108
109 /* (1) check for comments starting */
110 if (ip_buff[0]== '/' && ip_buff[1]=='*' && quotes==0 && single_quotes==0)
111 {
112 if(op_buff[opb_count-1] == '/') op_buff[opb_count-1]=' ';
113 comments= TRUE;
114 }
115
116
117 /* check for the end of comments -> don't expect nested
118 * comments
119 */
120
121 if (comments)
122 {
123 if (ip_buff[0]=='*' && ip_buff[1]=='/')
124 {
125 comments= FALSE;
126 continue;
127 }
128 else
129 continue;
130 }
131
132 /* skip ansi comments */
133 if (ip_buff[0]=='/' && ip_buff[1]=='/' && quotes ==0 && single_quotes==0)
134 {
135 Find_Next_Line(in);
136 continue;
137 }
138
139 /* (2.05) -> double " quotes " */
140 if (ip_buff[1]==34)
141 {
142 switch (quotes)
143 {
144 case 0: quotes=1; break;
145 case 1: quotes=0; break;
146 }
147 }
148
149 if (quotes)
150 continue;
151
152 /* single quotes */
153 if (ip_buff[1]==39)
154 {
155 switch(single_quotes)
156 {
157 case 0: single_quotes=1; break;
158 case 1: single_quotes=0; break;
159 }
160 }
161
162 if (single_quotes)
163 continue;
164
165 /* (2.1) braces -- be careful ! need to pass the first {
166 * to the later (5) process
167 */
168
169 /* NEED TO insert step 5 here */
170 /* (5) output output buffer on finding a { */
171 if (ip_buff[1]=='{' && fill_op && start_param_flag)
172 {
173 op_buff[opb_count]=';';
174 op_buff[++opb_count]=0;
175
176 if (eflag)
177 {
178 printf("%s\n", External_Prototype(op_buff));
179 }
180 else
181 {
182 for (i=0;i<(opb_count);i++)
183 printf("%c", op_buff[i]);
184 printf("\n");
185 }
186
187 /* reset the op_fill */
188 fill_op= FALSE;
189 opb_count=0;
190 bracket=0;
191 dont_copy_flag=0;
192 start_param_flag=0;
193 }
194
195 if (ip_buff[1]=='{')
196 brace_level++;
197
198 if (ip_buff[1]=='}')
199 {
200 brace_level--;
201 continue;
202 }
203
204 if (brace_level)
205 {
206 continue;
207 }
208
209
210 /* (2) # lines */
211 if (ip_buff[1]=='#')
212 {
213 /*clear the buffer first*/
214 ip_buff[1]= 0;
215 Find_Next_Line(in);
216 continue;
217 }
218
219
220
221 /* (3) start fillin ght op buffer */
222 if (ip_buff[1]>32 && ip_buff[1]!='/' && fill_op==FALSE)
223 {
224 fill_op=TRUE;
225 opb_count=0;
226 bracket=0;
227 dont_copy_flag=0;
228 start_param_flag=0;
229 }
230
231 if (!fill_op)
232 continue;
233
234 if (fill_op)
235 {
236 if (!dont_copy_flag)
237 op_buff[opb_count++]= ip_buff[1];
238
239 /* copy the info up to the last ) and no further */
240 if (ip_buff[1]=='(')
241 {
242 bracket++;
243 start_param_flag=TRUE;
244 }
245 if (ip_buff[1]==')')
246 {
247 bracket--;
248 if (!bracket)
249 {
250 /*start_param_flag=FALSE;*/
251 dont_copy_flag=TRUE;
252
253
254 }
255 }
256 }
257
258 /* (4) reset op buffer on finding a ; */
259 if (ip_buff[1]==';' && fill_op)
260 {
261
262 fill_op=FALSE;
263 opb_count=0;
264 bracket=0;
265 dont_copy_flag=0;
266 start_param_flag=0;
267 }
268
269
270 } while (!feof(in));
271 }
272
273
274
275 void Find_Next_Line(FILE *in)
276 {
277 char c;
278
279 do {
280
281 fread(&c, 1, sizeof(char), in);
282
283 } while ( (c!=10)&&(!feof(in)) );
284
285 }
286
287
288
289 char *External_Prototype(char *string)
290 {
291 char op_s[LINELENGTH],c;
292 int op=0,word_start=0,ip=0,word_count=0;
293
294 /*
295 here's the method :
296 (1) forget functions called main
297 (2) forget 'static' functions
298 (3) prefix all others with 'extern'
299 */
300
301 /* get the first word -> ignore prefix spaces
302 . word end is given by either char <=32 or char = '('
303 */
304
305 /* search all the words until a ( is encountered */
306 do {
307 op=0;
308
309 /* get the next word */
310 while (string[ip]<=32) ip++;
311
312 if (string[ip] !='(')
313 word_start = ip;
314
315 do {
316 c = string[ip++];
317 op_s[op++]=c;
318 } while (c>32 && c!='(');
319
320 op_s[op-1]=0;
321
322 word_count++;
323
324 /* is the first word static ?? */
325 if (strcmp( op_s, "static") ==0 && word_count==1 )
326 {
327 /* modified by par */
328 return "\0";
329 }
330 } while (c!='(');
331
332 /* okay (par) the last word read is the function name */
333 /* is the function name main ?? */
334 if (strcmp( op_s, "main")==0)
335 {
336 return "\0";
337 }
338
339 /* ok. so now ... prefix the original with extern */
340 strcpy(op_s, "extern ");
341 return strcat(op_s,string);
342 }
343
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.