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);