Statistics
| Branch: | Revision:

root / tracetool @ 22890ab5

History | View | Annotate | Download (4 kB)

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
16
usage: $0 [--nop | --simple] [-h | -c]
17
Generate tracing code for a file on stdin.
18

    
19
Backends:
20
  --nop     Tracing disabled
21
  --simple  Simple built-in backend
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

    
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

    
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

    
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
    cat <<EOF
173
#define NR_TRACE_EVENTS $simple_event_num
174
extern TraceEvent trace_list[NR_TRACE_EVENTS];
175
EOF
176
}
177

    
178
linetoc_begin_simple()
179
{
180
    cat <<EOF
181
#include "trace.h"
182

    
183
TraceEvent trace_list[] = {
184
EOF
185
    simple_event_num=0
186

    
187
}
188

    
189
linetoc_simple()
190
{
191
    local name
192
    name=$(get_name "$1")
193
    cat <<EOF
194
{.tp_name = "$name", .state=0},
195
EOF
196
    simple_event_num=$((simple_event_num + 1))
197
}
198

    
199
linetoc_end_simple()
200
{
201
    cat <<EOF
202
};
203
EOF
204
}
205

    
206
# Process stdin by calling begin, line, and end functions for the backend
207
convert()
208
{
209
    local begin process_line end
210
    begin="lineto$1_begin_$backend"
211
    process_line="lineto$1_$backend"
212
    end="lineto$1_end_$backend"
213

    
214
    "$begin"
215

    
216
    while read -r str; do
217
        # Skip comments and empty lines
218
        str=${str%%#*}
219
        test -z "$str" && continue
220

    
221
        echo
222
        "$process_line" "$str"
223
    done
224

    
225
    echo
226
    "$end"
227
}
228

    
229
tracetoh()
230
{
231
    cat <<EOF
232
#ifndef TRACE_H
233
#define TRACE_H
234

    
235
/* This file is autogenerated by tracetool, do not edit. */
236

    
237
#include "qemu-common.h"
238
EOF
239
    convert h
240
    echo "#endif /* TRACE_H */"
241
}
242

    
243
tracetoc()
244
{
245
    echo "/* This file is autogenerated by tracetool, do not edit. */"
246
    convert c
247
}
248

    
249
# Choose backend
250
case "$1" in
251
"--nop" | "--simple") backend="${1#--}" ;;
252
*) usage ;;
253
esac
254
shift
255

    
256
case "$1" in
257
"-h") tracetoh ;;
258
"-c") tracetoc ;;
259
"--check-backend") exit 0 ;; # used by ./configure to test for backend
260
*) usage ;;
261
esac
262

    
263
exit 0