/* (leave the space! lex insists on it!) Version 1.1 : P. Lebrun, Fermilab, July 1996 - Add a parameter (F77) or define (C) statement to the .inc and .h files so that we can check at mcfastRead run time if when we start overflowing the arrays. - Enforce the grouping rule upon reading a DBIN data file (F77 only), if the varname changes (refering to the template name, or the name of the data structure, then the index refering to the array of D.S. better be one, to make sure we start filling at the appropriate location. Version 1.2 : Lebrun, Fermilab, June 1997 - Add a warining if the 'database' statement is missing in the beginning of the file, to avoid such an obvious crash button. Since I am not sure where that check ought to go, this fix is probably not 100% reliable. - Fix the extraneous MAXNUM, in case of nested structure (It was my mistake!) - Fix a small XDR bug in the filter for integer arrays ------------ T. Wenaus 7/95 ToDo (.=done) ---- - $$$ f90 option on Fortran side - $$$ pointers - $$$ self-describing XDR I/O . new index behaviour; no prefix if '-' leads. . update structures . dummy word following n_obj_* in common to protect against misaligned commons . VARIABLE keyword following array declaration to stipulate that the most recent integer should be interpreted as the useful dimension of the array for XDR read/write . output of nested substructures in internal mode to XDR file implemented . eliminate C++ entirely from dbin and auxiliary code (eg. //, extern "C") . unify the Fortran and C data spaces . switch from use of CLHEP Strings to char arrays. No longer any C++ dependence in dbin. Can be used with C or C++. . ,->* in XDR filter code on dimension string; will correctly handle multi-dim arrays . write only the used number of array objects to XDR. VARIABLE keyword. . ivar eliminated; was causing fp overflows. rvar now used to load integers. - $$$ 'will generate file' report in dbin startup . access to version string - $$$ alternate (faster?) xdr encoding: copy to contiguous arrays . undimensioned instantiations . mgr code needs to be produced in close_makes since one routine for each declared structure should be generated. . handle F<-> moving routines for case of multi-dimensional arrays. [issue warning.] . XDR handling: have to handle moving of data between C data structures and Fortran data structures. Do this from the MGR routine, which performs the move before/after the XDR activity depending on encode/decode state. Need new routines, includes generated for XDR: . include file defining mapping of Fortran struct for C access . 'move from C structs to Fortran' and vice versa. . new units: fcmap -> nameFstruct.h fftoc -> nameFtoC.cc fctof -> nameCtoF.cc . add comment to GUI structure. Protect GUI, XDR code with cpp flags. . reimplement DOUBLE . xdr mgr code for multiple instantiations. Avoid code for non-existent instantiations. - verbatim directive for internal-mode (& other) include files - $$$ bounds checking for fixed-size templates - single-pass scheme for include files - command mode: - $$$ make ndim available to the user routine - $$$ make command name available to the user routine (for single-routine handling of multiple commands) - 2nd arg on dbin command line: dir to put generated sources in . dynamic instantiation of templates; declared array size . tools on Fortran and C++ sides to loop through all instantiations of an object . C++ side file handling in dbinc.cc . User's Guide . defining params in terms of other params (internal mode) FORTRAN STRUCTURES Handling of structures and templates has been converted to VMS-style Fortran structures. TEMPLATE INSTANTIATION - MAKE no longer accepts an instantiation name. Uses the index. DEFINE replaces this function of MAKE, but not fully re-implemented. GUI MENU DEFINITION - GUI menu definition file now generated: xxxxGUI.h. XDR/MCFIO DATA STRUCTURE I/O INTERNAL DATA STRUCTURE DEFINITION - MODE INTERNAL declaration - RECORD statement, instantiation handling. Instance name allowed as param on RECORD stmt. Hence multiple instantiations. - separation of structure def file from instantiation file - relaxed fixed size declarations, multi-dimensional arrays - restricted file set - different master include name, _dst - no _db extension to rerouted include file names DOUBLE - re-implemented * * dbin - DataBase INput tool * --------------------------- * * Torre Wenaus 31/12/1993 * * This utility takes an ascii parameter definition file and * using lex parsing of the file constructs * - a Fortran include file containing a common block that includes * all parameters, with explicit typing and documentation * - a Fortran routine to read the parameter definition file as the * data file that specifies parameter values, with extensive * error checking * - analogous include file and input routine in C. * * Thus given an ascii database that simultaneously specifies the * structure, mnemonic names, actual values, and documentation of * a parameter set, this package automatically generates the code * needed to read and use this database in Fortran and C programs. * * Accommodating a change in the database (eg. addition of a parameter) * involves nothing more than changing the database file itself and * rerunning this tool; a valuable simplification over the several manual * coding modifications -- in two languages if C and Fortran are * supported -- traditionally required. * * Example illustrating database file structure: * * STRUCTURE MUON ! parameter group, eg. subdetector name * REAL BLEN 400. ! barrel length * INT NBPL 24 ! number of barrel planes * REAL PLTHK(2) 1.0 2.0 ! inner and outer plate thicknesses * END STRUCTURE * * * Building variable names from mnemonics * -------------------------------------- * The derivation of variable name from the given mnemonic can be * done in whatever way is desired. What is presently done is * the first two characters of the structure (subdetector) name * are appended (with a leading _) to the mnemonic to come up with * the variable name. eg. the BLEN parameter above would have a * variable name BLEN_MU. * * * * Template structures: * -------------------- * * TEMPLATE MAT 5 ! structure template for materials, with max no. of materials * REAL A * REAL Z * REAL DENS * REAL RADL * REAL ABSL * END TEMPLATE * MAKE MAT CSI 129.97 54.02 4.51 1.86 37. ! instantiate template MAT, name CSI * MAKE MAT SCINT 6.25 3.4 1.03 43. 437. * * => COMMON // MAT_A(N_MAT), MAT_Z(N_MAT), MAT_DENS(N_MAT), MAT_RADL(N_MAT)... * IF (VARNAME.EQ.'MAT_TEMPLATE') THEN * INDEX = IMATIDX ! from lookup list using object name string * MAT_A(INDEX) = RVAR(1) * MAT_Z(INDEX) = RVAR(2) ... * * New: * - PROVIDE statement to have specified include file added to generated * .inc,.h * - FFREAD handling * - To split include file into several: * INCNAME name where name doesn't include type; .h,.inc added automatically * - dbin now accepts db filename on command line (or from stdin for backwards * compatibility). Path is prefixed to INCLUDEd files so they can be found * when the db is not in the current directory. * - .inc,.h diversion to new filename: INCNAME directive * - DIMENSION statement to generate constant integer parameter for array * dimensioning. Must appear OUTSIDE structures and templates. Variable name * is the mnemonic name without modification (so be sure to make it unique) * - INDEX statement to generate mnemonic pointers into an array. Like * DIMENSION, must appear OUTSIDE structures and templates and mnemonic * names are taken directly for variable names. * - DOUBLE supported only for structures, to reduce amount of code to be * maintained, and because only need for it I foresee is for constants * like pi. * - new COMMAND/CALL type for passing template-like structures to a * user routine for processing, rather than dbin loading the information * into dbin-defined data structures. Very much like defining and then * calling a command, hence the name. * - strings need not be quoted in COMMANDS (but ONLY in COMMANDS) * */ %p 17000 %n 2000 %a 7000 %s STRUCTURE %{ #include #include #include # define MAXLINE 2000 # define YYLMAX 2048 %} %s TEMPLATE %{ %} %s COMMAND %{ %} %s FFREAD %{ %} /***** DBIN Version number *****/ int idbin_version = 0001; char* stlower(char* st); char* stupper(char* st); void strsub(char* str, char* sub, char* repl); void check_finc_fh(); int npgmlines = 0, ntotlines = 0, ntotchars = 0, ndim = 0, n2dim = 0; int is_template = 0, n_elements = 0, n_templates = 0, indx = 0; int nguiel = 0, declare_record; int is_command = 0, new_template = 0, fixed_size = 0, print_listing = 0; int indxtot = 0, internal_mode = 0, incfile_open = 0; int nstructbase = 0, n_templ_entries = 0, ischar = 0, cray=0; int nv, nn, n, n1, np, nq; char *chmaterial = "material", *chnest = "nest", *chinternal="internal"; char dbpath[40]; /* pathname of database file */ char vartype[20], typenamc[20], typenamf[20], parent[30]; char fname[80], incfname[80], *fpnt; char dbin_dbvsn[10], dim[30], dim1[30], cstruct[30], template_size[30]; char varlist[10000], varlistc[10000], line1[MAXLINE]; int nvars = 0, nvarsc = 0; char curtype[30], curname[30], curstruct[30], fullname[30], curcomment[1000]; char values[50000], dbname[30], curvar[30], curvarc[30], *curval, *curnum, *curnumc; char uroutine[30]; char *iprefix = "ies_", *rprefix = "res_"; char *objname, *arg1, *arg2, *valpnt, *idxlst; extern char *getenv(); FILE *finc, *fh, *frdf, *frdc, *finitc, *finitf, *fopen(); FILE *fgui, *fxdr, *fxdrall, *fxdrmgr, *fxdrinc; FILE *finc_original, *fh_original; FILE *yyinlist[10]; int inlist = 0; DATABASE [ \t]*("DATABASE"|"database")+[^\n]* INTEGER [ \t]*("INT"|"int")+([^\n]*|[^\n]*(("/\n"|"/"+[ \t]*"!"+[^\n]+"\n")+[^\n]*)*) REAL [ \t]*("REAL"|"real")+([^\n]*|[^\n]*(("/\n"|"/"+[ \t]*"!"+[^\n]+"\n")+[^\n]*)*) DOUBLE [ \t]*("DOUBLE"|"double")+([^\n]*|[^\n]*(("/\n"|"/"+[ \t]*"!"+[^\n]+"\n")+[^\n]*)*) CHARACTER [ \t]*("CHAR"|"char")+([^\n]*|[^\n]*(("/\n"|"/"+[ \t]*"!"+[^\n]+"\n")+[^\n]*)*) MATERIAL [ \t]*("MATERIAL"|"material")+([^\n]*|[^\n]*(("/\n"|"/"+[ \t]*"!"+[^\n]+"\n")+[^\n]*)*) DIMENSION [ \t]*("DIMENSION"|"dimension")+([^\n]*|[^\n]*(("/\n"|"/"+[ \t]*"!"+[^\n]+"\n")+[^\n]*)*) INDEX [ \t]*("INDEX"|"index")+([^\n]*|[^\n]*(("/\n"|"/"+[ \t]*"!"+[^\n]+"\n")+[^\n]*)*) STRUCTURE [ \t]*("STRUCTURE"|"structure")+[^\n]* TEMPLATE [ \t]*("TEMPLATE"|"template")+[^\n]* RECORD [ \t]*("RECORD"|"record")+[^\n]* CHILD [ \t]*("CHILD"|"child")+[^\n]* NEST [ \t]*("NEST"|"nest")+[^\n]* PARENT [ \t]*("PARENT"|"parent")+[^\n]* MODE [ \t]*("MODE"|"mode")+[^\n]* MAKE [ \t]*("MAKE"|"make")+([^\n]*|[^\n]*(("/\n"|"/"+[ \t]*"!"+[^\n]+"\n")+[^\n]*)*) DEFINE [ \t]*("DEFINE"|"define")+([^\n]*|[^\n]*(("/\n"|"/"+[ \t]*"!"+[^\n]+"\n")+[^\n]*)*) PROVIDE [ \t]*("PROVIDE"|"provide")+[^\n]* INCLUDE [ \t]*("INCLUDE"|"include")+[^\n]* INCNAME [ \t]*("INCNAME"|"incname")+[^\n]* END [ \t]*("END"|"end")+[^\n]* FFREAD [ \t]*("FFREAD"|"ffread")+[^\n]* FFEND [ \t]*("FFEND"|"ffend")+[^\n]* FILE [ \t]*("FILE"|"file")+[^\n]* FILEEND [ \t]*("FILEEND"|"fileend")+[^\n]* COMMAND [ \t]*("COMMAND"|"command")+[^\n]* CALL [ \t]*("CALL"|"call")+[^\n]* ANY [^\n]* %% . ntotchars++; \n ntotlines++; ^{REAL}|{INTEGER}|{DOUBLE}|{CHARACTER}|{MATERIAL} { ++npgmlines; dbinparse(yytext,curtype,curname,curvar,curcomment,dim); /* turn mnemonic into variable name */ varsave(-1); fprintf(finitf,"* %s\n",line1); fprintf(finitc,"/* %s */\n",line1); fprintf(frdf, " else if (varname.eq.'%s.%s') then\n",curstruct,curname); if (strcmp(stlower(curtype),"real") == 0) { strcpy(vartype,"rvar"); strcpy(typenamf,"real"); strcpy(typenamc,"float"); } if (strcmp(stlower(curtype),"double") == 0) { strcpy(vartype,"dvar"); strcpy(typenamf,"double precision"); strcpy(typenamc,"double"); } if (strncmp(stlower(curtype),"int",3) == 0) { strcpy(vartype,"rvar"); strcpy(typenamf,"integer"); strcpy(typenamc,"int"); } if (strncmp(stlower(curtype),"char",4) == 0 || strcmp(stlower(curtype),"material") == 0) { strcpy(vartype,"chvar"); strcpy(typenamf,"character*80"); strcpy(typenamc,"char"); } if (strlen(dim) == 0) { fprintf(frdf, " %s.%s = %s(1) ! %s\n",curstruct,curname,vartype,curcomment); fprintf(finc, " %s %s ! %s\n",typenamf,curname,curcomment); if (strcmp(typenamc,"char")==0) { fprintf(frdc,"if (varname==\"%s.%s\"){ strcpy(%s->%s,chvar[0]); iok=1;}\n", curstruct,curname,curstruct,curname); fprintf(fh," %s %s[80]; /* %s */\n",typenamc,curname,curcomment); } else { fprintf(frdc,"if (varname==\"%s.%s\"){ %s->%s = %s[0]; iok=1;}\n", curstruct,curname,curstruct,curname,vartype); fprintf(fh," %s %s; /* %s */\n",typenamc,curname,curcomment); } curval = strtok(values," /\t\n"); if (strcmp(typenamc,"char")==0) { fprintf(finitc, " strcpy(%s->%s,%s);\n",curstruct,curname,curval); n1=0; while (n1%s = %s;\n",curstruct,curname,curval); } fprintf(finitf, " %s.%s = %s\n",curstruct,curname,curval); } else { if (strcmp(typenamc,"char")==0) { fprintf(frdf, " do i=1,%s ! %s\n",dim,curcomment); fprintf(frdf, " %s.%s(i) = chvar(i)\n",curstruct,curname); fprintf(frdf, " enddo\n"); } else { if (strcmp(typenamc,"double")==0) { fprintf(frdf, " call ucopy(%s,%s.%s,%s*2) ! %s\n",vartype,curstruct,curname,dim,curcomment); } else { fprintf(frdf, " call ucopy(%s,%s.%s,%s) ! %s\n",vartype,curstruct,curname,dim,curcomment); } } fprintf(finc, " %s %s(%s) ! %s\n",typenamf,curname,dim,curcomment); if (strcmp(typenamc,"char")==0) { fprintf(frdc, "if (varname==\"%s.%s\")\n {int i=0; while (i<%s) {strcpy(%s->%s[i],chvar[i]);i++;};iok=1;}\n", curstruct,curname,dim,curstruct,curname); } else { fprintf(frdc, "if (varname==\"%s.%s\")\n {int i=0; while (i<%s) {%s->%s[i]=%s[i];i++;};iok=1;}\n", curstruct,curname,dim,curstruct,curname,vartype); } strcpy(dim1,dim); strsub(dim1,",","]["); if (strcmp(typenamc,"char")==0) { fprintf(fh," %s %s[%s][80]; /* %s */\n",typenamc,curname,dim1,curcomment); } else { fprintf(fh," %s %s[%s]; /* %s */\n",typenamc,curname,dim1,curcomment); } arg1 = values; n = 0; while (n%s[%d],%s);\n",curstruct,curname,n,curval); n1=0; while (n1%s[%d] = %s;\n",curstruct,curname,n,curval); } fprintf(finitf, " %s.%s(%d) = %s\n",curstruct,curname,n+1,curval); n++; } } }