123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- # Copyright Deniz Bahadir 2015
- #
- # Distributed under the Boost Software License, Version 1.0.
- # (See accompanying file LICENSE_1_0.txt or copy at
- # http://www.boost.org/LICENSE_1_0.txt)
- #
- # See http://www.boost.org/libs/mpl for documentation.
- # See http://stackoverflow.com/a/29627158/3115457 for further information.
- import argparse
- import sys
- import os.path
- import re
- import fileinput
- import datetime
- import glob
- def check_header_comment(filename):
- """Checks if the header-comment of the given file needs fixing."""
- # Check input file.
- name = os.path.basename( filename )
- # Read content of input file.
- sourcefile = open( filename, "rU" )
- content = sourcefile.read()
- sourcefile.close()
- # Search content for '$Id$'.
- match = re.search(r'\$Id\$', content)
- if match == None:
- # Make sure that the correct value for '$Id$' was already set.
- match = re.search(r'\$Id: ' + name + r'\s+[^$]+\$', content)
- if match != None:
- # The given file needs no fixing.
- return False
- # The given file needs fixing.
- return True
- def check_input_files_for_variadic_seq(headerDir, sourceDir):
- """Checks if files, used as input when pre-processing MPL-containers in their variadic form, need fixing."""
- # Check input files in include/source-directories.
- files = glob.glob( os.path.join( headerDir, "*.hpp" ) )
- files += glob.glob( os.path.join( headerDir, "aux_", "*.hpp" ) )
- files += glob.glob( os.path.join( sourceDir, "src", "*" ) )
- for currentFile in sorted( files ):
- if check_header_comment( currentFile ):
- return True
- return False
- def check_input_files_for_numbered_seq(sourceDir, suffix, containers):
- """Check if files, used as input when pre-processing MPL-containers in their numbered form, need fixing."""
- # Check input files for each MPL-container type.
- for container in containers:
- files = glob.glob( os.path.join( sourceDir, container, container + '*' + suffix ) )
- for currentFile in sorted( files ):
- if check_header_comment( currentFile ):
- return True
- return False
- def check_input_files(headerDir, sourceDir, containers=['vector', 'list', 'set', 'map'],
- seqType='both', verbose=False):
- """Checks if source- and header-files, used as input when pre-processing MPL-containers, need fixing."""
- # Check the input files for containers in their variadic form.
- result1 = False
- if seqType == "both" or seqType == "variadic":
- if verbose:
- print "Check if input files for pre-processing Boost.MPL variadic containers need fixing."
- result1 = check_input_files_for_variadic_seq(headerDir, sourceDir)
- if verbose:
- if result1:
- print " At least one input file needs fixing!"
- else:
- print " No input file needs fixing!"
- # Check the input files for containers in their numbered form.
- result2 = False
- result3 = False
- if seqType == "both" or seqType == "numbered":
- if verbose:
- print "Check input files for pre-processing Boost.MPL numbered containers."
- result2 = check_input_files_for_numbered_seq(headerDir, ".hpp", containers)
- result3 = check_input_files_for_numbered_seq(sourceDir, ".cpp", containers)
- if verbose:
- if result2 or result3:
- print " At least one input file needs fixing!"
- else:
- print " No input file needs fixing!"
- # Return result.
- return result1 or result2 or result3
- def fix_header_comment(filename, timestamp):
- """Fixes the header-comment of the given file."""
- # Fix input file.
- name = os.path.basename( filename )
- for line in fileinput.input( filename, inplace=1, mode="rU" ):
- # If header-comment already contains anything for '$Id$', remove it.
- line = re.sub(r'\$Id:[^$]+\$', r'$Id$', line.rstrip())
- # Replace '$Id$' by a string containing the file's name (and a timestamp)!
- line = re.sub(re.escape(r'$Id$'), r'$Id: ' + name + r' ' + timestamp.isoformat() + r' $', line.rstrip())
- print(line)
- def fix_input_files_for_variadic_seq(headerDir, sourceDir, timestamp):
- """Fixes files used as input when pre-processing MPL-containers in their variadic form."""
- # Fix files in include/source-directories.
- files = glob.glob( os.path.join( headerDir, "*.hpp" ) )
- files += glob.glob( os.path.join( headerDir, "aux_", "*.hpp" ) )
- files += glob.glob( os.path.join( sourceDir, "src", "*" ) )
- for currentFile in sorted( files ):
- fix_header_comment( currentFile, timestamp )
- def fix_input_files_for_numbered_seq(sourceDir, suffix, timestamp, containers):
- """Fixes files used as input when pre-processing MPL-containers in their numbered form."""
- # Fix input files for each MPL-container type.
- for container in containers:
- files = glob.glob( os.path.join( sourceDir, container, container + '*' + suffix ) )
- for currentFile in sorted( files ):
- fix_header_comment( currentFile, timestamp )
- def fix_input_files(headerDir, sourceDir, containers=['vector', 'list', 'set', 'map'],
- seqType='both', verbose=False):
- """Fixes source- and header-files used as input when pre-processing MPL-containers."""
- # The new modification time.
- timestamp = datetime.datetime.now();
- # Fix the input files for containers in their variadic form.
- if seqType == "both" or seqType == "variadic":
- if verbose:
- print "Fix input files for pre-processing Boost.MPL variadic containers."
- fix_input_files_for_variadic_seq(headerDir, sourceDir, timestamp)
- # Fix the input files for containers in their numbered form.
- if seqType == "both" or seqType == "numbered":
- if verbose:
- print "Fix input files for pre-processing Boost.MPL numbered containers."
- fix_input_files_for_numbered_seq(headerDir, ".hpp", timestamp, containers)
- fix_input_files_for_numbered_seq(sourceDir, ".cpp", timestamp, containers)
- def to_existing_absolute_path(string):
- """Converts a path into its absolute path and verifies that it exists or throws an exception."""
- value = os.path.abspath(string)
- if not os.path.exists( value ) or not os.path.isdir( value ):
- msg = '"%r" is not a valid path to a directory.' % string
- raise argparse.ArgumentTypeError(msg)
- return value
- def main():
- """The main function."""
- # Prepare and run cmdline-parser.
- cmdlineParser = argparse.ArgumentParser(
- description="Fixes the input files used for pre-processing of Boost.MPL headers.")
- cmdlineParser.add_argument("-v", "--verbose", dest='verbose', action='store_true',
- help="Be a little bit more verbose.")
- cmdlineParser.add_argument("--check-only", dest='checkonly', action='store_true',
- help="Only checks if fixing is required.")
- cmdlineParser.add_argument(dest='sourceDir', metavar="<source-dir>",
- type=to_existing_absolute_path,
- help="The source-directory of Boost.")
- args = cmdlineParser.parse_args()
- # Some verbose debug output.
- if args.verbose:
- print "Arguments extracted from command-line:"
- print " verbose = ", args.verbose
- print " check-only = ", args.checkonly
- print " source directory = ", args.sourceDir
- # The directories for header- and source files of Boost.MPL.
- # NOTE: Assuming 'args.sourceDir' is the source-directory of the entire boost project.
- headerDir = os.path.join( args.sourceDir, "boost", "mpl" )
- sourceDir = os.path.join( args.sourceDir, "libs", "mpl", "preprocessed" )
- # Check that the header/source-directories exist.
- if not os.path.exists( headerDir ) or not os.path.exists( sourceDir ):
- # Maybe 'args.sourceDir' is not the source-directory of the entire boost project
- # but instead of the Boost.MPL git-directory, only?
- headerDir = os.path.join( args.sourceDir, "include", "boost", "mpl" )
- sourceDir = os.path.join( args.sourceDir, "preprocessed" )
- if not os.path.exists( headerDir ) or not os.path.exists( sourceDir ):
- cmdlineParser.print_usage()
- print "error: Cannot find Boost.MPL header/source files in given Boost source-directory!"
- sys.exit(0)
- # Some verbose debug output.
- if args.verbose:
- print "Chosen header-directory: ", headerDir
- print "Chosen source-directory: ", sourceDir
- if args.checkonly:
- # Check input files for generating pre-processed headers.
- result = check_input_files(headerDir, sourceDir, verbose = args.verbose)
- if result:
- print "Fixing the input-files used for pre-processing of Boost.MPL headers IS required."
- else:
- print "Fixing the input-files used for pre-processing of Boost.MPL headers is NOT required."
- else:
- # Fix input files for generating pre-processed headers.
- fix_input_files(headerDir, sourceDir, verbose = args.verbose)
- if __name__ == '__main__':
- main()
|