comparison host/libcdl/interp.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
89 toplevel = 0; 89 toplevel = 0;
90 transaction = 0; 90 transaction = 0;
91 loadable = 0; 91 loadable = 0;
92 container = 0; 92 container = 0;
93 node = 0; 93 node = 0;
94 filename = ""; 94 context = "";
95 error_fn_ptr = 0; 95 error_fn_ptr = 0;
96 warning_fn_ptr = 0; 96 warning_fn_ptr = 0;
97 current_commands = 0; 97 current_commands = 0;
98 cdl_result = false;
99
98 CYGDBG_MEMLEAK_CONSTRUCTOR(); 100 CYGDBG_MEMLEAK_CONSTRUCTOR();
99 cdlinterpreterbody_cookie = CdlInterpreterBody_Magic; 101 cdlinterpreterbody_cookie = CdlInterpreterBody_Magic;
100 102
101 Tcl_SetAssocData(tcl_interp, cdlinterpreter_assoc_data_key, 0, static_cast<ClientData>(this)); 103 Tcl_SetAssocData(tcl_interp, cdlinterpreter_assoc_data_key, 0, static_cast<ClientData>(this));
102 104
262 toplevel = 0; 264 toplevel = 0;
263 transaction = 0; 265 transaction = 0;
264 loadable = 0; 266 loadable = 0;
265 container = 0; 267 container = 0;
266 node = 0; 268 node = 0;
267 filename = ""; 269 context = "";
268 error_fn_ptr = 0; 270 error_fn_ptr = 0;
269 warning_fn_ptr = 0; 271 warning_fn_ptr = 0;
270 current_commands = 0; 272 current_commands = 0;
273 cdl_result = false;
271 274
272 // Make sure slave interpreters get deleted before the current one 275 // Make sure slave interpreters get deleted before the current one
273 for (std::vector<CdlInterpreter>::iterator i = slaves.begin(); i != slaves.end(); i++) { 276 for (std::vector<CdlInterpreter>::iterator i = slaves.begin(); i != slaves.end(); i++) {
274 delete *i; 277 delete *i;
275 *i = 0; 278 *i = 0;
414 CYG_REPORT_RETVAL(result); 417 CYG_REPORT_RETVAL(result);
415 return result; 418 return result;
416 } 419 }
417 420
418 std::string 421 std::string
419 CdlInterpreterBody::get_filename() const 422 CdlInterpreterBody::get_context() const
420 { 423 {
421 CYG_REPORT_FUNCNAME("CdlInterpreter::get_filename"); 424 CYG_REPORT_FUNCNAME("CdlInterpreter::get_context");
422 CYG_REPORT_FUNCARG1XV(this); 425 CYG_REPORT_FUNCARG1XV(this);
423 CYG_PRECONDITION_THISC(); 426 CYG_PRECONDITION_THISC();
424 427
425 CYG_REPORT_RETURN(); 428 CYG_REPORT_RETURN();
426 return filename; 429 return context;
427 } 430 }
428 431
429 CdlDiagnosticFnPtr 432 CdlDiagnosticFnPtr
430 CdlInterpreterBody::get_error_fn_ptr() const 433 CdlInterpreterBody::get_error_fn_ptr() const
431 { 434 {
530 533
531 CYG_REPORT_RETURN(); 534 CYG_REPORT_RETURN();
532 } 535 }
533 536
534 std::string 537 std::string
535 CdlInterpreterBody::push_filename(std::string new_filename) 538 CdlInterpreterBody::push_context(std::string new_context)
536 { 539 {
537 CYG_REPORT_FUNCNAME("CdlInterpreter::push_filename"); 540 CYG_REPORT_FUNCNAME("CdlInterpreter::push_context");
538 CYG_REPORT_FUNCARG1XV(this); 541 CYG_REPORT_FUNCARG1XV(this);
539 CYG_PRECONDITION_THISC(); 542 CYG_PRECONDITION_THISC();
540 CYG_PRECONDITIONC("" != new_filename); 543 CYG_PRECONDITIONC("" != new_context);
541 544
542 std::string result = filename; 545 std::string result = context;
543 filename = new_filename; 546 context = new_context;
544 return result; 547 return result;
545 } 548 }
546 549
547 void 550 void
548 CdlInterpreterBody::pop_filename(std::string old_filename) 551 CdlInterpreterBody::pop_context(std::string old_context)
549 { 552 {
550 CYG_REPORT_FUNCNAME("CdlInterpreter::pop_filename"); 553 CYG_REPORT_FUNCNAME("CdlInterpreter::pop_context");
551 CYG_REPORT_FUNCARG1XV(this); 554 CYG_REPORT_FUNCARG1XV(this);
552 CYG_PRECONDITION_THISC(); 555 CYG_PRECONDITION_THISC();
553 CYG_PRECONDITIONC("" != filename); 556 CYG_PRECONDITIONC("" != context);
554 557
555 filename = old_filename; 558 context = old_context;
556 559
557 CYG_REPORT_RETURN(); 560 CYG_REPORT_RETURN();
558 } 561 }
559 562
560 CdlDiagnosticFnPtr 563 CdlDiagnosticFnPtr
648 CYG_REPORT_FUNCARG1XV(this); 651 CYG_REPORT_FUNCARG1XV(this);
649 CYG_PRECONDITION_THISC(); 652 CYG_PRECONDITION_THISC();
650 653
651 int result = TCL_OK; 654 int result = TCL_OK;
652 int size = script.size(); 655 int size = script.size();
653 656
657 // Distinguish between results set by the Tcl interpreter and results
658 // set by CDL-related commands running in that interpreter.
659 cdl_result = false;
660
654 if (size < 2048) { 661 if (size < 2048) {
655 char buf[2048]; 662 char buf[2048];
656 script.copy(buf, size, 0); 663 script.copy(buf, size, 0);
657 buf[size] = '\0'; 664 buf[size] = '\0';
658 result = Tcl_Eval(tcl_interp, buf); 665 result = Tcl_Eval(tcl_interp, buf);
659 } else { 666 } else {
660 char* buf = static_cast<char*>(malloc(script.size() + 1)); 667 char* buf = static_cast<char*>(malloc(script.size() + 1));
661 if (0 == buf) { 668 if (0 == buf) {
662 // Stay within Tcl's error handling mechanism rather than 669 this->set_result(CdlParse::construct_diagnostic(this, "internal error", "", "Out of memory"));
663 // throw an exception. 670 result = TCL_ERROR;
664 char *msg = "Out of memory"; 671 } else {
665 Tcl_SetResult(tcl_interp, msg, TCL_STATIC); 672 script.copy(buf, size, 0);
666 str_result = msg; 673 buf[size] = '\0';
667 CYG_REPORT_RETVAL(TCL_ERROR); 674 result = Tcl_Eval(tcl_interp, buf);
668 return TCL_ERROR; 675 free(buf);
669 } 676 }
670 script.copy(buf, size, 0); 677 }
671 buf[size] = '\0'; 678
672 result = Tcl_Eval(tcl_interp, buf);
673 free(buf);
674 }
675 str_result = Tcl_GetStringResult(tcl_interp);
676 // The distinction between TCL_OK and TCL_RETURN is probably not worth 679 // The distinction between TCL_OK and TCL_RETURN is probably not worth
677 // worrying about. 680 // worrying about.
678 if (TCL_RETURN == result) { 681 if (TCL_RETURN == result) {
679 result = TCL_OK; 682 result = TCL_OK;
680 } 683 }
684
685 // If we have an error condition that was raised by the Tcl
686 // interpreter rather than by the library, it needs to be
687 // raised up to the library level. That way the error count
688 // etc. are kept accurate.
689 if ((TCL_OK != result) && !cdl_result) {
690 char* tcl_result = Tcl_GetStringResult(tcl_interp);
691 if ((0 == tcl_result) || ('\0' == tcl_result[0])) {
692 tcl_result = "Internal error, no additional information available.";
693 }
694 CdlParse::report_error(this, "", tcl_result);
695 }
696
697 str_result = Tcl_GetStringResult(tcl_interp);
681 CYG_REPORT_RETVAL(result); 698 CYG_REPORT_RETVAL(result);
682 return result; 699 return result;
683 } 700 }
684 701
685 // Ditto for Tcl Code that comes from a CDL file. Currently this is held 702 // Ditto for Tcl Code that comes from a CDL file. Currently this is held
692 CYG_REPORT_FUNCARG1XV(this); 709 CYG_REPORT_FUNCARG1XV(this);
693 CYG_PRECONDITION_THISC(); 710 CYG_PRECONDITION_THISC();
694 711
695 int result = TCL_OK; 712 int result = TCL_OK;
696 int size = script.size(); 713 int size = script.size();
714 // Distinguish between results set by the Tcl interpreter and results
715 // set by CDL-related commands running in that interpreter.
716 cdl_result = false;
717
697 if (size < 2048) { 718 if (size < 2048) {
698 char buf[2048]; 719 char buf[2048];
699 script.copy(buf, size, 0); 720 script.copy(buf, size, 0);
700 buf[size] = '\0'; 721 buf[size] = '\0';
701 result = Tcl_Eval(tcl_interp, buf); 722 result = Tcl_Eval(tcl_interp, buf);
702 } else { 723 } else {
703 char* buf = static_cast<char*>(malloc(script.size() + 1)); 724 char* buf = static_cast<char*>(malloc(script.size() + 1));
704 if (0 == buf) { 725 if (0 == buf) {
705 // Stay within Tcl's error handling mechanism rather than 726 this->set_result(CdlParse::construct_diagnostic(this, "internal error", "", "Out of memory"));
706 // throw an exception. 727 result = TCL_ERROR;
707 char *msg = "Out of memory"; 728 } else {
708 Tcl_SetResult(tcl_interp, msg, TCL_STATIC); 729 script.copy(buf, size, 0);
709 str_result = msg; 730 buf[size] = '\0';
710 CYG_REPORT_RETVAL(TCL_ERROR); 731 result = Tcl_Eval(tcl_interp, buf);
711 return TCL_ERROR; 732 free(buf);
712 } 733 }
713 script.copy(buf, size, 0); 734 }
714 buf[size] = '\0';
715 result = Tcl_Eval(tcl_interp, buf);
716 free(buf);
717 }
718 str_result = Tcl_GetStringResult(tcl_interp);
719 // The distinction between TCL_OK and TCL_RETURN is probably not worth 735 // The distinction between TCL_OK and TCL_RETURN is probably not worth
720 // worrying about. 736 // worrying about.
721 if (TCL_RETURN == result) { 737 if (TCL_RETURN == result) {
722 result = TCL_OK; 738 result = TCL_OK;
723 } 739 }
740
741 // If we have an error condition that was raised by the Tcl
742 // interpreter rather than by the library, it needs to be
743 // raised up to the library level. That way the error count
744 // etc. are kept accurate.
745 if ((TCL_OK != result) && !cdl_result) {
746 char* tcl_result = Tcl_GetStringResult(tcl_interp);
747 if ((0 == tcl_result) || ('\0' == tcl_result[0])) {
748 tcl_result = "Internal error, no additional information available.";
749 }
750 CdlParse::report_error(this, "", tcl_result);
751 }
752
753 str_result = Tcl_GetStringResult(tcl_interp);
724 CYG_REPORT_RETVAL(result); 754 CYG_REPORT_RETVAL(result);
725 return result; 755 return result;
726 } 756 }
727 757
728 // Ditto for evaluating an entire file. 758 // Ditto for evaluating an entire file.
732 CYG_REPORT_FUNCNAMETYPE("CdlInterpreter::eval_file", "result %d"); 762 CYG_REPORT_FUNCNAMETYPE("CdlInterpreter::eval_file", "result %d");
733 CYG_REPORT_FUNCARG1XV(this); 763 CYG_REPORT_FUNCARG1XV(this);
734 CYG_PRECONDITION_THISC(); 764 CYG_PRECONDITION_THISC();
735 CYG_PRECONDITIONC("" != script); 765 CYG_PRECONDITIONC("" != script);
736 766
767 // Distinguish between results set by the Tcl interpreter and results
768 // set by CDL-related commands running in that interpreter.
769 cdl_result = false;
770
737 int result = Tcl_EvalFile(tcl_interp, const_cast<char*>(script.c_str())); 771 int result = Tcl_EvalFile(tcl_interp, const_cast<char*>(script.c_str()));
738 str_result = Tcl_GetStringResult(tcl_interp);
739 // The distinction between TCL_OK and TCL_RETURN is probably not worth 772 // The distinction between TCL_OK and TCL_RETURN is probably not worth
740 // worrying about. 773 // worrying about.
741 if (TCL_RETURN == result) { 774 if (TCL_RETURN == result) {
742 result = TCL_OK; 775 result = TCL_OK;
743 } 776 }
744 CYG_REPORT_RETVAL(result); 777
745 return result; 778 // If we have an error condition that was raised by the Tcl
779 // interpreter rather than by the library, it needs to be
780 // raised up to the library level. That way the error count
781 // etc. are kept accurate.
782 if ((TCL_OK != result) && !cdl_result) {
783 char* tcl_result = Tcl_GetStringResult(tcl_interp);
784 if ((0 == tcl_result) || ('\0' == tcl_result[0])) {
785 tcl_result = "Internal error, no additional information available.";
786 }
787 CdlParse::report_error(this, "", tcl_result);
788 }
789
790 str_result = Tcl_GetStringResult(tcl_interp);
791 CYG_REPORT_RETVAL(result);
792 return result;
793 }
794
795 // Variants for when the result string is of no interest
796 int
797 CdlInterpreterBody::eval(std::string script)
798 {
799 std::string result_string;
800 return this->eval(script, result_string);
801 }
802
803 int
804 CdlInterpreterBody::eval_cdl_code(const cdl_tcl_code script)
805 {
806 std::string result_string;
807 return this->eval_cdl_code(script, result_string);
808 }
809
810 int
811 CdlInterpreterBody::eval_file(std::string filename)
812 {
813 std::string result_string;
814 return this->eval_file(filename, result_string);
746 } 815 }
747 816
748 //}}} 817 //}}}
749 //{{{ CdlInterpreter:: set_result() 818 //{{{ CdlInterpreter:: set_result()
750 819
757 { 826 {
758 CYG_REPORT_FUNCNAME("CdlInterpreter::set_result"); 827 CYG_REPORT_FUNCNAME("CdlInterpreter::set_result");
759 CYG_PRECONDITION_THISC(); 828 CYG_PRECONDITION_THISC();
760 829
761 Tcl_SetResult(tcl_interp, const_cast<char*>(result.c_str()), TCL_VOLATILE); 830 Tcl_SetResult(tcl_interp, const_cast<char*>(result.c_str()), TCL_VOLATILE);
762 CYG_REPORT_RETURN(); 831 this->cdl_result = true;
832
833 CYG_REPORT_RETURN();
834 }
835
836 bool
837 CdlInterpreterBody::result_set_by_cdl()
838 {
839 CYG_REPORT_FUNCNAMETYPE("CdlInterpreter::result_set_by_cdl", "result %d");
840 CYG_PRECONDITION_THISC();
841
842 bool result = this->cdl_result;
843 CYG_REPORT_RETVAL(result);
844 return result;
763 } 845 }
764 846
765 // ---------------------------------------------------------------------------- 847 // ----------------------------------------------------------------------------
766 // Also allow the result to be extracted again. 848 // Also allow the result to be extracted again.
767 std::string 849 std::string
805 CYG_ASSERT_CLASSC(interp); 887 CYG_ASSERT_CLASSC(interp);
806 888
807 try { 889 try {
808 result = (*command)(interp, argc, argv); 890 result = (*command)(interp, argc, argv);
809 } catch(std::bad_alloc e) { 891 } catch(std::bad_alloc e) {
810 interp->set_result(CdlParse::get_diagnostic_prefix(interp) + "Out of memory."); 892 interp->set_result(CdlParse::construct_diagnostic(interp, "internal error", "", "Out of memory."));
811 result = TCL_ERROR; 893 result = TCL_ERROR;
812 } catch(CdlStringException e) { 894 } catch(CdlStringException e) {
813 interp->set_result(e.get_message()); 895 interp->set_result(e.get_message());
814 result = TCL_ERROR; 896 result = TCL_ERROR;
815 } catch(...) { 897 } catch(...) {
816 CYG_FAIL("Unexpected C++ exception"); 898 CYG_FAIL("Unexpected C++ exception");
817 interp->set_result(CdlParse::get_diagnostic_prefix(interp) + "Internal error, unexpected C++ exception."); 899 interp->set_result(CdlParse::construct_diagnostic(interp, "internal error", "", "Unexpected C++ exception."));
818 result = TCL_ERROR; 900 result = TCL_ERROR;
819 } 901 }
820 902
821 CYG_REPORT_RETVAL(result); 903 CYG_REPORT_RETVAL(result);
822 return result; 904 return result;
1223 CYG_REPORT_FUNCNAME("CdlInterpreter::write_data"); 1305 CYG_REPORT_FUNCNAME("CdlInterpreter::write_data");
1224 CYG_REPORT_FUNCARG2XV(this, chan); 1306 CYG_REPORT_FUNCARG2XV(this, chan);
1225 CYG_PRECONDITION_THISC(); 1307 CYG_PRECONDITION_THISC();
1226 1308
1227 if (-1 == Tcl_Write(chan, const_cast<char*>(data.data()), data.size())) { 1309 if (-1 == Tcl_Write(chan, const_cast<char*>(data.data()), data.size())) {
1228 std::string msg = "Unexpected error writing to file " + this->get_filename() + " : " + Tcl_PosixError(tcl_interp); 1310 std::string msg = "Unexpected error writing to file " + this->get_context() + " : " + Tcl_PosixError(tcl_interp);
1229 throw CdlInputOutputException(msg); 1311 throw CdlInputOutputException(msg);
1230 } 1312 }
1231 1313
1232 CYG_REPORT_RETURN(); 1314 CYG_REPORT_RETURN();
1233 } 1315 }