#include #include #include #include #include #include #include #include /* for MAXPATHLEN */ #include "SDDAS_types.h" #include "libdb.h" /* for dbVirtualName */ #include "vidf_local.h" #include "symtab.h" // definition of symtab #include "vidf.y.tab.h" // for the Y_ defines extern "C" { /* We need to use these global variables to connect with the lex/yacc routines */ char GLOBAL_VIDFFileName [255]; symtab *GLOBAL_VIDF = NULL; } typedef std::multimap VIDFMapType; // Forward declarations - not shared routines int VIDF_InsertIntoVIDF_INT (void *vidf, char *vinst, char *key_name, int value) { VIDFMapType *VIDF = (VIDFMapType *) vidf; std::string real_key; real_key = "v2_"; real_key += vinst; real_key += "."; real_key += key_name; vidf_entry entry; entry.type = INT; entry.val.ival = value; // std::cout << real_key << " " << "->\"" << entry.val.ival << "\"" << std::endl; std::pair vidf_value (real_key, entry); VIDF->insert (vidf_value); return (1); } void FreeVIDFVals (vidf_vals **ret_val) { vidf_vals *temp, *back; temp = *ret_val; back = NULL; while (temp != NULL) { back = temp->next; free (temp); temp = back; } *ret_val = NULL; } void AddVIDFVal (vidf_vals **ret_val, vidf_value_type symtype, const vidf_union *ptr) { vidf_vals *new_node = (vidf_vals *) calloc (1, sizeof (vidf_vals)); vidf_vals *temp; new_node->next = NULL; new_node->type = symtype; switch (symtype) { case FLOAT : new_node->val.dval = ptr->dval; break; case INT : new_node->val.ival = ptr->ival; break; case CHAR : new_node->val.cval = ptr->cval; break; case STRING : new_node->val.sval = ptr->sval; break; } // switch if (*ret_val == NULL) *ret_val = new_node; else { temp = *ret_val; while (temp->next != NULL) temp = temp->next; temp->next = new_node; } } vidf_vals *FindNameinVIDF (void *vidf, char *tmp, vidf_vals **ret_val) { typedef std::multimap::iterator CIT; typedef std::pair Range; VIDFMapType *VIDF = (VIDFMapType *) vidf; Range range = VIDF->equal_range (tmp); if (range.first == range.second) { return (NULL); } else { CIT cit = range.first; while (cit != range.second) { AddVIDFVal (ret_val, cit->second.type, &cit->second.val); ++cit; } } return (*ret_val); } void DeleteVIDF (void *vidf) { // Go through all the VIDFs, freeing strings typedef std::multimap::const_iterator CIT; VIDFMapType *VIDF = (VIDFMapType *) vidf; CIT cit = VIDF->begin (); while (cit != VIDF->end ()) { if (cit->second.type == STRING) free (cit->second.val.sval); cit++; } VIDF->clear (); delete VIDF; } /* Free the storage used by the list pointed to by pointer p */ inline void free_vidf_list (symtab *p) { symtab *tmp; int i; while (p != NULL) { if ((p->symtype == Y_STRUCT) || (p->symtype == Y_VIDF)) { free_vidf_list((symtab *)p->ptr); free (p->symname); p->ptr = NULL; tmp = p->next; free (p); /* free symtab structure */ p = tmp; } else { free (p->symname); if ((p->array_length != 1) && (p->symtype == Y_STRING)) for (i = 0; i < p->array_length; ++i) free (((char **)p->ptr) [i]); free (p->ptr); /* free data storage */ p->ptr = NULL; tmp = p->next; free (p); /* free symtab structure */ p = tmp; } } } inline int DeleteVIDFSYMTAB (symtab *sym) { if (sym != NULL) { free_vidf_list (sym); sym = NULL; } return 1; } void ConvertToMap (VIDFMapType *VIDF, symtab *p, std::string key) { while (p != NULL) { switch (p->symtype) { case Y_FLOAT : { // fprintf (stdout, "float %s = %12.7e;\n", p->symname, *((float *)p->ptr)); for (int loop = 0; loop < p->array_length; loop++) { vidf_entry entry; entry.type = FLOAT; if (p->array_length > 1) entry.val.dval = ((float *)p->ptr) [loop]; else entry.val.dval = *((float *)p->ptr); std::string new_key = key + "." + p->symname; std::pair value (new_key, entry); VIDF->insert (value); } } break; case Y_INT : { // fprintf (stdout, "int %s = %d;\n", p->symname, *((int *)p->ptr)); for (int loop = 0; loop < p->array_length; loop++) { vidf_entry entry; entry.type = INT; if (p->array_length > 1) entry.val.ival = ((int *)p->ptr) [loop]; else entry.val.ival = *((int *)p->ptr); // std::cout << key+"."+p->symname << " " << p->array_length << "->\"" << entry.val.ival << "\"" << std::endl; std::pair value (key+"."+p->symname, entry); VIDF->insert (value); } } break; case Y_STRING : { // fprintf (stdout, "string %s = \"%s\";\n", p->symname, (char *) p->ptr); for (int loop = 0; loop < p->array_length; loop++) { vidf_entry entry; entry.type = STRING; if (p->array_length > 1) entry.val.sval = strdup (((char **)p->ptr) [loop]); else entry.val.sval = strdup ((char *)p->ptr); // std::cout << key+"."+p->symname << " " << p->array_length << "->\"" << entry.val.sval << "\"" << std::endl; std::pair value (key+"."+p->symname, entry); VIDF->insert (value); } } break; case Y_CHAR : { /* char tempchar = *((char *)p->ptr); if (tempchar > (int) 'Z') fprintf (stdout, "char %s = %d;\n", p->symname, (int) *((char *)p->ptr)); else fprintf (stdout, "char %s = '%c';\n", p->symname, *((char *)p->ptr)); */ for (int loop = 0; loop < p->array_length; loop++) { vidf_entry entry; entry.type = CHAR; if (p->array_length > 1) entry.val.cval = ((char *)p->ptr) [loop]; else entry.val.cval = *((char *)p->ptr); std::pair value (key+"."+p->symname, entry); VIDF->insert (value); } } break; case Y_STRUCT : { // fprintf (stdout, "struct %s {\n", p->symname); ConvertToMap (VIDF, (symtab *) p->ptr, key+"."+p->symname); // fprintf (stdout, "};\n"); } break; case Y_VIDF :{ // fprintf (stdout, "vidf %s {\n", p->symname); ConvertToMap (VIDF, (symtab *) p->ptr, p->symname); // fprintf (stdout, "}\n"); } break; }; // switch p = p->next; }; // while } // Return values are -1 and 1 int ParseNewVIDF (void **vidf, char *filename) { // Use the LEX/YACC stuff to read a VIDF extern FILE *v_in; if (!(v_in = fopen (filename, "r"))) { perror ("ParseVIDF: ERROR - opening VIDF"); return -1; } strcpy (GLOBAL_VIDFFileName, filename); while (!(feof (v_in))) { v_parse (); } if (fclose (v_in) != 0) { perror ("ParseVIDF: ERROR - closing VIDF"); } /* Non-reentrant scanners generated by Flex 2.5.9 and later (and some earlier versions according to the Flex manual) leak memory if yylex_destroy is not invoked. However, yylex_destroy is not defined before Flex 2.5.9, so give an implementation here that at least appears to work with Flex 2.5.4. */ /* Unfortunately, this only works on Flex v2.5.9+ #if !defined(YY_FLEX_MAJOR_VERSION) || YY_FLEX_MAJOR_VERSION < 2 \ || (YY_FLEX_MAJOR_VERSION == 2 \ && (!defined(YY_FLEX_MINOR_VERSION) || YY_FLEX_MINOR_VERSION < 5 \ || (YY_FLEX_MINOR_VERSION == 5 \ && (!defined(YY_FLEX_SUBMINOR_VERSION) \ || YY_FLEX_SUBMINOR_VERSION < 9)))) v_lex_destroy (); #endif */ // Put in a C++ multimap (red/black tree) VIDFMapType *VIDF = new VIDFMapType; ConvertToMap (VIDF, GLOBAL_VIDF, ""); *vidf = VIDF; // Get rid of the old tree structure DeleteVIDFSYMTAB (GLOBAL_VIDF); return 1; } void PrintVIDF (void *vidf) { typedef std::multimap::const_iterator CIT; VIDFMapType *VIDF = (VIDFMapType *) vidf; CIT cit = VIDF->begin (); std::cout << std::endl << "VIDF:" << std::endl; while (cit != VIDF->end()) { std::cout << (*cit).first << " - "; switch ((*cit).second.type) { case STRING : std::cout << (*cit).second.val.sval; break; case FLOAT : std::cout << (*cit).second.val.dval; break; case INT : std::cout << (*cit).second.val.ival; break; case CHAR : std::cout << (*cit).second.val.cval; break; } // switch std::cout << std::endl; cit++; } } /* int main (int argc, char *argv[]) { if (argc != 2) { printf ("usage: %s \n", argv [0]); } else { ParseVIDF (argv [1]); PrintVIDF (0); vidf_vals *p = NULL, *ret_val = NULL; Find_Name (0, "v2_MEXORBMC.bullshit", &ret_val); p = ret_val; while (p != NULL) { std::cout << p->val.ival << std::endl; p = p->next; } } exit (0); } */