Notes on integration of metaschema- and schema-derived metadata in chgen/gencpp applications: RJLRef: $PH/05f523/NamespaceAndSchemaIntegration.* This is in response to comments by Jing Tan in 05f523. Metaschema is tables SV, TT and TA + tables proposed in $PH/COOL-GEN/hcg_struct_migration.ppt (discussed later). Schema is any other tables needed by the application. These may be spread over system service and application domains (e.g. JPsim has tables from BDE and LCP as well as passive layout and active class subschema within its process-control application). .sch and .msdat files are information-equivalent, therefore one is redundant. The content of .dat files and .msdat files both include flat files wih the same format (field name and type sequence) depending on table row (object instance) type or class. Since .msdat and .dat tables have identical meta-data formats, .msdat should be used instead of .sch. Entity types are assigned int codes as surrogates based on their declared order in the schema (or in the TT table). The [meta-data] tables (SV,TT,TA) are read-only, and should be first so they have the same position over all applications. So we can append .msdat for application tables AFTER .msdat tables SV,TT,TA. Both levels of specification will have the same format. ALL tables are parsed by chgen in the same way: ------------------------ Read the pkey field to identify the table type of each row. IFF an internal object with the same pkey exists, skip this record. This prevents TT-rows 1 2 3 and their TA-children from being over-writen or duplicated if chgen already has pre-loaded copies of these tables to refer to (as a boot-strapped version will). The parser allocates memory for an instance (row) of that table-type then repeats fscanf for the intermediate fields in that table-type's TA-child sequence: When the last TA_child is reached, do the same thing unless it is of type tnn (text string of length nn). In that case, read up to EOLine into the last field's buffer (All tnn or cnn fields are truncated if necessary to avoid buffer overflow). //pr_create(//field of type specified in ttabbrev byte of pkey child_loop(TT, TA, TAid, TTid){ if (first_child(TT, TA) //Syntax Not Checkedxa - RJL) fscanf(fp, *keybuf,"%s"); //get pkey; else if (! last_child(TT, TA, TAid, TTid)) //get middle-children (fkeys first, if any) fscanf(fp, stringfor(TAcurr->fieldname), formatfor(TAcurr->fieldtype)); else //last child - needed for field-type tnn getchars_untilEOL(fp, *lastfieldbuf); } Note 1: formatfor() is a compile-time or run-time lookup of a format string equivalent to the TA field type. stringfor() needs the stringized value of the TA field name. (This is a run-time data to compile-time identifier translation) traditionally done by a switch(data){...case ident: ... } (You get a prize if you can avoid some form of switch or indexed table lookup here :-). Note 2: C++ Stream I/O could absorb all middle fields by < cd $CASE/gen/ver_13/chgen/src mercury.cs.uml.edu(45)> grep hcg_ *.c | wc 1299 8403 107160 But search for the 16 refs to items below (from TTTA_metadata_jk.ppt), and only in the pr_*.c files which process tables TT and TA in chgen/src: mercury.cs.uml.edu(70)> grep '(hcg_ts_list|hcg_table_seqlist|ts_list|ts_type)' pr_*.c | wc 16 68 1553 ----------------------------------