#!/usr/bin/perl # # Create ejs interfaces for structures in a C header file # use File::Basename; my $file = shift; my $basename = basename($file, ".h"); require smb_interfaces; my $parser = new smb_interfaces; $header = $parser->parse($file); use Data::Dumper; #print Dumper($header); # Create header open(FILE, ">ejs_${basename}.h"); print FILE "/* header auto-generated by build_smb_interfaces.pl */\n\n"; print FILE "#ifndef _ejs_${basename}_h\n"; print FILE "#define _ejs_${basename}_h\n\n"; sub struct_name($) { my $obj = shift; return defined($obj->{STRUCT_NAME}) ? $obj->{STRUCT_NAME} : $obj->{UNION_NAME}; } sub prototypes_for($) { my $obj = shift; my $name = struct_name($obj); print FILE "NTSTATUS ejs_push_$name(struct ejs_rpc *, struct MprVar *, const char *, const uint32_t *);\n"; print FILE "NTSTATUS ejs_pull_$name(struct ejs_rpc *, struct MprVar *, const char *, const uint32_t *);\n"; } sub pushpull_for($) { my $obj = shift; my $name = struct_name($obj); print FILE "NTSTATUS ejs_push_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, const uint32_t *r)\n"; print FILE "{\n"; print FILE "\tNDR_CHECK(ejs_push_struct_start(ejs, &v, \"output\"));\n"; print FILE "\n\treturn NT_STATUS_OK;\n"; print FILE "}\n\n"; print FILE "NTSTATUS ejs_pull_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, const uint32_t *r)\n"; print FILE "{\n"; print FILE "\tNDR_CHECK(ejs_pull_struct_start(ejs, &v, \"input\"));\n"; print FILE "\treturn NT_STATUS_OK;\n"; print FILE "}\n\n"; } foreach my $x (@{$header}) { # Prototypes for top level structures and unions prototypes_for($x); # Prototypes for non-anonymous nested structures and unions foreach my $e1 (@{$x->{DATA}}) { foreach my $e2 (@{$e1->{DATA}}) { if (defined($e2->{STRUCT_NAME}) or defined($e2->{UNION_NAME})) { prototypes_for($e2); } } } } print FILE "#endif\n"; close(FILE); # Create file open(FILE, ">ejs_${basename}.c"); print FILE "/* EJS wrapper functions auto-generated by build_smb_interfaces.pl */\n\n"; # Top level push/pull functions foreach my $x (@{$header}) { next, if $x->{STRUCT_NAME} eq ""; print FILE "static NTSTATUS ejs_pull_$x->{STRUCT_NAME}(struct ejs_rpc *ejs, struct MprVar *v, struct $x->{STRUCT_NAME} *r)\n"; print FILE "{\n"; print FILE "\tNDR_CHECK(ejs_pull_struct_start(ejs, &v, \"input\"));\n"; print FILE "\treturn NT_STATUS_OK;\n"; print FILE "}\n\n"; print FILE "static NTSTATUS ejs_push_$x->{STRUCT_NAME}(struct ejs_rpc *ejs, struct MprVar *v, const struct $x->{STRUCT_NAME} *r)\n\n"; print FILE "{\n"; print FILE "\tNDR_CHECK(ejs_push_struct_start(ejs, &v, \"output\"));\n"; print FILE "\treturn NT_STATUS_OK;\n"; print FILE "}\n\n"; } # Top level call functions foreach my $x (@{$header}) { next, if $x->{STRUCT_NAME} eq ""; $raw_name = $x->{STRUCT_NAME}; $raw_name =~ s/smb_/smb_raw_/; print FILE "static int ejs_$x->{STRUCT_NAME}(int eid, int argc, struct MprVar **argv)\n"; print FILE "{\n"; print FILE "\tstruct $x->{STRUCT_NAME} parms;\n\n"; print FILE "\t$raw_name(tree, ¶ms);\n"; print FILE "\tejsSetErrorMsg(eid, \"Not implemented\");\n"; print FILE "\treturn -1;\n"; print FILE "}\n\n"; } # Module initialisation 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, argtv);\n\n"; foreach my $x (@{$header}) { next, if $x->{STRUCT_NAME} eq ""; print FILE "\tmprSetCFunction(obj, \"$x->{STRUCT_NAME}\", ejs_$x->{STRUCT_NAME});\n"; } print FILE "}\n\n"; 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"; close(FILE);