Back to home page

Enduro/X

 
 

    


0001 /**
0002  * @brief Generate code for size & offset calculations done by compile & exec of the binary
0003  *   The generated binary will actually plot the object .V file.
0004  *
0005  * @file codegen.c
0006  */
0007 /* -----------------------------------------------------------------------------
0008  * Enduro/X Middleware Platform for Distributed Transaction Processing
0009  * Copyright (C) 2009-2016, ATR Baltic, Ltd. All Rights Reserved.
0010  * Copyright (C) 2017-2023, Mavimax, Ltd. All Rights Reserved.
0011  * This software is released under one of the following licenses:
0012  * AGPL (with Java and Go exceptions) or Mavimax's license for commercial use.
0013  * See LICENSE file for full text.
0014  * -----------------------------------------------------------------------------
0015  * AGPL license:
0016  *
0017  * This program is free software; you can redistribute it and/or modify it under
0018  * the terms of the GNU Affero General Public License, version 3 as published
0019  * by the Free Software Foundation;
0020  *
0021  * This program is distributed in the hope that it will be useful, but WITHOUT ANY
0022  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
0023  * PARTICULAR PURPOSE. See the GNU Affero General Public License, version 3
0024  * for more details.
0025  *
0026  * You should have received a copy of the GNU Affero General Public License along 
0027  * with this program; if not, write to the Free Software Foundation, Inc.,
0028  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0029  *
0030  * -----------------------------------------------------------------------------
0031  * A commercial use license is available from Mavimax, Ltd
0032  * contact@mavimax.com
0033  * -----------------------------------------------------------------------------
0034  */
0035 
0036 /*---------------------------Includes-----------------------------------*/
0037 
0038 #include <unistd.h>
0039 #include <stdio.h>
0040 #include <errno.h>
0041 #include <stdlib.h>
0042 #include <atmi.h>
0043 
0044 #include <ubf.h>
0045 #include <ferror.h>
0046 #include <fieldtable.h>
0047 #include <fdatatype.h>
0048 
0049 #include <ndrstandard.h>
0050 #include <ndebug.h>
0051 #include <errno.h>
0052 #include "viewc.h"
0053 #include <typed_view.h>
0054 /*---------------------------Externs------------------------------------*/
0055 /*---------------------------Macros-------------------------------------*/
0056 /*---------------------------Enums--------------------------------------*/
0057 /*---------------------------Typedefs-----------------------------------*/
0058 /*---------------------------Globals------------------------------------*/
0059 /*---------------------------Statics------------------------------------*/
0060 /*---------------------------Prototypes---------------------------------*/
0061 
0062 /**
0063  * Compile the code and invoke offset calculator...
0064  * @param sourcecode
0065  * @param ofile
0066  * @return EXSUCCEED/EXFAIL
0067  */
0068 exprivate int ndrx_view_invoke(char *sourcecode, char *ofile)
0069 {
0070     int ret = EXSUCCEED;
0071     char build_cmd[NDRX_BPATH_MAX+1];
0072     
0073     
0074     snprintf(build_cmd, sizeof(build_cmd), "%s -f %s -o %s", 
0075             ndrx_G_build_cmd, sourcecode, ofile);
0076     
0077     NDRX_LOG(log_info, ">>> About to execute: [%s]", build_cmd);
0078     
0079     if (EXSUCCEED!=system(build_cmd))
0080     {
0081         NDRX_LOG(log_error, "%s FAILED - Failed to build offset calc program", 
0082                 build_cmd);
0083         EXFAIL_OUT(ret);
0084     }
0085     
0086     NDRX_LOG(log_info, ">>> About to execute compiled binary to build V object: [%s]", ofile);
0087     
0088     if (EXSUCCEED!=system(ofile))
0089     {
0090         NDRX_LOG(log_error, "%s FAILED - Failed to calculate offsets!", 
0091                 ofile);
0092         EXFAIL_OUT(ret);
0093     }
0094     
0095 out:
0096     return ret;
0097 }
0098 
0099 /**
0100  * Plot the C header file.
0101  * This will generate all the stuff loaded into memory, if multiple view files
0102  * loaded, then output will go to this one. This must be followed by developers.
0103  * @param basename - file name with out extension
0104  * @param ofile the path to object file built
0105  * @return EXSUCCEED/EXFAIL
0106  */
0107 expublic int ndrx_view_generate_code(char *outdir, char *basename, 
0108         char *vsrcfile, char *Vfile, int no_UBF)
0109 {
0110     int ret = EXSUCCEED;
0111     FILE *f = NULL;
0112     char cfile[NDRX_BPATH_MAX+1];
0113     char ofile[NDRX_BPATH_MAX+1];
0114     ndrx_typedview_t * views = ndrx_view_get_handle();
0115     ndrx_typedview_t * vel, *velt;
0116     ndrx_typedview_field_t * fld;
0117     
0118     snprintf(cfile, sizeof(cfile), "%s_excompiled.c", basename);
0119     snprintf(ofile, sizeof(ofile), "./%s_excompiled", basename);
0120     snprintf(Vfile, PATH_MAX+1, "%s/%s.V", outdir, basename);
0121     
0122     NDRX_LOG(log_info, "C-Code to compile: [%s]", cfile);
0123     NDRX_LOG(log_info, "Compiled binary: [%s]", ofile);
0124     NDRX_LOG(log_info, "Compiled VIEW: [%s]", Vfile);
0125     NDRX_LOG(log_info, "Source VIEW: [%s]", vsrcfile);
0126     
0127     /* get the temp-file-name, it will be 
0128      * <basename>_excompiled.c and code <basename>_excompiled 
0129      */
0130     
0131     if (NULL==(f=NDRX_FOPEN(cfile, "w")))
0132     {
0133         NDRX_LOG(log_error, "Failed to open for write [%s]: %s", 
0134                 cfile, strerror(errno));
0135         EXFAIL_OUT(ret);
0136     }
0137     
0138     /* We need offsets for L_ and C_ fields... */
0139     
0140     fprintf(f, "/* Offset calculation auto-generated code */\n");
0141     fprintf(f, "/*---------------------------Includes-----------------------------------*/\n");
0142     fprintf(f, "#include <unistd.h>\n");
0143     fprintf(f, "#include <stdio.h>\n");
0144     fprintf(f, "#include <errno.h>\n");
0145     fprintf(f, "#include <stdlib.h>\n");
0146     fprintf(f, "#include <string.h>\n");
0147     fprintf(f, "#include <ndrstandard.h>\n");
0148     fprintf(f, "#include <ndebug.h>\n");
0149     fprintf(f, "#include <errno.h>\n");
0150     fprintf(f, "#include <view_cmn.h>\n");
0151     fprintf(f, "#include <atmi.h>\n");
0152     fprintf(f, "\n");
0153     fprintf(f, "/* Include auto-generated hdr: */\n");
0154     fprintf(f, "#include \"%s.h\"\n", basename);
0155     fprintf(f, "/*---------------------------Externs------------------------------------*/\n");
0156     fprintf(f, "/*---------------------------Macros-------------------------------------*/\n");
0157     fprintf(f, "/*---------------------------Enums--------------------------------------*/\n");
0158     fprintf(f, "/*---------------------------Typedefs-----------------------------------*/\n");
0159     fprintf(f, "/*---------------------------Globals------------------------------------*/\n");
0160     fprintf(f, "/*---------------------------Statics------------------------------------*/\n");
0161     fprintf(f, "/*---------------------------Prototypes---------------------------------*/\n");
0162     fprintf(f, "\n");
0163     fprintf(f, "/* Offset Calculator main  */\n");
0164     fprintf(f, "int main (int argc, char **argv)\n");
0165     fprintf(f, "{\n");
0166     fprintf(f, "    FILE *f = NULL;\n");
0167     fprintf(f, "    int ret = EXSUCCEED;\n");
0168     fprintf(f, "    char *output_file = \"%s\";\n", Vfile);
0169     fprintf(f, "    char *input_file = \"%s\";\n\n", vsrcfile);
0170     
0171     /* Generate definitions */
0172     EXHASH_ITER(hh, views, vel, velt)
0173     {
0174         fprintf(f, "    static ndrx_view_offsets_t  offs_%s[]=\n", vel->vname);
0175         fprintf(f, "    {\n");
0176             
0177         DL_FOREACH(vel->fields, fld)
0178         {
0179             char C_field[NDRX_VIEW_CNAME_LEN*3]="EXFAIL";
0180             char L_field[NDRX_VIEW_CNAME_LEN*3]="EXFAIL";
0181             
0182             if (fld->flags & NDRX_VIEW_FLAG_ELEMCNT_IND_C)
0183             {
0184                 snprintf(C_field, sizeof(C_field), "EXOFFSET(struct %s, C_%s)", 
0185                         vel->vname, fld->cname);
0186             }
0187 
0188             if (fld->flags & NDRX_VIEW_FLAG_LEN_INDICATOR_L)
0189             {
0190                 snprintf(L_field, sizeof(L_field), "EXOFFSET(struct %s, L_%s)", 
0191                         vel->vname, fld->cname);
0192             }
0193             
0194             fprintf(f, "        {\"%s\", EXOFFSET(struct %s, %s), EXELEM_SIZE(struct %s, %s), %s, %s},\n",
0195                     fld->cname, 
0196                     vel->vname, fld->cname, 
0197                     vel->vname, fld->cname,
0198                     C_field, L_field
0199                     );
0200         }
0201         
0202         fprintf(f, "        {NULL}\n");
0203         fprintf(f, "    };\n\n");    
0204     }
0205     
0206     fprintf(f, "    ndrx_view_loader_configure(%d);\n\n", no_UBF);
0207 
0208     fprintf(f, "    /* Load view file.. */\n");
0209     fprintf(f, "    if (EXSUCCEED!=ndrx_view_load_file(input_file, EXFALSE))\n");
0210     fprintf(f, "    {\n");
0211     fprintf(f,"%s", "        NDRX_LOG(log_error, \"Failed to load source VIEW file [%s]: %s\", \n");
0212     fprintf(f, "                input_file, tpstrerror(tperrno));\n");
0213     fprintf(f, "        EXFAIL_OUT(ret);\n");
0214     fprintf(f, "    }\n\n");
0215     
0216     /* Generate update offsets... */
0217     EXHASH_ITER(hh, views, vel, velt)
0218     {
0219         fprintf(f, "    if (EXSUCCEED!=ndrx_view_update_object(\"%s\", sizeof(struct %s)))\n", 
0220                 vel->vname, vel->vname);
0221         
0222         fprintf(f, "    {\n");
0223         fprintf(f, "        EXFAIL_OUT(ret);\n");
0224         fprintf(f, "    }\n\n");
0225         
0226         fprintf(f, "    if (EXSUCCEED!=ndrx_view_update_offsets(\"%s\", offs_%s))\n", 
0227                 vel->vname, vel->vname);
0228         
0229         fprintf(f, "    {\n");
0230         fprintf(f, "        EXFAIL_OUT(ret);\n");
0231         fprintf(f, "    }\n\n");
0232     }
0233     
0234     
0235     fprintf(f, "    if (NULL==(f=fopen(output_file, \"w\")))\n");
0236     fprintf(f, "    {");
0237     fprintf(f, "        int err =errno;\n");
0238     fprintf(f, "%s", "        NDRX_LOG(log_error, \"Failed to open output file: %s\", strerror(err));\n");
0239     fprintf(f, "        EXFAIL_OUT(ret);\n");
0240     fprintf(f, "    }\n\n");
0241 
0242     
0243     fprintf(f, "    if (EXSUCCEED!=ndrx_view_plot_object(f))\n");
0244     fprintf(f, "    {\n");
0245     fprintf(f, "        NDRX_LOG(log_error, \"Failed to plot VIEW object file!\");\n");
0246     fprintf(f, "        EXFAIL_OUT(ret);\n");
0247     fprintf(f, "    }\n");
0248     fprintf(f, "\n");
0249     fprintf(f, "\n");
0250     fprintf(f, "out:\n");
0251     fprintf(f, "\n");
0252     fprintf(f, "    if (NULL!=f)\n");
0253     fprintf(f, "    {\n");
0254     fprintf(f, "        fclose(f);\n");
0255     fprintf(f, "    }\n");
0256     fprintf(f, "\n");
0257     fprintf(f, "    if (EXSUCCEED!=ret)\n");
0258     fprintf(f, "    {\n");
0259     fprintf(f, "        unlink(output_file);\n");
0260     fprintf(f, "    }\n");
0261     fprintf(f, "\n");
0262     fprintf(f, "    return ret;\n");
0263     fprintf(f, "}\n");
0264 
0265     
0266     NDRX_FCLOSE(f);
0267     f = NULL;
0268     
0269     if (EXSUCCEED!=ndrx_view_invoke(cfile, ofile))
0270     {
0271         NDRX_LOG(log_error, "Failed to compile VIEW!");
0272         EXFAIL_OUT(ret);
0273     }
0274     else  
0275     {
0276         NDRX_LOG(log_info, "Compiled VIEW file: %s", Vfile);
0277     }
0278     
0279 out:
0280 
0281     if (NULL!=f)
0282     {
0283         NDRX_FCLOSE(f);
0284     }
0285 
0286     unlink(cfile);
0287     unlink(ofile);
0288 
0289     return ret;
0290 }
0291 
0292 /* vim: set ts=4 sw=4 et smartindent: */