1 #ifndef CLexer_h
#define CLexer_h
/*
* D L G L e x e r C l a s s D e f i n i t i o n
*
* Generated from: parser.dlg
*
* 1989-1999 by Will Cohen, Terence Parr, and Hank Dietz
* Purdue University Electrical Engineering
* DLG Version 1.33MR20
*/
#include "DLexerBase.h"
16 class CLexer : public DLGLexerBase {
public:
public:
static const int MAX_MODE;
static const int DfaStates;
static const int START;
static const int PREPROC;
static const int RR;
static const int COMMENT_LINE;
static const int COMMENT_MULTI;
static const int CONST_STRING;
static const int CONST_CHAR;
typedef unsigned short DfaState;
30 CLexer( DLGInputStream *in,
31 unsigned bufsize=2000 )
: DLGLexerBase( in, bufsize, 0 )
{
;
}
36 void mode( int );
37 ANTLRTokenType nextTokenType( void );
38 void advance( void );
protected:
40 ANTLRTokenType act1( );
41 ANTLRTokenType act2( );
42 ANTLRTokenType act3( );
43 ANTLRTokenType act4( );
44 ANTLRTokenType act5( );
45 ANTLRTokenType act6( );
46 ANTLRTokenType act7( );
47 ANTLRTokenType act8( );
48 ANTLRTokenType act9( );
49 ANTLRTokenType act10( );
50 ANTLRTokenType act11( );
51 ANTLRTokenType act12( );
52 ANTLRTokenType act13( );
53 ANTLRTokenType act14( );
54 ANTLRTokenType act15( );
55 ANTLRTokenType act16( );
56 ANTLRTokenType act17( );
57 ANTLRTokenType act18( );
58 ANTLRTokenType act19( );
59 ANTLRTokenType act20( );
60 ANTLRTokenType act21( );
61 ANTLRTokenType act22( );
62 ANTLRTokenType act23( );
63 ANTLRTokenType act24( );
64 ANTLRTokenType act25( );
65 ANTLRTokenType act26( );
66 ANTLRTokenType act27( );
67 ANTLRTokenType act28( );
68 ANTLRTokenType act29( );
69 ANTLRTokenType act30( );
70 ANTLRTokenType act31( );
71 ANTLRTokenType act32( );
72 ANTLRTokenType act33( );
73 ANTLRTokenType act34( );
74 ANTLRTokenType act35( );
75 ANTLRTokenType act36( );
76 ANTLRTokenType act37( );
77 ANTLRTokenType act38( );
78 ANTLRTokenType act39( );
79 ANTLRTokenType act40( );
80 ANTLRTokenType act41( );
81 ANTLRTokenType act42( );
82 ANTLRTokenType act43( );
83 ANTLRTokenType act44( );
84 ANTLRTokenType act45( );
85 ANTLRTokenType act46( );
86 ANTLRTokenType act47( );
87 ANTLRTokenType act48( );
88 ANTLRTokenType act49( );
89 ANTLRTokenType act50( );
90 ANTLRTokenType act51( );
91 ANTLRTokenType act52( );
92 ANTLRTokenType act53( );
93 ANTLRTokenType act54( );
94 ANTLRTokenType act55( );
95 ANTLRTokenType act56( );
96 ANTLRTokenType act57( );
97 ANTLRTokenType act58( );
98 ANTLRTokenType act59( );
99 ANTLRTokenType act60( );
100 ANTLRTokenType act61( );
101 ANTLRTokenType act62( );
102 ANTLRTokenType act63( );
103 ANTLRTokenType act64( );
104 ANTLRTokenType act65( );
105 ANTLRTokenType act66( );
106 ANTLRTokenType act67( );
107 ANTLRTokenType act68( );
108 ANTLRTokenType act69( );
109 ANTLRTokenType act70( );
110 ANTLRTokenType act71( );
111 ANTLRTokenType act72( );
112 ANTLRTokenType act73( );
113 ANTLRTokenType act74( );
114 ANTLRTokenType act75( );
115 ANTLRTokenType act76( );
116 ANTLRTokenType act77( );
117 ANTLRTokenType act78( );
118 ANTLRTokenType act79( );
119 ANTLRTokenType act80( );
120 ANTLRTokenType act81( );
121 ANTLRTokenType act82( );
122 ANTLRTokenType act83( );
123 ANTLRTokenType act84( );
124 ANTLRTokenType act85( );
125 ANTLRTokenType act86( );
126 ANTLRTokenType act87( );
127 ANTLRTokenType act88( );
128 ANTLRTokenType act89( );
129 ANTLRTokenType act90( );
130 ANTLRTokenType act91( );
131 ANTLRTokenType act92( );
132 ANTLRTokenType act93( );
133 ANTLRTokenType act94( );
134 ANTLRTokenType act95( );
135 ANTLRTokenType act96( );
136 ANTLRTokenType act97( );
137 ANTLRTokenType act98( );
138 ANTLRTokenType act99( );
139 ANTLRTokenType act100( );
140 ANTLRTokenType act101( );
141 ANTLRTokenType act102( );
142 ANTLRTokenType act103( );
143 ANTLRTokenType act104( );
144 ANTLRTokenType act105( );
145 ANTLRTokenType act106( );
146 ANTLRTokenType act107( );
147 ANTLRTokenType act108( );
148 ANTLRTokenType act109( );
149 ANTLRTokenType act110( );
150 ANTLRTokenType act111( );
151 ANTLRTokenType act112( );
152 ANTLRTokenType act113( );
153 ANTLRTokenType act114( );
154 ANTLRTokenType act115( );
155 ANTLRTokenType act116( );
156 ANTLRTokenType act117( );
157 ANTLRTokenType act118( );
158 ANTLRTokenType act119( );
159 ANTLRTokenType act120( );
160 ANTLRTokenType act121( );
161 ANTLRTokenType act122( );
162 ANTLRTokenType act123( );
163 ANTLRTokenType act124( );
164 ANTLRTokenType act125( );
165 ANTLRTokenType act126( );
166 ANTLRTokenType act127( );
167 ANTLRTokenType act128( );
168 ANTLRTokenType act129( );
169 ANTLRTokenType act130( );
170 ANTLRTokenType act131( );
171 ANTLRTokenType act132( );
172 ANTLRTokenType act133( );
173 ANTLRTokenType act134( );
174 ANTLRTokenType act135( );
175 ANTLRTokenType act136( );
176 ANTLRTokenType act137( );
177 ANTLRTokenType act138( );
178 ANTLRTokenType act139( );
179 ANTLRTokenType act140( );
180 ANTLRTokenType act141( );
181 ANTLRTokenType act142( );
182 ANTLRTokenType act143( );
183 ANTLRTokenType act144( );
184 ANTLRTokenType act145( );
185 ANTLRTokenType act146( );
186 ANTLRTokenType act147( );
187 ANTLRTokenType act148( );
188 ANTLRTokenType act149( );
189 ANTLRTokenType act150( );
190 ANTLRTokenType act151( );
191 ANTLRTokenType act152( );
192 ANTLRTokenType act153( );
193 ANTLRTokenType act154( );
194 ANTLRTokenType act155( );
195 ANTLRTokenType act156( );
196 ANTLRTokenType act157( );
197 ANTLRTokenType act158( );
198 ANTLRTokenType act159( );
199 ANTLRTokenType act160( );
200 ANTLRTokenType act161( );
201 ANTLRTokenType act162( );
202 ANTLRTokenType act163( );
203 ANTLRTokenType act164( );
204 static DfaState st0[67];
205 static DfaState st1[67];
206 static DfaState st2[67];
207 static DfaState st3[67];
208 static DfaState st4[67];
209 static DfaState st5[67];
210 static DfaState st6[67];
211 static DfaState st7[67];
212 static DfaState st8[67];
213 static DfaState st9[67];
214 static DfaState st10[67];
215 static DfaState st11[67];
216 static DfaState st12[67];
217 static DfaState st13[67];
218 static DfaState st14[67];
219 static DfaState st15[67];
220 static DfaState st16[67];
221 static DfaState st17[67];
222 static DfaState st18[67];
223 static DfaState st19[67];
224 static DfaState st20[67];
225 static DfaState st21[67];
226 static DfaState st22[67];
227 static DfaState st23[67];
228 static DfaState st24[67];
229 static DfaState st25[67];
230 static DfaState st26[67];
231 static DfaState st27[67];
232 static DfaState st28[67];
233 static DfaState st29[67];
234 static DfaState st30[67];
235 static DfaState st31[67];
236 static DfaState st32[67];
237 static DfaState st33[67];
238 static DfaState st34[67];
239 static DfaState st35[67];
240 static DfaState st36[67];
241 static DfaState st37[67];
242 static DfaState st38[67];
243 static DfaState st39[67];
244 static DfaState st40[67];
245 static DfaState st41[67];
246 static DfaState st42[67];
247 static DfaState st43[67];
248 static DfaState st44[67];
249 static DfaState st45[67];
250 static DfaState st46[67];
251 static DfaState st47[67];
252 static DfaState st48[67];
253 static DfaState st49[67];
254 static DfaState st50[67];
255 static DfaState st51[67];
256 static DfaState st52[67];
257 static DfaState st53[67];
258 static DfaState st54[67];
259 static DfaState st55[67];
260 static DfaState st56[67];
261 static DfaState st57[67];
262 static DfaState st58[67];
263 static DfaState st59[67];
264 static DfaState st60[67];
265 static DfaState st61[67];
266 static DfaState st62[67];
267 static DfaState st63[67];
268 static DfaState st64[67];
269 static DfaState st65[67];
270 static DfaState st66[67];
271 static DfaState st67[67];
272 static DfaState st68[67];
273 static DfaState st69[67];
274 static DfaState st70[67];
275 static DfaState st71[67];
276 static DfaState st72[67];
277 static DfaState st73[67];
278 static DfaState st74[67];
279 static DfaState st75[67];
280 static DfaState st76[67];
281 static DfaState st77[67];
282 static DfaState st78[67];
283 static DfaState st79[67];
284 static DfaState st80[67];
285 static DfaState st81[67];
286 static DfaState st82[67];
287 static DfaState st83[67];
288 static DfaState st84[67];
289 static DfaState st85[67];
290 static DfaState st86[67];
291 static DfaState st87[67];
292 static DfaState st88[67];
293 static DfaState st89[67];
294 static DfaState st90[67];
295 static DfaState st91[67];
296 static DfaState st92[67];
297 static DfaState st93[67];
298 static DfaState st94[67];
299 static DfaState st95[67];
300 static DfaState st96[67];
301 static DfaState st97[67];
302 static DfaState st98[67];
303 static DfaState st99[67];
304 static DfaState st100[67];
305 static DfaState st101[67];
306 static DfaState st102[67];
307 static DfaState st103[67];
308 static DfaState st104[67];
309 static DfaState st105[67];
310 static DfaState st106[67];
311 static DfaState st107[67];
312 static DfaState st108[67];
313 static DfaState st109[67];
314 static DfaState st110[67];
315 static DfaState st111[67];
316 static DfaState st112[67];
317 static DfaState st113[67];
318 static DfaState st114[67];
319 static DfaState st115[67];
320 static DfaState st116[67];
321 static DfaState st117[67];
322 static DfaState st118[67];
323 static DfaState st119[67];
324 static DfaState st120[67];
325 static DfaState st121[67];
326 static DfaState st122[67];
327 static DfaState st123[67];
328 static DfaState st124[67];
329 static DfaState st125[67];
330 static DfaState st126[67];
331 static DfaState st127[67];
332 static DfaState st128[67];
333 static DfaState st129[67];
334 static DfaState st130[67];
335 static DfaState st131[67];
336 static DfaState st132[67];
337 static DfaState st133[67];
338 static DfaState st134[67];
339 static DfaState st135[67];
340 static DfaState st136[67];
341 static DfaState st137[67];
342 static DfaState st138[67];
343 static DfaState st139[67];
344 static DfaState st140[67];
345 static DfaState st141[67];
346 static DfaState st142[67];
347 static DfaState st143[67];
348 static DfaState st144[67];
349 static DfaState st145[67];
350 static DfaState st146[67];
351 static DfaState st147[67];
352 static DfaState st148[67];
353 static DfaState st149[67];
354 static DfaState st150[67];
355 static DfaState st151[67];
356 static DfaState st152[67];
357 static DfaState st153[67];
358 static DfaState st154[67];
359 static DfaState st155[67];
360 static DfaState st156[67];
361 static DfaState st157[67];
362 static DfaState st158[67];
363 static DfaState st159[67];
364 static DfaState st160[67];
365 static DfaState st161[67];
366 static DfaState st162[67];
367 static DfaState st163[67];
368 static DfaState st164[67];
369 static DfaState st165[67];
370 static DfaState st166[67];
371 static DfaState st167[67];
372 static DfaState st168[67];
373 static DfaState st169[67];
374 static DfaState st170[67];
375 static DfaState st171[67];
376 static DfaState st172[67];
377 static DfaState st173[67];
378 static DfaState st174[67];
379 static DfaState st175[67];
380 static DfaState st176[67];
381 static DfaState st177[67];
382 static DfaState st178[67];
383 static DfaState st179[67];
384 static DfaState st180[67];
385 static DfaState st181[67];
386 static DfaState st182[67];
387 static DfaState st183[67];
388 static DfaState st184[67];
389 static DfaState st185[67];
390 static DfaState st186[67];
391 static DfaState st187[67];
392 static DfaState st188[67];
393 static DfaState st189[67];
394 static DfaState st190[67];
395 static DfaState st191[67];
396 static DfaState st192[67];
397 static DfaState st193[67];
398 static DfaState st194[67];
399 static DfaState st195[67];
400 static DfaState st196[67];
401 static DfaState st197[67];
402 static DfaState st198[67];
403 static DfaState st199[67];
404 static DfaState st200[67];
405 static DfaState st201[67];
406 static DfaState st202[67];
407 static DfaState st203[67];
408 static DfaState st204[67];
409 static DfaState st205[67];
410 static DfaState st206[67];
411 static DfaState st207[67];
412 static DfaState st208[67];
413 static DfaState st209[67];
414 static DfaState st210[67];
415 static DfaState st211[67];
416 static DfaState st212[67];
417 static DfaState st213[67];
418 static DfaState st214[67];
419 static DfaState st215[67];
420 static DfaState st216[67];
421 static DfaState st217[67];
422 static DfaState st218[67];
423 static DfaState st219[67];
424 static DfaState st220[67];
425 static DfaState st221[67];
426 static DfaState st222[67];
427 static DfaState st223[67];
428 static DfaState st224[67];
429 static DfaState st225[67];
430 static DfaState st226[67];
431 static DfaState st227[67];
432 static DfaState st228[67];
433 static DfaState st229[67];
434 static DfaState st230[67];
435 static DfaState st231[67];
436 static DfaState st232[67];
437 static DfaState st233[67];
438 static DfaState st234[67];
439 static DfaState st235[67];
440 static DfaState st236[67];
441 static DfaState st237[67];
442 static DfaState st238[67];
443 static DfaState st239[67];
444 static DfaState st240[67];
445 static DfaState st241[67];
446 static DfaState st242[67];
447 static DfaState st243[67];
448 static DfaState st244[67];
449 static DfaState st245[67];
450 static DfaState st246[67];
451 static DfaState st247[67];
452 static DfaState st248[67];
453 static DfaState st249[67];
454 static DfaState st250[67];
455 static DfaState st251[67];
456 static DfaState st252[67];
457 static DfaState st253[67];
458 static DfaState st254[67];
459 static DfaState st255[67];
460 static DfaState st256[67];
461 static DfaState st257[67];
462 static DfaState st258[67];
463 static DfaState st259[67];
464 static DfaState st260[67];
465 static DfaState st261[67];
466 static DfaState st262[67];
467 static DfaState st263[67];
468 static DfaState st264[67];
469 static DfaState st265[67];
470 static DfaState st266[67];
471 static DfaState st267[67];
472 static DfaState st268[67];
473 static DfaState st269[67];
474 static DfaState st270[67];
475 static DfaState st271[67];
476 static DfaState st272[67];
477 static DfaState st273[67];
478 static DfaState st274[67];
479 static DfaState st275[67];
480 static DfaState st276[67];
481 static DfaState st277[67];
482 static DfaState st278[67];
483 static DfaState st279[67];
484 static DfaState st280[67];
485 static DfaState st281[67];
486 static DfaState st282[67];
487 static DfaState st283[67];
488 static DfaState st284[67];
489 static DfaState st285[67];
490 static DfaState st286[67];
491 static DfaState st287[67];
492 static DfaState st288[67];
493 static DfaState st289[67];
494 static DfaState st290[67];
495 static DfaState st291[67];
496 static DfaState st292[67];
497 static DfaState st293[67];
498 static DfaState st294[67];
499 static DfaState st295[67];
500 static DfaState st296[67];
501 static DfaState st297[67];
502 static DfaState st298[67];
503 static DfaState st299[67];
504 static DfaState st300[67];
505 static DfaState st301[67];
506 static DfaState st302[67];
507 static DfaState st303[67];
508 static DfaState st304[67];
509 static DfaState st305[67];
510 static DfaState st306[67];
511 static DfaState st307[67];
512 static DfaState st308[67];
513 static DfaState st309[67];
514 static DfaState st310[67];
515 static DfaState st311[67];
516 static DfaState st312[67];
517 static DfaState st313[67];
518 static DfaState st314[67];
519 static DfaState st315[67];
520 static DfaState st316[67];
521 static DfaState st317[67];
522 static DfaState st318[67];
523 static DfaState st319[67];
524 static DfaState st320[67];
525 static DfaState st321[67];
526 static DfaState st322[67];
527 static DfaState st323[67];
528 static DfaState st324[67];
529 static DfaState st325[67];
530 static DfaState st326[67];
531 static DfaState st327[67];
532 static DfaState st328[67];
533 static DfaState st329[67];
534 static DfaState st330[67];
535 static DfaState st331[67];
536 static DfaState st332[67];
537 static DfaState st333[67];
538 static DfaState st334[67];
539 static DfaState st335[67];
540 static DfaState st336[67];
541 static DfaState st337[67];
542 static DfaState st338[67];
543 static DfaState st339[67];
544 static DfaState st340[67];
545 static DfaState st341[67];
546 static DfaState st342[67];
547 static DfaState st343[67];
548 static DfaState st344[67];
549 static DfaState st345[67];
550 static DfaState st346[67];
551 static DfaState st347[67];
552 static DfaState st348[67];
553 static DfaState st349[67];
554 static DfaState st350[67];
555 static DfaState st351[67];
556 static DfaState st352[67];
557 static DfaState st353[67];
558 static DfaState st354[67];
559 static DfaState st355[67];
560 static DfaState st356[67];
561 static DfaState st357[67];
562 static DfaState st358[67];
563 static DfaState st359[67];
564 static DfaState st360[67];
565 static DfaState st361[67];
566 static DfaState st362[67];
567 static DfaState st363[67];
568 static DfaState st364[67];
569 static DfaState st365[67];
570 static DfaState st366[67];
571 static DfaState st367[67];
572 static DfaState st368[67];
573 static DfaState st369[67];
574 static DfaState st370[67];
575 static DfaState st371[67];
576 static DfaState st372[67];
577 static DfaState st373[67];
578 static DfaState st374[67];
579 static DfaState st375[67];
580 static DfaState st376[67];
581 static DfaState st377[67];
582 static DfaState st378[67];
583 static DfaState st379[67];
584 static DfaState st380[67];
585 static DfaState st381[67];
586 static DfaState st382[67];
587 static DfaState st383[67];
588 static DfaState st384[67];
589 static DfaState st385[67];
590 static DfaState st386[67];
591 static DfaState st387[67];
592 static DfaState st388[67];
593 static DfaState st389[67];
594 static DfaState st390[67];
595 static DfaState st391[67];
596 static DfaState st392[67];
597 static DfaState st393[67];
598 static DfaState st394[67];
599 static DfaState st395[67];
600 static DfaState st396[67];
601 static DfaState st397[67];
602 static DfaState st398[67];
603 static DfaState st399[67];
604 static DfaState st400[67];
605 static DfaState st401[67];
606 static DfaState st402[67];
607 static DfaState st403[67];
608 static DfaState st404[67];
609 static DfaState st405[67];
610 static DfaState st406[8];
611 static DfaState st407[8];
612 static DfaState st408[8];
613 static DfaState st409[8];
614 static DfaState st410[8];
615 static DfaState st411[8];
616 static DfaState st412[8];
617 static DfaState st413[8];
618 static DfaState st414[8];
619 static DfaState st415[8];
620 static DfaState st416[4];
621 static DfaState st417[4];
622 static DfaState st418[4];
623 static DfaState st419[4];
624 static DfaState st420[4];
625 static DfaState st421[4];
626 static DfaState st422[4];
627 static DfaState st423[4];
628 static DfaState st424[6];
629 static DfaState st425[6];
630 static DfaState st426[6];
631 static DfaState st427[6];
632 static DfaState st428[6];
633 static DfaState st429[6];
634 static DfaState st430[6];
635 static DfaState st431[6];
636 static DfaState st432[6];
637 static DfaState st433[6];
638 static DfaState st434[6];
639 static DfaState st435[6];
640 static DfaState st436[6];
641 static DfaState st437[6];
642 static DfaState st438[4];
643 static DfaState st439[4];
644 static DfaState st440[4];
645 static DfaState st441[4];
646 static DfaState *dfa[442];
647 static DfaState dfa_base[];
static unsigned char *b_class_no[];
649 static DfaState accepts[443];
650 static DLGChar alternatives[443];
static ANTLRTokenType ( CLexer::*actions[165] )( );
static unsigned char shift0[257];
static unsigned char shift1[257];
static unsigned char shift2[257];
static unsigned char shift3[257];
static unsigned char shift4[257];
static unsigned char shift5[257];
static unsigned char shift6[257];
int ZZSHIFT( int c ) { return b_class_no[automaton][1+c]; }
//
// 133MR1 Deprecated feature to allow inclusion of user-defined code in DLG class header
//
#ifdef DLGLexerIncludeFile
#include DLGLexerIncludeFile
#endif
};
typedef ANTLRTokenType ( CLexer::*PtrCLexerMemberFunc )( );
#endif
1 /*
* CParser: P a r s e r H e a d e r
*
* Generated from: cccc.g
*
* Terence Parr, Russell Quong, Will Cohen, and Hank Dietz: 1989-1999
* Parr Research Corporation
* with Purdue University Electrical Engineering
* with AHPCRC, University of Minnesota
* ANTLR Version 1.33MR20
*/
#ifndef CParser_h
#define CParser_h
#ifndef ANTLR_VERSION
#define ANTLR_VERSION 13320
#endif
#ifndef zzTRACE_RULES
#define zzTRACE_RULES
#endif
#include "AParser.h"
#define zzTRACE_RULES
#include "AParser.h"
#include "cccc.h"
#include "cccc_utl.h"
#include "cccc_opt.h"
// the objects which PCCTS creates for ASTs as the #0 variable etc
// have type "pointer to ASTBase", which means they need to be cast
// to a pointer to my variant of AST if I want to call my AST
// methods on them
#define MY_AST( X ) ( ( AST* ) X )
// we have a global variable member for the language of the parse so
// that we can supply the names of dialects ( ansi_c, ansi_c++, mfc_c++ etc )
// for contexts where we wish to apply dialect-specific lexing or parsing
// rules
extern string parse_language;
43 class CParser : public ANTLRParser {
public:
45 static const ANTLRChar *tokenName( int tk );
protected:
47 static const ANTLRChar *_token_tbl[];
private:
51 ParseStore* ps;
52 ParseUtility* pu;
54 void tracein( const char *rulename ) { pu->tracein( rulename, guessing, LT( 1 ) ); }
55 void traceout( const char *rulename ) { pu->traceout( rulename, guessing, LT( 1 ) ); }
56 void syn(
57 _ANTLRTokenPtr tok, ANTLRChar *egroup, SetWordType *eset,
ANTLRTokenType etok, int k )
{
pu->syn( tok, egroup, eset, etok, k );
}
63 string typeCombine( const string& modifiers, const string& name, const string& indir )
{
string retval;
if( modifiers.size( )>0 )
{
retval=modifiers+" "+name;
}
else
{
retval=name;
}
if( indir.size( )>0 )
{
retval+=" ";
retval+=indir;
}
return retval;
}
// Many of the rules below accept string parameters to
// allow upward passing of attributes.
// Where the calling context does not need to receive
// the attributes, it can use the dummy values defined
// here to save allocating a string locally to satisfy the
// parameter list.
88 string d1, d2, d3;
public:
92 void init( const string& filename, const string& language )
{
pu=ParseUtility::currentInstance( );
ps=ParseStore::currentInstance( );
ANTLRParser::init( );
parse_language=language;
}
protected:
103 static SetWordType err1[36];
104 static SetWordType err2[36];
105 static SetWordType err3[36];
106 static SetWordType setwd1[276];
107 static SetWordType setwd2[276];
108 static SetWordType err4[36];
109 static SetWordType err5[36];
110 static SetWordType err6[36];
111 static SetWordType setwd3[276];
112 static SetWordType err7[36];
113 static SetWordType err8[36];
114 static SetWordType setwd4[276];
115 static SetWordType err9[36];
116 static SetWordType err10[36];
117 static SetWordType err11[36];
118 static SetWordType err12[36];
119 static SetWordType setwd5[276];
120 static SetWordType err13[36];
121 static SetWordType err14[36];
122 static SetWordType setwd6[276];
123 static SetWordType err15[36];
124 static SetWordType err16[36];
125 static SetWordType err17[36];
126 static SetWordType err18[36];
127 static SetWordType setwd7[276];
128 static SetWordType err19[36];
129 static SetWordType err20[36];
130 static SetWordType setwd8[276];
131 static SetWordType err21[36];
132 static SetWordType err22[36];
133 static SetWordType err23[36];
134 static SetWordType err24[36];
135 static SetWordType setwd9[276];
136 static SetWordType err25[36];
137 static SetWordType err26[36];
138 static SetWordType setwd10[276];
139 static SetWordType err27[36];
140 static SetWordType err28[36];
141 static SetWordType setwd11[276];
142 static SetWordType err29[36];
143 static SetWordType err30[36];
144 static SetWordType err31[36];
145 static SetWordType err32[36];
146 static SetWordType err33[36];
147 static SetWordType setwd12[276];
148 static SetWordType err34[36];
149 static SetWordType err35[36];
150 static SetWordType err36[36];
151 static SetWordType setwd13[276];
152 static SetWordType err37[36];
153 static SetWordType err38[36];
154 static SetWordType err39[36];
155 static SetWordType setwd14[276];
156 static SetWordType err40[36];
157 static SetWordType err41[36];
158 static SetWordType setwd15[276];
159 static SetWordType err42[36];
160 static SetWordType err43[36];
161 static SetWordType setwd16[276];
162 static SetWordType err44[36];
163 static SetWordType err45[36];
164 static SetWordType setwd17[276];
165 static SetWordType err46[36];
166 static SetWordType err47[36];
167 static SetWordType err48[36];
168 static SetWordType setwd18[276];
169 static SetWordType err49[36];
170 static SetWordType err50[36];
171 static SetWordType err51[36];
172 static SetWordType err52[36];
173 static SetWordType setwd19[276];
174 static SetWordType err53[36];
175 static SetWordType err54[36];
176 static SetWordType err55[36];
177 static SetWordType err56[36];
178 static SetWordType setwd20[276];
179 static SetWordType err57[36];
180 static SetWordType err58[36];
181 static SetWordType err59[36];
182 static SetWordType err60[36];
183 static SetWordType setwd21[276];
184 static SetWordType err61[36];
185 static SetWordType err62[36];
186 static SetWordType err63[36];
187 static SetWordType err64[36];
188 static SetWordType err65[36];
189 static SetWordType setwd22[276];
190 static SetWordType EQUAL_OP_set[36];
191 static SetWordType OP_ASSIGN_OP_set[36];
192 static SetWordType SHIFT_OP_set[36];
193 static SetWordType REL_OP_set[36];
194 static SetWordType DIV_OP_set[36];
195 static SetWordType PM_OP_set[36];
196 static SetWordType INCR_OP_set[36];
197 static SetWordType setwd23[276];
198 static SetWordType ADD_OP_set[36];
199 static SetWordType BITWISE_OP_set[36];
200 static SetWordType err75[36];
201 static SetWordType err76[36];
202 static SetWordType err77[36];
203 static SetWordType err78[36];
204 static SetWordType err79[36];
205 static SetWordType setwd24[276];
206 static SetWordType err80[36];
207 static SetWordType err81[36];
208 static SetWordType err82[36];
209 static SetWordType setwd25[276];
210 static SetWordType err83[36];
211 static SetWordType WildCard_set[36];
212 static SetWordType setwd26[276];
213 static SetWordType err85[36];
214 static SetWordType err86[36];
215 static SetWordType err87[36];
216 static SetWordType setwd27[276];
217 static SetWordType err88[36];
218 static SetWordType err89[36];
219 static SetWordType err90[36];
220 static SetWordType setwd28[276];
private:
222 void zzdflthandlers( int _signal, int *_retsignal );
public:
225 CParser( ANTLRTokenBuffer *input );
226 void start( void );
227 void link_item( string& scope );
228 void end_of_file( void );
229 void definition_or_declaration( string& scope );
230 void resync_tokens( void );
231 void extern_linkage_block( void );
232 void namespace_block( void );
233 void using_statement( void );
234 void explicit_template_instantiation( void );
235 void class_declaration_or_definition( string& scope );
236 void class_suffix( bool& is_definition, string& scope );
237 void class_suffix_trailer( void );
238 void opt_instance_list( void );
239 void union_definition( void );
240 void anonymous_union_definition( void );
241 void named_union_definition( void );
242 void enum_definition( void );
243 void anonymous_enum_definition( void );
244 void named_enum_definition( void );
245 void instance_declaration( string& scopeName );
246 void class_block( string& scope );
247 void class_block_item_list( string& scope );
248 void class_block_item( string& scope );
249 void class_item_qualifier_list( void );
250 void class_item_qualifier( void );
251 void access_modifier( void );
252 void method_declaration_or_definition_with_implicit_type( string& implicitScope );
253 void method_declaration_or_definition_with_explicit_type( string &scope );
254 void method_suffix( bool& is_definition );
255 void method_signature( string& scope, string& methodName, string& paramList );
256 void type( string& cvQualifiers, string& typeName, string& indirMods );
257 void cv_qualifier( string& cvQualifiers );
258 void type_name( string& typeName );
259 void indirection_modifiers( string& indirMods );
260 void indirection_modifier( string& indirMods );
261 void builtin_type( string& typeName );
262 void type_keyword( string& typeName );
263 void user_type( string& typeName );
264 void scoped_member_name( void );
265 void scoped_identifier( string& scope, string& name );
266 void explicit_scope_spec( string& scope );
267 void unscoped_member_name( string& name );
268 void dtor_member_name( string& name );
269 void operator_member_name( string& name );
270 void operator_identifier( string& opname );
271 void new_or_delete( void );
272 void param_list( string& scope, string& params );
273 void param_list_items( string& scope, string& items );
274 void more_param_items( string& scope, string& items );
275 void param_item( string& scope, string& item );
276 void param_type( string& scope, string& typeName );
277 void param_spec( void );
278 void knr_param_decl_list( void );
279 void opt_const_modifier( void );
280 void typedef_definition( void );
281 void fptr_typedef_definition( void );
282 void struct_typedef_definition( void );
283 void simple_typedef_definition( void );
284 void identifier_opt( void );
285 void tag_list_opt( void );
286 void tag( void );
287 void simple_type_alias( void );
288 void fptr_type_alias( void );
289 void class_or_method_declaration_or_definition( string& scope );
290 void class_prefix( string& modname, string& modtype );
291 void inheritance_list( string& childName );
292 void inheritance_item_list( string& childName );
293 void inheritance_access_key( void );
294 void inheritance_item( string& childName );
295 void class_key( string& modtype );
296 void access_key( void );
297 void ctor_init_list( void );
298 void ctor_init_item_list( void );
299 void ctor_init_item( void );
300 void linkage_qualifiers( void );
301 void linkage_qualifier( void );
302 void identifier_or_brace_block_or_both( void );
303 void opt_brace_block( void );
304 void instance_item( string& indir, string& name );
305 void item_specifier( string& indir, string& name );
306 void opt_initializer( void );
307 void init_expr( void );
308 void init_expr_item( void );
309 void cast_keyword( void );
310 void init_value( void );
311 void keyword( void );
312 void op( void );
313 void constant( void );
314 void literal( void );
315 void string_literal( void );
316 void block( void );
317 void balanced( void );
318 void balanced_list( void );
319 void nested_token_list( int nl );
320 void nested_token( int nl );
321 void scoped( void );
322 void brace_block( void );
323 void skip_until_matching_rbrace( int brace_level );
324 void paren_block( void );
325 void brack_block( void );
326 void brack_list( void );
327 void angle_balanced_list( void );
328 void angle_block( void );
329 static SetWordType RESYNCHRONISATION_set[36];
};
#endif /* CParser_h */
1 #ifndef Ctokens_h
#define Ctokens_h
/* Ctokens.h -- List of labelled tokens and stuff
*
* Generated from: cccc.g
*
* Terence Parr, Will Cohen, and Hank Dietz: 1989-1999
* Purdue University Electrical Engineering
* ANTLR Version 1.33MR20
*/
enum ANTLRTokenType {
Eof=1,
WHITESPACE=2,
DOS_NL=3,
MAC_NL=4,
UNIX_NL=5,
HASH=6,
DOS_P_EOL=7,
MAC_P_EOL=8,
UNIX_P_EOL=9,
P_LINECONT=10,
P_ANYTHING=11,
P_COMMULTI=12,
RR_DIRECTIVE=13,
RR_ANYTHING=14,
RR_END=15,
COMDEF=16,
COMLINE=17,
COMLINE_END=18,
COMLINE_ANYTHING=19,
COMMULTI=20,
COMMULTI_END=21,
COMMULTI_EOL=22,
COMMULTI_ANYTHING=23,
STRINGSTART=24,
STRINGCONST=25,
LYNNS_FIX=26,
ESCAPED_DQUOTE=27,
ESCAPED_OTHER=28,
S_ANYTHING=29,
CHARSTART=30,
CHARCONST=31,
CH_ANYTHING=32,
LBRACE=33,
RBRACE=34,
LPAREN=35,
RPAREN=36,
LBRACK=37,
RBRACK=38,
ASM=39,
AUTO=40,
BREAK=41,
CASE=42,
CATCH=43,
KW_CHAR=44,
CLASS=45,
KW_CONST=46,
CONTINUE=47,
DEFAULT=48,
DELETE=49,
DO=50,
KW_DOUBLE=51,
ELSE=52,
ENUM=53,
EXTERN=54,
KW_FLOAT=55,
FOR=56,
FRIEND=57,
GOTO=58,
IF=59,
INLINE=60,
KW_INT=61,
KW_LONG=62,
NEW=63,
OPERATOR=64,
PRIVATE=65,
PROTECTED=66,
PUBLIC=67,
REGISTER=68,
RETURN=69,
KW_SHORT=70,
SIGNED=71,
SIZEOF=72,
STATIC=73,
STRUCT=74,
SWITCH=75,
TEMPLATE=76,
KW_THIS=77,
THROW=78,
TRY=79,
TYPEDEF=80,
UNION=81,
UNSIGNED=82,
VIRTUAL=83,
KW_VOID=84,
VOLATILE=85,
WHILE=86,
ASSIGN_OP=90,
GREATERTHAN=105,
LESSTHAN=106,
GREATEREQUAL=107,
LESSEQUAL=108,
ASTERISK=110,
LOGICAL_AND_OP=124,
LOGICAL_OR_OP=125,
LOGICAL_NOT_OP=126,
QUERY_OP=127,
AMPERSAND=128,
PIPE=129,
TILDA=130,
COLONCOLON=132,
ARROW=133,
COLON=134,
PERIOD=135,
COMMA=136,
SEMICOLON=137,
NAMESPACE=138,
USING=139,
AND=140,
AND_EQ=141,
BITAND=142,
BITOR=143,
COMPL=144,
NOT=145,
OR=146,
OR_EQ=147,
XOR=148,
XOR_EQ=149,
KW_BOOL=150,
BTRUE=151,
BFALSE=152,
STATIC_CAST=153,
REINTERPRET_CAST=154,
CONST_CAST=155,
DYNAMIC_CAST=156,
TYPEID=157,
IMPLEMENTATION_KEYWORD=158,
IDENTIFIER=159,
OCT_NUM=160,
L_OCT_NUM=161,
INT_NUM=162,
L_INT_NUM=163,
HEX_NUM=164,
L_HEX_NUM=165,
FNUM=166,
ANYTHING=167,
Start=169,
Link_item=170,
End_of_file=171,
Definition_or_declaration=172,
Resync_tokens=173,
Extern_linkage_block=174,
Namespace_block=175,
Using_statement=176,
Explicit_template_instantiation=177,
Class_declaration_or_definition=178,
Class_suffix=179,
Class_suffix_trailer=180,
Opt_instance_list=181,
Union_definition=182,
Anonymous_union_definition=183,
Named_union_definition=184,
Enum_definition=185,
Anonymous_enum_definition=186,
Named_enum_definition=187,
Instance_declaration=188,
Class_block=189,
Class_block_item_list=190,
Class_block_item=191,
Class_item_qualifier_list=192,
Class_item_qualifier=193,
Access_modifier=194,
Method_declaration_or_definition_with_implicit_type=195,
Method_declaration_or_definition_with_explicit_type=196,
Method_suffix=197,
Method_signature=198,
Type=199,
Cv_qualifier=200,
MUTABLE=201,
Type_name=202,
Indirection_modifiers=203,
Indirection_modifier=204,
Builtin_type=205,
Type_keyword=206,
User_type=207,
Scoped_member_name=208,
Scoped_identifier=209,
Explicit_scope_spec=210,
Unscoped_member_name=211,
Dtor_member_name=212,
Operator_member_name=213,
Operator_identifier=214,
New_or_delete=215,
Param_list=216,
Param_list_items=217,
More_param_items=218,
Param_item=219,
Param_type=220,
Param_spec=221,
Knr_param_decl_list=222,
Opt_const_modifier=223,
Typedef_definition=224,
Fptr_typedef_definition=225,
Struct_typedef_definition=226,
Simple_typedef_definition=227,
Identifier_opt=228,
Tag_list_opt=229,
Tag=230,
Simple_type_alias=231,
Fptr_type_alias=232,
Class_or_method_declaration_or_definition=233,
Class_prefix=234,
Inheritance_list=235,
Inheritance_item_list=236,
Inheritance_access_key=237,
Inheritance_item=238,
Class_key=239,
Access_key=240,
Ctor_init_list=241,
Ctor_init_item_list=242,
Ctor_init_item=243,
Linkage_qualifiers=244,
Linkage_qualifier=245,
Identifier_or_brace_block_or_both=246,
Opt_brace_block=247,
Instance_item=248,
Item_specifier=249,
Opt_initializer=250,
Init_expr=251,
Init_expr_item=252,
Cast_keyword=253,
Init_value=254,
Keyword=255,
EXPLICIT=256,
Op=257,
Constant=258,
Literal=259,
String_literal=260,
Block=261,
Balanced=262,
Balanced_list=263,
Nested_token_list=264,
Nested_token=265,
Scoped=267,
Brace_block=268,
Skip_until_matching_rbrace=269,
Paren_block=270,
Brack_block=271,
Brack_list=272,
Angle_balanced_list=273,
Angle_block=274,
TOKENTYPE_MAX=275,
DLGminToken=0,
DLGmaxToken=9999};
#endif
1 #ifndef JLexer_h
#define JLexer_h
/*
* D L G L e x e r C l a s s D e f i n i t i o n
*
* Generated from: parser.dlg
*
* 1989-1999 by Will Cohen, Terence Parr, and Hank Dietz
* Purdue University Electrical Engineering
* DLG Version 1.33MR20
*/
#include "DLexerBase.h"
16 class JLexer : public DLGLexerBase {
public:
public:
static const int MAX_MODE;
static const int DfaStates;
static const int START;
static const int COMMENT_LINE;
static const int COMMENT_MULTI;
static const int CONST_STRING;
static const int CONST_CHAR;
typedef unsigned short DfaState;
28 JLexer( DLGInputStream *in,
29 unsigned bufsize=2000 )
: DLGLexerBase( in, bufsize, 0 )
{
;
}
34 void mode( int );
35 ANTLRTokenType nextTokenType( void );
36 void advance( void );
protected:
38 ANTLRTokenType act1( );
39 ANTLRTokenType act2( );
40 ANTLRTokenType act3( );
41 ANTLRTokenType act4( );
42 ANTLRTokenType act5( );
43 ANTLRTokenType act6( );
44 ANTLRTokenType act7( );
45 ANTLRTokenType act8( );
46 ANTLRTokenType act9( );
47 ANTLRTokenType act10( );
48 ANTLRTokenType act11( );
49 ANTLRTokenType act12( );
50 ANTLRTokenType act13( );
51 ANTLRTokenType act14( );
52 ANTLRTokenType act15( );
53 ANTLRTokenType act16( );
54 ANTLRTokenType act17( );
55 ANTLRTokenType act18( );
56 ANTLRTokenType act19( );
57 ANTLRTokenType act20( );
58 ANTLRTokenType act21( );
59 ANTLRTokenType act22( );
60 ANTLRTokenType act23( );
61 ANTLRTokenType act24( );
62 ANTLRTokenType act25( );
63 ANTLRTokenType act26( );
64 ANTLRTokenType act27( );
65 ANTLRTokenType act28( );
66 ANTLRTokenType act29( );
67 ANTLRTokenType act30( );
68 ANTLRTokenType act31( );
69 ANTLRTokenType act32( );
70 ANTLRTokenType act33( );
71 ANTLRTokenType act34( );
72 ANTLRTokenType act35( );
73 ANTLRTokenType act36( );
74 ANTLRTokenType act37( );
75 ANTLRTokenType act38( );
76 ANTLRTokenType act39( );
77 ANTLRTokenType act40( );
78 ANTLRTokenType act41( );
79 ANTLRTokenType act42( );
80 ANTLRTokenType act43( );
81 ANTLRTokenType act44( );
82 ANTLRTokenType act45( );
83 ANTLRTokenType act46( );
84 ANTLRTokenType act47( );
85 ANTLRTokenType act48( );
86 ANTLRTokenType act49( );
87 ANTLRTokenType act50( );
88 ANTLRTokenType act51( );
89 ANTLRTokenType act52( );
90 ANTLRTokenType act53( );
91 ANTLRTokenType act54( );
92 ANTLRTokenType act55( );
93 ANTLRTokenType act56( );
94 ANTLRTokenType act57( );
95 ANTLRTokenType act58( );
96 ANTLRTokenType act59( );
97 ANTLRTokenType act60( );
98 ANTLRTokenType act61( );
99 ANTLRTokenType act62( );
100 ANTLRTokenType act63( );
101 ANTLRTokenType act64( );
102 ANTLRTokenType act65( );
103 ANTLRTokenType act66( );
104 ANTLRTokenType act67( );
105 ANTLRTokenType act68( );
106 ANTLRTokenType act69( );
107 ANTLRTokenType act70( );
108 ANTLRTokenType act71( );
109 ANTLRTokenType act72( );
110 ANTLRTokenType act73( );
111 ANTLRTokenType act74( );
112 ANTLRTokenType act75( );
113 ANTLRTokenType act76( );
114 ANTLRTokenType act77( );
115 ANTLRTokenType act78( );
116 ANTLRTokenType act79( );
117 ANTLRTokenType act80( );
118 ANTLRTokenType act81( );
119 ANTLRTokenType act82( );
120 ANTLRTokenType act83( );
121 ANTLRTokenType act84( );
122 ANTLRTokenType act85( );
123 ANTLRTokenType act86( );
124 ANTLRTokenType act87( );
125 ANTLRTokenType act88( );
126 ANTLRTokenType act89( );
127 ANTLRTokenType act90( );
128 ANTLRTokenType act91( );
129 ANTLRTokenType act92( );
130 ANTLRTokenType act93( );
131 ANTLRTokenType act94( );
132 ANTLRTokenType act95( );
133 ANTLRTokenType act96( );
134 ANTLRTokenType act97( );
135 ANTLRTokenType act98( );
136 ANTLRTokenType act99( );
137 ANTLRTokenType act100( );
138 ANTLRTokenType act101( );
139 ANTLRTokenType act102( );
140 ANTLRTokenType act103( );
141 ANTLRTokenType act104( );
142 ANTLRTokenType act105( );
143 ANTLRTokenType act106( );
144 ANTLRTokenType act107( );
145 ANTLRTokenType act108( );
146 ANTLRTokenType act109( );
147 ANTLRTokenType act110( );
148 ANTLRTokenType act111( );
149 ANTLRTokenType act112( );
150 ANTLRTokenType act113( );
151 ANTLRTokenType act114( );
152 ANTLRTokenType act115( );
153 ANTLRTokenType act116( );
154 ANTLRTokenType act117( );
155 ANTLRTokenType act118( );
156 ANTLRTokenType act119( );
157 ANTLRTokenType act120( );
158 ANTLRTokenType act121( );
159 ANTLRTokenType act122( );
160 ANTLRTokenType act123( );
161 ANTLRTokenType act124( );
162 ANTLRTokenType act125( );
163 ANTLRTokenType act126( );
164 ANTLRTokenType act127( );
165 ANTLRTokenType act128( );
166 ANTLRTokenType act129( );
167 ANTLRTokenType act130( );
168 ANTLRTokenType act131( );
169 ANTLRTokenType act132( );
170 ANTLRTokenType act133( );
171 ANTLRTokenType act134( );
172 static DfaState st0[64];
173 static DfaState st1[64];
174 static DfaState st2[64];
175 static DfaState st3[64];
176 static DfaState st4[64];
177 static DfaState st5[64];
178 static DfaState st6[64];
179 static DfaState st7[64];
180 static DfaState st8[64];
181 static DfaState st9[64];
182 static DfaState st10[64];
183 static DfaState st11[64];
184 static DfaState st12[64];
185 static DfaState st13[64];
186 static DfaState st14[64];
187 static DfaState st15[64];
188 static DfaState st16[64];
189 static DfaState st17[64];
190 static DfaState st18[64];
191 static DfaState st19[64];
192 static DfaState st20[64];
193 static DfaState st21[64];
194 static DfaState st22[64];
195 static DfaState st23[64];
196 static DfaState st24[64];
197 static DfaState st25[64];
198 static DfaState st26[64];
199 static DfaState st27[64];
200 static DfaState st28[64];
201 static DfaState st29[64];
202 static DfaState st30[64];
203 static DfaState st31[64];
204 static DfaState st32[64];
205 static DfaState st33[64];
206 static DfaState st34[64];
207 static DfaState st35[64];
208 static DfaState st36[64];
209 static DfaState st37[64];
210 static DfaState st38[64];
211 static DfaState st39[64];
212 static DfaState st40[64];
213 static DfaState st41[64];
214 static DfaState st42[64];
215 static DfaState st43[64];
216 static DfaState st44[64];
217 static DfaState st45[64];
218 static DfaState st46[64];
219 static DfaState st47[64];
220 static DfaState st48[64];
221 static DfaState st49[64];
222 static DfaState st50[64];
223 static DfaState st51[64];
224 static DfaState st52[64];
225 static DfaState st53[64];
226 static DfaState st54[64];
227 static DfaState st55[64];
228 static DfaState st56[64];
229 static DfaState st57[64];
230 static DfaState st58[64];
231 static DfaState st59[64];
232 static DfaState st60[64];
233 static DfaState st61[64];
234 static DfaState st62[64];
235 static DfaState st63[64];
236 static DfaState st64[64];
237 static DfaState st65[64];
238 static DfaState st66[64];
239 static DfaState st67[64];
240 static DfaState st68[64];
241 static DfaState st69[64];
242 static DfaState st70[64];
243 static DfaState st71[64];
244 static DfaState st72[64];
245 static DfaState st73[64];
246 static DfaState st74[64];
247 static DfaState st75[64];
248 static DfaState st76[64];
249 static DfaState st77[64];
250 static DfaState st78[64];
251 static DfaState st79[64];
252 static DfaState st80[64];
253 static DfaState st81[64];
254 static DfaState st82[64];
255 static DfaState st83[64];
256 static DfaState st84[64];
257 static DfaState st85[64];
258 static DfaState st86[64];
259 static DfaState st87[64];
260 static DfaState st88[64];
261 static DfaState st89[64];
262 static DfaState st90[64];
263 static DfaState st91[64];
264 static DfaState st92[64];
265 static DfaState st93[64];
266 static DfaState st94[64];
267 static DfaState st95[64];
268 static DfaState st96[64];
269 static DfaState st97[64];
270 static DfaState st98[64];
271 static DfaState st99[64];
272 static DfaState st100[64];
273 static DfaState st101[64];
274 static DfaState st102[64];
275 static DfaState st103[64];
276 static DfaState st104[64];
277 static DfaState st105[64];
278 static DfaState st106[64];
279 static DfaState st107[64];
280 static DfaState st108[64];
281 static DfaState st109[64];
282 static DfaState st110[64];
283 static DfaState st111[64];
284 static DfaState st112[64];
285 static DfaState st113[64];
286 static DfaState st114[64];
287 static DfaState st115[64];
288 static DfaState st116[64];
289 static DfaState st117[64];
290 static DfaState st118[64];
291 static DfaState st119[64];
292 static DfaState st120[64];
293 static DfaState st121[64];
294 static DfaState st122[64];
295 static DfaState st123[64];
296 static DfaState st124[64];
297 static DfaState st125[64];
298 static DfaState st126[64];
299 static DfaState st127[64];
300 static DfaState st128[64];
301 static DfaState st129[64];
302 static DfaState st130[64];
303 static DfaState st131[64];
304 static DfaState st132[64];
305 static DfaState st133[64];
306 static DfaState st134[64];
307 static DfaState st135[64];
308 static DfaState st136[64];
309 static DfaState st137[64];
310 static DfaState st138[64];
311 static DfaState st139[64];
312 static DfaState st140[64];
313 static DfaState st141[64];
314 static DfaState st142[64];
315 static DfaState st143[64];
316 static DfaState st144[64];
317 static DfaState st145[64];
318 static DfaState st146[64];
319 static DfaState st147[64];
320 static DfaState st148[64];
321 static DfaState st149[64];
322 static DfaState st150[64];
323 static DfaState st151[64];
324 static DfaState st152[64];
325 static DfaState st153[64];
326 static DfaState st154[64];
327 static DfaState st155[64];
328 static DfaState st156[64];
329 static DfaState st157[64];
330 static DfaState st158[64];
331 static DfaState st159[64];
332 static DfaState st160[64];
333 static DfaState st161[64];
334 static DfaState st162[64];
335 static DfaState st163[64];
336 static DfaState st164[64];
337 static DfaState st165[64];
338 static DfaState st166[64];
339 static DfaState st167[64];
340 static DfaState st168[64];
341 static DfaState st169[64];
342 static DfaState st170[64];
343 static DfaState st171[64];
344 static DfaState st172[64];
345 static DfaState st173[64];
346 static DfaState st174[64];
347 static DfaState st175[64];
348 static DfaState st176[64];
349 static DfaState st177[64];
350 static DfaState st178[64];
351 static DfaState st179[64];
352 static DfaState st180[64];
353 static DfaState st181[64];
354 static DfaState st182[64];
355 static DfaState st183[64];
356 static DfaState st184[64];
357 static DfaState st185[64];
358 static DfaState st186[64];
359 static DfaState st187[64];
360 static DfaState st188[64];
361 static DfaState st189[64];
362 static DfaState st190[64];
363 static DfaState st191[64];
364 static DfaState st192[64];
365 static DfaState st193[64];
366 static DfaState st194[64];
367 static DfaState st195[64];
368 static DfaState st196[64];
369 static DfaState st197[64];
370 static DfaState st198[64];
371 static DfaState st199[64];
372 static DfaState st200[64];
373 static DfaState st201[64];
374 static DfaState st202[64];
375 static DfaState st203[64];
376 static DfaState st204[64];
377 static DfaState st205[64];
378 static DfaState st206[64];
379 static DfaState st207[64];
380 static DfaState st208[64];
381 static DfaState st209[64];
382 static DfaState st210[64];
383 static DfaState st211[64];
384 static DfaState st212[64];
385 static DfaState st213[64];
386 static DfaState st214[64];
387 static DfaState st215[64];
388 static DfaState st216[64];
389 static DfaState st217[64];
390 static DfaState st218[64];
391 static DfaState st219[64];
392 static DfaState st220[64];
393 static DfaState st221[64];
394 static DfaState st222[64];
395 static DfaState st223[64];
396 static DfaState st224[64];
397 static DfaState st225[64];
398 static DfaState st226[64];
399 static DfaState st227[64];
400 static DfaState st228[64];
401 static DfaState st229[64];
402 static DfaState st230[64];
403 static DfaState st231[64];
404 static DfaState st232[64];
405 static DfaState st233[64];
406 static DfaState st234[64];
407 static DfaState st235[64];
408 static DfaState st236[64];
409 static DfaState st237[64];
410 static DfaState st238[64];
411 static DfaState st239[64];
412 static DfaState st240[64];
413 static DfaState st241[64];
414 static DfaState st242[64];
415 static DfaState st243[64];
416 static DfaState st244[64];
417 static DfaState st245[64];
418 static DfaState st246[64];
419 static DfaState st247[64];
420 static DfaState st248[64];
421 static DfaState st249[64];
422 static DfaState st250[64];
423 static DfaState st251[64];
424 static DfaState st252[64];
425 static DfaState st253[64];
426 static DfaState st254[64];
427 static DfaState st255[64];
428 static DfaState st256[64];
429 static DfaState st257[64];
430 static DfaState st258[64];
431 static DfaState st259[64];
432 static DfaState st260[64];
433 static DfaState st261[64];
434 static DfaState st262[64];
435 static DfaState st263[64];
436 static DfaState st264[64];
437 static DfaState st265[64];
438 static DfaState st266[64];
439 static DfaState st267[64];
440 static DfaState st268[64];
441 static DfaState st269[64];
442 static DfaState st270[64];
443 static DfaState st271[64];
444 static DfaState st272[64];
445 static DfaState st273[64];
446 static DfaState st274[64];
447 static DfaState st275[64];
448 static DfaState st276[64];
449 static DfaState st277[64];
450 static DfaState st278[64];
451 static DfaState st279[64];
452 static DfaState st280[64];
453 static DfaState st281[64];
454 static DfaState st282[64];
455 static DfaState st283[64];
456 static DfaState st284[64];
457 static DfaState st285[64];
458 static DfaState st286[64];
459 static DfaState st287[64];
460 static DfaState st288[64];
461 static DfaState st289[64];
462 static DfaState st290[64];
463 static DfaState st291[64];
464 static DfaState st292[64];
465 static DfaState st293[64];
466 static DfaState st294[64];
467 static DfaState st295[64];
468 static DfaState st296[64];
469 static DfaState st297[64];
470 static DfaState st298[64];
471 static DfaState st299[64];
472 static DfaState st300[64];
473 static DfaState st301[64];
474 static DfaState st302[64];
475 static DfaState st303[64];
476 static DfaState st304[64];
477 static DfaState st305[64];
478 static DfaState st306[64];
479 static DfaState st307[64];
480 static DfaState st308[64];
481 static DfaState st309[64];
482 static DfaState st310[64];
483 static DfaState st311[64];
484 static DfaState st312[64];
485 static DfaState st313[64];
486 static DfaState st314[64];
487 static DfaState st315[64];
488 static DfaState st316[64];
489 static DfaState st317[64];
490 static DfaState st318[64];
491 static DfaState st319[64];
492 static DfaState st320[5];
493 static DfaState st321[5];
494 static DfaState st322[5];
495 static DfaState st323[5];
496 static DfaState st324[5];
497 static DfaState st325[5];
498 static DfaState st326[7];
499 static DfaState st327[7];
500 static DfaState st328[7];
501 static DfaState st329[7];
502 static DfaState st330[7];
503 static DfaState st331[7];
504 static DfaState st332[7];
505 static DfaState st333[7];
506 static DfaState st334[6];
507 static DfaState st335[6];
508 static DfaState st336[6];
509 static DfaState st337[6];
510 static DfaState st338[6];
511 static DfaState st339[6];
512 static DfaState st340[6];
513 static DfaState st341[6];
514 static DfaState st342[4];
515 static DfaState st343[4];
516 static DfaState st344[4];
517 static DfaState st345[4];
518 static DfaState *dfa[346];
519 static DfaState dfa_base[];
static unsigned char *b_class_no[];
521 static DfaState accepts[347];
522 static DLGChar alternatives[347];
static ANTLRTokenType ( JLexer::*actions[135] )( );
static unsigned char shift0[257];
static unsigned char shift1[257];
static unsigned char shift2[257];
static unsigned char shift3[257];
static unsigned char shift4[257];
int ZZSHIFT( int c ) { return b_class_no[automaton][1+c]; }
//
// 133MR1 Deprecated feature to allow inclusion of user-defined code in DLG class header
//
#ifdef DLGLexerIncludeFile
#include DLGLexerIncludeFile
#endif
};
typedef ANTLRTokenType ( JLexer::*PtrJLexerMemberFunc )( );
#endif
1 /*
* JParser: P a r s e r H e a d e r
*
* Generated from: java.g
*
* Terence Parr, Russell Quong, Will Cohen, and Hank Dietz: 1989-1999
* Parr Research Corporation
* with Purdue University Electrical Engineering
* with AHPCRC, University of Minnesota
* ANTLR Version 1.33MR20
*/
#ifndef JParser_h
#define JParser_h
#ifndef ANTLR_VERSION
#define ANTLR_VERSION 13320
#endif
#ifndef zzTRACE_RULES
#define zzTRACE_RULES
#endif
#include "AParser.h"
#define zzTRACE_RULES
#include "AParser.h"
#include "cccc.h"
#include "cccc_utl.h"
#include "cccc_opt.h"
// the objects which PCCTS creates for ASTs as the #0 variable etc
// have type "pointer to ASTBase", which means they need to be cast
// to a pointer to my variant of AST if I want to call my AST
// methods on them
#define MY_AST( X ) ( ( AST* ) X )
37 class JParser : public ANTLRParser {
public:
39 static const ANTLRChar *tokenName( int tk );
protected:
41 static const ANTLRChar *_token_tbl[];
private:
45 ParseStore* ps;
46 ParseUtility* pu;
48 void tracein( const char *rulename ) { pu->tracein( rulename, guessing, LT( 1 ) ); }
49 void traceout( const char *rulename ) { pu->traceout( rulename, guessing, LT( 1 ) ); }
50 void syn(
51 _ANTLRTokenPtr tok, ANTLRChar *egroup, SetWordType *eset,
ANTLRTokenType etok, int k )
{
pu->syn( tok, egroup, eset, etok, k );
}
57 string typeCombine( const string& modifiers, const string& name, const string& indir )
{
string retval;
if( modifiers.size( )>0 )
{
retval=modifiers+" "+name;
}
else
{
retval=name;
}
if( indir.size( )>0 )
{
retval+=" ";
retval+=indir;
}
return retval;
}
// we have a data member for the language of the parse so
// that we can supply the names of dialects ( ansi_c, ansi_c++, mfc_c++ etc )
// for contexts where we wish to apply dialect-specific parsing
// rules
80 string parse_language;
// Many of the rules below accept string parameters to
// allow upward passing of attributes.
// Where the calling context does not need to receive
// the attributes, it can use the dummy values defined
// here to save allocating a string locally to satisfy the
// parameter list.
88 string d1, d2, d3;
89 bool db;
public:
93 void init( const string& filename, const string& language )
{
pu=ParseUtility::currentInstance( );
ps=ParseStore::currentInstance( );
ANTLRParser::init( );
parse_language=language;
}
protected:
104 static SetWordType err1[28];
105 static SetWordType err2[28];
106 static SetWordType err3[28];
107 static SetWordType setwd1[221];
108 static SetWordType err4[28];
109 static SetWordType err5[28];
110 static SetWordType err6[28];
111 static SetWordType setwd2[221];
112 static SetWordType err7[28];
113 static SetWordType err8[28];
114 static SetWordType err9[28];
115 static SetWordType setwd3[221];
116 static SetWordType err10[28];
117 static SetWordType setwd4[221];
118 static SetWordType err11[28];
119 static SetWordType err12[28];
120 static SetWordType err13[28];
121 static SetWordType err14[28];
122 static SetWordType setwd5[221];
123 static SetWordType err15[28];
124 static SetWordType err16[28];
125 static SetWordType err17[28];
126 static SetWordType setwd6[221];
127 static SetWordType err18[28];
128 static SetWordType setwd7[221];
129 static SetWordType setwd8[221];
130 static SetWordType err19[28];
131 static SetWordType err20[28];
132 static SetWordType setwd9[221];
133 static SetWordType setwd10[221];
134 static SetWordType err21[28];
135 static SetWordType err22[28];
136 static SetWordType setwd11[221];
137 static SetWordType err23[28];
138 static SetWordType err24[28];
139 static SetWordType err25[28];
140 static SetWordType err26[28];
141 static SetWordType setwd12[221];
142 static SetWordType err27[28];
143 static SetWordType err28[28];
144 static SetWordType setwd13[221];
145 static SetWordType err29[28];
146 static SetWordType setwd14[221];
147 static SetWordType err30[28];
148 static SetWordType err31[28];
149 static SetWordType setwd15[221];
150 static SetWordType err32[28];
151 static SetWordType err33[28];
152 static SetWordType err34[28];
153 static SetWordType err35[28];
154 static SetWordType setwd16[221];
155 static SetWordType err36[28];
156 static SetWordType err37[28];
157 static SetWordType err38[28];
158 static SetWordType setwd17[221];
159 static SetWordType err39[28];
160 static SetWordType err40[28];
161 static SetWordType err41[28];
162 static SetWordType err42[28];
163 static SetWordType err43[28];
164 static SetWordType setwd18[221];
165 static SetWordType err44[28];
166 static SetWordType err45[28];
167 static SetWordType err46[28];
168 static SetWordType err47[28];
169 static SetWordType setwd19[221];
170 static SetWordType setwd20[221];
private:
172 void zzdflthandlers( int _signal, int *_retsignal );
public:
175 JParser( ANTLRTokenBuffer *input );
176 void compilationUnit( void );
177 void packageDefinition( string& scope );
178 void importDefinition( void );
179 void typeDefinition( string& parentScope );
180 void declaration( void );
181 void modifiers( Visibility& v );
182 void typeSpec( void );
183 void classTypeSpec( void );
184 void builtInTypeSpec( void );
185 void type( void );
186 void builtInType( void );
187 void identifier( void );
188 void typeSpec2( string& typeString, bool& isBuiltIn );
189 void classTypeSpec2( string& typeString );
190 void builtInTypeSpec2( string& typeString );
191 void identifier2( string& scope );
192 void identifierStar( void );
193 void modifier( Visibility& v );
194 void classDefinition( string& parentScope );
195 void superClassClause( const string& className );
196 void interfaceDefinition( const string& parentScope );
197 void classBlock( const string& className );
198 void interfaceExtends( const string& className );
199 void implementsClause( const std::string& className );
200 void moreSuperclassNames( const string& className, const string& inheritType );
201 void field( const string& className );
202 void typedDeclaration( const string& className, const string& typeName,
203 bool isBuiltIn, Visibility v, int startLine );
204 void methodDefinition( const string& className, const string& returnType, bool rtIsBuiltIn,
Visibility v, int startLine );
206 void variableDefinitions( const string& className, const string& returnType, bool rtIsBuiltIn,
Visibility v, int startLine );
208 void variableDeclarator( void );
209 void declaratorBrackets( void );
210 void varInitializer( void );
211 void arrayInitializer( void );
212 void initializer( void );
213 void ctorDefinition( const string& className, Visibility v );
214 void ctorHead( string& paramList, const string& className, Visibility v );
215 void throwsClause( void );
216 void returnTypeBrackersOnEndOfMethodHead( void );
217 void parameterDeclarationList(
// a string in which we accumulate a string of all parameters
219 string& paramList,
// the name of the owner class for the method
221 const string& clientName,
// visibility of the method
const Visibility& v
);
225 void parameterDeclaration(
// a string in which we accumulate a string of all parameters
227 string& paramList,
// the name of the owner class for the method
229 const string& clientName,
// visibility of the method
const Visibility& v,
// is this rule being used from a parameter list ( in which case
// we want to do record_userel_extent ) or from a syntacticly similar
// catch statement, which is buried in the implementation of a method
// and does not interest us
236 bool inParameterList
);
238 void parameterDeclaratorBrackets( string& bracks );
239 void parameterModifier( string& paramList );
240 void compoundStatement( void );
241 void statement( void );
242 void ifStatement( void );
243 void forStatement( void );
244 void whileStatement( void );
245 void doWhileStatement( void );
246 void breakStatement( void );
247 void continueStatement( void );
248 void returnStatement( void );
249 void switchStatement( void );
250 void throwStatement( void );
251 void syncStatement( void );
252 void emptyStatement( void );
253 void optElseClause( void );
254 void casesGroup( void );
255 void cases( void );
256 void optMoreCases( void );
257 void aCase( void );
258 void caseSList( void );
259 void forInit( void );
260 void forCond( void );
261 void forIter( void );
262 void tryBlock( void );
263 void handler( void );
264 void expression( void );
265 void expressionList( void );
266 void assignmentExpression( void );
267 void conditionalExpression( void );
268 void logicalOrExpression( void );
269 void logicalAndExpression( void );
270 void inclusiveOrExpression( void );
271 void exclusiveOrExpression( void );
272 void andExpression( void );
273 void equalityExpression( void );
274 void relationalPredicate( void );
275 void relationalExpression( void );
276 void shiftExpression( void );
277 void additiveExpression( void );
278 void multiplicativeExpression( void );
279 void unaryExpression( void );
280 void unaryExpressionNotPlusMinus( void );
281 void postfixExpression( void );
282 void primaryExpression( void );
283 void newExpression( void );
284 void argList( void );
285 void newArrayDeclarator( void );
286 void constant( void );
};
#endif /* JParser_h */
1 #ifndef Jtokens_h
#define Jtokens_h
/* Jtokens.h -- List of labelled tokens and stuff
*
* Generated from: java.g
*
* Terence Parr, Will Cohen, and Hank Dietz: 1989-1999
* Purdue University Electrical Engineering
* ANTLR Version 1.33MR20
*/
enum ANTLRTokenType {
Eof=1,
QUESTION=2,
LPAREN=3,
RPAREN=4,
LBRACK=5,
RBRACK=6,
LCURLY=7,
RCURLY=8,
COLON=9,
COMMA=10,
DOT=11,
ASSIGN=12,
EQUAL=13,
LNOT=14,
BNOT=15,
NOT_EQUAL=16,
DIV=17,
DIV_ASSIGN=18,
PLUS=19,
PLUS_ASSIGN=20,
INC=21,
MINUS=22,
MINUS_ASSIGN=23,
DEC=24,
STAR=25,
STAR_ASSIGN=26,
MOD=27,
MOD_ASSIGN=28,
SR=29,
SR_ASSIGN=30,
BSR=31,
BSR_ASSIGN=32,
GE=33,
GT=34,
SL=35,
SL_ASSIGN=36,
LE=37,
LESSTHAN=38,
BXOR=39,
BXOR_ASSIGN=40,
BOR=41,
BOR_ASSIGN=42,
LOR=43,
BAND=44,
BAND_ASSIGN=45,
LAND=46,
SEMI=47,
WS=48,
DOS_NL=49,
MAC_NL=50,
UNIX_NL=51,
COMLINE=52,
DOS_COMLINE_END=53,
MAC_COMLINE_END=54,
UNIX_COMLINE_END=55,
COMLINE_ANYTHING=56,
COMMULTI=57,
COMMULTI_END=58,
DOS_COMMULTI_EOL=59,
MAC_COMMULTI_EOL=60,
UNIX_COMMULTI_EOL=61,
COMMULTI_ANYTHING=62,
STRINGSTART=63,
STRINGCONST=64,
LYNNS_FIX=65,
ESCAPED_DQUOTE=66,
ESCAPED_OTHER=67,
S_ANYTHING=68,
CHARSTART=69,
CHARCONST=70,
CH_ANYTHING=71,
ABSTRACT=72,
KW_BOOLEAN=73,
BREAK=74,
KW_BYTE=75,
CATCH=76,
DEFAULT=77,
KW_CHAR=78,
CLASS=79,
KW_CONST=80,
CONTINUE=81,
DO=82,
KW_DOUBLE=83,
ELSE=84,
EXTENDS=85,
BFALSE=86,
FINAL=87,
FINALLY=88,
KW_FLOAT=89,
FOR=90,
IF=91,
IMPLEMENTS=92,
IMPORT=93,
INSTANCEOF=94,
KW_INT=95,
INTERFACE=96,
KW_LONG=97,
NATIVE=98,
NEW=99,
PNULL=100,
PACKAGE=101,
PRIVATE=102,
PROTECTED=103,
PUBLIC=104,
RETURN=105,
KW_SHORT=106,
SHUTUP=107,
STATIC=108,
SUPER=109,
SWITCH=110,
SYNCHRONIZED=111,
THINGS=112,
KW_THIS=113,
THREADSAFE=114,
THROW=115,
THROWS=116,
TRANSIENT=117,
BTRUE=118,
TRY=119,
KW_VOID=120,
VOLATILE=121,
WHILE=122,
CASE=123,
IDENT=124,
NUM_INT1=125,
NUM_INT2=126,
NUM_INT3=127,
NUM_INT4=128,
NUM_INT1A=129,
NUM_INT1B=130,
CompilationUnit=131,
PackageDefinition=132,
ImportDefinition=133,
TypeDefinition=134,
Declaration=135,
Modifiers=136,
TypeSpec=137,
ClassTypeSpec=138,
BuiltInTypeSpec=139,
Type=140,
BuiltInType=141,
Identifier=142,
TypeSpec2=143,
ClassTypeSpec2=144,
BuiltInTypeSpec2=145,
Identifier2=146,
IdentifierStar=147,
Modifier=148,
ClassDefinition=149,
SuperClassClause=150,
InterfaceDefinition=151,
ClassBlock=152,
InterfaceExtends=153,
ImplementsClause=154,
MoreSuperclassNames=155,
Field=156,
TypedDeclaration=157,
MethodDefinition=158,
VariableDefinitions=159,
VariableDeclarator=160,
DeclaratorBrackets=161,
VarInitializer=162,
ArrayInitializer=163,
Initializer=164,
CtorDefinition=165,
CtorHead=166,
ThrowsClause=167,
ReturnTypeBrackersOnEndOfMethodHead=168,
ParameterDeclarationList=169,
ParameterDeclaration=170,
ParameterDeclaratorBrackets=171,
ParameterModifier=172,
CompoundStatement=173,
Statement=174,
IfStatement=175,
ForStatement=176,
WhileStatement=177,
DoWhileStatement=178,
BreakStatement=179,
ContinueStatement=180,
ReturnStatement=181,
SwitchStatement=182,
ThrowStatement=183,
SyncStatement=184,
EmptyStatement=185,
OptElseClause=186,
CasesGroup=187,
Cases=188,
OptMoreCases=189,
ACase=190,
CaseSList=191,
ForInit=192,
ForCond=193,
ForIter=194,
TryBlock=195,
Handler=196,
Expression=197,
ExpressionList=198,
AssignmentExpression=199,
ConditionalExpression=200,
LogicalOrExpression=201,
LogicalAndExpression=202,
InclusiveOrExpression=203,
ExclusiveOrExpression=204,
AndExpression=205,
EqualityExpression=206,
RelationalPredicate=207,
RelationalExpression=208,
ShiftExpression=209,
AdditiveExpression=210,
MultiplicativeExpression=211,
UnaryExpression=212,
UnaryExpressionNotPlusMinus=213,
PostfixExpression=214,
PrimaryExpression=215,
NewExpression=216,
ArgList=217,
NewArrayDeclarator=218,
Constant=219,
NUM_FLOAT=220,
DLGminToken=0,
DLGmaxToken=9999};
#endif
1 /*
* cccc.h
* diagnostic and portability facilities for the cccc project
*/
#ifndef _CCCC_H__
#define _CCCC_H__
#ifdef _WIN32
#pragma warning ( disable:4786 4503 )
#endif
// I am trying to standardise on using the ANSI C++ names
// for the ANSI C header files, and bringing all of
// the includes of these libraries into this file.
// I have not yet attempted to purge includes for these
// files from the other source files.
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cctype>
#include <string>
using std::string;
#include <iostream>
#include <sstream>
#include <fstream>
using std::ostream;
using std::istream;
using std::ifstream;
using std::ofstream;
using std::istringstream;
using std::ostringstream;
using std::stringstream;
using std::endl;
using std::cout;
using std::cerr;
// debugging facilities
extern int DebugMask;
enum DebugFlags {
LEXER=0x01,
PARSER=0x02,
COUNTER=0x04,
MEMORY=0x08,
EXTENT=0x10,
DATABASE=0x20
};
#define DbgMsg( DF, OS, X ) if( DebugMask&DF ) { OS << X ; }
// the global database to which stuff is added...
54 class CCCC_Project;
extern CCCC_Project *prj;
// a nasty global array of identifiers we want the lexer to ignore
#define SKIP_IDENTIFIERS_ARRAY_SIZE 256
extern char *skip_identifiers[SKIP_IDENTIFIERS_ARRAY_SIZE];
#if 0
#include "DLGLexer.h"
#endif
// These macros were used to cover differences between the way the
// old strstream classes were used in Win32 and GNU builds.
// The differences are no longer necessary.
#define MAKE_STRSTREAM( X ) stringstream X;
#define CONVERT_STRSTREAM( X ) ( X )
#define RELEASE_STRSTREAM( X )
// The -gd option generates uncompilable code with a missing
// variable called zzTracePrevRuleName if the generated
// files cccc.cpp, java.cpp, ada.cpp don't include a version
// of AParser.h seen with zzTRACE_RULES defined.
// I'm not sure how this is supposed to work, but for the moment
// I am including it here which should make all three files OK.
// Note that this could break again if the header files shift around
// and AParser.h gets read before zzTRACE_RULES is defined.
// Another option is turning -gd off, but its the way we do the
// cccc -dp debug output which is very useful.
#include "cccc_tok.h"
#define zzTRACE_RULES
#include "AParser.h"
#endif
1 /*
CCCC - C and C++ Code Counter
Copyright ( C ) 1994-2005 Tim Littlefair ( tim_littlefair@hotmail.com )
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
( at your option ) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "cccc.h"
#include <fstream>
#include "cccc_itm.h"
#include "cccc_db.h"
CCCC_Project *current_loading_project=NULL;
CCCC_Module *current_loading_module=NULL;
CCCC_Member *current_loading_extent=NULL;
CCCC_UseRelationship *current_loading_userel=NULL;
#define LINE_BUFFER_SIZE 1000
int ifstr_line;
extern CCCC_Project *prj;
// the file scope variable last_supplier is used to supress repeated
// output of the supplier name in the use relationship section where
// the current record has the same supplier as the previous one
// the indentation makes this reasonably clear
static string last_supplier="";
// persistence facilities
#define SEP '@'
// This function provides the ability for the persistence functions
// defined below to do a quick peek at the first token on the stream
// leaving the get pointer at the start of that token.
// This should be static, but on MSVC++ this gives me an unresolved
// symbol at link.
51 bool PeekAtNextLinePrefix( ifstream& ifstr, string pfx )
{
bool retval=false;
char prefix_buffer[1024];
size_t initial_stream_pos=ifstr.tellg( );
ifstr.getline( prefix_buffer, 1023, SEP );
if( pfx==prefix_buffer )
{
retval=true;
}
ifstr.seekg( initial_stream_pos );
return retval;
}
// this is a sort of abstract junkyard function ( cf Abstract Factory )
66 template <class T> void DisposeOfImportRecord( T *record_ptr, int fromfile_status )
{
switch( fromfile_status )
{
case RECORD_ADDED:
// the newly created object has been added to the
// database
// we must not delete it
break;
case RECORD_TRANSCRIBED:
// the database already had an object for this item
// the content of the new object was merged in, but the object
// itself is no longer required
delete record_ptr;
break;
default:
// something went wrong, so we mention it
cerr << "Import error " << fromfile_status
<< " at line " << ifstr_line
<< " for " << record_ptr->key( )
<< endl;
delete record_ptr;
}
}
// when we add a record to, for example, the extent table for a member of
// a module, we need to merge the information in the new extent
// with what is already known
// there are two kinds of merge:
// 1. ordinary fields like module_type should either be consistent or
// blank for all extents relating to the same module, so where the old
// field is blank, we overwrite with the new field
// 2. the flags field in CCCC_Member contains a variety of single character
// flags giving the visibility, constness, etc. of the member, with '?' being
// used to reflect a state of lack of knowledge: in these cases, any other
// value can overwrite '?', all other values do not change.
105 void Resolve_Fields( string& field1, string& field2 )
{
if( field1.size( )==0 )
{
field1=field2;
}
}
template
void
115 DisposeOfImportRecord( CCCC_Module *record_ptr, int fromfile_status );
template
void
119 DisposeOfImportRecord( CCCC_Member *record_ptr, int fromfile_status );
template
void
123 DisposeOfImportRecord( CCCC_UseRelationship *record_ptr, int fromfile_status );
template
void
127 DisposeOfImportRecord( CCCC_Extent *record_ptr, int fromfile_status );
1 /*
CCCC - C and C++ Code Counter
Copyright ( C ) 1994-2005 Tim Littlefair ( tim_littlefair@hotmail.com )
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
( at your option ) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* cccc_db.h
*/
#ifndef CCCC_DB_H
#define CCCC_DB_H
#include "cccc.h"
#include "cccc_ext.h"
#include "cccc_rec.h"
#include "cccc_prj.h"
#include "cccc_mod.h"
#include "cccc_mem.h"
#include "cccc_use.h"
// The various FromFile functions need to indicate to their
// caller their status, particularly because the caller will have
// allocated an instance of the incoming class on the heap, and needs
// to know whether it has to delete it. There are two 'normal' outcomes
// plus a potentially infinite range of possible application error
// conditions. The normal conditions are where the new instance is
// the first encountered of this module/member/relationship/whatever
// and the allocated item has been added to the database and must not
// be deleted, and when the new instance is of a previously encountered
// entity, and the information from the new record has been transcribed
// and merged into the instance in the database, and the locally allocated
// instance must be deleted.
enum GeneralFromFileStatuses
{
RECORD_TRANSCRIBED = 0,
RECORD_ADDED = 1,
RECORD_ERROR = 2
// error conditions may return RECORD_ERROR, or may use a distinctive
// value defined as a literal
};
// This function provides the ability for the persistence functions
// defined below to do a quick peek at the first token on the stream
// leaving the get pointer at the start of that token.
57 bool PeekAtNextLinePrefix( ifstream& ifstr, string pfx );
// These are global variables because I don't want to have
// to pass the project, module, member, relationship down into all of the
// FromFile methods.
// There is probably a better way for a less lazy programmer than me.
extern CCCC_Project *current_loading_project;
extern CCCC_Module *current_loading_module;
extern CCCC_Member *current_loading_extent;
extern CCCC_UseRelationship *current_loading_userel;
// this one tracks the line number in the input file
extern int ifstr_line;
73 template <class T> void DisposeOfImportRecord( T *record_ptr, int fromfile_status );
75 void Resolve_Fields( string& field1, string& field2 );
#endif // CCCC_DB_H
1 /*
CCCC - C and C++ Code Counter
Copyright ( C ) 1994-2005 Tim Littlefair ( tim_littlefair@hotmail.com )
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
( at your option ) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* cccc_ext.cc
*/
#include "cccc_itm.h"
#include "cccc_ext.h"
#include "cccc_db.h"
#include "cccc_utl.h"
unsigned int CCCC_Extent::nextkey=0;
30 CCCC_Extent::CCCC_Extent( )
{
v=vINVALID;
ut=utINVALID;
extkey=++nextkey;
}
37 CCCC_Extent::CCCC_Extent( CCCC_Item& is )
{
char v_as_char='!', ut_as_char='!';
if(
is.Extract( filename ) &&
is.Extract( linenumber ) &&
is.Extract( description ) &&
is.Extract( flags ) &&
is.Extract( count_buffer ) &&
is.Extract( v_as_char ) &&
is.Extract( ut_as_char )
)
{
v=( Visibility ) v_as_char;
ut=( UseType ) ut_as_char;
}
else
{
// we can trust the string constructor to give us empty strings,
// but we need to initialise these
v=vDONTKNOW;
ut=utDONTKNOW;
}
extkey=++nextkey;
}
64 int CCCC_Extent::AddToItem( CCCC_Item& item )
{
int retval=FALSE;
if(
item.Insert( filename ) &&
item.Insert( linenumber ) &&
item.Insert( description ) &&
item.Insert( flags ) &&
item.Insert( count_buffer ) &&
item.Insert( ( char ) v ) &&
item.Insert( ( char ) ut )
)
{
retval=TRUE;
}
return retval;
}
84 int CCCC_Extent::GetFromItem( CCCC_Item &item )
{
int retval=FALSE;
char v_as_char, ut_as_char;
if(
item.Extract( filename ) &&
item.Extract( linenumber ) &&
item.Extract( description ) &&
item.Extract( flags ) &&
item.Extract( count_buffer ) &&
item.Extract( v_as_char ) &&
item.Extract( ut_as_char )
)
{
v = ( Visibility ) v_as_char;
ut = ( UseType ) ut_as_char;
retval=TRUE;
}
return retval;
}
107 string CCCC_Extent::name( int level ) const
{
string rtnbuf;
rtnbuf="";
switch( level )
{
case nlFILENAME:
rtnbuf=filename;
break;
case nlLINENUMBER:
rtnbuf=linenumber;
break;
case nlDESCRIPTION:
rtnbuf=description;
break;
case nlSEARCH:
case nlRANK:
// Extents have no meaningful internal primary key.
// We never want two extents to have the same
// key, so we use the running number extkey
// which is initialized in both constructors.
// This should cause extents to sort in order of
// their creation, which is fine.
char buf[16];
sprintf( buf, "%015d", extkey );
rtnbuf=buf;
break;
default:
rtnbuf+=filename;
rtnbuf+=":";
rtnbuf+=linenumber;
}
return rtnbuf.c_str( );
}
145 string CCCC_Extent::key( ) const { return name( nlRANK ); }
147 int CCCC_Extent::get_count( const char* count_tag ) {
int retval=0;
char local_count_buffer[100], *count_tag_ptr, *count_value_ptr;
strcpy( local_count_buffer, count_buffer.c_str( ) );
count_tag_ptr=strtok( local_count_buffer, ":" );
while( count_tag_ptr!=NULL )
{
count_value_ptr=strtok( NULL, " " );
if( strcmp( count_tag_ptr, count_tag ) ==0 )
{
retval+=atoi( count_value_ptr );
}
count_tag_ptr=strtok( NULL, ":" );
}
return retval;
}
1 /*
CCCC - C and C++ Code Counter
Copyright ( C ) 1994-2005 Tim Littlefair ( tim_littlefair@hotmail.com )
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
( at your option ) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* cccc_ext.h
*/
#ifndef CCCC_EXT_H
#define CCCC_EXT_H
#include <string>
using std::string;
#include "cccc_utl.h"
30 class CCCC_Item;
enum ExtentNameLevel { nlFILENAME=-1, nlLINENUMBER=-2, nlDESCRIPTION=-3};
33 class CCCC_Extent
{
35 friend class CCCC_Record;
36 friend class CCCC_Project;
38 string filename;
39 string linenumber;
40 string description;
41 string flags;
42 string count_buffer;
UseType ut;
Visibility v;
static unsigned int nextkey;
unsigned int extkey;
public:
48 CCCC_Extent( );
49 CCCC_Extent( CCCC_Item& is );
51 string name( int index ) const;
52 string key( ) const;
53 int GetFromItem( CCCC_Item& item );
54 int AddToItem( CCCC_Item& item );
55 Visibility get_visibility( ) const { return v; }
56 int get_count( const char *count_tag );
57 UseType get_usetype( ) const { return ut; }
58 const char* get_description( ) const { return description.c_str( ); }
};
#endif // CCCC_EXT_H
1 /*
CCCC - C and C++ Code Counter
Copyright ( C ) 1994-2005 Tim Littlefair ( tim_littlefair@hotmail.com )
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
( at your option ) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// cccc_htm.cc
// this file defines HTML output facilities for the CCCC project
#include "cccc.h"
#include "cccc_itm.h"
#include "cccc_htm.h"
// I would love to use the C++ standard preprocessor
// directive #if here, but I have had reports before now
// of people who are using compilers which only support
// #ifdef.
#ifdef CCCC_CONF_W32VC
#include <direct.h>
#else
#ifdef CCCC_CONF_W32BC
#include <direct.h>
#else
#include <unistd.h>
#endif
#endif
#include <time.h>
#include <sys/stat.h>
#include "cccc_utl.h"
typedef std::map<string, Source_Anchor> source_anchor_map_t;
source_anchor_map_t source_anchor_map;
// class static data members
CCCC_Project* CCCC_Html_Stream::prjptr;
string CCCC_Html_Stream::outdir;
string CCCC_Html_Stream::libdir;
55 void CCCC_Html_Stream::GenerateReports( CCCC_Project* prj,
int report_mask,
57 const string& file,
58 const string& dir )
{
prjptr=prj;
outdir=dir;
CCCC_Html_Stream main_html_stream( file.c_str( ), "Report on software metrics" );
if( report_mask & rtCONTENTS )
{
// For testing purposes, we want to be able to disable the inclusion
// of the current time in the report. This enables us to store a
// reference version of the report in RCS and expect the program
// to generate an identical one at regression testing time.
if( report_mask & rtSHOW_GEN_TIME )
{
main_html_stream.Table_Of_Contents( report_mask, true );
}
else
{
main_html_stream.Table_Of_Contents( report_mask, false );
}
}
if( report_mask & rtSUMMARY )
{
main_html_stream.Project_Summary( );
}
if( report_mask & rtPROC1 )
{
main_html_stream.Procedural_Summary( );
}
if( report_mask & rtPROC2 )
{
main_html_stream.Procedural_Detail( );
}
if( report_mask & rtOODESIGN )
{
main_html_stream.OO_Design( );
}
if( report_mask & rtSTRUCT1 )
{
main_html_stream.Structural_Summary( );
}
if( report_mask & rtSTRUCT2 )
{
main_html_stream.Structural_Detail( );
}
if( report_mask & rtSEPARATE_MODULES )
{
main_html_stream.Separate_Modules( );
}
if( report_mask & rtOTHER )
{
main_html_stream.Other_Extents( );
}
if( report_mask & rtSOURCE )
{
main_html_stream.Source_Listing( );
}
if( report_mask & rtCCCC )
{
main_html_stream.Put_Section_Heading( "About CCCC", "infocccc", 1 );
main_html_stream.fstr
<< "<P>This report was generated by the program CCCC, which is FREELY "
<< "REDISTRIBUTABLE but carries NO WARRANTY." << endl
<< "<P>CCCC was developed by Tim Littlefair. " << endl
<< "as part of a PhD research project. "
<< "This project is now completed and descriptions of the "
<< "findings can be accessed at "
<< "<A HREF=http://www.chs.ecu.edu.au/~tlittlef>"
<< "http://www.chs.ecu.edu.au/~tlittlef</A>. "
<< "<P>User support for CCCC can be obtained by "
<< "<A HREF=mailto:cccc-users@lists.sourceforge.net>"
<< "mailing the list cccc-users@lists.sourceforge.net</A>."
<< "<P>Please also visit the new CCCC development website at "
<< "<A HREF=http://sarnold.github.io/cccc/>http://sarnold.github.io/cccc/</A>."
<< endl;
}
}
148 CCCC_Html_Stream::~CCCC_Html_Stream( )
{
fstr << "</BODY></HTML>" << endl;
fstr.close( );
}
154 void CCCC_Html_Stream::Table_Of_Contents( int report_mask, bool showGenTime )
{
// record the number of report parts in the table, and the
// stream put pointer
// if we find that we have only generated a single part, we supress
// the TOC by seeking to the saved stream offset
int number_of_report_parts=0;
int saved_stream_offset=fstr.tellp( );
fstr << "<TABLE BORDER WIDTH=100%>" << endl
<< "<TR><TH COLSPAN=2>" << endl
<< "CCCC Software Metrics Report";
if( prjptr->name( nlSIMPLE )!="" )
{
fstr << " on project " << prjptr->name( nlSIMPLE );
}
fstr << endl;
// we have the option to disable the display of the generation time
// so that we can generate identical reports for regression testing
if( showGenTime==true )
{
time_t generationTime=time( NULL );
fstr << "<BR> generated " << ctime( &generationTime ) << endl;
}
fstr << "</TR>" << endl;
if( report_mask & rtSUMMARY )
{
Put_Section_TOC_Entry(
"Project Summary", "projsum",
"Summary table of high level measures summed "
"over all files processed in the current run." );
number_of_report_parts++;
}
if( report_mask & rtPROC1 )
{
Put_Section_TOC_Entry(
"Procedural Metrics Summary", "procsum",
"Table of procedural measures ( i.e. lines of "
"code, lines of comment, McCabe's cyclomatic "
"complexity summed over each module." );
number_of_report_parts++;
}
if( report_mask & rtPROC2 )
{
Put_Section_TOC_Entry(
"Procedural Metrics Detail", "procdet",
"The same procedural metrics as in the procedural "
"metrics summary, reported for individual "
"functions, grouped by module." );
number_of_report_parts++;
}
if( report_mask & rtOODESIGN )
{
Put_Section_TOC_Entry(
"Object Oriented Design", "oodesign",
"Table of four of the 6 metrics proposed by "
"Chidamber and Kemerer in their various papers on "
"'a metrics suite for object oriented design'." );
number_of_report_parts++;
}
if( report_mask & rtSTRUCT1 )
{
Put_Section_TOC_Entry(
"Structural Metrics Summary", "structsum",
"Structural metrics based on the relationships of "
"each module with others. Includes fan-out ( i.e. "
"number of other modules the current module "
"uses ), fan-in ( number of other modules which use "
"the current module ), and the Information Flow "
"measure suggested by Henry and Kafura, which "
"combines these to give a measure of coupling for "
"the module." );
number_of_report_parts++;
}
if( report_mask & rtSTRUCT2 )
{
Put_Section_TOC_Entry(
"Structural Metrics Detail", "structdet",
"The names of the modules included as clients and "
"suppliers in the counts for the Structural "
"Metrics Summary." );
number_of_report_parts++;
}
if( report_mask & rtOTHER )
{
Put_Section_TOC_Entry(
"Other Extents", "other",
"Lexical counts for parts of submitted source "
"files which the analyser was unable to assign to "
"a module. Each record in this table relates to "
"either a part of the code which triggered a "
"parse failure, or to the residual lexical counts "
"relating to parts of a file not associated with "
"a specific module."
);
number_of_report_parts++;
}
if( report_mask & rtCCCC )
{
Put_Section_TOC_Entry(
"About CCCC", "infocccc",
"A description of the CCCC program." );
number_of_report_parts++;
}
fstr << "</TR></TABLE>" << endl;
if( number_of_report_parts<2 )
{
fstr.seekp( saved_stream_offset );
}
}
276 void CCCC_Html_Stream::Put_Section_Heading(
277 string heading_title,
278 string heading_tag,
int heading_level )
{
fstr << "<H" << heading_level << ">"
<< "<A NAME=\"" << heading_tag << "\">"
<< heading_title
<< "</A></H" << heading_level
<< ">" << endl;
}
288 void CCCC_Html_Stream::Project_Summary( ) {
Put_Section_Heading( "Project Summary", "projsum", 1 );
fstr << "This table shows measures over the project as a whole." << endl;
fstr << "<UL>" << endl;
Metric_Description( "NOM", "Number of modules",
"Number of non-trivial modules identified by the "
"analyser. Non-trivial modules include all classes, "
"and any other module for which member functions are "
"identified." );
Metric_Description( "LOC", "Lines of Code",
"Number of non-blank, non-comment lines of source code "
"counted by the analyser." );
Metric_Description( "COM", "Lines of Comments",
"Number of lines of comment identified by the analyser" );
Metric_Description( "MVG", "McCabe's Cyclomatic Complexity",
"A measure of the decision complexity of the functions "
"which make up the program."
"The strict definition of this measure is that it is "
"the number of linearly independent routes through "
"a directed acyclic graph which maps the flow of control "
"of a subprogram. The analyser counts this by recording "
"the number of distinct decision outcomes contained "
"within each function, which yields a good approximation "
"to the formally defined version of the measure." );
Metric_Description( "L_C", "Lines of code per line of comment",
"Indicates density of comments with respect to textual "
"size of program" );
Metric_Description( "M_C", "Cyclomatic Complexity per line of comment",
"Indicates density of comments with respect to logical "
"complexity of program" );
Metric_Description( "IF4", "Information Flow measure",
"Measure of information flow between modules suggested "
"by Henry and Kafura. The analyser makes an approximate "
"count of this by counting inter-module couplings "
"identified in the module interfaces." );
fstr << "</UL>" << endl
<< "Two variants on the information flow measure IF4 are also "
<< "presented, one ( IF4v ) calculated using only relationships in the "
<< "visible part of the module interface, and the other ( IF4c ) "
<< "calculated using only those relationships which imply that changes "
<< "to the client must be recompiled of the supplier's definition "
<< "changes."
<< endl << endl;
// calculate the counts on which all displayed data will be based
int nom=prjptr->get_count( "NOM" ); // number of modules
int loc=prjptr->get_count( "LOC" ); // lines of code
int mvg=prjptr->get_count( "MVG" ); // McCabes cyclomatic complexity
int com=prjptr->get_count( "COM" ); // lines of comment
int if4=prjptr->get_count( "IF4" ); // intermodule complexity ( all couplings )
int if4v=prjptr->get_count( "IF4v" ); // intermodule complexity ( visible only )
int if4c=prjptr->get_count( "IF4c" ); // intermodule complexity ( concrete only )
int rej=prjptr->rejected_extent_table.get_count( "LOC" );
fstr << "<TABLE BORDER WIDTH=100%>" << endl
<< "<TR>" << endl;
Put_Header_Cell( "Metric", 70 );
Put_Header_Cell( "Tag", 10 );
Put_Header_Cell( "Overall", 10 );
Put_Header_Cell( "Per Module", 10 );
fstr << "</TR>" << endl;
fstr << "<TR>" << endl;
Put_Label_Cell( "Number of modules" );
Put_Label_Cell( "NOM" );
Put_Metric_Cell( nom );
Put_Label_Cell( "" );
fstr << "</TR>" << endl;
fstr << "<TR>" << endl;
Put_Label_Cell( "Lines of Code", 700 );
Put_Label_Cell( "LOC", 120 );
Put_Metric_Cell( loc, "LOCp" );
Put_Metric_Cell( loc, nom, "LOCper" );
fstr << "</TR>" << endl;
fstr << "<TR>" << endl;
Put_Label_Cell( "McCabe's Cyclomatic Number" );
Put_Label_Cell( "MVG" );
Put_Metric_Cell( mvg, "MVGp" );
Put_Metric_Cell( mvg, nom, "MVGper" );
fstr << "</TR>" << endl;
fstr << "<TR>" << endl;
Put_Label_Cell( "Lines of Comment" );
Put_Label_Cell( "COM" );
Put_Metric_Cell( com, "COM" );
Put_Metric_Cell( com, nom, "COMper" );
fstr << "</TR>" << endl;
fstr << "<TR>" << endl;
Put_Label_Cell( "LOC/COM" );
Put_Label_Cell( "L_C" );
Put_Metric_Cell( loc, com, "L_C" );
Put_Label_Cell( "" );
fstr << "</TR>" << endl;
fstr << "<TR>" << endl;
Put_Label_Cell( "MVG/COM" );
Put_Label_Cell( "M_C" );
Put_Metric_Cell( mvg, com, "M_C" );
Put_Label_Cell( "" );
fstr << "</TR>" << endl;
fstr << "<TR>" << endl;
Put_Label_Cell( "Information Flow measure ( inclusive )" );
Put_Label_Cell( "IF4" );
Put_Metric_Cell( if4 );
Put_Metric_Cell( if4, nom, "8.3" );
fstr << "</TR>" << endl;
fstr << "<TR>" << endl;
Put_Label_Cell( "Information Flow measure ( visible )" );
Put_Label_Cell( "IF4v" );
Put_Metric_Cell( if4v );
Put_Metric_Cell( if4v, nom, "8.3" );
fstr << "</TR>" << endl;
fstr << "<TR>" << endl;
Put_Label_Cell( "Information Flow measure ( concrete )" );
Put_Label_Cell( "IF4c" );
Put_Metric_Cell( if4c );
Put_Metric_Cell( if4c, nom, "8.3" );
fstr << "</TR>" << endl;
fstr << "<TR>" << endl;
Put_Label_Cell( "Lines of Code rejected by parser" );
Put_Label_Cell( "REJ" );
Put_Metric_Cell( rej, "REJ" );
Put_Label_Cell( "" );
fstr << "</TR>" << endl;
fstr << "</TABLE>" << endl;
}
426 void CCCC_Html_Stream::OO_Design( ) {
Put_Section_Heading( "Object Oriented Design", "oodesign", 1 );
fstr << "<UL>" << endl;
Metric_Description( "WMC", "Weighted methods per class",
"The sum of a weighting function over the functions of "
"the module. Two different weighting functions are "
"applied: WMC1 uses the nominal weight of 1 for each "
"function, and hence measures the number of functions, "
"WMCv uses a weighting function which is 1 for functions "
"accessible to other modules, 0 for private functions." );
Metric_Description( "DIT", "Depth of inheritance tree",
"The length of the longest path of inheritance ending at "
"the current module. The deeper the inheritance tree "
"for a module, the harder it may be to predict its "
"behaviour. On the other hand, increasing depth gives "
"the potential of greater reuse by the current module "
"of behaviour defined for ancestor classes." );
Metric_Description( "NOC", "Number of children",
"The number of modules which inherit directly from the "
"current module. Moderate values of this measure "
"indicate scope for reuse, however high values may "
"indicate an inappropriate abstraction in the design." );
Metric_Description( "CBO", "Coupling between objects",
"The number of other modules which are coupled to the "
"current module either as a client or a supplier. "
"Excessive coupling indicates weakness of module "
"encapsulation and may inhibit reuse." );
fstr << "</UL>" << endl << endl;
fstr << "The label cell for each row in this table provides a link to "
<< "the module summary table in the detailed report for the "
<< "module in question" << endl;
fstr << "<TABLE BORDER WIDTH=100%>" << endl
<< "<TR>" << endl;
Put_Header_Cell( "Module Name", 50 );
Put_Header_Cell( "WMC1", 10 );
Put_Header_Cell( "WMCv", 10 );
Put_Header_Cell( "DIT", 10 );
Put_Header_Cell( "NOC", 10 );
Put_Header_Cell( "CBO", 10 );
fstr << "</TR>" << endl;
CCCC_Module* mod_ptr=prjptr->module_table.first_item( );
int i=0;
while( mod_ptr!=NULL )
{
i++;
if( mod_ptr->is_trivial( ) == FALSE )
{
const char *metric_tags[5]={"WMC1", "WMCv", "DIT", "NOC", "CBO"};
fstr << "<TR>" << endl;
string href=mod_ptr->key( )+".html#summary";
Put_Label_Cell( mod_ptr->name( nlSIMPLE ).c_str( ), 0, "", href.c_str( ) );
int j;
for( j=0; j<5; j++ )
{
CCCC_Metric metric_value(
mod_ptr->get_count( metric_tags[j] ),
metric_tags[j]
);
Put_Metric_Cell( metric_value );
}
fstr << "</TR>" << endl;
}
mod_ptr=prjptr->module_table.next_item( );
}
fstr << "</TABLE>" << endl;
}
505 void CCCC_Html_Stream::Procedural_Summary( ) {
Put_Section_Heading( "Procedural Metrics Summary", "procsum", 1 );
fstr << "For descriptions of each of these metrics see the information "
<< "preceding the project summary table."
<< endl << endl;
fstr << "The label cell for each row in this table provides a link to "
<< "the functions table in the detailed report for the "
<< "module in question" << endl;
fstr << "<TABLE BORDER WIDTH=100%>" << endl
<< "<TR>" << endl;
Put_Header_Cell( "Module Name" );
Put_Header_Cell( "LOC", 8 );
Put_Header_Cell( "MVG", 8 );
Put_Header_Cell( "COM", 8 );
Put_Header_Cell( "L_C", 8 );
Put_Header_Cell( "M_C", 8 );
fstr << "</TR>" << endl;
CCCC_Module* mod_ptr=prjptr->module_table.first_item( );
int i=0;
while( mod_ptr!=NULL )
{
i++;
if( mod_ptr->is_trivial( ) == FALSE )
{
fstr << "<TR>" << endl;
string href=mod_ptr->key( )+".html#procdet";
Put_Label_Cell( mod_ptr->name( nlSIMPLE ).c_str( ), 0, "", href.c_str( ) );
int loc=mod_ptr->get_count( "LOC" );
int mvg=mod_ptr->get_count( "MVG" );
int com=mod_ptr->get_count( "COM" );
CCCC_Metric mloc( loc, "LOCm" );
CCCC_Metric mmvg( mvg, "MVGm" );
CCCC_Metric ml_c( loc, com, "L_C" );
CCCC_Metric mm_c( mvg, com, "M_C" );
Put_Metric_Cell( mloc );
Put_Metric_Cell( mmvg );
Put_Metric_Cell( com );
Put_Metric_Cell( ml_c );
Put_Metric_Cell( mm_c );
fstr << "</TR>" << endl;
}
mod_ptr=prjptr->module_table.next_item( );
}
fstr << "</TABLE>" << endl;
}
562 void CCCC_Html_Stream::Structural_Summary( )
{
Put_Section_Heading( "Structural Metrics Summary", "structsum", 1 );
fstr << "<UL>" << endl;
Metric_Description( "FI", "Fan-in",
"The number of other modules which pass information "
"into the current module." );
Metric_Description( "FO", "Fan-out",
"The number of other modules into which the current "
"module passes information" );
Metric_Description( "IF4", "Information Flow measure",
"A composite measure of structural complexity, "
"calculated as the square of the product of the fan-in "
"and fan-out of a single module. Proposed by Henry and "
"Kafura." );
fstr << "</UL>" << endl;
fstr << "Note that the fan-in and fan-out are calculated by examining the "
<< "interface of each module. As noted above, three variants of each "
<< "each of these measures are presented: a count restricted to the "
<< "part of the interface which is externally visible, a count which "
<< "only includes relationships which imply the client module needs "
<< "to be recompiled if the supplier's implementation changes, and an "
<< "inclusive count" << endl << endl;
fstr << "The label cell for each row in this table provides a link to "
<< "the relationships table in the detailed report for the "
<< "module in question" << endl << endl;
fstr << "<TABLE BORDER WIDTH=100%>" << endl;
fstr << "<TR>" << endl
<< "<TH BGCOLOR=AQUA ROWSPAN=2>Module Name</TH>" << endl
<< "<TH BGCOLOR=AQUA COLSPAN=3>Fan-out</TH>" << endl
<< "<TH BGCOLOR=AQUA COLSPAN=3>Fan-in</TH>" << endl
<< "<TH BGCOLOR=AQUA COLSPAN=3>IF4</TH>" << endl
<< "</TR>" << endl;
Put_Header_Cell( "vis", 7 );
Put_Header_Cell( "con", 7 );
Put_Header_Cell( "inc", 7 );
Put_Header_Cell( "vis", 7 );
Put_Header_Cell( "con", 7 );
Put_Header_Cell( "incl", 7 );
Put_Header_Cell( "vis", 7 );
Put_Header_Cell( "con", 7 );
Put_Header_Cell( "inc", 7 );
fstr << "</TR>" << endl;
CCCC_Module* module_ptr=prjptr->module_table.first_item( );
while( module_ptr!=NULL )
{
if( module_ptr->is_trivial( )==FALSE )
{
fstr << "<TR>" << endl;
int fov=module_ptr->get_count( "FOv" );
int foc=module_ptr->get_count( "FOc" );
int fo=module_ptr->get_count( "FO" );
int fiv=module_ptr->get_count( "FIv" );
int fic=module_ptr->get_count( "FIc" );
int fi=module_ptr->get_count( "FI" );
int if4v=module_ptr->get_count( "IF4v" );
int if4c=module_ptr->get_count( "IF4c" );
int if4=module_ptr->get_count( "IF4" );
// the last two arguments here turn on links to enable jumping between
// the summary and detail cells for the same module
string href=module_ptr->key( )+".html#structdet";
Put_Label_Cell( module_ptr->name( nlSIMPLE ).c_str( ), 0, "", href.c_str( ) );
Put_Metric_Cell( CCCC_Metric( fov, "FOv" ) );
Put_Metric_Cell( CCCC_Metric( foc, "FOc" ) );
Put_Metric_Cell( CCCC_Metric( fo, "FO" ) );
Put_Metric_Cell( CCCC_Metric( fiv, "FIv" ) );
Put_Metric_Cell( CCCC_Metric( fic, "FIc" ) );
Put_Metric_Cell( CCCC_Metric( fi, "FI" ) );
Put_Metric_Cell( CCCC_Metric( if4v, "IF4v" ) );
Put_Metric_Cell( CCCC_Metric( if4c, "IF4c" ) );
Put_Metric_Cell( CCCC_Metric( if4, "IF4" ) );
fstr << "</TR>" << endl;
}
module_ptr=prjptr->module_table.next_item( );
}
fstr << "</TABLE>" << endl;
}
653 void CCCC_Html_Stream::Put_Structural_Details_Cell(
654 CCCC_Module *mod, CCCC_Project *prj, int mask, UserelNameLevel nl )
{
fstr << "<TD WIDTH=50%>" << endl;
#if 0
std::cerr << "Relationships for " << mod->name( nlMODULE_NAME )
<< " ( " << mod << " )" << std::endl;
#endif
CCCC_Module::relationship_map_t::iterator iter;
CCCC_Module::relationship_map_t *relationship_map=NULL;
if( mask==rmeCLIENT )
{
relationship_map=&( mod->client_map );
}
else if( mask==rmeSUPPLIER )
{
relationship_map=&( mod->supplier_map );
}
if( relationship_map==NULL )
{
cerr << "unexpected relationship mask " << mask << endl;
}
else
{
for(
iter=relationship_map->begin( );
iter!=relationship_map->end( );
iter++
)
{
CCCC_UseRelationship *ur_ptr=( *iter ).second;
fstr << ur_ptr->name( nl ) << " ";
AugmentedBool vis=ur_ptr->is_visible( );
AugmentedBool con=ur_ptr->is_concrete( );
#if 0
std::cerr << ur_ptr->name( nlCLIENT )
<< " uses "
<< ur_ptr->name( nlSUPPLIER )
<< std::endl;
#endif
if( ( vis != abFALSE ) && ( con != abFALSE ) )
{
fstr << "[CV] ";
}
else if( vis != abFALSE )
{
fstr << "[V] ";
}
else if( con != abFALSE )
{
fstr << "[C] ";
}
fstr << "<BR>" << endl;
Put_Extent_List( *ur_ptr, true );
fstr << "<BR>" << endl;
}
}
// put a non-breaking space in to avoid the unpleasantness which
// goes with completely empty cells
fstr << " " << endl;
fstr << "</TD>" << endl;
}
723 void CCCC_Html_Stream::Structural_Detail( )
{
Put_Section_Heading( "Structural Metrics Detail", "structdet", 1 );
fstr << "<TABLE BORDER WIDTH=100%>" << endl;
fstr << "<TR>" << endl;
Put_Header_Cell( "Module Name", 20 );
Put_Header_Cell( "Clients", 40 );
Put_Header_Cell( "Suppliers", 40 );
fstr << "</TR>" << endl;
CCCC_Module* module_ptr=prjptr->module_table.first_item( );
while( module_ptr!=NULL )
{
if( module_ptr->is_trivial( )==FALSE )
{
fstr << "<TR>" << endl;
Put_Label_Cell( module_ptr->name( nlSIMPLE ).c_str( ), 0, "structdet", "structsum" );
Structural_Detail( module_ptr );
fstr << "</TR>" << endl;
}
module_ptr=prjptr->module_table.next_item( );
}
fstr << "</TABLE>" << endl;
}
749 void CCCC_Html_Stream::Procedural_Detail( ) {
Put_Section_Heading( "Procedural Metrics Detail", "procdet", 1 );
fstr << "<TABLE BORDER WIDTH=100%>" << endl;
CCCC_Module* mod_ptr=prjptr->module_table.first_item( );
while( mod_ptr!=NULL )
{
if(
( mod_ptr->name( nlMODULE_TYPE )!="builtin" ) &&
( mod_ptr->name( nlMODULE_TYPE )!="enum" ) &&
( mod_ptr->name( nlMODULE_TYPE )!="union" )
)
{
fstr << "<TR>" << endl;
Put_Label_Cell( mod_ptr->name( nlSIMPLE ).c_str( ), 50,
"procdet", "procsum", mod_ptr );
Put_Header_Cell( "LOC", 10 );
Put_Header_Cell( "MVG", 10 );
Put_Header_Cell( "COM", 10 );
Put_Header_Cell( "L_C", 10 );
Put_Header_Cell( "M_C", 10 );
fstr << "</TR>" << endl;
Procedural_Detail( mod_ptr );
}
mod_ptr=prjptr->module_table.next_item( );
}
fstr << "</TABLE>" << endl;
}
780 void CCCC_Html_Stream::Other_Extents( )
{
Put_Section_Heading( "Other Extents", "other", 1 );
fstr << "<TABLE BORDER WIDTH=100%>" << endl;
fstr << "<TR>" << endl;
Put_Header_Cell( "Location", 25 );
Put_Header_Cell( "Text", 45 );
Put_Header_Cell( "LOC", 10 );
Put_Header_Cell( "COM", 10 );
Put_Header_Cell( "MVG", 10 );
fstr << "</TR>" << endl;
if( prjptr->rejected_extent_table.records( ) == 0 )
{
fstr << "<TR><TD COLSPAN=5>"
<< " "
<< "</TD></TR>" << endl;
}
else
{
CCCC_Extent *extent_ptr=prjptr->rejected_extent_table.first_item( );
while( extent_ptr!=NULL )
{
fstr << "<TR>";
Put_Extent_Cell( *extent_ptr, 0 );
Put_Label_Cell( extent_ptr->name( nlDESCRIPTION ).c_str( ) );
Put_Metric_Cell( extent_ptr->get_count( "LOC" ), "" );
Put_Metric_Cell( extent_ptr->get_count( "COM" ), "" );
Put_Metric_Cell( extent_ptr->get_count( "MVG" ), "" );
fstr << "</TR>" << endl;
extent_ptr=prjptr->rejected_extent_table.next_item( );
}
}
fstr << "</TABLE>" << endl;
}
817 void CCCC_Html_Stream::Put_Section_TOC_Entry(
818 string section_name, string section_href,
819 string section_description )
{
fstr << "<TR>" << endl
<< "<TH><H4><A HREF=\"#" << section_href << "\">"
<< section_name << "</A></H4></TH>" << endl
<< "<TD>" << endl
<< section_description << endl
<< "</TR>" << endl;
}
829 void CCCC_Html_Stream::Put_Header_Cell( string label, int width )
{
fstr << "<TH BGCOLOR=\"AQUA\"";
if( width>0 )
{
fstr << " WIDTH=" << width << "%" ;
}
fstr << ">" ;
if( label.size( )>0 )
{
*this << label.c_str( );
}
else
{
// put a non-breaking space in to avoid the strange
// bevelling associated with empty cells
fstr << " ";
}
fstr << "</TH>";
}
851 void CCCC_Html_Stream::Put_Label_Cell(
852 string label, int width,
853 string ref_name, string ref_href,
854 CCCC_Record *rec_ptr )
{
fstr << "<TD";
if( width>0 )
{
fstr << " WIDTH=" << width <<"%";
}
fstr << ">" ;
if( ref_name.size( ) > 0 )
{
// we need to insert an HTML "<A NAME=...> tag for the current cell
// this enables other locations to jump in
fstr << "<A NAME=\"" << ref_name << "\"></A>" << endl;
}
if( ref_href.size( ) > 0 )
{
// we need to insert an HTML <A HREF=...> tag for the current cell
// this enables this cell to be a link to jump out
fstr << "<A HREF=\"" << ref_href << "\">" << endl;
// this anchor will need to be closed after the label has been displayed
}
if( label.size( )>0 )
{
*this << label.c_str( ) ;
}
else
{
// put a non-breaking space in to avoid the strange
// bevelling associated with empty cells
fstr << " ";
}
if( ref_href.size( ) > 0 )
{
// closing the anchor we opened above
fstr << "</A>" << endl;
}
if( rec_ptr != 0 )
{
fstr << "<BR>" << endl;
Put_Extent_List( *rec_ptr, true );
}
fstr << "</TD>";
}
905 void CCCC_Html_Stream::Put_Metric_Cell(
906 int count, string tag, int width )
{
CCCC_Metric m( count, tag.c_str( ) );
Put_Metric_Cell( m, width );
}
912 void CCCC_Html_Stream::Put_Metric_Cell(
913 int num, int denom, string tag, int width )
{
CCCC_Metric m( num, denom, tag.c_str( ) );
Put_Metric_Cell( m, width );
}
919 void CCCC_Html_Stream::Put_Metric_Cell( const CCCC_Metric& metric, int width )
{
fstr << "<TD ALIGN=RIGHT";
if( width>0 )
{
fstr << " WIDTH=" << width << "%" ;
}
switch( metric.emphasis_level( ) )
{
case elMEDIUM:
fstr << " BGCOLOR=\"YELLOW\"";
break;
case elHIGH:
fstr << " BGCOLOR=\"RED\"";
break;
default:
// no background colour
break;
}
fstr << ">";
*this << metric;
fstr << "</TD>";
}
946 void CCCC_Html_Stream::Put_Extent_URL( const CCCC_Extent& extent )
{
string filename=extent.name( nlFILENAME );
int linenumber=atoi( extent.name( nlLINENUMBER ).c_str( ) );
Source_Anchor anchor( filename, linenumber );
string key=anchor.key( );
source_anchor_map_t::value_type anchor_value( key, anchor );
source_anchor_map.insert( anchor_value );
anchor.Emit_HREF( fstr );
fstr
// << extent.name( nlDESCRIPTION )
<< "<BR>" << endl;
}
962 void CCCC_Html_Stream::Put_Extent_Cell( const CCCC_Extent& extent, int width, bool withDescription ) {
fstr << "<TD";
if( width>0 )
{
fstr << " WIDTH=" << width << "%>";
}
else
{
fstr << ">";
}
if( withDescription )
{
fstr << extent.name( nlDESCRIPTION ) << " " << endl;
}
Put_Extent_URL( extent );
fstr << "</TD>" << endl;
}
980 void CCCC_Html_Stream::Put_Extent_List( CCCC_Record& record, bool withDescription )
{
CCCC_Extent *ext_ptr=record.extent_table.first_item( );
while( ext_ptr!=NULL )
{
if( withDescription )
{
fstr << ext_ptr->name( nlDESCRIPTION ) << " " << endl;
}
Put_Extent_URL( *ext_ptr );
ext_ptr=record.extent_table.next_item( );
}
fstr << "<BR>" << endl;
}
// the next two methods define the two basic output operations through which
// all of the higher level output operations are composed
997 CCCC_Html_Stream& operator <<( CCCC_Html_Stream& os, const string& stg )
{
// initialise a character pointer to the start of the string's buffer
const char *cptr=stg.c_str( );
while( *cptr!='\000' ) {
char c=*cptr;
// the purpose of this is to filter out the characters which
// must be escaped in HTML
switch( c ) {
case '>': os.fstr << ">" ; break;
case '<': os.fstr << "<" ; break;
case '&': os.fstr << "&"; break;
// commas and parentheses do not need to be escaped, but
// we want to allow line breaking just inside
// parameter lists and after commas
// we insert a non-breaking space to guarantee a small indent
// on the new line, and one before the right parenthesis for
// symmetry
case ', ': os.fstr << ", " ; break;
case '( ': os.fstr << "( " ; break;
case ' )': os.fstr << " )" ; break;
default : os.fstr << c;
}
cptr++;
}
return os;
}
1026 CCCC_Html_Stream& operator <<( CCCC_Html_Stream& os, const CCCC_Metric& mtc )
{
const char *emphasis_prefix[]={"", "<EM>", "<STRONG>"};
const char *emphasis_suffix[]={"", "</EM>", "</STRONG>"};
// by writing to the underlying ostream object, we avoid the escape
// functionality
os.fstr << emphasis_prefix[mtc.emphasis_level( )]
<< mtc.value_string( )
<< emphasis_suffix[mtc.emphasis_level( )];
return os;
}
1039 void CCCC_Html_Stream::Separate_Modules( )
{
// this function generates a separate HTML report for each non-trivial
// module in the database
CCCC_Module* mod_ptr=prjptr->module_table.first_item( );
while( mod_ptr!=NULL )
{
int trivial_module=mod_ptr->is_trivial( );
if( trivial_module==FALSE )
{
string info="Detailed report on module " + mod_ptr->key( );
string filename=outdir;
filename+="/";
filename+=mod_ptr->key( )+".html";
CCCC_Html_Stream module_html_str( filename, info.c_str( ) );
module_html_str.Put_Section_Heading( info.c_str( ), "summary", 1 );
module_html_str.Module_Summary( mod_ptr );
module_html_str.Put_Section_Heading( "Definitions and Declarations",
"modext", 2 );
module_html_str.fstr << "<TABLE BORDER WIDTH=100%><TR>" << endl;
module_html_str.Put_Label_Cell( "Description", 50 );
module_html_str.Put_Header_Cell( "LOC", 10 );
module_html_str.Put_Header_Cell( "MVG", 10 );
module_html_str.Put_Header_Cell( "COM", 10 );
module_html_str.Put_Header_Cell( "L_C", 10 );
module_html_str.Put_Header_Cell( "M_C", 10 );
module_html_str.Module_Detail( mod_ptr );
module_html_str.fstr << "</TR></TABLE>" << endl;
module_html_str.Put_Section_Heading( "Functions", "proc", 2 );
module_html_str.fstr << "<TABLE BORDER WIDTH=100%><TR>" << endl;
module_html_str.Put_Label_Cell( "Function prototype", 50 );
module_html_str.Put_Header_Cell( "LOC", 10 );
module_html_str.Put_Header_Cell( "MVG", 10 );
module_html_str.Put_Header_Cell( "COM", 10 );
module_html_str.Put_Header_Cell( "L_C", 10 );
module_html_str.Put_Header_Cell( "M_C", 10 );
module_html_str.Procedural_Detail( mod_ptr );
module_html_str.fstr << "</TR></TABLE>" << endl;
module_html_str.Put_Section_Heading( "Relationships", "structdet", 2 );
module_html_str.fstr
<< "<TABLE BORDER WIDTH=100%>" << endl
<< "<TR><TH WIDTH=50%>Clients</TH><TH WIDTH=50%>Suppliers</TH></TR>"
<< endl
<< "<TR>" << endl;
module_html_str.Structural_Detail( mod_ptr );
module_html_str.fstr << "</TR></TABLE>" << endl;
}
else
{
#if 0
cerr << mod_ptr->module_type << " " << mod_ptr->key( )
<< " is trivial" << endl;
#endif
}
mod_ptr=prjptr->module_table.next_item( );
}
}
1105 void CCCC_Html_Stream::Module_Detail( CCCC_Module *module_ptr )
{
// this function generates the contents of the table of definition
// and declaration extents for a single module
// the output needs to be enveloped in a pair of <TABLE></TABLE> tags
// these have not been put within the function because it is designed
// to be used in two contexts:
// 1. within the Separate_Modules function, wrapped directly in the table
// tags
// 2. within the Module_Detail function, where the table tags are
// around the output of many calls to this function ( not yet implemented )
CCCC_Record::Extent_Table::iterator eIter = module_ptr->extent_table.begin( );
if( eIter==module_ptr->extent_table.end( ) )
{
fstr << "<TR><TD COLSPAN=6>"
<< "No module extents have been identified for this module"
<< "</TD></TR>" << endl;
}
else
{
while( eIter!=module_ptr->extent_table.end( ) )
{
CCCC_Extent *ext_ptr=( *eIter ).second;
fstr << "<TR>" << endl;
Put_Extent_Cell( *ext_ptr, 0, true );
int loc=ext_ptr->get_count( "LOC" );
int mvg=ext_ptr->get_count( "MVG" );
int com=ext_ptr->get_count( "COM" );
CCCC_Metric mloc( loc, "LOCf" );
CCCC_Metric mmvg( mvg, "MVGf" );
CCCC_Metric ml_c( loc, com, "L_C" );
CCCC_Metric mm_c( mvg, com, "M_C" );
Put_Metric_Cell( mloc );
Put_Metric_Cell( mmvg );
Put_Metric_Cell( com );
Put_Metric_Cell( ml_c );
Put_Metric_Cell( mm_c );
fstr << "</TR>" << endl;
eIter++;
}
}
fstr << "<TR><TD HEIGHT=12 COLSPAN=6></TD></TR>" << endl;
}
1154 void CCCC_Html_Stream::Procedural_Detail( CCCC_Module *module_ptr )
{
// this function generates the contents of the procedural detail table
// relating to a single module
// the output needs to be enveloped in a pair of <TABLE></TABLE> tags
// these have not been put within the function because it is designed
// to be used in two contexts:
// 1. within the Separate_Modules function, wrapped directly in the table
// tags
// 2. within the Procedural_Detail function, where the table tags are
// around the output of many calls to this function
CCCC_Module::member_map_t::iterator iter = module_ptr->member_map.begin( );
if( iter==module_ptr->member_map.end( ) )
{
fstr << "<TR><TD COLSPAN=6>"
<< "No member functions have been identified for this module"
<< "</TD></TR>" << endl;
}
else
{
while( iter!=module_ptr->member_map.end( ) )
{
CCCC_Member *mem_ptr=( *iter ).second;
fstr << "<TR>" << endl;
Put_Label_Cell( mem_ptr->name( nlLOCAL ).c_str( ), 0, "", "", mem_ptr );
int loc=mem_ptr->get_count( "LOC" );
int mvg=mem_ptr->get_count( "MVG" );
int com=mem_ptr->get_count( "COM" );
CCCC_Metric mloc( loc, "LOCf" );
CCCC_Metric mmvg( mvg, "MVGf" );
CCCC_Metric ml_c( loc, com, "L_C" );
CCCC_Metric mm_c( mvg, com, "M_C" );
Put_Metric_Cell( mloc );
Put_Metric_Cell( mmvg );
Put_Metric_Cell( com );
Put_Metric_Cell( ml_c );
Put_Metric_Cell( mm_c );
fstr << "</TR>" << endl;
iter++;
}
}
fstr << "<TR><TD HEIGHT=12 COLSPAN=6></TD></TR>" << endl;
}
1204 void CCCC_Html_Stream::Metric_Description(
1205 string abbreviation,
1206 string name,
1207 string description )
{
// this is intended to be called in the context of an unnumbered list
fstr << "<LI>" << abbreviation << " = " << name << "<BR>" << endl
<< description << endl;
}
1214 void CCCC_Html_Stream::Structural_Detail( CCCC_Module *module_ptr )
{
Put_Structural_Details_Cell( module_ptr, prjptr, rmeCLIENT, nlCLIENT );
Put_Structural_Details_Cell( module_ptr, prjptr, rmeSUPPLIER, nlSUPPLIER );
}
1220 void CCCC_Html_Stream::Module_Summary( CCCC_Module *module_ptr )
{
// calculate the counts on which all displayed data will be based
// int nof=module_ptr->member_table.records( ); // Number of functions
int nof=0;
int loc=module_ptr->get_count( "LOC" ); // lines of code
int mvg=module_ptr->get_count( "MVG" ); // McCabes cyclomatic complexity
int com=module_ptr->get_count( "COM" ); // lines of comment
// the variants of IF4 measure information flow and couplings
int if4=module_ptr->get_count( "IF4" ); // ( all couplings )
int if4v=module_ptr->get_count( "IF4v" ); // ( visible only )
int if4c=module_ptr->get_count( "IF4c" ); // ( concrete only )
int wmc1=module_ptr->get_count( "WMC1" ); // Weighted methods/class ( unity )
int wmcv=module_ptr->get_count( "WMCv" ); // Weighted methods/class ( visible )
int dit=module_ptr->get_count( "DIT" ); // depth of inheritance tree
int noc=module_ptr->get_count( "NOC" ); // number of children
int cbo=module_ptr->get_count( "CBO" ); // coupling between objects
fstr << "<TABLE BORDER WIDTH=100%>" << endl
<< "<TR>" << endl;
Put_Header_Cell( "Metric", 70 );
Put_Header_Cell( "Tag", 10 );
Put_Header_Cell( "Overall", 10 );
Put_Header_Cell( "Per Function", 10 );
fstr << "</TR>" << endl;
fstr << "<TR>" << endl;
Put_Label_Cell( "Lines of Code" );
Put_Label_Cell( "LOC" );
Put_Metric_Cell( loc, "LOCm" );
Put_Metric_Cell( loc, nof, "LOCg" );
fstr << "</TR>" << endl;
fstr << "<TR>" << endl;
Put_Label_Cell( "McCabe's Cyclomatic Number" );
Put_Label_Cell( "MVG" );
Put_Metric_Cell( mvg, "MVGm" );
Put_Metric_Cell( mvg, nof, "MVGf" );
fstr << "</TR>" << endl;
fstr << "<TR>" << endl;
Put_Label_Cell( "Lines of Comment" );
Put_Label_Cell( "COM" );
Put_Metric_Cell( com, "COMm" );
Put_Metric_Cell( com, nof, "8.3" );
fstr << "</TR>" << endl;
fstr << "<TR>" << endl;
Put_Label_Cell( "LOC/COM" );
Put_Label_Cell( "L_C" );
Put_Metric_Cell( loc, com, "L_C" );
Put_Label_Cell( "" );
fstr << "</TR>" << endl;
fstr << "<TR>" << endl;
Put_Label_Cell( "MVG/COM" );
Put_Label_Cell( "M_C" );
Put_Metric_Cell( mvg, com, "M_C" );
Put_Label_Cell( "" );
fstr << "</TR>" << endl;
fstr << "<TR>" << endl;
Put_Label_Cell( "Weighted Methods per Class ( weighting = unity )" );
Put_Label_Cell( "WMC1" );
Put_Metric_Cell( wmc1 );
Put_Label_Cell( "" ); // wmc1 should be identical to nof
fstr << "</TR>" << endl;
fstr << "<TR>" << endl;
Put_Label_Cell( "Weighted Methods per Class ( weighting = visible )" );
Put_Label_Cell( "WMCv" );
Put_Metric_Cell( wmcv );
Put_Label_Cell( "" );
fstr << "</TR>" << endl;
fstr << "<TR>" << endl;
Put_Label_Cell( "Depth of Inheritance Tree" );
Put_Label_Cell( "DIT" );
Put_Metric_Cell( dit );
Put_Label_Cell( "" );
fstr << "</TR>" << endl;
fstr << "<TR>" << endl;
Put_Label_Cell( "Number of Children" );
Put_Label_Cell( "NOC" );
Put_Metric_Cell( noc );
Put_Label_Cell( "" );
fstr << "</TR>" << endl;
fstr << "<TR>" << endl;
Put_Label_Cell( "Coupling between objects" );
Put_Label_Cell( "CBO" );
Put_Metric_Cell( cbo );
Put_Label_Cell( "" );
fstr << "</TR>" << endl;
fstr << "<TR>" << endl;
Put_Label_Cell( "Information Flow measure ( inclusive )" );
Put_Label_Cell( "IF4" );
Put_Metric_Cell( if4, 1, "IF4" );
Put_Metric_Cell( if4, nof, "8.3" );
fstr << "</TR>" << endl;
fstr << "<TR>" << endl;
Put_Label_Cell( "Information Flow measure ( visible )" );
Put_Label_Cell( "IF4v" );
Put_Metric_Cell( if4v, 1, "IF4v" );
Put_Metric_Cell( if4v, nof, "8.3" );
fstr << "</TR>" << endl;
fstr << "<TR>" << endl;
Put_Label_Cell( "Information Flow measure ( concrete )" );
Put_Label_Cell( "IF4c" );
Put_Metric_Cell( if4c, 1, "IF4c" );
Put_Metric_Cell( if4c, nof, "8.3" );
fstr << "</TR>" << endl;
fstr << "</TABLE>" << endl;
}
1343 CCCC_Html_Stream::CCCC_Html_Stream( const string& fname, const string& info )
{
// cerr << "Attempting to open file in directory " << outdir.c_str( ) << endl;
fstr.open( fname.c_str( ) );
if( fstr.good( ) != TRUE )
{
cerr << "failed to open " << fname.c_str( )
<< " for output in directory " << outdir.c_str( ) << endl;
exit( 1 );
}
else
{
// cerr << "File: " << fname << " Info: " << info << endl;
}
fstr << "<HTML><HEAD><TITLE>" << endl
<< info << endl
<< "</TITLE>" << endl
<< "</HEAD>" << endl
<< "<BODY>" << endl;
}
1365 int setup_anchor_data( )
{
int i=0;
Source_Anchor a1( "cccc_use.h", 12 );
Source_Anchor a2( "cccc_htm.h", 15 );
i++;
string key1=a1.key( ), key2=a2.key( );
i++;
source_anchor_map_t::value_type v1( key1, a1 );
source_anchor_map_t::value_type v2( key2, a2 );
i++;
source_anchor_map.insert( v1 );
source_anchor_map.insert( v2 );
return i;
}
1382 void CCCC_Html_Stream::Source_Listing( )
{
// The variable stream src_str used to be an instance
// of fstream which gets reopened many times.
// this worked under Linux but broke under Win32, so
// this variable is now a pointer which is repeatedly
// deleted and new'ed
string current_filename;
int current_line=0;
int next_anchor_required=0;
ifstream *src_str=NULL;
const char *style_open="<TT>", *style_close="</TT>";
string filename=outdir;
filename+="/cccc_src.html";
CCCC_Html_Stream source_html_str( filename.c_str( ), "source file" );
source_html_str.fstr << style_open << endl;
source_anchor_map_t::iterator iter=source_anchor_map.begin( );
while( iter!=source_anchor_map.end( ) )
{
char linebuf[1024];
Source_Anchor& nextAnchor=( *iter ).second;
if( current_filename!=nextAnchor.get_file( ) )
{
current_filename=nextAnchor.get_file( );
current_line=0;
delete src_str;
src_str=new ifstream( current_filename.c_str( ), std::ios::in );
src_str->getline( linebuf, 1023 );
source_html_str.fstr << style_close << endl;
source_html_str.Put_Section_Heading( current_filename.c_str( ), "", 1 );
source_html_str.fstr << style_open << endl;
}
while( src_str->good( ) )
{
current_line++;
if(
( iter!=source_anchor_map.end( ) ) &&
( current_filename==( *iter ).second.get_file( ) ) &&
( current_line==( *iter ).second.get_line( ) )
)
{
( *iter ).second.Emit_NAME( source_html_str.fstr );
iter++;
}
else
{
( *iter ).second.Emit_SPACE( source_html_str.fstr );
}
source_html_str << linebuf;
source_html_str.fstr << "<BR>" << endl;
src_str->getline( linebuf, 1023 );
}
// if there are any remaining anchors for this file the sorting
// by line number must be wrong
// complain and ignore
while(
( iter!=source_anchor_map.end( ) ) &&
( current_filename==( *iter ).second.get_file( ) )
)
{
( *iter ).second.Emit_NAME( source_html_str.fstr );
iter++;
source_html_str.fstr << "<BR>" << endl;
}
}
// delete the last input stream created
delete src_str;
source_html_str.fstr << style_close << " </BODY></HTML>" << endl;
}
1463 static string pad_string( int target_width, string the_string, string padding )
{
int spaces_required=target_width-the_string.size( );
string pad_string;
while( spaces_required>0 )
{
pad_string+=padding;
spaces_required--;
}
return pad_string+the_string;
}
1476 string Source_Anchor::key( ) const
{
string retval;
char linebuf[16];
sprintf( linebuf, "%d", line_ );
retval=file_+":"+pad_string( 10, linebuf, " " );
return retval;
}
1486 void Source_Anchor::Emit_HREF( ofstream& fstr )
{
string anchor_key=key( );
fstr << "<CODE><A HREF=\"cccc_src.html#" << anchor_key.c_str( ) << "\">"
<< file_.c_str( ) << ":" << line_
<< "</A></CODE>";
}
1495 void Source_Anchor::Emit_NAME( ofstream& fstr )
{
string anchor_key=key( );
char ln_buf[32];
sprintf( ln_buf, "%d", line_ );
string ln_string=pad_string( 8, ln_buf, " " );
string space_string=pad_string( 2, "", " " );
fstr << "<A NAME=\"" << anchor_key.c_str( ) << "\">"
<< ln_string.c_str( ) << space_string.c_str( ) << "</A>";
}
1506 void Source_Anchor::Emit_SPACE( ofstream& fstr )
{
string space_string=pad_string( 10, "", " " );
fstr << space_string.c_str( );
}
#ifdef UNIT_TEST
1515 int main( )
{
CCCC_Project *prj_ptr=test_project_ptr( );
CCCC_Html_Stream os( *prj_ptr, "cccc.htm", "." );
return 0;
}
#endif
1 /*
CCCC - C and C++ Code Counter
Copyright ( C ) 1994-2005 Tim Littlefair ( tim_littlefair@hotmail.com )
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
( at your option ) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __CCCC_HTM_H
#define __CCCC_HTM_H
#include "cccc.h"
#include <fstream>
#include <time.h>
#include "cccc_db.h"
#include "cccc_met.h"
enum ReportType {
rtCONTENTS=0x0001, rtSUMMARY=0x0002,
rtOODESIGN=0x0004,
rtPROC1=0x0010, rtPROC2=0x0020,
rtSTRUCT1=0x0040, rtSTRUCT2=0x0080,
rtOTHER=0x0100,
rtSEPARATE_MODULES=0x0200,
rtSOURCE=0x0400,
rtSHOW_GEN_TIME=0x800,
rtCCCC=0x8000
};
44 class CCCC_Html_Stream {
45 friend CCCC_Html_Stream& operator <<( CCCC_Html_Stream& os,
46 const string& stg );
47 friend CCCC_Html_Stream& operator <<( CCCC_Html_Stream& os,
48 const CCCC_Metric& mtc );
50 ofstream fstr;
51 static string libdir;
52 static string outdir;
53 static CCCC_Project* prjptr;
55 void Table_Of_Contents( int report_mask, bool showGenTime );
56 void Project_Summary( );
57 void Procedural_Summary( );
58 void Procedural_Detail( );
59 void Structural_Summary( );
60 void Structural_Detail( );
61 void OO_Design( );
62 void Other_Extents( );
63 void Separate_Modules( );
64 void Source_Listing( );
67 void Module_Summary( CCCC_Module *module_ptr );
68 void Module_Detail( CCCC_Module *module_ptr );
69 void Procedural_Detail( CCCC_Module *module_ptr );
70 void Structural_Detail( CCCC_Module *module_ptr );
72 void Separate_Module_Link( CCCC_Module *module_ptr );
74 void Put_Section_Heading( string section_name, string section_tag,
int section_level );
76 void Put_Section_TOC_Entry( string section_name, string section_href,
77 string section_description );
79 void Put_Header_Cell( string label, int width=0 );
80 void Put_Label_Cell( string label, int width=0,
81 string ref_name="", string ref_href="",
82 CCCC_Record *rec_ptr=0 );
83 void Put_Metric_Cell( const CCCC_Metric& metric, int width=0 );
84 void Put_Metric_Cell( int count, string tag, int width=0 );
85 void Put_Metric_Cell( int num, int denom, string tag, int width=0 );
86 void Put_Extent_URL( const CCCC_Extent& extent );
87 void Put_Extent_Cell( const CCCC_Extent& extent, int width=0, bool withDescription=false );
88 void Put_Extent_List( CCCC_Record& record, bool withDescription=false );
89 void Put_Structural_Details_Cell( CCCC_Module *mod,
90 CCCC_Project *prj,
int mask,
UserelNameLevel nl );
94 void Metric_Description( string abbreviation,
95 string name,
96 string description );
public:
99 static void GenerateReports( CCCC_Project* project, int report_mask,
100 const string& outfile, const string& outdir );
// general-purpose constructor with standard preamble
103 CCCC_Html_Stream( const string& fname, const string& info );
// destructor with standard trailer
106 ~CCCC_Html_Stream( );
};
109 CCCC_Html_Stream& operator <<( CCCC_Html_Stream& os, const string& stg );
110 CCCC_Html_Stream& operator <<( CCCC_Html_Stream& os, const CCCC_Metric& mtc );
111 CCCC_Html_Stream& operator <<( CCCC_Html_Stream& os, const CCCC_Extent& ext );
// this class is added to support the generation of an HTML file
// containing the source analysed by the run, with anchors embedded at
// each of the lines referred to in the other parts of the report
116 class Source_Anchor
{
// if this looks more like a struct to you, it does to me too...
// it could be embedded withing CCCC_Html_Stream except that this
// might make the default constructor unavailable for the std::map
// instantiation
123 string file_;
int line_;
public:
126 Source_Anchor( ):line_( 0 ) {}
127 Source_Anchor( string file, int line ) : file_( file ), line_( line ) {}
129 string get_file( ) const { return file_; }
130 int get_line( ) const { return line_; }
131 string key( ) const;
133 void Emit_HREF( ofstream& fstr );
134 void Emit_NAME( ofstream& fstr );
135 void Emit_SPACE( ofstream& fstr );
// the default copy constructor, assignment operator and destructor
// are OK for this class
};
#endif /* __CCCC_HTM_H */
1 // cccc_itm.cc
#include "cccc.h"
#include <fstream>
#include "cccc_itm.h"
#include <cstdio>
#include <cmath>
10 CCCC_Item::CCCC_Item( const string& s, char c )
{
buffer=s;
delimiter=c;
good=true;
}
17 CCCC_Item::CCCC_Item( const string& s )
{
buffer=s;
delimiter='@';
good=true;
}
24 CCCC_Item::CCCC_Item( )
{
buffer="";
delimiter='@';
good=true;
}
31 bool CCCC_Item::Insert( const string& s )
{
buffer+=s;
buffer+=delimiter;
#if 0
cerr << buffer << endl;
#endif
return good;
}
41 bool CCCC_Item::Insert( const char* cptr )
{
string s( cptr );
return Insert( s );
}
47 bool CCCC_Item::Extract( string& s )
{
size_t delimiter_position=buffer.find( delimiter );
if( delimiter_position!=string::npos )
{
good=true;
s=buffer.substr( 0, delimiter_position );
string tempBuffer=buffer.substr( delimiter_position+1 );
buffer=tempBuffer;
}
else
{
good=false;
}
return good;
}
64 bool CCCC_Item::Insert( int n )
{
char numbuf[64];
sprintf( numbuf, "%d", n );
return Insert( numbuf );
}
71 bool CCCC_Item::Extract( int& n )
{
string numstr;
bool retval=Extract( numstr );
n=atoi( numstr.c_str( ) );
return retval;
}
79 bool CCCC_Item::Insert( char c )
{
char charbuf[2];
sprintf( charbuf, "%c", c );
return Insert( charbuf );
}
86 bool CCCC_Item::Extract( char& c )
{
string charstr;
bool retval=Extract( charstr );
if( charstr.size( )==1 )
{
c=charstr[0];
}
return retval;
}
97 bool CCCC_Item::Insert( float f )
{
char numbuf[64];
sprintf( numbuf, "%f", f );
return Insert( numbuf );
}
104 bool CCCC_Item::Extract( float& f )
{
string numstr;
bool retval=Extract( numstr );
f=atof( numstr.c_str( ) );
return retval;
}
112 bool CCCC_Item::ToFile( ofstream& ofstr )
{
ofstr << buffer << endl;
good=ofstr.good( );
return good;
}
119 bool CCCC_Item::FromFile( ifstream& ifstr )
{
good=false;
char line_buffer[1024];
ifstr.getline( line_buffer, 1023 );
buffer=line_buffer;
if( ifstr.good( ) && buffer.size( )>0 && buffer.size( )<1023 )
{
delimiter=buffer[buffer.size( )-1];
good=true;
#if 0
cerr << "Delimiter is " << delimiter << endl;
#endif
}
return good;
}
1 // cccc_itm.h
#ifndef __CCCC_ITM_H
#define __CCCC_ITM_H
#include "cccc.h"
// Class CCCC_Item is a wrapper for a C++ standard string which allows
// insertion and extraction of fields using a standard delimiter.
// It is intended for use in the following contexts:
// 1. for transmission of extent information from the parser to the database
// 2. for transmission of option information from the main line to the database
// 3. for storage from the database to a flat file
// 4. for reloading from a flat file to the database.
15 class CCCC_Item
{
private:
char delimiter;
19 string buffer;
20 bool good;
public:
23 CCCC_Item( const string& s, char c );
24 CCCC_Item( const string& s );
25 CCCC_Item( );
27 bool Insert( const string& s );
28 bool Insert( const char* cptr );
29 bool Extract( string& s );
30 bool Insert( int n );
31 bool Extract( int& n );
32 bool Insert( char c );
33 bool Extract( char& c );
34 bool Insert( float f );
35 bool Extract( float& f );
37 bool ToFile( ofstream& ofstr );
38 bool FromFile( ifstream& ifstr );
};
#endif
1 /*
CCCC - C and C++ Code Counter
Copyright ( C ) 1994-2005 Tim Littlefair ( tim_littlefair@hotmail.com )
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
( at your option ) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// cccc_mem.cc
// implementation file for class CCCC_Member
#include "cccc.h"
#include "cccc_itm.h"
#include "cccc_mem.h"
#include "cccc_db.h"
29 CCCC_Member::CCCC_Member( )
: parent( NULL )
{
visibility=vDONTKNOW;
}
35 int CCCC_Member::get_count( const char* count_tag ) {
int retval=0;
string count_tag_str=count_tag;
if( count_tag_str=="WMC1" )
{
retval=1;
}
else if( count_tag_str=="WMCv" )
{
switch( get_visibility( ) )
{
case vPUBLIC:
case vPROTECTED:
retval=1;
break;
default:
NULL;
}
}
else
{
retval=extent_table.get_count( count_tag );
}
return retval;
}
64 int CCCC_Member::ToFile( ofstream& ofstr )
{
int retval=FALSE;
CCCC_Item member_line;
member_line.Insert( MEMBER_PREFIX );
member_line.Insert( parent->key( ) );
member_line.Insert( member_name );
member_line.Insert( member_type );
member_line.Insert( param_list );
member_line.ToFile( ofstr );
CCCC_Extent *extent_ptr=extent_table.first_item( );
while( extent_ptr!=NULL )
{
CCCC_Item extent_line;
extent_line.Insert( MEMEXT_PREFIX );
extent_line.Insert( parent->key( ) );
extent_line.Insert( member_name );
extent_line.Insert( member_type );
extent_line.Insert( param_list );
extent_ptr->AddToItem( extent_line );
extent_line.ToFile( ofstr );
extent_ptr=extent_table.next_item( );
}
if( ofstr.good( ) )
{
retval=TRUE;
}
return retval;
}
99 string CCCC_Member::name( int name_level ) const
{
string namestr;
switch( name_level )
{
case nlRANK:
case nlSEARCH:
// there is no scoping for C-style functions ...
if( parent==NULL )
{
namestr.append( "<NULL>::" );
}
else if(
( parent->name( nlMODULE_NAME )!="" ) &&
( parent->name( nlMODULE_TYPE )!="file" )
)
{
namestr.append( parent->name( nlMODULE_NAME ) );
namestr.append( "::" );
}
namestr.append( member_name );
namestr.append( param_list );
break;
case nlMEMBER_NAME:
case nlSIMPLE:
namestr=member_name;
break;
case nlMEMBER_TYPE:
namestr=member_type;
break;
case nlMEMBER_PARAMS:
namestr=param_list;
break;
case nlLOCAL:
namestr.append( member_name );
namestr.append( param_list );
break;
default:
cerr << "unexpected name level" << endl;
}
return namestr.c_str( );
}
148 int CCCC_Member::FromFile( ifstream& ifstr )
{
int retval=RECORD_ERROR;
enum MemberFromFileStatuses { MEMBER_RECORD_NO_PARENT_FOUND=3 };
CCCC_Item next_line;
next_line.FromFile( ifstr );
ifstr_line++;
string line_keyword_dummy;
string parent_name;
CCCC_Member *found_mptr=NULL;
if(
next_line.Extract( line_keyword_dummy ) &&
next_line.Extract( parent_name ) &&
next_line.Extract( this->member_name ) &&
next_line.Extract( this->member_type ) &&
next_line.Extract( this->param_list )
)
{
parent=current_loading_project->module_table.find( parent_name );
if( parent!=NULL )
{
found_mptr=
current_loading_project->member_table.find_or_insert( this );
if( found_mptr==this )
{
// the newly created instance of the module is the first
// and has taken its place in the database, so we protect
// it from deletion
retval=RECORD_ADDED;
}
else
{
retval=RECORD_TRANSCRIBED;
}
// process extent records
while( PeekAtNextLinePrefix( ifstr, MEMEXT_PREFIX ) )
{
CCCC_Extent *new_extent=new CCCC_Extent;
next_line.FromFile( ifstr );
ifstr_line++;
string parent_key_dummy, member_name_dummy,
member_type_dummy, param_list_dummy;
if(
next_line.Extract( line_keyword_dummy ) &&
next_line.Extract( parent_key_dummy ) &&
next_line.Extract( member_name_dummy ) &&
next_line.Extract( member_type_dummy ) &&
next_line.Extract( param_list_dummy ) &&
new_extent->GetFromItem( next_line )
)
{
// We don't ever expect to find duplicated extent records
// but just in case...
CCCC_Extent *found_eptr=
found_mptr->extent_table.find_or_insert( new_extent );
if( found_eptr!=new_extent )
{
cerr << "Failed to add extent for member "
<< found_mptr->key( ) << " at line " << ifstr_line
<< endl;
delete new_extent;
}
}
}
}
else // parent record not found
{
retval=MEMBER_RECORD_NO_PARENT_FOUND;
}
}
else // extraction of module intial line failed
{
// unexpected problem with the input
retval=RECORD_ERROR;
}
// If the import was successful, we will also have imported all dependent
// extent records following the main record.
// If not, we must skip them.
while( PeekAtNextLinePrefix( ifstr, MEMEXT_PREFIX ) )
{
CCCC_Item next_line;
next_line.FromFile( ifstr );
ifstr_line++;
cerr << "Ignoring member extent on line " << ifstr_line << endl;
}
return retval;
}
245 Visibility CCCC_Member::get_visibility( )
{
return visibility;
}
1 /*
CCCC - C and C++ Code Counter
Copyright ( C ) 1994-2005 Tim Littlefair ( tim_littlefair@hotmail.com )
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
( at your option ) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* cccc_mem.h
*/
#ifndef CCCC_MEM_H
#define CCCC_MEM_H
#include "cccc_rec.h"
static const string MEMBER_PREFIX="CCCC_Member";
static const string MEMEXT_PREFIX="CCCC_MemExt";
enum MemberNameLevel { nlMEMBER_NAME=-1, nlMEMBER_TYPE=-2, nlMEMBER_PARAMS=-3 };
32 class CCCC_Module;
34 class CCCC_Member : public CCCC_Record
{
36 friend class CCCC_Project;
37 friend class CCCC_Module;
38 string member_type, member_name, param_list;
Visibility visibility;
40 CCCC_Module *parent;
41 CCCC_Member( );
public:
43 string name( int index ) const;
44 CCCC_Member( CCCC_Item& member_data_line, CCCC_Module* parent_ptr=NULL );
45 int FromFile( ifstream& infile );
46 int ToFile( ofstream& outfile );
47 void generate_report( ostream& );
48 int get_count( const char *count_tag );
49 Visibility get_visibility( );
};
#endif // CCCC_MEM_H
1 /*
CCCC - C and C++ Code Counter
Copyright ( C ) 1994-2005 Tim Littlefair ( tim_littlefair@hotmail.com )
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
( at your option ) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// cccc_met.cc
#include "cccc.h"
#include "cccc_itm.h"
#include "cccc_met.h"
#include <sstream>
using std::ostringstream;
#include "cccc_opt.h"
extern const char *internal_treatments[];
31 Metric_Treatment::Metric_Treatment( CCCC_Item& treatment_line )
{
lower_threshold=0;
upper_threshold=0;
numerator_threshold=0;
width=0;
precision=0;
string option_dummy, treatment_dummy, lothresh_str,
hithresh_str, numthresh_str, width_str, precision_str;
if(
// treatment_line.Extract( option_dummy ) &&
// treatment_line.Extract( treatment_dummy ) &&
treatment_line.Extract( code ) &&
treatment_line.Extract( lothresh_str ) &&
treatment_line.Extract( hithresh_str ) &&
treatment_line.Extract( numerator_threshold ) &&
treatment_line.Extract( width ) &&
treatment_line.Extract( precision ) &&
treatment_line.Extract( name )
)
{
lower_threshold=atof( lothresh_str.c_str( ) );
upper_threshold=atof( hithresh_str.c_str( ) );
}
}
59 CCCC_Metric::CCCC_Metric( )
{
set_ratio( 0, 0 );
set_treatment( "" );
}
65 CCCC_Metric::CCCC_Metric( int n, const char* treatment_tag )
{
set_ratio( n, 1 ); set_treatment( treatment_tag );
}
70 CCCC_Metric::CCCC_Metric( int n, int d, const char* treatment_tag )
{
set_ratio( n, d ); set_treatment( treatment_tag );
}
75 void CCCC_Metric::set_treatment( const char* code )
{
treatment=CCCC_Options::getMetricTreatment( code );
}
80 void CCCC_Metric::set_ratio( float _num, float _denom )
{
numerator=_num; denominator=_denom;
}
85 EmphasisLevel CCCC_Metric::emphasis_level( ) const
{
EmphasisLevel retval=elLOW;
if( treatment!=NULL && numerator>treatment->numerator_threshold )
{
if( numerator > ( treatment->upper_threshold*denominator ) )
{
retval=elHIGH;
}
else if( numerator> ( treatment->lower_threshold*denominator ) )
{
retval=elMEDIUM;
}
}
return retval;
}
102 string CCCC_Metric::code( ) const
{
string retval;
if( treatment != NULL ) { retval=treatment->code; }
return retval;
}
109 string CCCC_Metric::name( ) const
{
string retval;
if( treatment != NULL ) { retval=treatment->name; }
return retval;
}
116 string CCCC_Metric::value_string( ) const
{
string retval;
char numerator_too_low='-';
char infinity='*';
ostringstream valuestr;
valuestr.setf( std::ios::fixed );
int width=6, precision=0;
float n_threshold=0, low_threshold=1e9, high_threshold=1e9;
if( treatment!=NULL )
{
width=treatment->width;
precision=treatment->precision;
n_threshold=treatment->numerator_threshold;
low_threshold=treatment->lower_threshold;
high_threshold=treatment->upper_threshold;
}
valuestr.width( width );
valuestr.precision( precision );
if( numerator<n_threshold )
{
string too_low_string( width, numerator_too_low );
valuestr << too_low_string;
}
else if( denominator==0 )
{
string infinity_string( width, infinity );
valuestr << infinity_string;
}
else
{
double result=numerator;
result/=denominator;
if( result!=0.0L )
{
// Visual C++ and GCC appear to give different behaviours
// when rounding a value which is exactly half way between
// two points representable in the desired format.
// An example of this occurs results from prn14, where the
// numerator 21 and denominator 16 are combined to give the
// value 1.2125 exactly, which Visual Studio renders as 1.213,
// GCC renders as 1.212. For consistency with the existing
// reference data, I choose to apply a very small downward
// rounding factor. The rounding factor is only applied if
// the value is not exactly equal to zero, as applying it
// to zero causes the value to be displayed as -0.0 instead
// of 0.0.
const double ROUNDING_FACTOR = 1.0e-9;
result-=ROUNDING_FACTOR;
}
valuestr << result;
}
retval=valuestr.str( );
return retval;
}
const char *internal_treatments[] =
{
"LOCf@30@100@0@6@0@Lines of code/function@",
"LOCm@500@2000@0@6@0@Lines of code/module @",
"LOCp@999999@999999@0@6@0@Lines of code/project @",
"MVGf@10@30@0@6@0@Cyclomatic complexity/function@",
"MVGm@200@1000@0@6@0@Cyclomatic complexity/module@",
"MVGp@999999@999999@0@6@0@Cyclomatic complexity/project@",
"COM@999999@999999@0@6@0@Comment lines@",
"M_C@5@10@5@6@3@MVG/COM McCabe/comment line@",
"L_C@7@30@20@6@3@LOC/COM Lines of code/comment line@",
"FI@12@20@0@6@0@Fan in ( overall )@",
"FIv@6@12@0@6@0@Fan in ( visible uses only )@",
"FIc@6@12@0@6@0@Fan in ( concrete uses only )@",
"FO@12@20@0@6@0@Fan out ( overall )@",
"FOv@6@12@0@6@0@Fan out ( visible uses only )@",
"FOc@6@12@0@6@0@Fan out ( concrete uses only )@",
"IF4@100@1000@0@6@0@Henry-Kafura/Shepperd measure ( overall )@",
"IF4v@30@100@0@6@0@Henry-Kafura/Shepperd measure ( visible only )@",
"IF4c@30@100@0@6@0@Henry-Kafura/Shepperd measure ( concrete only )@",
"WMC1@30@100@0@6@0@Weighting function = 1 unit per method@",
"WMCv@10@30@0@6@0@Weighting function = 1 unit per visible method@",
"DIT@3@60@6@0@Depth of Inheritance Tree@",
"NOC@4@15@0@6@0@Number of children@",
"CBO@12@30@0@6@0@Coupling between objects@",
NULL
};
1 /*
CCCC - C and C++ Code Counter
Copyright ( C ) 1994-2005 Tim Littlefair ( tim_littlefair@hotmail.com )
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
( at your option ) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __CCCC_MET_H
#define __CCCC_MET_H
#include <string>
#include "cccc_db.h"
#include "cccc_itm.h"
enum EmphasisLevel { elLOW=0, elMEDIUM=1, elHIGH=2 };
29 class CCCC_Html_Stream;
30 class CCCC_Metric;
// the single class CCCC_Metric which will be defined later in this file
// will be used for all metrics
// differences in output formats will be handled by giving each object
// of type CCCC_Metric a pointer to a an object of type Metric_Treatment
// which will be held in a global array called Metric_Treatment_Table
37 class Metric_Treatment
{
39 friend class CCCC_Metric;
40 friend void add_treatment( CCCC_Item& );
41 friend CCCC_Html_Stream& operator <<( CCCC_Html_Stream&, const CCCC_Metric& );
// a short code string is used to search for the metric treatment, and
// it has a full name
45 string code, name;
// lower_threshold and upper_threshold are the levels at which the metric
// is interpreted as moving between low, medium and high emphasis levels
float lower_threshold, upper_threshold;
// for ratio type metrics, we provide the facility for screening out of
// items for which the numerator lies below a given value
// e.g. we may impose a standard of 1 line of comment per 3 of code, but
// say that we do not require this standard to apply to routines shorter
// than 5 lines
int numerator_threshold;
// preferred display width and number of decimal places
int width, precision;
public:
62 Metric_Treatment( CCCC_Item& treatment_line );
64 friend class CCCC_Options;
};
// the main metric class
68 class CCCC_Metric {
69 Metric_Treatment* treatment;
float numerator, denominator;
71 friend CCCC_Metric& operator+( const CCCC_Metric&, const CCCC_Metric& );
public:
73 CCCC_Metric( );
74 CCCC_Metric( int n, const char* treatment_tag="" );
75 CCCC_Metric( int n, int d, const char* treatment_tag="" );
76 void set_treatment( const char* code );
77 void set_ratio( float _num, float _denom=1.0 );
78 EmphasisLevel emphasis_level( ) const;
79 string code( ) const;
80 string name( ) const;
81 string value_string( ) const;
};
#endif /* __CCCC_MET_H */
1 /*
CCCC - C and C++ Code Counter
Copyright ( C ) 1994-2005 Tim Littlefair ( tim_littlefair@hotmail.com )
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
( at your option ) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// cccc_mod.cc
// implementation file for CCCC_Module class
#include "cccc.h"
#include "cccc_itm.h"
#include "cccc_mod.h"
#include "cccc_db.h"
29 CCCC_Module::CCCC_Module( )
{
project=get_active_project( );
}
35 string CCCC_Module::name( int name_level ) const
{
string retval;
switch( name_level )
{
case nlMODULE_TYPE:
retval=module_type;
break;
case nlMODULE_NAME:
retval=module_name;
break;
case nlMODULE_TYPE_AND_NAME:
retval=module_type;
if( retval.size( )>0 )
{
retval=retval+" ";
}
retval=retval+module_name;
break;
default:
retval=module_name;
}
return retval.c_str( );
}
64 int CCCC_Module::get_count( const char* count_tag )
{
int retval=0;
if( strcmp( count_tag, "NOM" )==0 )
{
if( is_trivial( )==FALSE )
{
retval=1;
}
}
else if( strcmp( count_tag, "CBO" )==0 )
{
retval=client_map.size( )+supplier_map.size( );
}
else if( strcmp( count_tag, "NOC" )==0 )
{
retval=0;
relationship_map_t::iterator iter;
iter=client_map.begin( );
while( iter!=client_map.end( ) )
{
if( ( *iter ).second->get_usetype( )==utINHERITS )
{
retval++;
}
iter++;
}
}
else if( strcmp( count_tag, "DIT" )==0 )
{
retval=0;
// cyclical inheritance relationships in code would
// never compile, but this is no excuse for us allowing them
// to cause us to overflow the stack
static int recursion_depth=0;
recursion_depth++;
if( recursion_depth>100 )
{
cerr << "Recursion overflow attempting to calculate DIT for "
<< key( ) << endl;
retval=1000;
}
else
{
relationship_map_t::iterator iter;
iter=supplier_map.begin( );
while( iter!=supplier_map.end( ) )
{
if( ( *iter ).second->get_usetype( )==utINHERITS )
{
int parent_depth=
( *iter ).second->supplier_module_ptr( project )->get_count( "DIT" );
if( retval<parent_depth+1 )
{
retval=parent_depth+1;
}
}
iter++;
}
}
recursion_depth--;
}
else if( strncmp( count_tag, "FI", 2 )==0 )
{
relationship_map_t::iterator iter;
iter=supplier_map.begin( );
while( iter!=supplier_map.end( ) )
{
retval+=( *iter ).second->get_count( count_tag );
iter++;
}
}
else if( strncmp( count_tag, "FO", 2 )==0 )
{
relationship_map_t::iterator iter;
iter=client_map.begin( );
while( iter!=client_map.end( ) )
{
retval+=( *iter ).second->get_count( count_tag );
iter++;
}
}
else if( strncmp( count_tag, "IF4", 3 )==0 )
{
char if4_suffix=count_tag[3];
string fi_variant="FI", fo_variant="FO";
if( if4_suffix!=0 )
{
fi_variant+=if4_suffix;
fo_variant+=if4_suffix;
}
retval=get_count( fi_variant.c_str( ) )*get_count( fo_variant.c_str( ) );
retval*=retval;
}
else
{
CCCC_Extent *extPtr=extent_table.first_item( );
while( extPtr!=NULL )
{
int extent_count=extPtr->get_count( count_tag );
retval+=extent_count;
extPtr=extent_table.next_item( );
}
member_map_t::iterator memIter=member_map.begin( );
while( memIter!=member_map.end( ) )
{
int member_count=( *memIter ).second->get_count( count_tag );
retval+=member_count;
memIter++;
}
}
return retval;
}
181 int CCCC_Module::is_trivial( )
{
int retval=FALSE;
if(
( module_type=="builtin" ) ||
( module_type=="enum" ) ||
( module_type=="struct" ) ||
( module_type=="trivial" )
)
{
retval=TRUE;
}
return retval;
}
198 int CCCC_Module::ToFile( ofstream& ofstr )
{
int retval=FALSE;
CCCC_Item module_line;
module_line.Insert( MODULE_PREFIX );
module_line.Insert( module_name );
module_line.Insert( module_type );
module_line.ToFile( ofstr );
CCCC_Extent *extent_ptr=extent_table.first_item( );
while( extent_ptr!=NULL )
{
CCCC_Item extent_line;
extent_line.Insert( MODEXT_PREFIX );
extent_line.Insert( module_name );
extent_line.Insert( module_type );
extent_ptr->AddToItem( extent_line );
extent_line.ToFile( ofstr );
extent_ptr=extent_table.next_item( );
}
if( ofstr.good( ) )
{
retval=TRUE;
}
return retval;
}
228 int CCCC_Module::FromFile( ifstream& ifstr )
{
int retval=RECORD_ERROR;
CCCC_Item next_line;
next_line.FromFile( ifstr );
ifstr_line++;
string line_keyword_dummy;
CCCC_Module *found_mptr=NULL;
if(
next_line.Extract( line_keyword_dummy ) &&
next_line.Extract( this->module_name ) &&
next_line.Extract( this->module_type )
)
{
found_mptr=
current_loading_project->module_table.find_or_insert( this );
if( found_mptr==this )
{
// the newly created instance of the module is the first
// and has taken its place in the database, so we protect
// it from deletion
retval=RECORD_ADDED;
}
else
{
retval=RECORD_TRANSCRIBED;
}
// process extent records
while( PeekAtNextLinePrefix( ifstr, MODEXT_PREFIX ) )
{
CCCC_Extent *new_extent=new CCCC_Extent;
next_line.FromFile( ifstr );
ifstr_line++;
string module_name_dummy, module_type_dummy;
if(
next_line.Extract( line_keyword_dummy ) &&
next_line.Extract( module_name_dummy ) &&
next_line.Extract( module_type_dummy ) &&
new_extent->GetFromItem( next_line )
)
{
// We don't ever expect to find duplicated extent records
// but just in case...
CCCC_Extent *found_eptr=
found_mptr->extent_table.find_or_insert( new_extent );
if( found_eptr!=new_extent )
{
cerr << "Failed to add extent for module "
<< found_mptr->key( ) << " at line " << ifstr_line
<< endl;
delete new_extent;
}
}
}
}
else
{
// unexpected problem with the input
retval=RECORD_ERROR;
}
// If the import was successful, we will also have imported all dependent
// extent records following the main record.
// If not, we must skip them.
while( PeekAtNextLinePrefix( ifstr, MODEXT_PREFIX ) )
{
CCCC_Item next_line;
next_line.FromFile( ifstr );
ifstr_line++;
cerr << "Ignoring member extent on line " << ifstr_line << endl;
}
return retval;
}
1 /*
CCCC - C and C++ Code Counter
Copyright ( C ) 1994-2005 Tim Littlefair ( tim_littlefair@hotmail.com )
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
( at your option ) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* cccc_mod.h
*/
#ifndef CCCC_MOD_H
#define CCCC_MOD_H
#include "cccc.h"
#include "cccc_rec.h"
29 class CCCC_Item;
30 class CCCC_Project;
31 class CCCC_UseRelationship;
32 class CCCC_Member;
static const string MODULE_PREFIX="CCCC_Module";
static const string MODEXT_PREFIX="CCCC_ModExt";
enum ModuleNameLevel
{ nlMODULE_TYPE=-1, nlMODULE_NAME=-2, nlMODULE_TYPE_AND_NAME=-3 };
42 class CCCC_Module : public CCCC_Record
{
44 friend class CCCC_Project;
45 friend class CCCC_Html_Stream;
46 friend class CCCC_Xml_Stream;
47 CCCC_Project *project;
48 string module_name, module_type;
typedef std::map<string, CCCC_Member*> member_map_t;
51 member_map_t member_map;
typedef std::map<string, CCCC_UseRelationship*> relationship_map_t;
54 relationship_map_t client_map;
55 relationship_map_t supplier_map;
57 CCCC_Module( );
public:
61 string name( int name_level ) const;
63 int FromFile( ifstream& infile );
64 int ToFile( ofstream& outfile );
66 virtual int get_count( const char *count_tag );
67 int is_trivial( );
};
#endif // CCCC_MOD_H
1 /*
CCCC - C and C++ Code Counter
Copyright ( C ) 1994-2005 Tim Littlefair ( tim_littlefair@hotmail.com )
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
( at your option ) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// cccc_new.cc
// we are having some problems with heap corruption, so I am making sure that
// all class news and deletes are done by the malloc subsystem, and adding
// logging and deletion suppression
#include "cccc.h"
#include <stdlib.h>
#include <memory.h>
#ifdef CCCC_CONF_W32VC
#include <time.h>
#else
#ifdef CCCC_CONF_W32BC
#include <time.h>
#else
#include <sys/time.h>
#endif
#endif
#define USE_SYSTEM_NEW
#ifndef USE_SYSTEM_NEW
extern int dont_free;
43 ofstream str( "cccc_new.log" );
void *
46 operator new( size_t n )
{
void *retval=malloc( n );
memset( retval, 0xFA, n );
str << hex << retval << "@" << time( NULL ) << "+" << n << endl;
return retval;
}
void *
55 operator new[]( size_t n )
{
void *retval=malloc( n );
memset( retval, 0xFB, n );
str << hex << retval << "@" << time( NULL ) << "*" << n << endl;
return retval;
}
void
64 operator delete( void * cp )
{
str << hex << cp << "@" << time( NULL ) << "-" << endl;
memset( cp, 0xFC, 1 );
if( dont_free==0 )
{
free( cp );
}
}
void
75 operator delete[]( void * cp )
{
str << hex << cp << "@" << time( NULL ) << "/" << endl;
memset( cp, 0xFD, 1 );
if( dont_free==0 )
{
free( cp );
}
}
#endif
1 /*
CCCC - C and C++ Code Counter
Copyright ( C ) 1994-2005 Tim Littlefair ( tim_littlefair@hotmail.com )
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
( at your option ) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// cccc_opt.cc
#include "cccc.h"
#include <fstream>
#include "cccc_opt.h"
#include "cccc_utl.h"
#include "cccc_met.h"
#include <map>
typedef std::map<string, string> file_extension_language_map_t;
typedef std::map<string, Metric_Treatment*> metric_treatment_map_t;
typedef std::pair<string, string> dialect_keyword_t;
typedef std::map<dialect_keyword_t, string> dialect_keyword_map_t;
static file_extension_language_map_t extension_map;
static metric_treatment_map_t treatment_map;
static dialect_keyword_map_t dialect_keyword_map;
// these are declared extern so that it can be defined later in the file
extern const char *default_fileext_options[];
extern const char *default_treatment_options[];
extern const char *default_dialect_options[];
43 static void add_file_extension( CCCC_Item& fileext_line )
{
string ext, lang;
if(
fileext_line.Extract( ext ) &&
fileext_line.Extract( lang )
)
{
file_extension_language_map_t::value_type extension_pair( ext, lang );
extension_map.insert( extension_pair );
}
}
56 void add_treatment( CCCC_Item& treatment_line )
{
Metric_Treatment *new_treatment=new Metric_Treatment( treatment_line );
metric_treatment_map_t::iterator iter=
treatment_map.find( new_treatment->code );
if( iter!=treatment_map.end( ) )
{
delete ( *iter ).second;
( *iter ).second=new_treatment;
}
else
{
metric_treatment_map_t::value_type
treatment_pair( new_treatment->code, new_treatment );
treatment_map.insert( treatment_pair );
}
}
75 static void add_dialect_keyword( CCCC_Item& dialect_keyword_line )
{
string dialect, keyword, policy;
if(
dialect_keyword_line.Extract( dialect ) &&
dialect_keyword_line.Extract( keyword ) &&
dialect_keyword_line.Extract( policy )
)
{
dialect_keyword_map_t::key_type kt( dialect, keyword );
dialect_keyword_map_t::value_type vt( kt, policy );
dialect_keyword_map.insert( vt );
}
}
90 void CCCC_Options::Add_Option( CCCC_Item& option )
{
string first_token;
bool retval=option.Extract( first_token );
if( retval==false )
{
// do nothing
}
else if( first_token=="CCCC_FileExt" )
{
add_file_extension( option );
}
else if( first_token=="CCCC_MetTmnt" )
{
add_treatment( option );
}
else if( first_token=="CCCC_Dialect" )
{
add_dialect_keyword( option );
}
else
{
retval=false;
}
}
118 void CCCC_Options::Save_Options( const string& filename )
{
ofstream optstr( filename.c_str( ) );
file_extension_language_map_t::iterator felIter;
for( felIter=extension_map.begin( );
felIter!=extension_map.end( );
++felIter )
{
CCCC_Item extLine;
extLine.Insert( "CCCC_FileExt" );
extLine.Insert( ( *felIter ).first.c_str( ) );
extLine.Insert( ( *felIter ).second.c_str( ) );
extLine.ToFile( optstr );
}
metric_treatment_map_t::iterator tIter;
for( tIter=treatment_map.begin( );
tIter!=treatment_map.end( );
++tIter )
{
CCCC_Item tmtLine;
tmtLine.Insert( "CCCC_MetTmnt" );
tmtLine.Insert( ( *tIter ).second->code );
tmtLine.Insert( ( *tIter ).second->lower_threshold );
tmtLine.Insert( ( *tIter ).second->upper_threshold );
tmtLine.Insert( ( *tIter ).second->numerator_threshold );
tmtLine.Insert( ( *tIter ).second->width );
tmtLine.Insert( ( *tIter ).second->precision );
tmtLine.Insert( ( *tIter ).second->name );
tmtLine.ToFile( optstr );
}
dialect_keyword_map_t::iterator dkIter;
for( dkIter=dialect_keyword_map.begin( );
dkIter!=dialect_keyword_map.end( );
++dkIter )
{
CCCC_Item dkLine;
dkLine.Insert( "CCCC_Dialect" );
dkLine.Insert( ( *dkIter ).first.first );
dkLine.Insert( ( *dkIter ).first.second );
dkLine.Insert( ( *dkIter ).second );
dkLine.ToFile( optstr );
}
}
164 void CCCC_Options::Load_Options( const string& filename )
{
ifstream optstr( filename.c_str( ) );
while( optstr.good( ) )
{
CCCC_Item option_line;
if( optstr.good( ) &&
option_line.FromFile( optstr )
)
{
Add_Option( option_line );
}
}
}
// initialise using hard-coded defaults
182 void CCCC_Options::Load_Options( )
{
int i=0;
const char **option_ptr;
option_ptr=default_fileext_options;
while( ( *option_ptr )!=NULL )
{
string option_string="CCCC_FileExt@";
option_string+=( *option_ptr );
CCCC_Item option_line( option_string );
Add_Option( option_line );
option_ptr++;
}
option_ptr=default_treatment_options;
while( ( *option_ptr )!=NULL )
{
string option_string="CCCC_MetTmnt@";
option_string+=( *option_ptr );
CCCC_Item option_line( option_string );
Add_Option( option_line );
option_ptr++;
}
option_ptr=default_dialect_options;
while( ( *option_ptr )!=NULL )
{
string option_string="CCCC_Dialect@";
option_string+=( *option_ptr );
CCCC_Item option_line( option_string );
Add_Option( option_line );
option_ptr++;
}
}
// map a filename to a language
220 string CCCC_Options::getFileLanguage( const string& filename )
{
string retval;
string extension;
file_extension_language_map_t::iterator iter;
unsigned int extpos=filename.rfind( "." );
if( extpos!=string::npos )
{
extension=filename.substr( extpos );
iter=extension_map.find( extension );
if( iter!=extension_map.end( ) )
{
retval=( *iter ).second;
}
}
if( retval.size( )==0 )
{
iter=extension_map.find( "" );
if( iter!=extension_map.end( ) )
{
retval=( *iter ).second;
}
else
{
// could not find language for extension
cerr << "No language found for extension " << extension.c_str( ) << endl;
}
}
return retval;
}
// map a metric name to a Metric_Treatment object
253 Metric_Treatment *CCCC_Options::getMetricTreatment( const string& metric_tag )
{
Metric_Treatment *retval=NULL;
metric_treatment_map_t::iterator iter=treatment_map.find( metric_tag );
if( iter!=treatment_map.end( ) )
{
retval=( *iter ).second;
}
return retval;
}
264 string CCCC_Options::dialectKeywordPolicy( const string& lang, const string& kw )
{
string retval;
dialect_keyword_map_t::key_type kt( lang, kw );
dialect_keyword_map_t::const_iterator iter=dialect_keyword_map.find( kt );
if( iter!=dialect_keyword_map.end( ) )
{
retval=( *iter ).second;
}
return retval;
}
const char *default_fileext_options[]=
{
// file extensions
".c@c.ansi@",
".h@c++.ansi@",
".cc@c++.ansi@",
".cpp@c++.ansi@",
".cxx@c++.ansi@",
".c++@c++.ansi@",
".C@c++.ansi@",
".CC@c++.ansi@",
".CPP@c++.ansi@",
".CXX@c++.ansi@",
".hh@c++.ansi@",
".hpp@c++.ansi@",
".hxx@c++.ansi@",
".h++@c++.ansi@",
".H@c++.ansi@",
".HH@c++.ansi@",
".HPP@c++.ansi@",
".HXX@c++.ansi@",
".H++@c++.ansi@",
".j@java@",
".jav@java@",
".java@java@",
".J@java@",
".JAV@java@",
".JAVA@java@",
".ada@ada.95@",
".ads@ada.95@",
".adb@ada.95@",
".ADA@ada.95@",
".ADS@ada.95@",
".ADB@ada.95@",
// The language associated with the empty file extension would be used as a default
// if defined.
// This is presently disabled so that we don't process files in
// MSVC projects like .rc, .odl which are not in C++.
// "@c++.ansi@",
NULL
};
const char *default_treatment_options[] =
{
// metric treatments
// all metric values are displayed using the class CCCC_Metric, which may be
// viewed as ratio of two integers associated with a character string tag
// the denominator of the ratio defaults to 1, allowing simple counts to
// be handled by the same code as is used for ratios
//
// the tag associated with a metric is used as a key to lookup a record
// describing a policy for its display ( class Metric_Treatment )
//
// the fields of each treatment record are as follows:
// TAG the short string of characters used as the lookup key.
// T1, T2 two numeric thresholds which are the lower bounds for the ratio of
// the metric's numerator and denominator beyond which the
// value is treated as high or extreme by the analyser
// these will be displayed in emphasized fonts, and if the browser
// supports the BGCOLOR attribute, extreme values will have a red
// background, while high values will have a yellow background.
// The intent is that high values should be treated as suspicious but
// tolerable in moderation, whereas extreme values should almost
// always be regarded as defects ( not necessarily that you will fix
// them ).
// NT a third threshold which supresses calculation of ratios where
// the numerator is lower than NT.
// The principal reason for doing this is to prevent ratios like L_C
// being shown as *** ( infinity ) and displayed as extreme when the
// denominator is 0, providing the numerator is sufficiently low.
// Suitable values are probably similar to those for T1.
// W the width of the metric ( total number of digits ).
// P the precision of the metric ( digits after the decimal point ).
// Comment a free form field extending to the end of the line.
// TAG T1 T2 NT W P Comment
"LOCf@ 30@ 100@ 0@ 6@ 0@Lines of code/function@",
"LOCm@ 500@ 2000@ 0@ 6@ 0@Lines of code/single module@",
"LOCper@ 500@ 2000@ 0@ 6@ 3@Lines of code/average module@",
"LOCp@ 999999@ 999999@ 0@ 6@ 0@Lines of code/project@",
"MVGf@ 10@ 30@ 0@ 6@ 0@Cyclomatic complexity/function@",
"MVGm@ 200@ 1000@ 0@ 6@ 0@Cyclomatic complexity/single module@",
"MVGper@ 200@ 1000@ 0@ 6@ 3@Cyclomatic complexity/average module@",
"MVGp@ 999999@ 999999@ 0@ 6@ 0@Cyclomatic complexity/project@",
"COM@ 999999@ 999999@ 0@ 6@ 0@Comment lines@",
"COMper@999999@ 999999@ 0@ 6@ 3@Comment lines ( averaged )@",
"M_C@ 5@ 10@ 5@ 6@ 3@MVG/COM McCabe/comment line@",
"L_C@ 7@ 30@ 20@ 6@ 3@LOC/COM Lines of code/comment line@",
"FI@ 12@ 20@ 0@ 6@ 0@Fan in ( overall )@",
"FIv@ 6@ 12@ 0@ 6@ 0@Fan in ( visible uses only )@",
"FIc@ 6@ 12@ 0@ 6@ 0@Fan in ( concrete uses only )@",
"FO@ 12@ 20@ 0@ 6@ 0@Fan out ( overall )@",
"FOv@ 6@ 12@ 0@ 6@ 0@Fan out ( visible uses only )@",
"FOc@ 6@ 12@ 0@ 6@ 0@Fan out ( concrete uses only )@",
"IF4@ 100@ 1000@ 0@ 6@ 0@Henry-Kafura/Shepperd measure ( overall )@",
"IF4v@ 30@ 100@ 0@ 6@ 0@Henry-Kafura/Shepperd measure ( visible )@",
"IF4c@ 30@ 100@ 0@ 6@ 0@Henry-Kafura/Shepperd measure ( concrete )@",
// WMC stands for weighted methods per class,
// the suffix distinguishes the weighting function
"WMC1@ 30@ 100@ 0@ 6@ 0@Weighting function=1 unit per method@",
"WMCv@ 10@ 30@ 0@ 6@ 0@Weighting function=1 unit per visible method@",
"DIT@ 3@ 6@ 0@ 6@ 0@Depth of Inheritance Tree@",
"NOC@ 4@ 15@ 0@ 6@ 0@Number of children@",
"CBO@ 12@ 30@ 0@ 6@ 0@Coupling between objects@",
"8.3@ 999999@ 999999@ 0@ 8@ 3@General format for fixed precision 3 d.p.@",
NULL
};
const char *default_dialect_options[] =
{
// This configuration item allows the description of
// dialects in which C/C++ identifiers get treated
// as supplementary keyword. The rules specified
// here ( or in the runtime option file, if specified )
// allow the parser to make the call
// CCCC_Options::dialect_keyword_policy( lang, kw ) which
// returns a string. If nothing is known about the
// pair <lang, kw>, an empty string is returned. If
// an entry is specified here the associated string is
// returned, which is called the policy, which the
// parser uses to guide its actions. The most common
// policy is to ignore, but any string can be
// specified, providing the person implementing
// the parser can think of an intelligent way to
// proceed.
"c++.mfc@BEGIN_MESSAGE_MAP@start_skipping@",
"c++.mfc@END_MESSAGE_MAP@stop_skipping@",
"c++.stl@__STL_BEGIN_NAMESPACE@ignore@",
"c++.stl@__STL_END_NAMESPACE@ignore@",
NULL
};
1 /*
CCCC - C and C++ Code Counter
Copyright ( C ) 1994-2005 Tim Littlefair ( tim_littlefair@hotmail.com )
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
( at your option ) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// cccc_opt.h
#ifndef _CCCC_OPT_H
#define _CCCC_OPT_H
// This file defines the object which holds the major configuration
// options for the CCCC program including:
// - the default language associated with each file name extension;
// - the treatment of specific values of each metric; and
// - the application of dialect specific parsing rule ( e.g. rule to
// ignore MSVC++-specific pseudo-keywords when parsing the
// MS C++ dialect.
// This is a natural singleton class, hence all member functions are static
// and all data will be declared with static file scope in the implementation
// file.
#include "cccc.h"
#include "cccc_itm.h"
38 class Metric_Treatment;
40 class CCCC_Options
{
public:
// initialise using a file
44 static void Load_Options( const string& filename );
// initialise using hard-coded defaults
47 static void Load_Options( );
// save the current set of options to a file
50 static void Save_Options( const string& filename );
// add a new option into the current option set
53 static void Add_Option( CCCC_Item& option_line );
// map a filename to a language
56 static string getFileLanguage( const string& filename );
// map a metric name to a Metric_Treatment object
59 static Metric_Treatment *getMetricTreatment( const string& metric_tag );
// the following function allows the parser to use special
// handling rules for identifiers in particular situations
// ( especially pseudo-keywords like BEGIN_MESSAGE_MAP )
64 static string dialectKeywordPolicy( const string& lang, const string& kw );
};
#endif
1 /*
CCCC - C and C++ Code Counter
Copyright ( C ) 1994-2005 Tim Littlefair ( tim_littlefair@hotmail.com )
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
( at your option ) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// cccc_prj.cc
// We have some debugging messages specifically for looking at how
// use relationships are being handled.
#define DEBUG_USEREL 0
// implementation file for class CCCC_Project
#include "cccc.h"
#include "cccc_itm.h"
#include "cccc_prj.h"
#include "cccc_db.h"
33 CCCC_Project::CCCC_Project( const string& name )
{
// we prime the database with knowledge of the builtin base types
// we also add a record for the anonymous class which we will treat
// as the parent of all non-member functions
const char *builtin_type_info[]=
{
"void@builtin@<nofile>@0@builtin definition@d?????@@0@d@",
"int@builtin@<nofile>@0@builtin definition@d?????@@0@d@",
"char@builtin@<nofile>@0@builtin definition@d?????@@0@d@",
"long@builtin@<nofile>@0@builtin definition@d?????@@0@d@",
"float@builtin@<nofile>@0@builtin definition@d?????@@0@d@",
"double@builtin@<nofile>@0@builtin definition@d?????@@0@d@",
NULL
};
for( const char **ptr=builtin_type_info; *ptr!=NULL; ptr++ )
{
CCCC_Item type_info( *ptr );
add_module( type_info );
}
}
56 void CCCC_Project::add_module( CCCC_Item& module_line ) {
char linebuf[1024];
CCCC_Module *module_ptr=new CCCC_Module;
CCCC_Extent *extent_ptr=new CCCC_Extent;
if(
module_line.Extract( module_ptr->module_name ) &&
module_line.Extract( module_ptr->module_type ) &&
extent_ptr->GetFromItem( module_line )
)
{
CCCC_Module *lookup_module_ptr=module_table.find_or_insert( module_ptr );
if( lookup_module_ptr != NULL )
{
lookup_module_ptr->extent_table.find_or_insert( extent_ptr );
if( lookup_module_ptr!=module_ptr )
{
// do some work to transfer knowledge from the new module object
// then delete it
Resolve_Fields( lookup_module_ptr->module_type, module_ptr->module_type );
delete module_ptr;
}
}
}
else
{
cerr << "CCCC_Project::add_module_extent: extraction failed" << endl;
}
}
88 void CCCC_Project::add_member( CCCC_Item& member_data_line )
{
CCCC_Module *new_module_ptr=new CCCC_Module;
CCCC_Member *new_member_ptr=new CCCC_Member;
if(
member_data_line.Extract( new_module_ptr->module_name ) &&
member_data_line.Extract( new_member_ptr->member_name ) &&
member_data_line.Extract( new_member_ptr->member_type ) &&
member_data_line.Extract( new_member_ptr->param_list )
)
{
CCCC_Module *found_module_ptr=module_table.find_or_insert( new_module_ptr );
if( found_module_ptr==new_module_ptr )
{
// protect the new module from deletion at the end of this function
new_module_ptr=NULL;
}
new_member_ptr->parent=found_module_ptr;
CCCC_Member *found_member_ptr=member_table.find_or_insert( new_member_ptr );
if( found_member_ptr==new_member_ptr )
{
new_member_ptr=NULL;
}
found_member_ptr->add_extent( member_data_line );
}
else
{
cerr << "CCCC_Project::add_module extraction failed" << endl;
}
// clean up newly allocated records if they have not been accepted
// into the database
delete new_module_ptr;
delete new_member_ptr;
}
125 void CCCC_Project::add_userel( CCCC_Item& userel_data_line ) {
CCCC_UseRelationship *new_userel_ptr =
new CCCC_UseRelationship( userel_data_line );
CCCC_UseRelationship *lookup_userel_ptr =
userel_table.find_or_insert( new_userel_ptr );
if( lookup_userel_ptr != NULL )
{
if( new_userel_ptr != lookup_userel_ptr )
{
delete new_userel_ptr;
}
lookup_userel_ptr->add_extent( userel_data_line );
}
#if DEBUG_USEREL
cerr << "Adding " << lookup_userel_ptr->client << " uses "
<< lookup_userel_ptr->supplier << endl;
#endif
}
145 void CCCC_Project::add_rejected_extent( CCCC_Item& rejected_data_line )
{
CCCC_Extent *new_extent=new CCCC_Extent( rejected_data_line );
rejected_extent_table.find_or_insert( new_extent );
}
151 void CCCC_Project::reindex( )
{
CCCC_Member *member_ptr=member_table.first_item( );
while( member_ptr!=NULL )
{
if( member_ptr->parent!=NULL )
{
CCCC_Module::member_map_t::value_type
new_pair( member_ptr->key( ), member_ptr );
member_ptr->parent->member_map.insert( new_pair );
}
else
{
cerr << "Member " << member_ptr->key( ) << " has no parent"
<< endl;
}
CCCC_Extent *extent_ptr=member_ptr->extent_table.first_item( );
while( extent_ptr!=NULL )
{
Visibility extent_visibility=extent_ptr->get_visibility( );
Visibility member_visibility=member_ptr->get_visibility( );
if( member_ptr->visibility==vDONTKNOW )
{
member_ptr->visibility=extent_visibility;
}
else if(
( extent_visibility!=vDONTKNOW ) &&
( member_visibility!=extent_visibility )
)
{
member_ptr->visibility=vINVALID;
}
extent_ptr=member_ptr->extent_table.next_item( );
}
member_ptr=member_table.next_item( );
}
CCCC_UseRelationship *userel_ptr=userel_table.first_item( );
while( userel_ptr!=NULL )
{
CCCC_Module *supplier_ptr=new CCCC_Module;
supplier_ptr->module_name=userel_ptr->supplier;
CCCC_Module *found_supplier_ptr=
module_table.find_or_insert( supplier_ptr );
if( found_supplier_ptr!=supplier_ptr )
{
delete supplier_ptr;
supplier_ptr=found_supplier_ptr;
}
CCCC_Module *client_ptr=new CCCC_Module;
client_ptr->module_name=userel_ptr->client;
CCCC_Module *found_client_ptr=module_table.find_or_insert( client_ptr );
if( found_client_ptr!=client_ptr )
{
delete client_ptr;
client_ptr=found_client_ptr;
}
if(
( userel_ptr->supplier==userel_ptr->client ) ||
userel_ptr->supplier=="" ||
userel_ptr->client=="" ||
supplier_ptr->is_trivial( ) ||
client_ptr->is_trivial( )
)
{
#if DEBUG_USEREL
cerr << "Removing relationship between "
<< userel_ptr->supplier.c_str( )
<< " and "
<< userel_ptr->client.c_str( )
<< endl;
#endif
userel_table.remove( userel_ptr );
delete userel_ptr;
}
else
{
// create links from the client and supplier modules to the
// relationship object
#if DEBUG_USEREL
std::cerr << "Creating links for "
<< client_ptr->key( )
<< " ( " << client_ptr << " ) uses "
<< supplier_ptr->key( )
<< " ( " << supplier_ptr << " )" << std::endl;
#endif
CCCC_Module::relationship_map_t::value_type
new_supplier_pair( supplier_ptr->key( ), userel_ptr ),
new_client_pair( client_ptr->key( ), userel_ptr );
client_ptr->supplier_map.insert( new_supplier_pair );
supplier_ptr->client_map.insert( new_client_pair );
// calculate the visibility and concreteness of the
// relationship
AugmentedBool visible=abDONTKNOW;
AugmentedBool concrete=abDONTKNOW;
CCCC_Extent *extent_ptr=userel_ptr->extent_table.first_item( );
while( extent_ptr!=NULL )
{
switch( extent_ptr->get_visibility( ) )
{
case vPRIVATE:
case vIMPLEMENTATION:
if( visible!=abTRUE )
{
visible=abFALSE;
}
break;
case vPROTECTED:
case vPUBLIC:
visible=abTRUE;
break;
default:
// nothing to do
;
}
switch( extent_ptr->get_usetype( ) )
{
case utPARBYREF:
case utHASBYREF:
if( concrete!=abTRUE )
{
concrete=abFALSE;
}
break;
case utINHERITS:
case utPARBYVAL:
case utHASBYVAL:
concrete=abTRUE;
break;
default:
// nothing to do
;
}
extent_ptr=userel_ptr->extent_table.next_item( );
}
userel_ptr->visible=visible;
userel_ptr->concrete=concrete;
}
userel_ptr=userel_table.next_item( );
}
}
308 int CCCC_Project::get_count( const char* count_tag )
{
int retval=0;
retval+=module_table.get_count( count_tag );
retval+=rejected_extent_table.get_count( count_tag );
return retval;
}
317 int CCCC_Project::ToFile( ofstream& ofstr )
{
// this function could be rewritten much more elegantly using
// STL output iterators, and one day will be ...
int retval=FALSE;
CCCC_Module *module_ptr=module_table.first_item( );
while( module_ptr!=NULL )
{
module_ptr->ToFile( ofstr );
module_ptr=module_table.next_item( );
}
CCCC_Member *member_ptr=member_table.first_item( );
while( member_ptr!=NULL )
{
member_ptr->ToFile( ofstr );
member_ptr=member_table.next_item( );
}
CCCC_UseRelationship *userel_ptr=userel_table.first_item( );
while( userel_ptr!=NULL )
{
userel_ptr->ToFile( ofstr );
userel_ptr=userel_table.next_item( );
}
CCCC_Extent *rejext_ptr=rejected_extent_table.first_item( );
while( rejext_ptr!=NULL )
{
CCCC_Item extent_line;
extent_line.Insert( REJEXT_PREFIX );
rejext_ptr->AddToItem( extent_line );
extent_line.ToFile( ofstr );
rejext_ptr=rejected_extent_table.next_item( );
}
if( ofstr.good( ) )
{
retval=TRUE;
}
return retval;
}
364 int CCCC_Project::FromFile( ifstream& ifstr )
{
int retval=FALSE;
set_active_project( this );
while( PeekAtNextLinePrefix( ifstr, MODULE_PREFIX ) )
{
CCCC_Module *new_module=new CCCC_Module;
int fromfile_status=new_module->FromFile( ifstr );
DisposeOfImportRecord( new_module, fromfile_status );
}
while( PeekAtNextLinePrefix( ifstr, MEMBER_PREFIX ) )
{
CCCC_Member *new_member=new CCCC_Member;
int fromfile_status=new_member->FromFile( ifstr );
DisposeOfImportRecord( new_member, fromfile_status );
}
while( PeekAtNextLinePrefix( ifstr, USEREL_PREFIX ) )
{
CCCC_UseRelationship *new_userel=new CCCC_UseRelationship;
int fromfile_status=new_userel->FromFile( ifstr );
DisposeOfImportRecord( new_userel, fromfile_status );
}
while( PeekAtNextLinePrefix( ifstr, REJEXT_PREFIX ) )
{
CCCC_Extent *new_rejext=new CCCC_Extent;
CCCC_Item next_line;
next_line.FromFile( ifstr );
int fromfile_status=RECORD_ERROR;
if(
new_rejext->GetFromItem( next_line ) &&
new_rejext==rejected_extent_table.find_or_insert( new_rejext )
)
{
fromfile_status=RECORD_ADDED;
}
DisposeOfImportRecord( new_rejext, fromfile_status );
}
set_active_project( NULL );
return retval;
}
412 string CCCC_Project::name( int level ) const
{
return "";
}
1 /*
CCCC - C and C++ Code Counter
Copyright ( C ) 1994-2005 Tim Littlefair ( tim_littlefair@hotmail.com )
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
( at your option ) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* cccc_prj.h
*/
#ifndef CCCC_PRJ_H
#define CCCC_PRJ_H
#include "cccc_rec.h"
// forward declarations
28 class CCCC_Item;
29 class CCCC_Record;
30 class CCCC_Project;
31 class CCCC_Module;
32 class CCCC_Member;
33 class CCCC_UseRelationship;
34 class CCCC_Extent;
static const string REJEXT_PREFIX="CCCC_RejExt";
enum RelationshipMaskElements
{
rmeCLIENT=0x01, rmeSUPPLIER=0x02,
rmeHIDDEN=0x10, rmeVISIBLE=0x20, rmeHIDDEN_OR_VISIBLE=0x30,
rmeABSTRACT=0x40, rmeCONCRETE=0x80, rmeABSTRACT_OR_CONCRETE=0xC0
};
45 class CCCC_Project : public CCCC_Record
{
47 friend class CCCC_Html_Stream;
48 friend class CCCC_Xml_Stream;
49 friend class CCCC_Module;
50 friend class CCCC_Member;
51 friend class CCCC_UseRelationship;
52 friend class CCCC_Extent;
54 CCCC_Table<CCCC_Module> module_table;
55 CCCC_Table<CCCC_Member> member_table;
56 CCCC_Table<CCCC_UseRelationship> userel_table;
57 CCCC_Table<CCCC_Extent> rejected_extent_table;
59 std::map<string, CCCC_Item> OptionTable;
public: // because MSVC++ version of STL needs it to be...
// we need a record of which extents came from which files
// so that when we implement persistence, we can purge
// extent records from each file as we re-analyze it
struct ExtentTableEntry
{
CCCC_Table<CCCC_Extent> *table_ptr;
CCCC_Extent *extent_ptr;
ExtentTableEntry( ) : table_ptr( NULL ), extent_ptr( NULL ) {}
};
typedef std::multimap<string, ExtentTableEntry> FileExtentTable;
74 FileExtentTable file_extent_table;
public:
77 CCCC_Project( const string& name="" );
// these functions are used in both the analyzer
// and the load side of the persistence code
// to add entities to the project
82 void add_module( CCCC_Item& module_data_line );
83 void add_member( CCCC_Item& member_data_line );
84 void add_userel( CCCC_Item& use_data_line );
85 void add_rejected_extent( CCCC_Item& rejected_data_line );
// this function is used after loading and/or analysis
// has been completed to ( re )create the maps owned by
// each module of its members and relationships
90 void reindex( );
92 int get_count( const char *count_tag );
94 string name( int level ) const;
96 int FromFile( ifstream& infile );
97 int ToFile( ofstream& outfile );
99 void set_option( string key, CCCC_Item& option_data_line );
100 int get_option( string key, CCCC_Item& option_data_line );
};
#endif // CCCC_PRJ_H
1 /*
CCCC - C and C++ Code Counter
Copyright ( C ) 1994-2005 Tim Littlefair ( tim_littlefair@hotmail.com )
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
( at your option ) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* cccc_rec.cc
*/
#include "cccc_itm.h"
#include "cccc_rec.h"
#include "cccc_db.h"
CCCC_Project* CCCC_Record::active_project=NULL;
28 CCCC_Project* CCCC_Record::get_active_project( ) { return active_project; }
29 void CCCC_Record::set_active_project( CCCC_Project* prj ) { active_project=prj; }
31 void CCCC_Record::merge_flags( string& new_flags )
{
const char *new_flag_array=new_flags.c_str( );
const char *flag_array=flags.c_str( );
unsigned int len=strlen( flag_array );
if( strlen( new_flag_array )==len )
{
char buf[100];
unsigned int i;
for( i=0; i<len;i++ )
{
if( flag_array[i]=='?' )
{
buf[i]=new_flag_array[i];
}
else
{
buf[i]=flag_array[i];
}
}
buf[len]='\0';
flags=buf;
}
else
{
// if the parent record has just been created it may have
// an empty flags member, so we use Resolve_Fields to copy
// the flags from the first extent
Resolve_Fields( flags, new_flags );
}
}
63 void CCCC_Record::add_extent( CCCC_Item& is )
{
CCCC_Extent *new_extent=new CCCC_Extent;
new_extent->GetFromItem( is );
CCCC_Extent *inserted_extent=extent_table.find_or_insert( new_extent );
if( new_extent != inserted_extent )
{
delete new_extent;
}
}
75 string CCCC_Record::name( int /* level */ ) const { return ""; }
76 string CCCC_Record::key( ) const { return name( nlRANK ); }
1 /*
CCCC - C and C++ Code Counter
Copyright ( C ) 1994-2005 Tim Littlefair ( tim_littlefair@hotmail.com )
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
( at your option ) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* cccc_rec.h
*
* defines the database used by CCCC to generate a report
*/
#ifndef CCCC_REC_H
#define CCCC_REC_H
#include "cccc_tbl.h"
#include "cccc_ext.h"
#include "cccc_utl.h"
// The entities held within the database need to be able to return a variety
// of kinds of name including a simple name ( typically one word ), a fully
// qualified local name ( i.e as used within a class ), and a fully
// qualified global name.
// Subclasses may also have particular other names, which should be defined
// using negative indexes.
enum NameLevel { nlRANK, nlSEARCH, nlSIMPLE, nlLOCAL, nlGLOBAL };
38 class CCCC_Record
{
40 friend class CCCC_Html_Stream;
41 friend class CCCC_Xml_Stream;
42 static CCCC_Project *active_project;
protected:
typedef CCCC_Table<CCCC_Extent> Extent_Table;
45 Extent_Table extent_table;
46 string flags;
47 virtual void merge_flags( string& new_flags );
public:
49 virtual ~CCCC_Record( ) {}
50 virtual string name( int level ) const;
51 virtual string key( ) const;
52 AugmentedBool get_flag( PSFlag psf ) { return ( AugmentedBool ) flags[psf]; }
54 virtual void add_extent( CCCC_Item& );
55 virtual void sort( ) { extent_table.sort( ); }
56 virtual int get_count( const char *count_tag )=0;
57 friend int rank_by_string( const void *p1, const void *p2 );
58 static CCCC_Project* get_active_project( );
59 static void set_active_project( CCCC_Project* prj );
};
#endif // CCCC_REC_H
1 /*
CCCC - C and C++ Code Counter
Copyright ( C ) 1994-2005 Tim Littlefair ( tim_littlefair@hotmail.com )
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
( at your option ) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// cccc_tbl.cc
#ifndef _CCCC_TBL_BODY
#define _CCCC_TBL_BODY
#include "cccc_itm.h"
#include "cccc_tbl.h"
#include <cassert>
#define LINE_BUFFER_SIZE 1000
30 template <class T> CCCC_Table<T>::CCCC_Table( )
: sorted( true )
{
iter_ = map_t::end( );
}
36 template <class T> CCCC_Table<T>::~CCCC_Table( )
{
// the container should manage the destruction of its own
// nodes correctly, we just need to get rid of the
// objects to which we hold pointers.
// NB Although CCCC_Table holds pointers, it owns the
// objects they point to and is responsible for their disposal.
T* itemptr=first_item( );
while( itemptr!=NULL )
{
delete itemptr;
itemptr=next_item( );
}
}
template<class T>
52 int CCCC_Table<T>::get_count( const char* count_tag )
{
int retval=0;
T* itemptr=first_item( );
while( itemptr!=NULL )
{
retval+=itemptr->get_count( count_tag );
itemptr=next_item( );
}
return retval;
}
template<class T>
66 T* CCCC_Table<T>::find( string name )
{
T *retval=NULL;
typename map_t::iterator value_iterator=map_t::find( name );
if( value_iterator!=map_t::end( ) )
{
retval=( *value_iterator ).second;
}
return retval;
}
template<class T>
78 T* CCCC_Table<T>::find_or_insert( T* new_item_ptr )
{
string new_key=new_item_ptr->key( );
T *retval=find( new_key );
if( retval==NULL )
{
typename map_t::value_type new_pair( new_key, new_item_ptr );
map_t::insert( new_pair );
sorted=false;
retval=new_item_ptr;
}
return retval;
}
template<class T>
93 bool CCCC_Table<T>::remove( T* old_item_ptr )
{
bool retval=false;
typename map_t::iterator value_iterator=map_t::find( old_item_ptr->key( ) );
if( value_iterator!=map_t::end( ) )
{
this->erase( value_iterator );
retval=true;
}
return retval;
}
105 template <class T> void CCCC_Table<T>::sort( )
{
if( sorted==false )
{
sorted=true;
}
}
113 template <class T> void CCCC_Table<T>::reset_iterator( )
{
iter_=map_t::begin( );
}
118 template <class T> T* CCCC_Table<T>::first_item( )
{
reset_iterator( );
return next_item( );
}
124 template <class T> T* CCCC_Table<T>::next_item( )
{
T* retval=NULL;
if( iter_!=map_t::end( ) )
{
retval=( *iter_ ).second;
iter_++;
}
return retval;
}
135 template <class T> int CCCC_Table<T>::records( )
{
return map_t::size( );
}
#endif // _CCCC_TBL_BODY
1 /*
CCCC - C and C++ Code Counter
Copyright ( C ) 1994-2005 Tim Littlefair ( tim_littlefair@hotmail.com )
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
( at your option ) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* cccc_tbl.h
*
* defines the database used by CCCC to generate a report
*/
#ifndef CCCC_TBL_H
#define CCCC_TBL_H
#include <iostream>
#include <string>
#include <map>
using std::string;
// CCCC_Table started its life as an array of pointers to CCCC_Records.
// It will ultimately become identical to a std::map from string to T*.
// In the mean time we are supporting a legacy API.
37 template <class T> class CCCC_Table
38 : public std::map<string, T*>
{
typedef std::map<string, T*> map_t;
typename map_t::iterator iter_;
bool sorted;
public:
CCCC_Table( );
virtual ~CCCC_Table( );
int records( );
T* find( string name );
T* find_or_insert( T* new_item_ptr );
bool remove( T* old_item_ptr );
void reset_iterator( );
T* first_item( );
T* next_item( );
virtual int get_count( const char *count_tag );
void sort( );
};
#include "cccc_tbl.cc"
#endif // CCCC_DB_H
1 /*
CCCC - C and C++ Code Counter
Copyright ( C ) 1994-2005 Tim Littlefair ( tim_littlefair@hotmail.com )
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
( at your option ) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* cccc_tok.C
* implementation of a token class for the cccc project
*
*/
#include "cccc.h"
#include "cccc_tok.h"
/* static variables */
int ANTLRToken::RunningNesting=0;
int ANTLRToken::bCodeLine=0;
int ANTLRToken::numAllocated=0;
int toks_alloc1=0, toks_alloc2=0, toks_alloc3=0, toks_freed=0;
ANTLRToken currentLexerToken;
/*
** Token objects are used to count the occurences of states which
** our analyser is interested in within the text. Any metric which
** can be reduced to lexical counting on the text can be recorded
** this way.
**
** This implementation counts the following features:
** tokens
** comment lines
** lines containing at least one token of code
**
** It also makes a lexical count for the following tokens, each of which
** is expected to increase McCabe's cyclomatic complexity ( Vg ) for the
** section of code by one unit:
** IF FOR WHILE SWITCH BREAK RETURN ? && ||
**
** Note that && and || create additional paths through the code due to C/C++
** short circuit evaluation of logical expressions.
**
** Also note the way SWITCH constructs are counted: the desired increment
** in Vg is equal to the number of cases provided for, including the
** default case, whether or not an action is defined for it. This is acheived
** by counting the SWITCH at the head of the construct as a surrogate for
** the default case, and counting BREAKs as surrogates for the individual
** cases. This approach yields the correct results provided that the
** coding style in use ensures the use of BREAK after all non-default
** cases, and forbids 'drop through' from one case to another other than
** in the case where two or more values of the switch variable require
** identical actions, and no executable code is defined between the
** case gates ( as in the switch statement in ANTLRToken::CountToken( ) below ).
*/
/* default constructor */
69 ANTLRToken::ANTLRToken( ) : ANTLRCommonToken( ) {
toks_alloc1++;
CurrentNesting=-99;
}
/*
** constructor used by makeToken below
*/
77 ANTLRToken::ANTLRToken( ANTLRTokenType t, ANTLRChar *s ) :
ANTLRCommonToken( t, s ) {
setType( t );
setText( s );
CountToken( );
toks_alloc2++;
}
/* copy constructor */
87 ANTLRToken::ANTLRToken( ANTLRToken& copyTok ) {
setType( copyTok.getType( ) );
setText( copyTok.getText( ) );
setLine( copyTok.getLine( ) );
CurrentNesting=copyTok.CurrentNesting;
toks_alloc3++;
}
/*
** the virtual pseudo-constructor
** This is required because the PCCTS support code does not know the
** exact nature of the token which will be created by the user's code,
** and indeed does not forbid the user creating more than one kind of
** token, so long as ANTLRToken is defined and all token classes are
** subclassed from ANTLRAbstractToken
*/
103 ANTLRAbstractToken *ANTLRToken::makeToken(
104 ANTLRTokenType tt, ANTLRChar *txt, int line
) {
ANTLRToken *new_t = new ANTLRToken( tt, txt );
if( new_t==0 ) {
cerr << "Memory overflow in "
"ANTLRToken::makeToken( " << static_cast<int>( tt ) << ", "
<< txt << ", " << line << " )" << endl;
exit( 2 );
}
new_t->setLine( line );
DbgMsg(
LEXER, cerr,
"makeToken( tt=>" << static_cast<int>( tt ) <<
", txt=>" << txt <<
", line=>" << line <<
" )" << endl
);
return new_t;
}
/* the destructor */
128 ANTLRToken::~ANTLRToken( ) {
toks_freed++;
DbgMsg( MEMORY, cerr, "freeing token " << getText( )
<< " on line " << getLine( )
<< " c1:" << toks_alloc1 << " c2:" << toks_alloc2
<< " c3:" << toks_alloc3 << " freed:" << toks_freed << endl );
}
/* the assignment operator */
137 ANTLRToken& ANTLRToken::operator=( ANTLRToken& copyTok ) {
setType( copyTok.getType( ) );
setText( copyTok.getText( ) );
setLine( copyTok.getLine( ) );
CurrentNesting=copyTok.CurrentNesting;
return *this;
}
/*
** ANTLRToken::CountToken performs counting of features which are traced
** back to individual tokens created up by the lexer, i.e. the token count
** and McCabes VG. Code lines and comment lines are both identified during
** the processing of text which the lexer will ( usually ) skip, so the code
** to increment these counts is in the relevant lexer rules in the file
** cccc.g
*/
153 void ANTLRToken::CountToken( )
{
// we have seen a non-skippable pattern => this line counts toward LOC
bCodeLine=1;
CurrentNesting=RunningNesting;
DbgMsg( COUNTER, cerr, *this );
}
161 const char *ANTLRToken::getTokenTypeName( ) { return ""; }
/*
** structured output method for token objects
*/
166 ostream& operator << ( ostream& out, ANTLRToken& t ) {
int i;
out << "TOK: " << t.getTokenTypeName( )
<< " " << t.getText( )
<< " " << t.getLine( )
<< " " << t.getNestingLevel( );
out << endl;
return out;
}
1 /*
CCCC - C and C++ Code Counter
Copyright ( C ) 1994-2005 Tim Littlefair ( tim_littlefair@hotmail.com )
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
( at your option ) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* cccc_tok.h
* definition of the token class interface for the cccc project
*
*/
#ifndef __CCCC_TOK_H
#define __CCCC_TOK_H
#include "cccc.h"
// before we go into the token header file, the compiler must have seen
// a definition for enum ANTLRTokenType
// there are three conflicting 'real' definitions, one in use by each parser
// if we have seen one of these, we do not need to worry, otherwise we
// must create a dummy one
// the three definitions are in the files Ctokens.h Jtokens.h and Atokens.h
#if !defined( Ctokens_h ) && !defined( Jtokens_h ) && !defined( Atokens_h )
enum ANTLRTokenType { DUMMY, DEFINITION };
#endif
#include "AToken.h"
#include "cccc.h"
/*
** the class definition for ANTLRToken
** Note that the name ANTLRToken is required to be either a class or a typedef
** by the PCCTS support code
*/
49 class ANTLRToken : public ANTLRCommonToken {
// Lexical counting is done by attaching running counts of each of the
// interesting features to every token produced by the lexer
// the parser calculates the counts for a particular region by taking
// taking the differences of the counts for the first and last tokens
// in the region's extent.
// nesting levels are used to control resynchronisation
static int RunningNesting;
static int numAllocated;
int CurrentNesting;
62 friend ostream& operator << ( ostream&, ANTLRToken& );
63 friend class DLGLexer;
public:
static int bCodeLine;
67 ANTLRToken( ANTLRTokenType t, ANTLRChar *s );
68 ANTLRToken( ANTLRToken& copyTok );
69 ANTLRToken( );
70 ANTLRToken& operator=( ANTLRToken& copyTok );
72 virtual ~ANTLRToken( );
74 virtual ANTLRAbstractToken *makeToken( ANTLRTokenType tt,
75 ANTLRChar *txt,
int line );
78 static void IncrementNesting( ) { RunningNesting++; }
79 static void DecrementNesting( ) { RunningNesting--; }
81 int getNestingLevel( ) { return CurrentNesting; }
82 void CountToken( );
83 const char *getTokenTypeName( );
};
#define MY_TOK( t ) ( ( ANTLRToken* )( t ) )
87 ostream& operator << ( ostream&, ANTLRToken& );
extern ANTLRToken currentLexerToken;
#endif
1 /*
CCCC - C and C++ Code Counter
Copyright ( C ) 1994-2005 Tim Littlefair ( tim_littlefair@hotmail.com )
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
( at your option ) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// cccc_tpl.cc
// all explicit template instantiations for the project are collected here
// the assumption is that this file will be stable, so the expensive
// recompilation of the templates will be infrequent
#include "cccc_itm.h"
#include "cccc_tbl.h"
#include "cccc_db.h"
#include "cccc_htm.h"
#include "cccc_met.h"
#include "cccc_tbl.cc"
34 template class std::map<string, Source_Anchor>;
35 template class CCCC_Table<CCCC_Extent>;
36 template class CCCC_Table<CCCC_Module>;
37 template class CCCC_Table<CCCC_UseRelationship>;
38 template class CCCC_Table<CCCC_Member>;
1 /*
CCCC - C and C++ Code Counter
Copyright ( C ) 1994-2005 Tim Littlefair ( tim_littlefair@hotmail.com )
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
( at your option ) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// cccc_use.cc
// implementation of CCCC_UseRelationship class
#include "cccc.h"
#include "cccc_itm.h"
#include "cccc_use.h"
#include "cccc_db.h"
30 CCCC_UseRelationship::CCCC_UseRelationship( CCCC_Item& is )
{
is.Extract( client );
is.Extract( member );
is.Extract( supplier );
visible=abDONTKNOW;
concrete=abDONTKNOW;
ut=utDONTKNOW;
}
40 string CCCC_UseRelationship::name( int name_level ) const
{
string namestr;
switch( name_level )
{
case nlRANK:
case nlSIMPLE:
namestr.append( client );
namestr.append( " uses " );
namestr.append( supplier );
break;
case nlSUPPLIER:
namestr=supplier;
break;
case nlCLIENT:
namestr=client;
break;
default:
cerr << "unexpected name level" << endl;
}
return namestr.c_str( );
}
68 void CCCC_UseRelationship::add_extent( CCCC_Item& is )
{
// processing is similar to the CCCC_Record method, except that we update
// the visibility and concreteness data members
// but do not do merge_flags
CCCC_Extent *new_extent=new CCCC_Extent( is );
CCCC_Extent *inserted_extent=extent_table.find_or_insert( new_extent );
switch( new_extent->get_visibility( ) )
{
case vPUBLIC:
case vPROTECTED:
visible=abTRUE;
break;
case vPRIVATE:
case vIMPLEMENTATION:
visible=abFALSE;
break;
default:
// nothing required
;;
}
// a single relationship record represents all connections between two
// modules, hence it may have multiple extents which are of different use
// types
// the use type attached to the relationship record is used only to identify
// inheritance relationships
UseType new_ut=new_extent->get_usetype( );
if( new_ut==utINHERITS )
{
ut=utINHERITS;
}
switch( new_ut )
{
case utINHERITS:
case utHASBYVAL:
case utPARBYVAL:
case utVARBYVAL:
concrete=abTRUE;
break;
default:
// no change required
;;
}
if( new_extent != inserted_extent )
{
delete new_extent;
}
}
122 int CCCC_UseRelationship::get_count( const char* count_tag )
{
int retval=0;
if( ( strncmp( count_tag, "FI", 2 )==0 ) || ( strncmp( count_tag, "FO", 2 )==0 ) )
{
char suffix=count_tag[2];
switch( suffix )
{
case 0:
retval=1;
break;
case 'v':
if( visible!=abFALSE )
{
retval=1;
}
break;
case 'c':
if( concrete!=abFALSE )
{
retval=1;
}
break;
default:
cerr << "Unexpected count tag suffix" << count_tag << endl;
}
}
else
{
cerr << "Unexpected count tag " << count_tag << endl;
}
return retval;
}
164 CCCC_Module* CCCC_UseRelationship::supplier_module_ptr( CCCC_Project *prj )
{
return prj->module_table.find( supplier.c_str( ) );
}
169 CCCC_Module* CCCC_UseRelationship::client_module_ptr( CCCC_Project *prj )
{
return prj->module_table.find( client.c_str( ) );
}
175 int CCCC_UseRelationship::ToFile( ofstream& ofstr )
{
int retval=FALSE;
CCCC_Item line;
line.Insert( USEREL_PREFIX );
line.Insert( supplier );
line.Insert( client );
line.ToFile( ofstr );
CCCC_Extent *extent_ptr=extent_table.first_item( );
while( extent_ptr!=NULL )
{
CCCC_Item extent_line;
extent_line.Insert( USEEXT_PREFIX );
extent_line.Insert( supplier );
extent_line.Insert( client );
extent_ptr->AddToItem( extent_line );
extent_line.ToFile( ofstr );
extent_ptr=extent_table.next_item( );
}
if( ofstr.good( ) )
{
retval=TRUE;
}
return retval;
}
206 int CCCC_UseRelationship::FromFile( ifstream& ifstr )
{
int retval;
CCCC_Item next_line;
next_line.FromFile( ifstr );
ifstr_line++;
string line_keyword_dummy;
CCCC_UseRelationship *found_uptr=NULL;
if(
next_line.Extract( line_keyword_dummy ) &&
next_line.Extract( this->supplier ) &&
next_line.Extract( this->client )
)
{
found_uptr=
current_loading_project->userel_table.find_or_insert( this );
if( found_uptr==this )
{
// the newly created instance of the module is the first
// and has taken its place in the database, so we protect
// it from deletion
retval=RECORD_ADDED;
}
else
{
retval=RECORD_TRANSCRIBED;
}
// process extent records
while( PeekAtNextLinePrefix( ifstr, USEEXT_PREFIX ) )
{
CCCC_Extent *new_extent=new CCCC_Extent;
next_line.FromFile( ifstr );
ifstr_line++;
string supplier_dummy, client_dummy;
if(
next_line.Extract( line_keyword_dummy ) &&
next_line.Extract( supplier_dummy ) &&
next_line.Extract( client_dummy ) &&
new_extent->GetFromItem( next_line )
)
{
// We don't ever expect to find duplicated extent records
// but just in case...
CCCC_Extent *found_eptr=
found_uptr->extent_table.find_or_insert( new_extent );
if( found_eptr!=new_extent )
{
cerr << "Failed to add extent for relationship "
<< found_uptr->key( ) << " at line " << ifstr_line
<< endl;
delete new_extent;
}
}
}
}
else // extraction of module intial line failed
{
// unexpected problem with the input
retval=RECORD_ERROR;
}
// If the import was successful, we will also have imported all dependent
// extent records following the main record.
// If not, we must skip them.
while( PeekAtNextLinePrefix( ifstr, USEEXT_PREFIX ) )
{
CCCC_Item next_line;
next_line.FromFile( ifstr );
ifstr_line++;
cerr << "Ignoring userel extent on line " << ifstr_line << endl;
}
return retval;
}
1 /*
CCCC - C and C++ Code Counter
Copyright ( C ) 1994-2005 Tim Littlefair ( tim_littlefair@hotmail.com )
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
( at your option ) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* cccc_use.h
*/
#ifndef CCCC_USE_H
#define CCCC_USE_H
#include "cccc_rec.h"
27 class CCCC_Module;
static const string USEREL_PREFIX="CCCC_UseRel";
static const string USEEXT_PREFIX="CCCC_UseExt";
enum UserelNameLevel { nlSUPPLIER=-1, nlCLIENT=-2, nlMEMBER=-3 };
34 class CCCC_UseRelationship : public CCCC_Record
{
36 friend class CCCC_Project;
37 string supplier, client, member;
UseType ut;
AugmentedBool visible, concrete;
40 CCCC_UseRelationship( ) { ut=utDONTKNOW; }
public:
43 string name( int index ) const;
44 CCCC_UseRelationship( CCCC_Item& is );
45 int FromFile( ifstream& infile );
46 int ToFile( ofstream& outfile );
47 void add_extent( CCCC_Item& );
48 int get_count( const char *count_tag );
49 UseType get_usetype( ) const { return ut; }
50 AugmentedBool is_visible ( ) const { return visible; }
51 AugmentedBool is_concrete ( ) const { return concrete; }
52 void generate_report( ostream& os );
53 CCCC_Module* supplier_module_ptr( CCCC_Project *prj );
54 CCCC_Module* client_module_ptr( CCCC_Project *prj );
};
#endif // CCCC_USE_H
1 /*
CCCC - C and C++ Code Counter
Copyright ( C ) 1994-2005 Tim Littlefair ( tim_littlefair@hotmail.com )
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
( at your option ) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// cccc_utl.cc
// implementation of enumerations and utility classes for CCCC
// includes the Parse_Utility class which is a helper to centralise
// error recovery and recording facilities across the three parsers
#include "cccc.h"
#include "cccc_itm.h"
#include "cccc_utl.h"
#include "cccc_db.h"
#include "cccc_tok.h"
#include "AParser.h"
#include "ATokPtr.h"
#define DEBUG_EXTENT_STREAMS 1
#include <cassert>
#include <iomanip>
using std::ios;
//using std::trunc;
using std::ends;
using std::setw;
using std::setiosflags;
using std::resetiosflags;
#define FS "@"
#define RS "\n"
string ParseUtility::stack_rules[MAX_STACK_DEPTH];
int ParseUtility::stack_tokenline[MAX_STACK_DEPTH];
string ParseUtility::stack_tokentext[MAX_STACK_DEPTH];
int ParseUtility::stack_depth;
ParseUtility* ParseUtility::theCurrentInstance=NULL;
ParseStore* ParseStore::theCurrentInstance=NULL;
// insertion and extraction functions intended to support enumerations
57 void insert_enum( ostream& os, int e )
{
os << ( char ) e;
}
62 void extract_enum( istream& is, int& e )
{
e=0;
is >> ( char& ) e;
}
69 ostream& operator<<( ostream& os, AugmentedBool ab ) {
insert_enum( os, ab );
return os;
}
74 istream& operator>>( istream& is, AugmentedBool& ab ) {
extract_enum( is, ( int& )ab );
return is;
}
79 ostream& operator<<( ostream& os, Visibility v ) {
insert_enum( os, v );
return os;
}
84 istream& operator>>( istream& is, Visibility& v ) {
extract_enum( is, ( int& )v );
return is;
}
89 ostream& operator<<( ostream& os, UseType ut ) {
insert_enum( os, ut );
return os;
}
94 istream& operator>>( istream& is, UseType& ut ) {
extract_enum( is, ( int& )ut );
return is;
}
99 string ParseUtility::lookahead_text( int n )
{
static string retval;
retval="";
int i;
for( i=1; i<=n; i++ )
{
if( parser->LT( i ) != NULL )
{
retval=retval+parser->LT( i )->getText( );
retval=retval+" ";
}
}
return retval;
}
115 void ParseUtility::resynchronize( int initial_nesting,
116 SetWordType *resync_token_class,
117 ANTLRTokenPtr& resync_token )
{
// the interface for resynchronisation is as follows:
// the caller supplies a nesting level at which the resynchronisation must
// occur, and a token class containing all of the tokens which can
// be accepted to delimit the resynchronisation
// this function will scan until it finds that it is at the correct level and
// the next token of lookahead is in the resynchronisation set
// it will then accept as many tokens from the resynchronisation set as
// are available, consolidating the text of the tokens accepted
// as the text associated with the last token
string resync_text="...";
string string1=parser->LT( 1 )->getText( );
int line1=parser->LT( 1 )->getLine( );
string string2;
int line2=0;
int resynchronising=1;
while( resynchronising )
{
parser->consumeUntil( resync_token_class );
if(
( MY_TOK( parser->LT( 1 ) )->getNestingLevel( ) > initial_nesting ) &&
( parser->LT( 2 ) != NULL )
)
{
parser->consume( );
}
else
{
// we are ready to resynchronise
resynchronising=0;
string2=parser->LT( 1 )->getText( );
line2=parser->LT( 1 )->getLine( );
}
}
// we now consume a succession of tokens from the resynchronisation token
// class until we come across a token which is not in the set, or the
// nesting level changes
resync_token=parser->LT( 1 );
while(
parser->set_el( parser->LT( 1 )->getType( ), resync_token_class ) &&
( MY_TOK( parser->LT( 1 ) )->getNestingLevel( ) == initial_nesting )
)
{
string2=parser->LT( 1 )->getText( );
line2=parser->LT( 1 )->getLine( );
resync_text+=parser->LT( 1 )->getText( );
resync_text+=" ";
resync_token=parser->LT( 1 );
resync_token->setText( resync_text.c_str( ) );
parser->consume( );
}
cerr << "Unrecognized section from "
<< string1.c_str( ) << " on line " << line1 << " to "
<< string2.c_str( ) << " on line " << line2 << endl
<< "=====ignored section begins=====" << endl
<< resync_text.c_str( ) << endl
<< "===== ignored section ends =====" << endl;
}
183 ParseUtility::ParseUtility( ANTLRParser *parser )
{
// This is designed as a serial-singleton class ( e.g. many
// instances may exist over time but no more than one at a
// time ).
// For the lifetime of an instance, the static member theCurrentInstance
// points to it. When no instance exists, this pointer is null.
assert( theCurrentInstance==NULL );
theCurrentInstance=this;
trace_depth=0;
stack_depth=0;
this->parser=( ANTLR_Assisted_Parser* )parser;
}
199 ParseUtility::~ParseUtility( )
{
theCurrentInstance=NULL;
}
// This utility function is used to create
// a composite scope name from a qualifier scope
// and a relative name.
207 string ParseUtility::scopeCombine( const string& baseScope, const string& name )
{
// I am presently ( as at 3.pre44 ) experimenting with
// how I handle scopes. The present code has a policy
// of discarding scope information altogether and defining
// modules based solely on the final component of the
// fully qualified name.
// This variable may become a parameter to control policy in this
// area.
bool bIgnoreScope=true;
string retval;
if( bIgnoreScope )
{
retval=name;
}
else if( baseScope.size( )>0 && name.size( )>0 )
{
retval=baseScope+"::"+name;
}
else
{
retval=baseScope+name;
}
return retval;
}
234 ParseStore::ParseStore( const string& filename )
: theFilename( filename )
, pendingLexicalCounts( static_cast<int>( tcLAST ), 0 )
, flag( static_cast<int>( psfLAST )+1, '?' )
{
// This is designed as a serial-singleton class ( e.g. many
// instances may exist over time but no more than one at a
// time ).
// For the lifetime of an instance, the static member theCurrentInstance
// points to it. When no instance exists, this pointer is null.
assert( theCurrentInstance==NULL );
theCurrentInstance=this;
flag[psfLAST]='\0';
}
249 ParseStore::~ParseStore( )
{
// If the current object came from the default constructor
// it is the primary singleton instance and we wish to
// set the static pointer to itself back to null. Otherwise,
// it was a cached copy, and we don't really care.
if( theCurrentInstance==this )
{
theCurrentInstance=NULL;
}
}
261 int ParseStore::get_flag( PSFlag psf ) const {
return int( flag[psf] );
}
265 void ParseStore::set_flag( PSFlag psf, int value ) {
flag[psf]=value;
}
269 void ParseStore::set_flag( Visibility value ) {
MAKE_STRSTREAM( ofstr );
ofstr << value;
flag[psfVISIBILITY]=( ofstr.str( ) )[0];
RELEASE_STRSTREAM( ofstr );
}
276 Visibility ParseStore::get_visibility( )
{
return static_cast<Visibility>( flag[psfVISIBILITY] );
}
281 string ParseStore::filename( )
{
return theFilename;
}
void
287 ParseStore::
288 insert_extent( CCCC_Item& os, int startLine, int endLine,
289 const string& description, const string& flags,
290 UseType ut, bool allocate_lexcounts )
{
os.Insert( theFilename );
os.Insert( startLine );
os.Insert( description );
os.Insert( flags );
int i;
int lexical_counts_for_this_extent[tcLAST];
for( i=0; i<tcLAST; i++ )
{
lexical_counts_for_this_extent[i]=0;
}
if( allocate_lexcounts==true )
{
LineLexicalCountMatrix::iterator extentStartIter =
lineLexicalCounts.lower_bound( startLine );
LineLexicalCountMatrix::iterator extentEndIter =
lineLexicalCounts.upper_bound( endLine-1 );
LineLexicalCountMatrix::iterator llcmIter;
for( llcmIter=extentStartIter;
llcmIter!=extentEndIter;
++llcmIter )
{
// This record relates to a line within the current
// extent.
for( i=0; i<tcLAST; i++ )
{
lexical_counts_for_this_extent[i]+=( *llcmIter ).second[i];
}
}
// The lexical occurrences mentioned in the records processed
// above are now been accounted for in the database, so we
// purge these records. This has the effect of allowing
// accurate accounting on nested extents ( i.e. the outer
// extent will only be reported as containing lines which
// are not already listed in the inner extent ).
lineLexicalCounts.erase( extentStartIter, extentEndIter );
ostringstream lexcount_str;
lexcount_str << "LOC:" << lexical_counts_for_this_extent[tcCODELINES]
<< " COM:" << lexical_counts_for_this_extent[tcCOMLINES]
<< " MVG:" << lexical_counts_for_this_extent[tcMCCABES_VG]
<< ends;
os.Insert( lexcount_str.str( ).c_str( ) );
}
else
{
os.Insert( "*" );
}
os.Insert( ( char )flag[psfVISIBILITY] );
os.Insert( ( char )ut );
}
349 void ParseStore::record_module_extent( int startLine, int endLine,
350 const string& moduleName,
351 const string& moduleType,
352 const string& description,
UseType ut )
{
// See the lengthy comment in record_userel_extent about
// why we are filtering for empty module names.
if( moduleName.size( )>0 )
{
CCCC_Item module_line;
module_line.Insert( moduleName );
module_line.Insert( moduleType );
insert_extent( module_line, startLine, endLine,
description, flags( ), ut, true );
prj->add_module( module_line );
}
}
368 void ParseStore::record_function_extent( int startLine, int endLine,
369 const string& returnType,
370 const string& moduleName,
371 const string& memberName,
372 const string& paramList,
373 const string& description,
Visibility visibility,
UseType ut )
{
// We require every call to this function to specify a member
// function name and a parameter list.
if( memberName.size( )>0 )
{
// If the moduleName is an empty string, we remap this to the
// string "anonymous". This implies that we treat all
// C-style functions as belonging to a single module.
string mappedModuleName = moduleName;
if( mappedModuleName.size( )==0 )
{
mappedModuleName = "anonymous";
}
CCCC_Item function_line;
function_line.Insert( mappedModuleName );
function_line.Insert( memberName );
function_line.Insert( returnType );
function_line.Insert( paramList );
string baseFlags=flags( );
baseFlags[psfVISIBILITY]=visibility;
insert_extent( function_line, startLine, endLine,
description, baseFlags, ut, true );
prj->add_member( function_line );
}
}
405 void ParseStore::record_userel_extent( int startLine, int endLine,
406 const string& clientName,
407 const string& memberName,
408 const string& serverName,
409 const string& description,
Visibility visibility,
UseType ut )
{
CCCC_Item userel_line;
// This function should not be invoked unless the clientName
// and serverName are non-empty strings, however it appears
// that in test case prn16.java the parser does execute the
// actions of the 'implementsClause' rule, even though there
// is no 'implements' keyword outside comments in the program
// text.
// I don't understand this, but as a workaround, I filter at
// this point and ensure that if either clientName or serverName
// is empty, no action is taken.
if( clientName.size( )>0 && serverName.size( )>0 )
{
userel_line.Insert( clientName );
userel_line.Insert( memberName );
userel_line.Insert( serverName );
// for data member definitions, we record lexical data for the
// extent,
// for inheritance and parameter relationships we do not
bool record_lexcounts=false;
switch( ut )
{
case utHASBYVAL:
case utHASBYREF:
record_lexcounts=true;
break;
default:
record_lexcounts=false;
}
string baseFlags=flags( );
baseFlags[psfVISIBILITY]=visibility;
insert_extent( userel_line, startLine, endLine,
description, baseFlags, ut, record_lexcounts );
prj->add_userel( userel_line );
}
}
452 void ParseStore::record_other_extent( int startLine, int endLine,
453 const string& description )
{
CCCC_Item rejext_line;
insert_extent( rejext_line, startLine, endLine, description, flags( ), utREJECTED, true );
prj->add_rejected_extent( rejext_line );
}
460 static void toktrace( ANTLRAbstractToken *tok )
{
// at the LHS we put out information about the current token
if( tok != NULL )
{
DbgMsg( PARSER, cerr,
std::setw( 6 ) << tok->getLine( )
<< std::setw( 4 ) << ( int )tok->getType( )
<< std::setiosflags( ios::left )
<< std::resetiosflags( ios::right )
<< std::setw( 20 ) << tok->getText( )
);
}
else
{
DbgMsg( PARSER, cerr, std::setw( 30 )<<"" );
}
}
enum InOrOut { IO_IN, IO_OUT };
481 static void rectrace( const char *rulename,
const char *dir_indic,
int guessing,
ANTLRAbstractToken *tok )
{
static int trace_depth=0;
if( guessing )
{
DbgMsg( PARSER, cerr,
setw( trace_depth*4+1 ) << "" << dir_indic
<< "?" << rulename << endl );
}
else
{
trace_depth=( ( ANTLRToken* ) tok )->getNestingLevel( );
DbgMsg( PARSER, cerr,
setw( trace_depth*4 )<< "" << dir_indic << rulename << endl );
}
}
501 void ParseUtility::tracein(
const char *rulename, int guessing,
503 ANTLRAbstractToken *tok )
{
if( guessing == 0 )
{
stack_tokentext[stack_depth]=tok->getText( );
stack_tokenline[stack_depth]=tok->getLine( );
stack_rules[stack_depth]=rulename;
stack_depth++;
}
// first put out the token details
toktrace( tok );
// then the indented recognition trace
rectrace( rulename, "-> ", guessing, tok );
}
520 void ParseUtility::traceout( const char *rulename,
int guessing,
522 ANTLRAbstractToken *tok )
{
if( guessing == 0 )
{
stack_depth--;
// some error checking...
if( stack_depth<0 )
{
cerr << "ParseUtility::traceout negative stack depth - "
<< "exiting from rule " << rulename
<< " at " << tok->getText( ) << " on line " << tok->getLine( )
<< endl;
}
else if( rulename!=stack_rules[stack_depth] )
{
cerr << "ParseStore::traceout rule name mismatch - "
<< rulename << "!=" << stack_rules[stack_depth] << endl;
}
stack_tokentext[stack_depth]="";
stack_tokenline[stack_depth]=0;
stack_rules[stack_depth]="";
}
// first put out the token details
toktrace( tok );
rectrace( rulename, "<- ", guessing, tok );
}
549 void ParseUtility::syn(
550 _ANTLRTokenPtr tok, ANTLRChar *egroup, SetWordType *eset,
ANTLRTokenType etok, int k )
{
string filename=ParseStore::currentInstance( )->filename( );
if( tok != NULL )
{
cerr << filename << '( ' << tok->getLine( ) << " ):"
<< " syntax error at token " << tok->getText( ) << endl;
}
else
{
cerr << filename << "( 0 ): syntax error at null token" << endl;
}
#if 1
// The logic in the other half of this #if section
// generated too much noise for some people's taste.
// It's only really useful to myself ( TJL ) or anyone
// else with a taste for debugging cccc.g/java.g etc.
int i=stack_depth-1;
cerr << filename << '( ' << stack_tokenline[i]
<< " ): trying to match " << stack_rules[i]
<< " at '" << stack_tokentext[i] << "'"
<< endl;
#else
cerr << "Parser context:" << endl;
for( int i=stack_depth-1; i>=0; i-- )
{
cerr << filename << '( ' << stack_tokenline[i]
<< " ): trying to match " << stack_rules[i]
<< " at '" << stack_tokentext[i] << "'"
<< endl;
}
cerr << endl;
#endif
}
587 void ParseStore::endOfLine( int line )
{
// We only do the processing below if the line which has just
// ended contained at least one non-skippable token
// The flag which tells us whether this is true is set in the
// token constructor
if( ANTLRToken::bCodeLine )
{
pendingLexicalCounts[tcCODELINES]++;
LineLexicalCountMatrix::value_type
vt( line, LexicalCountArray( static_cast<int>( tcLAST ), 0 ) );
for( int i=0; i<tcLAST; i++ )
{
vt.second[i]=pendingLexicalCounts[i];
pendingLexicalCounts[i]=0;
}
lineLexicalCounts.insert( vt );
// reset the flat for next time
ANTLRToken::bCodeLine=false;
}
}
1 /*
CCCC - C and C++ Code Counter
Copyright ( C ) 1994-2005 Tim Littlefair ( tim_littlefair@hotmail.com )
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
( at your option ) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// cccc_utl.h
#ifndef __CCCC_UTL_H
#define __CCCC_UTL_H
#include "cccc.h"
#include <map>
#include <vector>
#include "cccc_tok.h"
#include "AParser.h"
30 class ANTLRAbstractToken;
31 class ANTLRTokenPtr;
32 class CCCC_Item;
// this file declares all enumeration datatypes used in the project, and
// also the parse state class, which is used to capture information in the
// parse and transfer it to the code database for later report generation
// for each enumeration, a single character code is defined for each member
// these codes are shown in the inline comments
// the enumerations are designed to support resolution of incomplete
// knowledge about several sections of code which relate to the same
// object to give the most complete picture available
45 class AST;
// the languages which can be parsed
// only C and C++ are implemented as yet
enum Language { lAUTO, lCPLUSPLUS, lANSIC, lJAVA, lADA };
extern Language global_language, file_language;
enum Visibility {
vPUBLIC='0', vPROTECTED='1', vPRIVATE='2', vIMPLEMENTATION='3',
vDONTKNOW='?', vDONTCARE='X', vINVALID='*'
};
56 ostream& operator << ( ostream&, Visibility );
57 istream& operator >> ( istream&, Visibility& );
enum AugmentedBool {
abFALSE='F', abTRUE='T', abDONTKNOW='?', abDONTCARE='X', abINVALID='*'
};
62 ostream& operator << ( ostream& os, AugmentedBool ab );
63 istream& operator >> ( istream& is, AugmentedBool& ab );
enum UseType {
utDECLARATION='D', utDEFINITION='d', // of methods and classes
utINHERITS='I', // inheritance, including Java
// extends and implements relations
utHASBYVAL='H', utHASBYREF='h', // class data member
utPARBYVAL='P', utPARBYREF='p', // method parameter or return value
utVARBYVAL='V', utVARBYREF='v', // local variable within a method
utTEMPLATE_NAME='T', // typedef alias for a template
utTEMPLATE_TYPE='t', // type over which a template is
// instantiated
utINVOKES='i', // C function invocation
utREJECTED='r', // for extents rejected by the parser
utWITH='w', // Ada 'with' keyword context
utDONTKNOW='?', utDONTCARE='X', utINVALID='*'
};
// the parse state object consists of a number of strings representing
// knowledge about the identification of the source code object currently
// being processed, a number of flags of type AugmentedBool, and
// items representing knowledge about the
// concerning the object's nature, and also its visibility
enum PSString {
pssFILE, pssRULE, pssFLAGS, // the context of the parse
pssMODTYPE, pssMODULE, // the syntactic class and name of the module
pssUTYPE, // unqualified type of the current member
pssINDIR, // indirection associated with the type above
pssITYPE, // type qualified with indirection
pssMEMBER, pssPARAMS, // name, parameter list of a member
pssDESCRIPTION, // textual description of the relationship type
pssLAST // used to dimension the array
};
enum PSFlag {
psfCONST, psfSTATIC, psfEXTERN, psfVIRTUAL, // AugmentedBool
psfVISIBILITY, // Visibility
psfLAST // used to dimension the array
};
enum PSVerbosity { psvSILENT, psvQUIET, psvLOUD };
#define MAX_STACK_DEPTH 1000
// I have moved some actions originally embedded within the C++ grammar
// out of the grammar into the class ParseUtility defined below, so that
// other grammars can use them as well for consistency and efficiency.
// The ParseUtility::resynchronize( ) method provides a standardised way
// of 1 ) resynchronising the parser, and 2 ) reporting the parse error
// which caused the problem. Unfortunately, to do the resynchronisation
// it requires access to protected functions of ANTLRParser.
// The class ANTLR_Assisted_Parser below is a hack to enable ParseUtility
// to violate the protection of the functions required: ParseUtility is
// passed a pointer to a real parser which is of a subclass of ANTLRParser,
// and casts it to this artificial subclass, so as to give ParseUtility
// friend rights and to access the protected functions.
// This hack is necessary because the class definition we need to affect
// is generated by PCCTS: I am not proud of it and if anyone can suggest
// a way of doing without modifying PCCTS or its support code, I will be
// very happy to hear about it.
123 class ANTLR_Assisted_Parser : public ANTLRParser
{
125 ANTLR_Assisted_Parser( ANTLRParser& parser ) : ANTLRParser( parser ) {}
126 friend class ParseUtility;
};
// The parse utility class is intended to assist the parser in a number
// of ways. In earlier versions, this class had at least two distinct
// roles:
// 1 ) as a place for common functions which each parser might call
// for diagnostics, resynchronisation etc; and
// 2 ) as a general storage area for state which needs to be remembered
// for any length of time during the parsing process.
// The class ParseStore has been added to support the second role,
// and it is hoped that the amount of stored state can be reduced
// in the near future.
139 class ParseUtility {
public:
142 ParseUtility( ANTLRParser *parser );
143 ~ParseUtility( );
// the following methods are used to service the standard tracein/traceout
// and syntax error reporting calls generated by PCCTS
147 void tracein( const char *rulename, int guessing, ANTLRAbstractToken *tok );
148 void traceout( const char *rulename, int guessing, ANTLRAbstractToken *tok );
149 void syn( _ANTLRTokenPtr tok, ANTLRChar *egroup, SetWordType *eset,
ANTLRTokenType etok, int k );
// this method consolidates the text of the next n tokens of lookahead
153 string lookahead_text( int n );
// this method searches for a string of tokens at the specified nesting
// depth from the specified token class, and uses them as a marker to
// resynchronise the parser
158 void resynchronize(
159 int initial_nesting, SetWordType *resync_token_class,
160 ANTLRTokenPtr& resync_token );
// This utility function is used to create
// a composite scope name from a qualifier scope
// and a relative name.
165 string scopeCombine( const string& baseScope, const string& name );
// Only one instance of this class should exist at any time.
// This method allows the parsers and lexers to access the instance.
169 static ParseUtility *currentInstance( ) { return theCurrentInstance; }
private:
static ParseUtility *theCurrentInstance;
174 ANTLR_Assisted_Parser *parser;
int trace_depth;
static int stack_depth;
177 static string stack_tokentext[MAX_STACK_DEPTH];
static int stack_tokenline[MAX_STACK_DEPTH];
179 static string stack_rules[MAX_STACK_DEPTH];
// copy constructor and assignment operator are private to
// prevent unexpected copying
183 ParseUtility( const ParseUtility& );
184 const ParseUtility& operator=( const ParseUtility& );
};
// LOC, COM and MVG are all counted by the lexical analyzer,
// but the counts must be apportioned after the parser has
// identified the extents of the various declarations and definitions
// they belong to.
// This is achieved by the lexer maintaining counts of each
// which are reported to the ParseUtility class on a line by line
// basis. ParseUtility uses this data to create a store which is
// used to apportion counts as the parser reports extents.
enum LexicalCount { tcCOMLINES, tcCODELINES, tcMCCABES_VG, tcLAST };
// The ParseStore class encapsulates all information storage
// requirements related to the parser, and also manages
// the process of feeding that information to the database
// when it is complete.
// In particular, the class is responsible for receiving and
// retaining counts of the lexical metrics ( LOC, COM,
// MVG ) on a line-by-line basis. These are counted in the
// lexical analyzer, and the line-by-line counts must be
// integrated to allocate the counts to the extents identified
// by the parser as belonging to significant declarations and
// definitions.
209 class ParseStore
{
public:
212 ParseStore( const string& filename );
213 ~ParseStore( );
215 void IncrementCount( LexicalCount lc ) { pendingLexicalCounts[lc]++; }
216 void endOfLine( int line );
// each of the functions below writes one or more records into
// the database of code
221 void record_module_extent( int startLine, int endLine,
222 const string& moduleName,
223 const string& moduleType,
224 const string& description,
UseType ut );
226 void record_function_extent( int startLine, int endLine,
227 const string& returnType,
228 const string& moduleName,
229 const string& memberName,
230 const string& paramList,
231 const string& description,
Visibility visibility,
UseType ut );
234 void record_userel_extent( int startLine, int endLine,
235 const string& clientName,
236 const string& memberName,
237 const string& serverName,
238 const string& description,
Visibility visibility,
UseType ut );
241 void record_other_extent( int startLine, int endLine,
242 const string& description );
243 void record_file_balance_extent( string );
// Each of the record_XXX methods above uses this function to
// add an extent record.
247 void insert_extent( CCCC_Item&, int, int,
248 const string&, const string&,
249 UseType, bool allocate_lexcounts );
// the class maintains a number of strings and flags which reflect
// the most recently recognized module, member, type ( with and without
// indirection ) etc, and the visibility of items occuring at the current
// context
255 int get_flag( PSFlag ) const;
256 void set_flag( PSFlag, int );
257 void set_flag( Visibility );
258 Visibility get_visibility( );
259 string filename( );
261 char *flags( ) { return &( *flag.begin( ) ); }
// We also need the automatically generated copy constructor
// and assignment operator to allow us to save state in the
// parser.
// Only one instance of this class should exist at any time.
// This method allows the parsers and lexers to access the instance.
269 static ParseStore *currentInstance( ) { return theCurrentInstance; }
private:
static ParseStore *theCurrentInstance;
273 string theFilename;
typedef std::vector<int> LexicalCountArray;
276 LexicalCountArray pendingLexicalCounts;
typedef std::map<int, LexicalCountArray> LineLexicalCountMatrix;
279 LineLexicalCountMatrix lineLexicalCounts;
typedef std::vector<char> CharArray;
282 CharArray flag;
// copy constructor and assignment operator are private to
// prevent unexpected copying
286 ParseStore( const ParseStore& );
287 const ParseStore& operator=( const ParseStore& );
};
#endif
1 // This version built on at Fri 01/06/2006
#define CCCC_VERSION 3.1.1
#define CCCC_VERSION_STRING "3.1.1"
1 /*
CCCC - C and C++ Code Counter
Copyright ( C ) 1994-2005 Tim Littlefair ( tim_littlefair@hotmail.com )
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
( at your option ) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// cccc_xml.cc
// this file defines XML output facilities for the CCCC project
#include "cccc.h"
#include "cccc_itm.h"
#include "cccc_xml.h"
// I would love to use the C++ standard preprocessor
// directive #if here, but I have had reports before now
// of people who are using compilers which only support
// #ifdef.
#ifdef CCCC_CONF_W32VC
#include <direct.h>
#else
#ifdef CCCC_CONF_W32BC
#include <direct.h>
#else
#include <unistd.h>
#endif
#endif
#include <string.h>
#include <time.h>
#include <sys/stat.h>
#include "cccc_utl.h"
// class static data members
CCCC_Project* CCCC_Xml_Stream::prjptr;
string CCCC_Xml_Stream::outdir;
string CCCC_Xml_Stream::libdir;
static const string XML_PREAMBLE = "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
static const string XML_COMMENT_BEGIN = "<!--";
static const string XML_COMMENT_END = "-->";
static const string XML_TAG_OPEN_BEGIN = "<";
static const string XML_TAG_OPEN_END = ">";
static const string XML_TAG_CLOSE_BEGIN = "</";
static const string XML_TAG_CLOSE_END = ">";
static const string XML_TAG_INLINE_BEGIN = "<";
static const string XML_TAG_INLINE_END = "/>";
static const string XML_SPACE = " ";
static const string XML_NEWLINE = "\n";
static const string XML_DQUOTE = "\"";
static const string XML_EQUALS = "=";
static const string PROJECT_NODE_NAME = "CCCC_Project";
static const string TIMESTAMP_NODE_NAME = "timestamp";
static const string SUMMARY_NODE_NAME = "project_summary";
static const string MODSUM_NODE_NAME = "module_summary";
static const string MODDET_NODE_NAME = "module_detail";
static const string PROCSUM_NODE_NAME = "procedural_summary";
static const string PROCDET_NODE_NAME = "procedural_detail";
static const string STRUCTSUM_NODE_NAME = "structural_summary";
static const string STRUCTDET_NODE_NAME = "structural_detail";
static const string OODESIGN_NODE_NAME = "oo_design";
static const string OTHER_NODE_NAME = "other_extents";
static const string REJECTED_NODE_NAME = "rejected_extent";
static const string NAME_NODE_NAME = "name";
static const string MODULE_NODE_NAME = "module";
static const string MEMBER_NODE_NAME = "member_function";
static const string EXTENT_NODE_NAME = "extent";
static const string SUPPLIERS_NODE_NAME = "suppliers";
static const string SUPMOD_NODE_NAME = "supplier_module";
static const string CLIENTS_NODE_NAME = "clients";
static const string CLIMOD_NODE_NAME = "client_module";
static const string DESC_NODE_NAME = "description";
static const string SRCREF_NODE_NAME = "source_reference";
static const string NOM_NODE_NAME = "number_of_modules";
static const string LOC_NODE_NAME = "lines_of_code";
static const string LOCPERMOD_NODE_NAME = "lines_of_code_per_module";
static const string LOCPERCOM_NODE_NAME = "lines_of_code_per_line_of_comment";
static const string LOCPERMEM_NODE_NAME = "lines_of_code_per_member_function";
static const string MVG_NODE_NAME = "McCabes_cyclomatic_complexity";
static const string MVGPERMOD_NODE_NAME = "McCabes_cyclomatic_complexity_per_module";
static const string MVGPERCOM_NODE_NAME = "McCabes_cyclomatic_complexity_per_line_of_comment";
static const string MVGPERMEM_NODE_NAME = "McCabes_cyclomatic_complexity_per_member_function";
static const string COM_NODE_NAME = "lines_of_comment";
static const string COMPERMOD_NODE_NAME = "lines_of_comment_per_module";
static const string COMPERMEM_NODE_NAME = "lines_of_comment_per_member_function";
static const string WMC1_NODE_NAME = "weighted_methods_per_class_unity";
static const string WMCV_NODE_NAME = "weighted_methods_per_class_visibility";
static const string DIT_NODE_NAME = "depth_of_inheritance_tree";
static const string NOC_NODE_NAME = "number_of_children";
static const string CBO_NODE_NAME = "coupling_between_objects";
static const string IF4_NODE_NAME = "IF4";
static const string IF4PERMOD_NODE_NAME = "IF4_per_module";
static const string IF4PERMEM_NODE_NAME = "IF4_per_member_function";
static const string IF4VIS_NODE_NAME = "IF4_visible";
static const string IF4VISPERMOD_NODE_NAME = "IF4_visible_per_module";
static const string IF4VISPERMEM_NODE_NAME = "IF4_visible_per_member_function";
static const string IF4CON_NODE_NAME = "IF4_concrete";
static const string IF4CONPERMOD_NODE_NAME = "IF4_concrete";
static const string IF4CONPERMEM_NODE_NAME = "IF4_concrete_per_member_function";
static const string FO_NODE_NAME = "fan_out";
static const string FOV_NODE_NAME = "fan_out_visible";
static const string FOC_NODE_NAME = "fan_out_concrete";
static const string FI_NODE_NAME = "fan_in";
static const string FIV_NODE_NAME = "fan_in_visible";
static const string FIC_NODE_NAME = "fan_in_concrete";
static const string REJ_LOC_NODE_NAME = "rejected_lines_of_code";
static const string VALUE_ATTR = "value";
static const string LEVEL_ATTR = "level";
static const string FILE_ATTR = "file";
static const string LINE_ATTR = "line";
static const string VISIBLE_ATTR = "visible";
static const string CONCRETE_ATTR = "concrete";
static const string LEVEL_NORMAL = "0";
static const string LEVEL_MEDIUM = "1";
static const string LEVEL_HIGH = "2";
static const string BOOL_FALSE = "false";
static const string BOOL_TRUE = "true";
136 static string ltrim( string value )
{
const int MAX_LENGTH = 1000;
int i = 0;
while( i<value.size( ) && value[i]==' ' )
{
++i;
}
return value.substr( i, MAX_LENGTH );
}
147 void CCCC_Xml_Stream::GenerateReports( CCCC_Project* prj,
int report_mask,
149 const string& file,
150 const string& dir )
{
prjptr=prj;
outdir=dir;
CCCC_Xml_Stream main_xml_stream( file.c_str( ), "Report on software metrics" );
// For testing purposes, we want to be able to disable the inclusion
// of the current time in the report. This enables us to store a
// reference version of the report in RCS and expect the program
// to generate an identical one at regression testing time.
if( report_mask & rtSHOW_GEN_TIME )
{
main_xml_stream.Timestamp( );
}
if( report_mask & rtSUMMARY )
{
main_xml_stream.Project_Summary( );
}
if( report_mask & rtPROC1 )
{
main_xml_stream.Procedural_Summary( );
}
if( report_mask & rtPROC2 )
{
main_xml_stream.Procedural_Detail( );
}
if( report_mask & rtOODESIGN )
{
main_xml_stream.OO_Design( );
}
if( report_mask & rtSTRUCT1 )
{
main_xml_stream.Structural_Summary( );
}
if( report_mask & rtSTRUCT2 )
{
main_xml_stream.Structural_Detail( );
}
if( report_mask & rtSEPARATE_MODULES )
{
main_xml_stream.Separate_Modules( );
}
if( report_mask & rtOTHER )
{
main_xml_stream.Other_Extents( );
}
}
207 CCCC_Xml_Stream::CCCC_Xml_Stream( const string& fname, const string& info )
{
// cerr << "Attempting to open file in directory " << outdir.c_str( ) << endl;
fstr.open( fname.c_str( ) );
if( fstr.good( ) != TRUE )
{
cerr << "failed to open " << fname.c_str( )
<< " for output in directory " << outdir.c_str( ) << endl;
exit( 1 );
}
fstr << XML_PREAMBLE << endl
<< XML_COMMENT_BEGIN << info << XML_COMMENT_END << endl
<< XML_TAG_OPEN_BEGIN << PROJECT_NODE_NAME << XML_TAG_OPEN_END << endl;
}
223 CCCC_Xml_Stream::~CCCC_Xml_Stream( )
{
fstr << XML_TAG_CLOSE_BEGIN << PROJECT_NODE_NAME << XML_TAG_CLOSE_END << endl;
fstr.close( );
}
229 void CCCC_Xml_Stream::Timestamp( )
{
time_t generationTime=time( NULL );
fstr << XML_TAG_OPEN_BEGIN << TIMESTAMP_NODE_NAME << XML_TAG_OPEN_END
<< ctime( &generationTime )
<< XML_TAG_CLOSE_BEGIN << TIMESTAMP_NODE_NAME << XML_TAG_CLOSE_END
<< endl;
}
238 void CCCC_Xml_Stream::Project_Summary( ) {
// calculate the counts on which all displayed data will be based
int nom=prjptr->get_count( "NOM" ); // number of modules
int loc=prjptr->get_count( "LOC" ); // lines of code
int mvg=prjptr->get_count( "MVG" ); // McCabes cyclomatic complexity
int com=prjptr->get_count( "COM" ); // lines of comment
int if4=prjptr->get_count( "IF4" ); // intermodule complexity ( all couplings )
int if4v=prjptr->get_count( "IF4v" ); // intermodule complexity ( visible only )
int if4c=prjptr->get_count( "IF4c" ); // intermodule complexity ( concrete only )
int rej=prjptr->rejected_extent_table.get_count( "LOC" );
fstr << XML_TAG_OPEN_BEGIN << SUMMARY_NODE_NAME << XML_TAG_OPEN_END << endl;
Put_Metric_Node( NOM_NODE_NAME, nom );
Put_Metric_Node( LOC_NODE_NAME, loc, "LOCp" );
Put_Metric_Node( LOCPERMOD_NODE_NAME, loc, nom, "LOCper" );
Put_Metric_Node( MVG_NODE_NAME, mvg, "MVGp" );
Put_Metric_Node( MVGPERMOD_NODE_NAME, mvg, nom, "MVGper" );
Put_Metric_Node( COM_NODE_NAME, com, "COM" );
Put_Metric_Node( COMPERMOD_NODE_NAME, com, nom, "COMper" );
Put_Metric_Node( LOCPERCOM_NODE_NAME, loc, com, "L_C" );
Put_Metric_Node( MVGPERCOM_NODE_NAME, mvg, com, "M_C" );
Put_Metric_Node( IF4_NODE_NAME, if4 );
Put_Metric_Node( IF4PERMOD_NODE_NAME, if4, nom, "8.3" );
Put_Metric_Node( IF4VIS_NODE_NAME, if4v );
Put_Metric_Node( IF4VISPERMOD_NODE_NAME, if4v, nom, "8.3" );
Put_Metric_Node( IF4CON_NODE_NAME, if4c );
Put_Metric_Node( IF4CONPERMOD_NODE_NAME, if4c, nom, "8.3" );
Put_Metric_Node( REJ_LOC_NODE_NAME, rej, "REJ" );
fstr << XML_TAG_CLOSE_BEGIN << SUMMARY_NODE_NAME << XML_TAG_CLOSE_END << endl;
}
270 void CCCC_Xml_Stream::OO_Design( )
{
fstr << XML_TAG_OPEN_BEGIN << OODESIGN_NODE_NAME << XML_TAG_OPEN_END << endl;
CCCC_Module* mod_ptr=prjptr->module_table.first_item( );
int i=0;
while( mod_ptr!=NULL )
{
i++;
if( mod_ptr->is_trivial( ) == FALSE )
{
fstr << XML_TAG_OPEN_BEGIN << MODULE_NODE_NAME << XML_TAG_OPEN_END << endl;
Put_Label_Node( NAME_NODE_NAME, mod_ptr->name( nlSIMPLE ).c_str( ), 0, "", "" );
CCCC_Metric wmc1( mod_ptr->get_count( "WMC1" ), "WMC1" );
CCCC_Metric wmcv( mod_ptr->get_count( "WMCv" ), "WMCv" );
CCCC_Metric dit( mod_ptr->get_count( "DIT" ), "DIT" );
CCCC_Metric noc( mod_ptr->get_count( "NOC" ), "NOC" );
CCCC_Metric cbo( mod_ptr->get_count( "CBO" ), "CBO" );
Put_Metric_Node( WMC1_NODE_NAME, wmc1 );
Put_Metric_Node( WMCV_NODE_NAME, wmcv );
Put_Metric_Node( DIT_NODE_NAME, dit );
Put_Metric_Node( NOC_NODE_NAME, noc );
Put_Metric_Node( CBO_NODE_NAME, cbo );
fstr << XML_TAG_CLOSE_BEGIN << MODULE_NODE_NAME << XML_TAG_CLOSE_END << endl;
}
mod_ptr=prjptr->module_table.next_item( );
}
fstr << XML_TAG_CLOSE_BEGIN << OODESIGN_NODE_NAME << XML_TAG_CLOSE_END << endl;
}
304 void CCCC_Xml_Stream::Procedural_Summary( )
{
fstr << XML_TAG_OPEN_BEGIN << PROCSUM_NODE_NAME << XML_TAG_OPEN_END << endl;
CCCC_Module* mod_ptr=prjptr->module_table.first_item( );
int i=0;
while( mod_ptr!=NULL )
{
i++;
if( mod_ptr->is_trivial( ) == FALSE )
{
fstr << XML_TAG_OPEN_BEGIN << MODULE_NODE_NAME << XML_TAG_OPEN_END << endl;
Put_Label_Node( NAME_NODE_NAME, mod_ptr->name( nlSIMPLE ).c_str( ), 0, "", "" );
int loc=mod_ptr->get_count( "LOC" );
int mvg=mod_ptr->get_count( "MVG" );
int com=mod_ptr->get_count( "COM" );
CCCC_Metric mloc( loc, "LOCm" );
CCCC_Metric mmvg( mvg, "MVGm" );
CCCC_Metric ml_c( loc, com, "L_C" );
CCCC_Metric mm_c( mvg, com, "M_C" );
Put_Metric_Node( LOC_NODE_NAME, mloc );
Put_Metric_Node( MVG_NODE_NAME, mmvg );
Put_Metric_Node( COM_NODE_NAME, com );
Put_Metric_Node( LOCPERCOM_NODE_NAME, ml_c );
Put_Metric_Node( MVGPERCOM_NODE_NAME, mm_c );
fstr << XML_TAG_CLOSE_BEGIN << MODULE_NODE_NAME << XML_TAG_CLOSE_END << endl;
}
mod_ptr=prjptr->module_table.next_item( );
}
fstr << XML_TAG_CLOSE_BEGIN << PROCSUM_NODE_NAME << XML_TAG_CLOSE_END << endl;
}
340 void CCCC_Xml_Stream::Structural_Summary( )
{
fstr << XML_TAG_OPEN_BEGIN << STRUCTSUM_NODE_NAME << XML_TAG_OPEN_END << endl;
CCCC_Module* module_ptr=prjptr->module_table.first_item( );
while( module_ptr!=NULL )
{
if( module_ptr->is_trivial( )==FALSE )
{
fstr << XML_TAG_OPEN_BEGIN << MODULE_NODE_NAME << XML_TAG_OPEN_END << endl;
Put_Label_Node( NAME_NODE_NAME, module_ptr->name( nlSIMPLE ).c_str( ), 0, "", "" );
int fov=module_ptr->get_count( "FOv" );
int foc=module_ptr->get_count( "FOc" );
int fo=module_ptr->get_count( "FO" );
int fiv=module_ptr->get_count( "FIv" );
int fic=module_ptr->get_count( "FIc" );
int fi=module_ptr->get_count( "FI" );
int if4v=module_ptr->get_count( "IF4v" );
int if4c=module_ptr->get_count( "IF4c" );
int if4=module_ptr->get_count( "IF4" );
// the last two arguments here turn on links to enable jumping between
// the summary and detail cells for the same module
Put_Metric_Node( FOV_NODE_NAME, CCCC_Metric( fov, "FOv" ) );
Put_Metric_Node( FOC_NODE_NAME, CCCC_Metric( foc, "FOc" ) );
Put_Metric_Node( FO_NODE_NAME, CCCC_Metric( fo, "FO" ) );
Put_Metric_Node( FIV_NODE_NAME, CCCC_Metric( fiv, "FIv" ) );
Put_Metric_Node( FIC_NODE_NAME, CCCC_Metric( fic, "FIc" ) );
Put_Metric_Node( FI_NODE_NAME, CCCC_Metric( fi, "FI" ) );
Put_Metric_Node( IF4VIS_NODE_NAME, CCCC_Metric( if4v, "IF4v" ) );
Put_Metric_Node( IF4CON_NODE_NAME, CCCC_Metric( if4c, "IF4c" ) );
Put_Metric_Node( IF4_NODE_NAME, CCCC_Metric( if4, "IF4" ) );
fstr << XML_TAG_CLOSE_BEGIN << MODULE_NODE_NAME << XML_TAG_CLOSE_END << endl;
}
module_ptr=prjptr->module_table.next_item( );
}
fstr << XML_TAG_CLOSE_BEGIN << STRUCTSUM_NODE_NAME << XML_TAG_CLOSE_END << endl;
}
383 void CCCC_Xml_Stream::Put_Structural_Details_Node(
384 CCCC_Module *mod, CCCC_Project *prj, int mask, UserelNameLevel nl )
{
#if 0
std::cerr << "Relationships for " << mod->name( nlMODULE_NAME )
<< " ( " << mod << " )" << std::endl;
#endif
CCCC_Module::relationship_map_t::iterator iter;
CCCC_Module::relationship_map_t *relationship_map=NULL;
string nodeTag;
if( mask==rmeCLIENT )
{
nodeTag = CLIMOD_NODE_NAME;
relationship_map=&( mod->client_map );
}
else if( mask==rmeSUPPLIER )
{
nodeTag = SUPMOD_NODE_NAME;
relationship_map=&( mod->supplier_map );
}
if( relationship_map==NULL )
{
cerr << "unexpected relationship mask " << mask << endl;
}
else
{
fstr << XML_TAG_OPEN_BEGIN << nodeTag << XML_TAG_OPEN_END << endl;
for(
iter=relationship_map->begin( );
iter!=relationship_map->end( );
iter++
)
{
CCCC_UseRelationship *ur_ptr=( *iter ).second;
Put_Label_Node( NAME_NODE_NAME, ur_ptr->name( nl ).c_str( ), 0, "", "" );
AugmentedBool vis=ur_ptr->is_visible( );
AugmentedBool con=ur_ptr->is_concrete( );
string visvalue = BOOL_FALSE;
string convalue = BOOL_FALSE;
if( vis!=abFALSE )
{
visvalue = BOOL_TRUE;
}
if( con!=abFALSE )
{
convalue = BOOL_TRUE;
}
Put_Label_Node( VISIBLE_ATTR, visvalue, 0, "", "" );
Put_Label_Node( CONCRETE_ATTR, convalue, 0, "", "" );
Put_Extent_List( *ur_ptr, true );
}
fstr << XML_TAG_CLOSE_BEGIN << nodeTag << XML_TAG_CLOSE_END << endl;
}
}
448 void CCCC_Xml_Stream::Structural_Detail( )
{
fstr << XML_TAG_OPEN_BEGIN << STRUCTDET_NODE_NAME << XML_TAG_OPEN_END << endl;
CCCC_Module* module_ptr=prjptr->module_table.first_item( );
while( module_ptr!=NULL )
{
if( module_ptr->is_trivial( )==FALSE )
{
Structural_Detail( module_ptr );
}
module_ptr=prjptr->module_table.next_item( );
}
fstr << XML_TAG_CLOSE_BEGIN << STRUCTDET_NODE_NAME << XML_TAG_CLOSE_END << endl;
}
463 void CCCC_Xml_Stream::Procedural_Detail( ) {
fstr << XML_TAG_OPEN_BEGIN << PROCDET_NODE_NAME << XML_TAG_OPEN_END << endl;
CCCC_Module* mod_ptr=prjptr->module_table.first_item( );
while( mod_ptr!=NULL )
{
if(
( mod_ptr->name( nlMODULE_TYPE )!="builtin" ) &&
( mod_ptr->name( nlMODULE_TYPE )!="enum" ) &&
( mod_ptr->name( nlMODULE_TYPE )!="union" )
)
{
fstr << XML_TAG_OPEN_BEGIN << MODULE_NODE_NAME << XML_TAG_OPEN_END << endl;
Put_Label_Node( NAME_NODE_NAME, mod_ptr->name( nlSIMPLE ).c_str( ), 50,
"procdet", "procsum", mod_ptr );
Procedural_Detail( mod_ptr );
fstr << XML_TAG_CLOSE_BEGIN << MODULE_NODE_NAME << XML_TAG_CLOSE_END << endl;
}
mod_ptr=prjptr->module_table.next_item( );
}
fstr << XML_TAG_CLOSE_BEGIN << PROCDET_NODE_NAME << XML_TAG_CLOSE_END << endl;
}
487 void CCCC_Xml_Stream::Other_Extents( )
{
fstr << XML_TAG_OPEN_BEGIN << OTHER_NODE_NAME << XML_TAG_OPEN_END << endl;
CCCC_Extent *extent_ptr=prjptr->rejected_extent_table.first_item( );
while( extent_ptr!=NULL )
{
fstr << XML_TAG_OPEN_BEGIN << REJECTED_NODE_NAME << XML_TAG_OPEN_END << endl;
Put_Label_Node( NAME_NODE_NAME, extent_ptr->name( nlDESCRIPTION ).c_str( ) );
Put_Extent_Node( *extent_ptr, 0 );
Put_Metric_Node( LOC_NODE_NAME, extent_ptr->get_count( "LOC" ), "" );
Put_Metric_Node( COM_NODE_NAME, extent_ptr->get_count( "COM" ), "" );
Put_Metric_Node( MVG_NODE_NAME, extent_ptr->get_count( "MVG" ), "" );
extent_ptr=prjptr->rejected_extent_table.next_item( );
fstr << XML_TAG_CLOSE_BEGIN << REJECTED_NODE_NAME << XML_TAG_CLOSE_END << endl;
}
fstr << XML_TAG_CLOSE_BEGIN << OTHER_NODE_NAME << XML_TAG_CLOSE_END << endl;
}
507 void CCCC_Xml_Stream::Put_Label_Node( string nodeTag, string label, int width,
508 string ref_name, string ref_href,
509 CCCC_Record *rec_ptr )
{
if( label.size( )>0 )
{
fstr << XML_TAG_OPEN_BEGIN << nodeTag << XML_TAG_OPEN_END;
*this << label;
fstr << XML_TAG_CLOSE_BEGIN << nodeTag << XML_TAG_CLOSE_END
<< endl;
}
else
{
// Do nothing
}
if( rec_ptr != 0 )
{
Put_Extent_List( *rec_ptr, true );
}
}
530 void CCCC_Xml_Stream::Put_Metric_Node( string nodeTag,
531 int count, string tag )
{
CCCC_Metric m( count, tag.c_str( ) );
Put_Metric_Node( nodeTag, m );
}
537 void CCCC_Xml_Stream::Put_Metric_Node( string nodeTag,
538 int num, int denom, string tag )
{
CCCC_Metric m( num, denom, tag.c_str( ) );
Put_Metric_Node( nodeTag, m );
}
544 void CCCC_Xml_Stream::Put_Metric_Node( string nodeTag, const CCCC_Metric& metric )
{
fstr << XML_TAG_INLINE_BEGIN << nodeTag << XML_SPACE
<< VALUE_ATTR << XML_EQUALS << XML_DQUOTE;
*this << metric;
fstr << XML_DQUOTE << XML_SPACE
<< LEVEL_ATTR << XML_EQUALS << XML_DQUOTE;
switch( metric.emphasis_level( ) )
{
case elMEDIUM:
fstr << LEVEL_MEDIUM;
break;
case elHIGH:
fstr << LEVEL_HIGH;
break;
default:
fstr << LEVEL_NORMAL;
break;
}
fstr << XML_DQUOTE << XML_SPACE << XML_TAG_INLINE_END << endl;
}
567 void CCCC_Xml_Stream::Put_Extent_URL( const CCCC_Extent& extent )
{
string filename=extent.name( nlFILENAME );
int linenumber=atoi( extent.name( nlLINENUMBER ).c_str( ) );
fstr << XML_TAG_INLINE_BEGIN << SRCREF_NODE_NAME << XML_SPACE
<< FILE_ATTR << XML_EQUALS << XML_DQUOTE;
*this << filename;
fstr << XML_DQUOTE << XML_SPACE
<< LINE_ATTR << XML_EQUALS << XML_DQUOTE;
*this << linenumber;
fstr << XML_DQUOTE << XML_SPACE << XML_TAG_INLINE_END << endl;
}
580 void CCCC_Xml_Stream::Put_Extent_Node( const CCCC_Extent& extent, int width, bool withDescription )
{
if( withDescription )
{
fstr << XML_TAG_OPEN_BEGIN << DESC_NODE_NAME << XML_TAG_OPEN_END
<< extent.name( nlDESCRIPTION )
<< XML_TAG_CLOSE_BEGIN << DESC_NODE_NAME << XML_TAG_CLOSE_END
<< endl;
}
Put_Extent_URL( extent );
}
592 void CCCC_Xml_Stream::Put_Extent_List( CCCC_Record& record, bool withDescription )
{
CCCC_Extent *ext_ptr=record.extent_table.first_item( );
while( ext_ptr!=NULL )
{
fstr << XML_TAG_OPEN_BEGIN << EXTENT_NODE_NAME << XML_TAG_OPEN_END
<< endl;
if( withDescription )
{
fstr << XML_TAG_OPEN_BEGIN << DESC_NODE_NAME << XML_TAG_OPEN_END
<< ext_ptr->name( nlDESCRIPTION )
<< XML_TAG_CLOSE_BEGIN << DESC_NODE_NAME << XML_TAG_CLOSE_END
<< endl;
}
Put_Extent_URL( *ext_ptr );
fstr << XML_TAG_CLOSE_BEGIN << EXTENT_NODE_NAME << XML_TAG_CLOSE_END
<< endl;
ext_ptr=record.extent_table.next_item( );
}
}
// the next two methods define the two basic output operations through which
// all of the higher level output operations are composed
615 CCCC_Xml_Stream& operator <<( CCCC_Xml_Stream& os, const string& stg )
{
// initialise a character pointer to the start of the string's buffer
const char *cptr=stg.c_str( );
while( *cptr!='\000' ) {
char c=*cptr;
// the purpose of this is to filter out the characters which
// must be escaped in HTML
switch( c ) {
case '>': os.fstr << ">" ; break;
case '<': os.fstr << "<" ; break;
case '&': os.fstr << "&"; break;
default : os.fstr << c;
}
cptr++;
}
return os;
}
635 CCCC_Xml_Stream& operator <<( CCCC_Xml_Stream& os, const CCCC_Metric& mtc )
{
// by writing to the underlying ostream object, we avoid the escape
// functionality
os.fstr << ltrim( mtc.value_string( ) ) ;
return os;
}
643 void CCCC_Xml_Stream::Separate_Modules( )
{
// this function generates a separate HTML report for each non-trivial
// module in the database
CCCC_Module* mod_ptr=prjptr->module_table.first_item( );
while( mod_ptr!=NULL )
{
int trivial_module=mod_ptr->is_trivial( );
if( trivial_module==FALSE )
{
string info="Detailed report on module " + mod_ptr->key( );
string filename=outdir;
filename+="/";
filename+=mod_ptr->key( )+".xml";
CCCC_Xml_Stream module_xml_str( filename, info.c_str( ) );
module_xml_str.Module_Summary( mod_ptr );
module_xml_str.fstr
<< XML_TAG_OPEN_BEGIN << MODDET_NODE_NAME << XML_TAG_OPEN_END
<< endl;
module_xml_str.Module_Detail( mod_ptr );
module_xml_str.fstr
<< XML_TAG_CLOSE_BEGIN << MODDET_NODE_NAME << XML_TAG_CLOSE_END
<< endl;
module_xml_str.fstr
<< XML_TAG_OPEN_BEGIN << PROCDET_NODE_NAME << XML_TAG_OPEN_END
<< endl;
module_xml_str.Procedural_Detail( mod_ptr );
module_xml_str.fstr
<< XML_TAG_CLOSE_BEGIN << PROCDET_NODE_NAME << XML_TAG_CLOSE_END
<< endl;
module_xml_str.fstr
<< XML_TAG_OPEN_BEGIN << STRUCTDET_NODE_NAME << XML_TAG_OPEN_END
<< endl;
module_xml_str.Structural_Detail( mod_ptr );
module_xml_str.fstr
<< XML_TAG_CLOSE_BEGIN << STRUCTDET_NODE_NAME << XML_TAG_CLOSE_END
<< endl;
}
else
{
#if 0
cerr << mod_ptr->module_type << " " << mod_ptr->key( )
<< " is trivial" << endl;
#endif
}
mod_ptr=prjptr->module_table.next_item( );
}
}
698 void CCCC_Xml_Stream::Module_Detail( CCCC_Module *module_ptr )
{
// this function generates the contents of the table of definition
// and declaration extents for a single module
// the output needs to be enveloped in a pair of <TABLE></TABLE> tags
// these have not been put within the function because it is designed
// to be used in two contexts:
// 1. within the Separate_Modules function, wrapped directly in the table
// tags
// 2. within the Module_Detail function, where the table tags are
// around the output of many calls to this function ( not yet implemented )
CCCC_Record::Extent_Table::iterator eIter = module_ptr->extent_table.begin( );
while( eIter!=module_ptr->extent_table.end( ) )
{
CCCC_Extent *ext_ptr=( *eIter ).second;
Put_Extent_Node( *ext_ptr, 0, true );
int loc=ext_ptr->get_count( "LOC" );
int mvg=ext_ptr->get_count( "MVG" );
int com=ext_ptr->get_count( "COM" );
CCCC_Metric mloc( loc, "LOCf" );
CCCC_Metric mmvg( mvg, "MVGf" );
CCCC_Metric ml_c( loc, com, "L_C" );
CCCC_Metric mm_c( mvg, com, "M_C" );
Put_Metric_Node( LOC_NODE_NAME, mloc );
Put_Metric_Node( MVG_NODE_NAME, mmvg );
Put_Metric_Node( COM_NODE_NAME, com );
Put_Metric_Node( LOCPERCOM_NODE_NAME, ml_c );
Put_Metric_Node( MVGPERCOM_NODE_NAME, mm_c );
eIter++;
}
}
734 void CCCC_Xml_Stream::Procedural_Detail( CCCC_Module *module_ptr )
{
// this function generates the contents of the procedural detail table
// relating to a single module
// the output needs to be enveloped in a pair of <TABLE></TABLE> tags
// these have not been put within the function because it is designed
// to be used in two contexts:
// 1. within the Separate_Modules function, wrapped directly in the table
// tags
// 2. within the Procedural_Detail function, where the table tags are
// around the output of many calls to this function
CCCC_Module::member_map_t::iterator iter = module_ptr->member_map.begin( );
while( iter!=module_ptr->member_map.end( ) )
{
fstr << XML_TAG_OPEN_BEGIN << MEMBER_NODE_NAME << XML_TAG_OPEN_END << endl;
CCCC_Member *mem_ptr=( *iter ).second;
Put_Label_Node( NAME_NODE_NAME, mem_ptr->name( nlLOCAL ).c_str( ), 0, "", "", mem_ptr );
int loc=mem_ptr->get_count( "LOC" );
int mvg=mem_ptr->get_count( "MVG" );
int com=mem_ptr->get_count( "COM" );
CCCC_Metric mloc( loc, "LOCf" );
CCCC_Metric mmvg( mvg, "MVGf" );
CCCC_Metric ml_c( loc, com, "L_C" );
CCCC_Metric mm_c( mvg, com, "M_C" );
Put_Metric_Node( LOC_NODE_NAME, mloc );
Put_Metric_Node( MVG_NODE_NAME, mmvg );
Put_Metric_Node( COM_NODE_NAME, com );
Put_Metric_Node( LOCPERCOM_NODE_NAME, ml_c );
Put_Metric_Node( MVGPERCOM_NODE_NAME, mm_c );
iter++;
fstr << XML_TAG_CLOSE_BEGIN << MEMBER_NODE_NAME << XML_TAG_CLOSE_END << endl;
}
}
775 void CCCC_Xml_Stream::Structural_Detail( CCCC_Module *module_ptr )
{
fstr << XML_TAG_OPEN_BEGIN << MODULE_NODE_NAME << XML_TAG_OPEN_END << endl;
Put_Label_Node( NAME_NODE_NAME, module_ptr->name( nlSIMPLE ).c_str( ), 0, "", "" );
Put_Structural_Details_Node( module_ptr, prjptr, rmeCLIENT, nlCLIENT );
Put_Structural_Details_Node( module_ptr, prjptr, rmeSUPPLIER, nlSUPPLIER );
fstr << XML_TAG_CLOSE_BEGIN << MODULE_NODE_NAME << XML_TAG_CLOSE_END << endl;
}
784 void CCCC_Xml_Stream::Module_Summary( CCCC_Module *module_ptr )
{
// calculate the counts on which all displayed data will be based
// int nof=module_ptr->member_table.records( ); // Number of functions
int nof=0;
int loc=module_ptr->get_count( "LOC" ); // lines of code
int mvg=module_ptr->get_count( "MVG" ); // McCabes cyclomatic complexity
int com=module_ptr->get_count( "COM" ); // lines of comment
// the variants of IF4 measure information flow and couplings
int if4=module_ptr->get_count( "IF4" ); // ( all couplings )
int if4v=module_ptr->get_count( "IF4v" ); // ( visible only )
int if4c=module_ptr->get_count( "IF4c" ); // ( concrete only )
int wmc1=module_ptr->get_count( "WMC1" ); // Weighted methods/class ( unity )
int wmcv=module_ptr->get_count( "WMCv" ); // Weighted methods/class ( visible )
int dit=module_ptr->get_count( "DIT" ); // depth of inheritance tree
int noc=module_ptr->get_count( "NOC" ); // number of children
int cbo=module_ptr->get_count( "CBO" ); // coupling between objects
fstr << XML_TAG_OPEN_BEGIN << MODSUM_NODE_NAME << XML_TAG_OPEN_END << endl;
Put_Metric_Node( LOC_NODE_NAME, loc, "LOCm" );
Put_Metric_Node( LOCPERMEM_NODE_NAME, loc, nof, "LOCg" );
Put_Metric_Node( MVG_NODE_NAME, mvg, "MVGm" );
Put_Metric_Node( MVGPERMEM_NODE_NAME, mvg, nof, "MVGf" );
Put_Metric_Node( LOC_NODE_NAME, com, "COMm" );
Put_Metric_Node( LOCPERMEM_NODE_NAME, com, nof, "8.3" );
Put_Metric_Node( LOCPERCOM_NODE_NAME, loc, com, "L_C" );
Put_Metric_Node( MVGPERCOM_NODE_NAME, mvg, com, "M_C" );
Put_Metric_Node( WMC1_NODE_NAME, wmc1 );
Put_Metric_Node( WMCV_NODE_NAME, wmcv );
Put_Metric_Node( DIT_NODE_NAME, dit );
Put_Metric_Node( NOC_NODE_NAME, noc );
Put_Metric_Node( CBO_NODE_NAME, cbo );
Put_Metric_Node( IF4_NODE_NAME, if4, 1, "IF4" );
Put_Metric_Node( IF4PERMEM_NODE_NAME, if4, nof, "8.3" );
Put_Metric_Node( IF4VIS_NODE_NAME, if4v, 1, "IF4v" );
Put_Metric_Node( IF4VISPERMEM_NODE_NAME, if4v, nof, "8.3" );
Put_Metric_Node( IF4CON_NODE_NAME, if4c, 1, "IF4c" );
Put_Metric_Node( IF4CONPERMEM_NODE_NAME, if4c, nof, "8.3" );
fstr << XML_TAG_CLOSE_BEGIN << MODSUM_NODE_NAME << XML_TAG_CLOSE_END << endl;
}
831 void CCCC_Xml_Stream::Source_Listing( )
{
}
#if 0
836 static string pad_string( int target_width, string the_string, string padding )
{
int spaces_required=target_width-the_string.size( );
string pad_string;
while( spaces_required>0 )
{
pad_string+=padding;
spaces_required--;
}
return pad_string+the_string;
}
#endif
#ifdef UNIT_TEST
852 int main( )
{
CCCC_Project *prj_ptr=test_project_ptr( );
CCCC_Xml_Stream os( *prj_ptr, "cccc.htm", "." );
return 0;
}
#endif
1 /*
CCCC - C and C++ Code Counter
Copyright ( C ) 1994-2005 Tim Littlefair ( tim_littlefair@hotmail.com )
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
( at your option ) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __CCCC_XML_H
#define __CCCC_XML_H
#include "cccc.h"
#include <fstream>
#include <time.h>
#include "cccc_db.h"
#include "cccc_met.h"
// Ideally, this class would be defined to reuse common
// facilities abstracted from CCCC_Html_Stream.
// This may happen in the future, for the moment, the implementation
// has been created by cut and paste.
// We need to include cccc_htm.h because it defines the enumeration
// ReportType.
#include "cccc_htm.h"
41 class CCCC_Xml_Stream {
42 friend CCCC_Xml_Stream& operator <<( CCCC_Xml_Stream& os,
43 const string& stg );
44 friend CCCC_Xml_Stream& operator <<( CCCC_Xml_Stream& os,
45 const CCCC_Metric& mtc );
47 ofstream fstr;
48 static string libdir;
49 static string outdir;
50 static CCCC_Project* prjptr;
52 void Timestamp( );
53 void Project_Summary( );
54 void Procedural_Summary( );
55 void Procedural_Detail( );
56 void Structural_Summary( );
57 void Structural_Detail( );
58 void OO_Design( );
59 void Other_Extents( );
60 void Separate_Modules( );
61 void Source_Listing( );
64 void Module_Summary( CCCC_Module *module_ptr );
65 void Module_Detail( CCCC_Module *module_ptr );
66 void Procedural_Detail( CCCC_Module *module_ptr );
67 void Structural_Detail( CCCC_Module *module_ptr );
69 void Separate_Module_Link( CCCC_Module *module_ptr );
71 void Put_Label_Node( string nodeTag, string label, int width=0,
72 string ref_name="", string ref_href="",
73 CCCC_Record *rec_ptr=0 );
74 void Put_Metric_Node( string nodeTag, const CCCC_Metric& metric );
75 void Put_Metric_Node( string nodeTag, int count, string tag );
76 void Put_Metric_Node( string nodeTag, int num, int denom, string tag );
77 void Put_Extent_URL( const CCCC_Extent& extent );
78 void Put_Extent_Node( const CCCC_Extent& extent, int width=0, bool withDescription=false );
79 void Put_Extent_List( CCCC_Record& record, bool withDescription=false );
80 void Put_Structural_Details_Node( CCCC_Module *mod,
81 CCCC_Project *prj,
int mask,
UserelNameLevel nl );
public:
86 static void GenerateReports( CCCC_Project* project, int report_mask,
87 const string& outfile, const string& outdir );
// general-purpose constructor with standard preamble
90 CCCC_Xml_Stream( const string& fname, const string& info );
// destructor with standard trailer
93 ~CCCC_Xml_Stream( );
};
96 CCCC_Xml_Stream& operator <<( CCCC_Xml_Stream& os, const string& stg );
97 CCCC_Xml_Stream& operator <<( CCCC_Xml_Stream& os, const CCCC_Metric& mtc );
98 CCCC_Xml_Stream& operator <<( CCCC_Xml_Stream& os, const CCCC_Extent& ext );
#if 0
// this class is added to support the generation of an HTML file
// containing the source analysed by the run, with anchors embedded at
// each of the lines referred to in the other parts of the report
104 class Source_Anchor
{
// if this looks more like a struct to you, it does to me too...
// it could be embedded withing CCCC_Xml_Stream except that this
// might make the default constructor unavailable for the std::map
// instantiation
111 string file_;
int line_;
public:
114 Source_Anchor( ):line_( 0 ) {}
115 Source_Anchor( string file, int line ) : file_( file ), line_( line ) {}
117 string get_file( ) const { return file_; }
118 int get_line( ) const { return line_; }
119 string key( ) const;
121 void Emit_HREF( ofstream& fstr );
122 void Emit_NAME( ofstream& fstr );
123 void Emit_SPACE( ofstream& fstr );
// the default copy constructor, assignment operator and destructor
// are OK for this class
};
#endif
#endif /* __CCCC_XML_H */
1 // ccccmain.cc
// command line interface implementation for the cccc project
#include "cccc.h"
#include "cccc_ver.h"
#include <fstream>
#include <list>
#include <iterator>
#ifdef _WIN32
#include <direct.h>
#include <io.h>
#define HANDLE intptr_t
#define INVALID_HANDLE_VALUE -1
#else
#include <sys/stat.h>
#endif
#include "cccc_itm.h"
#include "cccc_opt.h"
#include "cccc_met.h"
#include "cccc_db.h"
#include "cccc_utl.h"
#include "cccc_htm.h"
#include "cccc_xml.h"
// support for languages is now a compile-time option
#ifdef CC_INCLUDED
#include "CParser.h"
#include "CLexer.h"
#endif
#ifdef JAVA_INCLUDED
#include "JParser.h"
#include "JLexer.h"
#endif
#ifdef ADA_INCLUDED
#include "AdaPrser.h"
#include "ALexer.h"
#endif
#define NEW_PAGE "\f\n"
CCCC_Project *prj=NULL;
int DebugMask=0;
int dont_free=0;
char *skip_identifiers[SKIP_IDENTIFIERS_ARRAY_SIZE];
#if defined( _WIN32 ) && defined( __GNUG__ )
// Cygnus gcc for Win32 B19 will try to expand wildcards that are given at
// the commandline. Sadly this "globbing" will not work the way it is
// supposed in Win32, but luckily the whole globbing can be disabled by
// defining the following variable:
int _CRT_glob = 0;
#endif
/*
** global variables to hold default values for various things
*/
string current_filename, current_rule, parse_language;
// class Main encapsulates the top level of control for the program
// including command line handling
71 class Main
{
// most of the data members of this class are either set
// by default or gleaned from the command line
// each of the data members of type string or int can be
// set by a command line flag of the type --<member name>=<value>
79 string outdir;
80 string db_infile;
81 string db_outfile;
82 string opt_infile;
83 string opt_outfile;
84 string html_outfile;
85 string xml_outfile;
86 string lang;
int report_mask;
int debug_mask;
int files_parsed;
// As we gather up the list of files to be processed
// we work out and record the appropriate language to
// use for each.
typedef std::pair<string, string> file_entry;
95 std::list<file_entry> file_list;
// this function encapsulates adding an argument to the file_list
// for the time being, on Win32 only, it also performs filename globbing
99 void AddFileArgument( const string& );
public:
103 Main( );
104 void HandleArgs( int argc, char**argv );
105 void HandleDebugOption( const string& );
106 void HandleReportOption( const string& );
107 void PrintCredits( ostream& os );
108 void PrintUsage( ostream& os );
109 int ParseFiles( );
110 int DumpDatabase( );
111 int LoadDatabase( );
112 void GenerateHtml( );
113 void GenerateXml( );
114 void DescribeOutput( );
115 int filesParsed( );
117 friend int main( int argc, char** argv );
};
Main *app=NULL;
122 Main::Main( )
{
report_mask=0xFFFF&( ~( rtPROC2|rtSTRUCT2 ) ) ;
debug_mask=0;
files_parsed=0;
}
129 void Main::HandleArgs( int argc, char **argv )
{
bool accepting_options=true;
for( int i=1; i<argc; i++ )
{
string next_arg=argv[i];
if(
( accepting_options==false ) ||
( next_arg.substr( 0, 2 )!="--" )
)
{
// normally this will be a single file name, but
// the function below also encapsulates handling of
// globbing ( only required under Win32 ) and
// the conventional interpretation of '-' to mean
// read a list of files from standard input
AddFileArgument( next_arg );
}
else if( next_arg=="--" )
{
// we support the conventional use of a bare -- to turn
// off option processing and allow filenames that look like
// options to be accepted
accepting_options=false;
}
else if( next_arg=="--help" )
{
PrintUsage( cout );
exit( 1 );
}
else
{
// the options below this point are all of the form --opt=val,
// so we parse the argument to find the assignment
unsigned int assignment_pos=next_arg.find( "=" );
if( assignment_pos==string::npos )
{
cerr << "Unexpected option " << next_arg << endl;
PrintUsage( cerr );
exit( 2 );
}
else
{
string next_opt=next_arg.substr( 0, assignment_pos );
string next_val=next_arg.substr( assignment_pos+1 );
if( next_opt=="--outdir" )
{
outdir=next_val;
}
else if( next_opt=="--db_infile" )
{
db_infile=next_val;
}
else if( next_opt=="--db_outfile" )
{
db_outfile=next_val;
}
else if( next_opt=="--opt_infile" )
{
opt_infile=next_val;
}
else if( next_opt=="--opt_outfile" )
{
opt_outfile=next_val;
}
else if( next_opt=="--html_outfile" )
{
html_outfile=next_val;
}
else if( next_opt=="--xml_outfile" )
{
xml_outfile=next_val;
}
else if( next_opt=="--lang" )
{
lang=next_val;
}
else if( next_opt=="--report_mask" )
{
// The report option may either be an integer flag vector
// in numeric format ( including hex ) or may be a string of
// characters ( see HandleReportOption for what they mean ).
HandleReportOption( next_val.c_str( ) );
}
else if( next_opt=="--debug_mask" )
{
// The report option may either be an integer flag vector
// in numeric format ( including hex ) or may be a string of
// characters ( see HandleDebugOption for what they mean ).
HandleDebugOption( next_val.c_str( ) );
}
else
{
cerr << "Unexpected option " << next_opt << endl;
PrintUsage( cerr );
exit( 3 );
}
}
}
}
// we fill in defaults for things which have not been set
if( outdir=="" )
{
outdir=".cccc";
}
if( db_outfile=="" )
{
db_outfile=outdir+"/cccc.db";
}
if( html_outfile=="" )
{
html_outfile=outdir+"/cccc.html";
}
if( xml_outfile=="" )
{
xml_outfile=outdir+"/cccc.xml";
}
if( opt_outfile=="" )
{
opt_outfile=outdir+"/cccc.opt";
}
// the other strings all default to empty values
if( opt_infile=="" )
{
CCCC_Options::Load_Options( );
// save the options so that they can be edited
CCCC_Options::Save_Options( opt_outfile );
}
else
{
CCCC_Options::Load_Options( opt_infile );
}
}
271 void Main::AddFileArgument( const string& file_arg )
{
if( file_arg=="-" )
{
/*
** add files listed on standard input to the list of files
** to be processed
*/
while( !std::cin.eof( ) )
{
string filename;
std::cin >> filename;
file_entry file_entry( filename, lang );
file_list.push_back( file_entry );
}
}
else
{
#ifdef _WIN32
/*
** In Win32 we will have to expand all wildcards ourself, because the
** shell won't do this for us.
** This code reworked for 3.1.1 because we are now using the Visual C++ 2003
** Toolkit, which does not provide the same APIs as Visual Studio 5/6.
*/
_finddata_t fd;
HANDLE sh = _findfirst( file_arg.c_str( ), &fd );
// 3.pre40
// I discovered ( by behaviour, not documentation ) that
// the structure returned by FindFirstFile etc. only includes
// the final filename component, even if the search pattern
// included a directory.
// This is going to be a bugger to fix...
string directoryPrefix;
size_t directoryPrefixLength = file_arg.find_last_of( "/\\" );
if( directoryPrefixLength!=string::npos )
{
directoryPrefix = string( file_arg, 0, directoryPrefixLength+1 );
}
// Was it as easy as that?...
int findnextReturnValue = 0;
while ( findnextReturnValue==0 )
{
string sFileName=directoryPrefix;
sFileName.append( fd.name );
file_entry file_entry( sFileName, lang );
file_list.push_back( file_entry );
findnextReturnValue = _findnext( sh, &fd );
}
_findclose( sh );
#else
file_entry file_entry( file_arg, lang );
file_list.push_back( file_entry );
cout << file_arg << endl;
#endif
}
}
/*
** method to parse all of the supplied list of files
*/
336 int Main::ParseFiles( )
{
FILE *f;
std::list<file_entry>::iterator file_iterator=file_list.begin( );
while( file_iterator!=file_list.end( ) )
{
const file_entry &entry=*file_iterator;
string filename=entry.first;
string file_language=entry.second;
ParseStore ps( filename );
// The following objects are used to assist in the parsing
// process.
if( file_language.size( )==0 )
{
file_language=CCCC_Options::getFileLanguage( filename );
}
// CCCC supports a convention that the language may include an
// embedded '.', in which case the part before the . controls
// which parser runs, while the whole can be examined inside
// the parser to check for special dialect handling.
unsigned int period_pos=file_language.find( "." );
string base_language=file_language.substr( 0, period_pos );
f=fopen( filename.c_str( ), "r" );
if( f == NULL )
{
cerr << "Couldn't open " << filename << endl;
} else {
DLGFileInput in( f );
// show progress
cerr << "Processing " << filename;
// The first case is just to allow symetric handling
// of the optional inclusion of support for each language
if( 0 )
{
}
#ifdef CC_INCLUDED
else if(
( base_language=="c++" ) ||
( base_language=="c" )
)
{
cerr << " as C/C++ ( " << file_language << " )"
<< endl;
CLexer theLexer( &in );
ANTLRTokenBuffer thePipe( &theLexer );
theLexer.setToken( ¤tLexerToken );
CParser theParser( &thePipe );
ParseUtility pu( &theParser );
theParser.init( filename, file_language );
// This function turns of the annoying "guess failed" messages
// every time a syntactic predicate fails.
// This message is enabled by default when PCCTS is run with
// tracing turned on ( as it is by default in this application ).
// In the current case this is inappropriate as the C++ parser
// uses guessing heavily to break ambiguities, and we expect
// large numbers of guesses to be tested and to fail.
// This message and the flag which gates it were added around
// PCCTS 1.33 MR10.
// If you are building with an earlier version, this line should
// cause an error and can safely be commented out.
theParser.traceGuessOption( -1 );
theParser.start( );
files_parsed++;
}
#endif // CC_INCLUDED
#ifdef JAVA_INCLUDED
else if( base_language=="java" )
{
cerr << " as Java" << endl;
JLexer theLexer( &in );
ANTLRTokenBuffer thePipe( &theLexer );
theLexer.setToken( ¤tLexerToken );
JParser theParser( &thePipe );
theParser.init( filename, file_language );
theParser.traceGuessOption( -1 );
theParser.compilationUnit( );
files_parsed++;
}
#endif // JAVA_INCLUDED
#ifdef ADA_INCLUDED
else if( base_language=="ada" )
{
cerr << " as Ada" << endl;
ALexer theLexer( &in );
ANTLRTokenBuffer thePipe( &theLexer );
theLexer.setToken( ¤tLexerToken );
AdaPrser theParser( &thePipe );
theParser.init( filename, file_language );
theParser.traceGuessOption( -1 );
theParser.goal_symbol( );
files_parsed++;
}
#endif // ADA_INCLUDED
else if( base_language=="" )
{
cerr << " - no parseable language identified";
}
else
{
cerr << "Unexpected language " << base_language.c_str( )
<< " ( " << file_language.c_str( )
<< " ) for file " << filename.c_str( ) << endl;
}
// close the file
fclose( f );
}
file_iterator++;
}
return 0;
}
464 int Main::DumpDatabase( )
{
ofstream outfile( db_outfile.c_str( ) );
return prj->ToFile( outfile );
}
470 int Main::LoadDatabase( )
{
int retval=0;
if( db_infile!="" )
{
ifstream infile( db_infile.c_str( ) );
retval=prj->FromFile( infile );
}
return retval;
}
481 void Main::GenerateHtml( )
{
cerr << endl << "Generating HTML reports" << endl;
CCCC_Html_Stream::GenerateReports( prj, report_mask, html_outfile, outdir );
}
489 void Main::GenerateXml( )
{
cerr << endl << "Generating XML reports" << endl;
CCCC_Xml_Stream::GenerateReports( prj, report_mask, xml_outfile, outdir );
}
497 void Main::HandleDebugOption( const string& arg )
{
/*
** arg may either be a number, or a string of letters denoting
** facilities to be debugged.
** the string of letters is the public way - allowing input of a
** number is just there to support quickly adding a category of
** debug messages without having to change this file immediately
*/
DebugMask=atoi( arg.c_str( ) );
for ( int i=0; arg[i]!='\0'; i++ )
{
switch ( arg[i] ) {
case 'p' :
DebugMask |= PARSER;
break;
case 'l' :
DebugMask |= LEXER;
break;
case 'c' :
DebugMask |= COUNTER;
break;
case 'm' :
DebugMask |= MEMORY;
break;
case 'x' :
case 'X' :
DebugMask = 0xFF;
break;
}
}
}
534 void Main::HandleReportOption( const string& arg ) {
/*
** arg may either be a number, or a string of letters denoting
** reports to be generated
*/
report_mask=atoi( arg.c_str( ) );
for ( int i=0; arg[i]!='\0'; i++ ) {
switch ( arg[i] ) {
case 'c':
report_mask |= rtCONTENTS;
break;
case 's' :
report_mask |= rtSUMMARY;
break;
case 'p' :
report_mask |= rtPROC1;
break;
case 'P':
report_mask |= rtPROC2;
break;
case 'r' :
report_mask |= rtSTRUCT1;
break;
case 'R' :
report_mask |= rtSTRUCT2;
break;
case 'S' :
report_mask |= rtSEPARATE_MODULES;
break;
case 'o' :
report_mask |= rtOODESIGN;
break;
case 'L' : // for 'listing' as s and S for 'source' are already used
report_mask |= rtSOURCE;
break;
case 'j' :
report_mask |= rtOTHER;
break;
case 'h' :
report_mask |= rtCCCC;
break;
case 't' :
report_mask |= rtSHOW_GEN_TIME;
break;
default:
cerr << "Unexpected report requested:" << arg[i] << endl;
PrintUsage( cerr );
exit( -1 );
}
}
}
/*
** giving credit where it is due
*/
602 void Main::PrintCredits( ostream& os )
{
// the principal purpose of the constructor is to set up the
// two lots of boilerplate text that this class requires
string version_string="Version ";
version_string.append( CCCC_VERSION_STRING );
const char *credit_strings[] =
{
"CCCC - a code counter for C and C++",
"===================================",
"",
"A program to analyse C and C++ source code and report on",
"some simple software metrics",
version_string.c_str( ),
"Copyright Tim Littlefair, 1995, 1996, 1997, 1998, 1999, 2000",
"with contributions from Bill McLean, Herman Hueni, Lynn Wilson ",
"Peter Bell, Thomas Hieber and Kenneth H. Cox.",
"",
"The development of this program was heavily dependent on",
"the Purdue Compiler Construction Tool Set ( PCCTS ) ",
"by Terence Parr, Will Cohen, Hank Dietz, Russel Quoung, ",
"Tom Moog and others.",
"",
"CCCC comes with ABSOLUTELY NO WARRANTY.",
"This is free software, and you are welcome to redistribute it",
"under certain conditions. See the file COPYING in the source",
"code distribution for details.",
NULL
};
const char **string_ptr=credit_strings;
while( *string_ptr!=NULL )
{
os << *string_ptr << endl;
string_ptr++;
}
}
642 void Main::DescribeOutput( )
{
if( files_parsed>0 )
{
// make sure the user knows where the real output went
// make sure the user knows where the real output went
cerr << endl
<< "Primary HTML output is in " << html_outfile << endl;
if( report_mask & rtSEPARATE_MODULES )
{
cerr << "Detailed HTML reports on modules and source are in " << outdir << endl;
}
cerr << "Primary XML output is in " << xml_outfile << endl ;
if( report_mask & rtSEPARATE_MODULES )
{
cerr << "Detailed XML reports on modules are in " << outdir << endl;
}
cerr << "Database dump is in " << db_outfile << endl << endl;
}
else
{
cerr << endl << "No files parsed on this run" << endl << endl;
}
}
/*
** the usage message is printed on cerr if unexpected options are found,
** and on cout if option --help is found.
*/
671 void Main::PrintUsage( ostream& os )
{
const char *usage_strings[] =
{
"Usage: ",
"cccc [options] file1.c ... ",
"Process files listed on command line.",
"If the filenames include '-', read a list of files from standard input.",
"Command Line Options: ( default arguments/behaviour specified in braces )",
"--help * generate this help message",
"--outdir=<dname> * directory for generated files {.cccc}",
"--html_outfile=<fname> * name of main HTML report {<outdir>/cccc.html}",
"--xml_outfile=<fname> * name of main XML report {<outdir>/cccc.xml}",
"--db_infile=<fname> * preload internal database from named file",
" {empty file}",
"--db_outfile=<fname> * save internal database to file {<outdir>/cccc.db}",
"--opt_infile=<fname> * load options from named file {hard coded, see below}",
"--opt_outfile=<fname> * save options to named file {<outdir>/cccc.opt}",
"--lang=<string> * use language specified for files specified ",
" after this option ( c, c++, ada, java, no default )",
"--report_mask=<hex> * control report content ",
"--debug_mask=<hex> * control debug output content ",
" ( refer to ccccmain.cc for mask values )",
"Refer to ccccmain.cc for usage of --report_mask and --debug_mask.",
"Refer to cccc_opt.cc for hard coded default option values, including default ",
"extension/language mapping and metric treatment thresholds.",
NULL
};
const char **string_ptr=usage_strings;
while( *string_ptr!=NULL )
{
os << *string_ptr << endl;
string_ptr++;
}
}
707 int Main::filesParsed( )
{
return files_parsed;
}
712 int main( int argc, char **argv )
{
app=new Main;
prj=new CCCC_Project;
// process command line
app->HandleArgs( argc, argv );
// If we are still running, acknowledge those who helped
app->PrintCredits( cerr );
cerr << "Parsing" << endl;
CCCC_Record::set_active_project( prj );
app->ParseFiles( );
CCCC_Record::set_active_project( NULL );
if( app->filesParsed( )>0 )
{
prj->reindex( );
#ifdef _WIN32
_mkdir( app->outdir.c_str( ) );
#else
mkdir( app->outdir.c_str( ), 0777 );
#endif
app->DumpDatabase( );
// generate html output
app->GenerateHtml( );
app->GenerateXml( );
}
app->DescribeOutput( );
delete app;
delete prj;
return 0;
}