From b1247c27b40bfccec96025d912ed063e9280eda0 Mon Sep 17 00:00:00 2001 From: dkf Date: Tue, 11 Jan 2005 10:35:25 +0000 Subject: Improved version of Michael Kirkham's fix for parsing pad values. [1098779] --- ChangeLog | 7 ++++ generic/tkGrid.c | 10 +----- generic/tkInt.h | 7 +++- generic/tkObj.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- generic/tkPack.c | 83 +----------------------------------------- 5 files changed, 122 insertions(+), 93 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7021755..13a24f3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2005-01-11 Donal K. Fellows + + * 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-10 Joe English * unix/Makefile.in, unix/configure.in, unix/tkConfig.sh.in: Remove ${DBGX}, ${TK_DBGX} from Tk build system [Patch 1081595]. diff --git a/generic/tkGrid.c b/generic/tkGrid.c index e89e65a..7cdbb80 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.34 2004/11/07 22:00:23 pspjuth Exp $ + * RCS: @(#) $Id: tkGrid.c,v 1.35 2005/01/11 10:35:27 dkf Exp $ */ #include "tkInt.h" @@ -303,14 +303,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 58482f9..314a934 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.64 2004/10/26 13:15:09 dkf Exp $ + * RCS: $Id: tkInt.h,v 1.65 2005/01/11 10:35:27 dkf Exp $ */ #ifndef _TKINT @@ -1181,6 +1181,11 @@ EXTERN void TkpBuildRegionFromAlphaData _ANSI_ARGS_(( unsigned int width, unsigned int height, unsigned char *dataPtr, unsigned int pixelStride, unsigned int lineStride)); +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 1b4414b..8a5acf1 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.10 2004/01/13 02:06:00 davygrvy Exp $ + * RCS: @(#) $Id: tkObj.c,v 1.11 2005/01/11 10:35:27 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 4519462..269e395 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.20 2005/01/09 17:46:49 chengyemao Exp $ + * RCS: @(#) $Id: tkPack.c,v 1.21 2005/01/11 10:35:27 dkf Exp $ */ #include "tkPort.h" @@ -1046,87 +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); - - while(*padSpec && isspace(UCHAR(*padSpec))) padSpec++; - 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 -- cgit v0.12