blob: 28436f270564256dd85b9e879d77b5e50c5957a5 [file] [log] [blame]
# Copyright 2018 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import argparse
import os
import subprocess
import sys
def main():
args = parseInput()
assert validateHeaderInput(args.header), \
"Error: '%s' is not a valid .h file" % args.header
assert validateCodeInput(args.cc), \
"Error: '%s' is not a valid .cc file" % args.cc
assert validatePathInput(args.gen_dir), \
"Error: '%s' is not a valid output directory" % args.gen_dir
assert validateCddlInput(args.file), \
"Error: '%s' is not a valid CDDL file" % args.file
if args.log:
logPath = os.path.join(args.gen_dir, args.log)
log = open(logPath, "w")
log.write("OUTPUT FOR CDDL CODE GENERATION TOOL:\n\n")
log = open(logPath, "a")
if (args.verbose):
print("Logging to %s" % logPath)
else:
log = None
if (args.verbose):
print('Creating C++ files from provided CDDL file...')
echoAndRunCommand([args.cddl, "--header", args.header, "--cc", args.cc,
"--gen-dir", args.gen_dir, args.file],
False, log, args.verbose)
clangFormatLocation = findClangFormat()
if not clangFormatLocation:
if args.verbose:
print("WARNING: clang-format could not be found")
return
for filename in [args.header, args.cc]:
echoAndRunCommand([clangFormatLocation + 'clang-format', "-i",
os.path.join(args.gen_dir, filename)],
True, verbose=args.verbose)
def parseInput():
parser = argparse.ArgumentParser()
parser.add_argument("--cddl", help="path to the cddl executable to use")
parser.add_argument("--header", help="Specify the filename of the output \
header file. This is also the name that will be used for the include \
guard and as the include path in the source file.")
parser.add_argument("--cc", help="Specify the filename of the output \
source file")
parser.add_argument("--gen-dir", help="Specify the directory prefix that \
should be added to the output header and source file.")
parser.add_argument("--log", help="Specify the file to which stdout should \
be redirected.")
parser.add_argument("--verbose", help="Specify that we should log info \
messages to stdout")
parser.add_argument("file", help="the input file which contains the spec")
return parser.parse_args()
def validateHeaderInput(headerFile):
return headerFile and headerFile.endswith('.h')
def validateCodeInput(ccFile):
return ccFile and ccFile.endswith('.cc')
def validatePathInput(dirPath):
return dirPath and os.path.isdir(dirPath)
def validateCddlInput(cddlFile):
return cddlFile and os.path.isfile(cddlFile)
def echoAndRunCommand(commandArray, allowFailure,
logfile = None, verbose = False):
if verbose:
print("\tExecuting Command: '%s'" % " ".join(commandArray))
if logfile != None:
process = subprocess.Popen(commandArray, stdout=logfile, stderr=logfile)
process.wait()
logfile.flush()
else:
process = subprocess.Popen(commandArray)
process.wait()
returncode = process.returncode
if returncode != None and returncode != 0:
if not allowFailure:
sys.exit("\t\tERROR: Command failed with error code: '%i'!" % returncode)
elif verbose:
print("\t\tWARNING: Command failed with error code: '%i'!" % returncode)
def findClangFormat():
executable = "clang-format"
# Try and run from the environment variable
for directory in os.environ["PATH"].split(os.pathsep):
fullPath = os.path.join(directory, executable)
if os.path.isfile(fullPath):
return ""
# Check 2 levels up since this should be correct on the build machine
path = "../../"
fullPath = os.path.join(path, executable)
if os.path.isfile(fullPath):
return path
return None
if __name__ == "__main__":
main()