#ifndef SA_OUTPUT_H #define SA_OUTPUT_H #include #include //#include //#include //#include #include #include #include #include #include //---- SA_Output private methods --------------------------------------------------------- // parses the string label for variables // void SA_Output::SetString(int level,SA_OUTPUT_FCTTYPE fcttype,char *label) { // // std::cerr << "SA_Output::SetString -> Setting string \"" << label << "\" for function " << SA_OUTPUT_FCTTYPE_NAMES[fcttype] << " at level " << level << std::endl; // char *occurrence; // char *parsestr = label; // OutStr *newoutstr; // int length; // length of output string part // int cpylength; // for(occurrence = strchr(parsestr,'#'); occurrence != NULL; occurrence = strchr(parsestr,'#')) { // newoutstr = new OutStr; // newoutstr->level = level; // istrstream ins(occurrence+1,8); // ins >> newoutstr->varnumber; // length = occurrence-parsestr; // newoutstr->outstr = new char[length+2]; // cpylength = strxfrm(newoutstr->outstr,parsestr,length+1); // *((newoutstr->outstr)+length+2) = 0; // marking end of string // //std::cerr << "SA_Output::SetString -> inserting (" << newoutstr->level << "," << newoutstr->outstr << "," << newoutstr->varnumber << ")" << std::endl; // outstrs[fcttype].Ins(level,newoutstr); // parsestr = occurrence+1+(int)floor(log10(newoutstr->varnumber))+1; // } // if (parsestr < label+strlen(label)+1) { // is the string not fully parsed? // newoutstr = new OutStr; // int length = strlen(label)-(parsestr-label)+2; // newoutstr->outstr = new char[length]; // strcpy(newoutstr->outstr, parsestr); // *((newoutstr->outstr)+length-2) = '\n'; // concat std::endl to string // *((newoutstr->outstr)+length-1) = 0; // terminate the string // newoutstr->level = level; // newoutstr->varnumber = -1; // // std::cerr << "SA_Output::SetString -> inserting (" << newoutstr->level << "," << newoutstr->outstr << "," << newoutstr->varnumber << ")" << std::endl; // outstrs[fcttype].Ins(level,newoutstr); // } // } char *SA_Output::ExtractString(int fromi, int toi, char *source) { char *extractstr = new char[toi-fromi+2]; // one additional byte for the terminating zero for (int index = 0; index < toi-fromi+1; index++) { extractstr[index] = source[index+fromi]; } extractstr[toi-fromi+1] = 0; return(extractstr); } void SA_Output::ParseLine(int level,SA_OUTPUT_FCTTYPE fcttype,char *line) { // std::cout << "DBG: ParsingLine \"" << line << "\" " << std::endl; int startindex = 0; int varnumber; OutStr *newoutstr; int index; for (index = 0; line[index] != 0; index++) { if (line[index] == '#') { // possible variable occurence StripLeadingPosInt(&varnumber,line+index+1); if (varnumber >= 0) { // variablenumber has been stripped successfully! newoutstr = new OutStr(); newoutstr->varnumber = varnumber; newoutstr->level = level; newoutstr->outstr = ExtractString(startindex,index-1,line); // index-1 because '#' should not be copied outstrs[fcttype].Ins(level,newoutstr); // std::cout << "DBG: inserting \"" << newoutstr->outstr << "\" +varno: " << newoutstr->varnumber << " at level " << newoutstr->level << std::endl; startindex = index+1; // no need to take of digits, because they where already stripped } } } newoutstr = new OutStr(); newoutstr->varnumber = -1; newoutstr->level = level; newoutstr->outstr = ExtractString(startindex,index-1,line); // terminating zero must not be extracted because it is automatically generated by ExtractString; // std::cout << "DBG: inserting \"" << newoutstr->outstr << "\" +varno: " << newoutstr->varnumber << " at level " << newoutstr->level << std::endl; outstrs[fcttype].Ins(level,newoutstr); } // methods managing the output of the void pointers kept in "variables" //void SA_Output::OutByte(void *data) { // std::cout << *((Byte *)data); //} void SA_Output::OutInt(void *data) { std::cout << *((int *)data); } void SA_Output::OutLong(void *data) { std::cout << *((long *)data); } void SA_Output::OutDouble(void *data) { std::cout << *((double *)data); } void SA_Output::OutFloat(void *data) { std::cout << *((float *)data); } void SA_Output::OutString(void *data) { std::cout << (char *)data; } //---- SA_Output public methods --------------------------------------------------------- void SA_Output::AddVariable(int varnumber,SA_OUTPUT_VARTYPE vartype,void *var) { if (variables->Get(varnumber)!= NULL) { std::cerr << "SA_Output::AddVariable -> WARNING adding variable number " << varnumber << " which does already exists!" << std::endl; } OutVariable *newvariable = new OutVariable; switch (vartype) { // case SA_BYTE: newvariable.outfct = & SA_Output::OutByte; break; case SA_INT: newvariable->outfct = &SA_Output::OutInt; break; case SA_LONG: newvariable->outfct = &SA_Output::OutLong; break; case SA_FLOAT: newvariable->outfct = &SA_Output::OutFloat; break; case SA_DOUBLE: newvariable->outfct = &SA_Output::OutDouble; break; case SA_STRING: newvariable->outfct = &SA_Output::OutString; break; } newvariable->data = var; variables->Ins(varnumber,newvariable); } // test whether fktstr matches a string in array SA_OUT_FCTTYPE_NAMES or not SA_OUTPUT_FCTTYPE SA_Output::DetermineFctType(char *fktstr) { if (fktstr == NULL) return NO_SA_OUTPUT_FCTTYPE; int index = -1; do { index++; } while (index < N_OUTPUT_FCT && strcmp(SA_OUTPUT_FCTTYPE_NAMES[index],fktstr)!=0); // if index = N_OUTPUT_FKT+1 it has the same value as NO_SA_OUTPUT_FCTTYPE // std::cerr << "SA_Output::DetermineFctType -> string " << fktstr << " is of type " << index << std::endl; return((SA_OUTPUT_FCTTYPE)index); } // stripps the leading word, if it is a positiv integer value void SA_Output::StripLeadingPosInt(int *integer, char *line) { *integer = -1; // currently nothing ist stripped int startindex=0; int endindex = 0; // std::cout << "DBG: Stripping \"" << line << "\" to \""; while (line[startindex] == ' ') startindex++; endindex = startindex; while ('0' <= line[endindex] && line[endindex] <= '9') endindex++; if (line[endindex] == ' ' || line[endindex] == 0 || line[endindex] == '\n') { // leading digits must be a word, maybe the last word if (endindex > startindex) { // some digits have been found *integer = 0; int index; for (index = startindex; index < endindex; index++) { // calculate int value *integer *= 10; *integer += line[index]-48; } for (index = endindex; line[index] != 0; index++) { // move stringcontents ahead line[index-endindex] = line[index]; } line[index-endindex] = 0; // terminate the string with moved contents } } } SA_Output::SA_Output(char *id,char *rscfilename) { // setting previous output to NULL prevoutput = NULL; // setting identifier identifier = new char[strlen(id)+1]; strcpy(identifier, id); // setting default output strategy printid = true; printlevel = true; // memory allocation for lists variables = new TIntKeyList; outstrs = new TIntKeyList[N_OUTPUT_FCT]; for (int i = 0; i < N_OUTPUT_FCT;i++) { outstrs[i] = *(new TIntKeyList); } char *instr; std::ifstream infile(rscfilename); SA_OUTPUT_FCTTYPE fcttype; if (!infile) { std::cerr << "SA_Output::SA_Output -> cannot open file (" << rscfilename << ")" << std::endl; } else { char *inputline = new char[400]; infile.getline(inputline,400); while(infile && strcmp(inputline,identifier) != 0){ // search the block marked with "identifier" in rsc file infile.getline(inputline,400); } if (!infile) { // specified block not found. bail std::cout. std::cerr << "SA_Output::SA_Output -> No block specified by (" << identifier << ") in file (" << rscfilename << ")" << std::endl; return; }; int level = 0; // level of current input line SA_OUTPUT_FCTTYPE curfcttype = NO_SA_OUTPUT_FCTTYPE; // strings of what function are parsed char *endline = new char[strlen(identifier)+6]; strcpy(endline,identifier); strcat(endline," END\n"); // return must be appended, because from NOW on the return is appended to each inputline while (infile && strcmp(endline,inputline) != 0) { infile.getline(inputline,399); fcttype = DetermineFctType(inputline); if (fcttype != NO_SA_OUTPUT_FCTTYPE) { curfcttype = fcttype; } else { int nullposition = strlen(inputline); // append the chariage return and... inputline[nullposition] = '\n'; inputline[nullposition+1] = 0; // ... terminate the string again StripLeadingPosInt(&level,inputline); if (level > 0) { ParseLine(level,curfcttype,inputline); } } } if (!infile) { std::cerr << "SA_Output::SA_Output() -> WARNING: Parsing of resourcefile \"" << rscfilename << "\" was terminated by EOF and not by keyword \"" << identifier << " END\" " << inputline << std::endl; } SetOutputLevel(10); } } void SA_Output::SetPreviousOutput(SA_Output *previousout) { prevoutput = previousout; } SA_Output::~SA_Output() { } void SA_Output::OutputFunction(SA_OUTPUT_FCTTYPE fcttype) { outstrs[fcttype].Reset(); int oldlevel = -1; OutStr *curout = (OutStr *)outstrs[fcttype].Get(); if (printid && curout != NULL && curout->level <= outlevel) { std::cout << identifier << " OUTPUT:" << std::endl; } while(curout != NULL && curout->level <= outlevel) { if (curout->level > oldlevel && printlevel) { std::cout << "OUTPUTLEVEL(" << curout->level << ")" << std::endl; oldlevel = curout->level; } std::cout << curout->outstr; if (curout->varnumber > -1) { // is an variable to print? OutVariable *curvar = (OutVariable *)variables->Get(curout->varnumber); if (curvar != NULL) { // was the variable inserted? void (SA_Output::*curoutfct)(void *) = curvar->outfct; (this->*curoutfct)(curvar->data); } else { std::cout << "#??"; } } curout = (OutStr *)outstrs[fcttype].Next(); } } void SA_Output::OutputInit() { if (prevoutput != NULL) { prevoutput->OutputInit(); } OutputFunction(SA_OUT_INIT); } void SA_Output::OutputNeighbor() { if (prevoutput != NULL) { prevoutput->OutputNeighbor(); } OutputFunction(SA_OUT_N); } void SA_Output::OutputCostDiffNeg() { if (prevoutput != NULL) { prevoutput->OutputCostDiffNeg(); } OutputFunction(SA_OUT_CDNEG); } void SA_Output::OutputCostDiffPos(){ if (prevoutput != NULL) { prevoutput->OutputCostDiffPos(); } OutputFunction(SA_OUT_CDPOS); } void SA_Output::OutputAccept(){ if (prevoutput != NULL) { prevoutput->OutputAccept(); } OutputFunction(SA_OUT_ACC); } void SA_Output::OutputNotAccept() { if (prevoutput != NULL) { prevoutput->OutputNotAccept(); } OutputFunction(SA_OUT_NOTACC); } void SA_Output::OutputEquiYes() { if (prevoutput != NULL) { prevoutput->OutputEquiYes(); } OutputFunction(SA_OUT_EQUIYES); } void SA_Output::OutputEquiNo(){ if (prevoutput != NULL) { prevoutput->OutputEquiNo(); } OutputFunction(SA_OUT_EQUINO); } void SA_Output::OutputDecrT() { if (prevoutput != NULL) { prevoutput->OutputDecrT(); } OutputFunction(SA_OUT_DT); } void SA_Output::OutputFrozenYes() { if (prevoutput != NULL) { prevoutput->OutputFrozenYes(); } OutputFunction(SA_OUT_FROZYES); } void SA_Output::OutputFrozenNo() { if (prevoutput != NULL) { prevoutput->OutputFrozenNo(); } OutputFunction(SA_OUT_FROZNO); } void SA_Output::SetOutputLevel(int level) { outlevel = level; if (outlevel <= 10) { EnableIdentifier(0); } } void SA_Output::EnableIdentifier(int choice) { if (choice == 0) { printid = 0; } else { printid = 1; } } void SA_Output::EnableLevelNumbers(int choice) { if (choice == 0) { printlevel = 0; } else { printlevel = 1; } } #endif