summaryrefslogtreecommitdiffstats
path: root/generic/tkObj.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tkObj.c')
-rw-r--r--generic/tkObj.c233
1 files changed, 167 insertions, 66 deletions
diff --git a/generic/tkObj.c b/generic/tkObj.c
index a184cc6..7239aa2 100644
--- a/generic/tkObj.c
+++ b/generic/tkObj.c
@@ -3,7 +3,7 @@
*
* This file contains functions that implement the common Tk object types
*
- * Copyright (c) 1997 Sun Microsystems, Inc.
+ * Copyright © 1997 Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -72,8 +72,12 @@ typedef struct MMRep {
typedef struct WindowRep {
Tk_Window tkwin; /* Cached window; NULL if not found. */
TkMainInfo *mainPtr; /* MainWindow associated with tkwin. */
- long epoch; /* Value of mainPtr->deletionEpoch at last
+#if TCL_MAJOR_VERSION > 8
+ size_t epoch; /* Value of mainPtr->deletionEpoch at last
* successful lookup. */
+#else
+ long epoch;
+#endif
} WindowRep;
/*
@@ -92,32 +96,72 @@ static int SetMMFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
static int SetPixelFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
static int SetWindowFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
+#if TCL_MAJOR_VERSION < 9
+#ifdef __cplusplus
+extern "C" {
+#endif
+#if defined(USE_TCL_STUBS)
+/* Little hack to eliminate the need for "tclInt.h" here:
+ Just copy a small portion of TclIntStubs, just
+ enough to make it work */
+typedef struct TclIntStubs {
+ int magic;
+ void *hooks;
+ void (*dummy[34]) (void); /* dummy entries 0-33, not used */
+ int (*tclGetIntForIndex) (Tcl_Interp *interp, Tcl_Obj *objPtr, int endValue, int *indexPtr); /* 34 */
+} TclIntStubs;
+extern const TclIntStubs *tclIntStubsPtr;
+
+# undef Tcl_GetIntForIndex
+# define Tcl_GetIntForIndex(interp, obj, max, ptr) ((tclIntStubsPtr->tclGetIntForIndex == NULL)? \
+ ((int (*)(Tcl_Interp*, Tcl_Obj *, int, int*))(void *)((&(tclStubsPtr->tcl_PkgProvideEx))[645]))((interp), (obj), (max), (ptr)): \
+ tclIntStubsPtr->tclGetIntForIndex((interp), (obj), (max), (ptr)))
+#elif TCL_MINOR_VERSION < 7
+extern int TclGetIntForIndex(Tcl_Interp*, Tcl_Obj *, int, int*);
+# define Tcl_GetIntForIndex(interp, obj, max, ptr) TclGetIntForIndex(interp, obj, max, ptr)
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif
+
/*
* The following structure defines the implementation of the "pixel" Tcl
* object, used for measuring distances. The pixel object remembers its
* initial display-independent settings.
*/
-static const Tcl_ObjType pixelObjType = {
- "pixel", /* name */
+static const TkObjType pixelObjType = {
+ {"pixel", /* name */
FreePixelInternalRep, /* freeIntRepProc */
DupPixelInternalRep, /* dupIntRepProc */
NULL, /* updateStringProc */
- SetPixelFromAny /* setFromAnyProc */
+ NULL, /* setFromAnyProc */
+ TCL_OBJTYPE_V1(TkLengthOne)},
+ 0
};
+Tcl_Size
+TkLengthOne(
+ TCL_UNUSED(Tcl_Obj *))
+{
+ return 1;
+}
+
/*
* The following structure defines the implementation of the "pixel" Tcl
* object, used for measuring distances. The pixel object remembers its
* initial display-independent settings.
*/
-static const Tcl_ObjType mmObjType = {
- "mm", /* name */
+static const TkObjType mmObjType = {
+ {"mm", /* name */
FreeMMInternalRep, /* freeIntRepProc */
DupMMInternalRep, /* dupIntRepProc */
UpdateStringOfMM, /* updateStringProc */
- SetMMFromAny /* setFromAnyProc */
+ NULL, /* setFromAnyProc */
+ TCL_OBJTYPE_V1(TkLengthOne)},
+ 0
};
/*
@@ -125,12 +169,14 @@ static const Tcl_ObjType mmObjType = {
* Tcl object.
*/
-static const Tcl_ObjType windowObjType = {
- "window", /* name */
+static const TkObjType windowObjType = {
+ {"window", /* name */
FreeWindowInternalRep, /* freeIntRepProc */
DupWindowInternalRep, /* dupIntRepProc */
NULL, /* updateStringProc */
- SetWindowFromAny /* setFromAnyProc */
+ NULL, /* setFromAnyProc */
+ TCL_OBJTYPE_V0},
+ 0
};
/*
@@ -167,6 +213,46 @@ GetTypeCache(void)
/*
*----------------------------------------------------------------------
*
+ * TkGetIntForIndex --
+ *
+ * Almost the same as Tcl_GetIntForIndex, but it retrieves an int. Accepts
+ * "" (empty string) as well.
+ *
+ * Results:
+ * The return value is a standard Tcl object result.
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TkGetIntForIndex(
+ Tcl_Obj *indexObj,
+ Tcl_Size end,
+ int lastOK,
+ Tcl_Size *indexPtr)
+{
+ if (indexObj == NULL) {
+ *indexPtr = TCL_INDEX_NONE;
+ return TCL_OK;
+ }
+ if (Tcl_GetIntForIndex(NULL, indexObj, end + lastOK, indexPtr) != TCL_OK) {
+ const char *value = Tcl_GetString(indexObj);
+ if (!*value) {
+ /* empty string */
+ *indexPtr = (end == -1) ? -1 - TCL_SIZE_MAX : TCL_INDEX_NONE;
+ return TCL_OK;
+ }
+ return TCL_ERROR;
+ }
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* GetPixelsFromObjEx --
*
* Attempt to return a pixel value from the Tcl object "objPtr". If the
@@ -201,7 +287,7 @@ GetPixelsFromObjEx(
1.0, 10.0, 25.4, 0.35277777777777775 /*25.4 / 72.0*/
};
- if (objPtr->typePtr != &pixelObjType) {
+ if (objPtr->typePtr != &pixelObjType.objType) {
if (Tcl_GetDoubleFromObj(NULL, objPtr, &d) == TCL_OK) {
if (dblPtr != NULL) {
@@ -213,7 +299,7 @@ GetPixelsFromObjEx(
}
retry:
- fresh = (objPtr->typePtr != &pixelObjType);
+ fresh = (objPtr->typePtr != &pixelObjType.objType);
if (fresh) {
result = SetPixelFromAny(interp, objPtr);
if (result != TCL_OK) {
@@ -320,7 +406,7 @@ Tk_GetDoublePixelsFromObj(
if (result != TCL_OK) {
return result;
}
- if (objPtr->typePtr == &pixelObjType && !SIMPLE_PIXELREP(objPtr)) {
+ if (objPtr->typePtr == &pixelObjType.objType && !SIMPLE_PIXELREP(objPtr)) {
PixelRep *pixelPtr = GET_COMPLEXPIXEL(objPtr);
if (pixelPtr->units >= 0) {
@@ -433,7 +519,7 @@ SetPixelFromAny(
{
ThreadSpecificData *typeCache = GetTypeCache();
const Tcl_ObjType *typePtr;
- const char *string;
+ char *string;
char *rest;
double d;
int i, units;
@@ -453,20 +539,27 @@ SetPixelFromAny(
} else if (Tcl_GetDoubleFromObj(NULL, objPtr, &d) == TCL_OK) {
units = -1;
} else {
+ char savechar;
string = Tcl_GetString(objPtr);
- d = strtod(string, &rest);
- if (rest == string) {
- goto error;
+ rest = string + strlen(string);
+ while ((rest > string) && isspace(UCHAR(rest[-1]))) {
+ --rest; /* skip all spaces at the end */
}
- while ((*rest != '\0') && isspace(UCHAR(*rest))) {
- rest++;
+ if (rest > string) {
+ --rest; /* point to the character just before the last space */
+ }
+ if (rest == string) {
+ error:
+ if (interp != NULL) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "expected screen distance but got \"%.50s\"", string));
+ Tcl_SetErrorCode(interp, "TK", "VALUE", "PIXELS", (char *)NULL);
+ }
+ return TCL_ERROR;
}
switch (*rest) {
- case '\0':
- units = -1;
- break;
case 'm':
units = 0;
break;
@@ -482,7 +575,15 @@ SetPixelFromAny(
default:
goto error;
}
+ savechar = *rest;
+ *rest = '\0';
+ if (Tcl_GetDouble(NULL, string, &d) != TCL_OK) {
+ *rest = savechar;
+ goto error;
+ }
+ *rest = savechar;
}
+
/*
* Free the old internalRep before setting the new one.
*/
@@ -492,7 +593,7 @@ SetPixelFromAny(
typePtr->freeIntRepProc(objPtr);
}
- objPtr->typePtr = &pixelObjType;
+ objPtr->typePtr = &pixelObjType.objType;
i = (int) d;
if ((units < 0) && (i == d)) {
@@ -507,14 +608,6 @@ SetPixelFromAny(
SET_COMPLEXPIXEL(objPtr, pixelPtr);
}
return TCL_OK;
-
- error:
- if (interp != NULL) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "bad screen distance \"%.50s\"", string));
- Tcl_SetErrorCode(interp, "TK", "VALUE", "PIXELS", NULL);
- }
- return TCL_ERROR;
}
/*
@@ -552,7 +645,7 @@ Tk_GetMMFromObj(
10.0, 25.4, 1.0, 0.35277777777777775 /*25.4 / 72.0*/
};
- if (objPtr->typePtr != &mmObjType) {
+ if (objPtr->typePtr != &mmObjType.objType) {
result = SetMMFromAny(interp, objPtr);
if (result != TCL_OK) {
return result;
@@ -726,28 +819,29 @@ SetMMFromAny(
} else if (Tcl_GetDoubleFromObj(NULL, objPtr, &d) == TCL_OK) {
units = -1;
} else {
+ char savechar;
+
/*
* It wasn't a known int or double, so parse it.
*/
string = Tcl_GetString(objPtr);
- d = strtod(string, &rest);
+ rest = string + strlen(string);
+ while ((rest > string) && isspace(UCHAR(rest[-1]))) {
+ --rest; /* skip all spaces at the end */
+ }
+ if (rest > string) {
+ --rest; /* point to the character just before the last space */
+ }
if (rest == string) {
error:
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "bad screen distance \"%s\"", string));
- Tcl_SetErrorCode(interp, "TK", "VALUE", "DISTANCE", NULL);
+ "expected screen distance but got \"%.50s\"", string));
+ Tcl_SetErrorCode(interp, "TK", "VALUE", "PIXELS", (char *)NULL);
return TCL_ERROR;
}
- while ((*rest != '\0') && isspace(UCHAR(*rest))) {
- rest++;
- }
-
switch (*rest) {
- case '\0':
- units = -1;
- break;
case 'c':
units = 0;
break;
@@ -763,6 +857,13 @@ SetMMFromAny(
default:
goto error;
}
+ savechar = *rest;
+ *rest = '\0';
+ if (Tcl_GetDouble(NULL, string, &d) != TCL_OK) {
+ *rest = savechar;
+ goto error;
+ }
+ *rest = savechar;
}
/*
@@ -774,7 +875,7 @@ SetMMFromAny(
typePtr->freeIntRepProc(objPtr);
}
- objPtr->typePtr = &mmObjType;
+ objPtr->typePtr = &mmObjType.objType;
mmPtr = (MMRep *)ckalloc(sizeof(MMRep));
mmPtr->value = d;
@@ -818,7 +919,7 @@ TkGetWindowFromObj(
TkMainInfo *mainPtr = ((TkWindow *) tkwin)->mainPtr;
WindowRep *winPtr;
- if (objPtr->typePtr != &windowObjType) {
+ if (objPtr->typePtr != &windowObjType.objType) {
int result = SetWindowFromAny(interp, objPtr);
if (result != TCL_OK) {
return result;
@@ -893,7 +994,7 @@ SetWindowFromAny(
winPtr->epoch = 0;
objPtr->internalRep.twoPtrValue.ptr1 = winPtr;
- objPtr->typePtr = &windowObjType;
+ objPtr->typePtr = &windowObjType.objType;
return TCL_OK;
}
@@ -962,7 +1063,7 @@ FreeWindowInternalRep(
/*
*----------------------------------------------------------------------
*
- * TkNewWindowObj --
+ * Tk_NewWindowObj --
*
* This function allocates a new Tcl_Obj that refers to a particular
* Tk window.
@@ -977,10 +1078,10 @@ FreeWindowInternalRep(
*/
Tcl_Obj *
-TkNewWindowObj(
+Tk_NewWindowObj(
Tk_Window tkwin)
{
- Tcl_Obj *objPtr = Tcl_NewStringObj(Tk_PathName(tkwin), -1);
+ Tcl_Obj *objPtr = Tcl_NewStringObj(Tk_PathName(tkwin), TCL_INDEX_NONE);
TkMainInfo *mainPtr = ((TkWindow *) tkwin)->mainPtr;
WindowRep *winPtr;
@@ -1025,7 +1126,7 @@ TkParsePadAmount(
int *allPtr) /* Write the total padding here */
{
int firstInt, secondInt; /* The two components of the padding */
- int objc; /* The length of the list (should be 1 or 2) */
+ Tcl_Size objc; /* The length of the list (should be 1 or 2) */
Tcl_Obj **objv; /* The objects in the list */
/*
@@ -1033,12 +1134,12 @@ TkParsePadAmount(
* shimmered between a list and a pixel spec.
*/
- if (specObj->typePtr == &pixelObjType) {
+ if (specObj->typePtr == &pixelObjType.objType) {
if (Tk_GetPixelsFromObj(interp, tkwin, specObj, &firstInt) != TCL_OK){
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"bad pad value \"%s\": must be positive screen distance",
Tcl_GetString(specObj)));
- Tcl_SetErrorCode(interp, "TK", "VALUE", "PADDING", "DIST", NULL);
+ Tcl_SetErrorCode(interp, "TK", "VALUE", "PADDING", "DIST", (char *)NULL);
return TCL_ERROR;
}
secondInt = firstInt;
@@ -1055,8 +1156,8 @@ TkParsePadAmount(
}
if (objc != 1 && objc != 2) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "wrong number of parts to pad specification", -1));
- Tcl_SetErrorCode(interp, "TK", "VALUE", "PADDING", "PARTS", NULL);
+ "wrong number of parts to pad specification", TCL_INDEX_NONE));
+ Tcl_SetErrorCode(interp, "TK", "VALUE", "PADDING", "PARTS", (char *)NULL);
return TCL_ERROR;
}
@@ -1069,7 +1170,7 @@ TkParsePadAmount(
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"bad pad value \"%s\": must be positive screen distance",
Tcl_GetString(objv[0])));
- Tcl_SetErrorCode(interp, "TK", "VALUE", "PADDING", "DIST", NULL);
+ Tcl_SetErrorCode(interp, "TK", "VALUE", "PADDING", "DIST", (char *)NULL);
return TCL_ERROR;
}
@@ -1085,7 +1186,7 @@ TkParsePadAmount(
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"bad 2nd pad value \"%s\": must be positive screen distance",
Tcl_GetString(objv[1])));
- Tcl_SetErrorCode(interp, "TK", "VALUE", "PADDING", "DIST", NULL);
+ Tcl_SetErrorCode(interp, "TK", "VALUE", "PADDING", "DIST", (char *)NULL);
return TCL_ERROR;
}
@@ -1121,16 +1222,16 @@ TkParsePadAmount(
void
TkRegisterObjTypes(void)
{
- Tcl_RegisterObjType(&tkBorderObjType);
- Tcl_RegisterObjType(&tkBitmapObjType);
- Tcl_RegisterObjType(&tkColorObjType);
- Tcl_RegisterObjType(&tkCursorObjType);
- Tcl_RegisterObjType(&tkFontObjType);
- Tcl_RegisterObjType(&mmObjType);
- Tcl_RegisterObjType(&pixelObjType);
- Tcl_RegisterObjType(&tkStateKeyObjType);
- Tcl_RegisterObjType(&windowObjType);
- Tcl_RegisterObjType(&tkTextIndexType);
+ Tcl_RegisterObjType(&tkBorderObjType.objType);
+ Tcl_RegisterObjType(&tkBitmapObjType.objType);
+ Tcl_RegisterObjType(&tkColorObjType.objType);
+ Tcl_RegisterObjType(&tkCursorObjType.objType);
+ Tcl_RegisterObjType(&tkFontObjType.objType);
+ Tcl_RegisterObjType(&mmObjType.objType);
+ Tcl_RegisterObjType(&pixelObjType.objType);
+ Tcl_RegisterObjType(&tkStateKeyObjType.objType);
+ Tcl_RegisterObjType(&windowObjType.objType);
+ Tcl_RegisterObjType(&tkTextIndexType.objType);
}
/*