Back to home page

Enduro/X

 
 

    


0001 #!/usr/bin/perl
0002 
0003 #
0004 # @(#) Script is used to build Object API for XATMI and UBF
0005 #
0006 
0007 use Getopt::Std;
0008 #use Regexp::Common;
0009 
0010 our ($opt_i, $opt_o, $opt_h);
0011 $opt_i = 0; # Input file
0012 $opt_o = 0; # output name
0013 $opt_h = 0; # Help
0014 my $opt_ret = getopts ('i:o:h');
0015 
0016 if (!$opt_ret || $opt_h || !$opt_i || !$opt_o)
0017 {
0018         print STDERR "Usage: $0 -i <input file, c header> -o <output prefix>\n ";
0019         exit 1;
0020 }
0021 
0022 my $M_name_upper = uc $opt_o;
0023 $M_name_upper = "O$M_name_upper";
0024 $M_name = "o$opt_o";
0025 
0026 #
0027 # Remove whitespace from string
0028 #
0029 sub remove_white_space {
0030 
0031     my $ret = shift;
0032     
0033     
0034     $ret =~ s/^\s+//;
0035     $ret =~ s/\s+$//;
0036 
0037     return $ret;
0038 }
0039 
0040 sub split_by_comma_but_not_parenthesis {
0041 
0042     my $string=shift;
0043     my @array = ($string =~ /(
0044     [^,]*\([^)]*\)   # comma inside parens is part of the word
0045     |
0046     [^,]*)           # split on comma outside parens
0047     (?:,|$)/gx);
0048 
0049     return @array;
0050 }
0051 
0052 ################################################################################
0053 # Object API output file handling
0054 ################################################################################
0055 
0056 
0057 
0058 #
0059 # Have some file handers, one for header
0060 # and one for c
0061 #
0062 
0063 
0064 ################################################################################
0065 # Open C header
0066 ################################################################################
0067 sub open_h {
0068 
0069     $M_h_name = "${M_name}.h";
0070     print "Opening [$M_h_name]\n";
0071     open($M_h_fd, '>', $M_h_name) or die "Could not open file '$M_h_name' $!";
0072 
0073     my $title = "";
0074     my $defs = "";
0075 
0076     if ($M_name=~/^oatmisrv_integra/)
0077     {
0078         $title = "ATMI Server integration level Object API header (auto-generated)";
0079     }
0080     elsif ($M_name=~/^oatmisrv$/)
0081     {
0082         $title = "ATMI Server level Object API header (auto-generated)";
0083     }
0084     elsif ($M_name=~/^oatmi$/)
0085     {
0086         $title = "ATMI Object API header (auto-generated)";
0087 
0088         $defs = "\n#define Otperrno(P_CTXT) (*O_exget_tperrno_addr(P_CTXT))\n".
0089                 "#define Otpurcode(P_CTXT) (*O_exget_tpurcode_addr(P_CTXT))";
0090     }
0091     elsif($M_name=~/oubf/)
0092     {
0093         $title = "UBF Object API header (auto-generated)";
0094 
0095         $defs = "\n#define OBerror(P_CTXT)   (*O_Bget_Ferror_addr(P_CTXT))";
0096     }
0097     elsif($M_name=~/ondebug/)
0098     {
0099         $title = "Standard library debug routines";
0100     }
0101     elsif($M_name=~/onerror/)
0102     {
0103         $title = "Standard library error handler";
0104         $defs = "\n#define ONerror(P_CTXT)   (*O_Nget_Nerror_addr(P_CTXT))";
0105     }
0106     
0107 my $message = <<"END_MESSAGE";
0108 /**
0109  * \@brief $title
0110  *
0111  * \@file ${M_name}.h
0112  */
0113 /* -----------------------------------------------------------------------------
0114  * Enduro/X Middleware Platform for Distributed Transaction Processing
0115  * Copyright (C) 2009-2016, ATR Baltic, Ltd. All Rights Reserved.
0116  * Copyright (C) 2017-2023, Mavimax, Ltd. All Rights Reserved.
0117  * This software is released under one of the following licenses:
0118  * AGPL (with Java and Go exceptions) or Mavimax's license for commercial use.
0119  * See LICENSE file for full text.
0120  * -----------------------------------------------------------------------------
0121  * AGPL license:
0122  *
0123  * This program is free software; you can redistribute it and/or modify it under
0124  * the terms of the GNU Affero General Public License, version 3 as published
0125  * by the Free Software Foundation;
0126  *
0127  * This program is distributed in the hope that it will be useful, but WITHOUT ANY
0128  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
0129  * PARTICULAR PURPOSE. See the GNU Affero General Public License, version 3
0130  * for more details.
0131  *
0132  * You should have received a copy of the GNU Affero General Public License along
0133  * with this program; if not, write to the Free Software Foundation, Inc.,
0134  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0135  *
0136  * -----------------------------------------------------------------------------
0137  * A commercial use license is available from Mavimax, Ltd
0138  * contact\@mavimax.com
0139  * -----------------------------------------------------------------------------
0140  */
0141 #ifndef __${M_name_upper}_H
0142 #define __${M_name_upper}_H
0143 
0144 #ifdef  __cplusplus
0145 extern "C" {
0146 #endif
0147 /*---------------------------Includes-----------------------------------*/
0148 #include <stdint.h>
0149 #include <ubf.h>
0150 #include <atmi.h>
0151 /*---------------------------Externs------------------------------------*/
0152 /*---------------------------Macros-------------------------------------*/${defs}
0153 /*---------------------------Enums--------------------------------------*/
0154 /*---------------------------Typedefs-----------------------------------*/
0155 /*---------------------------Globals------------------------------------*/
0156 /*---------------------------Statics------------------------------------*/
0157 /*---------------------------Prototypes---------------------------------*/
0158 END_MESSAGE
0159     
0160 print $M_h_fd $message;
0161 
0162 }
0163 
0164 ################################################################################
0165 # Open C source file
0166 ################################################################################
0167 sub open_c {
0168 
0169 
0170     $M_c_name = "${M_name}.c";
0171     print "Opening [$M_c_name]\n";
0172     open($M_c_fd, '>', $M_c_name) or die "Could not open file '$M_c_name' $!";
0173 
0174     my $title = "";
0175 
0176     if ($M_name=~/^oatmisrv$/)
0177     {
0178         $title = "ATMI Server Level Object API code (auto-generated)";
0179     }
0180     if ($M_name=~/^oatmisrv_integra$/)
0181     {
0182         $title = "ATMI Server Integration Level Object API code (auto-generated)";
0183     }
0184     if ($M_name=~/^oatmi$/)
0185     {
0186         $title = "ATMI Object API code (auto-generated)";
0187     }
0188     elsif($M_name=~/oubf/)
0189     {
0190         $title = "UBF Object API code (auto-generated)";
0191     }
0192     elsif($M_name=~/ondebug/)
0193     {
0194         $title = "Standard library debugging object API code (auto-generated)";
0195     }
0196     elsif($M_name=~/onerror/)
0197     {
0198         $title = "Standard library error handling";
0199     }
0200 
0201 my $message = <<"END_MESSAGE";
0202 /**
0203  * \@brief $title
0204  *
0205  * \@file ${M_name}.c
0206  */
0207 /* -----------------------------------------------------------------------------
0208  * Enduro/X Middleware Platform for Distributed Transaction Processing
0209  * Copyright (C) 2009-2016, ATR Baltic, Ltd. All Rights Reserved.
0210  * Copyright (C) 2017-2023, Mavimax, Ltd. All Rights Reserved.
0211  * This software is released under one of the following licenses:
0212  * AGPL (with Java and Go exceptions) or Mavimax's license for commercial use.
0213  * See LICENSE file for full text.
0214  * -----------------------------------------------------------------------------
0215  * AGPL license:
0216  *
0217  * This program is free software; you can redistribute it and/or modify it under
0218  * the terms of the GNU Affero General Public License, version 3 as published
0219  * by the Free Software Foundation;
0220  *
0221  * This program is distributed in the hope that it will be useful, but WITHOUT ANY
0222  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
0223  * PARTICULAR PURPOSE. See the GNU Affero General Public License, version 3
0224  * for more details.
0225  *
0226  * You should have received a copy of the GNU Affero General Public License along
0227  * with this program; if not, write to the Free Software Foundation, Inc.,
0228  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0229  *
0230  * -----------------------------------------------------------------------------
0231  * A commercial use license is available from Mavimax, Ltd
0232  * contact\@mavimax.com
0233  * -----------------------------------------------------------------------------
0234  */
0235 #include <string.h>
0236 #include <stdio.h>
0237 #include <stdint.h>
0238 #include <stdlib.h>
0239 #include <memory.h>
0240 #include <errno.h>
0241 #include <dlfcn.h>
0242 
0243 #include <atmi.h>
0244 #include <atmi_tls.h>
0245 #include <ndrstandard.h>
0246 #include <ndebug.h>
0247 #include <ndrxdcmn.h>
0248 #include <userlog.h>
0249 #include <xa_cmn.h>
0250 /*---------------------------Externs------------------------------------*/
0251 /*---------------------------Macros-------------------------------------*/
0252 /*---------------------------Enums--------------------------------------*/
0253 /*---------------------------Typedefs-----------------------------------*/
0254 /*---------------------------Globals------------------------------------*/
0255 /*---------------------------Statics------------------------------------*/
0256 /*---------------------------Prototypes---------------------------------*/
0257 END_MESSAGE
0258 
0259 print $M_c_fd $message;
0260 
0261 }
0262 
0263 
0264 ################################################################################
0265 # Close C header
0266 ################################################################################
0267 sub close_h {
0268 $message = <<"END_MESSAGE";
0269 #endif  /* __${M_name_upper}_H */
0270 
0271 END_MESSAGE
0272 
0273 print $M_h_fd $message;
0274 
0275 close($M_h_fd)
0276 
0277 }
0278 
0279 ################################################################################
0280 # Close C source file
0281 ################################################################################
0282 sub close_c {
0283 
0284 $message = <<"END_MESSAGE";
0285 
0286 END_MESSAGE
0287 
0288 print $M_c_fd $message;
0289 
0290 close($M_c_fd)
0291 
0292     
0293 }
0294 
0295 
0296 ################################################################################
0297 # Generate Object API func signature
0298 ################################################################################
0299 sub gen_sig {
0300 
0301     my $func_type = shift;
0302     my $func_name = shift;
0303     my $func_args_list = shift;
0304     
0305     if ($func_args_list=~/^void$/)
0306     {
0307         return "$func_type O$func_name(TPCONTEXT_T *p_ctxt)";
0308     }
0309     else
0310     {
0311         return "$func_type O$func_name(TPCONTEXT_T *p_ctxt, $func_args_list)";
0312     }
0313 }
0314 
0315 ################################################################################
0316 # Have some extra debug, common
0317 ################################################################################
0318 
0319 sub debug_entry {
0320 
0321     $func_name = shift;
0322     $priv_flags = shift;
0323     
0324 my $debug_entry = <<"END_MESSAGE";
0325 
0326 #ifdef NDRX_OAPI_DEBUG
0327     NDRX_LOG(log_debug, "ENTRY: $func_name() enter, context: %p, current: %p", *p_ctxt, G_atmi_tls);
0328     NDRX_LOG(log_debug, "ENTRY: is_associated_with_thread = %d", 
0329         ((atmi_tls_t *)*p_ctxt)->is_associated_with_thread);
0330 
0331     NDRX_LOG(log_debug, "ENTRY: CTXT_PRIV_NSTD = %d", 
0332         ($priv_flags) & CTXT_PRIV_NSTD );
0333 
0334     NDRX_LOG(log_debug, "ENTRY: CTXT_PRIV_UBF = %d", 
0335         ($priv_flags) & CTXT_PRIV_UBF );
0336 
0337     NDRX_LOG(log_debug, "ENTRY: CTXT_PRIV_ATMI = %d", 
0338         ($priv_flags) & CTXT_PRIV_ATMI );
0339 
0340     NDRX_LOG(log_debug, "ENTRY: CTXT_PRIV_TRAN = %d", 
0341         ($priv_flags) & CTXT_PRIV_TRAN );
0342 
0343     NDRX_LOG(log_debug, "ENTRY: CTXT_PRIV_NOCHK = %d", 
0344         ($priv_flags) & CTXT_PRIV_NOCHK );
0345 
0346     NDRX_LOG(log_debug, "ENTRY: CTXT_PRIV_IGN = %d", 
0347         ($priv_flags) & CTXT_PRIV_IGN );
0348 #endif
0349 
0350 END_MESSAGE
0351 
0352     return $debug_entry;
0353 
0354 }
0355 
0356 sub debug_return {
0357 
0358     $func_name = shift;
0359 
0360 my $debug_return = <<"END_MESSAGE";
0361 
0362 #ifdef NDRX_OAPI_DEBUG
0363     NDRX_LOG(log_debug, "RETURN: $func_name() returns, context: %p, current: %p",
0364         *p_ctxt, G_atmi_tls);
0365 #endif
0366 
0367 END_MESSAGE
0368 
0369     return $debug_return;
0370 }
0371 
0372 ################################################################################
0373 # Write tpsetunsol object API header func, special case (complex hdr)
0374 ################################################################################
0375 
0376 sub write_h_tpsetunsol {
0377     print $M_h_fd "extern NDRX_API void (*Otpsetunsol (TPCONTEXT_T *p_ctxt, void (*disp) (char *data, long len, long flags))) (char *data, long len, long flags);\n";
0378 }
0379 
0380 ################################################################################
0381 # Write tpsetunsol object API func, special case (complex hdr)
0382 ################################################################################
0383 
0384 sub write_c_tpsetunsol {
0385     
0386     $func_name = "tpsetunsol";
0387     $priv_flags = "CTXT_PRIV_NSTD|CTXT_PRIV_UBF| CTXT_PRIV_ATMI | CTXT_PRIV_IGN";
0388     
0389     $oapi_debug_entry = debug_entry($func_name, $priv_flags);
0390     $oapi_debug_return = debug_return($func_name);
0391     
0392 $message = <<"END_MESSAGE";
0393 
0394 /**
0395  * Object-API wrapper for $func_name() - Auto generated.
0396  */
0397 expublic void (*Otpsetunsol (TPCONTEXT_T *p_ctxt, void (*disp) (char *data, long len, long flags))) (char *data, long len, long flags)
0398 {
0399     int did_set = EXFALSE;
0400     void (*ret) (char *data, long len, long flags) = NULL;
0401 
0402 $oapi_debug_entry 
0403     
0404     if (!((atmi_tls_t *)*p_ctxt)->is_associated_with_thread)
0405     {
0406         /* set the context */
0407         if (EXSUCCEED!=ndrx_tpsetctxt(*p_ctxt, 0, 
0408             $priv_flags))
0409         {
0410             userlog("ERROR! $func_name() failed to set context");
0411             ret = NULL;
0412             goto out;
0413         }
0414         did_set = EXTRUE;
0415     }
0416     else if ((atmi_tls_t *)*p_ctxt != G_atmi_tls)
0417     {
0418         userlog("WARNING! $func_name() context %p thinks that it is assocated "
0419                 "with current thread, but thread is associated with %p context!",
0420                 p_ctxt, G_atmi_tls);
0421     }
0422     
0423     ret = tpsetunsol(disp);
0424 
0425     if (did_set)
0426     {
0427         if (TPMULTICONTEXTS!=ndrx_tpgetctxt(p_ctxt, 0,
0428                 $priv_flags))
0429         {
0430             userlog("ERROR! $func_name() failed to get context");
0431             ret = NULL;
0432             goto out;
0433         }
0434     }
0435 out:
0436 $oapi_debug_return
0437     return ret; 
0438 }
0439 
0440 END_MESSAGE
0441 
0442     print $M_c_fd $message;
0443 }
0444 
0445 
0446 ################################################################################
0447 # Write C object API header func
0448 ################################################################################
0449 sub write_h {
0450     my $sig = shift;
0451     print $M_h_fd "extern NDRX_API $sig;\n";
0452 }
0453 
0454 ################################################################################
0455 # Write C object API function
0456 ################################################################################
0457 sub write_c {
0458     my $func_type = $_[0];
0459     my $func_name = $_[1];
0460     my $sig = $_[2];
0461     my $func_args_list = $_[3];
0462     
0463     my @func_arg_type = @{$_[4]};
0464     my @func_arg_name = @{$_[5]};
0465     my @func_arg_def = @{$_[6]};
0466     
0467     $M_func_name = $func_name;
0468     #
0469     # Generate function call
0470     #
0471     my $invoke = "$func_name(";
0472     my $first = 1;
0473     
0474     if ($func_args_list!~m/^void$/)
0475     {
0476         # Generate from arguments list;
0477         foreach my $name ( @func_arg_name )
0478         {
0479             if ($first)
0480             {
0481                 $first = 0;
0482             }
0483             else
0484             {
0485                 $invoke = "$invoke, ";
0486             }
0487             
0488             $invoke = "$invoke$name";
0489         }
0490     }
0491     
0492     $invoke = "$invoke)";
0493     
0494     $priv_flags = "";
0495     #
0496     # Calculate the flags, all UBF operations receive only UBF & TLS contexts
0497     # ATMI have ATMI too, plus somes have a TRAN
0498     #
0499     if ($M_name=~/^oatmi$/ 
0500         || $M_name=~/^oatmisrv$/
0501         || $M_name=~/^oatmisrv_integra$/
0502         )
0503     {
0504         if ($func_name=~/^tpcall$/ 
0505             ||$func_name=~/^tpacall$/
0506             ||$func_name=~/^tpgetrply$/
0507             ||$func_name=~/^tpconnect$/
0508             ||$func_name=~/^tpdiscon$/
0509             ||$func_name=~/^tpsend$/
0510             ||$func_name=~/^tprecv$/
0511             ||$func_name=~/^tpcancel$/
0512             ||$func_name=~/^tpreturn$/
0513             ||$func_name=~/^tpgetlev$/
0514             ||$func_name=~/^tpabort$/
0515             ||$func_name=~/^tpbegin$/
0516             ||$func_name=~/^tpcommit$/
0517             ||$func_name=~/^tpopen$/
0518             ||$func_name=~/^tpsuspend$/
0519             ||$func_name=~/^tpresume$/
0520             ||$func_name=~/^tpclose$/
0521             ||$func_name=~/^tppost$/
0522             ||$func_name=~/^tpenqueue$/
0523             ||$func_name=~/^tpdequeue$/
0524             ||$func_name=~/^tpenqueueex$/
0525             ||$func_name=~/^tpdequeueex$/
0526             ||$func_name=~/^tpgetctxt$/
0527             ||$func_name=~/^tpsetctxt$/
0528             ||$func_name=~/^tpfreectxt$/
0529             ||$func_name=~/^tpterm$/
0530         )
0531         {
0532             $priv_flags = "CTXT_PRIV_NSTD|CTXT_PRIV_UBF| CTXT_PRIV_ATMI | CTXT_PRIV_IGN| CTXT_PRIV_TRAN";
0533         }
0534         else
0535         {
0536             $priv_flags = "CTXT_PRIV_NSTD|CTXT_PRIV_UBF| CTXT_PRIV_ATMI | CTXT_PRIV_IGN";
0537         }
0538         
0539     }
0540     elsif($M_name=~/oubf/)
0541     {
0542         $priv_flags = "CTXT_PRIV_NSTD|CTXT_PRIV_UBF | CTXT_PRIV_IGN";
0543     }
0544     elsif($M_name=~/onerror/)
0545     {
0546         $priv_flags = "CTXT_PRIV_NSTD | CTXT_PRIV_IGN";
0547     }
0548     elsif($M_name=~/ondebug/)
0549     {
0550         $priv_flags = "CTXT_PRIV_NSTD | CTXT_PRIV_IGN";
0551     }
0552     
0553     $oapi_debug_entry = debug_entry($func_name, $priv_flags);
0554     $oapi_debug_return = debug_return($func_name);
0555 
0556     if ($func_type=~m/^int$/ 
0557         || $func_type=~m/^BFLDOCC$/
0558         || $func_type=~m/^long$/
0559         || $func_type=~m/^float$/
0560         || $func_type=~m/^double$/
0561         )
0562     {
0563 ################################################################################
0564 # integral type function
0565 ################################################################################
0566 $message = <<"END_MESSAGE";
0567 
0568 /**
0569  * Object-API wrapper for $func_name() - Auto generated.
0570  */
0571 expublic $sig 
0572 {
0573     $func_type ret = EXSUCCEED;
0574     int did_set = EXFALSE;
0575 
0576 $oapi_debug_entry 
0577 
0578     /* set the context */
0579     if (!((atmi_tls_t *)*p_ctxt)->is_associated_with_thread)
0580     {
0581         if (EXSUCCEED!=ndrx_tpsetctxt(*p_ctxt, 0, 
0582             $priv_flags))
0583         {
0584             userlog("ERROR! $func_name() failed to set context");
0585             EXFAIL_OUT(ret);
0586         }
0587         did_set = EXTRUE;
0588     }
0589     else if ((atmi_tls_t *)*p_ctxt != G_atmi_tls)
0590     {
0591         userlog("WARNING! $func_name() context %p thinks that it is assocated "
0592                 "with current thread, but thread is associated with %p context!",
0593                 p_ctxt, G_atmi_tls);
0594     }
0595     
0596     ret = $invoke;
0597 
0598     if (did_set)
0599     {
0600         if (TPMULTICONTEXTS!=ndrx_tpgetctxt(p_ctxt, 0, 
0601             $priv_flags))
0602         {
0603             userlog("ERROR! $func_name() failed to get context");
0604             EXFAIL_OUT(ret);
0605         }
0606     }
0607 out:
0608 $oapi_debug_return 
0609     return ret; 
0610 }
0611 
0612 END_MESSAGE
0613 ################################################################################
0614     }
0615     elsif ($func_type=~m/^void$/ && $func_name=~/^tpfreectxt$/)
0616     {
0617 ################################################################################
0618 # Special case for context free. We must not get the context anymore...
0619 # It is already made free and deallocated from globals
0620 ################################################################################
0621 $message = <<"END_MESSAGE";
0622 /**
0623  * Object-API wrapper for $func_name() - Auto generated.
0624  */
0625 expublic $sig 
0626 {
0627     int did_set = EXFALSE;
0628 
0629 $oapi_debug_entry 
0630 
0631  /* set the context */
0632     if (!((atmi_tls_t *)*p_ctxt)->is_associated_with_thread)
0633     {
0634          /* set the context */
0635         if (EXSUCCEED!=ndrx_tpsetctxt(*p_ctxt, 0,
0636             $priv_flags))
0637         {
0638             userlog("ERROR! $func_name() failed to set context");
0639         }
0640         did_set = EXTRUE;
0641     }
0642     else if ((atmi_tls_t *)*p_ctxt != G_atmi_tls)
0643     {
0644         userlog("WARNING! $func_name() context %p thinks that it is assocated "
0645                 "with current thread, but thread is associated with %p context!",
0646                 p_ctxt, G_atmi_tls);
0647     }
0648 
0649     $invoke;
0650 
0651     *p_ctxt = NULL;
0652 
0653 out:
0654 $oapi_debug_return
0655     return;
0656 }
0657 
0658 END_MESSAGE
0659 ################################################################################
0660     }
0661     elsif ($func_type=~m/^void$/)
0662     {
0663 ################################################################################
0664 # Void function
0665 ################################################################################
0666 $message = <<"END_MESSAGE";
0667 /**
0668  * Object-API wrapper for $func_name() - Auto generated.
0669  */
0670 expublic $sig 
0671 {
0672     int did_set = EXFALSE;
0673 
0674 $oapi_debug_entry 
0675 
0676  /* set the context */
0677     if (!((atmi_tls_t *)*p_ctxt)->is_associated_with_thread)
0678     {
0679          /* set the context */
0680         if (EXSUCCEED!=ndrx_tpsetctxt(*p_ctxt, 0,
0681             $priv_flags))
0682         {
0683             userlog("ERROR! $func_name() failed to set context");
0684         }
0685         did_set = EXTRUE;
0686     }
0687     else if ((atmi_tls_t *)*p_ctxt != G_atmi_tls)
0688     {
0689         userlog("WARNING! $func_name() context %p thinks that it is assocated "
0690                 "with current thread, but thread is associated with %p context!",
0691                 p_ctxt, G_atmi_tls);
0692     }
0693 
0694     $invoke;
0695 
0696     if (did_set)
0697     {
0698         if (TPMULTICONTEXTS!=ndrx_tpgetctxt(p_ctxt, 0,
0699             $priv_flags))
0700         {
0701             userlog("ERROR! $func_name() failed to get context");
0702         }
0703     }
0704 out:
0705 $oapi_debug_return
0706     return;
0707 }
0708 
0709 END_MESSAGE
0710 ################################################################################
0711     }
0712     elsif ($func_type=~m/^long \*$/ 
0713         || $func_type=~m/^char \*$/
0714         || $func_type=~m/^UBFH \*$/
0715         || $func_type=~m/^int \*$/
0716         )
0717     {
0718 ################################################################################
0719 # pointer function
0720 ################################################################################
0721 $message = <<"END_MESSAGE";
0722 
0723 /**
0724  * Object-API wrapper for $func_name() - Auto generated.
0725  */
0726 expublic $sig 
0727 {
0728     int did_set = EXFALSE;
0729     $func_type ret = NULL;
0730 
0731 $oapi_debug_entry 
0732     
0733     if (!((atmi_tls_t *)*p_ctxt)->is_associated_with_thread)
0734     {
0735         /* set the context */
0736         if (EXSUCCEED!=ndrx_tpsetctxt(*p_ctxt, 0, 
0737             $priv_flags))
0738         {
0739             userlog("ERROR! $func_name() failed to set context");
0740             ret = NULL;
0741             goto out;
0742         }
0743         did_set = EXTRUE;
0744     }
0745     else if ((atmi_tls_t *)*p_ctxt != G_atmi_tls)
0746     {
0747         userlog("WARNING! $func_name() context %p thinks that it is assocated "
0748                 "with current thread, but thread is associated with %p context!",
0749                 p_ctxt, G_atmi_tls);
0750     }
0751     
0752     ret = $invoke;
0753 
0754     if (did_set)
0755     {
0756         if (TPMULTICONTEXTS!=ndrx_tpgetctxt(p_ctxt, 0,
0757                 $priv_flags))
0758         {
0759             userlog("ERROR! $func_name() failed to get context");
0760             ret = NULL;
0761             goto out;
0762         }
0763     }
0764 out:
0765 $oapi_debug_return
0766     return ret; 
0767 }
0768 
0769 END_MESSAGE
0770 ################################################################################
0771     }
0772     elsif ($func_type=~m/^BFLDID$/)
0773     {
0774 ################################################################################
0775 # BFLDID function
0776 ################################################################################
0777 $message = <<"END_MESSAGE";
0778 
0779 /**
0780  * Object-API wrapper for $func_name() - Auto generated.
0781  */
0782 expublic $sig 
0783 {
0784     $func_type ret = BBADFLDID;
0785     int did_set = EXFALSE;
0786 
0787 $oapi_debug_entry 
0788  
0789     if (!((atmi_tls_t *)*p_ctxt)->is_associated_with_thread)
0790     {
0791         /* set the context */
0792         if (EXSUCCEED!=ndrx_tpsetctxt(*p_ctxt, 0, 
0793             $priv_flags))
0794         {
0795             userlog("ERROR! $func_name() failed to set context");
0796             ret = BBADFLDID;
0797             goto out;
0798         }
0799         did_set = EXTRUE;
0800     }
0801     else if ((atmi_tls_t *)*p_ctxt != G_atmi_tls)
0802     {
0803         userlog("WARNING! $func_name() context %p thinks that it is assocated "
0804                 "with current thread, but thread is associated with %p context!",
0805                 p_ctxt, G_atmi_tls);
0806     }
0807 
0808     ret = $invoke;
0809 
0810     if (did_set)
0811     {
0812         if (TPMULTICONTEXTS!=ndrx_tpgetctxt(p_ctxt, 0,
0813             $priv_flags))
0814         {
0815             userlog("ERROR! $func_name() failed to get context");
0816             ret = BBADFLDID;
0817             goto out;
0818         }
0819     }
0820 out:
0821 $oapi_debug_return
0822     return ret; 
0823 }
0824 
0825 END_MESSAGE
0826 ################################################################################
0827     }
0828     else
0829     {
0830         # return if unsupported
0831         print "!!! Unsupported return type [$func_type]\n";
0832         return;
0833     }
0834     
0835     print $M_c_fd $message;
0836     
0837 }
0838 
0839 
0840 open_h();
0841 open_c();
0842 ################################################################################
0843 # Open source file
0844 ################################################################################
0845 my $file = $opt_i;
0846 open my $info, $file or die "Could not open $file: $!";
0847 
0848 NEXT: while( my $line = <$info>)
0849 {   
0850     chomp $line;
0851     
0852     if ($line =~ m/extern NDRX_API.*\(.*/)
0853     {
0854         # read next line, if line not completed
0855         if ($line !~ m/\);\s*/)
0856         {
0857             my $next_line = <$info>;
0858             chomp $next_line;
0859 
0860             $next_line =~ s/^\s+//;
0861             $next_line =~ s/\s+$//;
0862 
0863             $line = $line.$next_line;
0864         }
0865 
0866         # skip some lines which we cannot parse
0867         if ($line =~ m/_tmgetsvrargs/)
0868         {
0869             next NEXT;
0870         }
0871 
0872         #Strip off any comments found
0873         $line =~ s/(\/\*.*\*\/)//gi;
0874 
0875         # Now get the function return type, name and arguments list
0876         my ($func_type, $func_name, $func_args_list) = 
0877                     ($line=~m/^extern NDRX_API\s*([A-Za-z0-9_]+\s*\**)\s*([A-Za-z0-9_]+)\s*\((.*)\)\s*;/);
0878 
0879 
0880         $func_type = remove_white_space($func_type);
0881         $func_name = remove_white_space($func_name);
0882         $func_args_list = remove_white_space($func_args_list);
0883 
0884         print "Processing line [$line] M_name = [$M_name]\n";
0885         
0886         #
0887         # Special case for tpsetunsol
0888         #
0889         if ($line =~ m/.*tpsetunsol.*/)
0890         {
0891         if ($M_name =~ m/^oatmi$/)
0892         {
0893             # This is ours..
0894             write_h_tpsetunsol();
0895             write_c_tpsetunsol();
0896             next NEXT;
0897         }
0898         else
0899         {
0900             print "skip - next\n";
0901             next NEXT;
0902         }
0903         }
0904 
0905         #
0906         # Skip the specific symbols, per output module
0907         #
0908         if ($M_name =~ m/^oatmisrv_integra$/)
0909         {
0910               # Skip the names from ATMI level
0911             if ($func_name !~ m/ndrx_main_integra/)
0912             {
0913                 print "skip - next\n";
0914                 next NEXT;
0915             }
0916         }
0917         elsif ($M_name =~ m/^oatmisrv$/)
0918         {
0919             # Include only server commands for ATMISRV level
0920             if ($func_name !~ m/tpreturn/
0921                 && $func_name !~ m/tpforward/
0922                 && $func_name !~ m/tpadvertise_full/
0923                 && $func_name !~ m/tpunadvertise/
0924                 && $func_name !~ m/tpext_addpollerfd/
0925                 && $func_name !~ m/tpext_delpollerfd/
0926                 && $func_name !~ m/tpext_addb4pollcb/
0927                 && $func_name !~ m/tpsrvsetctxdata/
0928                 && $func_name !~ m/tpsrvfreectxdata/
0929                 && $func_name !~ m/tpext_addperiodcb/
0930                 && $func_name !~ m/^ndrx_main$/
0931                 # This goes to integration module
0932                 #&& $func_name !~ m/ndrx_main_integra/ 
0933                 && $func_name !~ m/tpcontinue/
0934                 && $func_name !~ m/tpext_delb4pollcb/
0935                 && $func_name !~ m/tpext_delperiodcb/
0936                 && $func_name !~ m/tpgetsrvid/
0937                 && $func_name !~ m/tpreturn/
0938                 && $func_name !~ m/tpsrvgetctxdata/
0939                 && $func_name !~ m/tpsrvsetctxdata/
0940                 && $func_name !~ m/tpsrvfreectxdata/
0941                 && $func_name !~ m/tpunadvertise/
0942                 && $func_name !~ m/tpexit/
0943                 )
0944             {
0945                 print "skip - next\n";
0946                 next NEXT;
0947             }
0948         }
0949         elsif ($M_name =~ m/^oatmi$/)
0950         {
0951             # Skip the names from ATMI level
0952             if ($line =~ m/G_tpsvrinit__/
0953                 || $line =~ m/G_tpsvrdone__/ 
0954                 || $func_name =~ m/ndrx_main$/
0955                 || $func_name =~ m/_tmstartserver$/
0956                 || $func_name =~ m/_tmrunserver$/
0957                 || $func_name =~ m/_tmgetsvrargs$/
0958                 || $func_name =~ m/ndrx_main_integra/ 
0959                 || $func_name =~ m/ndrx_atmi_tls_get/
0960                 || $func_name =~ m/ndrx_atmi_tls_set/
0961                 || $func_name =~ m/ndrx_atmi_tls_free/
0962                 || $func_name =~ m/ndrx_atmi_tls_new/
0963                 # Skip the server stuff
0964                 || $func_name =~ m/tpreturn/
0965                 || $func_name =~ m/tpforward/
0966                 || $func_name =~ m/tpadvertise_full/
0967                 || $func_name =~ m/tpunadvertise/
0968                 || $func_name =~ m/tpservice/
0969                 || $func_name =~ m/tpext_addpollerfd/
0970                 || $func_name =~ m/tpext_delpollerfd/
0971                 || $func_name =~ m/tpext_addb4pollcb/
0972                 || $func_name =~ m/tpsrvsetctxdata/
0973                 || $func_name =~ m/tpsrvfreectxdata/
0974                 || $func_name =~ m/tpext_addperiodcb/
0975                 || $func_name =~ m/tpsvrinit/
0976                 || $func_name =~ m/tpgetsrvid/
0977                 || $func_name =~ m/tpsrvgetctxdata/
0978                 || $func_name =~ m/tpext_delb4pollcb/
0979                 || $func_name =~ m/tpsvrdone/
0980                 || $func_name =~ m/tpsvrthrinit/
0981                 || $func_name =~ m/tpsvrthrdone/
0982                 || $func_name =~ m/tpcontinue/
0983                 || $func_name =~ m/tpext_delperiodcb/
0984                 || $func_name =~ m/tpexit/
0985                 )
0986             {
0987                 print "skip - next\n";
0988                 next NEXT;
0989             }
0990         }
0991         elsif ($M_name =~ m/^oubf$/)
0992         {
0993             # Skip some bits from UBF level
0994             if ($func_name =~ m/^ndrx_ubf_tls_get$/
0995                 && $func_name =~ m/^ndrx_ubf_tls_set$/
0996                 && $func_name =~ m/^ndrx_ubf_tls_free$/
0997                 && $func_name =~ m/^ndrx_ubf_tls_new$/
0998                 )
0999             {
1000                 print "skip - next\n";
1001                 next NEXT;
1002             }
1003         }
1004         elsif ($M_name =~ m/^ondebug$/)
1005         {
1006             # Include logging commands only
1007             if ($func_name !~ m/^tplogdumpdiff$/
1008                 && $func_name !~ m/^tplogdump$/
1009                 && $func_name !~ m/^tplog$/
1010                 && $func_name !~ m/^tplogex$/
1011                 && $func_name !~ m/^tplogqinfo$/
1012                 && $func_name !~ m/^tploggetiflags$/
1013 
1014                 && $func_name !~ m/^ndrxlogdumpdiff$/
1015                 && $func_name !~ m/^ndrxlogdump$/
1016                 && $func_name !~ m/^ndrxlog$/
1017                 && $func_name !~ m/^ndrxlogex$/
1018 
1019                 && $func_name !~ m/^ubflogdumpdiff$/
1020                 && $func_name !~ m/^ubflogdump$/
1021                 && $func_name !~ m/^ubflog$/
1022                 && $func_name !~ m/^ubflogex$/
1023 
1024                 && $func_name !~ m/^tploggetreqfile$/
1025                 && $func_name !~ m/^tplogconfig$/
1026                 && $func_name !~ m/^tplogclosereqfile$/
1027                 && $func_name !~ m/^tplogclosethread$/
1028                 && $func_name !~ m/^tplogsetreqfile_direct$/
1029                 )
1030             {
1031                 print "skip - next\n";
1032                 next NEXT;
1033             }
1034         }
1035         elsif ($M_name =~ m/^onerror$/)
1036         {
1037             # Include only server commands for ATMISRV level
1038             if ($func_name !~ m/^Nstrerror$/
1039                 && $func_name !~ m/^_Nget_Nerror_addr$/
1040                 )
1041             {
1042                 print "skip - next\n";
1043                 next NEXT;
1044             }
1045         }
1046         # We need stuff for ndebug.h & nerror.h and this goes to ATMI level...
1047 
1048 
1049         # Process next, parse arguments and their types
1050         print "func_type      = [$func_type]\n";
1051         print "func_name      = [$func_name]\n";
1052         print "func_args_list = [$func_args_list]\n";
1053 
1054         my @func_arg_type = ();
1055         my @func_arg_name = ();
1056         my @func_arg_def = (); # in case if pointer to function used...
1057 
1058         #
1059         # Fix callbacks with commas
1060         #
1061         #my @args = split(/\,/, $func_args_list);
1062         my @args = split_by_comma_but_not_parenthesis($func_args_list);
1063 
1064         if ($func_args_list=~m/^void$/)
1065         {
1066             push @func_arg_type, "void";
1067         }
1068         else
1069         {
1070             # Extract the data type and ar
1071 
1072             SKIP_TYPE: foreach my $pair ( @args )
1073             {
1074                 $pair = remove_white_space($pair);
1075 
1076                 my $type = "";
1077                 my $name = "";
1078                 my $sign = "";
1079                 my $def = $pair;
1080 
1081 
1082                 if ($pair=~m/\(.*\)\(.*\)/)
1083                 {
1084                     print "Got ptr to function...\n";
1085                     ($name) = ($pair=~m/\(\s*\*(.*)\)\(.*\)/);
1086                 }
1087                 else
1088                 {
1089                     print "Normal type...\n";
1090                     ($sign, $type, $name) = 
1091                         ($pair=~m/^\s*(unsigned\s*|const\s*)?([A-Za-z0-9_]+\s*\**)\s*([A-Za-z0-9_]+)/);
1092                     $sign = remove_white_space($sign);
1093                     $type = remove_white_space($type);
1094                     $name = remove_white_space($name);
1095 
1096                     if ($sign!~m/^$/)
1097                     {
1098                         $type = "$sign $type";
1099                     }
1100                 }
1101 
1102                 #
1103                 # Seems like split_by_comma_but_not_parenthesis()
1104                 # generates last block empty.
1105                 #
1106                 if ($name=~m/^$/)
1107                 {
1108                     next SKIP_TYPE;
1109                 }
1110 
1111                 push @func_arg_def, $pair;
1112 
1113                 print "got param (pair: [$pair]), sign: [$sign], type: [$type], name: [$name], def: [$def]\n";
1114                 push @func_arg_type, $type;
1115                 push @func_arg_name, $name; 
1116             }
1117         }
1118         
1119         # Generate signature
1120         my $sig = gen_sig($func_type, $func_name, $func_args_list);
1121         
1122         # Write header;
1123         write_h($sig);
1124         
1125         # write func out
1126         write_c($func_type, $func_name, $sig, $func_args_list, 
1127             \@func_arg_type, \@func_arg_name, \@func_arg_def);
1128     }
1129 }
1130 
1131 close $info;
1132 
1133 close_h();
1134 close_c();
1135 
1136 # vim: set ts=4 sw=4 et smartindent: