Pack structures in comm protocol between UST and sessiond
[lttng-ust.git] / tools / lttng-gen-tp
CommitLineData
b25c5b37
YB
1#!/usr/bin/python
2#
3# Copyright (c) 2012 Yannick Brosseau <yannick.brosseau@gmail.com>
4#
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
8# of the License.
9#
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.
14#
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.
18
19import sys
20import getopt
21import re
db06a0a2
YB
22import os
23import subprocess
b25c5b37
YB
24
25class Usage(Exception):
26 def __init__(self, msg):
27 self.msg = msg
28
29class HeaderFile:
30 HEADER_TPL="""
31#undef TRACEPOINT_PROVIDER
32#define TRACEPOINT_PROVIDER {providerName}
33
34#undef TRACEPOINT_INCLUDE_FILE
35#define TRACEPOINT_INCLUDE_FILE ./{headerFilename}
36
37#ifdef __cplusplus
9cc0a748
MD
38extern "C"{{
39#endif /* __cplusplus */
b25c5b37
YB
40
41
42#if !defined({includeGuard}) || defined(TRACEPOINT_HEADER_MULTI_READ)
43#define {includeGuard}
44
45#include <lttng/tracepoint.h>
46
47"""
48 FOOTER_TPL="""
49#endif /* {includeGuard} */
50
51#include <lttng/tracepoint-event.h>
52
53#ifdef __cplusplus
54}}
9cc0a748 55#endif /* __cplusplus */
b25c5b37
YB
56
57"""
58 def __init__(self, filename, template):
59 self.outputFilename = filename
60 self.template = template
61
62 def write(self):
63 outputFile = open(self.outputFilename,"w")
85302e04 64 includeGuard = self.outputFilename.upper().replace(".","_")
b25c5b37
YB
65
66 outputFile.write(HeaderFile.HEADER_TPL.format(providerName=self.template.domain,
67 includeGuard = includeGuard,
68 headerFilename = self.outputFilename))
69 outputFile.write(self.template.text)
70 outputFile.write(HeaderFile.FOOTER_TPL.format(includeGuard = includeGuard))
71 outputFile.close()
72
73class CFile:
74 FILE_TPL="""
75#define TRACEPOINT_CREATE_PROBES
76/*
77 * The header containing our TRACEPOINT_EVENTs.
78 */
79#define TRACEPOINT_DEFINE
80#include "{headerFilename}"
81"""
82 def __init__(self, filename, template):
83 self.outputFilename = filename
84 self.template = template
85
86 def write(self):
87 outputFile = open(self.outputFilename,"w")
88
89 headerFilename = self.outputFilename.replace(".c",".h")
90
91 outputFile.write(CFile.FILE_TPL.format(
92 headerFilename = headerFilename))
93 outputFile.close()
94
db06a0a2
YB
95class ObjFile:
96 def __init__(self, filename, template):
97 self.outputFilename = filename
98 self.template = template
99 def _detectCC(self):
100 cc = ""
101 if os.environ.has_key('CC'):
102 cc = os.environ['CC']
103 try:
104 subprocess.call(cc,
105 stdout=subprocess.PIPE,
106 stderr=subprocess.PIPE)
107 except OSError, msg:
108 print "Invalid CC environment variable"
109 cc = ""
110
111 else:
112 # Try c first, if that fails try gcc
113 try:
114 useCC = True
115 subprocess.call("cc",
116 stdout=subprocess.PIPE,
117 stderr=subprocess.PIPE)
118 except OSError, msg:
119 useCC = False
120 if useCC:
121 cc = "cc"
122
123 else:
124 try:
125 useGCC = True
126 subprocess.call("gcc",
127 stdout=subprocess.PIPE,
128 stderr=subprocess.PIPE)
129 except OSError, msg:
130 useGCC = False
131 if useGCC:
132 cc = "gcc"
133 return cc
134
135 def write(self):
136 cFilename = self.outputFilename.replace(".o",".c")
137 cc = self._detectCC()
138 if cc == "":
139 raise RuntimeError("No C Compiler detected")
140 if os.environ.has_key('CFLAGS'):
141 cflags = os.environ['CFLAGS']
142 else:
143 cflags = ""
144
145 command = cc + " -c " + cflags + " -I. -llttng-ust" + " -o " + self.outputFilename + " " + cFilename
146 subprocess.call(command.split())
147
b25c5b37
YB
148class TemplateFile:
149 def __init__(self, filename):
150 self.domain = ""
151 self.inputFilename = filename
152 self.parseTemplate()
153
154
155 def parseTemplate(self):
156 f = open(self.inputFilename,"r")
157
158 self.text = f.read()
159
160 #Remove # comments (from input and output file
c233fe11
YB
161 removeComments = re.compile("#.*$",flags=re.MULTILINE)
162 self.text = removeComments.sub("",self.text)
b25c5b37 163 #Remove // comments
c233fe11
YB
164 removeLineComment = re.compile("\/\/.*$",flags=re.MULTILINE)
165 nolinecomment = removeLineComment.sub("",self.text)
b25c5b37
YB
166 #Remove all spaces and lines
167 cleantext = re.sub("\s*","",nolinecomment)
168 #Remove multine C style comments
169 nocomment = re.sub("/\*.*?\*/","",cleantext)
170 entries = re.split("TRACEPOINT_.*?",nocomment)
171
172 for entry in entries:
173 if entry != '':
174 decomp = re.findall("(\w*?)\((\w*?),(\w*?),", entry)
175 typea = decomp[0][0]
176 domain = decomp[0][1]
177 name = decomp[0][2]
178
179 if self.domain == "":
180 self.domain = domain
181 else:
182 if self.domain != domain:
183 print "Warning: different domain provided (%s,%s)" % (self.domain, domain)
184
185usage="""
186 lttng-gen-tp - Generate the LTTng-UST header and source based on a simple template
187
188 usage: lttng-gen-tp TEMPLATE_FILE [-o OUTPUT_FILE][-o OUTPUT_FILE]
189
190 If no OUTPUT_FILE is given, the .h and .c file will be generated.
191 (The basename of the template file with be used for the generated file.
db06a0a2 192 for example sample.tp will generate sample.h, sample.c and sample.o)
b25c5b37 193
db06a0a2 194 When using the -o option, the OUTPUT_FILE must end with either .h, .c or .o
b25c5b37
YB
195 The -o option can be repeated multiple times.
196
197 The template file must contains TRACEPOINT_EVENT and TRACEPOINT_LOGLEVEL
198 as per defined in the lttng/tracepoint.h file.
199 See the lttng-ust(3) man page for more details on the format.
200"""
201def main(argv=None):
202 if argv is None:
203 argv = sys.argv
204
205 try:
206 try:
207 opts, args = getopt.gnu_getopt(argv[1:], "ho:a", ["help"])
208 except getopt.error, msg:
209 raise Usage(msg)
210
211 except Usage, err:
212 print >>sys.stderr, err.msg
213 print >>sys.stderr, "for help use --help"
214 return 2
215
216 outputNames = []
217 for o, a in opts:
218 if o in ("-h", "--help"):
219 print usage
220 return(0)
221 if o in ("-o",""):
222 outputNames.append(a)
223 if o in ("-a",""):
224 all = True
a719be64
CB
225 try:
226 if len(args) == 0:
227 raise Usage("No template file given")
228
229 except Usage, err:
230 print >>sys.stderr, err.msg
231 print >>sys.stderr, "for help use --help"
232 return 2
b25c5b37
YB
233
234 doCFile = None
235 doHeader = None
db06a0a2 236 doObj = None
b25c5b37
YB
237 headerFilename = None
238 cFilename = None
db06a0a2 239 objFilename = None
b25c5b37
YB
240
241 if len(outputNames) > 0:
242 if len(args) > 1:
243 print "Cannot process more than one input if you specify an output"
244 return(3)
245
246 for outputName in outputNames:
247 if outputName[-2:] == ".h":
248 doHeader = True
249 headerFilename = outputName
250 elif outputName[-2:] == ".c":
251 doCFile = True
252 cFilename = outputName
253 elif outputName[-2:] == ".o":
db06a0a2
YB
254 doObj = True
255 objFilename = outputName
b25c5b37
YB
256 else:
257 print "output file type unsupported"
258 return(4)
259 else:
260 doHeader = True
261 doCFile = True
db06a0a2 262 doObj = True
b25c5b37
YB
263
264 # process arguments
265 for arg in args:
266
44745fc1
YB
267 tpl = None
268 try:
269 tpl = TemplateFile(arg)
270 except IOError as args:
271 print "Cannot read input file " + args.filename + " " + args.strerror
272 return -1
273 try:
274 if doHeader:
275 if headerFilename:
276 curFilename = headerFilename
277 else:
278 curFilename = re.sub("\.tp$",".h",arg)
279 doth = HeaderFile(curFilename, tpl)
280 doth.write()
281 if doCFile:
282 if cFilename:
283 curFilename = cFilename
284 else:
285 curFilename = re.sub("\.tp$",".c",arg)
286 dotc = CFile(curFilename, tpl)
287 dotc.write()
288 if doObj:
289 if objFilename:
290 curFilename = objFilename
291 else:
292 curFilename = re.sub("\.tp$",".o",arg)
293 dotobj = ObjFile(curFilename, tpl)
294 dotobj.write()
295 except IOError as args:
296 print "Cannot write output file " + args.filename + " " + args.strerror
297 return -1
298
b25c5b37
YB
299if __name__ == "__main__":
300 sys.exit(main())
This page took 0.0342 seconds and 4 git commands to generate.