]>
Commit | Line | Data |
---|---|---|
94a420b1 SH |
1 | #!/bin/sh |
2 | # | |
3 | # Code generator for trace events | |
4 | # | |
5 | # Copyright IBM, Corp. 2010 | |
6 | # | |
7 | # This work is licensed under the terms of the GNU GPL, version 2. See | |
8 | # the COPYING file in the top-level directory. | |
9 | ||
10 | # Disable pathname expansion, makes processing text with '*' characters simpler | |
11 | set -f | |
12 | ||
13 | usage() | |
14 | { | |
15 | cat >&2 <<EOF | |
26f7227b | 16 | usage: $0 [--nop | --simple] [-h | -c] |
94a420b1 SH |
17 | Generate tracing code for a file on stdin. |
18 | ||
19 | Backends: | |
26f7227b SH |
20 | --nop Tracing disabled |
21 | --simple Simple built-in backend | |
94a420b1 SH |
22 | |
23 | Output formats: | |
24 | -h Generate .h file | |
25 | -c Generate .c file | |
26 | EOF | |
27 | exit 1 | |
28 | } | |
29 | ||
30 | # Get the name of a trace event | |
31 | get_name() | |
32 | { | |
33 | echo ${1%%\(*} | |
34 | } | |
35 | ||
36 | # Get the argument list of a trace event, including types and names | |
37 | get_args() | |
38 | { | |
39 | local args | |
40 | args=${1#*\(} | |
41 | args=${args%)*} | |
42 | echo "$args" | |
43 | } | |
44 | ||
45 | # Get the argument name list of a trace event | |
46 | get_argnames() | |
47 | { | |
48 | local nfields field name | |
49 | nfields=0 | |
50 | for field in $(get_args "$1"); do | |
51 | nfields=$((nfields + 1)) | |
52 | ||
53 | # Drop pointer star | |
54 | field=${field#\*} | |
55 | ||
56 | # Only argument names have commas at the end | |
57 | name=${field%,} | |
58 | test "$field" = "$name" && continue | |
59 | ||
60 | printf "%s" "$name, " | |
61 | done | |
62 | ||
63 | # Last argument name | |
64 | if [ "$nfields" -gt 1 ] | |
65 | then | |
66 | printf "%s" "$name" | |
67 | fi | |
68 | } | |
69 | ||
26f7227b SH |
70 | # Get the number of arguments to a trace event |
71 | get_argc() | |
72 | { | |
73 | local name argc | |
74 | argc=0 | |
75 | for name in $(get_argnames "$1"); do | |
76 | argc=$((argc + 1)) | |
77 | done | |
78 | echo $argc | |
79 | } | |
80 | ||
94a420b1 SH |
81 | # Get the format string for a trace event |
82 | get_fmt() | |
83 | { | |
84 | local fmt | |
85 | fmt=${1#*\"} | |
86 | fmt=${fmt%\"*} | |
87 | echo "$fmt" | |
88 | } | |
89 | ||
90 | linetoh_begin_nop() | |
91 | { | |
92 | return | |
93 | } | |
94 | ||
95 | linetoh_nop() | |
96 | { | |
97 | local name args | |
98 | name=$(get_name "$1") | |
99 | args=$(get_args "$1") | |
100 | ||
101 | # Define an empty function for the trace event | |
102 | cat <<EOF | |
103 | static inline void trace_$name($args) | |
104 | { | |
105 | } | |
106 | EOF | |
107 | } | |
108 | ||
109 | linetoh_end_nop() | |
110 | { | |
111 | return | |
112 | } | |
113 | ||
114 | linetoc_begin_nop() | |
115 | { | |
116 | return | |
117 | } | |
118 | ||
119 | linetoc_nop() | |
120 | { | |
121 | # No need for function definitions in nop backend | |
122 | return | |
123 | } | |
124 | ||
125 | linetoc_end_nop() | |
126 | { | |
127 | return | |
128 | } | |
129 | ||
26f7227b SH |
130 | linetoh_begin_simple() |
131 | { | |
132 | cat <<EOF | |
133 | #include "simpletrace.h" | |
134 | EOF | |
135 | ||
136 | simple_event_num=0 | |
137 | } | |
138 | ||
139 | cast_args_to_uint64_t() | |
140 | { | |
141 | local arg | |
142 | for arg in $(get_argnames "$1"); do | |
143 | printf "%s" "(uint64_t)(uintptr_t)$arg" | |
144 | done | |
145 | } | |
146 | ||
147 | linetoh_simple() | |
148 | { | |
149 | local name args argc trace_args | |
150 | name=$(get_name "$1") | |
151 | args=$(get_args "$1") | |
152 | argc=$(get_argc "$1") | |
153 | ||
154 | trace_args="$simple_event_num" | |
155 | if [ "$argc" -gt 0 ] | |
156 | then | |
157 | trace_args="$trace_args, $(cast_args_to_uint64_t "$1")" | |
158 | fi | |
159 | ||
160 | cat <<EOF | |
161 | static inline void trace_$name($args) | |
162 | { | |
163 | trace$argc($trace_args); | |
164 | } | |
165 | EOF | |
166 | ||
167 | simple_event_num=$((simple_event_num + 1)) | |
168 | } | |
169 | ||
170 | linetoh_end_simple() | |
171 | { | |
172 | return | |
173 | } | |
174 | ||
175 | linetoc_begin_simple() | |
176 | { | |
177 | return | |
178 | } | |
179 | ||
180 | linetoc_simple() | |
181 | { | |
182 | return | |
183 | } | |
184 | ||
185 | linetoc_end_simple() | |
186 | { | |
187 | return | |
188 | } | |
189 | ||
94a420b1 SH |
190 | # Process stdin by calling begin, line, and end functions for the backend |
191 | convert() | |
192 | { | |
193 | local begin process_line end | |
194 | begin="lineto$1_begin_$backend" | |
195 | process_line="lineto$1_$backend" | |
196 | end="lineto$1_end_$backend" | |
197 | ||
198 | "$begin" | |
199 | ||
200 | while read -r str; do | |
201 | # Skip comments and empty lines | |
202 | str=${str%%#*} | |
203 | test -z "$str" && continue | |
204 | ||
205 | echo | |
206 | "$process_line" "$str" | |
207 | done | |
208 | ||
209 | echo | |
210 | "$end" | |
211 | } | |
212 | ||
213 | tracetoh() | |
214 | { | |
215 | cat <<EOF | |
216 | #ifndef TRACE_H | |
217 | #define TRACE_H | |
218 | ||
219 | /* This file is autogenerated by tracetool, do not edit. */ | |
220 | ||
221 | #include "qemu-common.h" | |
222 | EOF | |
223 | convert h | |
224 | echo "#endif /* TRACE_H */" | |
225 | } | |
226 | ||
227 | tracetoc() | |
228 | { | |
229 | echo "/* This file is autogenerated by tracetool, do not edit. */" | |
230 | convert c | |
231 | } | |
232 | ||
233 | # Choose backend | |
234 | case "$1" in | |
26f7227b | 235 | "--nop" | "--simple") backend="${1#--}" ;; |
94a420b1 SH |
236 | *) usage ;; |
237 | esac | |
238 | shift | |
239 | ||
240 | case "$1" in | |
241 | "-h") tracetoh ;; | |
242 | "-c") tracetoc ;; | |
243 | "--check-backend") exit 0 ;; # used by ./configure to test for backend | |
244 | *) usage ;; | |
245 | esac | |
246 | ||
247 | exit 0 |