]> sourceware.org Git - systemtap.git/blame - dtrace.in
BZ915247: remove i18n stub support from python dtrace.in script
[systemtap.git] / dtrace.in
CommitLineData
c1008fd0 1#!/usr/bin/python
bc65bf81 2# vim: et sta sts=4 sw=4 ts=8
c1008fd0
SC
3
4# This handles the systemtap equivalent of
d294a649 5# $(DTRACE) $(DTRACEFLAGS) -G -s $^ -o $@
c1008fd0 6# $(DTRACE) $(DTRACEFLAGS) -h -s $^ -o $@
d294a649
SC
7# which is a step that builds DTrace provider and probe definitions
8
b1568fd8 9# Copyright (C) 2009, 2010, 2011 Red Hat Inc.
c1008fd0
SC
10#
11# This file is part of systemtap, and is free software. You can
12# redistribute it and/or modify it under the terms of the GNU General
13# Public License (GPL); either version 2, or (at your option) any
14# later version.
15
398d1973
SC
16import os
17import posix
398d1973 18import sys
4c353c3a 19import shlex
c0d0d868 20from subprocess import call
e3c5bcd9 21from tempfile import mkstemp
c1008fd0 22
50e767ff
JS
23class _provider(object):
24 def __init__(self):
25 self.semaphores_def = "\n"
26
4f46087f 27 # is the type a basic scalar type?
398d1973
SC
28 def __basic_type(self, arg):
29 basic_types = [ "int","int*","long","long*","short","short int",
30 "unsigned long","char","char*","float","double" ]
4f46087f
SC
31 split_arg = arg.rsplit(None,1)
32 return (split_arg[0].strip() in basic_types) & (arg.find("[") == -1)
50e767ff 33
a49946ac 34 def __typedef_append(self, typedefs, this_probe, arg, c, add_typedefs):
5111fc3e
SC
35 if (add_typedefs):
36 split_arg = arg.rsplit(None,1)
398d1973 37 if (self.__basic_type(arg)):
4f46087f 38 return typedefs
5111fc3e
SC
39 type_name = " %s_arg%d" % (this_probe.replace("__","_"),c)
40 if (len(split_arg) > 1):
41 typedefs += ("typedef " + arg.replace(" " + split_arg[1].split("[")[0].lstrip("*"),type_name).strip() + "; ")
42 typedefs += (type_name + type_name + "_v;\n")
43 else:
44 typedefs += ("typedef " + arg.strip() + type_name + "; ")
45 typedefs += (type_name + type_name + "_v;\n")
46 return typedefs
50e767ff 47
398d1973 48 def __semaphore_def_append(self, this_probe):
8faa1fc5 49 # NB: unsigned short is fixed in ABI
ebbd2b45 50 self.semaphores_def += '#if defined STAP_SDT_V1\n'
398d1973
SC
51 self.semaphores_def += '#define %s_%s_semaphore %s_semaphore\n' % \
52 (self.provider,this_probe,this_probe)
a794dbeb 53 self.semaphores_def += '#endif\n'
5561d47d
SC
54 self.semaphores_def += '#if defined STAP_SDT_V1 || defined STAP_SDT_V2 \n'
55 self.semaphores_def += "__extension__ unsigned short %s_%s_semaphore __attribute__ ((unused)) __attribute__ ((section (\".probes\")));\n" % \
56 (self.provider,this_probe)
57 self.semaphores_def += '#else\n'
8f549224 58 self.semaphores_def += "__extension__ unsigned short %s_%s_semaphore __attribute__ ((unused)) __attribute__ ((section (\".probes\"))) __attribute__ ((visibility (\"hidden\")));\n" % \
398d1973 59 (self.provider,this_probe)
5561d47d 60 self.semaphores_def += '#endif\n'
50e767ff 61
4f46087f
SC
62 def semaphore_def_write(self, file):
63 file.write(self.semaphores_def)
50e767ff 64
5111fc3e 65 def generate(self, provider, header, add_typedefs):
c1008fd0
SC
66 have_provider = False
67 self.f = open(provider)
68 self.h = open(header,mode='w')
2a22df62 69 self.h.write("/* Generated by the Systemtap dtrace wrapper */\n")
6b51ee12
SC
70 self.h.write("\n#define _SDT_HAS_SEMAPHORES 1\n\n")
71 self.h.write("\n#define STAP_HAS_SEMAPHORES 1 /* deprecated */\n\n")
c1008fd0
SC
72 self.h.write("\n#include <sys/sdt.h>\n\n")
73 in_comment = False
5111fc3e 74 typedefs = ""
c1008fd0
SC
75 while (True):
76 line = self.f.readline()
77 if (line == ""):
78 break
5111fc3e 79 if (line.find("/*") != -1):
c1008fd0 80 in_comment = True
5111fc3e 81 if (line.find("*/") != -1):
c1008fd0
SC
82 in_comment = False
83 continue
84 if (in_comment):
85 continue
5111fc3e 86 if (line.find("provider") != -1):
c1008fd0
SC
87 tokens = line.split()
88 have_provider = True
89 self.provider = tokens[1]
5111fc3e
SC
90 elif (not have_provider):
91 if (add_typedefs):
92 self.h.write (line)
93 elif (have_provider and line.find("probe ") != -1):
c1008fd0
SC
94 while (line.find(")") < 0):
95 line += self.f.readline()
96 this_probe = line[line.find("probe ")+5:line.find("(")].strip()
97 this_probe_canon = self.provider.upper() + "_" + this_probe.replace("__","_").upper()
98 args = (line[line.find("(")+1:line.find(")")])
5111fc3e
SC
99 args_string = ""
100 arg = ""
c1008fd0
SC
101 i = 0
102 c = 0
398d1973 103 self.__semaphore_def_append (this_probe)
c1008fd0
SC
104 while (i < len(args)):
105 if (args[i:i+1] == ","):
398d1973
SC
106 args_string = ('%s %s,' %
107 (args_string, arg.strip()))
c1008fd0 108 c += 1
a49946ac
JS
109 typedefs = self.__typedef_append (typedefs, this_probe,
110 arg, c, add_typedefs)
5111fc3e 111 arg = ""
c1008fd0 112 else:
5111fc3e 113 arg = arg + args[i]
c1008fd0 114 i += 1
5111fc3e
SC
115 if (i != 0):
116 args_string = ('%s %s' % (args_string, arg.strip()))
398d1973 117 if (not args_string):
46607641 118 c = 0
63877c9a 119 stap_str = "DTRACE_PROBE(%s,%s" % \
398d1973 120 (self.provider,this_probe)
46607641
SC
121 else:
122 c += 1
a49946ac
JS
123 typedefs = self.__typedef_append (typedefs, this_probe,
124 arg, c, add_typedefs)
63877c9a 125 stap_str = "DTRACE_PROBE%d(%s,%s" % \
398d1973 126 (c,self.provider,this_probe)
4f988cd3 127 define_str = "#define %s(" % (this_probe_canon)
46607641 128 i = 1
4f988cd3 129 while (i <= c):
2a22df62 130 if (i != 1):
4f988cd3 131 define_str += ","
46607641
SC
132 define_str = define_str + "arg%s" % (i);
133 stap_str = stap_str + ",arg%s" % (i);
4f988cd3 134 i += 1
398d1973
SC
135 self.h.write('/* %s (%s) */\n' % \
136 (this_probe_canon,args_string))
137 self.h.write('#if defined STAP_SDT_V1\n')
138 self.h.write('#define %s_ENABLED() __builtin_expect (%s_semaphore, 0)\n' % \
139 (this_probe_canon,this_probe))
140 self.h.write('#define %s_%s_semaphore %s_semaphore\n' % \
141 (self.provider,this_probe,this_probe))
142 self.h.write('#else\n')
143 self.h.write('#define %s_ENABLED() __builtin_expect (%s_%s_semaphore, 0)\n' % \
144 (this_probe_canon,self.provider,this_probe))
145 self.h.write('#endif\n')
8faa1fc5 146 # NB: unsigned short is fixed in ABI
398d1973
SC
147 self.h.write("__extension__ extern unsigned short %s_%s_semaphore __attribute__ ((unused)) __attribute__ ((section (\".probes\")));\n" % \
148 (self.provider,this_probe))
149 self.h.write(define_str + ") \\\n")
150 self.h.write(stap_str + ")\n\n")
5111fc3e
SC
151 elif (line.find("}") != -1 and have_provider):
152 have_provider = False
153 if (add_typedefs):
398d1973 154 self.h.write(typedefs)
5111fc3e
SC
155 self.h.close()
156
c1008fd0 157
c1008fd0 158def usage ():
a54d79ce 159 print "Usage " + sys.argv[0] + " [--help] [-h | -G] [-C [-I<Path>]] -s File.d [-o <File>]"
5111fc3e
SC
160
161def help ():
162 usage()
a54d79ce
FCE
163 print "Where -h builds a systemtap header file from the .d file"
164 print " -C when used with -h, also run cpp preprocessor"
165 print " -o specifies an explicit output file name,"
166 print " the default for -G is file.o and -h is file.h"
167 print " -I when running cpp pass through this -I include Path"
168 print " -s specifies the name of the .d input file"
169 print " -G builds a stub file.o from file.d,"
170 print " which is required by some packages that use dtrace."
c1008fd0
SC
171 sys.exit(1)
172
4f988cd3
SC
173
174########################################################################
175# main
176########################################################################
177
a49946ac
JS
178def main():
179 if (len(sys.argv) < 2):
180 usage()
12aad6f0 181 return 1
c1008fd0 182
a49946ac
JS
183 i = 1
184 build_header = False
185 build_source = False
186 add_typedefs = False
187 keep_temps = False
188 use_cpp = False
b571f934 189 suffix = ""
a49946ac
JS
190 filename = ""
191 s_filename = ""
192 includes = []
193 defines = []
194 while (i < len(sys.argv)):
195 if (sys.argv[i] == "-o"):
196 i += 1
197 filename = sys.argv[i]
198 elif (sys.argv[i] == "-s"):
199 i += 1
200 s_filename = sys.argv[i]
201 elif (sys.argv[i] == "-C"):
202 use_cpp = True
203 elif (sys.argv[i].startswith("-D")):
204 defines.append(sys.argv[i])
205 elif (sys.argv[i] == "-h"):
206 build_header = True
b571f934 207 suffix = ".h"
a49946ac
JS
208 elif (sys.argv[i].startswith("-I")):
209 includes.append(sys.argv[i])
210 elif (sys.argv[i] == "-G"):
211 build_source = True
b571f934 212 suffix = ".o"
a49946ac
JS
213 elif (sys.argv[i] == "-k"):
214 keep_temps = True
215 elif (sys.argv[i] == "--types"):
216 add_typedefs = True
217 elif (sys.argv[i] == "--help"):
218 help()
c1008fd0 219 i += 1
a49946ac 220 if (build_header == False and build_source == False):
dd66ed3f 221 usage()
12aad6f0 222 return 1
a49946ac
JS
223
224 if (s_filename != "" and use_cpp):
225 (d,fn) = mkstemp(suffix=".d")
226 CPP = os.environ.get("CPP", "cpp")
4c353c3a 227 retcode = call(shlex.split(CPP) + includes + defines + [s_filename, fn])
a49946ac
JS
228 if (retcode != 0):
229 print "\"cpp includes s_filename\" failed"
230 usage()
12aad6f0 231 return 1
a49946ac
JS
232 s_filename = fn
233 if (filename == ""):
234 if (s_filename != ""):
235 (filename,ext) = os.path.splitext(s_filename)
236 filename = os.path.basename(filename)
237 else:
238 usage()
12aad6f0 239 return 1
c1008fd0 240 else:
b571f934 241 suffix = ""
8bab68f6 242 if (build_header):
a49946ac 243 providers = _provider()
b571f934 244 providers.generate(s_filename, filename + suffix, add_typedefs)
a49946ac
JS
245 elif (build_source):
246 (basename,ext) = os.path.splitext(s_filename)
4f46087f 247
a49946ac
JS
248 # create for semaphore_def_write
249 providers = _provider()
250 (d,fn) = mkstemp(suffix=".h")
251 providers.generate(s_filename, fn, add_typedefs)
252 if (not keep_temps):
253 os.remove(fn)
254 else:
255 print "header: " + fn
4f46087f 256
a49946ac
JS
257 (d,fn) = mkstemp(suffix=".c")
258 f = open(fn,mode='w')
69607fca
FCE
259 # dummy declaration just to make the object file non-empty
260 f.write("static void __dtrace (void) __attribute__((unused));\n")
261 f.write("static void __dtrace (void) {}\n")
a49946ac
JS
262 f.write("\n#include <sys/sdt.h>\n\n")
263 providers.semaphore_def_write(f)
264 f.close()
265 CC = os.environ.get("CC", "gcc")
266 CFLAGS = "-g " + os.environ.get("CFLAGS", "")
4c353c3a 267 retcode = call(shlex.split(CC) + defines + includes + shlex.split(CFLAGS) +
f6b267eb 268 ["-fPIC", "-I.", "-I@prefix@/include", "-c", fn, "-o",
b571f934
SC
269 filename + suffix], shell=False)
270 if (retcode != 0):
271 print "\"gcc " + fn + "\" failed"
272 usage()
12aad6f0 273 return 1
bc65bf81 274 if (not keep_temps):
a49946ac 275 os.remove(fn)
bc65bf81 276 else:
a49946ac
JS
277 print "source: " + fn
278 if (use_cpp):
279 if (not keep_temps):
280 os.remove(s_filename)
281 else:
282 print "cpp: " + s_filename
12aad6f0 283 return 0
a49946ac
JS
284
285if __name__ == "__main__":
12aad6f0 286 sys.exit(main())
This page took 0.112659 seconds and 5 git commands to generate.