comparison host/libcdl/interp.cxx @ 343:fbfd52cf7976

Try to resolve problems caused by API changes in Tcl 8.4, related to the use of const
author bartv
date Sat, 21 Sep 2002 22:05:08 +0000
parents ea3f0bd33a73
children 446d9e7e1db7
comparison
equal deleted inserted replaced
342:cac491d76066 343:fbfd52cf7976
8 // 8 //
9 //============================================================================ 9 //============================================================================
10 //####COPYRIGHTBEGIN#### 10 //####COPYRIGHTBEGIN####
11 // 11 //
12 // ---------------------------------------------------------------------------- 12 // ----------------------------------------------------------------------------
13 // Copyright (C) 2002 Bart Veer
13 // Copyright (C) 1999, 2000, 2001 Red Hat, Inc. 14 // Copyright (C) 1999, 2000, 2001 Red Hat, Inc.
14 // 15 //
15 // This file is part of the eCos host tools. 16 // This file is part of the eCos host tools.
16 // 17 //
17 // This program is free software; you can redistribute it and/or modify it 18 // This program is free software; you can redistribute it and/or modify it
143 CdlInterpreter result = 0; 144 CdlInterpreter result = 0;
144 try { 145 try {
145 result = new CdlInterpreterBody(tcl_interp); 146 result = new CdlInterpreterBody(tcl_interp);
146 147
147 std::string version = Cdl::get_library_version(); 148 std::string version = Cdl::get_library_version();
148 if (0 == Tcl_SetVar(tcl_interp, "cdl_version", const_cast<char*>(version.c_str()), TCL_GLOBAL_ONLY)) { 149 if (0 == Tcl_SetVar(tcl_interp, "cdl_version", CDL_TCL_CONST_CAST(char*,version.c_str()), TCL_GLOBAL_ONLY)) {
149 throw std::bad_alloc(); 150 throw std::bad_alloc();
150 } 151 }
151 if (0 == Tcl_SetVar(tcl_interp, "cdl_interactive", const_cast<char*>(Cdl::is_interactive() ? "1" : "0"), 152 if (0 == Tcl_SetVar(tcl_interp, "cdl_interactive", CDL_TCL_CONST_CAST(char*, (Cdl::is_interactive() ? "1" : "0")),
152 TCL_GLOBAL_ONLY)) { 153 TCL_GLOBAL_ONLY)) {
153 throw std::bad_alloc(); 154 throw std::bad_alloc();
154 } 155 }
155 } 156 }
156 catch(std::bad_alloc) { 157 catch(std::bad_alloc) {
191 Cdl::integer_to_string(next_slave++, slave_name); 192 Cdl::integer_to_string(next_slave++, slave_name);
192 slave_name = "slave" + slave_name; 193 slave_name = "slave" + slave_name;
193 194
194 // FIXME: creating a slave that is not safe appears to fail. 195 // FIXME: creating a slave that is not safe appears to fail.
195 #if 0 196 #if 0
196 Tcl_Interp* slave = Tcl_CreateSlave(interp, const_cast<char*>(slave_name.c_str()), safe); 197 Tcl_Interp* slave = Tcl_CreateSlave(interp, CDL_TCL_CONST_CAST(char*, slave_name.c_str()), safe);
197 #else 198 #else
198 Tcl_Interp* slave = Tcl_CreateInterp(); 199 Tcl_Interp* slave = Tcl_CreateInterp();
199 #endif 200 #endif
200 if (0 == slave) { 201 if (0 == slave) {
201 throw std::bad_alloc(); 202 throw std::bad_alloc();
685 // If we have an error condition that was raised by the Tcl 686 // If we have an error condition that was raised by the Tcl
686 // interpreter rather than by the library, it needs to be 687 // interpreter rather than by the library, it needs to be
687 // raised up to the library level. That way the error count 688 // raised up to the library level. That way the error count
688 // etc. are kept accurate. 689 // etc. are kept accurate.
689 if ((TCL_OK != result) && !cdl_result) { 690 if ((TCL_OK != result) && !cdl_result) {
690 char* tcl_result = Tcl_GetStringResult(tcl_interp); 691 const char* tcl_result = Tcl_GetStringResult(tcl_interp);
691 if ((0 == tcl_result) || ('\0' == tcl_result[0])) { 692 if ((0 == tcl_result) || ('\0' == tcl_result[0])) {
692 tcl_result = "Internal error, no additional information available."; 693 tcl_result = "Internal error, no additional information available.";
693 } 694 }
694 CdlParse::report_error(this, "", tcl_result); 695 CdlParse::report_error(this, "", tcl_result);
695 } 696 }
741 // If we have an error condition that was raised by the Tcl 742 // If we have an error condition that was raised by the Tcl
742 // interpreter rather than by the library, it needs to be 743 // interpreter rather than by the library, it needs to be
743 // raised up to the library level. That way the error count 744 // raised up to the library level. That way the error count
744 // etc. are kept accurate. 745 // etc. are kept accurate.
745 if ((TCL_OK != result) && !cdl_result) { 746 if ((TCL_OK != result) && !cdl_result) {
746 char* tcl_result = Tcl_GetStringResult(tcl_interp); 747 const char* tcl_result = Tcl_GetStringResult(tcl_interp);
747 if ((0 == tcl_result) || ('\0' == tcl_result[0])) { 748 if ((0 == tcl_result) || ('\0' == tcl_result[0])) {
748 tcl_result = "Internal error, no additional information available."; 749 tcl_result = "Internal error, no additional information available.";
749 } 750 }
750 CdlParse::report_error(this, "", tcl_result); 751 CdlParse::report_error(this, "", tcl_result);
751 } 752 }
766 767
767 // Distinguish between results set by the Tcl interpreter and results 768 // Distinguish between results set by the Tcl interpreter and results
768 // set by CDL-related commands running in that interpreter. 769 // set by CDL-related commands running in that interpreter.
769 cdl_result = false; 770 cdl_result = false;
770 771
771 int result = Tcl_EvalFile(tcl_interp, const_cast<char*>(script.c_str())); 772 int result = Tcl_EvalFile(tcl_interp, CDL_TCL_CONST_CAST(char*, script.c_str()));
772 // The distinction between TCL_OK and TCL_RETURN is probably not worth 773 // The distinction between TCL_OK and TCL_RETURN is probably not worth
773 // worrying about. 774 // worrying about.
774 if (TCL_RETURN == result) { 775 if (TCL_RETURN == result) {
775 result = TCL_OK; 776 result = TCL_OK;
776 } 777 }
778 // If we have an error condition that was raised by the Tcl 779 // If we have an error condition that was raised by the Tcl
779 // interpreter rather than by the library, it needs to be 780 // interpreter rather than by the library, it needs to be
780 // raised up to the library level. That way the error count 781 // raised up to the library level. That way the error count
781 // etc. are kept accurate. 782 // etc. are kept accurate.
782 if ((TCL_OK != result) && !cdl_result) { 783 if ((TCL_OK != result) && !cdl_result) {
783 char* tcl_result = Tcl_GetStringResult(tcl_interp); 784 const char* tcl_result = Tcl_GetStringResult(tcl_interp);
784 if ((0 == tcl_result) || ('\0' == tcl_result[0])) { 785 if ((0 == tcl_result) || ('\0' == tcl_result[0])) {
785 tcl_result = "Internal error, no additional information available."; 786 tcl_result = "Internal error, no additional information available.";
786 } 787 }
787 CdlParse::report_error(this, "", tcl_result); 788 CdlParse::report_error(this, "", tcl_result);
788 } 789 }
865 // This is the Tcl command proc that gets used for all CdlInterpreter 866 // This is the Tcl command proc that gets used for all CdlInterpreter
866 // commands. The ClientData field will be a CdlInterpreterCommand, 867 // commands. The ClientData field will be a CdlInterpreterCommand,
867 // i.e. a function pointer. That function needs a pointer to the 868 // i.e. a function pointer. That function needs a pointer to the
868 // CdlInterpreter object, which can be accessed via AssocData. 869 // CdlInterpreter object, which can be accessed via AssocData.
869 int 870 int
870 CdlInterpreterBody::tcl_command_proc(ClientData data, Tcl_Interp* tcl_interp, int argc, char* argv[]) 871 CdlInterpreterBody::tcl_command_proc(ClientData data, Tcl_Interp* tcl_interp, int argc, const char* argv[])
871 { 872 {
872 CYG_REPORT_FUNCNAMETYPE("CdlInterpreter::tcl_command_proc", "result %d"); 873 CYG_REPORT_FUNCNAMETYPE("CdlInterpreter::tcl_command_proc", "result %d");
873 CYG_REPORT_FUNCARG3XV(data, tcl_interp, argc); 874 CYG_REPORT_FUNCARG3XV(data, tcl_interp, argc);
874 CYG_PRECONDITIONC(0 != data); 875 CYG_PRECONDITIONC(0 != data);
875 876
918 CdlInterpreterCommand command; 919 CdlInterpreterCommand command;
919 ClientData data; 920 ClientData data;
920 } x; 921 } x;
921 x.command = command; 922 x.command = command;
922 923
923 if (0 == Tcl_CreateCommand(tcl_interp, const_cast<char*>(name.c_str()), &tcl_command_proc, x.data, 0)) { 924 // Tcl 8.4 involves some incompatible API changes
925 #if (TCL_MAJOR_VERSION > 8) || ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 4))
926 if (0 == Tcl_CreateCommand(tcl_interp, CDL_TCL_CONST_CAST(char*, name.c_str()), &tcl_command_proc, x.data, 0)) {
924 throw std::bad_alloc(); 927 throw std::bad_alloc();
925 } 928 }
929 #else
930 if (0 == Tcl_CreateCommand(tcl_interp, CDL_TCL_CONST_CAST(char*, name.c_str()),
931 (int (*)(ClientData,Tcl_Interp*, int, char*[])) &tcl_command_proc,
932 x.data, 0)) {
933 throw std::bad_alloc();
934 }
935 #endif
936
926 CYG_REPORT_RETURN(); 937 CYG_REPORT_RETURN();
927 } 938 }
928 939
929 // ---------------------------------------------------------------------------- 940 // ----------------------------------------------------------------------------
930 // Remove a command from an interpreter. This is just a wrapper for the 941 // Remove a command from an interpreter. This is just a wrapper for the
936 CYG_REPORT_FUNCNAME("CdlInterpreter::remove_command"); 947 CYG_REPORT_FUNCNAME("CdlInterpreter::remove_command");
937 CYG_REPORT_FUNCARG1XV(this); 948 CYG_REPORT_FUNCARG1XV(this);
938 CYG_PRECONDITION_THISC(); 949 CYG_PRECONDITION_THISC();
939 CYG_PRECONDITIONC("" != name); 950 CYG_PRECONDITIONC("" != name);
940 951
941 if (0 != Tcl_DeleteCommand(tcl_interp, const_cast<char*>(name.c_str()))) { 952 if (0 != Tcl_DeleteCommand(tcl_interp, CDL_TCL_CONST_CAST(char*, name.c_str()))) {
942 CYG_FAIL("attempt to delete non-existant command"); 953 CYG_FAIL("attempt to delete non-existant command");
943 } 954 }
944 CYG_REPORT_RETURN(); 955 CYG_REPORT_RETURN();
945 } 956 }
946 957
1022 { 1033 {
1023 CYG_REPORT_FUNCNAME("CdlInterpreter::set_variable"); 1034 CYG_REPORT_FUNCNAME("CdlInterpreter::set_variable");
1024 CYG_REPORT_FUNCARG2("this %p, name %s", this, name.c_str()); 1035 CYG_REPORT_FUNCARG2("this %p, name %s", this, name.c_str());
1025 CYG_PRECONDITION_THISC(); 1036 CYG_PRECONDITION_THISC();
1026 CYG_PRECONDITIONC("" != name); 1037 CYG_PRECONDITIONC("" != name);
1027 if (0 == Tcl_SetVar(tcl_interp, const_cast<char*>(name.c_str()), const_cast<char*>(value.c_str()), TCL_GLOBAL_ONLY)) { 1038 if (0 == Tcl_SetVar(tcl_interp, CDL_TCL_CONST_CAST(char*, name.c_str()), CDL_TCL_CONST_CAST(char*, value.c_str()), TCL_GLOBAL_ONLY)) {
1028 throw std::bad_alloc(); 1039 throw std::bad_alloc();
1029 } 1040 }
1030 CYG_REPORT_RETURN(); 1041 CYG_REPORT_RETURN();
1031 } 1042 }
1032 1043
1036 CYG_REPORT_FUNCNAME("CdlInterpreter::unset_variable"); 1047 CYG_REPORT_FUNCNAME("CdlInterpreter::unset_variable");
1037 CYG_REPORT_FUNCARG2("this %p, name %s", this, name.c_str()); 1048 CYG_REPORT_FUNCARG2("this %p, name %s", this, name.c_str());
1038 CYG_PRECONDITION_THISC(); 1049 CYG_PRECONDITION_THISC();
1039 CYG_PRECONDITIONC("" != name); 1050 CYG_PRECONDITIONC("" != name);
1040 1051
1041 Tcl_UnsetVar(tcl_interp, const_cast<char*>(name.c_str()), TCL_GLOBAL_ONLY); 1052 Tcl_UnsetVar(tcl_interp, CDL_TCL_CONST_CAST(char*, name.c_str()), TCL_GLOBAL_ONLY);
1042 CYG_REPORT_RETURN(); 1053 CYG_REPORT_RETURN();
1043 } 1054 }
1044 1055
1045 std::string 1056 std::string
1046 CdlInterpreterBody::get_variable(std::string name) 1057 CdlInterpreterBody::get_variable(std::string name)
1049 CYG_REPORT_FUNCARG2("this %p, name %s", this, name.c_str()); 1060 CYG_REPORT_FUNCARG2("this %p, name %s", this, name.c_str());
1050 CYG_PRECONDITION_THISC(); 1061 CYG_PRECONDITION_THISC();
1051 CYG_PRECONDITIONC("" != name); 1062 CYG_PRECONDITIONC("" != name);
1052 1063
1053 std::string result = ""; 1064 std::string result = "";
1054 char *tmp = Tcl_GetVar(tcl_interp, const_cast<char*>(name.c_str()), TCL_GLOBAL_ONLY); 1065 const char *tmp = Tcl_GetVar(tcl_interp, CDL_TCL_CONST_CAST(char*, name.c_str()), TCL_GLOBAL_ONLY);
1055 if (0 != tmp) { 1066 if (0 != tmp) {
1056 result = tmp; 1067 result = tmp;
1057 } 1068 }
1058 1069
1059 CYG_REPORT_RETURN(); 1070 CYG_REPORT_RETURN();
1076 CYG_REPORT_FUNCNAME("CdlInterpreter::set_assoc_data"); 1087 CYG_REPORT_FUNCNAME("CdlInterpreter::set_assoc_data");
1077 CYG_REPORT_FUNCARG3("this %p, key %s, data %p", this, key, data); 1088 CYG_REPORT_FUNCARG3("this %p, key %s, data %p", this, key, data);
1078 CYG_PRECONDITION_THISC(); 1089 CYG_PRECONDITION_THISC();
1079 CYG_PRECONDITIONC((0 != key) && ('\0' != key[0])); 1090 CYG_PRECONDITIONC((0 != key) && ('\0' != key[0]));
1080 1091
1081 Tcl_SetAssocData(tcl_interp, const_cast<char*>(key), del_proc, data); 1092 Tcl_SetAssocData(tcl_interp, CDL_TCL_CONST_CAST(char*, key), del_proc, data);
1082 CYG_REPORT_RETURN(); 1093 CYG_REPORT_RETURN();
1083 } 1094 }
1084 1095
1085 ClientData 1096 ClientData
1086 CdlInterpreterBody::get_assoc_data(const char* key) 1097 CdlInterpreterBody::get_assoc_data(const char* key)
1088 CYG_REPORT_FUNCNAMETYPE("CdlInterpreter::get_assoc_data", "result %p"); 1099 CYG_REPORT_FUNCNAMETYPE("CdlInterpreter::get_assoc_data", "result %p");
1089 CYG_REPORT_FUNCARG2("this %p, key %s", this, key); 1100 CYG_REPORT_FUNCARG2("this %p, key %s", this, key);
1090 CYG_PRECONDITION_THISC(); 1101 CYG_PRECONDITION_THISC();
1091 CYG_PRECONDITIONC((0 != key) && ('\0' != key[0])); 1102 CYG_PRECONDITIONC((0 != key) && ('\0' != key[0]));
1092 1103
1093 ClientData result = Tcl_GetAssocData(tcl_interp, const_cast<char*>(key), 0); 1104 ClientData result = Tcl_GetAssocData(tcl_interp, CDL_TCL_CONST_CAST(char*, key), 0);
1094 CYG_REPORT_RETVAL(result); 1105 CYG_REPORT_RETVAL(result);
1095 return result; 1106 return result;
1096 } 1107 }
1097 1108
1098 void 1109 void
1101 CYG_REPORT_FUNCNAME("CdlInterpreter::delete_assoc_data"); 1112 CYG_REPORT_FUNCNAME("CdlInterpreter::delete_assoc_data");
1102 CYG_REPORT_FUNCARG2("this %p, key %s", this, key); 1113 CYG_REPORT_FUNCARG2("this %p, key %s", this, key);
1103 CYG_PRECONDITION_THISC(); 1114 CYG_PRECONDITION_THISC();
1104 CYG_PRECONDITIONC((0 != key) && ('\0' != key[0])); 1115 CYG_PRECONDITIONC((0 != key) && ('\0' != key[0]));
1105 1116
1106 Tcl_DeleteAssocData(tcl_interp, const_cast<char*>(key)); 1117 Tcl_DeleteAssocData(tcl_interp, CDL_TCL_CONST_CAST(char*, key));
1107 CYG_REPORT_RETURN(); 1118 CYG_REPORT_RETURN();
1108 } 1119 }
1109 1120
1110 //}}} 1121 //}}}
1111 //{{{ CdlInterpreter:: file I/O 1122 //{{{ CdlInterpreter:: file I/O
1177 set_variable("::cdl_locate_subdirs_path", directory); 1188 set_variable("::cdl_locate_subdirs_path", directory);
1178 if (TCL_OK != eval(locate_subdirs_script, tcl_result)) { 1189 if (TCL_OK != eval(locate_subdirs_script, tcl_result)) {
1179 CYG_FAIL("Internal error evaluating Tcl script"); 1190 CYG_FAIL("Internal error evaluating Tcl script");
1180 } 1191 }
1181 1192
1182 int count; 1193 int count;
1183 char** array; 1194 const char** array;
1184 if (TCL_OK != Tcl_SplitList(tcl_interp, const_cast<char*>(tcl_result.c_str()), &count, &array)) { 1195 if (TCL_OK != Tcl_SplitList(tcl_interp, CDL_TCL_CONST_CAST(char*, tcl_result.c_str()), &count, CDL_TCL_CONST_CAST(char***, &array))) {
1185 throw std::bad_alloc(); 1196 throw std::bad_alloc();
1186 } 1197 }
1187 for (int i = 0; i < count; i++) { 1198 for (int i = 0; i < count; i++) {
1188 result.push_back(array[i]); 1199 result.push_back(array[i]);
1189 } 1200 }
1244 std::string tcl_result; 1255 std::string tcl_result;
1245 set_variable("::cdl_locate_files_path", directory); 1256 set_variable("::cdl_locate_files_path", directory);
1246 if (TCL_OK != eval(locate_files_script, tcl_result)) { 1257 if (TCL_OK != eval(locate_files_script, tcl_result)) {
1247 CYG_FAIL("Internal error evaluating Tcl script"); 1258 CYG_FAIL("Internal error evaluating Tcl script");
1248 } 1259 }
1249 int count; 1260 int count;
1250 char** array; 1261 const char** array;
1251 if (TCL_OK != Tcl_SplitList(tcl_interp, const_cast<char*>(tcl_result.c_str()), &count, &array)) { 1262 if (TCL_OK != Tcl_SplitList(tcl_interp, CDL_TCL_CONST_CAST(char*, tcl_result.c_str()), &count, CDL_TCL_CONST_CAST(char***, &array))) {
1252 throw std::bad_alloc(); 1263 throw std::bad_alloc();
1253 } 1264 }
1254 for (int i = 0; i < count; i++) { 1265 for (int i = 0; i < count; i++) {
1255 result.push_back(array[i]); 1266 result.push_back(array[i]);
1256 } 1267 }
1303 { 1314 {
1304 CYG_REPORT_FUNCNAME("CdlInterpreter::write_data"); 1315 CYG_REPORT_FUNCNAME("CdlInterpreter::write_data");
1305 CYG_REPORT_FUNCARG2XV(this, chan); 1316 CYG_REPORT_FUNCARG2XV(this, chan);
1306 CYG_PRECONDITION_THISC(); 1317 CYG_PRECONDITION_THISC();
1307 1318
1308 if (-1 == Tcl_Write(chan, const_cast<char*>(data.data()), data.size())) { 1319 if (-1 == Tcl_Write(chan, CDL_TCL_CONST_CAST(char*, data.data()), data.size())) {
1309 std::string msg = "Unexpected error writing to file " + this->get_context() + " : " + Tcl_PosixError(tcl_interp); 1320 std::string msg = "Unexpected error writing to file " + this->get_context() + " : " + Tcl_PosixError(tcl_interp);
1310 throw CdlInputOutputException(msg); 1321 throw CdlInputOutputException(msg);
1311 } 1322 }
1312 1323
1313 CYG_REPORT_RETURN(); 1324 CYG_REPORT_RETURN();