#!/bin/sh ########################################################################## # # This script is used to create CORBA 'Interface Definition Language' (IDL) # file. # # A definition of what methods can be called on what objects need to be # provided for both the caller and callee. The only information which is # required to make a caller able to call an object on a remote server is # the IDL of the object. # # This enables Aubit plug-ins to reside on different machines on the network # For instance, you can run a 4GL program on PC1, but get it to use UI # plugin on PC2, efectibely creating a thin UI client. # # See # http://www.gnome.org/projects/ORBit2/documentation.html # http://www.omg.org/technology/documents/formal/c_language_mapping.htm # C mappings : http://www.omg.org/docs/formal/99-07-39.pdf ########################################################################## #Get settings if [ "$AUBITDIR" != "" ] then . $AUBITDIR/etc/aubitrc else echo "WARNING: AUBITDIR not set" echo "ERROR: cannot read settings. STOP." exit 3 fi if [ $# -lt 1 -o "$1" = "--help" ]; then echo "Creates CORBA IDL API definition file" echo " " echo "Usage: idlmagic [] [] > .idl" echo " SpecFile - contains specifications for the API (.spec)" echo " APIName - API name (will be overwritten by LIBRARY tag if declared" echo " in SpecFile)" echo " EnvVar - Environment variable to read (will be overwritten by" echo " VARIABLE tag if declared in the SpecFile)" echo " " echo "Example: " echo " idlmagic sqlapi.spec SQL SQLTYPE > CORBA-API_SQL.idl " echo " " echo "SpecFile file format:" echo " func-name param-type param-name ... -> returns" echo " line beginning with * is a comment" echo " line beginning with # or / is included in the output Eg #define //comment etc" echo " " echo "Example input File :" echo " LIBRARY TEST" echo " VARIABLE VTEST" echo " * This is a comment - Note - there are no spaces for void* int* etc." echo " pdf_rep_print void* rep,int a,int s,int right_margin -> int*" echo " disp_fields int n int attr ... -> int" echo " " exit 0 fi specfile=$1 CREATE="idl" if [ "$2" = "-client" ] ; then CREATE="client" fi if [ "$2" = "-server" ] ; then CREATE="server" fi if [ "$2" = "-skelimpl" ] ; then CREATE="skelimpl" fi if [ "$2" = "-add-to-skelimpl" ] ; then CREATE="add-to-skelimpl" fi if [ "$2" = "-add-func-calls" ]; then CREATE="add-func-calls" INFILE=$3 fi # if [ "$2" = "-H" ] ; then # MAKE_HEADER=2 # else # lib=$2 # env=$3 # fi lib_prefix= api_prefix= if grep "^LIBRARY " $specfile > /dev/null ; then lib=`$AWK '/^LIBRARY /{print $2}' $specfile` lib_downshift=`echo $lib | tr A-Z a-z` fi if grep "^VARIABLE " $specfile > /dev/null ; then env=`$AWK '/^VARIABLE /{print $2}' $specfile` fi #if you want prefix to be added to API function names if grep "^API_PREFIX " $specfile > /dev/null ; then api_prefix=`$AWK '/^API_PREFIX /{print $2}' $specfile` fi #if you want prefix to be added to LIB functions calls if grep "^LIB_PREFIX " $specfile > /dev/null ; then lib_prefix=`$AWK '/^LIB_PREFIX /{print $2}' $specfile` fi #name of the headers file to be refgerenced with #include if grep "^HEADER_FILE " $specfile > /dev/null ; then HEADER_FILE=`$AWK '/^HEADER_FILE /{print $2}' $specfile` fi #echo "/* Library=$lib env=$env */" ############################################################################# # Creation of the .idl file ############################################################################# if [ "$CREATE" = "idl" ]; then #if [ "$MAKE_HEADER" = "2" ] ; then # use_prefix=1 #else # use_prefix=0 #fi $AWK -v use_prefix=$use_prefix -v lib="$lib" -v env="$env" \ -v lib_prefix="$lib_prefix" -v api_prefix="$api_prefix" \ -v HEADER_FILE="$HEADER_FILE" ' BEGIN { FS="[ \t,]+" print "" if (COMMENTS=="1") { print "/*" print " * lib=" lib " env=" env " lib_prefix=" lib_prefix " api_prefix=" api_prefix print " *" print " * This file was created from .spec file of same name, using idlmagic script" print " * - if you need to edit it, edit .spec file instad, and use [make filename.idl]" print " * to re-create it." print " *" print " */" print "" print "/*" print "=====================================================================" print " CORBA IDL definitions" print "=====================================================================" print "*/" } ##include print "" #When inteface yyy declaration is used within module xxx #we end up with typedef CORBA_Object yyy_xxx in lib.h - I dont #think we need that #print "module Examples {" if (use_prefix==0) { print " interface " lib " {" } else { print " interface " lib " {" } print "" } /^LIBRARY / {next} /^#ifdef/ {next} /^#undef/ {next} /^#endif/ {next} /^VARIABLE / {next} /^HEADER_FILE / {next} /^MULTILOAD_LIBRARY/ {next} /^API_PREFIX / {next} /^LIB_PREFIX / {next} /^MAP / { map[$2]=$3; next} /^#/ {print next } /^\// {print next } /^extern/ {print next } /^\/\*/ {print next } /^ \*/ {print next } /^\*\// {print next } /^$/ {next} /^\*/ {next } /^[ ]*$/ {next} { fname=$1 rtype="void" c=0 for (a=2;a<=NF;a++) { if ($a==" "||$a=="\t"||$a==",") continue; param_type[c]=$a if (param_type[c]=="->") { param_type[c]="" a++ rtype=$a #Map return types to CORBA types if (rtype=="char*") {rtype="string"} break } if (param_type[c]=="...") { param_name[c]="" a++ c++ break } a++ param_name[c]=$a c++; } if (c==0) { param_name[c]="" param_type[c]="void" c++ } if (use_prefix==0) { printf " " rtype " CORBA_" api_prefix fname "(" } else { printf " " rtype " CORBA_" lib_prefix fname "(" } va_start="" args="" for (b=0;b "dlmagic.log" } function pind(rtype,rname) { if (rtype=="char*") return sprintf("A4GL_null_as_null(%s)",rname); return rname; #print "Unknown type : " rtype > "dlmagic.log" } BEGIN { FS="[ ,]+" if (COMMENTS=="1") { print "/*" if (CREATE=="") print " * CREATE is empty" else print " * CREATE=" CREATE print " * lib=" lib " env=" env " lib_prefix=" lib_prefix " api_prefix=" api_prefix print " * @file" print " * File definition" print " *" print " * This file was created from .spec file of same name, using idlmagic script" print " * - if you need to edit it, edit .spec file instad, and use [make filename.c]" print " * to re-create it." print " *" print " * @todo Take the prototypes here declared. See if the functions are static" print " * or to be externally seen" print " * @todo Doxygen comments to add to functions" print " */" print "" print "/*******************************************************************" print "* (c) 1997-2005 Aubit Computing Ltd." print "*" print "*" print "********************************************************************/" print "" print "" } if (HEADER_FILE=="") print "#include \"a4gl_libaubit4gl_int.h\"" else print "#include " HEADER_FILE print "#include \"CAPI_" lib_downshift ".h\"" print "" if (DBG=="1") { print "#ifdef DEBUG" print "#ifndef DEBUG_SPEC_CORBA" print "#define DEBUG_SPEC_CORBA" print "#endif" print "#endif" } if (CREATE=="server") print "static void *libptr=0;" #print "static int (*func)();" #print "static double (*func_d)();" #print "void *A4GL_find_func(void *p,char *s);" if (CREATE=="server") print "int A4GL_CSERVER_" lib "_initlib (void);" if (CREATE=="client") print "int A4GL_CCLIENT_" lib "_initlib (void);" if (CREATE=="server") print "void A4GL_CSERVER_" lib "_clrlibptr (void);" if (CREATE=="client") print "void A4GL_CCLIENT_" lib "_clrlibptr (void);" #defined and initialised in corba_server_util.c: if (CREATE=="client") print "extern CORBA_ORB global_orb; /* global orb */" if (CREATE=="client") print "int A4GL_CORBA_client_main (int argc, char* argv[]);" if (CREATE=="client") print "void client_init (int *argc_ptr,char *argv[],CORBA_ORB *orb, CORBA_Environment *ev);" if (CREATE=="client") print "void etk_abort_if_exception(CORBA_Environment *ev, const char* mesg);" if (CREATE=="server") print "//int dlclose (void *__handle);" if (CREATE=="server") print "" if (COMMENTS=="1") { if (CREATE=="server") print "/**" if (CREATE=="server") print " * Library init function." if (CREATE=="server") print " *" if (CREATE=="server") print " * @todo : explain ussage and parameters." if (CREATE=="server") print " * @return ." if (CREATE=="server") print " */" if (CREATE=="server") print "" } if (CREATE=="server") print "void A4GL_CSERVER_" lib "_clrlibptr (void) {" if (CREATE=="client") print "void A4GL_CCLIENT_" lib "_clrlibptr (void) {" if (CREATE=="server") print " //TODO- implement if needed CORBA server equivalent" if (CREATE=="client") print " //TODO- implement if needed CORBA client equivalent" print " //if (libptr) {dlclose(libptr);}" print " //libptr=0;" print "}" print "" if (CREATE=="server") print "int main (int argc, char *argv[]) {" if (CREATE=="server") print " int retcode;" if (CREATE=="server") print " retcode=A4GL_CORBA_server_main(argc,argv); //in corba_server_util.c" if (CREATE=="server") print " exit (retcode);" if (CREATE=="server") print "}" if (CREATE=="server") print " " if (CREATE=="server") print "int A4GL_CSERVER_" lib "_initlib (void) {" if (CREATE=="client") print "int A4GL_CCLIENT_" lib "_initlib (void) {" if (CREATE=="server") print "//TODO-main() allready called server init func A4GL_CORBA_server_main() in corba_server_util.c" if (CREATE=="server") print "//Anything else to do/initialise here or is this obsolete for CORBA server?" if (CREATE=="client") print "//TODO-call CORBA client init func A4GL_CORBA_client_main() in corba_server_util.c" print "//typedef int (*x_func)(void);" print "//static x_func func;" print "// libptr=(void *)A4GL_dl_openlibrary(\"" lib "\",acl_getenv(\"" env "\"));" print "// if (libptr==0) {" print "// A4GL_exitwith(\"Unable to open " $lib " library...\");" print "// return 0;" print "// }" print "// func=(x_func)A4GL_find_func_allow_missing(libptr,\"" lib_prefix "A4GL" lib "_initlib\");" print "//" print "// if (func)" print "// return func();" print "// else" print " return 1;" print "}" print "" print "" #calls impl_" lib "__create which is created in CAPI_*-skelimpl.c by orbit-idl #and declared static - so we cant call it from other objects and need #to add it to CAPI_*-skelimpl.c instead if (CREATE=="DISABLEDserver") { print "/* Creates servant and registers in context of ORB @orb. The ORB will" print " * delegate incoming requests to specific servant object. @return" print " * object reference. If error occures @ev points to exception object" print " * on return." print " */" #not static - called from A4GL_CORBA_server_main() in SERVER_corba_server_util.c #print "static CORBA_Object" print "CORBA_Object" print "server_activate_service (CORBA_ORB orb," print " PortableServer_POA poa," print " CORBA_Environment *ev)" print "{" print lib " ref = CORBA_OBJECT_NIL;" print " ref = impl_" lib "__create (poa, ev);" print " if (etk_raised_exception(ev)) { " print " return CORBA_OBJECT_NIL;" print " } else {" print " return ref;" print " }" print "}" } if (CREATE=="client") { print "/*" print " * main - this is the CORBA client init function" print " */" print "int A4GL_CORBA_client_main (int argc, char* argv[]) {" print "CORBA_char filename[] = \"" lib ".ref\"; //ref file to discover server" print "CORBA_Environment ev[1];" print lib " service = CORBA_OBJECT_NIL;" print "CORBA_exception_init(ev);" print " client_init (&argc, argv, &global_orb, ev);" print " etk_abort_if_exception(ev, \"init failed\");" print " g_print (\"Reading service reference from file %s \", filename);" print " service = (" lib ") etk_import_object_from_file (global_orb,filename,ev);" print " etk_abort_if_exception(ev, \"import service failed\");" print " /* We would here invoke whatever function we want to call on the" print " server side, but we instead will just return after finised" print " CORBA client initialisation, and let API functions do the calling" print " */" print " //client_run (service, amount, ev);" print " // etk_abort_if_exception(ev, \"service not reachable\");" print " /* This cleanup probably is equivalent to " print " void A4GL_CCLIENT_" lib "_clrlibptr (void) {" print " if (libptr) {dlclose(libptr);}" print " libptr=0;" print " }" print " for dlopen() API, and therefore should be in CAPI_%-client.c ?" print " " print " Otherwise, should we call it before we exit 4GL program?" print " */" print " //client_cleanup (global_orb, service, ev);" print " //etk_abort_if_exception(ev, \"cleanup failed\");" print " " print " return 0;" print "}" } } /^LIBRARY / {next} /^#ifdef/ {if (DBG=="0") next} /^#undef/ {if (DBG=="0") next} /^#endif/ {if (DBG=="0") next} /^VARIABLE / {next} /^HEADER_FILE / {next} /^MULTILOAD_LIBRARY/ {next} /^API_PREFIX / {next} /^LIB_PREFIX / {next} /MAP / { map[$2]=$3; next} /^#/ {print next } /^\// {print next } /^extern/ {print next } /^ \*/ {print next } /^\*\// {print next } /^\*/ {next} /^$/ {next} /^[ ]*$/ {next} { fname=$1 call_fname=$1 rtype="void" c=0 for (a=2;a<=NF;a++) { param_type[c]=$a if (param_type[c]=="->") { param_type[c]="" a++ rtype=$a break } if (param_type[c]=="...") { param_name[c]="" call_fname="internal_"fname a++ c++ break } a++ param_name[c]=$a c++; } #THIS SHOULD BE PART OF .spec file #print "" #print "/**" #print " * API call function for xyz ." #print " *" #print " * @todo : explain ussage and parameters." #print " * @param xyz Explain me..." #print " * @return xyz Explain me..." #print " */" #print "" if (CREATE=="server") printf rtype " CORBA_" api_prefix fname "(" else printf rtype " " api_prefix fname "(" va_start="" args="" dargs="" debug_args="Call to " rtype " " api_prefix fname "(" for (b=0;bservant.vepv = &impl_"$lib"_vepv; newservant->poa = poa; POA_"$lib"__init((PortableServer_Servant) newservant, ev); objid = PortableServer_POA_activate_object(poa, newservant, ev); CORBA_free(objid); retval = PortableServer_POA_servant_to_reference(poa, newservant, ev); return retval; } static void impl_"$lib"__destroy(impl_POA_$lib * servant, CORBA_Environment * ev) { PortableServer_ObjectId *objid; objid = PortableServer_POA_servant_to_id(servant->poa, servant, ev); PortableServer_POA_deactivate_object(servant->poa, objid, ev); CORBA_free(objid); POA_"$lib"__fini((PortableServer_Servant) servant, ev); g_free(servant); } X cat<