Mercurial > flash_v2
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 } |
