⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 interp.cxx

📁 eCos1.31版
💻 CXX
📖 第 1 页 / 共 3 页
字号:
}//}}}//{{{  CdlInterpreter:: variables                               // ----------------------------------------------------------------------------// Provide some more stubs, this time for accessing Tcl global variables.voidCdlInterpreterBody::set_variable(std::string name, std::string value){    CYG_REPORT_FUNCNAME("CdlInterpreter::set_variable");    CYG_REPORT_FUNCARG2("this %p, name %s", this, name.c_str());    CYG_PRECONDITION_THISC();    CYG_PRECONDITIONC("" != name);    if (0 == Tcl_SetVar(tcl_interp, const_cast<char*>(name.c_str()), const_cast<char*>(value.c_str()), TCL_GLOBAL_ONLY)) {        throw std::bad_alloc();    }    CYG_REPORT_RETURN();}voidCdlInterpreterBody::unset_variable(std::string name){    CYG_REPORT_FUNCNAME("CdlInterpreter::unset_variable");    CYG_REPORT_FUNCARG2("this %p, name %s", this, name.c_str());    CYG_PRECONDITION_THISC();    CYG_PRECONDITIONC("" != name);    Tcl_UnsetVar(tcl_interp, const_cast<char*>(name.c_str()), TCL_GLOBAL_ONLY);    CYG_REPORT_RETURN();}std::stringCdlInterpreterBody::get_variable(std::string name){    CYG_REPORT_FUNCNAME("CdlInterpreter::get_variable");    CYG_REPORT_FUNCARG2("this %p, name %s", this, name.c_str());    CYG_PRECONDITION_THISC();    CYG_PRECONDITIONC("" != name);    std::string result = "";    char *tmp = Tcl_GetVar(tcl_interp, const_cast<char*>(name.c_str()), TCL_GLOBAL_ONLY);    if (0 != tmp) {        result = tmp;    }        CYG_REPORT_RETURN();    return result;}//}}}//{{{  CdlInterpreter:: assoc data                              // ----------------------------------------------------------------------------// Associated data. It is useful to be able to store some C++ data with// Tcl interpreters, so that the implementations of various commands// can retrieve details of the current state. Tcl provides the necessary// underlying support via routines Tcl_SetAssocData() etc., and the// routines here are just stubs for the underlying Tcl ones.voidCdlInterpreterBody::set_assoc_data(const char* key, ClientData data, Tcl_InterpDeleteProc* del_proc){    CYG_REPORT_FUNCNAME("CdlInterpreter::set_assoc_data");    CYG_REPORT_FUNCARG3("this %p, key %s, data %p", this, key, data);    CYG_PRECONDITION_THISC();    CYG_PRECONDITIONC((0 != key) && ('\0' != key[0]));    Tcl_SetAssocData(tcl_interp, const_cast<char*>(key), del_proc, data);    CYG_REPORT_RETURN();}ClientDataCdlInterpreterBody::get_assoc_data(const char* key){    CYG_REPORT_FUNCNAMETYPE("CdlInterpreter::get_assoc_data", "result %p");    CYG_REPORT_FUNCARG2("this %p, key %s", this, key);    CYG_PRECONDITION_THISC();    CYG_PRECONDITIONC((0 != key) && ('\0' != key[0]));    ClientData result = Tcl_GetAssocData(tcl_interp, const_cast<char*>(key), 0);    CYG_REPORT_RETVAL(result);    return result;}voidCdlInterpreterBody::delete_assoc_data(const char* key){    CYG_REPORT_FUNCNAME("CdlInterpreter::delete_assoc_data");    CYG_REPORT_FUNCARG2("this %p, key %s", this, key);    CYG_PRECONDITION_THISC();    CYG_PRECONDITIONC((0 != key) && ('\0' != key[0]));    Tcl_DeleteAssocData(tcl_interp, const_cast<char*>(key));    CYG_REPORT_RETURN();}//}}}//{{{  CdlInterpreter:: file I/O                                // ----------------------------------------------------------------------------// Tcl provides file I/O facilities that are already known to be portable// to the platforms of interest.boolCdlInterpreterBody::is_directory(std::string name){    CYG_REPORT_FUNCNAMETYPE("CdlInterpreter::is_directory", "result %d");    CYG_REPORT_FUNCARG1XV(this);    CYG_PRECONDITION_THISC();    CYG_PRECONDITIONC("" != name);    bool result = false;    std::string command = "file isdirectory \"" + name + "\"";    std::string tcl_result;    if ((TCL_OK == this->eval(command, tcl_result)) && ("1" == tcl_result)) {        result = true;    }    CYG_REPORT_RETVAL(result);    return result;}boolCdlInterpreterBody::is_file(std::string name){    CYG_REPORT_FUNCNAMETYPE("CdlInterpreter::is_file", "result %d");    CYG_REPORT_FUNCARG1XV(this);    CYG_PRECONDITION_THISC();    CYG_PRECONDITIONC("" != name);    bool result = false;    std::string command = "file isfile \"" + name + "\"";    std::string tcl_result;    if ((TCL_OK == this->eval(command, tcl_result)) && ("1" == tcl_result)) {        result = true;    }    CYG_REPORT_RETVAL(result);    return result;}// ----------------------------------------------------------------------------voidCdlInterpreterBody::locate_subdirs(std::string directory, std::vector<std::string>& result){    CYG_REPORT_FUNCNAME("CdlInterpreter::locate_subdirs");    CYG_REPORT_FUNCARG2XV(this, &result);    CYG_PRECONDITION_THISC();        static char locate_subdirs_script[] = "\set pattern [file join \"$::cdl_locate_subdirs_path\" * .]  \n\set result {}                                               \n\foreach entry [glob -nocomplain -- $pattern] {              \n\    set entry [file tail [file dirname $entry]]             \n\    if {$entry != \"CVS\"} {                                \n\        lappend result $entry                               \n\    }                                                       \n\}                                                           \n\return $result                                              \n\";        std::string                 tcl_result = "";    set_variable("::cdl_locate_subdirs_path", directory);    if (TCL_OK != eval(locate_subdirs_script, tcl_result)) {        CYG_FAIL("Internal error evaluating Tcl script");    }    int         count;    char**      array;    if (TCL_OK != Tcl_SplitList(tcl_interp, const_cast<char*>(tcl_result.c_str()), &count, &array)) {        throw std::bad_alloc();    }    for (int i = 0; i < count; i++) {        result.push_back(array[i]);    }    Tcl_Free((char*) array);    CYG_REPORT_RETURN();}// ----------------------------------------------------------------------------// Locating all subdirs requires some simple recursionvoidCdlInterpreterBody::locate_all_subdirs(std::string directory, std::vector<std::string>& result){    CYG_REPORT_FUNCNAME("CdlInterpreter::locate_all_subdirs");    CYG_REPORT_FUNCARG2XV(this, &result);    CYG_PRECONDITION_THISC();    CYG_PRECONDITIONC("" != directory);    std::vector<std::string> subdirs;    locate_subdirs(directory, subdirs);    std::vector<std::string>::const_iterator i, j;    for (i = subdirs.begin(); i != subdirs.end(); i++) {        result.push_back(*i);        std::vector<std::string> its_subdirs;        locate_all_subdirs(directory + "/" + *i, its_subdirs);        for (j = its_subdirs.begin(); j != its_subdirs.end(); j++) {            result.push_back(*i + "/" + *j);        }    }    CYG_REPORT_RETURN();}// ----------------------------------------------------------------------------// Locating the files in a particular subdirectory. This requires another// simple Tcl script.voidCdlInterpreterBody::locate_files(std::string directory, std::vector<std::string>& result){    CYG_REPORT_FUNCNAME("CdlInterpreter::locate_files");    CYG_REPORT_FUNCARG2XV(this, &result);    CYG_PRECONDITION_THISC();    CYG_PRECONDITIONC("" != directory);    static char locate_files_script[] = "\set pattern [file join \"$::cdl_locate_files_path\" *]  \n\set result {}                                           \n\foreach entry [glob -nocomplain -- $pattern] {          \n\    if ([file isdirectory $entry]) {                    \n\        continue                                        \n\    }                                                   \n\    lappend result [file tail $entry]                   \n\ }                                                      \n\return $result                                          \n\";     std::string                 tcl_result;    set_variable("::cdl_locate_files_path", directory);    if (TCL_OK != eval(locate_files_script, tcl_result)) {        CYG_FAIL("Internal error evaluating Tcl script");    }    int         count;    char**      array;    if (TCL_OK != Tcl_SplitList(tcl_interp, const_cast<char*>(tcl_result.c_str()), &count, &array)) {        throw std::bad_alloc();    }    for (int i = 0; i < count; i++) {        result.push_back(array[i]);    }    Tcl_Free((char*) array);    CYG_REPORT_RETURN();}// ----------------------------------------------------------------------------// Locating all files can be achieved by combining locate_all_subdirs()// and locate_files().voidCdlInterpreterBody::locate_all_files(std::string directory, std::vector<std::string>& result){    CYG_REPORT_FUNCNAME("CdlInterpreter::locate_all_files");    CYG_REPORT_FUNCARG2XV(this, &result);    CYG_PRECONDITION_THISC();    CYG_PRECONDITIONC("" != directory);    std::vector<std::string> files;    std::vector<std::string>::const_iterator i, j;    locate_files(directory, files);    for (i = files.begin(); i != files.end(); i++) {        result.push_back(*i);    }        std::vector<std::string> all_subdirs;    locate_all_subdirs(directory, all_subdirs);    for (i = all_subdirs.begin(); i != all_subdirs.end(); i++) {        std::vector<std::string> subdir_files;        locate_files(directory + "/" + *i, subdir_files);        for (j = subdir_files.begin(); j != subdir_files.end(); j++) {            result.push_back(*i + "/" + *j);        }    }    CYG_REPORT_RETURN();}// ----------------------------------------------------------------------------// Write some data to a file, throwing an I/O exception on failure. This// functionality is needed whenever savefile data is generated, it is// convenient to have a utility function to do the job. Also, performing// the Tcl_Write involves passing const data as a non-const argument:// if this ever causes problems in future it is a good idea to isolate// the problem here.voidCdlInterpreterBody::write_data(Tcl_Channel chan, std::string data)    throw(CdlInputOutputException){    CYG_REPORT_FUNCNAME("CdlInterpreter::write_data");    CYG_REPORT_FUNCARG2XV(this, chan);    CYG_PRECONDITION_THISC();    if (-1 == Tcl_Write(chan, const_cast<char*>(data.data()), data.size())) {        std::string msg = "Unexpected error writing to file " + this->get_filename() + " : " + Tcl_PosixError(tcl_interp);        throw CdlInputOutputException(msg);    }        CYG_REPORT_RETURN();}//}}}//{{{  CdlInterpreter:: quote() etc.                            // ----------------------------------------------------------------------------// Given a string, quote it in such a way that the Tcl interpreter will// process it as a single word, but keep the result as human-readable// as possible. If there are no special characters then just return the// string itself. Otherwise quoting is necessary.//// The choice is between braces and double quotes. Generally braces// are better and more consistent, but there is a problem if the// string argument itself contains braces. These could be// backslash-escaped, but the Tcl interpreter will not automatically// remove the backslashes so we would end up with a discrepancy// between the original data and what is seen by the parser. In this// case quote marks have to be used instead.//// NOTE: this code may not behave sensibly when it comes to i18n// issues.std::stringCdlInterpreterBody::quote(std::string src){    CYG_REPORT_FUNCNAME("CdlInterpreter::quote");    std::string  result = "";    bool         contains_specials = false;    unsigned int i;    if (0 == src.size()) {        // An empty string. The best way to represent this is an empty        // set of quotes.        result = "\"\"";        CYG_REPORT_RETURN();        return result;    }        if ('#' == src[0]) {        contains_specials = true;    }        for (i = 0; (i < src.size()) && !contains_specials; i++) {        if (isspace(src[i])) {            contains_specials = true;            break;        }        switch(src[i]) {          case '{':          case '}':          case '\\':          case '$':          case '"':          case '[':          case ']':          case '#':          case ';':              contains_specials = true;              break;                      default:              break;        }    }    if (!contains_specials) {        result = src;    } else{        // If the data is a multiline item, it is better to start it in column 0.        // Unfortunately there is the question of what to do with the opening        // quote. Putting it on the current line, followed by a backslash-escaped        // newline, introduces a space into the string. If the string begins with        // a space anyway then arguably this would be harmless, but it could        // be confusing to the user. Putting the opening double quote into column 0        // means that the first line of data is indented relative to the rest of        // the data, but still appears to be the best alternative.        if (src.find('\n') != std::string::npos) {            result += "\\\n";        }        result += '\"';        for (i = 0; i < src.size(); i++) {            switch(src[i]) {              case '\\':              case '$':              case '"':              case '[':              case ']':                  result += '\\';                  result += src[i];                  break;                                default:                result += src[i];                break;            }        }        result += '\"';    }        CYG_REPORT_RETURN();    return result;}// ----------------------------------------------------------------------------// Given some data which may be multiline, return a string which corresponds// to that data turned into a comment.std::stringCdlInterpreterBody::multiline_comment(const std::string& orig, int first_indent, int second_indent){    CYG_REPORT_FUNCNAME("CdlInterpreter::multiline_comment");    std::string indent  = std::string(first_indent, ' ') + "# " + std::string(second_indent, ' ');    std::string result  = "";    bool indent_needed = true;        std::string::const_iterator str_i;    for (str_i = orig.begin(); str_i != orig.end(); str_i++) {        if (indent_needed) {            result += indent;            indent_needed = false;        }        result += *str_i;        if ('\n' == *str_i) {            indent_needed = true;        }    }        CYG_REPORT_RETURN();    return result;}// ----------------------------------------------------------------------------// Given some data, append it to the current line and add additional commented// and indented lines as required.std::stringCdlInterpreterBody::extend_comment(const std::string& orig, int first_indent, int second_indent){    CYG_REPORT_FUNCNAME("CdlInterpreter::extend_comment");    std::string indent  = std::string(first_indent, ' ') + "# " + std::string(second_indent, ' ');    std::string result = "";    bool indent_needed = false;        std::string::const_iterator str_i;    for (str_i = orig.begin(); str_i != orig.end(); str_i++) {        if (indent_needed) {            result += indent;            indent_needed = false;        }        result += *str_i;        if ('\n' == *str_i) {            indent_needed = true;        }    }        CYG_REPORT_RETURN();    return result;}//}}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -