3 # Copyright (c) 2012 Yannick Brosseau <yannick.brosseau@gmail.com>
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License
7 # as published by the Free Software Foundation; only version 2
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License along
16 # with this program; if not, write to the Free Software Foundation, Inc.,
17 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 from __future__
import print_function
26 class Usage(Exception):
27 def __init__(self
, msg
):
32 #undef TRACEPOINT_PROVIDER
33 #define TRACEPOINT_PROVIDER {providerName}
35 #undef TRACEPOINT_INCLUDE
36 #define TRACEPOINT_INCLUDE "./{headerFilename}"
38 #if !defined({includeGuard}) || defined(TRACEPOINT_HEADER_MULTI_READ)
39 #define {includeGuard}
41 #include <lttng/tracepoint.h>
45 #endif /* {includeGuard} */
47 #include <lttng/tracepoint-event.h>
49 def __init__(self
, filename
, template
):
50 self
.outputFilename
= filename
51 self
.template
= template
54 outputFile
= open(self
.outputFilename
,"w")
55 # Include guard macro will be created by uppercasing the filename and
56 # replacing all non alphanumeric characters with '_'
57 includeGuard
= re
.sub('[^0-9a-zA-Z]', '_', self
.outputFilename
.upper())
59 outputFile
.write(HeaderFile
.HEADER_TPL
.format(providerName
=self
.template
.domain
,
60 includeGuard
= includeGuard
,
61 headerFilename
= self
.outputFilename
))
62 outputFile
.write(self
.template
.text
)
63 outputFile
.write(HeaderFile
.FOOTER_TPL
.format(includeGuard
= includeGuard
))
68 #define TRACEPOINT_CREATE_PROBES
70 * The header containing our TRACEPOINT_EVENTs.
72 #define TRACEPOINT_DEFINE
73 #include "{headerFilename}"
75 def __init__(self
, filename
, template
):
76 self
.outputFilename
= filename
77 self
.template
= template
80 outputFile
= open(self
.outputFilename
,"w")
82 headerFilename
= self
.outputFilename
.replace(".c",".h")
84 outputFile
.write(CFile
.FILE_TPL
.format(
85 headerFilename
= headerFilename
))
89 def __init__(self
, filename
, template
):
90 self
.outputFilename
= filename
91 self
.template
= template
94 if 'CC' in os
.environ
:
97 subprocess
.call(cc
.split(),
98 stdout
=subprocess
.PIPE
,
99 stderr
=subprocess
.PIPE
)
100 except OSError as msg
:
101 print("Invalid CC environment variable")
105 # Try c first, if that fails try gcc
108 subprocess
.call("cc",
109 stdout
=subprocess
.PIPE
,
110 stderr
=subprocess
.PIPE
)
111 except OSError as msg
:
119 subprocess
.call("gcc",
120 stdout
=subprocess
.PIPE
,
121 stderr
=subprocess
.PIPE
)
122 except OSError as msg
:
129 cFilename
= self
.outputFilename
.replace(".o",".c")
130 cc
= self
._detectCC
()
132 raise RuntimeError("No C Compiler detected")
133 if 'CPPFLAGS' in os
.environ
:
134 cppflags
= " " + os
.environ
['CPPFLAGS']
137 if 'CFLAGS' in os
.environ
:
138 cflags
= " " + os
.environ
['CFLAGS']
141 if 'LDFLAGS' in os
.environ
:
142 ldflags
= " " + os
.environ
['LDFLAGS']
146 command
= cc
+ " -c" + cppflags
+ cflags
+ ldflags
+ " -I. -llttng-ust" + " -o " + self
.outputFilename
+ " " + cFilename
148 print("Compile command: " + command
)
149 subprocess
.call(command
.split())
152 def __init__(self
, filename
):
154 self
.inputFilename
= filename
158 def parseTemplate(self
):
159 f
= open(self
.inputFilename
,"r")
163 #Remove # comments (from input and output file) but keep
164 # #include in the output file
165 removeComments
= re
.compile("#[^include].*$",flags
=re
.MULTILINE
)
166 self
.text
= removeComments
.sub("",self
.text
)
167 # Remove #include directive from the parsed text
168 removePreprocess
= re
.compile("#.*$",flags
=re
.MULTILINE
)
169 noPreprocess
= removePreprocess
.sub("", self
.text
)
171 removeLineComment
= re
.compile("\/\/.*$",flags
=re
.MULTILINE
)
172 nolinecomment
= removeLineComment
.sub("", noPreprocess
)
173 #Remove all spaces and lines
174 cleantext
= re
.sub("\s*","",nolinecomment
)
175 #Remove multine C style comments
176 nocomment
= re
.sub("/\*.*?\*/","",cleantext
)
177 entries
= re
.split("TRACEPOINT_.*?",nocomment
)
179 for entry
in entries
:
181 decomp
= re
.findall("(\w*?)\((\w*?),(\w*?),", entry
)
183 domain
= decomp
[0][1]
186 if self
.domain
== "":
189 if self
.domain
!= domain
:
190 print("Warning: different domain provided (%s,%s)" % (self
.domain
, domain
))
195 lttng-gen-tp - Generate the LTTng-UST header and source based on a simple template
197 usage: lttng-gen-tp TEMPLATE_FILE [-o OUTPUT_FILE][-o OUTPUT_FILE]
199 If no OUTPUT_FILE is given, the .h and .c file will be generated.
200 (The basename of the template file with be used for the generated file.
201 for example sample.tp will generate sample.h, sample.c and sample.o)
203 When using the -o option, the OUTPUT_FILE must end with either .h, .c or .o
204 The -o option can be repeated multiple times.
206 The template file must contains TRACEPOINT_EVENT and TRACEPOINT_LOGLEVEL
207 as per defined in the lttng/tracepoint.h file.
208 See the lttng-ust(3) man page for more details on the format.
216 opts
, args
= getopt
.gnu_getopt(argv
[1:], "ho:av", ["help","verbose"])
217 except getopt
.error
as msg
:
221 print(err
.msg
, file=sys
.stderr
)
222 print("for help use --help", file=sys
.stderr
)
227 if o
in ("-h", "--help"):
231 outputNames
.append(a
)
234 if o
in ("-v", "--verbose"):
239 raise Usage("No template file given")
242 print(err
.msg
, file=sys
.stderr
)
243 print("for help use --help", file=sys
.stderr
)
249 headerFilename
= None
253 if len(outputNames
) > 0:
255 print("Cannot process more than one input if you specify an output")
258 for outputName
in outputNames
:
259 if outputName
[-2:] == ".h":
261 headerFilename
= outputName
262 elif outputName
[-2:] == ".c":
264 cFilename
= outputName
265 elif outputName
[-2:] == ".o":
267 objFilename
= outputName
269 print("output file type unsupported")
278 if arg
[-3:] != ".tp":
279 print(arg
+ " does not end in .tp. Skipping.")
284 tpl
= TemplateFile(arg
)
285 except IOError as args
:
286 print("Cannot read input file " + args
.filename
+ " " + args
.strerror
)
291 curFilename
= headerFilename
293 curFilename
= re
.sub("\.tp$",".h",arg
)
294 doth
= HeaderFile(curFilename
, tpl
)
298 curFilename
= cFilename
300 curFilename
= re
.sub("\.tp$",".c",arg
)
301 dotc
= CFile(curFilename
, tpl
)
305 curFilename
= objFilename
307 curFilename
= re
.sub("\.tp$",".o",arg
)
308 dotobj
= ObjFile(curFilename
, tpl
)
310 except IOError as args
:
311 print("Cannot write output file " + args
.filename
+ " " + args
.strerror
)
314 if __name__
== "__main__":
This page took 0.035783 seconds and 4 git commands to generate.