Mercurial > ecos
comparison host/libcdl/component.cxx @ 82:6736c52df507 ecos-sw-2000-04-14
Merge from eCos master repository on 2000-04-14-13:35:46-BST
| author | jlarmour |
|---|---|
| date | Tue, 18 Apr 2000 21:51:55 +0000 |
| parents | 435cced73e2f |
| children | 6ed91473a1cd |
comparison
equal
deleted
inserted
replaced
| 81:89fef2181d7d | 82:6736c52df507 |
|---|---|
| 117 { | 117 { |
| 118 CYG_REPORT_FUNCNAMETYPE("CdlComponentBody::parse_component", "result %d"); | 118 CYG_REPORT_FUNCNAMETYPE("CdlComponentBody::parse_component", "result %d"); |
| 119 CYG_REPORT_FUNCARG1("argc %d", argc); | 119 CYG_REPORT_FUNCARG1("argc %d", argc); |
| 120 CYG_PRECONDITION_CLASSC(interp); | 120 CYG_PRECONDITION_CLASSC(interp); |
| 121 | 121 |
| 122 const char* diag_argv0 = CdlParse::get_tcl_cmd_name(argv[0]); | 122 std::string diag_argv0 = CdlParse::get_tcl_cmd_name(argv[0]); |
| 123 | 123 |
| 124 CdlLoadable loadable = interp->get_loadable(); | 124 CdlLoadable loadable = interp->get_loadable(); |
| 125 CdlPackage package = dynamic_cast<CdlPackage>(loadable); | 125 CdlPackage package = dynamic_cast<CdlPackage>(loadable); |
| 126 CdlContainer parent = interp->get_container(); | 126 CdlContainer parent = interp->get_container(); |
| 127 CdlToplevel toplevel = interp->get_toplevel(); | 127 CdlToplevel toplevel = interp->get_toplevel(); |
| 128 std::string filename = interp->get_filename(); | |
| 129 CYG_ASSERT_CLASSC(loadable); // There should always be a loadable during parsing | 128 CYG_ASSERT_CLASSC(loadable); // There should always be a loadable during parsing |
| 130 CYG_ASSERT_CLASSC(package); // And packages are the only loadable for software CDL. | 129 CYG_ASSERT_CLASSC(package); // And packages are the only loadable for software CDL. |
| 131 CYG_ASSERT_CLASSC(parent); | 130 CYG_ASSERT_CLASSC(parent); |
| 132 CYG_ASSERT_CLASSC(toplevel); | 131 CYG_ASSERT_CLASSC(toplevel); |
| 133 CYG_ASSERTC("" != filename); | |
| 134 | 132 |
| 135 // The new component should be created and added to the package | 133 // The new component should be created and added to the package |
| 136 // early on. If there is a parsing error it will get cleaned up | 134 // early on. If there is a parsing error it will get cleaned up |
| 137 // automatically as a consequence of the package destructor. | 135 // automatically as a consequence of the package destructor. |
| 138 // However it is necessary to validate the name first. Errors | 136 // However it is necessary to validate the name first. Errors |
| 143 int result = TCL_OK; | 141 int result = TCL_OK; |
| 144 try { | 142 try { |
| 145 | 143 |
| 146 // Currently there are no options. This may change in future. | 144 // Currently there are no options. This may change in future. |
| 147 if (3 != argc) { | 145 if (3 != argc) { |
| 148 CdlParse::report_error(interp, std::string("Incorrect number of arguments to ") + diag_argv0 + | 146 CdlParse::report_error(interp, "", |
| 149 "\n Expecting name and properties list."); | 147 std::string("Incorrect number of arguments to `") + diag_argv0 + |
| 148 "'\nExpecting name and properties list."); | |
| 150 ok = false; | 149 ok = false; |
| 151 goto done; | 150 goto done; |
| 152 } | 151 } |
| 153 if (!Tcl_CommandComplete(argv[2])) { | 152 if (!Tcl_CommandComplete(argv[2])) { |
| 154 CdlParse::report_error(interp, std::string("Invalid property list for cdl_component ") + argv[1]); | 153 CdlParse::report_error(interp, "", |
| 154 std::string("Invalid property list for cdl_component `") + argv[1] + "'."); | |
| 155 ok = false; | 155 ok = false; |
| 156 goto done; | 156 goto done; |
| 157 } | 157 } |
| 158 | 158 |
| 159 if (0 != toplevel->lookup(argv[1])) { | 159 if (0 != toplevel->lookup(argv[1])) { |
| 160 CdlParse::report_error(interp, std::string("Component ") + argv[1] + " cannot be loaded.\n" + | 160 CdlParse::report_error(interp, "", |
| 161 " The name is already in use."); | 161 std::string("Component `") + argv[1] + |
| 162 "' cannot be loaded.\nThe name is already in use."); | |
| 162 ok = false; | 163 ok = false; |
| 163 } else { | 164 } else { |
| 164 new_component = new CdlComponentBody(argv[1]); | 165 new_component = new CdlComponentBody(argv[1]); |
| 165 toplevel->add_node(package, parent, new_component); | 166 toplevel->add_node(package, parent, new_component); |
| 166 } | 167 } |
| 171 // reason to abort the whole parsing process. | 172 // reason to abort the whole parsing process. |
| 172 CYG_REPORT_RETVAL(TCL_OK); | 173 CYG_REPORT_RETVAL(TCL_OK); |
| 173 return TCL_OK; | 174 return TCL_OK; |
| 174 } | 175 } |
| 175 } catch(std::bad_alloc e) { | 176 } catch(std::bad_alloc e) { |
| 176 interp->set_result(CdlParse::get_diagnostic_prefix(interp) + "Out of memory."); | 177 interp->set_result(CdlParse::construct_diagnostic(interp, "internal error", "", "Out of memory")); |
| 177 result = TCL_ERROR; | 178 result = TCL_ERROR; |
| 178 } catch(CdlParseException e) { | 179 } catch(CdlParseException e) { |
| 179 interp->set_result(e.get_message()); | 180 interp->set_result(e.get_message()); |
| 180 result = TCL_ERROR; | 181 result = TCL_ERROR; |
| 181 } catch(...) { | 182 } catch(...) { |
| 182 interp->set_result(CdlParse::get_diagnostic_prefix(interp) + "internal error, unexpected C++ exception."); | 183 interp->set_result(CdlParse::construct_diagnostic(interp, "internal error", "", "Unexpected C++ exception")); |
| 183 result = TCL_ERROR; | 184 result = TCL_ERROR; |
| 184 } | 185 } |
| 185 if (TCL_OK != result) { | 186 if (TCL_OK != result) { |
| 186 CYG_REPORT_RETVAL(result); | 187 CYG_REPORT_RETVAL(result); |
| 187 return result; | 188 return result; |
| 192 | 193 |
| 193 // Push the component as the current node early on. This aids | 194 // Push the component as the current node early on. This aids |
| 194 // diagnostics. Also make it the new container. | 195 // diagnostics. Also make it the new container. |
| 195 CdlNode old_node = interp->push_node(new_component); | 196 CdlNode old_node = interp->push_node(new_component); |
| 196 CdlContainer old_container = interp->push_container(new_component); | 197 CdlContainer old_container = interp->push_container(new_component); |
| 197 std::string old_filename; | 198 std::string old_context; |
| 198 CYG_ASSERTC(parent == old_container); | 199 CYG_ASSERTC(parent == old_container); |
| 199 | 200 |
| 200 // Declare these outside the scope of the try statement, to allow | 201 // Declare these outside the scope of the try statement, to allow |
| 201 // goto calls for the error handling. | 202 // goto calls for the error handling. |
| 202 std::string tcl_result; | 203 std::string tcl_result; |
| 260 new_component->CdlBuildableBody::check_properties(interp); | 261 new_component->CdlBuildableBody::check_properties(interp); |
| 261 new_component->CdlDefinableBody::check_properties(interp); | 262 new_component->CdlDefinableBody::check_properties(interp); |
| 262 | 263 |
| 263 // There should be at most one each of wizard and script. | 264 // There should be at most one each of wizard and script. |
| 264 if (new_component->count_properties(CdlPropertyId_Wizard) > 1) { | 265 if (new_component->count_properties(CdlPropertyId_Wizard) > 1) { |
| 265 CdlParse::report_error(interp, "A component should have at most one `wizard' property."); | 266 CdlParse::report_error(interp, "", "A component should have at most one `wizard' property."); |
| 266 } | 267 } |
| 267 if (new_component->count_properties(CdlPropertyId_Script) > 1) { | 268 if (new_component->count_properties(CdlPropertyId_Script) > 1) { |
| 268 CdlParse::report_error(interp, "A component should have at most one `script' property."); | 269 CdlParse::report_error(interp, "", "A component should have at most one `script' property."); |
| 269 } | 270 } |
| 270 | 271 |
| 271 // If there is a script property, life gets more interesting. | 272 // If there is a script property, life gets more interesting. |
| 272 if (new_component->has_property(CdlPropertyId_Script)) { | 273 if (new_component->has_property(CdlPropertyId_Script)) { |
| 273 CdlProperty_String prop = dynamic_cast<CdlProperty_String>(new_component->get_property(CdlPropertyId_Script)); | 274 CdlProperty_String prop = dynamic_cast<CdlProperty_String>(new_component->get_property(CdlPropertyId_Script)); |
| 275 std::string script_name = prop->get_string(); | 276 std::string script_name = prop->get_string(); |
| 276 | 277 |
| 277 // Try to locate this script. | 278 // Try to locate this script. |
| 278 std::string script_filename = package->find_absolute_file(script_name, "cdl", false); | 279 std::string script_filename = package->find_absolute_file(script_name, "cdl", false); |
| 279 if ("" == script_filename) { | 280 if ("" == script_filename) { |
| 280 CdlParse::report_error(interp, "Unable to find script " + script_name); | 281 CdlParse::report_error(interp, "", "Unable to find script `" + script_name + "'."); |
| 281 } else { | 282 } else { |
| 282 // The script exists, so we need to try and execute it. | 283 // The script exists, so we need to try and execute it. |
| 283 // The current container is still set correctly, but we need | 284 // The current container is still set correctly, but we need |
| 284 // to change the filename and install a different set | 285 // to change the filename and install a different set |
| 285 // of commands. | 286 // of commands. |
| 286 old_filename = interp->push_filename(script_filename); | 287 old_context = interp->push_context(script_filename); |
| 287 new_commands.clear(); | 288 new_commands.clear(); |
| 288 for (i = 0; 0 != script_commands[i].command; i++) { | 289 for (i = 0; 0 != script_commands[i].command; i++) { |
| 289 new_commands.push_back(script_commands[i]); | 290 new_commands.push_back(script_commands[i]); |
| 290 } | 291 } |
| 291 old_commands = interp->push_commands(new_commands); | 292 old_commands = interp->push_commands(new_commands); |
| 292 result = interp->eval_file(script_filename, tcl_result); | 293 result = interp->eval_file(script_filename, tcl_result); |
| 293 interp->pop_commands(old_commands); | 294 interp->pop_commands(old_commands); |
| 294 interp->pop_filename(old_filename); | 295 interp->pop_context(old_context); |
| 295 } | 296 } |
| 296 } | 297 } |
| 297 | 298 |
| 298 done2: | 299 done2: |
| 299 // Dummy command just to keep the compiler happy | 300 // Dummy command just to keep the compiler happy |
| 300 filename = ""; | 301 old_context = ""; |
| 301 | 302 |
| 302 } catch (std::bad_alloc e) { | 303 } catch (std::bad_alloc e) { |
| 303 // Errors at this stage should be reported via Tcl, not via C++. | 304 // Errors at this stage should be reported via Tcl, not via C++. |
| 304 // However there is no point in continuing with the parsing operation, | 305 // However there is no point in continuing with the parsing operation, |
| 305 // just give up. | 306 // just give up. |
| 306 interp->set_result(CdlParse::get_diagnostic_prefix(interp) + "Out of memory."); | 307 interp->set_result(CdlParse::construct_diagnostic(interp, "internal error", "", "Out of memory")); |
| 307 result = TCL_ERROR; | 308 result = TCL_ERROR; |
| 308 } catch (CdlParseException e) { | 309 } catch (CdlParseException e) { |
| 309 interp->set_result(e.get_message()); | 310 interp->set_result(e.get_message()); |
| 310 result = TCL_ERROR; | 311 result = TCL_ERROR; |
| 311 } catch(...) { | 312 } catch(...) { |
| 312 interp->set_result(CdlParse::get_diagnostic_prefix(interp) + "internal error, unexpected C++ exception."); | 313 interp->set_result(CdlParse::construct_diagnostic(interp, "internal error", "", "Unexpected C++ exception")); |
| 313 result = TCL_ERROR; | 314 result = TCL_ERROR; |
| 314 } | 315 } |
| 315 | 316 |
| 316 // Restore the interpreter to its prior state. | 317 // Restore the interpreter to its prior state. |
| 317 interp->pop_node(old_node); | 318 interp->pop_node(old_node); |
| 423 CdlNode old_node = 0; | 424 CdlNode old_node = 0; |
| 424 | 425 |
| 425 try { | 426 try { |
| 426 | 427 |
| 427 if (3 != argc) { | 428 if (3 != argc) { |
| 428 CdlParse::report_error(interp, "Invalid cdl_component command in savefile, expecting two arguments."); | 429 CdlParse::report_error(interp, "", "Invalid cdl_component command in savefile, expecting two arguments."); |
| 429 } else { | 430 } else { |
| 430 | 431 |
| 431 CdlNode current_node = config->lookup(argv[1]); | 432 CdlNode current_node = config->lookup(argv[1]); |
| 432 if (0 == current_node) { | 433 if (0 == current_node) { |
| 433 // FIXME: save value in limbo | 434 // FIXME: save value in limbo |
| 434 CdlParse::report_error(interp, | 435 CdlParse::report_error(interp, "", |
| 435 std::string("The savefile contains a cdl_component command for an unknown component `") | 436 std::string("The savefile contains a cdl_component command for an unknown component `") |
| 436 + argv[1] + "'"); | 437 + argv[1] + "'"); |
| 437 } else { | 438 } else { |
| 438 config->get_savefile_subcommands("cdl_component", subcommands); | 439 config->get_savefile_subcommands("cdl_component", subcommands); |
| 439 toplevel_commands = interp->push_commands(subcommands); | 440 toplevel_commands = interp->push_commands(subcommands); |
