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 13use warnings; 14use strict; 15 16# Forward declarations 17sub default_typefn; 18sub 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# 34our %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# 63sub 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# 73sub 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# 93sub 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. 116die("Usage is extract_defines <module> <output file> <input files...>\n") 117 unless (@ARGV >= 2); 118my ($module, $outfile, @filelist) = @ARGV; 119my $mm; 120if (! defined($mm = $ModMap{$module})) { 121 die("Don't know how to handle module $module\n") 122} 123my $out; 124if (! 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. 129my $defines = {}; 130my $tfn = \&default_typefn; 131my $i = 0; 132while ($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. 150print $out ("static constval_t constants[] = {\n"); 151foreach 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} 157print $out ("\tNULL,\t\t\t\t0,\tother,\n\t 0,\n};\n"); 158close($out); 159exit(0); 160