wmi-1.3.16 from opsview.com
This commit is contained in:
@@ -0,0 +1,407 @@
|
||||
###################################################
|
||||
# create C header files for an IDL structure
|
||||
# Copyright tridge@samba.org 2000
|
||||
# Copyright jelmer@samba.org 2005
|
||||
# released under the GNU GPL
|
||||
|
||||
package Parse::Pidl::Samba4::Header;
|
||||
|
||||
use strict;
|
||||
use Parse::Pidl::Typelist qw(mapType);
|
||||
use Parse::Pidl::Util qw(has_property is_constant);
|
||||
use Parse::Pidl::NDR qw(GetNextLevel GetPrevLevel);
|
||||
use Parse::Pidl::Samba4 qw(is_intree);
|
||||
|
||||
use vars qw($VERSION);
|
||||
$VERSION = '0.01';
|
||||
|
||||
my($res);
|
||||
my($tab_depth);
|
||||
|
||||
sub pidl($) { $res .= shift; }
|
||||
|
||||
sub tabs()
|
||||
{
|
||||
my $res = "";
|
||||
$res .="\t" foreach (1..$tab_depth);
|
||||
return $res;
|
||||
}
|
||||
|
||||
#####################################################################
|
||||
# parse a properties list
|
||||
sub HeaderProperties($$)
|
||||
{
|
||||
my($props,$ignores) = @_;
|
||||
my $ret = "";
|
||||
|
||||
foreach my $d (keys %{$props}) {
|
||||
next if (grep(/^$d$/, @$ignores));
|
||||
if($props->{$d} ne "1") {
|
||||
$ret.= "$d($props->{$d}),";
|
||||
} else {
|
||||
$ret.="$d,";
|
||||
}
|
||||
}
|
||||
|
||||
if ($ret) {
|
||||
pidl "/* [" . substr($ret, 0, -1) . "] */";
|
||||
}
|
||||
}
|
||||
|
||||
#####################################################################
|
||||
# parse a structure element
|
||||
sub HeaderElement($)
|
||||
{
|
||||
my($element) = shift;
|
||||
|
||||
pidl tabs();
|
||||
if (has_property($element, "represent_as")) {
|
||||
pidl mapType($element->{PROPERTIES}->{represent_as})." ";
|
||||
} else {
|
||||
HeaderType($element, $element->{TYPE}, "");
|
||||
pidl " ";
|
||||
my $numstar = $element->{POINTERS};
|
||||
if ($numstar >= 1) {
|
||||
$numstar-- if Parse::Pidl::Typelist::scalar_is_reference($element->{TYPE});
|
||||
}
|
||||
foreach (@{$element->{ARRAY_LEN}})
|
||||
{
|
||||
next if is_constant($_) and
|
||||
not has_property($element, "charset");
|
||||
$numstar++;
|
||||
}
|
||||
pidl "*" foreach (1..$numstar);
|
||||
}
|
||||
pidl $element->{NAME};
|
||||
foreach (@{$element->{ARRAY_LEN}}) {
|
||||
next unless (is_constant($_) and
|
||||
not has_property($element, "charset"));
|
||||
pidl "[$_]";
|
||||
}
|
||||
|
||||
pidl ";";
|
||||
if (defined $element->{PROPERTIES}) {
|
||||
HeaderProperties($element->{PROPERTIES}, ["in", "out"]);
|
||||
}
|
||||
pidl "\n";
|
||||
}
|
||||
|
||||
#####################################################################
|
||||
# parse a struct
|
||||
sub HeaderStruct($$)
|
||||
{
|
||||
my($struct,$name) = @_;
|
||||
pidl "struct $name {\n";
|
||||
$tab_depth++;
|
||||
my $el_count=0;
|
||||
if (defined $struct->{ELEMENTS}) {
|
||||
foreach (@{$struct->{ELEMENTS}}) {
|
||||
HeaderElement($_);
|
||||
$el_count++;
|
||||
}
|
||||
}
|
||||
if ($el_count == 0) {
|
||||
# some compilers can't handle empty structures
|
||||
pidl tabs()."char _empty_;\n";
|
||||
}
|
||||
$tab_depth--;
|
||||
pidl tabs()."}";
|
||||
if (defined $struct->{PROPERTIES}) {
|
||||
HeaderProperties($struct->{PROPERTIES}, []);
|
||||
}
|
||||
}
|
||||
|
||||
#####################################################################
|
||||
# parse a enum
|
||||
sub HeaderEnum($$)
|
||||
{
|
||||
my($enum,$name) = @_;
|
||||
my $first = 1;
|
||||
|
||||
if (not Parse::Pidl::Util::useUintEnums()) {
|
||||
pidl "enum $name {\n";
|
||||
$tab_depth++;
|
||||
foreach my $e (@{$enum->{ELEMENTS}}) {
|
||||
unless ($first) { pidl ",\n"; }
|
||||
$first = 0;
|
||||
pidl tabs();
|
||||
pidl $e;
|
||||
}
|
||||
pidl "\n";
|
||||
$tab_depth--;
|
||||
pidl "}";
|
||||
} else {
|
||||
my $count = 0;
|
||||
pidl "enum $name { __donnot_use_enum_$name=0x7FFFFFFF};\n";
|
||||
my $with_val = 0;
|
||||
my $without_val = 0;
|
||||
foreach my $e (@{$enum->{ELEMENTS}}) {
|
||||
my $t = "$e";
|
||||
my $name;
|
||||
my $value;
|
||||
if ($t =~ /(.*)=(.*)/) {
|
||||
$name = $1;
|
||||
$value = $2;
|
||||
$with_val = 1;
|
||||
die ("you can't mix enum member with values and without values when using --uint-enums!")
|
||||
unless ($without_val == 0);
|
||||
} else {
|
||||
$name = $t;
|
||||
$value = $count++;
|
||||
$without_val = 1;
|
||||
die ("you can't mix enum member with values and without values when using --uint-enums!")
|
||||
unless ($with_val == 0);
|
||||
}
|
||||
pidl "#define $name ( $value )\n";
|
||||
}
|
||||
pidl "\n";
|
||||
}
|
||||
}
|
||||
|
||||
#####################################################################
|
||||
# parse a bitmap
|
||||
sub HeaderBitmap($$)
|
||||
{
|
||||
my($bitmap,$name) = @_;
|
||||
|
||||
pidl "/* bitmap $name */\n";
|
||||
pidl "#define $_\n" foreach (@{$bitmap->{ELEMENTS}});
|
||||
pidl "\n";
|
||||
}
|
||||
|
||||
#####################################################################
|
||||
# parse a union
|
||||
sub HeaderUnion($$)
|
||||
{
|
||||
my($union,$name) = @_;
|
||||
my %done = ();
|
||||
|
||||
pidl "union $name {\n";
|
||||
$tab_depth++;
|
||||
foreach my $e (@{$union->{ELEMENTS}}) {
|
||||
if ($e->{TYPE} ne "EMPTY") {
|
||||
if (! defined $done{$e->{NAME}}) {
|
||||
HeaderElement($e);
|
||||
}
|
||||
$done{$e->{NAME}} = 1;
|
||||
}
|
||||
}
|
||||
$tab_depth--;
|
||||
pidl "}";
|
||||
|
||||
if (defined $union->{PROPERTIES}) {
|
||||
HeaderProperties($union->{PROPERTIES}, []);
|
||||
}
|
||||
}
|
||||
|
||||
sub decorate($$)
|
||||
{
|
||||
my($name,$levels) = @_;
|
||||
my $prev_ptr = 0;
|
||||
foreach my $i (0..$#{$levels}) {
|
||||
if ($levels->[$i]{TYPE} eq "POINTER") {
|
||||
$name = "*$name";
|
||||
$prev_ptr = 1;
|
||||
} elsif ($levels->[$i]{TYPE} eq "ARRAY") {
|
||||
$name = ($prev_ptr ? "($name)" : $name) . "[$levels->[$i]{SIZE_IS}]";
|
||||
}
|
||||
}
|
||||
$name
|
||||
}
|
||||
|
||||
sub HeaderDecorated($$)
|
||||
{
|
||||
my($e,$name) = @_;
|
||||
$name = $e->{NAME} unless defined($name);
|
||||
pidl "typedef ";
|
||||
if (has_property($e, "charset")) {
|
||||
pidl "const char";
|
||||
} else {
|
||||
pidl mapType($e->{DATA}{DATA_TYPE});
|
||||
}
|
||||
pidl " " . decorate($name, $e->{DATA}{LEVELS});
|
||||
}
|
||||
|
||||
#####################################################################
|
||||
# parse a type
|
||||
sub HeaderType($$$)
|
||||
{
|
||||
my($e,$data,$name) = @_;
|
||||
if (ref($data) eq "HASH") {
|
||||
($data->{TYPE} eq "ENUM") && HeaderEnum($data, $name);
|
||||
($data->{TYPE} eq "BITMAP") && HeaderBitmap($data, $name);
|
||||
($data->{TYPE} eq "STRUCT") && HeaderStruct($data, $name);
|
||||
($data->{TYPE} eq "UNION") && HeaderUnion($data, $name);
|
||||
($data->{TYPE} eq "DECORATED") && HeaderDecorated($e, $name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (has_property($e, "charset") and $e->{TYPEREF}{DATA}{TYPE} ne "DECORATED") {
|
||||
pidl "const char";
|
||||
} else {
|
||||
pidl mapType($e->{TYPE});
|
||||
}
|
||||
}
|
||||
|
||||
#####################################################################
|
||||
# parse a typedef
|
||||
sub HeaderTypedef($)
|
||||
{
|
||||
my($typedef) = shift;
|
||||
HeaderType($typedef, $typedef->{DATA}, $typedef->{NAME});
|
||||
pidl ";\n\n" unless ($typedef->{DATA}->{TYPE} eq "BITMAP");
|
||||
}
|
||||
|
||||
#####################################################################
|
||||
# parse a const
|
||||
sub HeaderConst($)
|
||||
{
|
||||
my($const) = shift;
|
||||
if (!defined($const->{ARRAY_LEN}[0])) {
|
||||
pidl "#define $const->{NAME}\t( $const->{VALUE} )\n";
|
||||
} else {
|
||||
pidl "#define $const->{NAME}\t $const->{VALUE}\n";
|
||||
}
|
||||
}
|
||||
|
||||
#####################################################################
|
||||
# parse a function
|
||||
sub HeaderFunctionInOut($$)
|
||||
{
|
||||
my($fn,$prop) = @_;
|
||||
|
||||
foreach (@{$fn->{ELEMENTS}}) {
|
||||
HeaderElement($_) if (has_property($_, $prop));
|
||||
}
|
||||
}
|
||||
|
||||
#####################################################################
|
||||
# determine if we need an "in" or "out" section
|
||||
sub HeaderFunctionInOut_needed($$)
|
||||
{
|
||||
my($fn,$prop) = @_;
|
||||
|
||||
return 1 if ($prop eq "out" && $fn->{RETURN_TYPE} ne "void");
|
||||
|
||||
foreach (@{$fn->{ELEMENTS}}) {
|
||||
return 1 if (has_property($_, $prop));
|
||||
}
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
my %headerstructs;
|
||||
|
||||
#####################################################################
|
||||
# parse a function
|
||||
sub HeaderFunction($)
|
||||
{
|
||||
my($fn) = shift;
|
||||
|
||||
return if ($headerstructs{$fn->{NAME}});
|
||||
|
||||
$headerstructs{$fn->{NAME}} = 1;
|
||||
|
||||
pidl "\nstruct $fn->{NAME} {\n";
|
||||
$tab_depth++;
|
||||
my $needed = 0;
|
||||
|
||||
if (HeaderFunctionInOut_needed($fn, "in")) {
|
||||
pidl tabs()."struct {\n";
|
||||
$tab_depth++;
|
||||
HeaderFunctionInOut($fn, "in");
|
||||
$tab_depth--;
|
||||
pidl tabs()."} in;\n\n";
|
||||
$needed++;
|
||||
}
|
||||
|
||||
if (HeaderFunctionInOut_needed($fn, "out")) {
|
||||
pidl tabs()."struct {\n";
|
||||
$tab_depth++;
|
||||
HeaderFunctionInOut($fn, "out");
|
||||
if ($fn->{RETURN_TYPE} ne "void") {
|
||||
pidl tabs().mapType($fn->{RETURN_TYPE}) . " result;\n";
|
||||
}
|
||||
$tab_depth--;
|
||||
pidl tabs()."} out;\n\n";
|
||||
$needed++;
|
||||
}
|
||||
|
||||
if (! $needed) {
|
||||
# sigh - some compilers don't like empty structures
|
||||
pidl tabs()."int _dummy_element;\n";
|
||||
}
|
||||
|
||||
$tab_depth--;
|
||||
pidl "};\n\n";
|
||||
}
|
||||
|
||||
sub HeaderImport
|
||||
{
|
||||
my @imports = @_;
|
||||
foreach (@imports) {
|
||||
s/\.idl\"$//;
|
||||
s/^\"//;
|
||||
pidl "#include \"librpc/gen_ndr/$_\.h\"\n";
|
||||
}
|
||||
}
|
||||
|
||||
sub HeaderInclude
|
||||
{
|
||||
my @includes = @_;
|
||||
foreach (@includes) {
|
||||
pidl "#include $_\n";
|
||||
}
|
||||
}
|
||||
|
||||
#####################################################################
|
||||
# parse the interface definitions
|
||||
sub HeaderInterface($)
|
||||
{
|
||||
my($interface) = shift;
|
||||
|
||||
pidl "#ifndef _HEADER_$interface->{NAME}\n";
|
||||
pidl "#define _HEADER_$interface->{NAME}\n\n";
|
||||
|
||||
foreach my $d (@{$interface->{DATA}}) {
|
||||
next if ($d->{TYPE} ne "CONST");
|
||||
HeaderConst($d);
|
||||
}
|
||||
|
||||
foreach my $d (@{$interface->{DATA}}) {
|
||||
next if ($d->{TYPE} ne "TYPEDEF");
|
||||
HeaderTypedef($d);
|
||||
}
|
||||
|
||||
foreach my $d (@{$interface->{DATA}}) {
|
||||
next if ($d->{TYPE} ne "FUNCTION");
|
||||
|
||||
HeaderFunction($d);
|
||||
}
|
||||
|
||||
pidl "#endif /* _HEADER_$interface->{NAME} */\n";
|
||||
}
|
||||
|
||||
#####################################################################
|
||||
# parse a parsed IDL into a C header
|
||||
sub Parse($)
|
||||
{
|
||||
my($idl) = shift;
|
||||
$tab_depth = 0;
|
||||
|
||||
$res = "";
|
||||
%headerstructs = ();
|
||||
pidl "/* header auto-generated by pidl */\n\n";
|
||||
if (!is_intree()) {
|
||||
pidl "#include <core.h>\n\n";
|
||||
}
|
||||
|
||||
foreach (@{$idl}) {
|
||||
($_->{TYPE} eq "INTERFACE") && HeaderInterface($_);
|
||||
($_->{TYPE} eq "IMPORT") && HeaderImport(@{$_->{PATHS}});
|
||||
($_->{TYPE} eq "INCLUDE") && HeaderInclude(@{$_->{PATHS}});
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
1;
|
||||
Reference in New Issue
Block a user