~lttng/lttng-ust/lttng-ust

« back to all changes in this revision

Viewing changes to tools/lttng-gen-tp

  • Committer: Mathieu Desnoyers
  • Author(s): Yannick Brosseau
  • Date: 2012-02-16 14:11:11 UTC
  • Revision ID: git-v1:b25c5b37ef536d7b09fe901d97e678220ec69c9a
Create the lttng-gen-tp tools as an helper to generate UST .h and .c files

Based on a template file which contains TRACEPOINT_EVENT definition, the
tools generate the necessary .h and .c to create the probes.

Include an example use in tests/gen-tp/

(refs #24)

Signed-off-by: Yannick Brosseau <yannick.brosseau@gmail.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
23
class Usage(Exception):
 
24
    def __init__(self, msg):
 
25
        self.msg = msg
 
26
 
 
27
class HeaderFile:
 
28
    HEADER_TPL="""
 
29
#undef TRACEPOINT_PROVIDER
 
30
#define TRACEPOINT_PROVIDER {providerName}
 
31
 
 
32
#undef TRACEPOINT_INCLUDE_FILE
 
33
#define TRACEPOINT_INCLUDE_FILE ./{headerFilename}
 
34
 
 
35
#ifdef __cplusplus
 
36
#extern "C"{{
 
37
#endif /*__cplusplus */
 
38
 
 
39
 
 
40
#if !defined({includeGuard}) || defined(TRACEPOINT_HEADER_MULTI_READ)
 
41
#define {includeGuard}
 
42
 
 
43
#include <lttng/tracepoint.h>
 
44
 
 
45
"""
 
46
    FOOTER_TPL="""
 
47
#endif /* {includeGuard} */
 
48
 
 
49
#include <lttng/tracepoint-event.h>
 
50
 
 
51
#ifdef __cplusplus
 
52
}}
 
53
#endif /*__cplusplus */
 
54
 
 
55
"""
 
56
    def __init__(self, filename, template):
 
57
        self.outputFilename = filename
 
58
        self.template = template
 
59
 
 
60
    def write(self):
 
61
        outputFile = open(self.outputFilename,"w")
 
62
        includeGuard = "_"+self.outputFilename.upper().replace(".","_")
 
63
 
 
64
        outputFile.write(HeaderFile.HEADER_TPL.format(providerName=self.template.domain,
 
65
                                           includeGuard = includeGuard,
 
66
                                           headerFilename = self.outputFilename))
 
67
        outputFile.write(self.template.text)
 
68
        outputFile.write(HeaderFile.FOOTER_TPL.format(includeGuard = includeGuard))
 
69
        outputFile.close()
 
70
 
 
71
class CFile:
 
72
    FILE_TPL="""
 
73
#define TRACEPOINT_CREATE_PROBES
 
74
/*
 
75
 * The header containing our TRACEPOINT_EVENTs.
 
76
 */
 
77
#define TRACEPOINT_DEFINE
 
78
#include "{headerFilename}"
 
79
"""
 
80
    def __init__(self, filename, template):
 
81
        self.outputFilename = filename
 
82
        self.template = template
 
83
 
 
84
    def write(self):
 
85
        outputFile = open(self.outputFilename,"w")
 
86
 
 
87
        headerFilename = self.outputFilename.replace(".c",".h")
 
88
 
 
89
        outputFile.write(CFile.FILE_TPL.format(
 
90
                                           headerFilename = headerFilename))
 
91
        outputFile.close()
 
92
 
 
93
class TemplateFile:
 
94
    def __init__(self, filename):
 
95
        self.domain = ""
 
96
        self.inputFilename = filename
 
97
        self.parseTemplate()
 
98
 
 
99
 
 
100
    def parseTemplate(self):
 
101
        f = open(self.inputFilename,"r")
 
102
 
 
103
        self.text = f.read()
 
104
 
 
105
        #Remove # comments (from input and output file
 
106
        self.text = re.sub("#.*$","",self.text,flags=re.MULTILINE)
 
107
        #Remove // comments
 
108
        nolinecomment = re.sub("\/\/.*$","",self.text,flags=re.MULTILINE)
 
109
        #Remove all spaces and lines
 
110
        cleantext = re.sub("\s*","",nolinecomment)
 
111
        #Remove multine C style comments
 
112
        nocomment = re.sub("/\*.*?\*/","",cleantext)
 
113
        entries = re.split("TRACEPOINT_.*?",nocomment)
 
114
 
 
115
        for entry in entries:
 
116
            if entry != '':
 
117
                decomp = re.findall("(\w*?)\((\w*?),(\w*?),", entry)
 
118
                typea = decomp[0][0]
 
119
                domain = decomp[0][1]
 
120
                name = decomp[0][2]
 
121
 
 
122
                if self.domain == "":
 
123
                    self.domain = domain
 
124
                else:
 
125
                    if self.domain != domain:
 
126
                        print "Warning: different domain provided (%s,%s)" % (self.domain, domain)
 
127
 
 
128
usage="""
 
129
 lttng-gen-tp - Generate the LTTng-UST header and source based on a simple template
 
130
 
 
131
 usage: lttng-gen-tp TEMPLATE_FILE [-o OUTPUT_FILE][-o OUTPUT_FILE]
 
132
 
 
133
 If no OUTPUT_FILE is given, the .h and .c file will be generated.
 
134
 (The basename of the template file with be used for the generated file.
 
135
  for example sample.tp will generate sample.h and sample.c)
 
136
 
 
137
 When using the -o option, the OUTPUT_FILE must end with either .h or .c
 
138
 The -o option can be repeated multiple times.
 
139
 
 
140
 The template file must contains TRACEPOINT_EVENT and TRACEPOINT_LOGLEVEL
 
141
 as per defined in the lttng/tracepoint.h file.
 
142
 See the lttng-ust(3) man page for more details on the format.
 
143
"""
 
144
def main(argv=None):
 
145
    if argv is None:
 
146
        argv = sys.argv
 
147
 
 
148
    try:
 
149
        try:
 
150
            opts, args = getopt.gnu_getopt(argv[1:], "ho:a", ["help"])
 
151
        except getopt.error, msg:
 
152
             raise Usage(msg)
 
153
 
 
154
    except Usage, err:
 
155
        print >>sys.stderr, err.msg
 
156
        print >>sys.stderr, "for help use --help"
 
157
        return 2
 
158
 
 
159
    outputNames = []
 
160
    for o, a in opts:
 
161
        if o in ("-h", "--help"):
 
162
            print usage
 
163
            return(0)
 
164
        if o in ("-o",""):
 
165
            outputNames.append(a)
 
166
        if o in ("-a",""):
 
167
            all = True
 
168
 
 
169
    doCFile = None
 
170
    doHeader = None
 
171
    headerFilename = None
 
172
    cFilename = None
 
173
 
 
174
    if len(outputNames) > 0:
 
175
        if len(args) > 1:
 
176
            print "Cannot process more than one input if you specify an output"
 
177
            return(3)
 
178
 
 
179
        for outputName in outputNames:
 
180
            if outputName[-2:] == ".h":
 
181
                doHeader = True
 
182
                headerFilename = outputName
 
183
            elif outputName[-2:] == ".c":
 
184
                doCFile = True
 
185
                cFilename = outputName
 
186
            elif outputName[-2:] == ".o":
 
187
                print "Not yet implemented, sorry"
 
188
            else:
 
189
                print "output file type unsupported"
 
190
                return(4)
 
191
    else:
 
192
        doHeader = True
 
193
        doCFile = True
 
194
 
 
195
    # process arguments
 
196
    for arg in args:
 
197
 
 
198
        tpl = TemplateFile(arg)
 
199
        if doHeader:
 
200
            if headerFilename:
 
201
                curFilename = headerFilename
 
202
            else:
 
203
                curFilename = re.sub("\.tp$",".h",arg)
 
204
            doth = HeaderFile(curFilename, tpl)
 
205
            doth.write()
 
206
        if doCFile:
 
207
            if cFilename:
 
208
                curFilename = cFilename
 
209
            else:
 
210
                curFilename = re.sub("\.tp$",".c",arg)
 
211
            dotc = CFile(curFilename, tpl)
 
212
            dotc.write()
 
213
 
 
214
if __name__ == "__main__":
 
215
    sys.exit(main())