Cleanup lttng-gen-tp: Help not showing when using -h,--help
[lttng-ust.git] / tools / lttng-gen-tp
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
19 import sys
20 import getopt
21 import re
22 import os
23 import subprocess
24
25 class Usage(Exception):
26 def __init__(self, msg):
27 self.msg = msg
28
29 class 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
38 extern "C"{{
39 #endif /* __cplusplus */
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 }}
55 #endif /* __cplusplus */
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")
64 includeGuard = self.outputFilename.upper().replace(".","_")
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
73 class 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
95 class 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
148 class 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
161 removeComments = re.compile("#.*$",flags=re.MULTILINE)
162 self.text = removeComments.sub("",self.text)
163 #Remove // comments
164 removeLineComment = re.compile("\/\/.*$",flags=re.MULTILINE)
165 nolinecomment = removeLineComment.sub("",self.text)
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
185 usage="""
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.
192 for example sample.tp will generate sample.h, sample.c and sample.o)
193
194 When using the -o option, the OUTPUT_FILE must end with either .h, .c or .o
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 """
201 def 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
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
233
234 doCFile = None
235 doHeader = None
236 doObj = None
237 headerFilename = None
238 cFilename = None
239 objFilename = None
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":
254 doObj = True
255 objFilename = outputName
256 else:
257 print "output file type unsupported"
258 return(4)
259 else:
260 doHeader = True
261 doCFile = True
262 doObj = True
263
264 # process arguments
265 for arg in args:
266
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
299 if __name__ == "__main__":
300 sys.exit(main())
This page took 0.035415 seconds and 5 git commands to generate.