| |||||||||||
Module implementing driver 'toC' to save the compilation result to a C file Description A module implementing the driver 'toC' to save the result of
a Mosel model compilation to a C file: the execution of the generated
program performs the model processing. Further explanation of this example: Whitepaper 'Generalized file handling in Mosel', Section 8.2 Example: code generation
Source Files By clicking on a file name, a preview is opened at the bottom of this page.
export.c /****************************************** Mosel NI Examples ================= File export.c ````````````` Example module defining an IO driver that generates a C-file embedding a model (c) 2008 Fair Isaac Corporation author: Y. Colombani, 2003 *******************************************/ #include <stdlib.h> #include <stdio.h> #include <string.h> #include "xprm_ni.h" static char prg_part1[]= "#include <stdio.h>\n" "#include \"xprm_rt.h\"\n\n" "static unsigned int bimfile[]={"; static char prg_part2[]= "0};\n\n" "int main(int argc,char *argv[])\n" "{\n" " char modname[40];\n" " XPRMmodel mod;\n" " int rts;\n\n" " rts=XPRMinit();\n" " if((rts!=0)&&(rts!=32))\n" " {\n" " char msg[512];\n\n" " XPRMgetlicerrmsg(msg,512);\n" " fprintf(stderr,\"%s\",msg);\n" " return 1;\n" " }\n\n" #ifdef _WIN32 " sprintf(modname,\"mem:%#Ix/%u\",\n" " (size_t)bimfile,"; #else " sprintf(modname,\"mem:%#lx/%u\",\n" " (unsigned long)bimfile,"; #endif static char prg_part3[]= ");\n" " if((mod=XPRMloadmod(modname,NULL))==NULL)\n" " return 2;\n" " if(XPRMrunmod(mod,&rts,NULL))\n" " return 3;\n" " else\n" " return rts;\n" "}\n"; typedef struct { unsigned int total; /* Total number of bytes written so far */ union { char c[4]; unsigned int i; } map; /* Mapping between 4 chars and an integer */ int nb_remain; /* Number of bytes not yet written */ int nb_printed; /* Number of numbers written on the line */ } s_tocdata; /*******************************************************/ /* toC driver: to generate a C program from a bim file */ /* Example: "export.toC:mymodel.c" */ /* Using it from Mosel console: */ /* compile mymodel '' export.toC:mymodel.c */ /*******************************************************/ /* Functions of 'toC' driver */ static void *toc_open(XPRMcontext ctx,int *mode,const char *fname); static int toc_close(XPRMcontext ctx,s_tocdata *td,int mode); static long toc_write(XPRMcontext ctx,s_tocdata *td,char *buffer, unsigned long size); static XPRMiofcttab iodrv_toc[]= { {XPRM_IOCTRL_OPEN,(void *)toc_open}, {XPRM_IOCTRL_CLOSE,(void *)toc_close}, {XPRM_IOCTRL_WRITE,(void *)toc_write}, {XPRM_IOCTRL_INFO,"extended_filename"}, {0,NULL} }; /* Drivers of export module: toC */ static XPRMiodrvtab iodrv_export[]= { {"toC",iodrv_toc}, {NULL,NULL} }; /* Table of services: only IO drivers */ static XPRMdsoserv tabserv[]= { {XPRM_SRV_IODRVS,iodrv_export} }; /* DSO interface: only services */ static XPRMdsointer dsointer= { 0,NULL, 0,NULL, 0,NULL, sizeof(tabserv)/sizeof(mm_dsoserv),tabserv }; static XPRMnifct mm; /* For storing Mosel NI function table */ /************************************************/ /* Initialize the library just after loading it */ /************************************************/ DSO_INIT export_init(XPRMnifct nifct, int *interver,int *libver, XPRMdsointer **interf) { mm=nifct; /* Save the table of Mosel NI functions */ *interver=XPRM_NIVERS; /* The interface version we are using */ *libver=XPRM_MKVER(0,0,1); /* The version of the module: 0.0.1 */ *interf=&dsointer; /* Our interface */ return 0; } /*****************************/ /* Open the C-file to create */ /*****************************/ static void *toc_open(XPRMcontext ctx,int *mode,const char *fname) { s_tocdata *td; /* 1st: open actual file */ if(mm->fopen(ctx,*mode,fname)<0) { *mode|=XPRM_F_SILENT; /* Error message already displayed */ /* switch so silent mode */ return NULL; } else { td=(s_tocdata *)malloc(sizeof(s_tocdata)); td->total=0; td->nb_remain=0; td->nb_printed=0; mm->printf(ctx,"%s\n",prg_part1); /* Display the beginning of program */ return td; } } /********************/ /* Close the C-file */ /********************/ static int toc_close(XPRMcontext ctx,s_tocdata *td,int mode) { if(td->nb_remain>0) /* Send bytes to be written */ { td->total+=td->nb_remain; for(;td->nb_remain<4;td->nb_remain++) td->map.c[td->nb_remain]=0; mm->printf(ctx,"%#x,",td->map.i); } /* and complete program */ mm->printf(ctx,"%s%u%s",prg_part2,td->total,prg_part3); return mm->fclose(ctx,mode); } /**************************/ /* Write a list of values */ /**************************/ static long toc_write(XPRMcontext ctx,s_tocdata *td,char *buffer, unsigned long size) { int i; if(size+td->nb_remain<4) /* Not enough for an integer... */ { for(i=0;i<size;i++) td->map.c[td->nb_remain+i]=buffer[i]; td->nb_remain+=size; /* store them for next call */ } else { if(td->nb_remain>0) /* Bytes from previous call first... */ { for(i=0;i<4-td->nb_remain;i++) td->map.c[td->nb_remain+i]=buffer[i]; mm->printf(ctx,"%#x,",td->map.i); td->total+=4; td->nb_printed++; size-=4-td->nb_remain; buffer-=4-td->nb_remain; } while(size>=4) /* then the buffer we receive */ { td->map.c[0]=buffer[0]; td->map.c[1]=buffer[1]; td->map.c[2]=buffer[2]; td->map.c[3]=buffer[3]; mm->printf(ctx,"%#x,",td->map.i); size-=4; buffer+=4; td->total+=4; if(++td->nb_printed>=6) { td->nb_printed=0; mm->printf(ctx,"\n"); } } td->nb_remain=size; /* Keep track of remaining bytes */ memcpy(td->map.c,buffer,size); } return 1; } | |||||||||||
© Copyright 2024 Fair Isaac Corporation. |