295 lines
5.8 KiB
Perl
295 lines
5.8 KiB
Perl
###################################################
|
|
# dump function for IDL structures
|
|
# Copyright tridge@samba.org 2000
|
|
# Copyright jelmer@samba.org 2005
|
|
# released under the GNU GPL
|
|
|
|
=pod
|
|
|
|
=head1 NAME
|
|
|
|
Parse::Pidl::Dump - Dump support
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
This module provides functions that can generate IDL code from
|
|
internal pidl data structures.
|
|
|
|
=cut
|
|
|
|
package Parse::Pidl::Dump;
|
|
|
|
use Exporter;
|
|
|
|
use vars qw($VERSION);
|
|
$VERSION = '0.01';
|
|
@ISA = qw(Exporter);
|
|
@EXPORT_OK = qw(DumpType DumpTypedef DumpStruct DumpEnum DumpBitmap DumpUnion DumpFunction);
|
|
|
|
use strict;
|
|
use Parse::Pidl::Util qw(has_property);
|
|
|
|
my($res);
|
|
|
|
#####################################################################
|
|
# dump a properties list
|
|
sub DumpProperties($)
|
|
{
|
|
my($props) = shift;
|
|
my $res = "";
|
|
|
|
foreach my $d ($props) {
|
|
foreach my $k (keys %{$d}) {
|
|
if ($k eq "in") {
|
|
$res .= "[in] ";
|
|
next;
|
|
}
|
|
if ($k eq "out") {
|
|
$res .= "[out] ";
|
|
next;
|
|
}
|
|
if ($k eq "ref") {
|
|
$res .= "[ref] ";
|
|
next;
|
|
}
|
|
$res .= "[$k($d->{$k})] ";
|
|
}
|
|
}
|
|
return $res;
|
|
}
|
|
|
|
#####################################################################
|
|
# dump a structure element
|
|
sub DumpElement($)
|
|
{
|
|
my($element) = shift;
|
|
my $res = "";
|
|
|
|
(defined $element->{PROPERTIES}) &&
|
|
($res .= DumpProperties($element->{PROPERTIES}));
|
|
$res .= DumpType($element->{TYPE});
|
|
$res .= " ";
|
|
for my $i (1..$element->{POINTERS}) {
|
|
$res .= "*";
|
|
}
|
|
$res .= "$element->{NAME}";
|
|
foreach (@{$element->{ARRAY_LEN}}) {
|
|
$res .= "[$_]";
|
|
}
|
|
|
|
return $res;
|
|
}
|
|
|
|
#####################################################################
|
|
# dump a struct
|
|
sub DumpStruct($)
|
|
{
|
|
my($struct) = shift;
|
|
my($res);
|
|
|
|
$res .= "struct ";
|
|
if ($struct->{NAME}) {
|
|
$res.="$struct->{NAME} ";
|
|
}
|
|
|
|
$res.="{\n";
|
|
if (defined $struct->{ELEMENTS}) {
|
|
foreach (@{$struct->{ELEMENTS}}) {
|
|
$res .= "\t" . DumpElement($_) . ";\n";
|
|
}
|
|
}
|
|
$res .= "}";
|
|
|
|
return $res;
|
|
}
|
|
|
|
|
|
#####################################################################
|
|
# dump a struct
|
|
sub DumpEnum($)
|
|
{
|
|
my($enum) = shift;
|
|
my($res);
|
|
|
|
$res .= "enum {\n";
|
|
|
|
foreach (@{$enum->{ELEMENTS}}) {
|
|
if (/^([A-Za-z0-9_]+)[ \t]*\((.*)\)$/) {
|
|
$res .= "\t$1 = $2,\n";
|
|
} else {
|
|
$res .= "\t$_,\n";
|
|
}
|
|
}
|
|
|
|
$res.= "}";
|
|
|
|
return $res;
|
|
}
|
|
|
|
#####################################################################
|
|
# dump a struct
|
|
sub DumpBitmap($)
|
|
{
|
|
my($bitmap) = shift;
|
|
my($res);
|
|
|
|
$res .= "bitmap {\n";
|
|
|
|
foreach (@{$bitmap->{ELEMENTS}}) {
|
|
if (/^([A-Za-z0-9_]+)[ \t]*\((.*)\)$/) {
|
|
$res .= "\t$1 = $2,\n";
|
|
} else {
|
|
die ("Bitmap $bitmap->{NAME} has field $_ without proper value");
|
|
}
|
|
}
|
|
|
|
$res.= "}";
|
|
|
|
return $res;
|
|
}
|
|
|
|
|
|
#####################################################################
|
|
# dump a union element
|
|
sub DumpUnionElement($)
|
|
{
|
|
my($element) = shift;
|
|
my($res);
|
|
|
|
if (has_property($element, "default")) {
|
|
$res .= "[default] ;\n";
|
|
} else {
|
|
$res .= "[case($element->{PROPERTIES}->{case})] ";
|
|
$res .= DumpElement($element), if defined($element);
|
|
$res .= ";\n";
|
|
}
|
|
|
|
return $res;
|
|
}
|
|
|
|
#####################################################################
|
|
# dump a union
|
|
sub DumpUnion($)
|
|
{
|
|
my($union) = shift;
|
|
my($res);
|
|
|
|
(defined $union->{PROPERTIES}) &&
|
|
($res .= DumpProperties($union->{PROPERTIES}));
|
|
$res .= "union {\n";
|
|
foreach my $e (@{$union->{ELEMENTS}}) {
|
|
$res .= DumpUnionElement($e);
|
|
}
|
|
$res .= "}";
|
|
|
|
return $res;
|
|
}
|
|
|
|
#####################################################################
|
|
# dump a type
|
|
sub DumpType($)
|
|
{
|
|
my($data) = shift;
|
|
|
|
if (ref($data) eq "HASH") {
|
|
return DumpStruct($data) if ($data->{TYPE} eq "STRUCT");
|
|
return DumpUnion($data) if ($data->{TYPE} eq "UNION");
|
|
return DumpEnum($data) if ($data->{TYPE} eq "ENUM");
|
|
return DumpBitmap($data) if ($data->{TYPE} eq "BITMAP");
|
|
} else {
|
|
return $data;
|
|
}
|
|
}
|
|
|
|
#####################################################################
|
|
# dump a typedef
|
|
sub DumpTypedef($)
|
|
{
|
|
my($typedef) = shift;
|
|
my($res);
|
|
|
|
$res .= "typedef ";
|
|
$res .= DumpType($typedef->{DATA});
|
|
$res .= " $typedef->{NAME};\n\n";
|
|
|
|
return $res;
|
|
}
|
|
|
|
#####################################################################
|
|
# dump a typedef
|
|
sub DumpFunction($)
|
|
{
|
|
my($function) = shift;
|
|
my($first) = 1;
|
|
my($res);
|
|
|
|
$res .= DumpType($function->{RETURN_TYPE});
|
|
$res .= " $function->{NAME}(\n";
|
|
for my $d (@{$function->{ELEMENTS}}) {
|
|
unless ($first) { $res .= ",\n"; } $first = 0;
|
|
$res .= DumpElement($d);
|
|
}
|
|
$res .= "\n);\n\n";
|
|
|
|
return $res;
|
|
}
|
|
|
|
#####################################################################
|
|
# dump a module header
|
|
sub DumpInterfaceProperties($)
|
|
{
|
|
my($header) = shift;
|
|
my($data) = $header->{DATA};
|
|
my($first) = 1;
|
|
my($res);
|
|
|
|
$res .= "[\n";
|
|
foreach my $k (keys %{$data}) {
|
|
$first || ($res .= ",\n"); $first = 0;
|
|
$res .= "$k($data->{$k})";
|
|
}
|
|
$res .= "\n]\n";
|
|
|
|
return $res;
|
|
}
|
|
|
|
#####################################################################
|
|
# dump the interface definitions
|
|
sub DumpInterface($)
|
|
{
|
|
my($interface) = shift;
|
|
my($data) = $interface->{DATA};
|
|
my($res);
|
|
|
|
$res .= DumpInterfaceProperties($interface->{PROPERTIES});
|
|
|
|
$res .= "interface $interface->{NAME}\n{\n";
|
|
foreach my $d (@{$data}) {
|
|
($d->{TYPE} eq "TYPEDEF") &&
|
|
($res .= DumpTypedef($d));
|
|
($d->{TYPE} eq "FUNCTION") &&
|
|
($res .= DumpFunction($d));
|
|
}
|
|
$res .= "}\n";
|
|
|
|
return $res;
|
|
}
|
|
|
|
|
|
#####################################################################
|
|
# dump a parsed IDL structure back into an IDL file
|
|
sub Dump($)
|
|
{
|
|
my($idl) = shift;
|
|
my($res);
|
|
|
|
$res = "/* Dumped by pidl */\n\n";
|
|
foreach my $x (@{$idl}) {
|
|
($x->{TYPE} eq "INTERFACE") &&
|
|
($res .= DumpInterface($x));
|
|
}
|
|
return $res;
|
|
}
|
|
|
|
1;
|