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);