1 #
2 # Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
3 #
4
5 #
6 # This script scans the exacct header files and extracts the names of any
7 # #defines that are to be exported by the Exacct modules. All such #defines
8 # are written out as an array of structs to a file which is subsequently
9 # included into the module. Parameters to this script are the name of the
10 # module to generate for, and the output file to use.
11 #
12
13 use warnings;
14 use strict;
15
16 # Forward declarations
17 sub default_typefn;
18 sub catalog_typefn;
19
20 #
21 # Map of module names to files and lists + patterns of macros to declare.
22 # Each entry in the hash is keyed by the module name, and the value of each
23 # entry is a list of actions, where each action is a (keyword, param) pair.
24 # The valid actions are:
25 # typefn => <fn_ptr>
26 # fn_ptr is a function which when given a constant name,
27 # returns the type - see default_typefn and catalog_typefn.
28 # declare => [ <constant>, ... ]
29 # Add the passed list of constants.
30 # scan => [ <file> <regular expression> ]
31 # Scan the specified file in /usr/include
32 # for #defines that match the passed RE.
33 #
34 our %ModMap = (
35 Exacct => [
36 typefn => \&default_typefn,
37 declare => [ qw(P_PID P_TASKID P_PROJID) ],
38 scan => [ 'sys/exacct.h' =>
39 qr/(?:EW|EP|EXR)_\w+/ ],
40 ],
41 Catalog => [
42 typefn => \&catalog_typefn,
43 scan => [ 'sys/exacct_catalog.h' =>
44 qr/EX[TCD]_\w+/ ],
45 ],
46 File => [
47 typefn => \&default_typefn,
48 # From exacct.h.
49 declare => [ qw(EO_HEAD EO_TAIL EO_NO_VALID_HDR
50 EO_POSN_MSK EO_VALIDATE_MSK) ],
51 ],
52 Object => [
53 typefn => \&default_typefn,
54 # From sys/exacct.h.
55 declare => [ qw(EO_ERROR EO_NONE EO_ITEM EO_GROUP) ],
56 ],
57 );
58
59 #
60 # Constants may have a 'type' associated, currently only used by ::Catalog
61 # (see below). For all other cases the type is 'other'.
62 #
63 sub default_typefn
64 {
65 return('other');
66 }
67
68 #
69 # ::Catalog uses the 'type' field to determine whether a given constant is a
70 # type, a catalog or a data id. This function works out what type of constant
71 # has been passed and returns the appropriate type.
72 #
73 sub catalog_typefn
74 {
75 my ($define) = @_;
76 if ($define =~ /_MASK$/) {
77 return('other');
78 } elsif ($define =~ /^EXT_/) {
79 return('type');
80 } elsif ($define =~ /^EXC_/) {
81 return('catlg');
82 } elsif ($define =~ /^EXD_/) {
83 return('id');
84 } else {
85 return('other');
86 }
87 }
88
89 #
90 # Process a C header file, looking for #defines of interest. Candidates are
91 # saved in the $defines arrayref. Note nested includes are not processed.
92 #
93 sub process_file
94 {
95 my ($file, $filelist, $pattern, $typefn, $defines) = @_;
96 my $fh;
97 if ($_ = (grep(m{/$file$}, @$filelist))[0]) {
98 open($fh, '<', $_) || die("Can't open $_: $!\n");
99 } else {
100 die("Can't find $file\n");
101 }
102 my $line;
103 while (defined($line = <$fh>)) {
104 if ($line =~ /#define\s+\b($pattern)\b/) {
105 $defines->{$1} = &$typefn($1);
106 }
107 }
108 close($fh);
109 }
110
111 #
112 # Main routine.
113 #
114
115 # Check arguments and open the output file.
116 die("Usage is extract_defines <module> <output file> <input files...>\n")
117 unless (@ARGV >= 2);
118 my ($module, $outfile, @filelist) = @ARGV;
119 my $mm;
120 if (! defined($mm = $ModMap{$module})) {
121 die("Don't know how to handle module $module\n")
122 }
123 my $out;
124 if (! open($out, ">$outfile")) {
125 die("Can't open $outfile: $!\n");
126 }
127
128 # Perform the appropriate set of actions from ModMap for the specified module.
129 my $defines = {};
130 my $tfn = \&default_typefn;
131 my $i = 0;
132 while ($i < @$mm) {
133 my $act = $$mm[$i++];
134 my $parm = $$mm[$i++];
135 if ($act eq 'typefn') {
136 $tfn = $parm;
137 } elsif ($act eq 'declare') {
138 foreach my $d (@$parm) {
139 $defines->{$d} = &$tfn($d);
140 }
141 } elsif ($act eq 'scan') {
142 process_file($parm->[0], \@filelist, $parm->[1], $tfn,
143 $defines);
144 } else {
145 die("Illegal action $act\n");
146 }
147 }
148
149 # Print the structure definition.
150 print $out ("static constval_t constants[] = {\n");
151 foreach my $def (sort(keys(%$defines))) {
152 my $type = $defines->{$def};
153 my $len = length($def);
154 my $t = "\t" . "\t" x (3 - int(($len + 3) / 8));
155 print $out ("\t\"$def\",$t$len,\t$type,\n\t (unsigned int) $def,\n");
156 }
157 print $out ("\tNULL,\t\t\t\t0,\tother,\n\t 0,\n};\n");
158 close($out);
159 exit(0);