File Coverage

blib/lib/C/Analyzer.pm
Criterion Covered Total %
statement 37 289 12.8
branch 8 88 9.0
condition 0 91 0.0
subroutine 6 18 33.3
pod 13 13 100.0
total 64 499 12.8


line stmt bran cond sub pod time code
1             #!/usr/bin/perl
2             package C::Analyzer;
3              
4             BEGIN {
5 1     1   79717 use Exporter ();
  1         4  
  1         46  
6 1     1   8 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
  1         2  
  1         188  
7 1     1   3 $VERSION = '0.01';
8 1         29 @ISA = qw(Exporter);
9              
10             #Give a hoot don't pollute, do not export more than needed by default
11 1         4 @EXPORT = qw();
12 1         2 @EXPORT_OK = qw();
13 1         23 %EXPORT_TAGS = ();
14             }
15              
16 1     1   6 use strict;
  1         3  
  1         105  
17 1     1   7 use warnings;
  1         2  
  1         4025  
18              
19             my %calls = ();
20             my @calls_table = ();
21             my @rec_track = ();
22              
23             #################### subroutine header begin ####################
24              
25             =head2 new
26              
27             Usage : my $analyzer = new Analyzer(
28             _inputPath => "/home/sindhu/test/afs", # folder path
29             _cppPath => "/usr/bin", # GNU C preprocessor path
30             _inputOption => "dir_and_subdir", # if dir or dir/subdir
31             );
32             Purpose : Constructors, Static method that return an object
33             Returns : Object
34             Argument : _inputPath, _inputOption, _cppPath, _functionName
35             Throws : None
36             Comment : Can be extended for other important inputs as well in future.
37             See Also :
38              
39             =cut
40              
41             #################### subroutine header end ####################
42              
43             sub new {
44 1     1 1 11 my $class = shift;
45 1         6 my %params = @_;
46 1         2 my $self = {};
47 1 50       4 if ( defined( $params{'_inputPath'} ) ) {
48 1         3 $self->{'_inputPath'} = $params{'_inputPath'};
49             }
50             else {
51 0         0 print "Error: Missing file/folder path\n";
52 0         0 exit;
53             }
54              
55 1 50       3 if ( defined( $params{'_inputOption'} ) ) {
56 1         3 $self->{'_inputOption'} = $params{'_inputOption'};
57             }
58             else {
59 0         0 init $self->{'_inputOption'} = "dir";
60             }
61 1 50       3 if ( defined( $params{'_cppPath'} ) ) {
62 1         2 $self->{'_cppPath'} = $params{'_cppPath'};
63             }
64             else {
65 0         0 print "Error: Missing GNU C Processor path\n";
66 0         0 exit;
67             }
68 1 50       3 if ( defined( $params{'_cppOptions'} ) ) {
69 0         0 $self->{'_cppOptions'} = $params{'_cppOptions'};
70             }
71             else {
72 1         2 $self->{'_cppOptions'} = "-nostdinc";
73             }
74 1 50       3 if ( defined( $params{'_functionName'} ) ) {
75 0         0 $self->{'_functionName'} = $params{'_functionName'};
76             }
77             else {
78 1         3 $self->{'_functionName'} = "main";
79             }
80 1 50       2 if ( defined( $params{'_reportType'} ) ) {
81 0         0 $self->{'_reportType'} = $params{'_reportType'};
82             }
83             else {
84 1         2 $self->{'_reportType'} = "Text";
85             }
86 1 50       3 if ( defined( $params{'_reportOptions'} ) ) {
87 0         0 $self->{'_reportOptions'} = $params{'_reportOptions'};
88             }
89             else {
90 1         2 $self->{'_reportOptions'} = "fullDetails";
91             }
92 1 50       3 if ( defined( $params{'_treeType'} ) ) {
93 0         0 $self->{'_treeType'} = $params{'_treeType'};
94             }
95             else {
96 1         4 $self->{'_treeType'} = "callTree";
97             }
98 1         4 bless $self, $class;
99             }
100              
101             #################### subroutine header begin ####################
102              
103             =head2 init
104              
105             Usage : init()
106             Purpose : initializes variables, gets C files in dir/subdirs,
107             runs GNU C Preprocessor and updates functions and
108             calls in each C file
109             Returns : None
110             Argument : None
111             Throws : None
112             Comment : None
113             See Also :
114              
115             =cut
116              
117             #################### subroutine header end ####################
118              
119             sub init() {
120 0     0 1   my ($self) = @_;
121 0           &clean();
122 0           my $folder = "";
123 0           my $opt = "";
124 0           my $cppPath = "";
125 0           my $cppOpts = "";
126 0           my $funName = "";
127 0           my $cfiles;
128             my $ppfiles;
129 0           my $cfile;
130              
131 0 0         $folder = $self->{_inputPath} if defined($folder);
132 0 0         $opt = $self->{_inputOption} if defined($opt);
133 0 0         $cppPath = $self->{_cppPath} if defined($cppPath);
134 0 0         $cppOpts = $self->{_cppOptions} if defined($cppOpts);
135              
136 0           $cfiles = &getListOfCFiles( \$folder, \$opt );
137 0           $ppfiles = &runGnuPreprocessor( \$cfiles, \$cppPath, \$cppOpts );
138 0           &identifyFunctionsAndCalls( \$ppfiles, \$opt, \$folder );
139 0           return;
140             }
141              
142             #################### subroutine header begin ####################
143              
144             =head2 calltree
145              
146             Usage : calltree()
147             Purpose : Initial preperations for calltree generation for
148             user given functions.
149             Returns : None
150             Argument : Takes a reference to list of functions
151             Throws : None
152             Comment : None
153             See Also :
154              
155             =cut
156              
157             #################### subroutine header end ####################
158              
159             sub calltree() {
160 0     0 1   my ( $class, $functions ) = @_;
161 0           my @funclist = ();
162 0 0         if ( defined($functions) ) {
163 0           @funclist = @{$functions};
  0            
164             }
165             else {
166 0           @funclist = qw(main);
167             }
168 0           foreach my $function (@funclist) {
169 0           &prepareCalltreeInit( \$function );
170             }
171 0           return;
172             }
173              
174             #################### subroutine header begin ####################
175              
176             =head2 getListOfCFiles
177              
178             Usage : getListOfCFiles()
179             Purpose : Takes folder name and GNU C Preprocessor options
180             and returns list of C files in dir/subdir
181             Returns : reference to array of C files
182             Argument : folder name and GNU C Preprocessor options
183             Throws : None
184             Comment : None
185             See Also :
186             None
187              
188             =cut
189              
190             #################### subroutine header end ####################
191              
192             sub getListOfCFiles() {
193 0     0 1   my ( $folder, $opt ) = @_;
194 0           my @cfiles = ();
195 0           my $OS = $^O;
196 0           $$folder =~ s/\//\\/g;
197 0 0 0       if ( ( defined $OS )
      0        
198             && ( $OS eq "MSWin32" )
199             && ( $$opt eq "dir_and_subdir" ) )
200             {
201 0           @cfiles = `dir /b /s \"$$folder\*.c\"`;
202             }
203 0 0 0       if ( ( defined $OS ) && ( $OS eq "MSWin32" ) && ( $$opt eq "dir" ) ) {
      0        
204 0           chdir $$folder;
205 0           @cfiles = `dir /b *.c`;
206             }
207 0 0 0       if ( ( defined $OS )
      0        
208             && ( $OS eq "linux" )
209             && ( $$opt eq "dir_and_subdir" ) )
210             {
211 0           my $path = $$folder;
212 0           $path =~ s/\\/\//g;
213 0           chdir $path;
214 0           @cfiles = `find \. -name \*.c`;
215              
216             }
217 0 0 0       if ( ( defined $OS ) && ( $OS eq "linux" ) && ( $$opt eq "dir" ) ) {
      0        
218 0           chdir $$folder;
219 0           @cfiles = `find *.c`;
220             }
221 0           return ( \@cfiles );
222             }
223              
224             #################### subroutine header begin ####################
225              
226             =head2 prepareCalltreeInit
227              
228             Usage : prepareCalltreeInit()
229             Purpose : final preparations for calltree generation
230             Returns : none
231             Argument : function name
232             Throws : None
233             Comment : None
234             See Also :
235             None
236              
237             =cut
238              
239             #################### subroutine header end ####################
240              
241             sub prepareCalltreeInit() {
242 0     0 1   my ($function) = shift;
243 0           my $localtime = localtime();
244 0           my @calls = ();
245 0 0         if ( exists $calls{$$function} ) {
246 0           @calls = @{ $calls{$$function} };
  0            
247             }
248             else {
249 0           print "Function does not exists\n";
250 0           return;
251             }
252 0 0 0       if ( defined($$function) && defined( $calls[0] ) ) {
253 0           print "<0>$$function$calls[0]\n";
254             }
255 0           $| = 1;
256 0           shift(@calls);
257 0           my $calltablelen = scalar(@calls);
258 0 0         if ( $calltablelen == 0 ) {
259 0           print "Sorry! Function \"$$function\" does not contain any calls";
260 0           return;
261             }
262 0           &generateCalltree( $$function, 1 );
263 0           print "\n";
264 0           return;
265             }
266              
267             #################### subroutine header begin ####################
268              
269             =head2 generateCalltree
270              
271             Usage : generateCalltree()
272             Purpose : Functions that actually generates the functional calltree
273             Returns : none
274             Argument : function name and tab count
275             Throws : None
276             Comment : None
277             See Also :
278             None
279              
280             =cut
281              
282             #################### subroutine header end ####################
283              
284             sub generateCalltree() {
285 0     0 1   my ( $function, $tabcount ) = ( shift, shift );
286 0 0         if ( $calls{$function} ) {
287 0           push( @rec_track, $function );
288 0           my @calls = @{ $calls{$function} };
  0            
289 0           shift(@calls);
290 0           foreach my $call (@calls) {
291 0           my $curr_cnt = $tabcount;
292 0           my $temp_call = $call;
293              
294 0 0         if ( $temp_call =~ /^\[/ ) {
295 0           next;
296             }
297 0           $temp_call =~ /(\w+)\s*\(/;
298 0           $temp_call = $1;
299 0           $temp_call = trim($temp_call);
300 0           my $temp_fun = $function;
301 0           $temp_fun = trim($temp_fun);
302 0           my $is_there = 0;
303 0           foreach my $element (@rec_track) {
304              
305 0 0         if ( $element eq $temp_call ) {
306 0           $is_there = 1;
307              
308             # $temp_element = $element;
309 0           last;
310             }
311             }
312 0 0         if ( $is_there eq 0 ) {
313              
314 0           my $str = "";
315 0           for ( my $i = 0 ; $i < $tabcount ; $i++ ) {
316              
317 0           print " ";
318 0           $str = "$str" . " ";
319 0           $| = 1;
320             }
321              
322 0 0         if ( $call =~ /^\(/ ) {
323 0           $call = "__double_def" . "$call";
324 0           print "<$tabcount>$call\n";
325 0           $call = "";
326             }
327             else {
328 0           print "<$tabcount>$call\n";
329             }
330              
331 0           $| = 1;
332 0           $temp_call = $call;
333 0           $temp_call =~ /(\w+)\s*\(/;
334 0           $temp_call = $1;
335 0           $temp_call = trim($temp_call);
336 0 0 0       my $tmp = "$str" . ""
337             if ( defined($temp_call) && defined($str) );
338 0           $tmp = "";
339              
340 0 0         if ( defined($temp_call) ) {
341 0           &generateCalltree( $temp_call, $tabcount + 1 );
342             }
343              
344             }
345             else {
346 0           my $str = "";
347 0           for ( my $i = 0 ; $i < $tabcount ; $i++ ) {
348              
349 0           print " ";
350 0           $str = "$str" . " ";
351              
352 0           $| = 1;
353             }
354              
355 0 0         if ( $call =~ /^\(/ ) {
356 0           $call = "__double_def" . "$call";
357 0           print "<$tabcount>$call ---@\n";
358 0           $call = "";
359             }
360             else {
361 0           print "<$tabcount>$call\n";
362             }
363              
364 0           my $temp_call = $call;
365 0           $temp_call =~ /(\w+)\s*\(/;
366 0           $temp_call = $1;
367 0           $temp_call = trim($temp_call);
368 0           $| = 1;
369              
370             }
371             }
372             }
373 0           return;
374             }
375              
376             #################### subroutine header begin ####################
377              
378             =head2 runGnuPreprocessor
379              
380             Usage : runGnuPreprocessor()
381             Purpose : runs GNU C preprocessor in the user given path
382             Returns : returns a reference to list of names of preprocessed files
383             Argument : reference of list of C files, CPP Path, Options
384             Throws : None
385             Comment : None
386             See Also :
387             None
388              
389             =cut
390              
391             #################### subroutine header end ####################
392              
393             sub runGnuPreprocessor() {
394 0     0 1   my ( $cfiles, $cppPath, $cppOpts ) = @_;
395 0           my ( $prepfile, $prep_str );
396 0           my @ppfiles = ();
397 0           my $len = scalar(@$$cfiles);
398 0           my $cnt = 0;
399 0           foreach my $cfile (@$$cfiles) {
400 0           $cnt++;
401 0           chomp($cfile);
402 0           $cfile =~ s/\\/\//g;
403 0           &progress_bar( $cnt, $len, 50, '=' );
404 0 0         if ( $cfile =~ /(.*)(\.c|\.C)$/ ) {
405 0           my $stripfile = trim($1);
406 0           $stripfile =~ s/\\/\//g;
407 0           $prepfile = "$stripfile" . "._pp";
408             }
409             $prep_str =
410 0           "\"$$cppPath" . "/cpp\"" . " "
411             . "$$cppOpts" . " "
412             . "\"$cfile\"" . " "
413             . "> \"$prepfile\" 2>junk.txt";
414 0           push( @ppfiles, $prepfile );
415 0           system($prep_str);
416             }
417 0           print "\n";
418 0           @$$cfiles = ();
419 0           return ( \@ppfiles );
420             }
421              
422             #################### subroutine header begin ####################
423              
424             =head2 identifyFunctionsAndCalls
425              
426             Usage : identifyFunctionsAndCalls()
427             Purpose : initial preperation for parsing each C file to identify
428             functions and calls
429             Returns : none
430             Argument : reference to list of preprocessor files, options and folder
431             names.
432             Throws : None
433             Comment : None
434             See Also :
435             None
436              
437             =cut
438              
439             #################### subroutine header end ####################
440              
441             sub identifyFunctionsAndCalls() {
442 0     0 1   my ( $ppfiles, $opt, $folder ) = @_;
443 0           my $fun_calls;
444 0           foreach my $ppfile (@$$ppfiles) {
445 0           $fun_calls = parseCFile( \$ppfile, \$$opt, \$$folder );
446 0           updateHashTable( \$fun_calls );
447             }
448 0           return;
449             }
450              
451             #################### subroutine header begin ####################
452              
453             =head2 parseCFile
454              
455             Usage : parseCFile()
456             Purpose : Parser module to identify functions and calls in C files.
457             Returns : reference to array of funs and calls.
458             Argument : reference to filename, options and foldername
459             Throws : None
460             Comment : None
461             See Also :
462             None
463              
464             =cut
465              
466             #################### subroutine header end ####################
467              
468             sub parseCFile() {
469 0     0 1   my ( $infile, $opt_s, $FolderName ) = shift;
470 0           my @t_funs_calls = ();
471 0           my @pplines = ();
472 0           my $OpenCount = 0;
473 0           my $CloseCount = 0;
474 0           my $lno = 0;
475 0           my $fragment;
476             my $filename;
477 0           my $fun;
478 0 0         open( PPFILE, "<$$infile" ) || die("Cannot open input file $$infile\n");
479 0           @pplines = ;
480 0           close(PPFILE);
481              
482 0           foreach my $ppfile (@pplines) {
483 0           $lno++;
484 0           $ppfile =~ s/\".*\(.*\"/ /g;
485              
486 0 0         if ( $ppfile =~ /^\#\s*([0-9]+)\s*\"(.*)\s*\"/ ) {
487 0           $lno = $1;
488 0           $lno--;
489 0           $filename = trim($2);
490 0           next;
491             }
492 0           while ( $ppfile =~ /(\w+)\s*\(/g ) {
493 0           my $t_fun = $1;
494 0           $t_fun = trim($t_fun);
495 0 0 0       if ( ( $t_fun eq "if" )
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
496             || ( $t_fun eq "for" )
497             || ( $t_fun eq "while" )
498             || ( $t_fun eq "switch" )
499             || ( $t_fun eq "case" )
500             || ( $t_fun eq "int" )
501             || ( $t_fun eq "char" )
502             || ( $t_fun eq "flaot" )
503             || ( $t_fun eq "double" )
504             || ( $t_fun eq "long" )
505             || ( $t_fun eq "short" )
506             || ( $t_fun eq "bit" )
507             || ( $t_fun eq "unsigned" )
508             || ( $t_fun eq "return" ) )
509             {
510 0           next;
511             }
512 0 0         if ($opt_s) {
513 0           my $filelength = length($FolderName);
514 0           $fragment = substr $filename, $filelength;
515 0           $fragment = "." . "$fragment";
516 0 0         if ( $t_fun eq "" ) {
517             ;
518             }
519             else {
520 0           $fun = "$t_fun" . "($lno, $fragment)";
521             }
522             }
523             else {
524 0 0         if ( $t_fun eq "" ) {
525 0           print;
526             }
527             else {
528 0           $fun = "$t_fun" . "($lno, $filename)";
529             }
530             }
531 0           push( @t_funs_calls, $fun );
532 0           $fragment = "";
533             }
534 0           while ( $ppfile =~ /(;)/g ) {
535 0           push( @t_funs_calls, $1 );
536             }
537 0           while ( $ppfile =~ /({)/g ) {
538 0           $OpenCount++;
539 0           push( @t_funs_calls, $1 );
540             }
541 0           while ( $ppfile =~ /(})/g ) {
542 0           $CloseCount++;
543 0           push( @t_funs_calls, $1 );
544             }
545             }
546 0           return ( \@t_funs_calls );
547             }
548              
549             #################### subroutine header begin ####################
550              
551             =head2 updateHashTable
552              
553             Usage : updateHashTable()
554             Purpose : updates function wise calls hash table
555             Returns : reference to hash table containing functions and calls
556             Argument : None
557             Throws : None
558             Comment : None
559             See Also :
560             None
561              
562             =cut
563              
564             #################### subroutine header end ####################
565              
566             sub updateHashTable() {
567 0     0 1   my $fun_calls = shift;
568 0           my $OpenCount = 0;
569 0           my $CloseCount = 0;
570 0           my $function;
571 0           my $FUNCTIONFOUND = 0;
572 0           my $item = -1;
573 0           my $titem;
574 0           my $cnt1 = 0;
575 0           my $call;
576             my $fun_remain;
577              
578 0           foreach my $x (@$$fun_calls) {
579 0           $item++;
580              
581 0 0         if ( $x eq "{" ) {
582 0           $OpenCount++;
583             }
584 0 0         if ( $x eq "}" ) {
585 0           $CloseCount++;
586             }
587 0 0 0       if ( !defined( @$$fun_calls[$item] )
588             || !defined( @$$fun_calls[ $item + 1 ] ) )
589             {
590 0           next;
591             }
592 0           $titem = $item + 1;
593 0 0 0       if ( ( @$$fun_calls[$item] =~ /(\w+.*)/ )
      0        
594             && ( @$$fun_calls[ $item + 1 ] eq "{" )
595             && ( $OpenCount == $CloseCount ) )
596             {
597 0           $function = $1;
598 0           $function =~ /(\w+)\s*\(/;
599 0           $function = $1;
600 0           $function = trim($function);
601 0           $fun_remain = $';
602 0           $fun_remain = "(" . $fun_remain;
603 0           push( @{ $calls{$function} }, $fun_remain );
  0            
604 0           $FUNCTIONFOUND = 1;
605             }
606 0 0 0       if ( ( $FUNCTIONFOUND == 1 ) && ( $OpenCount != $CloseCount ) ) {
607 0 0 0       if ( ( $x eq "{" ) || ( $x eq "}" ) || ( $x eq ";" ) ) {
      0        
608 0           next;
609             }
610             else {
611 0           $call = $x;
612 0           push( @calls_table, $call );
613 0           $call = trim($call);
614 0 0         if ( defined($call) ) {
615 0           push( @{ $calls{$function} }, $call );
  0            
616             }
617             }
618             }
619             }
620              
621 0           return;
622             }
623              
624             #################### subroutine header begin ####################
625              
626             =head2 trim
627              
628             Usage : trim()
629             Purpose : trims leading and trailing white spaces in strings
630             Returns : trimmed string
631             Argument : string
632             Throws : None
633             Comment : None
634             See Also :
635             None
636              
637             =cut
638              
639             #################### subroutine header end ####################
640             sub trim($) {
641 0     0 1   my $string = shift;
642 0 0         $string =~ s/^\s+// if defined($string);
643 0 0         $string =~ s/\s+$// if defined($string);
644 0           return $string;
645             }
646              
647             #################### subroutine header begin ####################
648              
649             =head2 clean
650              
651             Usage : clean()
652             Purpose : safe exit
653             Returns : none
654             Argument : none
655             Throws : None
656             Comment : None
657             See Also :
658             None
659              
660             =cut
661              
662             #################### subroutine header end ####################
663             sub clean() {
664 0     0 1   %calls = ();
665 0           @calls_table = ();
666 0           @rec_track = ();
667 0           return;
668             }
669              
670             #################### subroutine header begin ####################
671              
672             =head2 progress_bar
673              
674             Usage : progress_bar()
675             Purpose : simple and neat progress bar
676             Returns : none
677             Argument : none
678             Throws : None
679             Comment : None
680             See Also :
681             None
682              
683             =cut
684              
685             #################### subroutine header end ####################
686              
687             sub progress_bar {
688 0     0 1   my ( $got, $total, $width, $char ) = @_;
689 0   0       $width ||= 25;
690 0   0       $char ||= '=';
691 0           my $num_width = length $total;
692 0           local $| = 1;
693 0           printf "[%-${width}s] processed [%${num_width}s/%s] (%.2f%%)\r",
694             $char x ( ( $width - 1 ) * $got / $total ) . '>', $got, $total,
695             100 * $got / +$total;
696             }
697             #################### main pod documentation begin ###################
698             ## Below is the stub of documentation for your module.
699             ## You better edit it!
700              
701             =head1 NAME
702              
703             C::Analyzer - Generates C Call Control Flow tree for C source code
704              
705             =head1 SYNOPSIS
706              
707             use warnings;
708             use strict;
709             use C::Analyzer;
710              
711             my @functions = qw(afs_CheckServers afs_cv2string);
712             my $analyzer = new Analyzer(
713             _inputPath => "/home/foo",
714             _cppPath => "/usr/local/bin",
715             );
716             $analyzer->init();
717             # "main" function taken if no parameter passed to this method.
718             $analyzer->calltree( \@functions );
719              
720             $analyzer->clean();
721              
722             I
723              
724             =head1 DESCRIPTION
725              
726             Creates Call stack/tree of C source code
727              
728             =head2 GETTING HELP
729              
730             If you have questions about Analyzer you can get help from the I mailing list. You can get help
731             on subscribing and using the list by emailing I.
732              
733             =head2 NOTES
734              
735             The Analyzer is evolving and there are plans to add more features, so it's good to have the latest copy.
736              
737             =head2 Architecture of Analyzer
738              
739             |-Input folder of C files-| |----Call Stack Output---|
740              
741             .------------------------.
742             | 1. #include | .-.
743             | 2. | .-------. |A|
744             | 3. void main(void) | | Perl | |N| .------------------------.
745             | 4. { | | script| |A| |A| |<0>main(3, a.c) |
746             | 5. foo(); |-------| using |--|P|--|L|-------| <1>foo(5, a.c) |
747             | 6. } | | API | |I| |Y| | <2>bar(10, a.c) |
748             | 7. | |methods| |Z| `-----------------------/
749             | 8. int foo() | | | |E|
750             | 9. { | `-------' |R|
751             | 10. bar(); | `-'
752             | 11. } |
753             `-----------------------/
754              
755             =head2 Outline Usage
756              
757             =head3 C
758              
759             Analyzer expects couple of mandatory inputs. One, folder that contains C/H files. Second, path for GNU C Preprocessor.
760              
761             for example:
762             my $analyzer = new Analyzer(
763             _inputPath => "/home/foo",
764             _cppPath => "/usr/local/bin",
765             );
766              
767             =head3 C
768              
769             Analyzer expects optional inputs as well.
770            
771             It allows directory and sub directory parsing. Default is directory processing. To tell analyzer module to recursively process
772             C files in all directories and sub directories, use _inputOption
773            
774             for example:
775             my $analyzer = new Analyzer(
776             _inputPath => "/home/foo",
777             _cppPath => "/usr/local/bin",
778             _inputOption => "dir_and_subdir",
779             );
780              
781             There is an option to provide additional GNU C Preprocessor options using "_cppOptions"
782            
783             for example:
784             my $analyzer = new Analyzer(
785             _inputPath => "/home/foo",
786             _cppPath => "/usr/local/bin",
787             _inputOption => "dir_and_subdir",
788             _cppOptions => "-DMACRO1 -DMACRO2",
789             );
790              
791             =head1 BUGS
792              
793             None.
794              
795              
796             =head1 SUPPORT
797              
798             The Analyzer is free Open Source software. IT COMES WITHOUT WARRANTY OF ANY KIND.
799             Please let me know if you could add more features for this module.I will be more than
800             happy to add them.
801            
802             =head1 AUTHOR
803              
804             Sreekanth Kocharlakota
805             CPAN ID: bmpOg
806             Sreekanth Kocharlakota
807             sreekanth@cpan.org
808             http://www.languagesemantics.com
809              
810             =head1 COPYRIGHT
811              
812             The Analyzer module is Copyright (c) 1994-2007 Sreekanth Kocharlakota. USA.
813             This program is free software licensed under the...
814              
815             The General Public License (GPL)
816             Version 2, June 1991
817              
818             The full text of the license can be found in the
819             LICENSE file included with this module.
820              
821              
822             =head1 SEE ALSO
823              
824             perl(1).
825              
826             =cut
827              
828             #################### main pod documentation end ###################
829              
830             1;
831              
832             # The preceding line will help the module return a true value
833