#include #include #include #include using namespace std; #include "TclUtils/TclParameterSet.hh" #define parser_check_argc_2(N) do {\ if (argc != N-1)\ {\ Tcl_AppendResult(interp, getTclHandle(), " ", argv[0],\ " : wrong # of arguments", 0);\ return TCL_ERROR;\ }\ } while (0); #define parser_check_argc_3(N) do {\ if (argc != N-1)\ {\ Tcl_AppendResult(interp, getTclHandle(), " ", argv[0], " ",\ argv[1]," : wrong # of arguments", 0);\ return TCL_ERROR;\ }\ } while (0); TclParameterSet::TclParameterSet() { _modified = true; } TclParameterSet::~TclParameterSet() { } int TclParameterSet::setParameter(Tcl_Interp *interp, const char *name, char *value) { std::map::iterator it = _parameterSet.find(std::string(name)); if (it == _parameterSet.end()) { // Parameter not found Tcl_ResetResult(interp); Tcl_AppendResult(interp, "parameter \"", name, "\" not found", 0); return TCL_ERROR; } int i; double d; switch (it->second.tclLinkType) { case TCL_PARM_INT: { if (Tcl_GetInt(interp, value, &i) != TCL_OK) return TCL_ERROR; if (configChangeCallback(interp, name, i) != TCL_OK) return TCL_ERROR; *reinterpret_cast(it->second.p) = i; } break; case TCL_PARM_BOOLEAN: { if (Tcl_GetBoolean(interp, value, &i) != TCL_OK) return TCL_ERROR; bool tmp(i); if (configChangeCallback(interp, name, tmp) != TCL_OK) return TCL_ERROR; *reinterpret_cast(it->second.p) = tmp; } break; case TCL_PARM_DOUBLE: { if (Tcl_GetDouble(interp, value, &d) != TCL_OK) return TCL_ERROR; if (configChangeCallback(interp, name, d) != TCL_OK) return TCL_ERROR; *reinterpret_cast(it->second.p) = d; } break; case TCL_PARM_FLOAT: { if (Tcl_GetDouble(interp, value, &d) != TCL_OK) return TCL_ERROR; if (d < -FLT_MAX || d > FLT_MAX) { Tcl_SetResult(interp, "float value too large to represent", TCL_VOLATILE); return TCL_ERROR; } float tmp(d); if (configChangeCallback(interp, name, tmp) != TCL_OK) return TCL_ERROR; *reinterpret_cast(it->second.p) = tmp; } break; case TCL_PARM_STRING: { std::string tmp(value); if (configChangeCallback(interp, name, tmp) != TCL_OK) return TCL_ERROR; *reinterpret_cast(it->second.p) = tmp; } break; case TCL_PARM_LIST_INT: { std::vector tmp; if (parseTclList(interp, value, &tmp) != TCL_OK) return TCL_ERROR; if (configChangeCallback(interp, name, tmp) != TCL_OK) return TCL_ERROR; *reinterpret_cast *>(it->second.p) = tmp; } break; case TCL_PARM_LIST_BOOLEAN: { std::vector tmp; if (parseTclList(interp, value, &tmp) != TCL_OK) return TCL_ERROR; if (configChangeCallback(interp, name, tmp) != TCL_OK) return TCL_ERROR; *reinterpret_cast *>(it->second.p) = tmp; } break; case TCL_PARM_LIST_DOUBLE: { std::vector tmp; if (parseTclList(interp, value, &tmp) != TCL_OK) return TCL_ERROR; if (configChangeCallback(interp, name, tmp) != TCL_OK) return TCL_ERROR; *reinterpret_cast *>(it->second.p) = tmp; } break; case TCL_PARM_LIST_FLOAT: { std::vector tmp; if (parseTclList(interp, value, &tmp) != TCL_OK) return TCL_ERROR; if (configChangeCallback(interp, name, tmp) != TCL_OK) return TCL_ERROR; *reinterpret_cast *>(it->second.p) = tmp; } break; case TCL_PARM_LIST_STRING: { std::vector tmp; if (parseTclList(interp, value, &tmp) != TCL_OK) return TCL_ERROR; if (configChangeCallback(interp, name, tmp) != TCL_OK) return TCL_ERROR; *reinterpret_cast *>(it->second.p) = tmp; } break; case TCL_PARM_ARR_INT: case TCL_PARM_ARR_BOOLEAN: case TCL_PARM_ARR_DOUBLE: case TCL_PARM_ARR_FLOAT: case TCL_PARM_ARR_STRING: Tcl_ResetResult(interp); Tcl_AppendResult(interp, "parameter \"", name, "\" is an array", 0); return TCL_ERROR; default: std::cerr << "ERROR in TclParameterSet::setParameter: " << "invalid link type " << it->second.tclLinkType << "\nThis is a bug. Please report. Aborting." << std::endl; abort(); } ++it->second.modified; _modified = true; return TCL_OK; } int TclParameterSet::setParameter(Tcl_Interp *interp, const char *name, const char *index, char *value) { std::map::iterator it = _parameterSet.find(std::string(name)); if (it == _parameterSet.end()) { // Parameter not found Tcl_ResetResult(interp); Tcl_AppendResult(interp, "parameter \"", name, "\" not found", 0); return TCL_ERROR; } int i; double d; switch (it->second.tclLinkType) { case TCL_PARM_INT: case TCL_PARM_BOOLEAN: case TCL_PARM_DOUBLE: case TCL_PARM_FLOAT: case TCL_PARM_STRING: case TCL_PARM_LIST_INT: case TCL_PARM_LIST_BOOLEAN: case TCL_PARM_LIST_DOUBLE: case TCL_PARM_LIST_FLOAT: case TCL_PARM_LIST_STRING: Tcl_ResetResult(interp); Tcl_AppendResult(interp, "parameter \"", name, "\" is not an array", 0); return TCL_ERROR; case TCL_PARM_ARR_INT: { if (Tcl_GetInt(interp, value, &i) != TCL_OK) return TCL_ERROR; (*reinterpret_cast(it->second.p))[index] = i; } break; case TCL_PARM_ARR_BOOLEAN: { if (Tcl_GetBoolean(interp, value, &i) != TCL_OK) return TCL_ERROR; bool tmp(i); (*reinterpret_cast(it->second.p))[index] = tmp; } break; case TCL_PARM_ARR_DOUBLE: { if (Tcl_GetDouble(interp, value, &d) != TCL_OK) return TCL_ERROR; (*reinterpret_cast(it->second.p))[index] = d; } break; case TCL_PARM_ARR_FLOAT: { if (Tcl_GetDouble(interp, value, &d) != TCL_OK) return TCL_ERROR; if (d < -FLT_MAX || d > FLT_MAX) { Tcl_SetResult(interp, "float value too large to represent", TCL_VOLATILE); return TCL_ERROR; } float tmp(d); (*reinterpret_cast(it->second.p))[index] = tmp; } break; case TCL_PARM_ARR_STRING: { (*reinterpret_cast(it->second.p))[index] = std::string(value); } break; default: std::cerr << "ERROR in TclParameterSet::setParameter: " << "invalid link type " << it->second.tclLinkType << "\nThis is a bug. Please report. Aborting." << std::endl; abort(); } ++it->second.modified; _modified = true; return TCL_OK; } void TclParameterSet::setModified(void) { _modified = true; } bool TclParameterSet::isDefined(const char *name) const { std::map::const_iterator it = _parameterSet.find(std::string(name)); if (it == _parameterSet.end()) return false; else return true; } int TclParameterSet::getArraySize(const char *name) const { std::map::const_iterator it = _parameterSet.find(std::string(name)); if (it == _parameterSet.end()) return -2; switch (it->second.tclLinkType) { case TCL_PARM_ARR_STRING: return reinterpret_cast(it->second.p)->size(); case TCL_PARM_ARR_BOOLEAN: return reinterpret_cast(it->second.p)->size(); case TCL_PARM_ARR_INT: return reinterpret_cast(it->second.p)->size(); case TCL_PARM_ARR_DOUBLE: return reinterpret_cast(it->second.p)->size(); case TCL_PARM_ARR_FLOAT: return reinterpret_cast(it->second.p)->size(); default: return -1; } } bool TclParameterSet::isArray(const char *name) const { std::map::const_iterator it = _parameterSet.find(std::string(name)); if (it == _parameterSet.end()) return false; switch (it->second.tclLinkType) { case TCL_PARM_ARR_STRING: case TCL_PARM_ARR_BOOLEAN: case TCL_PARM_ARR_INT: case TCL_PARM_ARR_DOUBLE: case TCL_PARM_ARR_FLOAT: return true; default: return false; } } std::list TclParameterSet::getParamIndices(const char *name) const { std::list parlist; std::map::const_iterator it = _parameterSet.find(std::string(name)); if (it != _parameterSet.end()) { // Found the parameter switch (it->second.tclLinkType) { case TCL_PARM_INT: case TCL_PARM_BOOLEAN: case TCL_PARM_DOUBLE: case TCL_PARM_FLOAT: case TCL_PARM_STRING: case TCL_PARM_LIST_INT: case TCL_PARM_LIST_BOOLEAN: case TCL_PARM_LIST_DOUBLE: case TCL_PARM_LIST_FLOAT: case TCL_PARM_LIST_STRING: // Not an array break; case TCL_PARM_ARR_INT: { for (MapOfInts::const_iterator ip = reinterpret_cast(it->second.p)->begin(); ip != reinterpret_cast(it->second.p)->end(); ++ip) parlist.push_back(ip->first); } break; case TCL_PARM_ARR_BOOLEAN: { for (MapOfBools::const_iterator ip = reinterpret_cast(it->second.p)->begin(); ip != reinterpret_cast(it->second.p)->end(); ++ip) parlist.push_back(ip->first); } break; case TCL_PARM_ARR_DOUBLE: { for (MapOfDoubles::const_iterator ip = reinterpret_cast(it->second.p)->begin(); ip != reinterpret_cast(it->second.p)->end(); ++ip) parlist.push_back(ip->first); } break; case TCL_PARM_ARR_FLOAT: { for (MapOfFloats::const_iterator ip = reinterpret_cast(it->second.p)->begin(); ip != reinterpret_cast(it->second.p)->end(); ++ip) parlist.push_back(ip->first); } break; case TCL_PARM_ARR_STRING: { for (MapOfStrings::const_iterator ip = reinterpret_cast(it->second.p)->begin(); ip != reinterpret_cast(it->second.p)->end(); ++ip) parlist.push_back(ip->first); } break; default: std::cerr << "ERROR in TclParameterSet::getParamIndices: " << "invalid link type " << it->second.tclLinkType << "\nThis is a bug. Please report. Aborting." << std::endl; abort(); } } return parlist; } int TclParameterSet::getParamIndices(Tcl_Interp *interp, const char *name) const { std::list parlist = getParamIndices(name); Tcl_ResetResult(interp); if (parlist.size() == 0) { // Check if there is a problem if (!isArray(name)) { if (isDefined(name)) Tcl_AppendResult(interp, "parameter \"", name, "\" is not an array", 0); else Tcl_AppendResult(interp, "parameter \"", name, "\" not found", 0); return TCL_ERROR; } } else { for (std::list::iterator i = parlist.begin(); i != parlist.end(); ++i) Tcl_AppendElement(interp, const_cast(i->c_str())); } return TCL_OK; } int TclParameterSet::getParameter(Tcl_Interp *interp, const char *name) const { Tcl_ResetResult(interp); std::map::const_iterator it = _parameterSet.find(std::string(name)); if (it == _parameterSet.end()) { // Parameter not found Tcl_AppendResult(interp, "parameter \"", name, "\" not found", 0); return TCL_ERROR; } char buffer[64]; switch (it->second.tclLinkType) { case TCL_PARM_INT: sprintf(buffer, "%d", *reinterpret_cast(it->second.p)); Tcl_SetResult(interp, buffer, TCL_VOLATILE); break; case TCL_PARM_BOOLEAN: sprintf(buffer, "%d", static_cast(*reinterpret_cast(it->second.p))); Tcl_SetResult(interp, buffer, TCL_VOLATILE); break; case TCL_PARM_DOUBLE: Tcl_PrintDouble(interp, *reinterpret_cast(it->second.p), buffer); Tcl_SetResult(interp, buffer, TCL_VOLATILE); break; case TCL_PARM_FLOAT: Tcl_PrintDouble(interp, static_cast( *reinterpret_cast(it->second.p)), buffer); Tcl_SetResult(interp, buffer, TCL_VOLATILE); break; case TCL_PARM_STRING: { std::string c(*reinterpret_cast(it->second.p)); if (c.size()) Tcl_SetResult(interp, const_cast(c.c_str()), TCL_VOLATILE); } break; case TCL_PARM_LIST_INT: { std::vector *tmp = reinterpret_cast *>(it->second.p); for (int i=0; isize(); ++i) { sprintf(buffer, "%d", (*tmp)[i]); Tcl_AppendElement(interp, buffer); } } break; case TCL_PARM_LIST_BOOLEAN: { std::vector *tmp = reinterpret_cast *>(it->second.p); for (int i=0; isize(); ++i) { sprintf(buffer, "%d", static_cast((*tmp)[i])); Tcl_AppendElement(interp, buffer); } } break; case TCL_PARM_LIST_DOUBLE: { std::vector *tmp = reinterpret_cast *>(it->second.p); for (int i=0; isize(); ++i) { Tcl_PrintDouble(interp, (*tmp)[i], buffer); Tcl_AppendElement(interp, buffer); } } break; case TCL_PARM_LIST_FLOAT: { std::vector *tmp = reinterpret_cast *>(it->second.p); for (int i=0; isize(); ++i) { Tcl_PrintDouble(interp, static_cast((*tmp)[i]), buffer); Tcl_AppendElement(interp, buffer); } } break; case TCL_PARM_LIST_STRING: { std::vector *tmp = reinterpret_cast *>(it->second.p); for (int i=0; isize(); ++i) { std::string c((*tmp)[i]); Tcl_AppendElement(interp, const_cast(c.c_str())); } } break; case TCL_PARM_ARR_INT: case TCL_PARM_ARR_BOOLEAN: case TCL_PARM_ARR_DOUBLE: case TCL_PARM_ARR_FLOAT: case TCL_PARM_ARR_STRING: Tcl_AppendResult(interp, "parameter \"", name, "\" is an array", 0); return TCL_ERROR; default: std::cerr << "ERROR in TclParameterSet::getParameter: invalid link type " << it->second.tclLinkType << '\n' << "This is a bug. Please report. Aborting." << std::endl; abort(); } return TCL_OK; } static void printNChars(std::ostream& os, char c, size_t n) { for (size_t i=0; i(s.c_str()); for (int i=0; i<=maxlen && i < s.size(); ++i) if (c[i] == '\n') c[i] = ' '; if (s.size() <= maxlen) { os << s; printNChars(os, ' ', maxlen-s.size()); } else { // Truncate the string and print ellipsis at the end os << s.substr(0, maxlen-3); os << "..."; } } int TclParameterSet::printParameterTable(std::ostream& os) const { const size_t maxfieldlen = 24; std::list names(getParamNames()); std::map values; size_t maxnamelen = strlen("Name"); size_t maxvaluelen = strlen("Value"); size_t maxnwritelen = strlen("Writes"); std::string tmp; for (std::list::const_iterator it = names.begin(); it != names.end(); ++it) { if (it->size() > maxnamelen) maxnamelen = it->size(); if (isArray(it->c_str())) tmp = ""; else { getParameter(&tmp, it->c_str()); if (tmp.size() == 0) tmp = ""; } values[*it] = tmp; if (tmp.size() > maxvaluelen) maxvaluelen = tmp.size(); } if (maxnamelen + maxvaluelen > maxfieldlen*2) { // We have a formatting problem... if (maxnamelen < maxfieldlen) maxvaluelen = maxfieldlen*2 - maxnamelen; else if (maxvaluelen < maxfieldlen) maxnamelen = maxfieldlen*2 - maxvaluelen; else { maxnamelen = maxfieldlen; maxvaluelen = maxfieldlen; } } // Assume 80-column terminal. Use 2 spaces between fields and // require at least 1 space at the end of line. size_t maxdescrlen = 80 - 3*2 - 1 - maxnamelen - maxvaluelen - maxnwritelen; // Print the header printField(os, "Name", maxnamelen); os << " "; printField(os, "Value", maxvaluelen); os << " "; printField(os, "Writes", maxnwritelen); os << " "; printField(os, "Description", maxdescrlen); os << '\n'; printNChars(os, '-', maxnamelen); os << " "; printNChars(os, '-', maxvaluelen); os << " "; printNChars(os, '-', maxnwritelen); os << " "; if (maxdescrlen > strlen("Description")+3) printNChars(os, '-', strlen("Description")+3); else printNChars(os, '-', maxdescrlen); os << '\n'; // Print the table of parameters char buffer[32]; for (std::map::const_iterator im = values.begin(); im != values.end(); ++im) { printField(os, im->first, maxnamelen); os << " "; printField(os, im->second, maxvaluelen); os << " "; sprintf(buffer, "%d", getConfigCount(im->first.c_str())); printField(os, buffer, maxnwritelen); os << " "; getParameterDescription(&tmp, im->first.c_str()); printField(os, tmp, maxdescrlen); os << '\n'; } os.flush(); return TCL_OK; } int TclParameterSet::printParameterTable(Tcl_Interp *interp) const { std::ostringstream ost; int status = printParameterTable(ost); Tcl_SetResult(interp, const_cast( ost.str().c_str()), TCL_VOLATILE); return status; } std::map TclParameterSet::getArrayAsMapOfStrings(const char *name) const { std::map result; std::map::const_iterator it = _parameterSet.find(std::string(name)); if (it == _parameterSet.end()) // Not found return result; char buffer[64]; switch (it->second.tclLinkType) { case TCL_PARM_INT: case TCL_PARM_BOOLEAN: case TCL_PARM_DOUBLE: case TCL_PARM_FLOAT: case TCL_PARM_STRING: case TCL_PARM_LIST_INT: case TCL_PARM_LIST_BOOLEAN: case TCL_PARM_LIST_DOUBLE: case TCL_PARM_LIST_FLOAT: case TCL_PARM_LIST_STRING: // Not an array return result; case TCL_PARM_ARR_INT: { for (MapOfInts::const_iterator ip = reinterpret_cast(it->second.p)->begin(); ip != reinterpret_cast(it->second.p)->end(); ++ip) { sprintf(buffer, "%d", ip->second); result.insert(std::make_pair(ip->first,std::string(buffer))); } } break; case TCL_PARM_ARR_BOOLEAN: { for (MapOfBools::const_iterator ip = reinterpret_cast(it->second.p)->begin(); ip != reinterpret_cast(it->second.p)->end(); ++ip) { sprintf(buffer, "%d", static_cast(ip->second)); result.insert(std::make_pair(ip->first,std::string(buffer))); } } break; case TCL_PARM_ARR_DOUBLE: { for (MapOfDoubles::const_iterator ip = reinterpret_cast(it->second.p)->begin(); ip != reinterpret_cast(it->second.p)->end(); ++ip) { #if (TCL_MAJOR_VERSION > 7) Tcl_PrintDouble(0, ip->second, buffer); #else sprintf(buffer, "%#g", ip->second); #endif result.insert(std::make_pair(ip->first,std::string(buffer))); } } break; case TCL_PARM_ARR_FLOAT: { for (MapOfFloats::const_iterator ip = reinterpret_cast(it->second.p)->begin(); ip != reinterpret_cast(it->second.p)->end(); ++ip) { #if (TCL_MAJOR_VERSION > 7) Tcl_PrintDouble(0, static_cast(ip->second), buffer); #else sprintf(buffer, "%#g", static_cast(ip->second)); #endif result.insert(std::make_pair(ip->first,std::string(buffer))); } } break; case TCL_PARM_ARR_STRING: { result = *reinterpret_cast(it->second.p); } break; default: std::cerr << "ERROR in TclParameterSet::getArrayAsMapOfStrings: invalid link type " << it->second.tclLinkType << '\n' << "This is a bug. Please report. Aborting." << std::endl; abort(); } return result; } int TclParameterSet::getArrayAsList(Tcl_Interp *interp, const char *name) const { Tcl_ResetResult(interp); std::map::const_iterator it = _parameterSet.find(std::string(name)); if (it == _parameterSet.end()) { // Parameter not found Tcl_AppendResult(interp, "parameter \"", name, "\" not found", 0); return TCL_ERROR; } char buffer[64]; switch (it->second.tclLinkType) { case TCL_PARM_INT: case TCL_PARM_BOOLEAN: case TCL_PARM_DOUBLE: case TCL_PARM_FLOAT: case TCL_PARM_STRING: case TCL_PARM_LIST_INT: case TCL_PARM_LIST_BOOLEAN: case TCL_PARM_LIST_DOUBLE: case TCL_PARM_LIST_FLOAT: case TCL_PARM_LIST_STRING: Tcl_AppendResult(interp, "parameter \"", name, "\" is not an array", 0); return TCL_ERROR; case TCL_PARM_ARR_INT: { for (MapOfInts::const_iterator ip = reinterpret_cast(it->second.p)->begin(); ip != reinterpret_cast(it->second.p)->end(); ++ip) { Tcl_AppendElement(interp, const_cast(ip->first.c_str())); sprintf(buffer, "%d", ip->second); Tcl_AppendElement(interp, buffer); } } break; case TCL_PARM_ARR_BOOLEAN: { for (MapOfBools::const_iterator ip = reinterpret_cast(it->second.p)->begin(); ip != reinterpret_cast(it->second.p)->end(); ++ip) { Tcl_AppendElement(interp, const_cast(ip->first.c_str())); sprintf(buffer, "%d", static_cast(ip->second)); Tcl_AppendElement(interp, buffer); } } break; case TCL_PARM_ARR_DOUBLE: { for (MapOfDoubles::const_iterator ip = reinterpret_cast(it->second.p)->begin(); ip != reinterpret_cast(it->second.p)->end(); ++ip) { Tcl_AppendElement(interp, const_cast(ip->first.c_str())); Tcl_PrintDouble(interp, ip->second, buffer); Tcl_AppendElement(interp, buffer); } } break; case TCL_PARM_ARR_FLOAT: { for (MapOfFloats::const_iterator ip = reinterpret_cast(it->second.p)->begin(); ip != reinterpret_cast(it->second.p)->end(); ++ip) { Tcl_AppendElement(interp, const_cast(ip->first.c_str())); Tcl_PrintDouble(interp, static_cast(ip->second), buffer); Tcl_AppendElement(interp, buffer); } } break; case TCL_PARM_ARR_STRING: { for (MapOfStrings::const_iterator ip = reinterpret_cast(it->second.p)->begin(); ip != reinterpret_cast(it->second.p)->end(); ++ip) { Tcl_AppendElement(interp, const_cast(ip->first.c_str())); Tcl_AppendElement(interp, const_cast(ip->second.c_str())); } } break; default: std::cerr << "ERROR in TclParameterSet::getArrayAsList: invalid link type " << it->second.tclLinkType << '\n' << "This is a bug. Please report. Aborting." << std::endl; abort(); } return TCL_OK; } int TclParameterSet::arrayUnset(Tcl_Interp *interp, const char * name, char * pattern) { Tcl_ResetResult(interp); std::map::iterator it = _parameterSet.find(std::string(name)); if (it == _parameterSet.end()) { // Parameter not found Tcl_AppendResult(interp, "parameter \"", name, "\" not found", 0); return TCL_ERROR; } const int linkType(it->second.tclLinkType); if (!(linkType == TCL_PARM_ARR_INT || linkType == TCL_PARM_ARR_BOOLEAN || linkType == TCL_PARM_ARR_DOUBLE || linkType == TCL_PARM_ARR_FLOAT || linkType == TCL_PARM_ARR_STRING)) { Tcl_AppendResult(interp, "parameter \"", name, "\" is not an array", 0); return TCL_ERROR; } #define array_erase_pattern(MAPTYPE) do {\ std::vector matches;\ MAPTYPE *array = reinterpret_cast(it->second.p);\ for (MAPTYPE::const_iterator m = array->begin(); m != array->end(); ++m)\ if (Tcl_StringMatch(const_cast(m->first.c_str()), pattern))\ matches.push_back(m->first);\ if (matches.size() > 0)\ {\ somethingHasChanged = true;\ for (int i=0; ierase(matches[i]);\ }\ } while(0); bool somethingHasChanged = false; if (pattern) { // Unset array elements which match the pattern switch (linkType) { case TCL_PARM_ARR_INT: array_erase_pattern(MapOfInts); break; case TCL_PARM_ARR_BOOLEAN: array_erase_pattern(MapOfBools); break; case TCL_PARM_ARR_DOUBLE: array_erase_pattern(MapOfDoubles); break; case TCL_PARM_ARR_FLOAT: array_erase_pattern(MapOfFloats); break; case TCL_PARM_ARR_STRING: array_erase_pattern(MapOfStrings); break; default: std::cerr << "ERROR in TclParameterSet::arrayUnset: invalid link type " << it->second.tclLinkType << '\n' << "This is a bug. Please report. Aborting." << std::endl; abort(); } } else { // Unset the whole array switch (linkType) { case TCL_PARM_ARR_INT: if ((reinterpret_cast(it->second.p))->size()) { (reinterpret_cast(it->second.p))->clear(); somethingHasChanged = true; } break; case TCL_PARM_ARR_BOOLEAN: if ((reinterpret_cast(it->second.p))->size()) { (reinterpret_cast(it->second.p))->clear(); somethingHasChanged = true; } break; case TCL_PARM_ARR_DOUBLE: if ((reinterpret_cast(it->second.p))->size()) { (reinterpret_cast(it->second.p))->clear(); somethingHasChanged = true; } break; case TCL_PARM_ARR_FLOAT: if ((reinterpret_cast(it->second.p))->size()) { (reinterpret_cast(it->second.p))->clear(); somethingHasChanged = true; } break; case TCL_PARM_ARR_STRING: if ((reinterpret_cast(it->second.p))->size()) { (reinterpret_cast(it->second.p))->clear(); somethingHasChanged = true; } break; default: std::cerr << "ERROR in TclParameterSet::arrayUnset: invalid link type " << it->second.tclLinkType << '\n' << "This is a bug. Please report. Aborting." << std::endl; abort(); } } if (somethingHasChanged) { ++it->second.modified; _modified = true; } return TCL_OK; } int TclParameterSet::setArrayFromList(Tcl_Interp *interp, const char *name, char *value) { Tcl_ResetResult(interp); std::map::iterator it = _parameterSet.find(std::string(name)); if (it == _parameterSet.end()) { // Parameter not found Tcl_AppendResult(interp, "parameter \"", name, "\" not found", 0); return TCL_ERROR; } const int linkType(it->second.tclLinkType); if (!(linkType == TCL_PARM_ARR_INT || linkType == TCL_PARM_ARR_BOOLEAN || linkType == TCL_PARM_ARR_DOUBLE || linkType == TCL_PARM_ARR_FLOAT || linkType == TCL_PARM_ARR_STRING)) { Tcl_AppendResult(interp, "parameter \"", name, "\" is not an array", 0); return TCL_ERROR; } int listlen; char **listelem = 0; if (Tcl_SplitList(interp, value, &listlen, &listelem) != TCL_OK) return TCL_ERROR; if (listlen % 2) { Tcl_AppendResult( interp, "can't set \"", name, "\": list must have an even number of elements", 0); Tcl_Free(reinterpret_cast(listelem)); return TCL_ERROR; } int numElements = listlen/2; if (numElements == 0) { Tcl_Free(reinterpret_cast(listelem)); return TCL_OK; } switch (linkType) { case TCL_PARM_ARR_INT: { MapOfInts tmp; int x; for (int i=0; i(listelem)); return TCL_ERROR; } } MapOfInts *array = reinterpret_cast(it->second.p); for (MapOfInts::const_iterator m = tmp.begin(); m != tmp.end(); ++m) (*array)[m->first] = m->second; } break; case TCL_PARM_ARR_BOOLEAN: { MapOfBools tmp; int x; for (int i=0; i(x); } else { Tcl_Free(reinterpret_cast(listelem)); return TCL_ERROR; } } MapOfBools *array = reinterpret_cast(it->second.p); for (MapOfBools::const_iterator m = tmp.begin(); m != tmp.end(); ++m) (*array)[m->first] = m->second; } break; case TCL_PARM_ARR_DOUBLE: { MapOfDoubles tmp; double x; for (int i=0; i(listelem)); return TCL_ERROR; } } MapOfDoubles *array = reinterpret_cast(it->second.p); for (MapOfDoubles::const_iterator m = tmp.begin(); m != tmp.end(); ++m) (*array)[m->first] = m->second; } break; case TCL_PARM_ARR_FLOAT: { MapOfFloats tmp; double x; for (int i=0; i= -FLT_MAX && x <= FLT_MAX) { tmp[listelem[i*2]] = static_cast(x); continue; } else Tcl_SetResult(interp, "float value too large to represent", TCL_VOLATILE); } Tcl_Free(reinterpret_cast(listelem)); return TCL_ERROR; } MapOfFloats *array = reinterpret_cast(it->second.p); for (MapOfFloats::const_iterator m = tmp.begin(); m != tmp.end(); ++m) (*array)[m->first] = m->second; } break; case TCL_PARM_ARR_STRING: { MapOfStrings *array = reinterpret_cast(it->second.p); for (int i=0; isecond.tclLinkType << '\n' << "This is a bug. Please report. Aborting." << std::endl; abort(); } Tcl_Free(reinterpret_cast(listelem)); ++it->second.modified; _modified = true; return TCL_OK; } int TclParameterSet::getParameter(Tcl_Interp *interp, const char *name, const char *index) const { std::map::const_iterator it = _parameterSet.find(std::string(name)); if (it == _parameterSet.end()) { // Parameter not found Tcl_ResetResult(interp); Tcl_AppendResult(interp, "parameter \"", name, "\" not found", 0); return TCL_ERROR; } char buffer[64]; bool indexNotFound = false; switch (it->second.tclLinkType) { case TCL_PARM_INT: case TCL_PARM_BOOLEAN: case TCL_PARM_DOUBLE: case TCL_PARM_FLOAT: case TCL_PARM_STRING: case TCL_PARM_LIST_INT: case TCL_PARM_LIST_BOOLEAN: case TCL_PARM_LIST_DOUBLE: case TCL_PARM_LIST_FLOAT: case TCL_PARM_LIST_STRING: Tcl_ResetResult(interp); Tcl_AppendResult(interp, "parameter \"", name, "\" is not an array", 0); return TCL_ERROR; case TCL_PARM_ARR_INT: { MapOfInts::iterator mip = reinterpret_cast(it->second.p)->find(std::string(index)); if (mip == reinterpret_cast(it->second.p)->end()) indexNotFound = true; else { sprintf(buffer, "%d", mip->second); Tcl_SetResult(interp, buffer, TCL_VOLATILE); } } break; case TCL_PARM_ARR_BOOLEAN: { MapOfBools::iterator mbp = reinterpret_cast(it->second.p)->find(std::string(index)); if (mbp == reinterpret_cast(it->second.p)->end()) indexNotFound = true; else { sprintf(buffer, "%d", static_cast(mbp->second)); Tcl_SetResult(interp, buffer, TCL_VOLATILE); } } break; case TCL_PARM_ARR_DOUBLE: { MapOfDoubles::iterator mdp = reinterpret_cast(it->second.p)->find(std::string(index)); if (mdp == reinterpret_cast(it->second.p)->end()) indexNotFound = true; else { Tcl_PrintDouble(interp, mdp->second, buffer); Tcl_SetResult(interp, buffer, TCL_VOLATILE); } } break; case TCL_PARM_ARR_FLOAT: { MapOfFloats::iterator mdp = reinterpret_cast(it->second.p)->find(std::string(index)); if (mdp == reinterpret_cast(it->second.p)->end()) indexNotFound = true; else { Tcl_PrintDouble(interp, static_cast(mdp->second), buffer); Tcl_SetResult(interp, buffer, TCL_VOLATILE); } } break; case TCL_PARM_ARR_STRING: { MapOfStrings::iterator msp = reinterpret_cast(it->second.p)->find(std::string(index)); if (msp == reinterpret_cast(it->second.p)->end()) indexNotFound = true; else { std::string c = msp->second; if (c.size()) Tcl_SetResult(interp, const_cast(c.c_str()), TCL_VOLATILE); else Tcl_ResetResult(interp); } } break; default: std::cerr << "ERROR in TclParameterSet::getParameter: " << "invalid link type " << it->second.tclLinkType << "\nThis is a bug. Please report. Aborting." << std::endl; abort(); } if (indexNotFound) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "parameter \"", name, "\" with index \"", index, "\" not found", 0); return TCL_ERROR; } return TCL_OK; } int TclParameterSet::getParameter(std::string *str, const char *name, const char *index) const { std::map::const_iterator it = _parameterSet.find(std::string(name)); if (it == _parameterSet.end()) { // Parameter not found str->erase(); return TCL_ERROR; } char buffer[64]; bool indexNotFound = false; switch (it->second.tclLinkType) { case TCL_PARM_INT: case TCL_PARM_BOOLEAN: case TCL_PARM_DOUBLE: case TCL_PARM_FLOAT: case TCL_PARM_STRING: case TCL_PARM_LIST_INT: case TCL_PARM_LIST_BOOLEAN: case TCL_PARM_LIST_DOUBLE: case TCL_PARM_LIST_FLOAT: case TCL_PARM_LIST_STRING: std::cerr << "ERROR in TclParameterSet::getParameter : " << "parameter \"" << name << "\" is not an array" << std::endl; return TCL_ERROR; case TCL_PARM_ARR_INT: { MapOfInts::const_iterator mip = reinterpret_cast(it->second.p)->find(std::string(index)); if (mip == reinterpret_cast(it->second.p)->end()) indexNotFound = true; else { sprintf(buffer, "%d", mip->second); *str = std::string(buffer); } } break; case TCL_PARM_ARR_BOOLEAN: { MapOfBools::iterator mbp = reinterpret_cast(it->second.p)->find(std::string(index)); if (mbp == reinterpret_cast(it->second.p)->end()) indexNotFound = true; else { sprintf(buffer, "%d", static_cast(mbp->second)); *str = std::string(buffer); } } break; case TCL_PARM_ARR_FLOAT: { MapOfFloats::const_iterator mdp = reinterpret_cast(it->second.p)->find(std::string(index)); if (mdp == reinterpret_cast(it->second.p)->end()) indexNotFound = true; else { #if (TCL_MAJOR_VERSION > 7) Tcl_PrintDouble(0, static_cast(mdp->second), buffer); #else sprintf(buffer, "%#g", static_cast(mdp->second)); #endif *str = std::string(buffer); } } break; case TCL_PARM_ARR_DOUBLE: { MapOfDoubles::const_iterator mdp = reinterpret_cast(it->second.p)->find(std::string(index)); if (mdp == reinterpret_cast(it->second.p)->end()) indexNotFound = true; else { #if (TCL_MAJOR_VERSION > 7) Tcl_PrintDouble(0, mdp->second, buffer); #else sprintf(buffer, "%#g", mdp->second); #endif *str = std::string(buffer); } } break; case TCL_PARM_ARR_STRING: { MapOfStrings::const_iterator msp = reinterpret_cast(it->second.p)->find(std::string(index)); if (msp == reinterpret_cast(it->second.p)->end()) indexNotFound = true; else *str = msp->second; } break; default: std::cerr << "ERROR in TclParameterSet::getParameter: " << "invalid link type " << it->second.tclLinkType << "\nThis is a bug. Please report. Aborting." << std::endl; abort(); } if (indexNotFound) { std::cerr << "ERROR in TclParameterSet::getParameter : " << "parameter \"" << name << "\" with index \"" << index << "\" not found" << std::endl; str->erase(); return TCL_ERROR; } return TCL_OK; } bool TclParameterSet::isAnythingModified(void) const { bool b = _modified; _modified = false; return b; } int TclParameterSet::getParameter(std::string *str, const char *name) const { std::map::const_iterator it = _parameterSet.find(std::string(name)); if (it == _parameterSet.end()) { // Parameter not found str->erase(); return TCL_ERROR; } char buffer[64]; switch (it->second.tclLinkType) { case TCL_PARM_INT: sprintf(buffer, "%d", *reinterpret_cast(it->second.p)); *str = std::string(buffer); break; case TCL_PARM_BOOLEAN: sprintf(buffer, "%d", static_cast(*reinterpret_cast(it->second.p))); *str = std::string(buffer); break; case TCL_PARM_DOUBLE: #if (TCL_MAJOR_VERSION > 7) Tcl_PrintDouble(0, *reinterpret_cast(it->second.p), buffer); #else sprintf(buffer, "%#g", *reinterpret_cast(it->second.p)); #endif *str = std::string(buffer); break; case TCL_PARM_FLOAT: #if (TCL_MAJOR_VERSION > 7) Tcl_PrintDouble(0, static_cast( *reinterpret_cast(it->second.p)), buffer); #else sprintf(buffer, "%#g", static_cast( *reinterpret_cast(it->second.p))); #endif *str = std::string(buffer); break; case TCL_PARM_STRING: *str = *reinterpret_cast(it->second.p); break; case TCL_PARM_LIST_INT: case TCL_PARM_LIST_BOOLEAN: case TCL_PARM_LIST_DOUBLE: case TCL_PARM_LIST_FLOAT: case TCL_PARM_LIST_STRING: { Tcl_Interp *interp = Tcl_CreateInterp(); getParameter(interp, name); #if (TCL_MAJOR_VERSION > 7) *str = std::string(Tcl_GetStringResult(interp)); #else *str = std::string(interp->result); #endif Tcl_DeleteInterp(interp); } break; case TCL_PARM_ARR_INT: case TCL_PARM_ARR_BOOLEAN: case TCL_PARM_ARR_DOUBLE: case TCL_PARM_ARR_FLOAT: case TCL_PARM_ARR_STRING: std::cerr << "ERROR in TclParameterSet::getParameter : " << "parameter \"" << name << "\" is an array" << std::endl; return TCL_ERROR; default: std::cerr << "ERROR in TclParameterSet::getParameter: " << "invalid link type " << it->second.tclLinkType << "\nThis is a bug. Please report. Aborting." << std::endl; abort(); } return TCL_OK; } int TclParameterSet::setParameterDescription(const char *name, const std::string descr) { std::map::iterator it = _parameterSet.find(std::string(name)); if (it == _parameterSet.end()) { // Parameter not found return TCL_ERROR; } else { it->second.description = descr; } return TCL_OK; } int TclParameterSet::getParameterDescription(std::string *str, const char *name) const { std::map::const_iterator it = _parameterSet.find(std::string(name)); if (it == _parameterSet.end()) { // Parameter not found str->erase(); return TCL_ERROR; } if (it->second.description.size() == 0) { *str = _linkTypeString(it->second.tclLinkType); } else { *str = it->second.description; } return TCL_OK; } int TclParameterSet::getParameterDescription(Tcl_Interp *interp, const char *name) const { std::map::const_iterator it = _parameterSet.find(std::string(name)); if (it == _parameterSet.end()) { // Parameter not found Tcl_ResetResult(interp); Tcl_AppendResult(interp, "parameter \"", name, "\" not found", 0); return TCL_ERROR; } if (it->second.description.size() == 0) { Tcl_SetResult( interp, const_cast(_linkTypeString(it->second.tclLinkType).c_str()), TCL_VOLATILE); } else { Tcl_SetResult( interp, const_cast(it->second.description.c_str()), TCL_VOLATILE); } return TCL_OK; } int TclParameterSet::getConfigCount(const char *name) const { std::map::const_iterator it = _parameterSet.find(std::string(name)); if (it == _parameterSet.end()) return -1; else return it->second.modified; } bool TclParameterSet::checkConfigCount(std::ostream& os, const char *caller) const { bool printWarningHeader = true; for (std::map::const_iterator it = _parameterSet.begin(); it != _parameterSet.end(); ++it) { if (!isArray(it->first.c_str()) && it->second.modified != 1) { if (printWarningHeader) { os << "WARNING in " << caller << " : some simple parameters " << "are not configured or\n" << "configured more than once." << " These parameters are set as follows:"; printWarningHeader = false; } std::string s; getParameter(&s, it->first.c_str()); os << '\n' << it->first << " is "; if (it->second.tclLinkType == TCL_PARM_STRING) os << '"' << s << '"'; else if (it->second.tclLinkType == TCL_PARM_LIST_STRING || it->second.tclLinkType == TCL_PARM_LIST_BOOLEAN || it->second.tclLinkType == TCL_PARM_LIST_INT || it->second.tclLinkType == TCL_PARM_LIST_FLOAT || it->second.tclLinkType == TCL_PARM_LIST_DOUBLE) os << '{' << s << '}'; else os << s; if (it->second.modified == 0) os << " "; else os << " "; } } if (!printWarningHeader) os << std::endl; return printWarningHeader; } int TclParameterSet::getParamNames(Tcl_Interp *interp) const { Tcl_ResetResult(interp); for (std::map::const_iterator it = _parameterSet.begin(); it != _parameterSet.end(); ++it) Tcl_AppendElement(interp, const_cast(it->first.c_str())); return TCL_OK; } std::list TclParameterSet::getParamNames() const { std::list l; for (std::map::const_iterator it = _parameterSet.begin(); it != _parameterSet.end(); ++it) l.push_back(it->first); return l; } std::string TclParameterSet::_linkTypeString(int linkType) { static const std::string linktypes[N_TCL_LINK_TYPES] = { "string parameter", "boolean parameter", "integer parameter", "double parameter", "float parameter", "array of strings", "array of boolean values", "array of integers", "array of doubles", "array of floats", "list of strings", "list of boolean values", "list of integers", "list of doubles", "list of floats", }; if (linkType < 0 || linkType >= N_TCL_LINK_TYPES) { // If we are here, we have a bug ... std::cerr << "ERROR in TclParameterSet::_linkTypeString: invalid link type " << linkType << '\n' << "This is a bug. Please report. Aborting." << std::endl; abort(); } return linktypes[linkType]; } int TclParameterSet::parseCommand(Tcl_Interp * const interp, int argc, char *argv[]) { // std::cout << "TclParameterSet::parseCommand: argc = " // << argc << std::endl; // for (int i=0; i 4) { Tcl_AppendResult(interp, getTclHandle(), " ", argv[0], " ", argv[1]," : wrong # of arguments", 0); return TCL_ERROR; } if (argc == 4) return arrayUnset(interp, argv[2], argv[3]); else return arrayUnset(interp, argv[2], 0); } else if (strcmp("names", argv[1]) == 0) { parser_check_argc_3(4); return getParamIndices(interp, argv[2]); } else if (strcmp("size", argv[1]) == 0) { parser_check_argc_3(4); int size = getArraySize(argv[2]); if (size == -2) { Tcl_AppendResult(interp, "parameter \"", argv[2], "\" not found", 0); return TCL_ERROR; } else if (size == -1) { Tcl_AppendResult(interp, "parameter \"", argv[2], "\" is not an array", 0); return TCL_ERROR; } else { char buffer[32]; sprintf(buffer, "%d", size); Tcl_SetResult(interp, buffer, TCL_VOLATILE); } } else if (strcmp("exists", argv[1]) == 0) { parser_check_argc_3(4); Tcl_SetResult(interp, const_cast( isArray(argv[2]) ? "1" : "0"), TCL_VOLATILE); } else { Tcl_AppendResult(interp, getTclHandle(), " ", argv[0], ": bad option \"", argv[1], "\": must be set, get, size, exists, or names", 0); return TCL_ERROR; } return TCL_OK; } else if (strcmp("paramtable", argv[0]) == 0) { parser_check_argc_2(2); return printParameterTable(interp); } else if (strcmp("numconfig", argv[0]) == 0) { parser_check_argc_2(3); // Check that this is not an array element char *name = argv[1]; bool isArray = false; char *openParen = strchr(name, '('); if (openParen != 0 && openParen != name) if (name[strlen(name)-1] == ')') isArray = true; if (isArray) { Tcl_AppendResult(interp, "Parameter \"", name, "\" appears to be an array element.", " No info available.", 0); return TCL_ERROR; } int count = getConfigCount(name); if (count >= 0) { char buffer[32]; sprintf(buffer, "%d", count); Tcl_SetResult(interp, buffer, TCL_VOLATILE); return TCL_OK; } else { Tcl_AppendResult(interp, "parameter \"", argv[1], "\" not found", 0); return TCL_ERROR; } } else if (strcmp("parameter", argv[0]) == 0 || strcmp("parameters", argv[0]) == 0) { parser_check_argc_2(2); return getParamNames(interp); } else if (strcmp("paramtype", argv[0]) == 0) { parser_check_argc_2(3); char *name = argv[1]; std::map::const_iterator it = _parameterSet.find(std::string(name)); if (it == _parameterSet.end()) { Tcl_AppendResult(interp, "parameter \"", name, "\" not found", 0); return TCL_ERROR; } Tcl_SetResult(interp, const_cast(_linkTypeString( it->second.tclLinkType).c_str()), TCL_VOLATILE); return TCL_OK; } else if (strcmp("info", argv[0]) == 0) { // if (argc == 1) // { // Tcl_AppendResult(interp, "Please type \"", getTclHandle(), // " info paramName\" to get information", // " about\na particular parameter. The list of", // " parameter names can be obtained\nusing the \"", // getTclHandle(), " parameters\" command.", 0); // return TCL_OK; // } parser_check_argc_2(3); return getParameterDescription(interp, argv[1]); } else if (strcmp("help", argv[0]) == 0) { struct _helpInfo { char *command; char *args; char *info; } helpData[] = { {"array", "option paramName ?valueList?", "Available options are \"get\", \"set\", \"unset\", \"size\", \"names\", and \"exists\".\nThis command implements an interface to array parameters, similar\nto the Tcl \"array\" command."}, {"cget", "paramName", "Returns a parameter value. Use parentheses () for array indices."}, {"configure", "paramName", "Sets a parameter value. Use parentheses () for array indices."}, {"info", "paramName", "Prints a parameter description."}, {"paramtype", "paramName", "Returns parameter type."}, {"parameters", "", "Returns the list of all parameter names."}, {"paramtable", "", "Outputs basic info about all parameters in a table-like layout."}, {"numconfig", "paramName", "Returns the number of times a parameter was configured from Tcl.\nparamName may be either scalar or array name, but not a name of\nan individual array element."} }; int size = sizeof(helpData)/sizeof(helpData[0]); if (argc == 1) { // Append all help topics for (int i=1; i* vec)\ {\ assert(interp);\ assert(vec);\ vec->clear();\ std::string stmp(s);\ int listlen;\ char **listelem;\ if (Tcl_SplitList(interp, const_cast(stmp.c_str()),\ &listlen, &listelem) != TCL_OK)\ return TCL_ERROR;\ for (int i=0; i InsertMethod (std::string(listelem[i]));\ Tcl_Free((char *)listelem);\ return TCL_OK;\ } // string_to_list(std::string&,std::vector,push_back) // string_to_list(std::string&,std::list,push_back) // string_to_list(std::string&,std::set,insert) string_to_list(char*,std::vector,push_back) string_to_list(char*,std::list,push_back) string_to_list(char*,std::set,insert) #define list_parser(RefType,Container,ContainedType,InsertMethod,TempType,ParserFun) int\ TclParameterSet::parseTclList(Tcl_Interp* interp, const RefType s,\ Container < ContainedType >* vec)\ {\ assert(interp);\ assert(vec);\ vec->clear();\ std::string stmp(s);\ int listlen;\ char **listelem;\ if (Tcl_SplitList(interp, const_cast(stmp.c_str()),\ &listlen, &listelem) != TCL_OK)\ return TCL_ERROR;\ TempType tmp;\ for (int i=0; iclear();\ Tcl_Free((char *)listelem);\ return TCL_ERROR;\ }\ vec-> InsertMethod (static_cast< ContainedType >(tmp));\ }\ Tcl_Free((char *)listelem);\ return TCL_OK;\ } #define float_list_parser(RefType,Container,InsertMethod) int\ TclParameterSet::parseTclList(Tcl_Interp* interp, const RefType s,\ Container < float >* vec)\ {\ assert(interp);\ assert(vec);\ vec->clear();\ std::string stmp(s);\ int listlen;\ char **listelem;\ if (Tcl_SplitList(interp, const_cast(stmp.c_str()),\ &listlen, &listelem) != TCL_OK)\ return TCL_ERROR;\ double tmp;\ for (int i=0; iclear();\ Tcl_Free((char *)listelem);\ return TCL_ERROR;\ }\ if (tmp < -FLT_MAX || tmp > FLT_MAX)\ {\ vec->clear();\ Tcl_Free((char *)listelem);\ Tcl_SetResult(interp, "float value too large to represent",\ TCL_VOLATILE);\ return TCL_ERROR;\ }\ vec-> InsertMethod (static_cast(tmp));\ }\ Tcl_Free((char *)listelem);\ return TCL_OK;\ } list_parser(char*,std::vector,int,push_back,int,Tcl_GetInt) list_parser(char*,std::vector,bool,push_back,int,Tcl_GetBoolean) list_parser(char*,std::vector,double,push_back,double,Tcl_GetDouble) float_list_parser(char*,std::vector,push_back) list_parser(char*,std::list,int,push_back,int,Tcl_GetInt) list_parser(char*,std::list,bool,push_back,int,Tcl_GetBoolean) list_parser(char*,std::list,double,push_back,double,Tcl_GetDouble) float_list_parser(char*,std::list,push_back) list_parser(char*,std::set,int,insert,int,Tcl_GetInt) list_parser(char*,std::set,bool,insert,int,Tcl_GetBoolean) list_parser(char*,std::set,double,insert,double,Tcl_GetDouble) float_list_parser(char*,std::set,insert) #define setup_parameter_method(T, paramLinkType) int\ TclParameterSet::setupParameter(\ const char *name, T * param, const T & initValue)\ {\ if (name == 0)\ {\ std::cerr << "ERROR in TclParameterSet::setupParameter: NULL name."\ << std::endl;\ return TCL_ERROR;\ }\ if (param == 0)\ {\ std::cerr << "ERROR in TclParameterSet::setupParameter: NULL parameter pointer.\n"\ << "Can't set up parameter \"" << name << "\"."\ << std::endl;\ return TCL_ERROR;\ }\ std::string s(name);\ std::map::const_iterator it = _parameterSet.find(s);\ if (it != _parameterSet.end())\ {\ std::cerr << "ERROR in TclParameterSet::setupParameter: parameter named \""\ << name << "\" already exists" << std::endl;\ return TCL_ERROR;\ }\ *param = initValue;\ TclParameter tmp;\ tmp.p = param;\ tmp.tclLinkType = paramLinkType ;\ tmp.modified = 0;\ _parameterSet.insert(std::make_pair(s,tmp));\ return TCL_OK;\ } #define setup_noinit_method(T, paramLinkType) int\ TclParameterSet::setupParameter(\ const char *name, T * param)\ {\ if (name == 0)\ {\ std::cerr << "ERROR in TclParameterSet::setupParameter: NULL name."\ << std::endl;\ return TCL_ERROR;\ }\ if (param == 0)\ {\ std::cerr << "ERROR in TclParameterSet::setupParameter: NULL parameter pointer.\n"\ << "Can't set up parameter \"" << name << "\"."\ << std::endl;\ return TCL_ERROR;\ }\ std::string s(name);\ std::map::const_iterator it = _parameterSet.find(s);\ if (it != _parameterSet.end())\ {\ std::cerr << "ERROR in TclParameterSet::setupParameter: parameter named \""\ << name << "\" already exists" << std::endl;\ return TCL_ERROR;\ }\ TclParameter tmp;\ tmp.p = param;\ tmp.tclLinkType = paramLinkType ;\ tmp.modified = 0;\ _parameterSet.insert(std::make_pair(s,tmp));\ return TCL_OK;\ } #define const_noinit_method(T, paramLinkType) int\ TclParameterSet::setupParameter(\ const char *name, const volatile T * param)\ {\ if (name == 0)\ {\ std::cerr << "ERROR in TclParameterSet::setupParameter: NULL name."\ << std::endl;\ return TCL_ERROR;\ }\ if (param == 0)\ {\ std::cerr << "ERROR in TclParameterSet::setupParameter: NULL parameter pointer.\n"\ << "Can't set up parameter \"" << name << "\"."\ << std::endl;\ return TCL_ERROR;\ }\ std::string s(name);\ std::map::const_iterator it = _parameterSet.find(s);\ if (it != _parameterSet.end())\ {\ std::cerr << "ERROR in TclParameterSet::setupParameter: parameter named \""\ << name << "\" already exists" << std::endl;\ return TCL_ERROR;\ }\ TclParameter tmp;\ tmp.p = const_cast(param);\ tmp.tclLinkType = paramLinkType ;\ tmp.modified = 0;\ _parameterSet.insert(std::make_pair(s,tmp));\ return TCL_OK;\ } setup_parameter_method(int, TCL_PARM_INT) setup_parameter_method(bool, TCL_PARM_BOOLEAN) setup_parameter_method(float, TCL_PARM_FLOAT) setup_parameter_method(double, TCL_PARM_DOUBLE) setup_parameter_method(std::string, TCL_PARM_STRING) setup_parameter_method(std::vector, TCL_PARM_LIST_INT) setup_parameter_method(std::vector, TCL_PARM_LIST_BOOLEAN) setup_parameter_method(std::vector, TCL_PARM_LIST_FLOAT) setup_parameter_method(std::vector, TCL_PARM_LIST_DOUBLE) setup_parameter_method(std::vector, TCL_PARM_LIST_STRING) setup_parameter_method(MapOfInts, TCL_PARM_ARR_INT) setup_parameter_method(MapOfBools, TCL_PARM_ARR_BOOLEAN) setup_parameter_method(MapOfFloats, TCL_PARM_ARR_FLOAT) setup_parameter_method(MapOfDoubles, TCL_PARM_ARR_DOUBLE) setup_parameter_method(MapOfStrings, TCL_PARM_ARR_STRING) setup_parameter_method(CSMapOfInts, TCL_PARM_ARR_INT) setup_parameter_method(CSMapOfBools, TCL_PARM_ARR_BOOLEAN) setup_parameter_method(CSMapOfFloats, TCL_PARM_ARR_FLOAT) setup_parameter_method(CSMapOfDoubles, TCL_PARM_ARR_DOUBLE) setup_parameter_method(CSMapOfStrings, TCL_PARM_ARR_STRING) setup_noinit_method(int, TCL_PARM_INT) setup_noinit_method(bool, TCL_PARM_BOOLEAN) setup_noinit_method(float, TCL_PARM_FLOAT) setup_noinit_method(double, TCL_PARM_DOUBLE) setup_noinit_method(std::string, TCL_PARM_STRING) setup_noinit_method(std::vector, TCL_PARM_LIST_INT) setup_noinit_method(std::vector, TCL_PARM_LIST_BOOLEAN) setup_noinit_method(std::vector, TCL_PARM_LIST_FLOAT) setup_noinit_method(std::vector, TCL_PARM_LIST_DOUBLE) setup_noinit_method(std::vector, TCL_PARM_LIST_STRING) setup_noinit_method(MapOfInts, TCL_PARM_ARR_INT) setup_noinit_method(MapOfBools, TCL_PARM_ARR_BOOLEAN) setup_noinit_method(MapOfFloats, TCL_PARM_ARR_FLOAT) setup_noinit_method(MapOfDoubles, TCL_PARM_ARR_DOUBLE) setup_noinit_method(MapOfStrings, TCL_PARM_ARR_STRING) setup_noinit_method(CSMapOfInts, TCL_PARM_ARR_INT) setup_noinit_method(CSMapOfBools, TCL_PARM_ARR_BOOLEAN) setup_noinit_method(CSMapOfFloats, TCL_PARM_ARR_FLOAT) setup_noinit_method(CSMapOfDoubles, TCL_PARM_ARR_DOUBLE) setup_noinit_method(CSMapOfStrings, TCL_PARM_ARR_STRING) const_noinit_method(int, TCL_PARM_INT) const_noinit_method(bool, TCL_PARM_BOOLEAN) const_noinit_method(float, TCL_PARM_FLOAT) const_noinit_method(double, TCL_PARM_DOUBLE) const_noinit_method(std::string, TCL_PARM_STRING) const_noinit_method(std::vector, TCL_PARM_LIST_INT) const_noinit_method(std::vector, TCL_PARM_LIST_BOOLEAN) const_noinit_method(std::vector, TCL_PARM_LIST_FLOAT) const_noinit_method(std::vector, TCL_PARM_LIST_DOUBLE) const_noinit_method(std::vector, TCL_PARM_LIST_STRING) const_noinit_method(MapOfInts, TCL_PARM_ARR_INT) const_noinit_method(MapOfBools, TCL_PARM_ARR_BOOLEAN) const_noinit_method(MapOfFloats, TCL_PARM_ARR_FLOAT) const_noinit_method(MapOfDoubles, TCL_PARM_ARR_DOUBLE) const_noinit_method(MapOfStrings, TCL_PARM_ARR_STRING) const_noinit_method(CSMapOfInts, TCL_PARM_ARR_INT) const_noinit_method(CSMapOfBools, TCL_PARM_ARR_BOOLEAN) const_noinit_method(CSMapOfFloats, TCL_PARM_ARR_FLOAT) const_noinit_method(CSMapOfDoubles, TCL_PARM_ARR_DOUBLE) const_noinit_method(CSMapOfStrings, TCL_PARM_ARR_STRING)