2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
|
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
|
-
+
-
-
-
+
-
-
-
-
-
-
-
-
-
-
+
-
-
-
+
+
-
-
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
|
* Restore the variable's flags, remove the record of our active traces,
* and then return.
*/
done:
if (code == TCL_ERROR) {
if (leaveErrMsg) {
const char *type = "";
const char *verb = "";
Tcl_Obj *options = Tcl_GetReturnOptions((Tcl_Interp *)iPtr, code);
Tcl_Obj *errorInfoKey, *errorInfo;
const char *type = "";
TclNewLiteralStringObj(errorInfoKey, "-errorinfo");
Tcl_IncrRefCount(errorInfoKey);
Tcl_DictObjGet(NULL, options, errorInfoKey, &errorInfo);
Tcl_IncrRefCount(errorInfo);
Tcl_DictObjRemove(NULL, options, errorInfoKey);
if (Tcl_IsShared(errorInfo)) {
Tcl_DecrRefCount(errorInfo);
errorInfo = Tcl_DuplicateObj(errorInfo);
Tcl_IncrRefCount(errorInfo);
}
Tcl_AppendToObj(errorInfo, "\n (", -1);
switch (flags&(TCL_TRACE_READS|TCL_TRACE_WRITES|TCL_TRACE_ARRAY)) {
case TCL_TRACE_READS:
type = "read";
Tcl_AppendToObj(errorInfo, type, -1);
verb = "read";
type = verb;
break;
case TCL_TRACE_WRITES:
type = "set";
Tcl_AppendToObj(errorInfo, "write", -1);
verb = "set";
type = "write";
break;
case TCL_TRACE_ARRAY:
type = "trace array";
Tcl_AppendToObj(errorInfo, "array", -1);
verb = "trace array";
type = "array";
break;
}
if (disposeFlags & TCL_TRACE_RESULT_OBJECT) {
Tcl_SetObjResult((Tcl_Interp *)iPtr, (Tcl_Obj *) result);
} else {
Tcl_SetResult((Tcl_Interp *)iPtr, result, TCL_STATIC);
}
Tcl_AddErrorInfo((Tcl_Interp *)iPtr, "");
Tcl_AppendObjToErrorInfo((Tcl_Interp *)iPtr, Tcl_ObjPrintf(
"\n (%s trace on \"%s%s%s%s\")", type, part1,
(part2 ? "(" : ""), (part2 ? part2 : ""),
(part2 ? ")" : "") ));
if (disposeFlags & TCL_TRACE_RESULT_OBJECT) {
TclVarErrMsg((Tcl_Interp *) iPtr, part1, part2, type,
TclVarErrMsg((Tcl_Interp *) iPtr, part1, part2, verb,
Tcl_GetString((Tcl_Obj *) result));
} else {
TclVarErrMsg((Tcl_Interp *) iPtr, part1, part2, type, result);
TclVarErrMsg((Tcl_Interp *) iPtr, part1, part2, verb, result);
}
Tcl_AppendToObj(errorInfo, " trace on \"", -1);
Tcl_AppendToObj(errorInfo, part1, -1);
if (part2 != NULL) {
Tcl_AppendToObj(errorInfo, "(", -1);
Tcl_AppendToObj(errorInfo, part1, -1);
Tcl_AppendToObj(errorInfo, ")", -1);
}
Tcl_AppendToObj(errorInfo, "\")", -1);
Tcl_DictObjPut(NULL, options, errorInfoKey, errorInfo);
Tcl_DecrRefCount(errorInfoKey);
Tcl_DecrRefCount(errorInfo);
code = Tcl_SetReturnOptions((Tcl_Interp *) iPtr, options);
iPtr->flags &= ~(ERR_ALREADY_LOGGED);
Tcl_DiscardInterpState(state);
} else {
Tcl_RestoreInterpState((Tcl_Interp *) iPtr, state);
}
DisposeTraceResult(disposeFlags,result);
} else if (state) {
|