Subversion Repositories DevTools

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
227 dpurdie 1
#! perl
2
########################################################################
3
# Copyright ( C ) 2004 ERG Limited, All rights reserved
4
#
5
# Module name   : gen_metrics.pl
6
# Module type   : JATS Makefile system
7
# Compiler(s)   : n/a
8
# Environment(s): JATS
9
#
10
# Description   : Post process the JATS build and makefiles and generate
11
#                 a collection of program metrics
12
#
13
# Usage:          JATS etool gen_metrics
14
#
15
# Version   Who     Date        Description
16
#           DDP     07-Dec-04   Created
17
#......................................................................#
18
 
255 dpurdie 19
require 5.006_001;
227 dpurdie 20
 
21
use strict;
22
use warnings;
23
use JatsError;
24
use JatsMakeInfo;
25
use ReadBuildConfig qw(:All);
26
use FileUtils;
27
use JatsSystem;
28
use JatsMakeConfig;
29
 
30
use Pod::Usage;                             # Required for help support
31
use Getopt::Long;                           # Option processing
32
 
33
#
34
#   Global variables
35
#
36
my  $VERSION = "1.0.0";                     # Update this
37
my  %source;                                # Source files
38
my  %include;                               # Local include directories
39
my  $cccc_path = "c:/Program Files/CCCC/cccc.exe";   # Path to CCCC utility
40
my  $cccc_out  = "./interface/cccc";        # Output directory
41
 
42
#
43
#   Global variables - Options
44
#
45
my  $opt_help = 0;
46
my  $opt_manual;
47
my  $opt_verbose = 0;
48
my  $opt_headers = 0;
49
my  $opt_cccc_path;
50
 
51
my $result = GetOptions (
52
                "help+"         => \$opt_help,              # flag, multiple use allowed
53
                "manual"        => \$opt_manual,            # flag, multiple use allowed
54
                "verbose+"      => \$opt_verbose,           # flag, multiple use allowed
55
                "headers!"      => \$opt_headers,           # Flag, +no allowed
56
                "cccc=s"        => \$opt_cccc_path          # String
57
                );
58
 
59
                #
60
                #   UPDATE THE DOCUMENTATION AT THE END OF THIS FILE !!!
61
                #
62
 
63
#-------------------------------------------------------------------------------
64
# Function        : Main entry point
65
#
66
# Description     : Parse user arguments
67
#                   Generate metrics
68
#
69
# Inputs          : None
70
#
71
# Returns         : Error code
72
#
73
 
74
#
75
#   Process help and manual options
76
#
77
pod2usage(-verbose => 0, -message => "Version: $VERSION")  if ($opt_help == 1  || ! $result);
78
pod2usage(-verbose => 1)  if ($opt_help == 2 );
79
pod2usage(-verbose => 2)  if ($opt_manual || ($opt_help > 2));
80
 
81
#
82
#   Configure the Error reporting process now that we have the user options
83
#
84
ErrorConfig( 'name'    =>'METRICS',
85
             'verbose' => $opt_verbose,
86
            );
87
 
88
#
89
#   Ensure that we are in a suitable directory
90
#   Need to be in the project root directory
91
#
92
Verbose ("Locate project root directory");
93
 
94
#
95
#   Locate the base of the JATS build
96
#   This will be provided by Makefile.gbe
97
#
98
ReadMakeInfo();
99
my $interface_path = "$::ScmRoot/$::ScmInterface";
100
 
101
#
102
#   Read in all the makefile data in one hit
103
#
104
my $mfdata = JatsMakeConfigReader::GetAllMakeInfo();
105
#   Sanity test of user options
106
#
107
 
108
if ( $opt_cccc_path )
109
{
110
    Error ("CCCC not found: $opt_cccc_path") unless ( -x $opt_cccc_path );
111
    $cccc_path = $opt_cccc_path;
112
}
113
Error ("CCCC not found: $cccc_path" ) unless ( -x "$cccc_path" );
114
 
115
#-------------------------------------------------------------------------------
116
#   Process all the constituent makefile data and buildup a list of source files
117
#
118
foreach my $dir ( $mfdata->AllDirs() )
119
{
120
    my $mff = $mfdata->GetEntry($dir);
121
 
122
    Verbose ("Processing: $dir");
123
 
124
    foreach my $tgt ( $mff->GetPlatforms() )
125
    {
126
        my $cwd = $mff->GetDataItem($tgt, '$Cwd');
127
        Verbose( "Target: $tgt, CWD: $cwd\n");
128
 
129
        #
130
        #   Locate all the C, C++ and headers
131
        #   I don't think JATS handles Java file at the moment
132
        #
133
        foreach my $var ( '@CXXSRCS' ,'@CSRCS', '@CHDRS' )
134
        {
135
            if ( my $data = $mff->GetDataItem($tgt, $var) )
136
            {
137
                Verbose2( "$var : @{$data}");
138
                foreach my $file ( @$data )
139
                {
140
                    #
141
                    #   Add the makefile's CWD to the file unless the file
142
                    #   already has an absolute path
143
                    #
144
                    $file = $cwd . "/" . $file unless ( $file =~ m~^/~ );
145
                    unless ( $source{$file} )
146
                    {
147
                        $source{$file} = 1;
148
                        Verbose ("Adding: $file");
149
                    }
150
                }
151
            }
152
        }
153
 
154
        #
155
        #   Locate all the included directories in case we need
156
        #   an exhaustive search of all header files
157
        #
158
        foreach my $var ( '@INCDIRS' )
159
        {
160
            if ( my $data = $mff->GetDataItem($tgt, $var) )
161
            {
162
                Verbose2( "$var : @{$data}");
163
                foreach my $dir ( @$data )
164
                {
165
                    #
166
                    #   Add the makefile's CWD to the file unless the file
167
                    #   already has an absolute path
168
                    #
169
                    $dir = $cwd . "/" . $dir unless ( $dir =~ m~^/~ );
170
                    unless ( $include{$dir} )
171
                    {
172
                        $include{$dir} = 1;
173
                        Verbose ("Adding dir: $dir");
174
                    }
175
                }
176
            }
177
        }
178
    }
179
}
180
 
181
#-------------------------------------------------------------------------------
182
#   Now have a complete list of files that are specified as source files
183
#   within all the project makefile.pl's, but these are not all the source
184
#   files as the included header files are not mentioned
185
#
186
#   This may be sufficient as it is a list of the interface file
187
#
188
#   If requested add all the header files from all the include directories
189
if ( $opt_headers )
190
{
191
    foreach my $dir ( keys %include )
192
    {
193
        my @files = glob ( "$dir/*.h" );
194
        foreach my $file ( @files )
195
        {
196
            unless ( $source{$file} )
197
            {
198
                $source{$file} = 1;
199
                Verbose ("Adding header: $file");
200
            }
201
        }
202
    }
203
}
204
 
205
#-------------------------------------------------------------------------------
206
#   Kick of the CCCC processing of all the discovered source files
207
#   Remove any existing CCCC output
208
#
209
    System ("rm -rf $cccc_out");
210
    System ("mkdir -p $cccc_out");
211
 
212
    my @file_list = sort keys( %source );
213
    System ("\"$cccc_path\" --outdir=$cccc_out @file_list");
214
 
215
    # --debug_mask=plc
216
 
217
    exit;
218
 
219
#-------------------------------------------------------------------------------
220
#   Documentation
221
#
222
 
223
=pod
224
 
225
=head1 NAME
226
 
227
gen_metrics - Create Metrics
228
 
229
=head1 SYNOPSIS
230
 
231
 jats etool gen_metrics [options]
232
 
233
 Options:
234
    -help              - Brief help message
235
    -help -help        - Detailed help message
236
    -man               - Full documentation
237
    -verbose           - Verbose display of operation
238
    -cccc=path         - Alternate location of the CCCC program
239
    -[no]headers       - Add all headers files from included subdirectories
240
 
241
=head1 OPTIONS
242
 
243
=over 8
244
 
245
=item B<-help>
246
 
247
Print a brief help message and exits.
248
 
249
=item B<-help -help>
250
 
251
Print a detailed help message with an explanation for each option.
252
 
253
=item B<-man>
254
 
255
Prints the manual page and exits.
256
 
257
=item B<-verbose>
258
 
259
Prints internal information during the execution of the script. This option
260
does not affect the operation of the underlying CCCC program
261
 
262
=item B<-cccc=path>
263
 
264
This option specifies the absolute path of the F<CCCC.EXE> utility program. The
265
default operation looks for "cccc" in its standard installed location. Under
266
Windows this is F<c:/Program Files/CCCC/cccc.exe>
267
 
268
=item B<-[no]headers>
269
 
270
Includes all the ".h" files in directories named in "IncDir" directives.
271
The default operation is "noheaders"
272
 
273
=back
274
 
275
=head1 DESCRIPTION
276
 
277
The program uses a utility called CCCC to generate a variety of static
278
program metrics including:
279
 
280
=over 8
281
 
282
=item *
283
 
284
Lines of Code
285
 
286
=item *
287
 
288
Comment Lines
289
 
290
=item  *
291
 
292
McCabe's Cyclomatic Complexity
293
 
294
=back
295
 
296
CCCC is a tool for the analysis of source code in various languages (primarily
297
C++), which generates a report in HTML format on various measurements of the
298
code processed. Although the tool was originally implemented to process C++ and
299
ANSI C, the present version is also able to process Java source files, and
300
support has been present in earlier versions for Ada95. The name CCCC stands for
301
'C and C++ Code Counter'.
302
 
303
This program uses the information generated by the "JATS BUILD" process to
304
determine a list of files to been processed by the utility. Files for
305
inclusion are:
306
 
307
=over 4
308
 
309
=item *
310
 
311
Files specified with a "Src" directive
312
Only C, C++ and Header files are included
313
 
314
=item *
315
 
316
All headers files in directories named in a "AddIncDir" or
317
"AddDir" directive. This operation is not default. It must
318
been invoked with the "-header" option
319
 
320
=back
321
 
322
The CCCC program generates a number of output files in the interface/cccc
323
directory. The main files of interest are:
324
 
325
=over 4
326
 
327
=item *
328
 
329
cccc.html - Main output file
330
 
331
=item *
332
 
333
anonymous.html - Details of "C" files by function.
334
This file contains information that is not present in the
335
summary file.
336
 
337
=back
338
 
339
CCCC also generates a series of XML files that contains the same information
340
as the HTML files.
341
 
342
=head1 USAGE
343
 
344
The gen_metrics program uses information extracted from the build.pl and
345
makefile.pl files when the sandbox build environment is created. This
346
information is generated by the JATS BUILD command. This command must been run
347
before the gen_metrics program.
348
 
349
The gen_metrics program is an extension to the JATS framework. It must be run
350
within the JATS framework and not standalone.
351
 
352
=head2  Example
353
 
354
The following command will generate a set of metrics for the files in a sandbox.
355
It is assumed that the user is in the same directory as the packages build.pl
356
script.
357
 
358
    jats build
359
    jats etool gen_metrics.pl
360
 
361
This command sequence will do the following:
362
 
363
=over 4
364
 
365
=item C<jats build>
366
 
367
This will build the sandbox, generate makefile files and store information
368
extracted from the makefile.pl for possible post processing.
369
 
370
This command does not have to immediately preceed the metrics generation
371
command, but it does need to be performed at some stage before the metrics
372
cane be generated.
373
 
374
=item C<jats etool gen_metrics.pl>
375
 
376
This will post process the stored information and determine the source files
377
for the package, before running the CCCC utility over the files.
378
 
379
=back
380
 
381
=cut
382