-#!/usr/bin/python
+#!/usr/bin/env python
#
# Copyright (c) 2012 Yannick Brosseau <yannick.brosseau@gmail.com>
#
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+from __future__ import print_function
import sys
import getopt
import re
+import os
+import subprocess
class Usage(Exception):
def __init__(self, msg):
#undef TRACEPOINT_PROVIDER
#define TRACEPOINT_PROVIDER {providerName}
-#undef TRACEPOINT_INCLUDE_FILE
-#define TRACEPOINT_INCLUDE_FILE ./{headerFilename}
-
-#ifdef __cplusplus
-#extern "C"{{
-#endif /*__cplusplus */
-
+#undef TRACEPOINT_INCLUDE
+#define TRACEPOINT_INCLUDE "./{headerFilename}"
#if !defined({includeGuard}) || defined(TRACEPOINT_HEADER_MULTI_READ)
#define {includeGuard}
#endif /* {includeGuard} */
#include <lttng/tracepoint-event.h>
-
-#ifdef __cplusplus
-}}
-#endif /*__cplusplus */
-
"""
def __init__(self, filename, template):
self.outputFilename = filename
def write(self):
outputFile = open(self.outputFilename,"w")
- includeGuard = "_"+self.outputFilename.upper().replace(".","_")
+ # Include guard macro will be created by uppercasing the filename and
+ # replacing all non alphanumeric characters with '_'
+ includeGuard = re.sub('[^0-9a-zA-Z]', '_', self.outputFilename.upper())
outputFile.write(HeaderFile.HEADER_TPL.format(providerName=self.template.domain,
includeGuard = includeGuard,
headerFilename = headerFilename))
outputFile.close()
+class ObjFile:
+ def __init__(self, filename, template):
+ self.outputFilename = filename
+ self.template = template
+ def _detectCC(self):
+ cc = ""
+ if 'CC' in os.environ:
+ cc = os.environ['CC']
+ try:
+ subprocess.call(cc.split(),
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ except OSError as msg:
+ print("Invalid CC environment variable")
+ cc = ""
+
+ else:
+ # Try c first, if that fails try gcc
+ try:
+ useCC = True
+ subprocess.call("cc",
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ except OSError as msg:
+ useCC = False
+ if useCC:
+ cc = "cc"
+
+ else:
+ try:
+ useGCC = True
+ subprocess.call("gcc",
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ except OSError as msg:
+ useGCC = False
+ if useGCC:
+ cc = "gcc"
+ return cc
+
+ def write(self):
+ cFilename = self.outputFilename.replace(".o",".c")
+ cc = self._detectCC()
+ if cc == "":
+ raise RuntimeError("No C Compiler detected")
+ if 'CPPFLAGS' in os.environ:
+ cppflags = " " + os.environ['CPPFLAGS']
+ else:
+ cppflags = ""
+ if 'CFLAGS' in os.environ:
+ cflags = " " + os.environ['CFLAGS']
+ else:
+ cflags = ""
+ if 'LDFLAGS' in os.environ:
+ ldflags = " " + os.environ['LDFLAGS']
+ else:
+ ldflags = ""
+
+ command = cc + " -c" + cppflags + cflags + ldflags + " -I. -llttng-ust" + " -o " + self.outputFilename + " " + cFilename
+ if verbose:
+ print("Compile command: " + command)
+ subprocess.call(command.split())
+
class TemplateFile:
def __init__(self, filename):
self.domain = ""
self.text = f.read()
- #Remove # comments (from input and output file
- self.text = re.sub("#.*$","",self.text,flags=re.MULTILINE)
+ #Remove # comments (from input and output file) but keep
+ # #include in the output file
+ removeComments = re.compile("#[^include].*$",flags=re.MULTILINE)
+ self.text = removeComments.sub("",self.text)
+ # Remove #include directive from the parsed text
+ removePreprocess = re.compile("#.*$",flags=re.MULTILINE)
+ noPreprocess = removePreprocess.sub("", self.text)
#Remove // comments
- nolinecomment = re.sub("\/\/.*$","",self.text,flags=re.MULTILINE)
+ removeLineComment = re.compile("\/\/.*$",flags=re.MULTILINE)
+ nolinecomment = removeLineComment.sub("", noPreprocess)
#Remove all spaces and lines
cleantext = re.sub("\s*","",nolinecomment)
#Remove multine C style comments
self.domain = domain
else:
if self.domain != domain:
- print "Warning: different domain provided (%s,%s)" % (self.domain, domain)
+ print("Warning: different domain provided (%s,%s)" % (self.domain, domain))
+
+verbose=False
usage="""
lttng-gen-tp - Generate the LTTng-UST header and source based on a simple template
If no OUTPUT_FILE is given, the .h and .c file will be generated.
(The basename of the template file with be used for the generated file.
- for example sample.tp will generate sample.h and sample.c)
+ for example sample.tp will generate sample.h, sample.c and sample.o)
- When using the -o option, the OUTPUT_FILE must end with either .h or .c
+ When using the -o option, the OUTPUT_FILE must end with either .h, .c or .o
The -o option can be repeated multiple times.
The template file must contains TRACEPOINT_EVENT and TRACEPOINT_LOGLEVEL
try:
try:
- opts, args = getopt.gnu_getopt(argv[1:], "ho:a", ["help"])
- except getopt.error, msg:
+ opts, args = getopt.gnu_getopt(argv[1:], "ho:av", ["help","verbose"])
+ except getopt.error as msg:
raise Usage(msg)
- except Usage, err:
- print >>sys.stderr, err.msg
- print >>sys.stderr, "for help use --help"
+ except Usage as err:
+ print(err.msg, file=sys.stderr)
+ print("for help use --help", file=sys.stderr)
return 2
outputNames = []
for o, a in opts:
if o in ("-h", "--help"):
- print usage
+ print(usage)
return(0)
if o in ("-o",""):
outputNames.append(a)
if o in ("-a",""):
all = True
+ if o in ("-v", "--verbose"):
+ global verbose
+ verbose = True
+ try:
+ if len(args) == 0:
+ raise Usage("No template file given")
+
+ except Usage as err:
+ print(err.msg, file=sys.stderr)
+ print("for help use --help", file=sys.stderr)
+ return 2
doCFile = None
doHeader = None
+ doObj = None
headerFilename = None
cFilename = None
+ objFilename = None
if len(outputNames) > 0:
if len(args) > 1:
- print "Cannot process more than one input if you specify an output"
+ print("Cannot process more than one input if you specify an output")
return(3)
for outputName in outputNames:
doCFile = True
cFilename = outputName
elif outputName[-2:] == ".o":
- print "Not yet implemented, sorry"
+ doObj = True
+ objFilename = outputName
else:
- print "output file type unsupported"
+ print("output file type unsupported")
return(4)
else:
doHeader = True
doCFile = True
+ doObj = True
# process arguments
for arg in args:
+ if arg[-3:] != ".tp":
+ print(arg + " does not end in .tp. Skipping.")
+ continue
- tpl = TemplateFile(arg)
- if doHeader:
- if headerFilename:
- curFilename = headerFilename
- else:
- curFilename = re.sub("\.tp$",".h",arg)
- doth = HeaderFile(curFilename, tpl)
- doth.write()
- if doCFile:
- if cFilename:
- curFilename = cFilename
- else:
- curFilename = re.sub("\.tp$",".c",arg)
- dotc = CFile(curFilename, tpl)
- dotc.write()
+ tpl = None
+ try:
+ tpl = TemplateFile(arg)
+ except IOError as args:
+ print("Cannot read input file " + args.filename + " " + args.strerror)
+ return -1
+ try:
+ if doHeader:
+ if headerFilename:
+ curFilename = headerFilename
+ else:
+ curFilename = re.sub("\.tp$",".h",arg)
+ doth = HeaderFile(curFilename, tpl)
+ doth.write()
+ if doCFile:
+ if cFilename:
+ curFilename = cFilename
+ else:
+ curFilename = re.sub("\.tp$",".c",arg)
+ dotc = CFile(curFilename, tpl)
+ dotc.write()
+ if doObj:
+ if objFilename:
+ curFilename = objFilename
+ else:
+ curFilename = re.sub("\.tp$",".o",arg)
+ dotobj = ObjFile(curFilename, tpl)
+ dotobj.write()
+ except IOError as args:
+ print("Cannot write output file " + args.filename + " " + args.strerror)
+ return -1
if __name__ == "__main__":
sys.exit(main())