This file is indexed.

/usr/lib/python2.7/dist-packages/PyMetrics/processargs.py is in pymetrics 0.8.1-7.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
""" Process command line arguments.

Usage:

>>> pa = ProcessArgs( 'file1.py', 'file2.py', '/home/files/file3.py' )
>>> pa = ProcessArgs( "inFile1.py", sqlFileName='sqlF1.sql', genCsvSw=False,genKwCntSw=True )
>>> pa = ProcessArgs()  #doctest +NORMALIZE_WHITESPACE +ELLIPSIS
python PyMetrics [ options ] pgm1.py [ pgm2.py ... ]
<BLANKLINE>
Complexity metrics are computed for the Python input files
pgm1.py, pgm2.py, etc. At least one file name is required,
else this message appears.
<BLANKLINE>
Three types of output can be produced:
<BLANKLINE>
* Standard output for a quick summary of the main metrics.
* A text file containing SQL commands necessary to build a SQL table
        in the database of your choice.
* A text file containing Comma-Separated Values (CSV) formatted data
        necessary to load into most spreadsheet programs.
        PLEASE NOTE: multi-line literals have the new-line character
        replaced with the character "\\n" in the output text.
<BLANKLINE>
Capitalized options negate the default option.
<BLANKLINE>
options:
  --version             show program's version number and exit
  -h, --help            show this help message and exit
  -s SQLFILENAME, --sql=SQLFILENAME
                        name of output SQL command file. (Default is
                        metricData.sql)
  -t SQLTOKENTABLENAME, --tokentable=SQLTOKENTABLENAME
                        name of output SQL token table. (Default is
                        metricTokens)
  -m SQLMETRICSTABLENAME, --metricstable=SQLMETRICSTABLENAME
                        name of output SQL metrics table. (Default is
                        metricData)
  -c CSVFILENAME, --csv=CSVFILENAME
                        name of output CSV data file. (Default is
                        metricData.csv)
  -f INFILELIST, --files=INFILELIST
                        File containing list of path names to modules for
                        analysis.
  -i INCLUDEMETRICSSTR, --include=INCLUDEMETRICSSTR
                        list of metrics to include in run. This is a comma
                        separated list of metric module names with no
                        whitespace. Optionally, you can specify the class name
                        of the metric by following the module name with a
                        colon (:) and the metric class name. (Default metrics
                        are 'simple:SimpleMetric,mccabe:McCabeMetric,
                        sloc:SLOCMetric'. Default metric class name for metric 
                        module 'wxYz' is 'WxYzMetric' when only module name
                        given -- note capitalized metric class name.)
  -l LIBNAME, --library=LIBNAME
                        user-defined name applied to collection of modules
                        (Default is '')
  -e, --exists          assume SQL tables exist and does not generate creation
                        code. Using this option sets option -N. (Default is
                        False)
  -N, --noold           create new command output files and tables after
                        deleting old results, if any. Ignored if -e is set.
                        (Default is False)
  -B, --nobasic         suppress production of Basic metrics (Default is
                        False)
  -S, --nosql           suppress production of output SQL command text file.
                        (Default is False)
  -C, --nocsv           suppress production of CSV output text file. (Default
                        is False)
  -H, --noheadings      suppress heading line in csv file. (Default is False)
  -k, --kwcnt           generate keyword counts. (Default is False)
  -K, --nokwcnt         suppress keyword counts. (Default is True)
  -q, --quiet           suppress normal summary output to stdout. (Default is
                        False)
  -z, --zero            display zero or empty values in output to stdout.
                        (Default is to suppress zero/empty output)
  -v, --verbose         Produce verbose output - more -v's produce more
                        output. (Default is no verbose output to stdout)
  -d, --debug           Provide debug output, not usually generated - internal
                        use only
<BLANKLINE>
No program file names given.
<BLANKLINE>

    $Id: processargs.py,v 1.4 2008/07/24 04:28:12 rcharney Exp $
"""
__version__ = "$Revision: 1.3 $"[11:-2]
__author__ = 'Reg. Charney <pymetrics@charneyday.com>'

import sys
from optparse import OptionParser, BadOptionError
from doctestsw import *

usageStr = """python PyMetrics [ options ] pgm1.py [ pgm2.py ... ]

Complexity metrics are computed for the Python input files
pgm1.py, pgm2.py, etc. At least one file name is required,
else this message appears.

Three types of output can be produced:

* Standard output for a quick summary of the main metrics.
* A text file containing SQL commands necessary to build a SQL table
        in the database of your choice.
* A text file containing Comma-Separated Values (CSV) formatted data
        necessary to load into most spreadsheet programs.
        PLEASE NOTE: multi-line literals have the new-line character
        replaced with the character "\\n" in the output text.

Capitalized options negate the default option.
"""

class PyMetricsOptionParser( OptionParser ):
  """ Subclass OptionParser so I can override default error handler."""
  def __init__( self, *args, **kwds ):
    """ Just call super class's __init__ since we aren't making changes here."""
    OptionParser.__init__( self, *args, **kwds )
    
  def error( self, msg ):
    """ Explicitly raise BadOptionError so calling program can handle it."""
    raise BadOptionError( msg )
    
class ProcessArgsError( Exception ): pass

class ProcessArgs( object ):
    """ Process command line arguments."""
    def __init__( self,
                  *pArgs,
                  **pKwds
                ):
        """ Initial processing of arguments."""

        # precedence for defaults, parameters, and command line arguments/keywords
        # is:
        #
        #   command line parameters/keywords take precedence over
        #   parameters used to instantiate ProcessArgs that takes precedence over
        #   default values for keywords.
        #
        # This implies we set completed options with defaults first
        # then override completed options with parameters
        # then override completed options with command line args/keywords
        #

        # default values for possible parameters
        libName = ''
        sqlFileName = "metricData.sql"
        sqlTokenTableName = "metricTokens"
        sqlMetricsTableName = "metricData"
        csvFileName = "metricData.csv"
        inFileList = None
        includeMetricsStr = 'simple:SimpleMetric,mccabe:McCabeMetric,sloc:SLOCMetric'
        excludeMetricsStr = None
        debugSw = False
        debugSw = False
        quietSw = False
        zeroSw = False
        genBasicSw = True
        genKwCntSw = False
        genSqlSw = True
        genCsvSw = True
        genHdrSw = True
        genAppendSw = True
        genNewSw = False
        genExistsSw = False
        verbose = 0

        self.__dict__.update( locals() )
        del( self.__dict__['self'] )  # remove recursive self from self.__dict__
        self.__dict__.update( pKwds )
        del( self.__dict__['pKwds'] ) # remove redundant pKwds in self.__dict__

        # set up option parser
        parser = PyMetricsOptionParser( '', version="%prog 0.8.1" )
        parser.add_option("-s", "--sql", 
                          dest="sqlFileName",
                          default=self.sqlFileName,
                          help="name of output SQL command file. (Default is %s)" % self.sqlFileName )
        parser.add_option("-t", "--tokentable", 
                          dest="sqlTokenTableName",
                          default=self.sqlTokenTableName,
                          help="name of output SQL token table. (Default is %s)" % self.sqlTokenTableName )
        parser.add_option("-m", "--metricstable", 
                          dest="sqlMetricsTableName",
                          default=self.sqlMetricsTableName,
                          help="name of output SQL metrics table. (Default is %s)" % self.sqlMetricsTableName )
        parser.add_option("-c", "--csv", 
                          dest="csvFileName",
                          default=self.csvFileName,
                          help="name of output CSV data file. (Default is %s)" % self.csvFileName )
        parser.add_option("-f", "--files", 
                          dest="inFileList",
                          default=self.inFileList,
                          help="File containing list of path names to modules for analysis." )
        parser.add_option("-i", "--include", 
                          dest="includeMetricsStr",
                          default=self.includeMetricsStr,
                          help="list of metrics to include in run. This is a comma separated list of metric module names with no whitespace. Optionally, you can specify the class name of the metric by following the module name with a colon (:) and the metric class name. (Default metrics are 'simple:SimpleMetric,mccabe:McCabeMetric,sloc:SLOCMetric'. Default metric class name for metric module 'wxYz' is 'WxYzMetric' when only module name given -- note capitalized metric class name.)" )
        parser.add_option("-l", "--library", 
                          dest="libName",
                          default=self.libName,
                          help="user-defined name applied to collection of modules (Default is '')" )
        parser.add_option("-e", "--exists",
                          action="store_true", 
                          dest="genExistsSw", 
                          default=self.genExistsSw,
                          help="assume SQL tables exist and does not generate creation code. Using this option sets option -N. (Default is %s)" % (self.genExistsSw) )
        parser.add_option("-N", "--noold",
                          action="store_true", 
                          dest="genNewSw", 
                          default=self.genNewSw,
                          help="create new command output files and tables after deleting old results, if any. Ignored if -e is set. (Default is %s)" % (self.genNewSw) )
        parser.add_option("-B", "--nobasic",
                          action="store_false", 
                          dest="genBasicSw", 
                          default=self.genBasicSw,
                          help="suppress production of Basic metrics (Default is %s)" % (not self.genBasicSw) )
        parser.add_option("-S", "--nosql",
                          action="store_false", 
                          dest="genSqlSw", 
                          default=self.genSqlSw,
                          help="suppress production of output SQL command text file. (Default is %s)" % (not self.genSqlSw) )
        parser.add_option("-C", "--nocsv",
                          action="store_false", 
                          dest="genCsvSw", 
                          default=self.genCsvSw,
                          help="suppress production of CSV output text file. (Default is %s)" % (not self.genCsvSw) )
        parser.add_option("-H", "--noheadings",
                          action="store_false", 
                          dest="genHdrSw", 
                          default=self.genHdrSw,
                          help="suppress heading line in csv file. (Default is %s)" % (not self.genHdrSw) )
        parser.add_option("-k", "--kwcnt",
                          action="store_true", 
                          dest="genKwCntSw", 
                          default=self.genKwCntSw,
                          help="generate keyword counts. (Default is %s)" % (self.genKwCntSw,) )
        parser.add_option("-K", "--nokwcnt",
                          action="store_false", 
                          dest="genKwCntSw", 
                          default=self.genKwCntSw,
                          help="suppress keyword counts. (Default is %s)" % (not self.genKwCntSw) )
        parser.add_option("-q", "--quiet",
                          action="store_true", 
                          dest="quietSw", 
                          default=self.quietSw,
                          help="suppress normal summary output to stdout. (Default is %s)" % (self.quietSw) )
        parser.add_option("-z", "--zero",
                          action="store_true", 
                          dest="zeroSw", 
                          default=self.zeroSw,
                          help="display zero or empty values in output to stdout. (Default is to suppress zero/empty output)" )
        parser.add_option("-v", "--verbose",
                          action="count", 
                          dest="verbose", 
                          default=self.verbose,
                          help="Produce verbose output - more -v's produce more output. (Default is no verbose output to stdout)")
        parser.add_option("-d", "--debug",
                          action="store_true", 
                          dest="debugSw", 
                          default=self.debugSw,
                          help="Provide debug output, not usually generated - internal use only")

        # parse the command line/arguments for this instance
        try:
            (options, args) = parser.parse_args()
        except BadOptionError, e:
            sys.stderr.writelines( "\nBadOptionError: %s\n" % str( e ) )
            sys.stderr.writelines( "\nThe valid options are:\n\n" )
            sys.stderr.writelines( parser.format_help() )
            sys.exit( 1 )

        # augment parameter values from instantiation with 
        #   command line values.
        # the command line parameter values take precidence 
        #   over values in program.

        args.extend( pArgs )

        # convert command line arguments into instance values
        self.__dict__.update( options.__dict__ )

        if self.inFileList:
            try:
                inF = open( self.inFileList )
                files = inF.read().split()
                inF.close()
                args.extend( files )
            except IOError, e:
                raise ProcessArgsError( e )

        self.inFileNames = args

        self.includeMetrics = self.processIncludeMetrics( self.includeMetricsStr )

        if len( args ) < 1:
            print usageStr
            print parser.format_help()
            e = "No program file names given.\n"
            # because of what I believe to be a bug in the doctest module,
            # which makes it mishandle exceptions, I have 'faked' the handling
            # of raising an exception and just return
            if doctestSw:
              print e
              return
            else:
              raise ProcessArgsError( e )

        so = None
        if self.genSqlSw and self.sqlFileName:
            # Try opening command file for input. If OK, then file exists.
            # Else, the commamd file does not exist to create SQL table and
            # this portion of the command file must be generated as if new
            # table was to be created.
            # 
            # NOTE: This assumption can be dangerous. If the table does exist
            # but the command file is out of sync with the table, then a valid
            # table can be deleted and recreated, thus losing the old data.
            # The workaround for this is to examine the SQL database for the 
            # table and only create the table, if needed.
            try:
                if self.sqlFileName:
                    self.so = open( self.sqlFileName, "r" )
                    self.so.close()
            except IOError:
                self.genNewSw = True
            
            try:
                mode = "a"
                if self.genNewSw:
                    mode = "w"
                so = open( self.sqlFileName, mode )    # check to see that we can write file
                so.close()
            except IOError, e:
                sys.stderr.writelines( str(e) + " -- No SQL command file will be generated\n" )
                self.genSqlSw = False
                so = None

        co = None
        if self.genCsvSw and self.csvFileName:
            try:
                mode = "a"
                if self.genNewSw:
                    mode = "w"
                co = open( self.csvFileName, mode )    # check we will be able to write file
                co.close()
            except IOError, e:
                sys.stderr.writelines( str(e) + " -- No CSV output file will be generated\n" )
                self.genCsvSw = False
                co = None
                
        if self.genExistsSw:
            # Assuming that table already exists, means concatenating 
            # data is not needed - we only want new data in SQL command file.
            self.genNewSw = True

    def conflictHandler( self, *args, **kwds ):
        print "args=%s" % args
        print "kwds=%s" % kwds

    def processIncludeMetrics( self, includeMetricsStr ):
        includeMetrics = []
        try:
            metricList = includeMetricsStr.split( ',' )
            for a in metricList:
                s = a.split( ':' )
                if len( s ) == 2:    # both metric class and module name given
                    includeMetrics.append( s )
                elif len( s ) == 1:
                    # only the module name given. Generate default metric
                    # class name by capitalizing first letter of module
                    # name and appending "Metric" so the default metric
                    # class name for module wxYz is WxYzMetric.
                    if s[0]:
                        defName = s[0][0].upper() + s[0][1:] + 'Metric'
                        includeMetrics.append( (s[0], defName) )
                    else:
                        raise ProcessArgsError("Missing metric module name")
                else:
                    raise ProcessArgsError("Malformed items in includeMetric string")
        except AttributeError, e:
            e = ( "Invalid list of metric names: %s" % 
                includeMetricsStr )
            raise ProcessArgsError( e )
        return includeMetrics

def testpa( pa ):
    """ Test of ProcessArgs.

    Usage:

    >>> pa=ProcessArgs('inFile.py')
    >>> testpa(pa)  #doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
    Arguments processed:
      sqlFileName=metricData.sql
      sqlTokenTableName=metricTokens
      sqlMetricsTableName=metricData
      csvFileName=metricData.csv
      Include Metric Modules=simple:SimpleMetric,mccabe:McCabeMetric
      quietSw=False
      genCsvSw=True
      genHdrSw=True
      genKwCntSw=False
      verbose=...
    Metrics to be used are:
      Module simple contains metric class SimpleMetric
      Module mccabe contains metric class McCabeMetric
    Input files:
      inFile.py
    >>>
    """
    print """
Arguments processed:
\tsqlFileName=%s
\tsqlTokenTableName=%s
\tsqlMetricsTableName=%s
\tcsvFileName=%s
\tinclude Metric Modules=%s
\tquietSw=%s
\tgenNewSw=%s
\tgenExistsSw=%s
\tgenSqlSw=%s
\tgenCsvSw=%s
\tgenHdrSw=%s
\tgenKwCntSw=%s
\tverbose=%s""" % (
        pa.sqlFileName,
        pa.sqlTokenTableName,
        pa.sqlMetricsTableName,
        pa.csvFileName,
        pa.includeMetricsStr,
        pa.quietSw,
        pa.genNewSw,
        pa.genExistsSw,
        pa.genSqlSw,
        pa.genCsvSw,
        pa.genHdrSw,
        pa.genKwCntSw,
        pa.verbose)
    print "Metrics to be used are:"
    for m,n in pa.includeMetrics:
        print "\tModule %s contains metric class %s" % (m,n)
    if pa.inFileNames:
        print "Input files:"
        for f in pa.inFileNames:
            print "\t%s" % f

if __name__ == "__main__":

    # ignore doctestsw.doctestSw if this is run as a standalone
    # module. Instead, look at the first argument on the command
    # line. If it is "doctest", set doctestSw = True and delete
    # the parameter "doctest" from sys.argv, thus leaving things
    # as _normal_.
    if len(sys.argv) > 1 and sys.argv[1] == 'doctest':
      doctestSw = True
      sys.argv[1:] = sys.argv[2:]
      import doctest
      doctest.testmod( sys.modules[__name__] )
      sys.exit( 0 )

    print "=== ProcessArgs: %s ===" % ("'file1.py', 'file2.py', '/home/files/file3.py'",)
    try:
      pa = ProcessArgs( 'file1.py', 'file2.py', '/home/files/file3.py' )
      testpa( pa )
    except ProcessArgsError, e:
      sys.stderr.writelines( str( e ) )
    print
    print "=== ProcessArgs: %s ===" % ("inFile1.py, sqlFileName='sqlF1.sql', genCsvSw=False,genKwCntSw=True",)
    try:
      pa = ProcessArgs( "inFile1.py", sqlFileName='sqlF1.sql', genCsvSw=False,genKwCntSw=True )
      testpa( pa )
    except ProcessArgsError, e:
      sys.stderr.writelines( str( e ) )
    print
    print "=== ProcessArgs: %s ===" % ("No arguments",)
    try:
      pa = ProcessArgs()
      testpa( pa )
    except ProcessArgsError, e:
      sys.stderr.writelines( str( e ) )
    print
    sys.exit( 0 )