2005-08-02 10:10:31 +04:00
#!/usr/bin/perl
2005-08-02 21:02:25 +04:00
#
# Create ejs interfaces for structures in a C header file
#
2005-08-02 10:10:31 +04:00
2005-08-02 21:02:25 +04:00
use File::Basename ;
2005-08-05 08:50:32 +04:00
use Data::Dumper ;
2005-08-07 22:04:34 +04:00
#
# Generate parse tree for header file
#
2005-08-02 10:10:31 +04:00
2005-08-07 22:04:34 +04:00
my $ file = shift ;
2005-08-02 10:10:31 +04:00
require smb_interfaces ;
2005-08-02 21:02:25 +04:00
my $ parser = new smb_interfaces ;
$ header = $ parser - > parse ( $ file ) ;
2005-08-02 10:10:31 +04:00
2005-08-07 22:04:34 +04:00
#
2005-08-08 01:10:32 +04:00
# Make second pass over tree to make it easier to process.
2005-08-07 22:04:34 +04:00
#
2005-08-08 01:10:32 +04:00
sub flatten_structs ($) {
2005-08-07 22:04:34 +04:00
my $ obj = shift ;
2005-08-08 01:10:32 +04:00
my $ s = { %$ obj } ;
2005-08-07 22:04:34 +04:00
# Map NAME, STRUCT_NAME and UNION_NAME elements into a more likeable
# property.
2005-08-08 01:10:32 +04:00
if ( defined ( $ obj - > { STRUCT_NAME } ) or defined ( $ obj - > { UNION_NAME } ) ) {
2005-08-07 22:04:34 +04:00
2005-08-08 01:10:32 +04:00
$ s - > { TYPE_DEFINED } = defined ( $ obj - > { STRUCT_NAME } ) ? $ obj - > { STRUCT_NAME }
2005-08-07 22:04:34 +04:00
: $ obj - > { UNION_NAME } ;
2005-08-08 01:10:32 +04:00
delete $ s - > { STRUCT_NAME } ;
delete $ s - > { UNION_NAME } ;
2005-08-07 22:04:34 +04:00
}
2005-08-08 02:14:30 +04:00
# Create a new list of structure fields with flattened names
2005-08-07 22:04:34 +04:00
foreach my $ elt ( @ { $ obj - > { DATA } } ) {
foreach my $ name ( @ { $ elt - > { NAME } } ) {
2005-08-08 01:10:32 +04:00
my $ new_elt = { %$ elt } ;
$ new_elt - > { NAME } = $ name ;
2005-08-08 02:14:30 +04:00
$ new_elt - > { PARENT } = $ s ;
2005-08-08 01:10:32 +04:00
push ( @ { $ s - > { FIELDS } } , flatten_structs ( $ new_elt ) ) ;
2005-08-07 22:04:34 +04:00
}
}
2005-08-08 01:10:32 +04:00
delete $ s - > { DATA } ;
2005-08-07 22:04:34 +04:00
2005-08-08 01:10:32 +04:00
return $ s ;
2005-08-07 22:04:34 +04:00
}
2005-08-08 02:14:30 +04:00
@ newheader = map { flatten_structs ( $ _ ) } @ { $ header } ;
2005-08-02 21:02:25 +04:00
2005-08-07 23:22:20 +04:00
#
# Generate implementation
#
2005-08-02 21:02:25 +04:00
2005-08-05 09:32:39 +04:00
open ( FILE , ">libcli/gen_raw/ejs_${basename}.c" ) ;
2005-08-02 21:02:25 +04:00
print FILE "/* EJS wrapper functions auto-generated by build_smb_interfaces.pl */\n\n" ;
2005-08-05 09:32:39 +04:00
print FILE "#include \"includes.h\"\n" ;
print FILE "#include \"lib/appweb/ejs/ejs.h\"\n" ;
print FILE "#include \"scripting/ejs/ejsrpc.h\"\n" ; # TODO: remove this
print FILE "\n" ;
2005-08-08 02:14:30 +04:00
# Top level call functions
2005-08-05 08:50:32 +04:00
2005-08-08 02:14:30 +04:00
foreach my $ s ( @ newheader ) {
2005-08-05 19:54:11 +04:00
2005-08-08 02:14:30 +04:00
if ( $ s - > { TYPE } eq "struct" ) {
2005-08-05 22:06:15 +04:00
2005-08-08 02:14:30 +04:00
# Top level struct
2005-08-05 08:50:32 +04:00
2005-08-08 02:14:30 +04:00
print FILE "static NTSTATUS ejs_$s->{TYPE_DEFINED}(int eid, int argc, struct MprVar **argv)\n" ;
print FILE "{\n" ;
print FILE "\treturn NT_STATUS_OK;\n" ;
print FILE "}\n\n" ;
2005-08-05 05:23:35 +04:00
2005-08-08 02:14:30 +04:00
} else {
2005-08-05 05:23:35 +04:00
2005-08-08 02:14:30 +04:00
# Top level union
2005-08-05 08:50:32 +04:00
2005-08-08 02:14:30 +04:00
foreach my $ arm ( @ { $ s - > { FIELDS } } ) {
2005-08-05 08:50:32 +04:00
2005-08-08 02:14:30 +04:00
print FILE "static NTSTATUS ejs_$s->{TYPE_DEFINED}_$arm->{NAME}(int eid, int argc, struct MprVar **argv)\n" ;
print FILE "{\n" ;
print FILE "\treturn NT_STATUS_OK;\n" ;
print FILE "}\n\n" ;
2005-08-05 08:50:32 +04:00
}
}
2005-08-08 02:14:30 +04:00
}
2005-08-05 08:50:32 +04:00
2005-08-08 02:14:30 +04:00
# Module initialisation
2005-08-05 08:50:32 +04:00
2005-08-08 02:14:30 +04:00
print FILE "static int ejs_${basename}_init(int eid, int argc, struct MprVar **argv)\n" ;
print FILE "{\n" ;
print FILE "\tstruct MprVar *obj = mprInitObject(eid, \"${basename}\", argc, argv);\n\n" ;
2005-08-05 05:23:35 +04:00
2005-08-08 02:14:30 +04:00
foreach my $ s ( @ newheader ) {
if ( $ s - > { TYPE } eq "struct" ) {
print FILE "\tmprSetCFunction(obj, \"$s->{TYPE_DEFINED}\", ejs_$s->{TYPE_DEFINED});\n" ;
} else {
foreach my $ arm ( @ { $ s - > { FIELDS } } ) {
print FILE "\tmprSetCFunction(obj, \"$s->{TYPE_DEFINED}_$arm->{NAME}\", ejs_$s->{TYPE_DEFINED});\n" ;
2005-08-05 08:50:32 +04:00
}
}
2005-08-05 05:23:35 +04:00
}
2005-08-08 02:14:30 +04:00
print FILE "}\n\n" ;
2005-08-05 22:06:15 +04:00
2005-08-08 02:14:30 +04:00
print FILE "NTSTATUS ejs_init_${basename}(void)\n" ;
print FILE "{\n" ;
print FILE "\treturn smbcalls_register_ejs(\"${basename}_init\", ejs_${basename}_init);\n" ;
print FILE "}\n" ;
2005-08-05 22:06:15 +04:00
2005-08-08 02:14:30 +04:00
close ( FILE ) ;
exit ;
2005-08-05 05:23:35 +04:00
foreach my $ x ( @ { $ header } ) {
next , if $ x - > { STRUCT_NAME } eq "" ;
$ raw_name = $ x - > { STRUCT_NAME } ;
$ raw_name =~ s/smb_/smb_raw_/ ;
2005-08-05 05:04:45 +04:00
print FILE "static int ejs_$x->{STRUCT_NAME}(int eid, int argc, struct MprVar **argv)\n" ;
print FILE "{\n" ;
2005-08-05 22:06:15 +04:00
print FILE "\tstruct $x->{STRUCT_NAME} params;\n" ;
2005-08-05 08:50:32 +04:00
print FILE "\tstruct smbcli_tree *tree;\n" ;
print FILE "\tNTSTATUS result;\n\n" ;
$ output = << "__HERE__" ;
if ( argc != 1 || argv [ 0 ] - > type != MPR_TYPE_OBJECT ) {
ejsSetErrorMsg ( eid , "invalid arguments" ) ;
return - 1 ;
}
tree = mprGetThisPtr ( eid , "tree" ) ;
if ( ! tree ) {
ejsSetErrorMsg ( eid , "invalid tree" ) ;
return - 1 ;
}
__HERE__
print FILE $ output ;
print FILE "\tresult = $raw_name(tree, ¶ms);\n\n" ;
2005-08-05 05:23:35 +04:00
2005-08-05 08:50:32 +04:00
print FILE "\tmpr_Return(eid, mprNTSTATUS(status));\n" ;
print FILE "\tif (NT_STATUS_EQUAL(status, NT_STATUS_INTERNAL_ERROR)) {\n" ;
print FILE "\t\treturn -1;\n" ;
print FILE "\t}\n\n" ;
print FILE "\treturn 0;\n" ;
2005-08-05 05:23:35 +04:00
2005-08-05 05:04:45 +04:00
print FILE "}\n\n" ;
2005-08-02 21:02:25 +04:00
}