mirror of
https://github.com/samba-team/samba.git
synced 2025-01-26 10:04:02 +03:00
r8910: An initial parser to parse structures in smb_interfaces.h. This will be
used to generate ejs objects for making raw smb calls. Running 'make smb_interfaces' should run the build_smb_interfaces.pl script which at the moment only displays a dump of the parsed data. Const is also not working right now but it's bedtime. (This used to be commit 1be5f55d7f6926bf7266ea72623990f0bb558c94)
This commit is contained in:
parent
6e64a8b40f
commit
e3374bb48d
1200
source4/build/pidl/smb_interfaces.pm
Normal file
1200
source4/build/pidl/smb_interfaces.pm
Normal file
File diff suppressed because it is too large
Load Diff
215
source4/build/pidl/smb_interfaces.yp
Normal file
215
source4/build/pidl/smb_interfaces.yp
Normal file
@ -0,0 +1,215 @@
|
||||
########################
|
||||
# Parse::Yapp parser for a C header file that contains only structures
|
||||
# or unions.
|
||||
|
||||
# Copyright (C) 2005, Tim Potter <tpot@samba.org> released under the
|
||||
# GNU GPL version 2 or later
|
||||
|
||||
################
|
||||
# grammar
|
||||
|
||||
%%
|
||||
|
||||
definitions:
|
||||
definition { [$_[1]] }
|
||||
| definitions definition { push(@{$_[1]}, $_[2]); $_[1] }
|
||||
;
|
||||
|
||||
definition:
|
||||
struct
|
||||
| union
|
||||
| typedef
|
||||
| enum
|
||||
;
|
||||
|
||||
struct: STRUCT optional_identifier '{' elements '}' pointers optional_identifiers ';'
|
||||
{
|
||||
my $name = defined($_[2]) ? $_[2] : $_[7];
|
||||
{
|
||||
"NAME" => $name,
|
||||
"TYPE" => "STRUCT",
|
||||
"DATA" => $_[4],
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
union:
|
||||
UNION optional_identifier '{' elements '}' pointers optional_identifier ';'
|
||||
{
|
||||
my $name = defined($_[2]) ? $_[2] : $_[7];
|
||||
{
|
||||
"NAME" => $name,
|
||||
"TYPE" => "UNION",
|
||||
"DATA" => $_[4],
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
typedef:
|
||||
TYPEDEF STRUCT '{' elements '}' optional_identifier ';'
|
||||
;
|
||||
|
||||
enum:
|
||||
ENUM IDENTIFIER '{' enum_identifiers '}' ';'
|
||||
;
|
||||
|
||||
enum_identifiers: enum_identifier
|
||||
| enum_identifiers ',' enum_identifier
|
||||
;
|
||||
|
||||
enum_identifier: IDENTIFIER
|
||||
| IDENTIFIER '=' IDENTIFIER
|
||||
;
|
||||
|
||||
elements: #empty
|
||||
| elements element { push(@{$_[1]}, $_[2]); $_[1] }
|
||||
;
|
||||
|
||||
element:
|
||||
| struct
|
||||
| union
|
||||
| STRUCT IDENTIFIER pointers IDENTIFIER ';'
|
||||
| UNION IDENTIFIER pointers IDENTIFIER ';'
|
||||
| type pointers IDENTIFIER array ';'
|
||||
{{
|
||||
"NAME" => $_[3],
|
||||
"TYPE" => $_[1],
|
||||
"POINTERS" => $_[2],
|
||||
}}
|
||||
;
|
||||
|
||||
array: #empty
|
||||
| '[' CONSTANT ']'
|
||||
;
|
||||
|
||||
type: IDENTIFIER
|
||||
| ENUM IDENTIFIER
|
||||
;
|
||||
|
||||
pointers:
|
||||
#empty { 0 }
|
||||
| pointers '*' { $_[1]+1 }
|
||||
;
|
||||
|
||||
optional_identifiers: optional_identifier { [$_[1]] }
|
||||
| optional_identifiers ',' optional_identifier { push(@{$_[1]}, $_[3]); $_[1] }
|
||||
;
|
||||
|
||||
optional_identifier: IDENTIFIER | #empty { undef }
|
||||
;
|
||||
|
||||
%%
|
||||
|
||||
#####################################################################
|
||||
# traverse a perl data structure removing any empty arrays or
|
||||
# hashes and any hash elements that map to undef
|
||||
sub CleanData($)
|
||||
{
|
||||
sub CleanData($);
|
||||
my($v) = shift;
|
||||
if (ref($v) eq "ARRAY") {
|
||||
foreach my $i (0 .. $#{$v}) {
|
||||
CleanData($v->[$i]);
|
||||
if (ref($v->[$i]) eq "ARRAY" && $#{$v->[$i]}==-1) {
|
||||
$v->[$i] = undef;
|
||||
next;
|
||||
}
|
||||
}
|
||||
# this removes any undefined elements from the array
|
||||
@{$v} = grep { defined $_ } @{$v};
|
||||
} elsif (ref($v) eq "HASH") {
|
||||
foreach my $x (keys %{$v}) {
|
||||
CleanData($v->{$x});
|
||||
if (!defined $v->{$x}) { delete($v->{$x}); next; }
|
||||
if (ref($v->{$x}) eq "ARRAY" && $#{$v->{$x}}==-1) { delete($v->{$x}); next; }
|
||||
}
|
||||
}
|
||||
return $v;
|
||||
}
|
||||
|
||||
sub _Error {
|
||||
if (exists $_[0]->YYData->{ERRMSG}) {
|
||||
print $_[0]->YYData->{ERRMSG};
|
||||
delete $_[0]->YYData->{ERRMSG};
|
||||
return;
|
||||
};
|
||||
my $line = $_[0]->YYData->{LINE};
|
||||
my $last_token = $_[0]->YYData->{LAST_TOKEN};
|
||||
my $file = $_[0]->YYData->{INPUT_FILENAME};
|
||||
|
||||
print "$file:$line: Syntax error near '$last_token'\n";
|
||||
}
|
||||
|
||||
sub _Lexer($)
|
||||
{
|
||||
my($parser)=shift;
|
||||
|
||||
$parser->YYData->{INPUT} or return('',undef);
|
||||
|
||||
again:
|
||||
$parser->YYData->{INPUT} =~ s/^[ \t]*//;
|
||||
|
||||
for ($parser->YYData->{INPUT}) {
|
||||
if (/^\#/) {
|
||||
if (s/^\# (\d+) \"(.*?)\"( \d+|)//) {
|
||||
$parser->YYData->{LINE} = $1-1;
|
||||
$parser->YYData->{INPUT_FILENAME} = $2;
|
||||
goto again;
|
||||
}
|
||||
if (s/^\#line (\d+) \"(.*?)\"( \d+|)//) {
|
||||
$parser->YYData->{LINE} = $1-1;
|
||||
$parser->YYData->{INPUT_FILENAME} = $2;
|
||||
goto again;
|
||||
}
|
||||
if (s/^(\#.*)$//m) {
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
if (s/^(\n)//) {
|
||||
$parser->YYData->{LINE}++;
|
||||
goto again;
|
||||
}
|
||||
if (s/^\"(.*?)\"//) {
|
||||
$parser->YYData->{LAST_TOKEN} = $1;
|
||||
return('TEXT',$1);
|
||||
}
|
||||
if (s/^(\d+)(\W|$)/$2/) {
|
||||
$parser->YYData->{LAST_TOKEN} = $1;
|
||||
return('CONSTANT',$1);
|
||||
}
|
||||
if (s/^([\w_]+)//) {
|
||||
$parser->YYData->{LAST_TOKEN} = $1;
|
||||
if ($1 =~
|
||||
/^(const|typedef|union|struct|enum)$/x) {
|
||||
return uc($1);
|
||||
}
|
||||
return('IDENTIFIER',$1);
|
||||
}
|
||||
if (s/^(.)//s) {
|
||||
$parser->YYData->{LAST_TOKEN} = $1;
|
||||
return($1,$1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub parse($$)
|
||||
{
|
||||
my ($self,$filename) = @_;
|
||||
|
||||
my $saved_delim = $/;
|
||||
undef $/;
|
||||
my $cpp = $ENV{CPP};
|
||||
if (! defined $cpp) {
|
||||
$cpp = "cpp"
|
||||
}
|
||||
my $data = `$cpp -D__PIDL__ -xc $filename`;
|
||||
$/ = $saved_delim;
|
||||
|
||||
$self->YYData->{INPUT} = $data;
|
||||
$self->YYData->{LINE} = 0;
|
||||
$self->YYData->{LAST_TOKEN} = "NONE";
|
||||
|
||||
my $idl = $self->YYParse( yylex => \&_Lexer, yyerror => \&_Error );
|
||||
|
||||
return CleanData($idl);
|
||||
}
|
@ -140,6 +140,13 @@ idl: build/pidl/Parse/Pidl/IDL.pm
|
||||
build/pidl/Parse/Pidl/IDL.pm: build/pidl/idl.yp
|
||||
-yapp -s -m 'Parse::Pidl::IDL' -o build/pidl/Parse/Pidl/IDL.pm build/pidl/idl.yp
|
||||
|
||||
smb_interfaces: build/pidl/smb_interfaces.pm
|
||||
$(PERL) -Ibuild/pidl script/build_smb_interfaces.pl \
|
||||
include/smb_interfaces.h
|
||||
|
||||
build/pidl/smb_interfaces.pm: build/pidl/smb_interfaces.yp
|
||||
-yapp -s -m 'smb_interfaces' -o build/pidl/smb_interfaces.pm build/pidl/smb_interfaces.yp
|
||||
|
||||
pch: proto include/includes.h.gch
|
||||
|
||||
pch_clean:
|
||||
|
10
source4/script/build_smb_interfaces.pl
Executable file
10
source4/script/build_smb_interfaces.pl
Executable file
@ -0,0 +1,10 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
my $idl_file = shift;
|
||||
|
||||
require smb_interfaces;
|
||||
my $idl_parser = new smb_interfaces;
|
||||
$parse = $idl_parser->parse($idl_file);
|
||||
|
||||
use Data::Dumper;
|
||||
print Dumper($parse);
|
Loading…
x
Reference in New Issue
Block a user