-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathconsts2code
executable file
·108 lines (98 loc) · 3.21 KB
/
consts2code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#! /usr/bin/env perl
###############################################
# Extract PAPI constants from a C header file #
# and convert them to Go code. #
# #
# By Scott Pakin <[email protected]> #
###############################################
use Getopt::Long;
use File::Basename;
use warnings;
use strict;
# Parse the command line.
my $usagestr= "Usage: $0 [--format=<printf_format>] [--comment=<comment>] [--keep=<regex>...] [--ignore=<regex>...] [--[no-]ifdef] <filename.h>\n";
my @in_regexes; # Keep only lines that match all of these regular expressions
my @out_regexes; # Discard lines that match any of these regular expressions
my $comment; # Comment string for block of constants
my $format; # printf format string to output each line; takes two "%s"es
my $ifdef = 1; # If true, keep only lines that aren't #ifdef'd out; falsee=keep all lines
GetOptions("format=s" => \$format,
"comment=s" => \$comment,
"ifdef!" => \$ifdef,
"keep=s" => \@in_regexes,
"ignore=s" => \@out_regexes)
|| die $usagestr;
die $usagestr if $#ARGV < 0;
my $hfilename = $ARGV[0];
# Find the header file by passing it to the C preprocessor. If we
# were given only a header file, output it and exit.
my $full_hfilename;
open(CPP, "echo '#include <$hfilename>' | cpp - |") || die "open: $!\n";
while (my $oneline = <CPP>) {
if ($oneline =~ /\"([^\"]+$hfilename)\"/) {
$full_hfilename = $1;
last;
}
}
close CPP;
die "${0}: cpp failed to find $hfilename\n" if !defined $full_hfilename;
$hfilename = $full_hfilename;
if (!defined $comment || !defined $format) {
print $hfilename, "\n";
exit 0;
}
# Find all commented PAPI_* definitions.
my %def2comment;
open(HFILE, "<$hfilename") || die "open: $!\n";
READCOMMENTS:
while (my $oneline = <HFILE>) {
foreach my $regex (@in_regexes) {
next READCOMMENTS if $oneline !~ $regex;
}
foreach my $regex (@out_regexes) {
next READCOMMENTS if $oneline =~ $regex;
}
next if $oneline !~ m,^(\S*)\s+PAPI_([_A-Z0-9]+)\b.*/\*(?:\*<)?\s*(.*?)\s*\*/,;
$def2comment{$2} = $3;
}
close HFILE;
# Run the .h file through the C preprocessor to filter away
# definitions that are commented out.
if ($ifdef) {
my %all_def2comments = %def2comment;
%def2comment = ();
open(CPP, "cpp -dM $hfilename|") || die "open: $!\n";
READCPPDEFS:
while (my $oneline = <CPP>) {
foreach my $regex (@in_regexes) {
next READCPPDEFS if $oneline !~ $regex;
}
foreach my $regex (@out_regexes) {
next READCPPDEFS if $oneline =~ $regex;
}
next if $oneline !~ m,^(\S*)\s+PAPI_([_A-Z0-9]+)\b,;
next if !defined $all_def2comments{$2};
$def2comment{$2} = $all_def2comments{$2};
}
close CPP || die "close: $!\n";
}
# Write the package contents.
my $hfilebase = basename $hfilename;
open(GOFMT, "|gofmt") || die "open: $!\n";
print GOFMT <<"GO_HEADER";
package papi
/*
This file was generated automatically from $hfilebase.
*/
// #include <papi.h>
import "C"
// $comment
const (
GO_HEADER
;
foreach my $def (sort keys %def2comment) {
printf GOFMT $format, $def, $def;
print GOFMT " // $def2comment{$def}\n";
}
print GOFMT ")\n";
close GOFMT;