"Fossies" - the Fresh Open Source Software Archive 
Member "cpostp1.c" (9 May 1995, 17644 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 "cpostp1.c" see the
Fossies "Dox" file reference documentation.
1 /*------------------------------------------------------------------
2 * cpostp1.c : Pass 1 of cPost
3 *------------------------------------------------------------------
4 * 12-02-91 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 /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
17
18 /*------------------------------------------------------------------
19 * add bracketing starts in front of braces
20 *------------------------------------------------------------------*/
21 static void AddLBracket(
22 File *file,
23 char *line,
24 char *mask,
25 int *maxMask,
26 Tok *tok
27 )
28 {
29 int lIndent;
30 int rIndent;
31 int place;
32 Tok *sib;
33
34 /*---------------------------------------------------------------
35 * see if matching bracket is on this line - if so, skip
36 *---------------------------------------------------------------*/
37 sib = tok->sib;
38 if (sib && (sib->tok.line == tok->tok.line))
39 return;
40
41 /*---------------------------------------------------------------
42 * find minimum indent of left and right brace
43 *---------------------------------------------------------------*/
44 lIndent = strspn(line," ");
45 if (!tok->sib)
46 place = lIndent;
47 else
48 {
49 rIndent = strspn(file->line[sib->tok.line-1]," ");
50 place = min(lIndent,rIndent);
51 }
52
53 /*---------------------------------------------------------------
54 * if no indentation on { or }, don't bracket!
55 *---------------------------------------------------------------*/
56 if (!place)
57 return;
58
59 /*---------------------------------------------------------------
60 * we'll bracket the column BEFORE this
61 *---------------------------------------------------------------*/
62 place--;
63
64 /*---------------------------------------------------------------
65 * set the mask, maxMask, and write bracket to line
66 *---------------------------------------------------------------*/
67 mask[place]++;
68 *maxMask = max(place,*maxMask);
69
70 if (' ' == line[place])
71 line[place] = '\x01';
72 }
73
74 /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
75 /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
76
77 /*------------------------------------------------------------------
78 * add bracketing ends
79 *------------------------------------------------------------------*/
80 static void AddRBracket(
81 File *file,
82 char *line,
83 char *mask,
84 int *maxMask,
85 Tok *tok
86 )
87 {
88 Tok *sib;
89
90 /*---------------------------------------------------------------
91 * see if matching bracket is on this line - if so, skip
92 *---------------------------------------------------------------*/
93 sib = tok->sib;
94 if (sib && (sib->tok.line == tok->tok.line))
95 return;
96
97 /*---------------------------------------------------------------
98 * safety valve
99 *---------------------------------------------------------------*/
100 if (-1 == *maxMask)
101 return;
102
103 /*---------------------------------------------------------
104 * add end bracket to line
105 *---------------------------------------------------------*/
106 if (' ' == line[*maxMask])
107 line[*maxMask] = '\x03';
108
109 /*---------------------------------------------------------
110 * reset mask and maxMask
111 *---------------------------------------------------------*/
112 mask[*maxMask]--;
113 if (!mask[*maxMask])
114 {
115 *maxMask -= 1;
116 while (-1 != *maxMask)
117 if (mask[*maxMask])
118 break;
119 else
120 *maxMask -= 1;
121 }
122 }
123
124
125 /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
126 /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
127
128 /*------------------------------------------------------------------
129 * add bracketing chars to line based on mask
130 *------------------------------------------------------------------*/
131 static char *AddMBrackets(
132 File *file,
133 char *line,
134 char *mask,
135 int maxMask
136 )
137 {
138 int i;
139
140 /*------------------------------------------------------------
141 * see if we need to make the line longer
142 *------------------------------------------------------------*/
143 if (maxMask + 1 >= (int) strlen(line))
144 {
145 char *newLine;
146
147 newLine = malloc(maxMask+3);
148 if (!newLine)
149 cPostError(1,"out of memory!!!");
150
151 if ('\n' == line[strlen(line)-1])
152 line[strlen(line)-1] = ' ';
153
154 memset(newLine,' ',maxMask+1);
155 newLine[maxMask+1] = '\n';
156 newLine[maxMask+2] = 0;
157 memcpy(newLine,line,strlen(line));
158
159 free(line);
160 line = newLine;
161 }
162
163 /*---------------------------------------------------------------
164 * get number of first non-blank column
165 *---------------------------------------------------------------*/
166 maxMask = min(maxMask,(int)strspn(line," "));
167
168 /*---------------------------------------------------------------
169 * for each non-zero entry in mask, write bracket
170 *---------------------------------------------------------------*/
171 for (i=0; i<=maxMask; i++)
172 {
173 if (mask[i])
174 if (' ' == line[i])
175 line[i] = '\02';
176 }
177
178 return line;
179 }
180
181 /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
182 /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
183
184 /*------------------------------------------------------------------
185 * strip trailing blanks off a line (that has a \n at the end!!)
186 *------------------------------------------------------------------*/
187 static void StripTrailingBlanks(
188 char *line
189 )
190 {
191 int slen;
192
193 slen = strlen(line);
194 if ('\n' != line[slen-1])
195 {
196 fprintf(stderr,"line found without carriage return!!\n");
197 return;
198 }
199
200 line[slen-1] = ' ';
201
202 while (*line && (' ' == line[slen-1]))
203 {
204 line[slen-1] = '\0';
205 slen--;
206 }
207
208 line[slen] = '\n';
209 }
210
211 /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
212 /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
213
214 /*------------------------------------------------------------------
215 * add function information to trees and lists
216 *------------------------------------------------------------------*/
217 static void AddFunctionPrototype(
218 Info *info,
219 File *file,
220 char *name
221 )
222 {
223 Function *func;
224
225 func = GetFunction(info,name);
226
227 if (!ListFind(file->funcProList,&func))
228 if (!ListAdd(file->funcProList,&func))
229 cPostError(1,"error adding function prototype to list");
230 }
231
232 /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
233 /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
234
235 /*------------------------------------------------------------------
236 * add function information to trees and lists
237 *------------------------------------------------------------------*/
238 static void AddFunctionDefinition(
239 Info *info,
240 File *file,
241 char *name,
242 unsigned long lineNo
243 )
244 {
245 Function *func;
246
247 func = GetFunction(info,name);
248 if (!ListFind(file->funcDefList,&func))
249 if (!ListAdd(file->funcDefList,&func))
250 cPostError(1,"error adding function definition to list");
251
252 func->fileName = file->name;
253 func->lineNo = lineNo;
254 }
255
256 /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
257 /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
258
259 /*------------------------------------------------------------------
260 * add function information to trees and lists
261 *------------------------------------------------------------------*/
262 static void AddFunctionUsage(
263 Info *info,
264 char *calleeName,
265 char *callerName
266 )
267 {
268 Function *caller;
269 Function *callee;
270
271 callee = GetFunction(info,calleeName);
272 caller = GetFunction(info,callerName);
273
274 if (!ListFind(caller->callsList, &callee))
275 if (!ListAdd(caller->callsList, &callee))
276 cPostError(1,"error adding function callee to list");
277
278 if (!ListFind(callee->calledByList,&caller))
279 if (!ListAdd(callee->calledByList,&caller))
280 cPostError(1,"error adding function caller to list");
281 }
282
283 /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
284 /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
285
286 /*------------------------------------------------------------------
287 *
288 *------------------------------------------------------------------*/
289 PageEject *addPageEject(
290 File *file,
291 Tok *tok,
292 PageEject *pageJ
293 )
294 {
295 PageEject *new;
296 unsigned long lineNo;
297 char *line;
298
299 /*---------------------------------------------------------------
300 * get space for new node
301 *---------------------------------------------------------------*/
302 new = malloc(sizeof(PageEject));
303 if (!new)
304 cPostError(1,"out of memory!!!");
305
306 /*---------------------------------------------------------------
307 * link into list
308 *---------------------------------------------------------------*/
309 if (!pageJ)
310 file->breakList = new;
311 else
312 pageJ->next = new;
313
314 new->next = NULL;
315 new->lineNo = file->lines;
316
317 /*---------------------------------------------------------------
318 * find first non blank line after token
319 *---------------------------------------------------------------*/
320 lineNo = tok->tok.line;
321 if (lineNo >= file->lines)
322 return new;
323
324 line = file->line[lineNo];
325 while (strspn(line," \n") == strlen(line))
326 {
327 lineNo++;
328 if (lineNo >= file->lines)
329 return new;
330
331 line = file->line[lineNo];
332 }
333
334 new->lineNo = lineNo;
335 return new;
336 }
337
338 /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
339 /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
340
341 /*------------------------------------------------------------------
342 * pass 1 of cPost
343 * - expand tabs, put bracketing around braces, write output files
344 *------------------------------------------------------------------*/
345 int Pass1(
346 File *file,
347 Info *info
348 )
349 {
350 Tok *next;
351 Tok *def;
352 char *mask;
353 char *this;
354 int lineNo;
355 int i;
356 FILE *tempFile;
357 Tok *stack;
358 Tok *temp;
359 int maxMask;
360 int brackLvl;
361 Tok *lastSemi;
362 int doLastSemi;
363 int inFunc;
364 PageEject *pageJ;
365
366 /*---------------------------------------------------------------
367 * print status
368 *---------------------------------------------------------------*/
369 fprintf(stderr," Reading file %s\n",file->name);
370
371 /*---------------------------------------------------------------
372 * parse the file
373 *---------------------------------------------------------------*/
374 info->indent1 = 1;
375
376 cParse(file,info);
377
378 info->indent1 = 0;
379
380 /*---------------------------------------------------------------
381 * go down list, adding function information to function tree,
382 * and computing bracket information
383 *---------------------------------------------------------------*/
384 next = file->tokList;
385 def = NULL;
386 stack = NULL;
387 lastSemi = NULL;
388 pageJ = NULL;
389 brackLvl = 0;
390 inFunc = 0;
391 doLastSemi = 1;
392
393 while (next)
394 {
395 switch(next->extType)
396 {
397 /*---------------------------------------------------------
398 * function stuff
399 *---------------------------------------------------------*/
400 case TOKEN_FUNPRO:
401 AddFunctionPrototype(info,file,next->str);
402 break;
403
404 case TOKEN_FUNDEF:
405 def = next;
406 AddFunctionDefinition(info,file,next->str,next->tok.line);
407 inFunc = 1;
408
409 if (doLastSemi && lastSemi)
410 {
411 pageJ = addPageEject(file,lastSemi,pageJ);
412
413 lastSemi = NULL;
414 doLastSemi = 0;
415 }
416
417 break;
418
419 case TOKEN_FUNUSE:
420 AddFunctionUsage(info,next->str,def ? def->str : "");
421 break;
422
423 /*---------------------------------------------------------
424 * semicolons for page breaks
425 *---------------------------------------------------------*/
426 case TOKEN_SCOLON:
427 case TOKEN_PREPROC:
428 if (doLastSemi)
429 lastSemi = next;
430 break;
431
432 /*---------------------------------------------------------
433 * bracket stuff
434 *---------------------------------------------------------*/
435 case TOKEN_LBRACE:
436 brackLvl++;
437 next->sib = NULL;
438 next->flags = 0;
439
440 /*---------------------------------------------------
441 * put { on the stack
442 *---------------------------------------------------*/
443 next->sib = stack;
444 stack = next;
445 next->flags = 1;
446
447 break;
448
449 case TOKEN_RBRACE:
450 next->sib = NULL;
451 next->flags = 0;
452
453 next->extType = TOKEN_RBRACE;
454
455 /*---------------------------------------------------
456 * remove { from stack, point { to } and } to {
457 *---------------------------------------------------*/
458 if (!stack)
459 fprintf(stderr,"unmatched } on line %ld\n",next->tok.line);
460 else
461 {
462 temp = stack;
463 stack = stack->sib;
464
465 temp->sib = next;
466 next->sib = temp;
467 next->flags = 1;
468 }
469
470 if (brackLvl > 0)
471 brackLvl--;
472
473 /*------------------------------------------------------
474 * add conditional break, if it's time
475 *------------------------------------------------------*/
476 if (inFunc && !brackLvl)
477 {
478 pageJ = addPageEject(file,next,pageJ);
479
480 doLastSemi = 0;
481 }
482
483 break;
484 }
485
486 next = next->next;
487 }
488
489 /*---------------------------------------------------------------
490 * check for extra { on the stack
491 *---------------------------------------------------------------*/
492 while (stack)
493 {
494 fprintf(stderr,"unmatched { on line %ld\n",stack->tok.line);
495 stack = stack->sib;
496 }
497
498 /*---------------------------------------------------------------
499 * now, let's add the bracketing characters
500 *---------------------------------------------------------------*/
501
502 /*---------------------------------------------------------------
503 * initialize mask
504 *---------------------------------------------------------------*/
505 mask = malloc(file->maxLineLen+1);
506 if (!mask)
507 cPostError(1,"out of memory!!!");
508
509 memset(mask,0,file->maxLineLen+1);
510
511 /*---------------------------------------------------------------
512 * process each line
513 *---------------------------------------------------------------*/
514 next = file->tokList;
515 maxMask = -1;
516 for (lineNo=0; lineNo < (int)file->lines; lineNo++)
517 {
518 this = file->line[lineNo];
519
520 /*------------------------------------------------------------
521 * go to next token in this line
522 *------------------------------------------------------------*/
523 while (next && (next->tok.line < (unsigned long)(lineNo + 1)))
524 next = next->next;
525
526 /*------------------------------------------------------------
527 * add beginning and ending brackets
528 *------------------------------------------------------------*/
529 if (info->oBrack)
530 {
531 while (next && (next->tok.line == (unsigned long)(lineNo + 1)))
532 {
533 if ((TOKEN_LBRACE == next->extType) && (next->flags))
534 AddLBracket(file,this,mask,&maxMask,next);
535
536 else if ((TOKEN_RBRACE == next->extType) && (next->flags))
537 AddRBracket(file,this,mask,&maxMask,next);
538
539 next = next->next;
540 }
541 }
542
543 /*------------------------------------------------------------
544 * add middle brackets
545 *------------------------------------------------------------*/
546 file->line[lineNo] = AddMBrackets(file,this,mask,maxMask);
547 }
548
549 /*---------------------------------------------------------------
550 * generate temp file name
551 *---------------------------------------------------------------*/
552 file->tempName = TempFileName(&tempFile,info);
553
554 /*---------------------------------------------------------------
555 * write file to temp file
556 *---------------------------------------------------------------*/
557 for (i=0; i<(int)file->lines; i++)
558 fputs(file->line[i],tempFile);
559
560 fclose(tempFile);
561
562 /*---------------------------------------------------------------
563 * let's clean up all the memory we used
564 *---------------------------------------------------------------*/
565 free(mask);
566
567 /*---------------------------------------------------------------
568 * clean out our data structures
569 *---------------------------------------------------------------*/
570 cParseDone(file,info);
571
572 return 0;
573 }
574