4
# Copyright (c) 2008, 2009 Sun Microsystems, Inc.
5
# Use is subject to license terms.
9
# Redistribution and use in source and binary forms, with or without
10
# modification, are permitted provided that the following conditions are met:
12
# * Redistributions of source code must retain the above copyright
13
# notice, this list of conditions and the following disclaimer.
14
# * Redistributions in binary form must reproduce the above copyright
15
# notice, this list of conditions and the following disclaimer in
16
# the documentation and/or other materials provided with the
18
# * Neither the name of the above-listed copyright holders nor the names
19
# of its contributors may be used to endorse or promote products derived
20
# from this software without specific prior written permission.
22
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
23
# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
26
# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
# ident "@(#)dheadgen.pl 1.4 07/06/24 SMI"
37
# DTrace Header Generator
38
# -----------------------
40
# This script is meant to mimic the output of dtrace(1M) with the -h
41
# (headergen) flag on system that lack native support for DTrace. This script
42
# is intended to be integrated into projects that use DTrace's static tracing
43
# facilities (USDT), and invoked as part of the build process to have a
44
# common build process on all target systems. To facilitate this, this script
45
# is licensed under a BSD license. On system with native DTrace support, the
46
# dtrace(1M) command will be invoked to create the full header file; on other
47
# systems, this script will generated a stub header file.
49
# Normally, generated macros take the form PROVIDER_PROBENAME(). It may be
50
# desirable to customize the output of this script and of dtrace(1M) to
51
# tailor the precise macro name. To do this, edit the emit_dtrace() subroutine
52
# to pattern match for the lines you want to customize.
70
# Insert customization here. For example, if you want to change the
71
# name of the macros you may do something like this:
73
# $line =~ s/(\s)[A-Z]+_/\1TRACE_MOZILLA_/;
80
# The remaining code deals with parsing D provider definitions and emitting
81
# the stub header file. There should be no need to edit this absent a bug.
85
# Emit the two relevant macros for each probe in the given provider:
86
# PROVIDER_PROBENAME(<args>)
87
# PROVIDER_PROBENAME_ENABLED() (0)
90
my ($provname, @probes) = @_;
92
$provname = uc($provname);
94
foreach my $probe (@probes) {
95
my $probename = uc($$probe{'name'});
96
my $argc = $$probe{'argc'};
99
$probename =~ s/__/_/g;
101
$line = "#define\t${provname}_${probename}(";
102
for (my $i = 0; $i < $argc; $i++) {
103
$line .= ($i == 0 ? '' : ', ');
109
$line = "#define\t${provname}_${probename}_ENABLED() (0)\n";
119
$filename =~ s/.*\///g;
120
$filename = uc($filename);
121
$filename =~ s/\./_/g;
125
* Generated by dheadgen(1).
128
#ifndef\t_${filename}
129
#define\t_${filename}
141
$filename =~ s/.*\///g;
142
$filename = uc($filename);
143
$filename =~ s/\./_/g;
150
#endif /* _$filename */
155
# Get the next token from the file keeping track of the line number.
162
while (scalar(@tokens) == 0) {
163
if (scalar(@lines) == 0) {
166
die "expected more data at line $lineno";
170
push(@tokens, split(/(\s+|\n|[(){},#;]|\/\*|\*\/)/,
174
$tok = shift(@tokens);
175
next if ($tok eq '');
176
next if ($tok =~ /^[ \t]+$/);
183
# Ignore newlines, comments and typedefs
190
$tok = get_token($eof_ok);
191
return if ($eof_ok && $eof);
192
if ($tok eq "typedef" or $tok =~ /^#/) {
195
last if ($tok eq "\n");
198
} elsif ($tok eq '/*') {
199
while (get_token(0) ne '*/') {
203
} elsif ($tok eq "\n") {
217
while (($tok = next_token(0)) eq "\n") {
221
die "expected '$t' at line $lineno rather than '$tok'" if ($t ne $tok);
227
my $tok = next_token(0);
230
return (@args) if ($tok eq ')');
232
if ($tok eq 'void') {
240
$tok = next_token(0);
241
if ($tok eq ',' || $tok eq ')') {
244
last if ($tok eq ')');
254
die "usage: $0 [-f] <filename.d>\n";
257
usage() if (scalar(@ARGV) < 1);
258
if ($ARGV[0] eq '-f') {
259
usage() if (scalar(@ARGV < 2));
264
usage() if ($infile !~ /(.+)\.d$/);
267
# If the system has native support for DTrace, we'll use that binary instead.
269
if (-x '/usr/sbin/dtrace' && !$force) {
270
open(DTRACE, "-| /usr/sbin/dtrace -C -h -s $infile -o /dev/stdout")
271
or die "can't invoke dtrace(1M)";
282
emit_prologue($infile);
284
open(D, "< $infile") or die "couldn't open $infile";
290
my $tok = next_token(1);
293
if ($newline && $tok eq '#') {
297
last if ($tok eq "\n");
300
} elsif ($tok eq "\n") {
302
} elsif ($tok eq 'provider') {
303
my $provname = next_token(0);
308
$tok = next_token(0);
309
if ($tok eq 'probe') {
310
my $probename = next_token(0);
311
my @args = get_args();
313
next while (next_token(0) ne ';');
316
'name' => $probename,
317
'argc' => scalar(@args)
320
} elsif ($tok eq '}') {
323
emit_provider($provname, @probes);
330
die "syntax error at line $lineno near '$tok'\n";
336
emit_epilogue($infile);