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

📄 parse.cxx

📁 eCos1.31版
💻 CXX
📖 第 1 页 / 共 3 页
字号:
            } else {                value = argv[index];            }            index++;        }        // At this stage index points at the next argument to be processed, and should not        // be updated again.                // Unless the option can occur multiple times, make sure that it is not already        // present in the options vector.        if (!multiple_flag) {            for (i = 0; i < result.size(); i++) {                if (name == result[i].first) {                    CdlParse::report_warning(interp, diag_prefix + ", option " + name +                                             " can only be used once.");                    break;                }            }        }        // The name/value pair is valid, so add it to the result vector.        result.push_back(std::make_pair(name, value));    }        CYG_REPORT_RETVAL(index);    return index;}//}}}//{{{  Diagnostic prefix                        // Construct a suitable prefix for any warning or error message. This// should include the filename and the entity name.//// Obviously a line number would be rather useful as well, but this is not// very easy because of the way Tcl interpreters work.std::stringCdlParse::get_diagnostic_prefix(CdlInterpreter interp){    std::string filename        = interp->get_filename();    CdlNode     current_node    = interp->get_node();    std::string result = ("" != filename) ? filename : "<unknown data source>";    if (0 != current_node) {        result += ", " + current_node->get_class_name() + " " + current_node->get_name();    }    result += "\n    ";    return result;}//}}}//{{{  Error count tracking                     // Keep track of the number of errors that have occurred while doing some// parsing. This functionality is not provided directly by the CdlInterpreter// class, instead it is implemented using assoc data.static const char       error_count_key[]       = "CdlErrorCount";static voiderror_count_delproc(ClientData data, Tcl_Interp* interp){    CYG_REPORT_FUNCNAME("CdlParse::error_count_delproc");    int* newed_ptr = static_cast<int*>(data);    delete newed_ptr;    CYG_REPORT_RETURN();}voidCdlParse::clear_error_count(CdlInterpreter interp){    CYG_REPORT_FUNCNAME("CdlParse::clear_error_count");    CYG_REPORT_FUNCARG1("interp %p", interp);    CYG_PRECONDITION_CLASSC(interp);    int*        newed_ptr = static_cast<int*>(interp->get_assoc_data(error_count_key));    if (0 != newed_ptr) {        *newed_ptr = 0;    }    CYG_REPORT_RETURN();}voidCdlParse::incr_error_count(CdlInterpreter interp, int how_much){    CYG_REPORT_FUNCNAME("CdlParse::incr_error_counter");    CYG_REPORT_FUNCARG2("interp %p, how_much %d", interp, how_much);    CYG_PRECONDITION_CLASSC(interp);    CYG_PRECONDITION(how_much > 0, "previous errors cannot be undone");        int* newed_ptr = static_cast<int*>(interp->get_assoc_data(error_count_key));    if (0 == newed_ptr) {        newed_ptr = new int(how_much);        interp->set_assoc_data(error_count_key, static_cast<void*>(newed_ptr), &error_count_delproc);    } else {        CYG_ASSERT((*newed_ptr + how_much) > *newed_ptr, "number of parsing errors should not overflow");        *newed_ptr += how_much;    }    CYG_REPORT_RETURN();}intCdlParse::get_error_count(CdlInterpreter interp){    CYG_REPORT_FUNCNAMETYPE("CdlParse::get_error_count", "count %d");    CYG_REPORT_FUNCARG1("interp %p", interp);    CYG_PRECONDITION_CLASSC(interp);    int result = 0;    int* newed_ptr = static_cast<int*>(interp->get_assoc_data(error_count_key));    if (0 != newed_ptr) {        result = *newed_ptr;    }    CYG_REPORT_RETVAL(result);    return result;}//}}}//{{{  Error and warning reporting              // Report an error or warning. This involves adding a suitable prefix// and invoking the reporting callback currently associated with the// interpreter. For errors it is also necessary to increment the error// counter so that later count can detect the number of errors that// have occurred.//// The error callback is allowed to raise a CdlParseException. This should// not be caught here. Instead this exception is caught in every parse// routine, before it can go back through the Tcl interpreter.//// FIXME: cope with prefixing multiline error messages.voidCdlParse::report_error(CdlInterpreter interp, std::string message){    CYG_REPORT_FUNCNAME("CdlParse::report_error");    CYG_REPORT_FUNCARG1("interp %p", interp);    CYG_PRECONDITION_CLASSC(interp);    incr_error_count(interp);        message = get_diagnostic_prefix(interp) + message;    CdlDiagnosticFnPtr fn = interp->get_error_fn_ptr();    CYG_ASSERT(0 != fn, "during parsing an interpreter should have an associated error reporting function");    (*fn)(message);    CYG_REPORT_RETURN();}voidCdlParse::report_warning(CdlInterpreter interp, std::string message){    CYG_REPORT_FUNCNAME("CdlParse::report_warning");    CYG_REPORT_FUNCARG1("interp %p", interp);    CYG_PRECONDITION_CLASSC(interp);        message = get_diagnostic_prefix(interp) + message;    CdlDiagnosticFnPtr fn = interp->get_warning_fn_ptr();    if (0 != fn) {        (*fn)(message);    }    CYG_REPORT_RETURN();}//}}}//{{{  The "unknown" command                    // ----------------------------------------------------------------------------// This routine should be installed in interpreters that get used for// parsing CDL scripts. It gets invoked when the CDL script contains// an unrecognised command, e.g. because of a typo, and makes sure that// the usual diagnostics process is observed.//// This routine should be uninstalled after the parsing is complete,// to avoid e.g. a ParseException when it is not expected.intCdlParse::unknown_command(CdlInterpreter interp, int argc, char** argv){    CYG_REPORT_FUNCNAME("CdlParse::unknown_command");    CYG_REPORT_FUNCARG3XV(interp, argc, argv);    CYG_PRECONDITIONC(2 <= argc);    CYG_PRECONDITION_CLASSC(interp);        report_error(interp, std::string("Unknown command `") + argv[1] + "'.");    CYG_UNUSED_PARAM(int, argc);        return TCL_OK;}//}}}//}}}//{{{  Property-related parser utilities        // ----------------------------------------------------------------------------// Utilities related to parsing properties, rather than more general parsing.// Provide a prefix that matches the current property.std::stringCdlParse::get_property_prefix(char* argv0){    CYG_REPORT_FUNCNAME("CdlParse::get_property_prefix");    std::string result = std::string("Property " ) + CdlParse::get_tcl_cmd_name(argv0) + ", ";    CYG_REPORT_RETURN();    return result;}std::stringCdlParse::get_property_prefix(CdlProperty prop){    CYG_REPORT_FUNCNAME("CdlParse::get_property_prefix");    std::string result = std::string("Property ");    const std::vector<std::string>& argv = prop->get_argv();    result = result + argv[0] + ", ";        CYG_REPORT_RETURN();    return result;}// A variant of report_parse_error() which also adds the property prefix.voidCdlParse::report_property_parse_error(CdlInterpreter interp, char* argv0, std::string msg){    CYG_REPORT_FUNCNAME("CdlPase::report_property_parse_error");    report_error(interp, get_property_prefix(argv0) + msg);        CYG_REPORT_RETURN();}voidCdlParse::report_property_parse_error(CdlInterpreter interp, CdlProperty prop, std::string msg){    CYG_REPORT_FUNCNAME("CdlParse::report_property_parse_error");    report_error(interp, get_property_prefix(prop) + msg);    CYG_REPORT_RETURN();}//}}}//{{{  Generic property parsers                 // ----------------------------------------------------------------------------// Generic parsers//// These routines provide some more generic property parsing routines. argv[0]// generally provides sufficient information to allow for sensible error messages.// The command-specific parsers have to provide a property name. In addition it is// possible to provide a function to handle per-command options, and another// function that performs a final sanity check before the property gets added// to the current entity.//{{{  parse_minimal_property()         // ----------------------------------------------------------------------------// A minimal property takes no arguments.intCdlParse::parse_minimal_property(CdlInterpreter interp, int argc, char** argv, std::string name,                                 char** options_desc, void (*final_parser)(CdlInterpreter, CdlProperty_Minimal)){    CYG_REPORT_FUNCNAME("parse_minimal_property");    CYG_PRECONDITION_CLASSC(interp);        CdlProperty_Minimal new_property = 0;    try {        std::vector<std::pair<std::string,std::string> > options;        int data_index = CdlParse::parse_options(interp, property_string + argv[0], options_desc, argc, argv, 1, options);                if (data_index < argc) {            CdlParse::report_property_parse_error(interp, argv[0],  std::string("Unexpected data ") + argv[data_index]);        } else {                    // The command is valid, turn it into a property.            // The property has been parsed successfully. Add it to the current node            CdlNode current_node = interp->get_node();            CYG_ASSERTC(0 != current_node);            new_property = CdlProperty_MinimalBody::make(current_node, name, argc, argv, options);            if (0 != final_parser) {                (*final_parser)(interp, new_property);            }        }    } catch(...) {                if (0 != new_property) {            delete new_property;        }        throw;    }        return TCL_OK;}//}}}//{{{  parse_string_property()          // ----------------------------------------------------------------------------intCdlParse::parse_string_property(CdlInterpreter interp, int argc, char** argv, std::string name,                                char** options_desc, void (*final_parser)(CdlInterpreter, CdlProperty_String)){    CYG_REPORT_FUNCNAME("parse_string_property");    CYG_PRECONDITION_CLASSC(interp);        CdlProperty_String new_property = 0;        try {        std::vector<std::pair<std::string,std::string> > options;        int data_index = CdlParse::parse_options(interp, property_string + argv[0], options_desc, argc, argv, 1, options);        if (data_index == argc) {            CdlParse::report_property_parse_error(interp, argv[0], "missing argument.");        } else if ((data_index + 1) < argc) {            CdlParse::report_property_parse_error(interp, argv[0], std::string("Too many arguments, expecting just one."));        } else {

⌨️ 快捷键说明

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