"Fossies" - the Fresh Open Source Software Archive 
Member "cpostpar.c" (9 May 1995, 13681 Bytes) of package /linux/misc/old/cpost.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "cpostpar.c" see the
Fossies "Dox" file reference documentation.
1 /*------------------------------------------------------------------
2 * cPostPar.c : higher level parser for cPost
3 *------------------------------------------------------------------
4 * 03-19-92 originally by Patrick J. Mueller
5 * 12-03-92 converted from cBook to cPost
6 *------------------------------------------------------------------*/
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11
12 #include "ctok.h"
13 #include "cpost.h"
14
15 /*------------------------------------------------------------------
16 * is string a C keyword
17 *------------------------------------------------------------------*/
18 static int IsKeyword(
19 Info *info,
20 char *str
21 )
22 {
23 if (HashFind(info->reservedHash,&str))
24 return 1;
25 else
26 return 0;
27 }
28
29 /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
30 /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
31
32 /*------------------------------------------------------------------
33 * add function information to tokens in list
34 *------------------------------------------------------------------*/
35 static void AddFunctionInfoToTokens(
36 File *file
37 )
38 {
39 Tok *next;
40 Tok *func;
41
42 /*---------------------------------------------------------------
43 * loop through the file
44 *---------------------------------------------------------------*/
45 next = file->tokList;
46 while (NULL != next)
47 {
48 /*------------------------------------------------------------
49 * continue reading till we have an identifier
50 *------------------------------------------------------------*/
51 if (TOKEN_IDENT != next->extType)
52 {
53 next = next->next;
54 continue;
55 }
56
57 /*---------------------------------------------------------
58 * if next token is (, this is a function name!
59 *---------------------------------------------------------*/
60 func = next;
61 next = next->next;
62 if (NULL == next)
63 return;
64
65 while ((TOKEN_COMMENT == next->extType) ||
66 (TOKEN_PREPROC == next->extType))
67 {
68 next = next->next;
69
70 if (NULL == next)
71 return;
72 }
73
74 if (TOKEN_LPAREN == next->extType)
75 {
76
77 /*------------------------------------------------------
78 * if we're in braces, it's usage
79 *------------------------------------------------------*/
80 if (next->nestBrace > 0)
81 func->extType = TOKEN_FUNUSE;
82
83 /*------------------------------------------------------
84 * otherwise it's a prototype or definition
85 *------------------------------------------------------*/
86 else
87 {
88 /*---------------------------------------------------
89 * get to the top level parenthesis
90 *---------------------------------------------------*/
91 while (next->nestParen > 0)
92 {
93 next = next->next;
94 if (NULL == next)
95 return;
96 }
97
98 /*---------------------------------------------------
99 * if next token is ;, it's a prototype, otherwise
100 * it's a definition - we'll assume it's a prototype
101 * though
102 *---------------------------------------------------*/
103 func->extType = TOKEN_FUNPRO;
104
105 next = next->next;
106 if (NULL == next)
107 return;
108
109 while ((TOKEN_COMMENT == next->extType) ||
110 (TOKEN_PREPROC == next->extType))
111 {
112 next = next->next;
113
114 if (NULL == next)
115 return;
116 }
117
118 if (TOKEN_SCOLON == next->extType)
119 func->extType = TOKEN_FUNPRO;
120 else if (TOKEN_COMMA == next->extType)
121 func->extType = TOKEN_FUNPRO;
122 else
123 func->extType = TOKEN_FUNDEF;
124 }
125 }
126 }
127 }
128
129 /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
130 /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
131
132 /*------------------------------------------------------------------
133 * function that walks over hash table - for each thing in hash
134 * table, see if it's a function - if not, release the strings
135 * storage - otherwise add to the info hash table
136 *------------------------------------------------------------------*/
137 static int CleanUpHashTableWalker(
138 char **ident,
139 Info *info
140 )
141 {
142 Function func;
143 Function *found;
144
145 func.name = *ident;
146
147 /*---------------------------------------------------------------
148 * see if it's a function
149 *---------------------------------------------------------------*/
150 found = ListFind(info->funcTree,&func);
151
152 /*---------------------------------------------------------------
153 * if not found, release string storage
154 *---------------------------------------------------------------*/
155 if (!found)
156 {
157 free(*ident);
158 return 0;
159 }
160
161 /*---------------------------------------------------------------
162 * see if it's already in the info hash table
163 *---------------------------------------------------------------*/
164 if (HashFind(info->identHash,ident))
165 {
166 free(*ident);
167 return 0;
168 }
169
170 /*---------------------------------------------------------------
171 * if not, add it
172 *---------------------------------------------------------------*/
173 if (!HashAdd(info->identHash,ident))
174 cPostError(1,"error adding identifier to global hash table");
175
176 return 0;
177 }
178
179 /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
180 /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
181
182 /*------------------------------------------------------------------
183 * parse the file for functions
184 *------------------------------------------------------------------*/
185 void cParse(
186 File *file,
187 Info *info
188 )
189 {
190 void *hTokenizer;
191 Tok *next;
192 Tok *prev;
193 Tok *fnc;
194 static char tmpIdent [MAX_IDENT_LEN + 1];
195 char *ptmpIdent = tmpIdent;
196 char **pptmpIdent = &ptmpIdent;
197 char **tempStr;
198
199 /*---------------------------------------------------------------
200 * read the file
201 *---------------------------------------------------------------*/
202 if (NULL == FileReadLines(info,file))
203 cPostError(1,"unable to read file");
204
205 file->identHash = HashCreate(sizeof(char *),
206 1000,
207 (HashFunc *)IdentHash,
208 (ListCompareFunc *)IdentCompare,
209 cPostNoMem);
210 if (!file->identHash)
211 cPostError(1,"error creating hash table");
212
213 /*------------------------------------------------------------
214 * initialize tokenization
215 *------------------------------------------------------------*/
216 hTokenizer = CTokInit(GetBlockOfFile,file);
217 if (!hTokenizer)
218 cPostError(1,"error initializing tokenization");
219
220 file->tokList = NULL;
221 next = malloc(sizeof(Tok));
222 if (!next)
223 cPostError(1,"out of memory!!!");
224
225 next->next = NULL;
226 next->nestParen = 0;
227 next->nestBrace = 0;
228 next->str = NULL;
229
230 prev = NULL;
231
232 fnc = NULL;
233
234 /*------------------------------------------------------------
235 * build list of tokens
236 *------------------------------------------------------------*/
237 CTokGet(hTokenizer,&(next->tok));
238 while (TOKEN_EOF != next->tok.type)
239 {
240
241 /*------------------------------------------------------------
242 * get a little more info
243 *------------------------------------------------------------*/
244 next->extType = next->tok.type;
245
246 if (TOKEN_OPER == next->extType)
247 {
248 switch(next->tok.ident[0])
249 {
250 case '{':
251 next->extType = TOKEN_LBRACE;
252 next->nestBrace++;
253
254 if (next->nestParen)
255 {
256 fprintf(stderr,"unmatched ( on or before "
257 "line %ld\n",next->tok.line);
258 next->nestParen = 0;
259 }
260 break;
261
262 case '}':
263 next->extType = TOKEN_RBRACE;
264 next->nestBrace--;
265
266 if (next->nestParen)
267 {
268 fprintf(stderr,"unmatched ( on or before "
269 "line %ld\n",next->tok.line);
270 next->nestParen = 0;
271 }
272 break;
273
274 case '(':
275 next->extType = TOKEN_LPAREN;
276 next->nestParen++;
277
278 /*---------------------------------------------------
279 * add the identifier before this, if there was one
280 *---------------------------------------------------*/
281 if (!fnc)
282 break;
283
284 /*------------------------------------------------------
285 * get string from hash or add it
286 *------------------------------------------------------*/
287 tempStr = HashFind(file->identHash,pptmpIdent);
288 if (tempStr)
289 fnc->str = *tempStr;
290 else
291 {
292 fnc->str = malloc(1+strlen(tmpIdent));
293 if (!fnc->str)
294 cPostError(1,"out of memory!!!");
295
296 strcpy(fnc->str,tmpIdent);
297 if (!HashAdd(file->identHash,&(fnc->str)))
298 cPostError(1,"error adding identifier to file hash table");
299 }
300
301 fnc = NULL;
302 break;
303
304 case ')':
305 next->extType = TOKEN_RPAREN;
306
307 if (next->nestParen)
308 next->nestParen--;
309 else
310 {
311 fprintf(stderr,"unnested ) on "
312 "line %ld\n",next->tok.line);
313 next->nestParen = 0;
314 }
315
316 break;
317
318 case ';':
319 next->extType = TOKEN_SCOLON;
320 break;
321
322 case ',':
323 next->extType = TOKEN_COMMA;
324 break;
325 }
326 }
327
328 else if (TOKEN_IDENT == next->extType)
329 {
330
331 if (IsKeyword(info,next->tok.ident))
332 next->extType = TOKEN_RESER;
333 else
334 {
335 strcpy(tmpIdent,next->tok.ident);
336 fnc = next;
337 }
338 }
339
340 /*------------------------------------------------------------
341 * link into list
342 *------------------------------------------------------------*/
343 if (NULL == file->tokList)
344 file->tokList = next;
345 else
346 prev->next = next;
347
348 /*------------------------------------------------------------
349 * get next token
350 *------------------------------------------------------------*/
351 prev = next;
352 next = malloc(sizeof(Tok));
353 if (!next)
354 cPostError(1,"out of memory!!!");
355
356 next->next = NULL;
357 next->nestParen = prev->nestParen;
358 next->nestBrace = prev->nestBrace;
359 next->str = NULL;
360
361 CTokGet(hTokenizer,&(next->tok));
362 }
363
364 /*---------------------------------------------------------------
365 * free the last hanging token
366 *---------------------------------------------------------------*/
367 free(next);
368
369 /*------------------------------------------------------------
370 * terminate tokenization
371 *------------------------------------------------------------*/
372 CTokTerm(hTokenizer);
373
374 /*---------------------------------------------------------------
375 * analyze the tokens
376 *---------------------------------------------------------------*/
377 AddFunctionInfoToTokens(file);
378 }
379
380 /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
381 /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
382
383 /*------------------------------------------------------------------
384 * clean up after parsing file for functions
385 *------------------------------------------------------------------*/
386 void cParseDone(
387 File *file,
388 Info *info
389 )
390 {
391 Tok *tok;
392 Tok *next;
393 int i;
394
395 /*---------------------------------------------------------------
396 * walk over old hash table, adding functions to info hash table
397 * and freeing non-function strings
398 *---------------------------------------------------------------*/
399 HashIterate(file->identHash,(ListIterateFunc *)CleanUpHashTableWalker,info);
400
401 /*---------------------------------------------------------------
402 * destroy the file hash table
403 *---------------------------------------------------------------*/
404 HashDestroy(file->identHash);
405
406 /*---------------------------------------------------------------
407 * now clean up token list
408 *---------------------------------------------------------------*/
409 tok = file->tokList;
410
411 /*---------------------------------------------------------------
412 * loop through tokens and free 'um
413 *---------------------------------------------------------------*/
414 while (tok)
415 {
416 next = tok->next;
417 free(tok);
418 tok = next;
419 }
420
421 /*---------------------------------------------------------------
422 * release file storage
423 *---------------------------------------------------------------*/
424 for (i=0; i<(int)file->lines; i++)
425 free(file->line[i]);
426
427 free(file->line);
428 }