#include "genhash.h" void _demeter_create_make_instance(int numberofcomps,char **cnames,char *currname) { register int i; char *makeinstancename = new char[256]; ofstream outFile("notmod/def/make_instance-DEM.C",ios::out); if (outFile==NULL) { cerr << "Cannot open \"" << "notmod/def/make_instance-DEM.C" << "\"" << endl; exit(-1); } cout << "Created notmod/def/make_instance.C" << endl; outFile << "#include \n" << "#include \n" << "#include \"" << currname << ".h\"\n"; outFile << "extern void _demeter_hash_error(const char*);\n"; for (i = 0; i \n" << "#include \n" << "#include \"" << nameofcomp << ".h\"\n"; for (i = 0;i < sizeofhashtable;i++) hashTable[i].count = 0,hashTable[i].bucketelement = NULL; for (i = 0; i < numberofnames;i++) { if (nameflags[i] == 'A') outFile << "\nstatic Universal *" << namelist[i] << "_" << nameofcomp << "_make_instance() {\n" << " cerr << \"make_instance: " << namelist[i] << " is an abstract class.\" << endl;\n return NULL;\n}\n"; else outFile << "\nstatic Universal *" << namelist[i] << "_" << nameofcomp << "_make_instance() {\n" << " return new " << namelist[i] << "();\n}\n"; } for (i = 0; i < numberofnames;i++) { char* t = new char[strlen(namelist[i]) + strlen(nameofcomp) + 1]; sprintf(t,"%s_%s",namelist[i],nameofcomp); int index = _demeter_hash(t); if (hashTable[index].count == 0) { struct BucketElement * iBucketElement = (struct BucketElement*) malloc(sizeof(BucketElement)); iBucketElement->name = t; iBucketElement->next = NULL; hashTable[index].bucketelement = iBucketElement; hashTable[index].count++; if (maxlength < hashTable[index].count) maxlength = hashTable[index].count; continue; } else if (strcmp(hashTable[index].bucketelement->name,t) > 0) { struct BucketElement * iBucketElement = (struct BucketElement*) malloc(sizeof(BucketElement)); iBucketElement->name = t; iBucketElement->next = hashTable[index].bucketelement; hashTable[index].bucketelement = iBucketElement; hashTable[index].count++; if (maxlength < hashTable[index].count) maxlength = hashTable[index].count; continue; } else { BucketElement * curr = hashTable[index].bucketelement; BucketElement * prev = hashTable[index].bucketelement; while ( (curr->next != NULL) && (strcmp(curr->name,namelist[i]) < 0)) prev = curr,curr = curr->next; int result = strcmp(curr->name,t); if (result == 0) continue; struct BucketElement * iBucketElement = (struct BucketElement*) malloc(sizeof(BucketElement)); iBucketElement->name = t; iBucketElement->next = NULL; if (result < 0) curr->next = iBucketElement; else { iBucketElement->next = curr; prev->next = iBucketElement; } hashTable[index].count++; if (maxlength < hashTable[index].count) maxlength = hashTable[index].count; } } cout << "Generated a hash table for " << numberofnames << " classes: \n"; double averagecost = 0.0; double bestcost = 0.0; int minilength = maxlength; int single = 0; for (i = 0;i < 256;i++) { if (hashTable[i].count == 1) single = 1; else if (hashTable[i].count) averagecost += log(hashTable[i].count+1.0)/256.0; if ((hashTable[i].count>1) && (minilength > hashTable[i].count)) minilength = hashTable[i].count; } if (single) bestcost = 1; else bestcost = log(minilength)/log(2.0)+1; cout << "\n The maximum length of the collision lists: " << maxlength; cout << "\n The minimum length of the collision lists: " << minilength; cout << "\n The expected average length of the collision lists: " << numberofnames / 256.0; cout << "\n The wost cost of a succsessful search: CI + " << log(maxlength+1.0)/log(2.0) << "*CS"; cout << "\n The best cost of a succsessful search: CI + " << bestcost << "*CS"; cout << "\n The average cost of a search: CI + " <next != NULL) { outFile << "\n { &" << curr->name << "_make_instance,\n" << " \"" << curr->name << "\"},\n"; curr = curr->next; } outFile << "\n { &" << curr->name << "_make_instance,\n" << " \"" << curr->name << "\"}"; } else { outFile << "{ 0,0 }"; } outFile << " } }"; if (i != 255) outFile << ",\n"; } outFile << " };\n\n\n" << "/*****************************************************************\n" << "* search in the current hash table *\n" << "******************************************************************/\n" << " char localclass[300];\n" << " sprintf(localclass,\"%s_" << nameofcomp << "\",classname);\n" << " int length = strlen(localclass);" << "\n" << " int index = _demeter_hash(localclass);" << "\n" << " if ( _" << nameofcomp << "_HashTable[index].count==0)\n" << " return NULL;\n" << " else\n" << " {\n" << " int left = 0;\n" << " int right = _" << nameofcomp << "_HashTable[index].count-1;\n" << " int middle;\n" << " while (!(left > right))\n" << " {\n" << " middle = (left+right)/2;\n" << " int result = strcmp(_" << nameofcomp << "_HashTable[index].bucketelements[" << "middle].name,localclass);\n" << " if (result == 0)\n" << " return (Universal *)(*_" << nameofcomp << "_HashTable[index].bucketelements[" << "middle].ctr)();\n" << " else\n" << " if (result < 0)\n" << " left = middle+1;\n" << " else\n" << " right = middle-1;\n" << " }\n" << " return NULL;\n" << " }\n" << "}\n"; outFile.close(); } // Demeter_in = Input . void Demeter_in::create_make_instance( int argc,char* * argv ) { DEM_TRACE("Demeter_in","void Demeter_in::create_make_instance(int argc,char* * argv)"); // variables for carrying in and out // assignments for carrying in // prefix class wrappers // outgoing calls // construction edge prefix wrappers this->get_input()->create_make_instance( argc , argv ); // construction edge suffix wrappers // suffix class wrappers // assignments for carrying out } // Input : Cd_graph // *common* . void Input::create_make_instance( int argc,char* * argv ) { DEM_TRACE("Input","void Input::create_make_instance(int argc,char* * argv)"); #ifndef NOTRACE DemTrace demTraceEmptyMethod(__FILE__,__LINE__,"Input",form(" at %s , *** PREMATURELY TERMINATED *** ", this->get_type())); #endif } // Cd_graph = Adjacency_Nlist // [ DemNumber ] // [ DemNumber ] // [ Adjacency_List ] // [ Vertices_With_Same_Fset_List ] // [ Vertex_Comma_list ] // [ Term_Comma_list ] . void Cd_graph::create_make_instance( int argc,char* * argv ) { DEM_TRACE("Cd_graph","void Cd_graph::create_make_instance(int argc,char* * argv)"); // variables for carrying in and out // assignments for carrying in // prefix class wrappers if (argc == 1) { cout << "\nUsage: " << argv[0] << " cd-param-exp name1 ..." << endl; exit(1); } argc--;argv++; int numberofclasses = adjacencies->list_length(); int numberofterminals = 0; if (terminal_sets) numberofterminals = terminal_sets->list_length(); char ** namelist = (char**) malloc((numberofclasses+numberofterminals) * sizeof(char *)); char * nameflags = (char*) malloc(numberofclasses+numberofterminals); int count = 0; Adjacency_list_iterator next(*adjacencies); Adjacency* each; while (each = next()) { /* violation of the Law of Demeter */ namelist[count] = each->get_source()->get_vertex_name()->get_val(); if (each->get_ns()->isAbstract()) nameflags[count]='A'; else nameflags[count]='C'; count++; } if (numberofterminals) { Vertex_list_iterator next1(*terminal_sets); Vertex* each1; while (each1 = next1()) { namelist[count] = each1->get_vertex_name()->get_val(); nameflags[count]='C'; count++; } } _demeter_create_make_instance_for_curr(numberofterminals+numberofclasses,namelist,argv[1],nameflags); int numberofcomps = argc-1; char ** cnames = (char**) malloc(numberofcomps * sizeof(char *)); count = 0; while (count < argc) { cnames[count] = argv[count+1]; count++; } _demeter_create_make_instance(numberofcomps,cnames,argv[1]); // outgoing calls // suffix class wrappers // assignments for carrying out }