summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordkf <donal.k.fellows@manchester.ac.uk>2005-01-11 10:46:37 (GMT)
committerdkf <donal.k.fellows@manchester.ac.uk>2005-01-11 10:46:37 (GMT)
commitb394b866b6cf9b57b603d95b820570b119439fee (patch)
tree5c852c4af5d1b9344503dd2d99590fe03b4ae485
parent81d9c06d1ce5cfb61913049037b3f03977cb7cc7 (diff)
downloadtk-b394b866b6cf9b57b603d95b820570b119439fee.zip
tk-b394b866b6cf9b57b603d95b820570b119439fee.tar.gz
tk-b394b866b6cf9b57b603d95b820570b119439fee.tar.bz2
Improved version of Michael Kirkham's fix for parsing pad values. [1098779]
-rw-r--r--ChangeLog7
-rw-r--r--generic/tkGrid.c10
-rw-r--r--generic/tkInt.h7
-rw-r--r--generic/tkObj.c108
-rw-r--r--generic/tkPack.c82
5 files changed, 122 insertions, 92 deletions
diff --git a/ChangeLog b/ChangeLog
index 9a2b20d..ea21238 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2005-01-11 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tkObj.c (TkParsePadAmount):
+ * generic/tkPack.c: Moved function to tkObj.c and rewrote so that it
+ takes advantage of Tcl_Objs properly and cannot leave objects in an
+ inconsistent state. [Bug 1098779]
+
2005-01-07 Donal K. Fellows <donal.k.fellows@man.ac.uk>
* generic/tkWindow.c (GetScreen): Make sure the result is reset on
diff --git a/generic/tkGrid.c b/generic/tkGrid.c
index 7624537..9de0742 100644
--- a/generic/tkGrid.c
+++ b/generic/tkGrid.c
@@ -8,7 +8,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkGrid.c,v 1.25.2.1 2004/02/18 20:10:34 pspjuth Exp $
+ * RCS: @(#) $Id: tkGrid.c,v 1.25.2.2 2005/01/11 10:46:39 dkf Exp $
*/
#include "tkInt.h"
@@ -293,14 +293,6 @@ static void StickyToString _ANSI_ARGS_((int flags, char *result));
static int StringToSticky _ANSI_ARGS_((char *string));
static void Unlink _ANSI_ARGS_((Gridder *gridPtr));
-/*
- * Prototypes for procedures contained in other files but not exported
- * using tkIntDecls.h
- */
-
-void TkPrintPadAmount _ANSI_ARGS_((Tcl_Interp*, char*, int, int));
-int TkParsePadAmount _ANSI_ARGS_((Tcl_Interp*, Tk_Window, Tcl_Obj*, int*, int*));
-
static Tk_GeomMgr gridMgrType = {
"grid", /* name */
GridReqProc, /* requestProc */
diff --git a/generic/tkInt.h b/generic/tkInt.h
index 9fdf1fa..177cd28 100644
--- a/generic/tkInt.h
+++ b/generic/tkInt.h
@@ -11,7 +11,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: $Id: tkInt.h,v 1.56.2.3 2004/10/27 00:37:37 davygrvy Exp $
+ * RCS: $Id: tkInt.h,v 1.56.2.4 2005/01/11 10:46:39 dkf Exp $
*/
#ifndef _TKINT
@@ -1171,6 +1171,11 @@ EXTERN void TkCreateExitHandler _ANSI_ARGS_((Tcl_ExitProc *proc,
EXTERN void TkDeleteExitHandler _ANSI_ARGS_((Tcl_ExitProc *proc,
ClientData clientData));
EXTERN Tcl_ExitProc TkFinalize;
+EXTERN void TkPrintPadAmount _ANSI_ARGS_((Tcl_Interp *interp,
+ char *buffer, int pad1, int pad2));
+EXTERN int TkParsePadAmount _ANSI_ARGS_((Tcl_Interp *interp,
+ Tk_Window tkwin, Tcl_Obj *objPtr,
+ int *pad1Ptr, int *pad2Ptr));
/*
* Unsupported commands.
diff --git a/generic/tkObj.c b/generic/tkObj.c
index fff25d9..92d9443 100644
--- a/generic/tkObj.c
+++ b/generic/tkObj.c
@@ -9,7 +9,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkObj.c,v 1.8 2003/01/28 20:39:16 jenglish Exp $
+ * RCS: @(#) $Id: tkObj.c,v 1.8.2.1 2005/01/11 10:46:39 dkf Exp $
*/
#include "tkInt.h"
@@ -828,6 +828,112 @@ FreeWindowInternalRep(objPtr)
}
/*
+ *--------------------------------------------------------------
+ *
+ * TkParsePadAmount --
+ *
+ * This procedure parses a padding specification and returns
+ * the appropriate padding values. A padding specification can
+ * be either a single pixel width, or a list of two pixel widths.
+ * If a single pixel width, the amount specified is used for
+ * padding on both sides. If two amounts are specified, then
+ * they specify the left/right or top/bottom padding.
+ *
+ * Results:
+ * A standard Tcl return value.
+ *
+ * Side effects:
+ * An error message is written to the interpreter is something
+ * is not right.
+ *
+ *--------------------------------------------------------------
+ */
+
+int
+TkParsePadAmount(interp, tkwin, specObj, halfPtr, allPtr)
+ Tcl_Interp *interp; /* Interpreter for error reporting. */
+ Tk_Window tkwin; /* A window. Needed by Tk_GetPixels() */
+ Tcl_Obj *specObj; /* The argument to "-padx", "-pady", "-ipadx",
+ * or "-ipady". The thing to be parsed. */
+ int *halfPtr; /* Write the left/top part of padding here */
+ 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_Obj **objv; /* The objects in the list */
+
+ /*
+ * Check for a common case where a single object would otherwise
+ * be shimmered between a list and a pixel spec.
+ */
+
+ if (specObj->typePtr == &pixelObjType) {
+ if (Tk_GetPixelsFromObj(interp, tkwin, specObj, &firstInt) != TCL_OK) {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, "bad pad value \"",
+ Tcl_GetString(specObj),
+ "\": must be positive screen distance", (char *) NULL);
+ return TCL_ERROR;
+ }
+ secondInt = firstInt;
+ goto done;
+ }
+
+ /*
+ * Pad specifications are a list of one or two elements, each of
+ * which is a pixel specification.
+ */
+
+ if (Tcl_ListObjGetElements(interp, specObj, &objc, &objv) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (objc != 1 || objc != 2) {
+ Tcl_AppendResult(interp,
+ "wrong number of parts to pad specification", NULL);
+ return TCL_ERROR;
+ }
+
+ /*
+ * Parse the first part.
+ */
+
+ if (Tk_GetPixelsFromObj(interp, tkwin, objv[0], &firstInt) != TCL_OK ||
+ (firstInt < 0)) {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, "bad pad value \"", Tcl_GetString(objv[0]),
+ "\": must be positive screen distance", (char *) NULL);
+ return TCL_ERROR;
+ }
+
+ /*
+ * Parse the second part if it exists, otherwise it is as if it
+ * was the same as the first part.
+ */
+
+ if (objc == 1) {
+ secondInt = firstInt;
+ } else if (Tk_GetPixelsFromObj(interp, tkwin, objv[1],
+ &secondInt) != TCL_OK || (secondInt < 0)) {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, "bad 2nd pad value \"",
+ Tcl_GetString(objv[1]),
+ "\": must be positive screen distance", (char *) NULL);
+ return TCL_ERROR;
+ }
+
+ /*
+ * Write the parsed bits back into the receiving variables.
+ */
+
+ done:
+ if (halfPtr != 0) {
+ *halfPtr = firstInt;
+ }
+ *allPtr = firstInt + secondInt;
+ return TCL_OK;
+}
+
+/*
*----------------------------------------------------------------------
*
* TkRegisterObjTypes --
diff --git a/generic/tkPack.c b/generic/tkPack.c
index 5ea54cc..6a57384 100644
--- a/generic/tkPack.c
+++ b/generic/tkPack.c
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkPack.c,v 1.16.2.1 2003/07/17 03:17:08 dgp Exp $
+ * RCS: @(#) $Id: tkPack.c,v 1.16.2.2 2005/01/11 10:46:39 dkf Exp $
*/
#include "tkPort.h"
@@ -1046,86 +1046,6 @@ GetPacker(tkwin)
/*
*--------------------------------------------------------------
*
- * TkParsePadAmount --
- *
- * This procedure parses a padding specification and returns
- * the appropriate padding values. A padding specification can
- * be either a single pixel width, or a list of two pixel widths.
- * If a single pixel width, the amount specified is used for
- * padding on both sides. If two amounts are specified, then
- * they specify the left/right or top/bottom padding.
- *
- * Results:
- * A standard Tcl return value.
- *
- * Side effects:
- * An error message is written to the interpreter is something
- * is not right.
- *
- *--------------------------------------------------------------
- */
-
-int
-TkParsePadAmount(interp, tkwin, specObj, halfPtr, allPtr)
- Tcl_Interp *interp; /* Interpreter for error reporting. */
- Tk_Window tkwin; /* A window. Needed by Tk_GetPixels() */
- Tcl_Obj *specObj; /* The argument to "-padx", "-pady", "-ipadx",
- * or "-ipady". The thing to be parsed. */
- int *halfPtr; /* Write the left/top part of padding here */
- int *allPtr; /* Write the total padding here */
-{
- char *secondPart; /* The second pixel amount of the list */
- char *separator = 0; /* Separator between 1st and 2nd pixel widths */
- int sepChar = 0; /* Character used as the separator */
- int firstInt, secondInt; /* The two components of the padding */
- char *padSpec = Tcl_GetString(specObj);
-
- for (secondPart=padSpec;
- (*secondPart != '\0') && !isspace(UCHAR(*secondPart));
- secondPart++)
- { /* Do nothing */ }
- if (*secondPart != '\0') {
- separator = secondPart;
- sepChar = *secondPart;
- *secondPart = '\0';
- secondPart++;
- while ( isspace(UCHAR(*secondPart)) ) {
- secondPart++;
- }
- if (*secondPart == '\0'){
- secondPart = 0;
- *separator = sepChar;
- }
- } else {
- secondPart = 0;
- }
- if ((Tk_GetPixels(interp, tkwin, padSpec, &firstInt) != TCL_OK) ||
- (firstInt < 0)) {
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "bad pad value \"", padSpec,
- "\": must be positive screen distance", (char *) NULL);
- return TCL_ERROR;
- }
- if (secondPart) {
- if ((Tk_GetPixels(interp, tkwin, secondPart, &secondInt) != TCL_OK) ||
- (secondInt < 0)) {
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "bad 2nd pad value \"", secondPart,
- "\": must be positive screen distance", (char *) NULL);
- return TCL_ERROR;
- }
- *separator = sepChar;
- } else {
- secondInt = firstInt;
- }
- if (halfPtr != 0) *halfPtr = firstInt;
- *allPtr = firstInt + secondInt;
- return TCL_OK;
-}
-
-/*
- *--------------------------------------------------------------
- *
* PackAfter --
*
* This procedure does most of the real work of adding