From owner-svn-ports-all@FreeBSD.ORG Tue Apr 29 23:38:31 2014 Return-Path: Delivered-To: svn-ports-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 6C1545AE; Tue, 29 Apr 2014 23:38:31 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 5821798D; Tue, 29 Apr 2014 23:38:31 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s3TNcVYh002530; Tue, 29 Apr 2014 23:38:31 GMT (envelope-from mi@svn.freebsd.org) Received: (from mi@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s3TNcUVQ002527; Tue, 29 Apr 2014 23:38:30 GMT (envelope-from mi@svn.freebsd.org) Message-Id: <201404292338.s3TNcUVQ002527@svn.freebsd.org> From: Mikhail Teterin Date: Tue, 29 Apr 2014 23:38:30 +0000 (UTC) To: ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-head@freebsd.org Subject: svn commit: r352662 - in head/graphics/gdtclft: . files X-SVN-Group: ports-head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-ports-all@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: SVN commit messages for the ports tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 29 Apr 2014 23:38:31 -0000 Author: mi Date: Tue Apr 29 23:38:30 2014 New Revision: 352662 URL: http://svnweb.freebsd.org/changeset/ports/352662 QAT: https://qat.redports.org/buildarchive/r352662/ Log: Switch from using our own method of figuring out TCL_VER to USES=tcl:84+ PR: ports/181412 Bump PORTREVISION accordingly. Add STAGE-conformance (grrr..) Get rid of the short pkg-plist in favor of PLIST_{DIRS,FILES}. While here, improve the code itself a bit: * Use Tcl API more, instead of cooking our own implementations. * Add meainingful checks for safe interpreters instead of blindly letting them use the same functionality as the trusted ones. * Fix compiler warnings enough for WARNS=3. Sponsored by: United Marsupials Added: head/graphics/gdtclft/files/patch-improve - copied, changed from r352636, head/graphics/gdtclft/files/patch-gif Deleted: head/graphics/gdtclft/files/patch-gif head/graphics/gdtclft/pkg-plist Modified: head/graphics/gdtclft/Makefile head/graphics/gdtclft/files/Makefile.bsd Modified: head/graphics/gdtclft/Makefile ============================================================================== --- head/graphics/gdtclft/Makefile Tue Apr 29 23:18:20 2014 (r352661) +++ head/graphics/gdtclft/Makefile Tue Apr 29 23:38:30 2014 (r352662) @@ -3,34 +3,37 @@ PORTNAME= Gdtclft PORTVERSION= 2.2.5 -PORTREVISION= 11 +PORTREVISION= 12 CATEGORIES= graphics tcl -MASTER_SITES= http://www.graphviz.org/pub/ +MASTER_SITES= DISTNAME= ${PORTNAME}${PORTVERSION} MAINTAINER= mi@aldan.algebra.com COMMENT= A TCL interface to the Thomas Boutell's Gd library -LIB_DEPENDS= tcl${TCL_DVER}.1:${PORTSDIR}/lang/tcl${TCL_DVER} \ - gd:${PORTSDIR}/graphics/gd +LIB_DEPENDS= gd:${PORTSDIR}/graphics/gd -TCL_VER?= 8.4 -TCL_DVER= ${TCL_VER:S/.//} +USES= tcl:84+ uidfix MAKEFILE= ${FILESDIR}/Makefile.bsd MAKE_ENV= TCL_VER=${TCL_VER} MKDIR="${MKDIR}" \ - INSTALL_DATA="${INSTALL_DATA}" + INSTALL_DATA="${INSTALL_DATA}" STAGEDIR="${STAGEDIR}" ALL_TARGET= all MANN= gdtclft.n +MANCOMPRESSED= no +GDTCLDIR= lib/tcl${TCL_VER}/gdtclft +PLIST_DIRS= ${GDTCLDIR} +PLIST_FILES= ${GDTCLDIR}/pkgIndex.tcl +PLIST_FILES+= ${GDTCLDIR}/libGdtclft2.so +.if !defined(NO_STAGE) +PLIST_FILES+= ${__MANPAGES} +.endif -NO_STAGE= yes post-patch: ${REINPLACE_CMD} -Ee 's,[[:space:]]+$$,,' ${WRKSRC}/${MANN} post-install: - ${INSTALL_MAN} ${WRKSRC}/${MANN} ${PREFIX}/man/mann/ + ${INSTALL_MAN} ${WRKSRC}/${MANN} ${STAGEDIR}${PREFIX}/man/mann/ .include - -PLIST_SUB!= ${SETENV} TCL_VER=${TCL_VER} ${MAKE} -f ${MAKEFILE} env Modified: head/graphics/gdtclft/files/Makefile.bsd ============================================================================== --- head/graphics/gdtclft/files/Makefile.bsd Tue Apr 29 23:18:20 2014 (r352661) +++ head/graphics/gdtclft/files/Makefile.bsd Tue Apr 29 23:38:30 2014 (r352662) @@ -1,27 +1,28 @@ PACKAGE = Gdtclft VERSION = 2.3 -SHLIB_NAME = lib${PACKAGE}2.so.3 +SHLIB_NAME = lib${PACKAGE}2.so -SRCS = gdhandle.c gdCmd.c +SRCS = gdCmd.c +LOCALBASE ?=/usr/local PREFIX ?=/usr/local TCL_VER ?=8.4 -WARNS = 2 +WARNS = 3 -.if exists(${PREFIX}/lib/tcl${TCL_VER}/tclConfig.sh) +.if exists(${LOCALBASE}/lib/tcl${TCL_VER}/tclConfig.sh) # If for some reason the file does not exist -- make the best guess. In # reality, it will exist by the time we are actually doing the build, so # the quality of the guess does not matter. But we still try well. -mi -TCL_STUB_LIB_SPEC!= . ${PREFIX}/lib/tcl${TCL_VER}/tclConfig.sh; \ +TCL_STUB_LIB_SPEC!= . ${LOCALBASE}/lib/tcl${TCL_VER}/tclConfig.sh; \ echo $$TCL_STUB_LIB_SPEC .else -TCL_STUB_LIB_SPEC= -L${PREFIX}/lib -ltclstub${TCL_VER:S/.//} +TCL_STUB_LIB_SPEC= -L${LOCALBASE}/lib -ltclstub${TCL_VER:S/.//} .endif -LDADD = -L${PREFIX}/lib -lgd -lpng -lz -lm ${TCL_STUB_LIB_SPEC} +LDADD = -L${LOCALBASE}/lib -lgd -lpng -lz -lm ${TCL_STUB_LIB_SPEC} -CFLAGS +=-I${PREFIX}/include/tcl${TCL_VER} -I${PREFIX}/include/gd -CFLAGS +=-DNDEBUG -Wall -I. -DUSE_TCL_STUBS -I${PREFIX}/include +CFLAGS +=-I${LOCALBASE}/include/tcl${TCL_VER} -I${LOCALBASE}/include/gd +CFLAGS +=-DNDEBUG -Wall -I. -DUSE_TCL_STUBS -I${LOCALBASE}/include CFLAGS +=-DVERSION=\"${VERSION}\" all: pkgIndex.tcl @@ -29,17 +30,14 @@ all: pkgIndex.tcl pkgIndex.tcl: echo 'package ifneeded $(PACKAGE) $(VERSION) [list load [file join $$dir $(SHLIB_NAME)] $(PACKAGE)]' > pkgIndex.tcl -DIR = lib/tcl${TCL_VER}/gdtclft +DIR = lib/tcl${TCL_VER}/gdtclft LIBDIR = ${PREFIX}/${DIR} -MANDIR = ${PREFIX}/man/man +MANDIR = ${PREFIX}/man/man -${LIBDIR}: - ${MKDIR} ${LIBDIR} +${STAGEDIR}${LIBDIR}: + ${MKDIR} $@ -env: - @${ECHO} SHLIB_NAME=${SHLIB_NAME} SHLIB_LINK=${SHLIB_LINK} DIR=${DIR} - -beforeinstall: ${LIBDIR} - ${INSTALL_DATA} pkgIndex.tcl ${LIBDIR} +beforeinstall: ${STAGEDIR}${LIBDIR} + ${INSTALL_DATA} pkgIndex.tcl ${STAGEDIR}${LIBDIR} .include Copied and modified: head/graphics/gdtclft/files/patch-improve (from r352636, head/graphics/gdtclft/files/patch-gif) ============================================================================== --- head/graphics/gdtclft/files/patch-gif Tue Apr 29 17:32:57 2014 (r352636, copy source) +++ head/graphics/gdtclft/files/patch-improve Tue Apr 29 23:38:30 2014 (r352662) @@ -6,92 +6,347 @@ GIF, JPEG, and WBMP formats are also add Also, in case of file-opening failure, a useful error string is returned. +Dispense with our own table of handles and use Tcl-objects capability +instead. + +Compiler-warning fixes now allow compiling on FreeBSD with WARNS=3. + +When used in a safe interpreter, the functionality is limited to +disallow access to filesystem. + Use freely and get yourself a pademelon... -mi (http://cafepress.com/buy/pademelon?pid=5934485) --- gdCmd.c Fri Aug 4 17:11:05 2000 -+++ gdCmd.c Mon Dec 4 03:50:17 2006 ++++ gdCmd.c 2014-04-29 18:27:30.000000000 -0400 @@ -19,4 +19,5 @@ */ +#include #include #include -@@ -47,10 +48,10 @@ +@@ -24,5 +25,4 @@ + #include + #include "gd.h" +-#include "gdhandle.h" + + #ifdef WIN32 +@@ -30,28 +30,47 @@ + #endif + +-void *GDHandleTable; ++static Tcl_UpdateStringProc GdPtrTypeUpdate; ++static Tcl_SetFromAnyProc GdPtrTypeSet; ++static Tcl_ObjType GdPtrType = { ++ .name = "gd", ++ .updateStringProc = GdPtrTypeUpdate, ++ .setFromAnyProc = GdPtrTypeSet ++}; ++#define IMGPTR(O) (O->internalRep.otherValuePtr) + +-/* global data */ +-typedef struct { +- tblHeader_pt handleTbl; +-} GdData; ++/* The only two symbols exported */ ++Tcl_AppInitProc Gdtclft_Init, Gdtclft_SafeInit; + +-static int tclGdCreateCmd(), tclGdDestroyCmd(), tclGdWriteCmd(), +- tclGdColorCmd(), tclGdInterlaceCmd(), tclGdSetCmd(), tclGdLineCmd(), +- tclGdRectCmd(), tclGdArcCmd(), tclGdFillCmd(), tclGdSizeCmd(), +- tclGdTextCmd(), tclGdCopyCmd(), tclGdGetCmd(), +- tclGdBrushCmd(), tclGdStyleCmd(), tclGdTileCmd(), tclGdPolygonCmd(), +- tclGdColorNewCmd(), tclGdColorExactCmd(), tclGdColorClosestCmd(), +- tclGdColorResolveCmd(), tclGdColorFreeCmd(), tclGdColorTranspCmd(), +- tclGdColorGetCmd(), tclGdWriteBufCmd(); ++typedef int (GdDataFunction)(Tcl_Interp *interp, ++ int argc, Tcl_Obj *CONST objv[]); ++typedef int (GdImgFunction)(Tcl_Interp *interp, gdImagePtr gdImg, ++ int argc, const int args[]); ++ ++static GdDataFunction tclGdCreateCmd, tclGdDestroyCmd, tclGdWriteCmd, ++ tclGdColorCmd, tclGdInterlaceCmd, tclGdSetCmd, tclGdLineCmd, ++ tclGdRectCmd, tclGdArcCmd, tclGdFillCmd, tclGdSizeCmd, ++ tclGdTextCmd, tclGdCopyCmd, tclGdGetCmd, tclGdWriteBufCmd, ++ tclGdBrushCmd, tclGdStyleCmd, tclGdTileCmd, tclGdPolygonCmd; ++ ++static GdImgFunction tclGdColorNewCmd, tclGdColorExactCmd, ++ tclGdColorClosestCmd, tclGdColorResolveCmd, tclGdColorFreeCmd, ++ tclGdColorTranspCmd, tclGdColorGetCmd; typedef struct { - char *cmd; -+ const char *cmd; - int (*f)(); - int minargs, maxargs; - int subcmds; - int ishandle; +- int (*f)(); +- int minargs, maxargs; +- int subcmds; +- int ishandle; - char *usage; +-} cmdOptions; ++ const char *cmd; ++ GdDataFunction *f; ++ unsigned int minargs, maxargs; ++ unsigned int subcmds; ++ unsigned int ishandle; ++ unsigned int unsafearg; + const char *usage; - } cmdOptions; ++} cmdDataOptions; ++ ++typedef struct { ++ const char *cmd; ++ GdImgFunction *f; ++ unsigned int minargs, maxargs; ++ const char *usage; ++} cmdImgOptions; -@@ -61,16 +62,39 @@ + typedef struct { +@@ -60,53 +79,81 @@ + } BuffSinkContext; - static cmdOptions subcmdVec[] = { +-static cmdOptions subcmdVec[] = { - {"create", tclGdCreateCmd, 2, 2, 0, 0, - "width height"}, -+ {"create", tclGdCreateCmd, 2, 3, 0, 0, +- {"createFromPNG", tclGdCreateCmd, 1, 1, 0, 0, ++static cmdDataOptions subcmdVec[] = { ++ {"create", tclGdCreateCmd, 2, 3, 0, 0, 0, + "width height ?true?"}, - {"createFromPNG", tclGdCreateCmd, 1, 1, 0, 0, - "filehandle"}, -+ {"createFromGIF", tclGdCreateCmd, 1, 1, 0, 0, ++ {"createFromPNG", tclGdCreateCmd, 1, 1, 0, 0, 2, + "filehandle"}, - {"createFromGD", tclGdCreateCmd, 1, 1, 0, 0, - "filehandle"}, -+ {"createFromGD2", tclGdCreateCmd, 1, 1, 0, 0, ++ {"createFromGIF", tclGdCreateCmd, 1, 1, 0, 0, 2, + "filehandle"}, - {"createFromXBM", tclGdCreateCmd, 1, 1, 0, 0, ++ {"createFromGD", tclGdCreateCmd, 1, 1, 0, 0, 2, + "filehandle"}, +- {"createFromGD", tclGdCreateCmd, 1, 1, 0, 0, ++ {"createFromGD2", tclGdCreateCmd, 1, 1, 0, 0, 2, "filehandle"}, +- {"createFromXBM", tclGdCreateCmd, 1, 1, 0, 0, ++ {"createFromXBM", tclGdCreateCmd, 1, 1, 0, 0, 2, ++ "filehandle"}, +#ifdef NOX11 -+ {"createFromXPM-NOT-AVAILABLE", tclGdCreateCmd, 1, 1, 0, 0, ++ {"createFromXPM-NOT-AVAILABLE", tclGdCreateCmd, 1, 1, 0, 0, 2, + "filename"}, +#else -+ {"createFromXPM", tclGdCreateCmd, 1, 1, 0, 0, ++ {"createFromXPM", tclGdCreateCmd, 1, 1, 0, 0, 2, + "filename"}, +#endif -+ {"createFromJPG", tclGdCreateCmd, 1, 1, 0, 0, -+ "filehandle"}, -+ {"createFromJPEG", tclGdCreateCmd, 1, 1, 0, 0, ++ {"createFromJPG", tclGdCreateCmd, 1, 1, 0, 0, 2, + "filehandle"}, -+ {"createFromWBMP", tclGdCreateCmd, 1, 1, 0, 0, ++ {"createFromJPEG", tclGdCreateCmd, 1, 1, 0, 0, 2, + "filehandle"}, ++ {"createFromWBMP", tclGdCreateCmd, 1, 1, 0, 0, 2, + "filehandle"}, - {"destroy", tclGdDestroyCmd, 1, 1, 0, 1, +- {"destroy", tclGdDestroyCmd, 1, 1, 0, 1, ++ {"destroy", tclGdDestroyCmd, 1, 1, 0, 1, 0, "gdhandle"}, -+ {"writeGIF", tclGdWriteCmd, 2, 2, 0, 1, +- {"writePNG", tclGdWriteCmd, 2, 2, 0, 1, ++ {"writeGIF", tclGdWriteCmd, 2, 2, 0, 1, 3, + "gdhandle filehandle"}, -+ {"writeJPG", tclGdWriteCmd, 2, 3, 0, 1, ++ {"writeJPG", tclGdWriteCmd, 2, 3, 0, 1, 3, + "gdhandle filehandle ?quality?"}, -+ {"writeJPEG", tclGdWriteCmd, 2, 3, 0, 1, ++ {"writeJPEG", tclGdWriteCmd, 2, 3, 0, 1, 3, + "gdhandle filehandle ?quality?"}, - {"writePNG", tclGdWriteCmd, 2, 2, 0, 1, ++ {"writePNG", tclGdWriteCmd, 2, 2, 0, 1, 3, "gdhandle filehandle"}, -@@ -79,4 +103,8 @@ - {"writeGD", tclGdWriteCmd, 2, 2, 0, 1, +- {"writePNGvar", tclGdWriteBufCmd, 2, 2, 0, 1, ++ {"writePNGvar", tclGdWriteBufCmd, 2, 2, 0, 1, 0, + "gdhandle var"}, +- {"writeGD", tclGdWriteCmd, 2, 2, 0, 1, ++ {"writeGD", tclGdWriteCmd, 2, 2, 0, 1, 3, "gdhandle filehandle"}, -+ {"writeGD2", tclGdWriteCmd, 2, 2, 0, 1, +- +- {"interlace", tclGdInterlaceCmd, 1, 2, 0, 1, ++ {"writeGD2", tclGdWriteCmd, 2, 2, 0, 1, 3, + "gdhandle filehandle"}, -+ {"writeWBMP", tclGdWriteCmd, 3, 3, 0, 1, ++ {"writeWBMP", tclGdWriteCmd, 3, 3, 0, 1, 3, + "gdhandle filehandle foreground"}, - - {"interlace", tclGdInterlaceCmd, 1, 2, 0, 1, -@@ -79,4 +103,8 @@ - {"writeGD", tclGdWriteCmd, 2, 2, 0, 1, - "gdhandle filehandle"}, -+ {"writeGD2", tclGdWriteCmd, 2, 2, 0, 1, ++ {"writeGD2", tclGdWriteCmd, 2, 2, 0, 1, 3, + "gdhandle filehandle"}, -+ {"writeWBMP", tclGdWriteCmd, 3, 3, 0, 1, -+ "gdhandle filehandle foreground"}, ++ {"interlace", tclGdInterlaceCmd, 1, 2, 0, 1, 0, + "gdhandle ?on-off?"}, + +- {"color", tclGdColorCmd, 2, 5, 1, 1, ++ {"color", tclGdColorCmd, 2, 5, 1, 1, 0, + "option values..."}, +- {"brush", tclGdBrushCmd, 2, 2, 0, 2, ++ {"brush", tclGdBrushCmd, 2, 2, 0, 2, 0, + "gdhandle brushhandle"}, +- {"style", tclGdStyleCmd, 2, 999, 0, 1, ++ {"style", tclGdStyleCmd, 2, 999, 0, 1, 0, + "gdhandle color..."}, +- {"tile", tclGdTileCmd, 2, 2, 0, 2, ++ {"tile", tclGdTileCmd, 2, 2, 0, 2, 0, + "gdhandle tilehandle"}, + +- {"set", tclGdSetCmd, 4, 4, 0, 1, ++ {"set", tclGdSetCmd, 4, 4, 0, 1, 0, + "gdhandle color x y"}, +- {"line", tclGdLineCmd, 6, 6, 0, 1, ++ {"line", tclGdLineCmd, 6, 6, 0, 1, 0, + "gdhandle color x1 y1 x2 y2"}, +- {"rectangle", tclGdRectCmd, 6, 6, 0, 1, ++ {"rectangle", tclGdRectCmd, 6, 6, 0, 1, 0, + "gdhandle color x1 y1 x2 y2"}, +- {"fillrectangle", tclGdRectCmd, 6, 6, 0, 1, ++ {"fillrectangle", tclGdRectCmd, 6, 6, 0, 1, 0, + "gdhandle color x1 y1 x2 y2"}, +- {"arc", tclGdArcCmd, 8, 8, 0, 1, ++ {"arc", tclGdArcCmd, 8, 8, 0, 1, 0, + "gdhandle color cx cy width height start end"}, +- {"fillarc", tclGdArcCmd, 8, 8, 0, 1, ++ {"fillarc", tclGdArcCmd, 8, 8, 0, 1, 0, + "gdhandle color cx cy width height start end"}, +- {"polygon", tclGdPolygonCmd, 2, 999, 0, 1, ++ {"polygon", tclGdPolygonCmd, 2, 999, 0, 1, 0, + "gdhandle color x1 y1 x2 y2 x3 y3 ..."}, +- {"fillpolygon", tclGdPolygonCmd, 3, 999, 0, 1, ++ {"fillpolygon", tclGdPolygonCmd, 3, 999, 0, 1, 0, + "gdhandle color x1 y1 x2 y2 x3 y3 ..."}, +- {"fill", tclGdFillCmd, 4, 5, 0, 1, ++ {"fill", tclGdFillCmd, 4, 5, 0, 1, 0, + "gdhandle color x y ?bordercolor?"}, + /* +@@ -114,32 +161,25 @@ + * of text string, so the text command provides its own handle processing and checking + */ +- {"text", tclGdTextCmd, 8, 8, 0, 0, ++ {"text", tclGdTextCmd, 8, 8, 0, 0, 4, + "gdhandle color fontpathname size angle x y string"}, + + +- {"copy", tclGdCopyCmd, 8, 10, 0, 2, ++ {"copy", tclGdCopyCmd, 8, 10, 0, 2, 0, + "desthandle srchandle destx desty srcx srcy destw desth ?srcw srch?"}, + +- {"get", tclGdGetCmd, 3, 3, 0, 1, ++ {"get", tclGdGetCmd, 3, 3, 0, 1, 0, + "gdhandle x y"}, +- {"size", tclGdSizeCmd, 1, 1, 0, 1, ++ {"size", tclGdSizeCmd, 1, 1, 0, 1, 0, + "gdhandle"}, + }; + +-static cmdOptions colorCmdVec[] = { +- {"new", tclGdColorNewCmd, 5, 5, 1, 1, +- "gdhandle red green blue"}, +- {"exact", tclGdColorExactCmd, 5, 5, 1, 1, +- "gdhandle red green blue"}, +- {"closest", tclGdColorClosestCmd, 5, 5, 1, 1, +- "gdhandle red green blue"}, +- {"resolve", tclGdColorResolveCmd, 5, 5, 1, 1, +- "gdhandle red green blue"}, +- {"free", tclGdColorFreeCmd, 3, 3, 1, 1, +- "gdhandle color"}, +- {"transparent", tclGdColorTranspCmd, 2, 3, 1, 1, +- "gdhandle ?color?"}, +- {"get", tclGdColorGetCmd, 2, 3, 1, 1, +- "gdhandle ?color?"} ++static cmdImgOptions colorCmdVec[] = { ++ {"new", tclGdColorNewCmd, 5, 5, "red green blue"}, ++ {"exact", tclGdColorExactCmd, 5, 5, "red green blue"}, ++ {"closest", tclGdColorClosestCmd, 5, 5, "red green blue"}, ++ {"resolve", tclGdColorResolveCmd, 5, 5, "red green blue"}, ++ {"free", tclGdColorFreeCmd, 3, 3, "color"}, ++ {"transparent", tclGdColorTranspCmd, 2, 3, "?color?"}, ++ {"get", tclGdColorGetCmd, 2, 3, "?color?"} + }; + +@@ -317,11 +357,10 @@ + * + */ +-int ++static int + gdCmd(ClientData clientData, Tcl_Interp *interp, + int argc, Tcl_Obj *CONST objv[]) + { +- GdData *gdData = (GdData *)clientData; +- int argi, subi; +- char buf[100]; ++ unsigned int argi; ++ size_t subi; + /* Check for subcommand. */ + if (argc < 2) { +@@ -336,9 +375,7 @@ + + /* Check arg count. */ +- if (argc - 2 < subcmdVec[subi].minargs || +- argc - 2 > subcmdVec[subi].maxargs) { +- sprintf(buf, "wrong # args: should be \"gd %s %s\"", +- subcmdVec[subi].cmd, subcmdVec[subi].usage); +- Tcl_SetResult(interp, buf, TCL_VOLATILE); ++ if ((unsigned)argc - 2 < subcmdVec[subi].minargs || ++ (unsigned)argc - 2 > subcmdVec[subi].maxargs) { ++ Tcl_WrongNumArgs(interp, 2, objv, subcmdVec[subi].usage); + return TCL_ERROR; + } +@@ -346,20 +383,6 @@ + /* Check for valid handle(s). */ + if (subcmdVec[subi].ishandle > 0) { +- /* Are any handles allocated? */ +- if (gdData->handleTbl == NULL) { +- sprintf(buf, "no such handle%s: ", +- subcmdVec[subi].ishandle > 1 ? "s" : ""); +- Tcl_SetResult(interp, buf, TCL_VOLATILE); +- for (argi = 2 + subcmdVec[subi].subcmds; +- argi < 2 + subcmdVec[subi].subcmds + +- subcmdVec[subi].ishandle; +- argi++) { +- Tcl_AppendResult(interp, +- Tcl_GetString(objv[argi]), " ", 0); +- } +- return TCL_ERROR; +- } + /* Check each handle to see if it's a valid handle. */ +- if (2+subcmdVec[subi].subcmds+subcmdVec[subi].ishandle > argc) { ++ if (2+subcmdVec[subi].subcmds+subcmdVec[subi].ishandle > (unsigned)argc) { + Tcl_SetResult(interp, "GD handle(s) not specified", TCL_STATIC); + return TCL_ERROR; +@@ -369,12 +392,26 @@ + subcmdVec[subi].ishandle); + argi++) { +- if (! gdHandleXlate(interp, gdData->handleTbl, +- Tcl_GetString(objv[argi]))) ++ if (objv[argi]->typePtr != &GdPtrType && ++ GdPtrTypeSet(interp, objv[argi]) != TCL_OK) + return TCL_ERROR; + } + } + ++ /* ++ * If we are operating in a safe interpreter, check, ++ * if this command is suspect -- and only let existing ++ * filehandles through, if so. ++ */ ++ if (clientData != NULL && subcmdVec[subi].unsafearg != 0) { ++ const char *fname = ++ Tcl_GetString(objv[subcmdVec[subi].unsafearg]); ++ if (!Tcl_IsChannelExisting(fname)) ++ Tcl_AppendResult(interp, "Access to ", fname, ++ " not allowed in safe interpreter", TCL_STATIC); ++ return TCL_ERROR; ++ } ++ + /* Call the subcommand function. */ +- return (*subcmdVec[subi].f)(interp, gdData, argc, objv); ++ return (*subcmdVec[subi].f)(interp, argc, objv); + } + } +@@ -390,5 +427,5 @@ + + static int +-tclGdCreateCmd(Tcl_Interp *interp, GdData *gdData, ++tclGdCreateCmd(Tcl_Interp *interp, + int argc, Tcl_Obj *CONST objv[]) + { +@@ -397,16 +434,29 @@ + FILE *filePtr; + ClientData clientdata; +- char *cmd, buf[50]; ++ char *cmd; ++ Tcl_Obj *result; + int fileByName; - {"interlace", tclGdInterlaceCmd, 1, 2, 0, 1, -@@ -402,9 +430,20 @@ cmd = Tcl_GetString(objv[1]); if (strcmp(cmd, "create") == 0) { + int trueColor = 0; @@ -100,7 +355,6 @@ Use freely and get yourself a pademelon. return TCL_ERROR; if (Tcl_GetIntFromObj(interp, objv[3], &h) != TCL_OK) return TCL_ERROR; -- im = gdImageCreate(w, h); + /* An optional argument may specify true for "TrueColor" */ + if (argc == 5 && Tcl_GetBooleanFromObj(interp, objv[4], + &trueColor) == TCL_ERROR) @@ -109,23 +363,19 @@ Use freely and get yourself a pademelon. + if (trueColor) + im = gdImageCreateTrueColor(w, h); + else -+ im = gdImageCreate(w, h); + im = gdImageCreate(w, h); + if (im == NULL) { -@@ -414,30 +453,70 @@ ++ char buf[255]; + sprintf(buf, "GD unable to allocate %d X %d image", w, h); + Tcl_SetResult(interp, buf, TCL_VOLATILE); +@@ -414,6 +464,19 @@ } } else { + char *arg2 = Tcl_GetString(objv[2]); fileByName = 0; /* first try to get file from open channel */ - if (Tcl_GetOpenFile(interp, Tcl_GetString(objv[2]), 0, 1, &clientdata) == TCL_OK) { -- filePtr = (FILE *)clientdata; -- } else { -- /* Not a channel, or Tcl_GetOpenFile() not supported. -- * See if we can open directly. -- */ -- fileByName++; -- if ((filePtr = fopen(Tcl_GetString(objv[2]),"rb")) == NULL) { + + if (cmd[10] == 'X' && cmd[11] == 'P' && cmd[12] == 'M') { +#ifdef NOX11 @@ -139,28 +389,31 @@ Use freely and get yourself a pademelon. + } else { + if (Tcl_GetOpenFile(interp, arg2, 0, 1, &clientdata) + == TCL_OK) { -+ filePtr = (FILE *)clientdata; -+ } else { -+ /* Not a channel, or Tcl_GetOpenFile() not supported. -+ * See if we can open directly. -+ */ -+ fileByName++; + filePtr = (FILE *)clientdata; + } else { +@@ -422,43 +485,68 @@ + */ + fileByName++; +- if ((filePtr = fopen(Tcl_GetString(objv[2]),"rb")) == NULL) { + if ((filePtr = fopen(arg2, "rb")) == NULL) { + Tcl_AppendResult(interp, + "could not open :", arg2, "': ", + strerror(errno), NULL); -+ return TCL_ERROR; -+ } -+ Tcl_ResetResult(interp); -+ } + return TCL_ERROR; + } + Tcl_ResetResult(interp); + } + -+ /* Read PNG, XBM, or GD file? */ + /* Read PNG, XBM, or GD file? */ +- if (cmd[10] == 'P') { + switch (cmd[10]) { + case 'P': -+ im = gdImageCreateFromPng(filePtr); + im = gdImageCreateFromPng(filePtr); +- } else if (cmd[10] == 'X') { + break; + case 'X': -+ im = gdImageCreateFromXbm(filePtr); + im = gdImageCreateFromXbm(filePtr); +- } else { + break; + case 'G': /* GIF, GD2, and GD */ + if (cmd[11] == 'I') @@ -168,7 +421,7 @@ Use freely and get yourself a pademelon. + else if (cmd[12] == '2') + im = gdImageCreateFromGd2(filePtr); + else -+ im = gdImageCreateFromGd(filePtr); + im = gdImageCreateFromGd(filePtr); + break; + case 'J': + im = gdImageCreateFromJpeg(filePtr); @@ -179,24 +432,12 @@ Use freely and get yourself a pademelon. + default: + Tcl_AppendResult(interp, cmd + 10, + "unrecognizable format requested", NULL); - return TCL_ERROR; - } -- Tcl_ResetResult(interp); -- } -- /* Read PNG, XBM, or GD file? */ -- if (cmd[10] == 'P') { -- im = gdImageCreateFromPng(filePtr); -- } else if (cmd[10] == 'X') { -- im = gdImageCreateFromXbm(filePtr); -- } else { -- im = gdImageCreateFromGd(filePtr); -- } -- if (fileByName) { -- fclose(filePtr); -+ if (fileByName) { -+ fclose(filePtr); -+ } ++ return TCL_ERROR; } + if (fileByName) { + fclose(filePtr); + } ++ } + if (im == NULL) { - Tcl_SetResult(interp,"GD unable to read image file", TCL_STATIC); @@ -205,7 +446,42 @@ Use freely and get yourself a pademelon. + cmd + 10, NULL); return TCL_ERROR; } -@@ -472,15 +551,41 @@ + } + +- *(gdImagePtr *)(gdHandleAlloc(gdData->handleTbl, buf)) = im; +- Tcl_SetResult(interp, buf, TCL_VOLATILE); ++ result = Tcl_NewObj(); ++ IMGPTR(result) = im; ++ result->typePtr = &GdPtrType; ++ result->bytes = NULL; ++ Tcl_SetObjResult(interp, result); + return TCL_OK; + } + + static int +-tclGdDestroyCmd(Tcl_Interp *interp, GdData *gdData, int argc, Tcl_Obj *CONST objv[]) ++tclGdDestroyCmd(Tcl_Interp *interp, int argc, Tcl_Obj *CONST objv[]) + { + gdImagePtr im; +- void *hdl; + +- /* Get the handle, and the image pointer. */ +- hdl = (void *)gdHandleXlate(interp, gdData->handleTbl, +- Tcl_GetString(objv[2])); +- im = *(gdImagePtr *)hdl; +- /* Release the handle, destroy the image. */ +- gdHandleFree(gdData->handleTbl, hdl); ++ /* Get the image pointer and destroy it */ ++ im = IMGPTR(objv[2]); + gdImageDestroy(im); + +@@ -467,20 +555,45 @@ + + static int +-tclGdWriteCmd(Tcl_Interp *interp, GdData *gdData, int argc, Tcl_Obj *CONST objv[]) ++tclGdWriteCmd(Tcl_Interp *interp, int argc, Tcl_Obj *CONST objv[]) + { + gdImagePtr im; FILE *filePtr; ClientData clientdata; - char *cmd; @@ -238,18 +514,19 @@ Use freely and get yourself a pademelon. + } + /* Get the image pointer. */ - im = *(gdImagePtr *)gdHandleXlate(interp, gdData->handleTbl, - Tcl_GetString(objv[2])); - -+ fname = Tcl_GetString(objv[3]); +- im = *(gdImagePtr *)gdHandleXlate(interp, gdData->handleTbl, +- Tcl_GetString(objv[2])); ++ im = IMGPTR(objv[2]); + ++ fname = Tcl_GetString(objv[3]); + /* Get the file reference. */ fileByName = 0; /* first try to get file from open channel */ - if (Tcl_GetOpenFile(interp, Tcl_GetString(objv[3]), 1, 1, &clientdata) == TCL_OK) { + if (Tcl_GetOpenFile(interp, fname, 1, 1, &clientdata) == TCL_OK) { filePtr = (FILE *)clientdata; } else { -@@ -489,5 +594,7 @@ +@@ -489,5 +602,7 @@ */ fileByName++; - if ((filePtr = fopen(Tcl_GetString(objv[3]),"wb")) == NULL) { @@ -258,7 +535,7 @@ Use freely and get yourself a pademelon. + "': ", strerror(errno), NULL); return TCL_ERROR; } -@@ -496,8 +603,22 @@ +@@ -496,8 +611,22 @@ /* Do it. */ - if (cmd[5] == 'P') { @@ -266,7 +543,6 @@ Use freely and get yourself a pademelon. + case 'P': gdImagePng(im, filePtr); - } else { -- gdImageGd(im, filePtr); + break; + case 'G': + if (cmd[6] == 'I') @@ -274,7 +550,7 @@ Use freely and get yourself a pademelon. + else if (cmd[7] == '2') + gdImageGd2(im, filePtr, GD2_CHUNKSIZE, GD2_FMT_COMPRESSED); + else -+ gdImageGd(im, filePtr); + gdImageGd(im, filePtr); + break; + case 'J': + gdImageJpeg(im, filePtr, arg4); @@ -284,6 +560,491 @@ Use freely and get yourself a pademelon. + break; } if (fileByName) { +@@ -510,5 +639,5 @@ + + static int +-tclGdInterlaceCmd(Tcl_Interp *interp, GdData *gdData, ++tclGdInterlaceCmd(Tcl_Interp *interp, + int argc, Tcl_Obj *CONST objv[]) + { +@@ -517,6 +646,5 @@ + + /* Get the image pointer. */ +- im = *(gdImagePtr *)gdHandleXlate(interp, gdData->handleTbl, +- Tcl_GetString(objv[2])); ++ im = IMGPTR(objv[2]); + + if (argc == 4) { +@@ -535,7 +663,6 @@ + } + +- + static int +-tclGdColorCmd(Tcl_Interp *interp, GdData *gdData, ++tclGdColorCmd(Tcl_Interp *interp, + int argc, Tcl_Obj *CONST objv[]) + { +@@ -551,17 +678,14 @@ + { + /* Check arg count. */ +- if (argc - 2 < colorCmdVec[subi].minargs || +- argc - 2 > colorCmdVec[subi].maxargs) ++ if ((unsigned)argc - 2 < colorCmdVec[subi].minargs || ++ (unsigned)argc - 2 > colorCmdVec[subi].maxargs) + { +- Tcl_AppendResult(interp, +- "wrong # args: should be \"gd color ", +- colorCmdVec[subi].cmd, " ", +- colorCmdVec[subi].usage, "\"", 0); ++ Tcl_WrongNumArgs(interp, 3, objv, ++ colorCmdVec[subi].usage); + return TCL_ERROR; + } + + /* Get the image pointer. */ +- im = *(gdImagePtr *)gdHandleXlate(interp, gdData->handleTbl, +- Tcl_GetString(objv[3])); ++ im = IMGPTR(objv[3]); + /* Parse off integer arguments. + * 1st 4 are gd color +@@ -605,5 +729,5 @@ + + static int +-tclGdColorNewCmd(Tcl_Interp *interp, gdImagePtr im, int argc, int args[]) ++tclGdColorNewCmd(Tcl_Interp *interp, gdImagePtr im, int argc, const int args[]) + { + int color; +@@ -615,5 +739,5 @@ + + static int +-tclGdColorExactCmd(Tcl_Interp *interp, gdImagePtr im, int argc, int args[]) ++tclGdColorExactCmd(Tcl_Interp *interp, gdImagePtr im, int argc, const int args[]) + { + int color; +@@ -625,5 +749,5 @@ + + static int +-tclGdColorClosestCmd(Tcl_Interp *interp, gdImagePtr im, int argc, int args[]) ++tclGdColorClosestCmd(Tcl_Interp *interp, gdImagePtr im, int argc, const int args[]) + { + int color; +@@ -635,5 +759,5 @@ + + static int +-tclGdColorResolveCmd(Tcl_Interp *interp, gdImagePtr im, int argc, int args[]) ++tclGdColorResolveCmd(Tcl_Interp *interp, gdImagePtr im, int argc, const int args[]) + { + int color; +@@ -645,5 +769,5 @@ + + static int +-tclGdColorFreeCmd(Tcl_Interp *interp, gdImagePtr im, int argc, int args[]) ++tclGdColorFreeCmd(Tcl_Interp *interp, gdImagePtr im, int argc, const int args[]) + { + gdImageColorDeallocate(im, args[0]); +@@ -652,5 +776,5 @@ + + static int +-tclGdColorTranspCmd(Tcl_Interp *interp, gdImagePtr im, int argc, int args[]) ++tclGdColorTranspCmd(Tcl_Interp *interp, gdImagePtr im, int argc, const int args[]) + { + int color; +@@ -668,33 +792,37 @@ + + static int +-tclGdColorGetCmd(Tcl_Interp *interp, gdImagePtr im, int argc, int args[]) ++tclGdColorGetCmd(Tcl_Interp *interp, gdImagePtr im, int argc, const int args[]) + { +- char buf[30]; +- int i; ++ int i, ncolors; ++ Tcl_Obj *tuple[4], *result; + ++ ncolors = gdImageColorsTotal(im); + /* IF one arg, return the single color, else return list of all colors. */ + if (argc == 1) + { + i = args[0]; +- if (i >= gdImageColorsTotal(im) || im->open[i]) { ++ if (i >= ncolors || im->open[i]) { + Tcl_SetResult(interp, "No such color", TCL_STATIC); + return TCL_ERROR; + } +- sprintf(buf, "%d %d %d %d", i, +- gdImageRed(im,i), +- gdImageGreen(im,i), +- gdImageBlue(im,i)); +- Tcl_SetResult(interp, buf, TCL_VOLATILE); ++ tuple[0] = Tcl_NewIntObj(i); ++ tuple[1] = Tcl_NewIntObj(gdImageRed(im,i)); ++ tuple[2] = Tcl_NewIntObj(gdImageGreen(im,i)); ++ tuple[3] = Tcl_NewIntObj(gdImageBlue(im,i)); ++ Tcl_SetObjResult(interp, Tcl_NewListObj(4, tuple)); + } else { +- for (i = 0; i < gdImageColorsTotal(im); i++) ++ result = Tcl_NewListObj(0, NULL); ++ for (i = 0; i < ncolors; i++) + { + if (im->open[i]) + continue; +- sprintf(buf, "%d %d %d %d", i, +- gdImageRed(im,i), +- gdImageGreen(im,i), +- gdImageBlue(im,i)); +- Tcl_AppendElement(interp, buf); ++ tuple[0] = Tcl_NewIntObj(i); ++ tuple[1] = Tcl_NewIntObj(gdImageRed(im,i)); ++ tuple[2] = Tcl_NewIntObj(gdImageGreen(im,i)); ++ tuple[3] = Tcl_NewIntObj(gdImageBlue(im,i)); ++ Tcl_ListObjAppendElement(NULL, result, ++ Tcl_NewListObj(4, tuple)); + } ++ Tcl_SetObjResult(interp, result); + } + +@@ -703,5 +831,5 @@ + + static int +-tclGdBrushCmd(Tcl_Interp *interp, GdData *gdData, ++tclGdBrushCmd(Tcl_Interp *interp, + int argc, Tcl_Obj *CONST objv[]) + { +@@ -709,8 +837,6 @@ + + /* Get the image pointers. */ +- im = *(gdImagePtr *)gdHandleXlate(interp, gdData->handleTbl, +- Tcl_GetString(objv[2])); +- imbrush = *(gdImagePtr *)gdHandleXlate(interp, gdData->handleTbl, +- Tcl_GetString(objv[3])); ++ im = IMGPTR(objv[2]); ++ imbrush = IMGPTR(objv[3]); + + /* Do it. */ +@@ -721,5 +847,5 @@ + + static int +-tclGdTileCmd(Tcl_Interp *interp, GdData *gdData, ++tclGdTileCmd(Tcl_Interp *interp, + int argc, Tcl_Obj *CONST objv[]) + { +@@ -727,8 +853,6 @@ + + /* Get the image pointers. */ +- im = *(gdImagePtr *)gdHandleXlate(interp, gdData->handleTbl, +- Tcl_GetString(objv[2])); +- tile = *(gdImagePtr *)gdHandleXlate(interp, gdData->handleTbl, +- Tcl_GetString(objv[3])); ++ im = IMGPTR(objv[2]); ++ tile = IMGPTR(objv[3]); + + /* Do it. */ +@@ -740,5 +864,5 @@ + + static int +-tclGdStyleCmd(Tcl_Interp *interp, GdData *gdData, ++tclGdStyleCmd(Tcl_Interp *interp, + int argc, Tcl_Obj *CONST objv[]) + { +@@ -749,6 +873,5 @@ + + /* Get the image pointer. */ +- im = *(gdImagePtr *)gdHandleXlate(interp, gdData->handleTbl, +- Tcl_GetString(objv[2])); ++ im = IMGPTR(objv[2]); + + /* Figure out how many colors in the style list and allocate memory. */ +@@ -788,5 +911,5 @@ + + static int +-tclGdSetCmd(Tcl_Interp *interp, GdData *gdData, ++tclGdSetCmd(Tcl_Interp *interp, + int argc, Tcl_Obj *CONST objv[]) + { +@@ -795,6 +918,5 @@ + + /* Get the image pointer. */ +- im = *(gdImagePtr *)gdHandleXlate(interp, gdData->handleTbl, +- Tcl_GetString(objv[2])); ++ im = IMGPTR(objv[2]); + + /* Get the color, x, y values. */ +@@ -813,5 +935,5 @@ + + static int +-tclGdLineCmd(Tcl_Interp *interp, GdData *gdData, ++tclGdLineCmd(Tcl_Interp *interp, + int argc, Tcl_Obj *CONST objv[]) + { +@@ -820,6 +942,5 @@ + + /* Get the image pointer. */ +- im = *(gdImagePtr *)gdHandleXlate(interp, gdData->handleTbl, +- Tcl_GetString(objv[2])); ++ im = IMGPTR(objv[2]); + + /* Get the color, x, y values. */ +@@ -842,14 +963,13 @@ + + static int +-tclGdRectCmd(Tcl_Interp *interp, GdData *gdData, ++tclGdRectCmd(Tcl_Interp *interp, + int argc, Tcl_Obj *CONST objv[]) + { + gdImagePtr im; + int color, x1, y1, x2, y2; +- char *cmd; ++ const char *cmd; + + /* Get the image pointer. */ +- im = *(gdImagePtr *)gdHandleXlate(interp, gdData->handleTbl, +- Tcl_GetString(objv[2])); ++ im = IMGPTR(objv[2]); + + /* Get the color, x, y values. */ +@@ -876,14 +996,13 @@ + + static int +-tclGdArcCmd(Tcl_Interp *interp, GdData *gdData, ++tclGdArcCmd(Tcl_Interp *interp, + int argc, Tcl_Obj *CONST objv[]) + { + gdImagePtr im; + int color, cx, cy, width, height, start, end; +- char *cmd; ++ const char *cmd; + + /* Get the image pointer. */ +- im = *(gdImagePtr *)gdHandleXlate(interp, gdData->handleTbl, +- Tcl_GetString(objv[2])); ++ im = IMGPTR(objv[2]); + + /* Get the color, x, y values. */ +@@ -917,5 +1036,5 @@ + + static int +-tclGdPolygonCmd(Tcl_Interp *interp, GdData *gdData, ++tclGdPolygonCmd(Tcl_Interp *interp, + int argc, Tcl_Obj *CONST objv[]) + { +@@ -925,9 +1044,8 @@ + gdPointPtr points = NULL; + int retval = TCL_OK; +- char *cmd; ++ const char *cmd; + *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***