bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Question about POSIX regex support


From: Gallagher James
Subject: Re: Question about POSIX regex support
Date: Fri, 22 Jun 2007 11:09:15 -0600

Thanks for the script!

James

On Jun 22, 2007, at 2:57 AM, James Youngman wrote:

On 6/22/07, Bruno Haible <address@hidden> wrote:
3) Verify that every source file that includes gnulib headers starts out
     with   #include <config.h>.


Here's a quick way of doing that (derived from the coreutils Makefile.maint) :-

#! /usr/bin/env python


import re
import sys

FIRST_INCLUDE = 'config.h'
problems = 0

LINE_SMELLS_SRC = [
   [r'(?<!\w)free \(\(', "don't cast the argument to free()"],
   [r'\*\) *x(m|c|re)alloc(?!\w)',"don't cast the result of x*alloc"],
   [r'\*\) *alloca(?!\w)',"don't cast the result of alloca"],
   [r'[ ]       ',"found SPACE-TAB; remove the space"],
   [r'(?<!\w)([fs]?scanf|ato([filq]|ll))(?!\w)',
    'do not use *scan''f, ato''f, ato''i, ato''l, ato''ll, ato''q, or
ss''canf'],
[r'error \(EXIT_SUCCESS',"passing EXIT_SUCCESS to error is confusing"],
   [r'file[s]ystem', "prefer writing 'file system' to 'filesystem'"],
   [r'HAVE''_CONFIG_H', "Avoid checking HAVE_CONFIG_H"],
#   [r'HAVE_FCNTL_H', "Avoid checking HAVE_FCNTL_H"],
   [r'O_NDELAY', "Avoid using O_NDELAY"],
   [r'the *the', "'the the' is probably not deliberate"],
[r'(?<!\w)error \([^_"]*[^_]"[^"]*[a-z]{3}', "untranslated error message"],
   [r'^# *if\s+defined *\(', "useless parentheses in '#if defined'"],

   ]

FILE_SMELLS_SRC = [
   [r'# *include <assert.h>(?!.*assert \()',
    "If you include <assert.h>, use assert()."],
   [r'# *include "quotearg.h"(?!.*(?<!\w)quotearg(_[^ ]+)? \()',
    "If you include \"quotearg.h\", use one of its functions."],
   [r'# *include "quote.h"(?!.*(?<!\w)quote(_[^ ]+)? \()',
    "If you include \"quote.h\", use one of its functions."],
   [r'\s$', "trailing whitespace"],
   ]

# missing check: ChangeLog prefixes
# missing: sc_always_defined_macros from coreutils
# missing: sc_tight_scope

COMPILED_LINE_SMELLS = [(re.compile(pong[0]), pong[1])
                       for pong in LINE_SMELLS_SRC]
COMPILED_FILE_SMELLS = [(re.compile(pong[0], re.DOTALL), pong[1])
                       for pong in FILE_SMELLS_SRC]

def Problem(filename, desc):
   global problems
   print >> sys.stderr, "error: %s: %s" % (filename, desc)
   problems += 1

def Warning(filename, desc):
   print >> sys.stderr, "warning: %s: %s" % (filename, desc)


def BuildIncludeList(text):
   include_re = re.compile(r'# *include +[<"](.*)[>"]')
   return [m.group(1) for m in include_re.finditer(text)]


def CheckFirstInclude(filename, lines, fulltext):
   includes = BuildIncludeList(fulltext)
   if includes and includes[0] != FIRST_INCLUDE:
       if FIRST_INCLUDE in includes:
fmt = "%s is first include file, but %s should be included first"
           Problem(filename, fmt % (includes[0], FIRST_INCLUDE))
   if FIRST_INCLUDE not in includes:
       Warning(filename,
               "%s should be included by most files" % FIRST_INCLUDE)

def CheckLineSmells(filename, lines, fulltext):
   for line in lines:
       for smell in COMPILED_LINE_SMELLS:
           match = smell[0].search(line[1])
           if match:
               Problem(filename, '%d: "%s": %s'
                       % (line[0], match.group(0), smell[1]))


def CheckFileSmells(filename, lines, fulltext):
   for smell in COMPILED_FILE_SMELLS:
       match = smell[0].search(fulltext)
       if match:
           Problem(filename, ' %s' % (smell[1],))




def SniffSourceFile(filename, lines, fulltext):
for sniffer in [CheckFirstInclude, CheckLineSmells, CheckFileSmells]:
       sniffer(filename, lines, fulltext)


def main(args):
   "main program"
   for srcfile in args[1:]:
       f = open(srcfile)
       line_number = 1
       lines = []
       for line in f.readlines():
           lines.append( (line_number, line) )
           line_number += 1
       fulltext = '\n'.join([line[1] for line in lines])
       SniffSourceFile(srcfile, lines, fulltext)
       f.close()
   if problems:
       return 1
   else:
       return 0


if __name__ == "__main__":
   sys.exit(main(sys.argv))


--
James Gallagher                jgallagher at opendap.org
OPeNDAP, Inc                   406.723.8663







reply via email to

[Prev in Thread] Current Thread [Next in Thread]