Index: generic/tkCanvas.c =================================================================== RCS file: /cvsroot/tktoolkit/tk/generic/tkCanvas.c,v retrieving revision 1.20 diff -r1.20 tkCanvas.c 294c294 < static CONST char** GetStringsFromObjs _ANSI_ARGS_((int argc, --- > CONST char** GetStringsFromObjs _ANSI_ARGS_((int argc, 5489c5489 < static CONST char ** --- > CONST char ** Index: generic/tkInt.h =================================================================== RCS file: /cvsroot/tktoolkit/tk/generic/tkInt.h,v retrieving revision 1.54 diff -r1.54 tkInt.h 1066,1067c1066,1068 < EXTERN int Tk_TextCmd _ANSI_ARGS_((ClientData clientData, < Tcl_Interp *interp, int argc, CONST char **argv)); --- > EXTERN int Tk_TextObjCmd _ANSI_ARGS_((ClientData clientData, > Tcl_Interp *interp, int objc, > Tcl_Obj *CONST objv[])); Index: generic/tkTest.c =================================================================== RCS file: /cvsroot/tktoolkit/tk/generic/tkTest.c,v retrieving revision 1.21 diff -r1.21 tkTest.c 2328c2328,2332 < textPtr = (TkText *) info.clientData; --- > if (info.isNativeObjectProc) { > textPtr = (TkText *) info.objClientData; > } else { > textPtr = (TkText *) info.clientData; > } Index: generic/tkText.c =================================================================== RCS file: /cvsroot/tktoolkit/tk/generic/tkText.c,v retrieving revision 1.32 diff -r1.32 tkText.c 33c33,35 < * Custom options for handling "-state" --- > * The 'TkTextState' enum in tkText.h is used to define a type for the > * -state option of the Text widget. These values are used as indices > * into the string table below. 36,38c38,39 < static Tk_CustomOption stateOption = { < (Tk_OptionParseProc *) TkStateParseProc, < TkStatePrintProc, (ClientData) NULL /* only "normal" and "disabled" */ --- > static char *stateStrings[] = { > "disabled", "normal", (char *) NULL 42c43,45 < * Information used to parse text configuration options: --- > * The 'TkWrapMode' enum in tkText.h is used to define a type for the > * -wrap option of the Text widget. These values are used as indices > * into the string table below. 45,151c48,49 < static Tk_ConfigSpec configSpecs[] = { < {TK_CONFIG_BOOLEAN, "-autoseparators", "autoSeparators", < "AutoSeparators", DEF_TEXT_AUTO_SEPARATORS, < Tk_Offset(TkText, autoSeparators), 0}, < {TK_CONFIG_BORDER, "-background", "background", "Background", < DEF_TEXT_BG_COLOR, Tk_Offset(TkText, border), TK_CONFIG_COLOR_ONLY}, < {TK_CONFIG_BORDER, "-background", "background", "Background", < DEF_TEXT_BG_MONO, Tk_Offset(TkText, border), TK_CONFIG_MONO_ONLY}, < {TK_CONFIG_SYNONYM, "-bd", "borderWidth", (char *) NULL, < (char *) NULL, 0, 0}, < {TK_CONFIG_SYNONYM, "-bg", "background", (char *) NULL, < (char *) NULL, 0, 0}, < {TK_CONFIG_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", < DEF_TEXT_BORDER_WIDTH, Tk_Offset(TkText, borderWidth), 0}, < {TK_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor", < DEF_TEXT_CURSOR, Tk_Offset(TkText, cursor), TK_CONFIG_NULL_OK}, < {TK_CONFIG_BOOLEAN, "-exportselection", "exportSelection", < "ExportSelection", DEF_TEXT_EXPORT_SELECTION, < Tk_Offset(TkText, exportSelection), 0}, < {TK_CONFIG_SYNONYM, "-fg", "foreground", (char *) NULL, < (char *) NULL, 0, 0}, < {TK_CONFIG_FONT, "-font", "font", "Font", < DEF_TEXT_FONT, Tk_Offset(TkText, tkfont), 0}, < {TK_CONFIG_COLOR, "-foreground", "foreground", "Foreground", < DEF_TEXT_FG, Tk_Offset(TkText, fgColor), 0}, < {TK_CONFIG_PIXELS, "-height", "height", "Height", < DEF_TEXT_HEIGHT, Tk_Offset(TkText, height), 0}, < {TK_CONFIG_COLOR, "-highlightbackground", "highlightBackground", < "HighlightBackground", DEF_TEXT_HIGHLIGHT_BG, < Tk_Offset(TkText, highlightBgColorPtr), 0}, < {TK_CONFIG_COLOR, "-highlightcolor", "highlightColor", "HighlightColor", < DEF_TEXT_HIGHLIGHT, Tk_Offset(TkText, highlightColorPtr), 0}, < {TK_CONFIG_PIXELS, "-highlightthickness", "highlightThickness", < "HighlightThickness", < DEF_TEXT_HIGHLIGHT_WIDTH, Tk_Offset(TkText, highlightWidth), 0}, < {TK_CONFIG_BORDER, "-insertbackground", "insertBackground", "Foreground", < DEF_TEXT_INSERT_BG, Tk_Offset(TkText, insertBorder), 0}, < {TK_CONFIG_PIXELS, "-insertborderwidth", "insertBorderWidth", "BorderWidth", < DEF_TEXT_INSERT_BD_COLOR, Tk_Offset(TkText, insertBorderWidth), < TK_CONFIG_COLOR_ONLY}, < {TK_CONFIG_PIXELS, "-insertborderwidth", "insertBorderWidth", "BorderWidth", < DEF_TEXT_INSERT_BD_MONO, Tk_Offset(TkText, insertBorderWidth), < TK_CONFIG_MONO_ONLY}, < {TK_CONFIG_INT, "-insertofftime", "insertOffTime", "OffTime", < DEF_TEXT_INSERT_OFF_TIME, Tk_Offset(TkText, insertOffTime), 0}, < {TK_CONFIG_INT, "-insertontime", "insertOnTime", "OnTime", < DEF_TEXT_INSERT_ON_TIME, Tk_Offset(TkText, insertOnTime), 0}, < {TK_CONFIG_PIXELS, "-insertwidth", "insertWidth", "InsertWidth", < DEF_TEXT_INSERT_WIDTH, Tk_Offset(TkText, insertWidth), 0}, < {TK_CONFIG_INT, "-maxundo", "maxUndo", "MaxUndo", < DEF_TEXT_MAX_UNDO, Tk_Offset(TkText, maxUndo), 0}, < {TK_CONFIG_PIXELS, "-padx", "padX", "Pad", < DEF_TEXT_PADX, Tk_Offset(TkText, padX), 0}, < {TK_CONFIG_PIXELS, "-pady", "padY", "Pad", < DEF_TEXT_PADY, Tk_Offset(TkText, padY), 0}, < {TK_CONFIG_RELIEF, "-relief", "relief", "Relief", < DEF_TEXT_RELIEF, Tk_Offset(TkText, relief), 0}, < {TK_CONFIG_BORDER, "-selectbackground", "selectBackground", "Foreground", < DEF_TEXT_SELECT_COLOR, Tk_Offset(TkText, selBorder), < TK_CONFIG_COLOR_ONLY}, < {TK_CONFIG_BORDER, "-selectbackground", "selectBackground", "Foreground", < DEF_TEXT_SELECT_MONO, Tk_Offset(TkText, selBorder), < TK_CONFIG_MONO_ONLY}, < {TK_CONFIG_STRING, "-selectborderwidth", "selectBorderWidth", "BorderWidth", < DEF_TEXT_SELECT_BD_COLOR, Tk_Offset(TkText, selBdString), < TK_CONFIG_COLOR_ONLY|TK_CONFIG_NULL_OK}, < {TK_CONFIG_STRING, "-selectborderwidth", "selectBorderWidth", "BorderWidth", < DEF_TEXT_SELECT_BD_MONO, Tk_Offset(TkText, selBdString), < TK_CONFIG_MONO_ONLY|TK_CONFIG_NULL_OK}, < {TK_CONFIG_COLOR, "-selectforeground", "selectForeground", "Background", < DEF_TEXT_SELECT_FG_COLOR, Tk_Offset(TkText, selFgColorPtr), < TK_CONFIG_COLOR_ONLY}, < {TK_CONFIG_COLOR, "-selectforeground", "selectForeground", "Background", < DEF_TEXT_SELECT_FG_MONO, Tk_Offset(TkText, selFgColorPtr), < TK_CONFIG_MONO_ONLY}, < {TK_CONFIG_BOOLEAN, "-setgrid", "setGrid", "SetGrid", < DEF_TEXT_SET_GRID, Tk_Offset(TkText, setGrid), 0}, < {TK_CONFIG_PIXELS, "-spacing1", "spacing1", "Spacing", < DEF_TEXT_SPACING1, Tk_Offset(TkText, spacing1), < TK_CONFIG_DONT_SET_DEFAULT}, < {TK_CONFIG_PIXELS, "-spacing2", "spacing2", "Spacing", < DEF_TEXT_SPACING2, Tk_Offset(TkText, spacing2), < TK_CONFIG_DONT_SET_DEFAULT}, < {TK_CONFIG_PIXELS, "-spacing3", "spacing3", "Spacing", < DEF_TEXT_SPACING3, Tk_Offset(TkText, spacing3), < TK_CONFIG_DONT_SET_DEFAULT}, < {TK_CONFIG_CUSTOM, "-state", "state", "State", < DEF_TEXT_STATE, Tk_Offset(TkText, state), 0, &stateOption}, < {TK_CONFIG_STRING, "-tabs", "tabs", "Tabs", < DEF_TEXT_TABS, Tk_Offset(TkText, tabOptionString), TK_CONFIG_NULL_OK}, < {TK_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus", < DEF_TEXT_TAKE_FOCUS, Tk_Offset(TkText, takeFocus), < TK_CONFIG_NULL_OK}, < {TK_CONFIG_BOOLEAN, "-undo", "undo", "Undo", < DEF_TEXT_UNDO, Tk_Offset(TkText, undo), 0}, < {TK_CONFIG_INT, "-width", "width", "Width", < DEF_TEXT_WIDTH, Tk_Offset(TkText, width), 0}, < {TK_CONFIG_CUSTOM, "-wrap", "wrap", "Wrap", < DEF_TEXT_WRAP, Tk_Offset(TkText, wrapMode), 0, &textWrapModeOption}, < {TK_CONFIG_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand", < DEF_TEXT_XSCROLL_COMMAND, Tk_Offset(TkText, xScrollCmd), < TK_CONFIG_NULL_OK}, < {TK_CONFIG_STRING, "-yscrollcommand", "yScrollCommand", "ScrollCommand", < DEF_TEXT_YSCROLL_COMMAND, Tk_Offset(TkText, yScrollCmd), < TK_CONFIG_NULL_OK}, < {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL, < (char *) NULL, 0, 0} --- > static char *wrapStrings[] = { > "char", "none", "word", (char *) NULL 155,162c53 < * Boolean variable indicating whether or not special debugging code < * should be executed. < */ < < int tkTextDebug = 0; < < /* < * Custom options for handling "-wrap": --- > * Information used to parse text configuration options: 165,175c56,164 < static int WrapModeParseProc _ANSI_ARGS_((ClientData clientData, < Tcl_Interp *interp, Tk_Window tkwin, < CONST char *value, char *widgRec, int offset)); < static char * WrapModePrintProc _ANSI_ARGS_((ClientData clientData, < Tk_Window tkwin, char *widgRec, int offset, < Tcl_FreeProc **freeProcPtr)); < < Tk_CustomOption textWrapModeOption = { < WrapModeParseProc, < WrapModePrintProc, < (ClientData) NULL --- > static Tk_OptionSpec optionSpecs[] = { > {TK_OPTION_BOOLEAN, "-autoseparators", "autoSeparators", > "AutoSeparators", DEF_TEXT_AUTO_SEPARATORS, -1, > Tk_Offset(TkText, autoSeparators), 0, 0, 0}, > {TK_OPTION_BORDER, "-background", "background", "Background", > DEF_TEXT_BG_COLOR, -1, Tk_Offset(TkText, border), > 0, (ClientData) DEF_TEXT_BG_MONO, 0}, > {TK_OPTION_SYNONYM, "-bd", (char *) NULL, (char *) NULL, > (char *) NULL, 0, -1, 0, (ClientData) "-borderwidth", 0}, > {TK_OPTION_SYNONYM, "-bg", (char *) NULL, (char *) NULL, > (char *) NULL, 0, -1, 0, (ClientData) "-background", 0}, > {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", > DEF_TEXT_BORDER_WIDTH, -1, Tk_Offset(TkText, borderWidth), > 0, 0, 0}, > {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor", > DEF_TEXT_CURSOR, -1, Tk_Offset(TkText, cursor), > TK_OPTION_NULL_OK, 0, 0}, > {TK_OPTION_BOOLEAN, "-exportselection", "exportSelection", > "ExportSelection", DEF_TEXT_EXPORT_SELECTION, -1, > Tk_Offset(TkText, exportSelection), 0, 0, 0}, > {TK_OPTION_SYNONYM, "-fg", "foreground", (char *) NULL, > (char *) NULL, 0, -1, 0, (ClientData) "-foreground", 0}, > {TK_OPTION_FONT, "-font", "font", "Font", > DEF_TEXT_FONT, -1, Tk_Offset(TkText, tkfont), 0, 0, 0}, > {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground", > DEF_TEXT_FG, -1, Tk_Offset(TkText, fgColor), 0, > 0, 0}, > {TK_OPTION_PIXELS, "-height", "height", "Height", > DEF_TEXT_HEIGHT, -1, Tk_Offset(TkText, height), 0, 0, 0}, > {TK_OPTION_COLOR, "-highlightbackground", "highlightBackground", > "HighlightBackground", DEF_TEXT_HIGHLIGHT_BG, > -1, Tk_Offset(TkText, highlightBgColorPtr), > 0, 0, 0}, > {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor", > DEF_TEXT_HIGHLIGHT, -1, Tk_Offset(TkText, highlightColorPtr), > 0, 0, 0}, > {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness", > "HighlightThickness", DEF_TEXT_HIGHLIGHT_WIDTH, -1, > Tk_Offset(TkText, highlightWidth), 0, 0, 0}, > {TK_OPTION_BORDER, "-insertbackground", "insertBackground", "Foreground", > DEF_TEXT_INSERT_BG, > -1, Tk_Offset(TkText, insertBorder), > 0, 0, 0}, > {TK_OPTION_PIXELS, "-insertborderwidth", "insertBorderWidth", > "BorderWidth", DEF_TEXT_INSERT_BD_COLOR, -1, > Tk_Offset(TkText, insertBorderWidth), 0, > (ClientData) DEF_TEXT_INSERT_BD_MONO, 0}, > {TK_OPTION_INT, "-insertofftime", "insertOffTime", "OffTime", > DEF_TEXT_INSERT_OFF_TIME, -1, Tk_Offset(TkText, insertOffTime), > 0, 0, 0}, > {TK_OPTION_INT, "-insertontime", "insertOnTime", "OnTime", > DEF_TEXT_INSERT_ON_TIME, -1, Tk_Offset(TkText, insertOnTime), > 0, 0, 0}, > {TK_OPTION_PIXELS, "-insertwidth", "insertWidth", "InsertWidth", > DEF_TEXT_INSERT_WIDTH, -1, Tk_Offset(TkText, insertWidth), > 0, 0, 0}, > {TK_OPTION_INT, "-maxundo", "maxUndo", "MaxUndo", > DEF_TEXT_MAX_UNDO, -1, Tk_Offset(TkText, maxUndo), 0, 0, 0}, > {TK_OPTION_PIXELS, "-padx", "padX", "Pad", > DEF_TEXT_PADX, -1, Tk_Offset(TkText, padX), 0, 0, 0}, > {TK_OPTION_PIXELS, "-pady", "padY", "Pad", > DEF_TEXT_PADY, -1, Tk_Offset(TkText, padY), 0, 0, 0}, > {TK_OPTION_RELIEF, "-relief", "relief", "Relief", > DEF_TEXT_RELIEF, -1, Tk_Offset(TkText, relief), 0, 0, 0}, > {TK_OPTION_BORDER, "-selectbackground", "selectBackground", "Foreground", > DEF_TEXT_SELECT_COLOR, -1, Tk_Offset(TkText, selBorder), > 0, (ClientData) DEF_TEXT_SELECT_MONO, 0}, > {TK_OPTION_PIXELS, "-selectborderwidth", "selectBorderWidth", > "BorderWidth", DEF_TEXT_SELECT_BD_COLOR, > Tk_Offset(TkText, selBorderWidthPtr), > Tk_Offset(TkText, selBorderWidth), > TK_OPTION_NULL_OK, (ClientData) DEF_TEXT_SELECT_BD_MONO, 0}, > {TK_OPTION_COLOR, "-selectforeground", "selectForeground", "Background", > DEF_TEXT_SELECT_FG_COLOR, -1, Tk_Offset(TkText, selFgColorPtr), > 0, (ClientData) DEF_TEXT_SELECT_FG_MONO, 0}, > {TK_OPTION_BOOLEAN, "-setgrid", "setGrid", "SetGrid", > DEF_TEXT_SET_GRID, -1, Tk_Offset(TkText, setGrid), 0, 0, 0}, > {TK_OPTION_PIXELS, "-spacing1", "spacing1", "Spacing", > DEF_TEXT_SPACING1, -1, Tk_Offset(TkText, spacing1), > TK_OPTION_DONT_SET_DEFAULT, 0 , 0 }, > {TK_OPTION_PIXELS, "-spacing2", "spacing2", "Spacing", > DEF_TEXT_SPACING2, -1, Tk_Offset(TkText, spacing2), > TK_OPTION_DONT_SET_DEFAULT, 0 , 0 }, > {TK_OPTION_PIXELS, "-spacing3", "spacing3", "Spacing", > DEF_TEXT_SPACING3, -1, Tk_Offset(TkText, spacing3), > TK_OPTION_DONT_SET_DEFAULT, 0 , 0 }, > {TK_OPTION_STRING_TABLE, "-state", "state", "State", > DEF_TEXT_STATE, -1, Tk_Offset(TkText, state), > 0, (ClientData) stateStrings, 0}, > {TK_OPTION_STRING, "-tabs", "tabs", "Tabs", > DEF_TEXT_TABS, Tk_Offset(TkText, tabOptionPtr), -1, > TK_OPTION_NULL_OK, 0, 0}, > {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus", > DEF_TEXT_TAKE_FOCUS, -1, Tk_Offset(TkText, takeFocus), > TK_OPTION_NULL_OK, 0, 0}, > {TK_OPTION_BOOLEAN, "-undo", "undo", "Undo", > DEF_TEXT_UNDO, -1, Tk_Offset(TkText, undo), 0, 0 , 0}, > {TK_OPTION_INT, "-width", "width", "Width", > DEF_TEXT_WIDTH, -1, Tk_Offset(TkText, width), 0, 0, 0}, > {TK_OPTION_STRING_TABLE, "-wrap", "wrap", "Wrap", > DEF_TEXT_WRAP, -1, Tk_Offset(TkText, wrapMode), > 0, (ClientData) wrapStrings, 0}, > {TK_OPTION_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand", > DEF_TEXT_XSCROLL_COMMAND, -1, Tk_Offset(TkText, xScrollCmd), > TK_OPTION_NULL_OK, 0, 0}, > {TK_OPTION_STRING, "-yscrollcommand", "yScrollCommand", "ScrollCommand", > DEF_TEXT_YSCROLL_COMMAND, -1, Tk_Offset(TkText, yScrollCmd), > TK_OPTION_NULL_OK, 0, 0}, > {TK_OPTION_END} 179,236c168,196 < *-------------------------------------------------------------- < * < * WrapModeParseProc -- < * < * This procedure is invoked during option processing to handle < * "-wrap" options for text widgets. < * < * Results: < * A standard Tcl return value. < * < * Side effects: < * The wrap mode for a given item gets replaced by the wrap mode < * indicated in the value argument. < * < *-------------------------------------------------------------- < */ < < static int < WrapModeParseProc(clientData, interp, tkwin, value, widgRec, offset) < ClientData clientData; /* some flags.*/ < Tcl_Interp *interp; /* Used for reporting errors. */ < Tk_Window tkwin; /* Window containing canvas widget. */ < CONST char *value; /* Value of option (list of tag < * names). */ < char *widgRec; /* Pointer to record for item. */ < int offset; /* Offset into item. */ < { < int c; < size_t length; < < register TkWrapMode *wrapPtr = (TkWrapMode *) (widgRec + offset); < < if(value == NULL || *value == 0) { < *wrapPtr = TEXT_WRAPMODE_NULL; < return TCL_OK; < } < < c = value[0]; < length = strlen(value); < < if ((c == 'c') && (strncmp(value, "char", length) == 0)) { < *wrapPtr = TEXT_WRAPMODE_CHAR; < return TCL_OK; < } < if ((c == 'n') && (strncmp(value, "none", length) == 0)) { < *wrapPtr = TEXT_WRAPMODE_NONE; < return TCL_OK; < } < if ((c == 'w') && (strncmp(value, "word", length) == 0)) { < *wrapPtr = TEXT_WRAPMODE_WORD; < return TCL_OK; < } < Tcl_AppendResult(interp, "bad wrap mode \"", value, < "\": must be char, none, or word", < (char *) NULL); < *wrapPtr = TEXT_WRAPMODE_CHAR; < return TCL_ERROR; < } --- > * The structure below holds information about a line-based search > * in the text widget. It is private to this file, at present. > * However, the first 12 fields in it are very generic and so this > * basic structure could be used for a more general line-based > * searching mechanism. > */ > > typedef struct TkLineSearchSpec { > int exact; /* Whether search is exact or regexp */ > int noCase; /* Case-insenstivive? */ > int all; /* Whether all or the first match should > * be reported */ > int startLine; /* First line to examine */ > int startOffset; /* Index in first line to start at */ > int stopLine; /* Last line to examine, or -1 when we > * search all available text */ > int stopOffset; /* Index to stop at, provided stopLine > * is not -1 */ > int numLines; /* Total lines which are available */ > int backwards; /* Searching forwards or backwards */ > Tcl_Obj *varPtr; /* If non-NULL, store length(s) of > * match(es) in this variable */ > Tcl_Obj *countPtr; /* Keeps track of currently found > * lengths */ > Tcl_Obj *resPtr; /* Keeps track of currently found > * locations */ > TkText *textPtr; /* Information about text widget. */ > int searchElide; /* Search in hidden text as well */ > } TkLineSearchSpec; 239,257c199,200 < *-------------------------------------------------------------- < * < * WrapModePrintProc -- < * < * This procedure is invoked by the Tk configuration code < * to produce a printable string for the "-wrap" configuration < * option for canvas items. < * < * Results: < * The return value is a string describing the state for < * the item referred to by "widgRec". In addition, *freeProcPtr < * is filled in with the address of a procedure to call to free < * the result string when it's no longer needed (or NULL to < * indicate that the string doesn't need to be freed). < * < * Side effects: < * None. < * < *-------------------------------------------------------------- --- > * Boolean variable indicating whether or not special debugging code > * should be executed. 260,281c203 < static char * < WrapModePrintProc(clientData, tkwin, widgRec, offset, freeProcPtr) < ClientData clientData; /* Ignored. */ < Tk_Window tkwin; /* Window containing canvas widget. */ < char *widgRec; /* Pointer to record for item. */ < int offset; /* Ignored. */ < Tcl_FreeProc **freeProcPtr; /* Pointer to variable to fill in with < * information about how to reclaim < * storage for return string. */ < { < register TkWrapMode *wrapPtr = (TkWrapMode *) (widgRec + offset); < < if (*wrapPtr==TEXT_WRAPMODE_CHAR) { < return "char"; < } else if (*wrapPtr==TEXT_WRAPMODE_NONE) { < return "none"; < } else if (*wrapPtr==TEXT_WRAPMODE_WORD) { < return "word"; < } else { < return ""; < } < } --- > int tkTextDebug = 0; 288,289c210 < TkText *textPtr, int argc, CONST char **argv, < int flags)); --- > TkText *textPtr, int objc, Tcl_Obj *CONST objv[])); 291,292c212,214 < CONST char *index1String, CONST char *index2String, < TkTextIndex *indexPtr1, TkTextIndex *indexPtr2)); --- > Tcl_Obj *index1Obj, Tcl_Obj *index2Obj, > CONST TkTextIndex *indexPtr1, > CONST TkTextIndex *indexPtr2)); 294,295c216,217 < static void InsertChars _ANSI_ARGS_((TkText *textPtr, < TkTextIndex *indexPtr, CONST char *string)); --- > static int InsertChars _ANSI_ARGS_((TkText *textPtr, > CONST TkTextIndex *indexPtr, Tcl_Obj *stringPtr)); 306c228,229 < Tcl_Interp *interp, int argc, CONST char **argv)); --- > Tcl_Interp *interp, > int objc, Tcl_Obj *CONST objv[])); 308,310c231,235 < Tcl_Interp *interp, int argc, CONST char **argv)); < static int TextWidgetCmd _ANSI_ARGS_((ClientData clientData, < Tcl_Interp *interp, int argc, CONST char **argv)); --- > Tcl_Interp *interp, > int objc, Tcl_Obj *CONST objv[])); > static int TextWidgetObjCmd _ANSI_ARGS_((ClientData clientData, > Tcl_Interp *interp, > int objc, Tcl_Obj *CONST objv[])); 314c239,240 < Tcl_Interp *interp, int argc, CONST char **argv)); --- > Tcl_Interp *interp, > int objc, Tcl_Obj *CONST objv[])); 321c247 < TkTextIndex *index, int what)); --- > CONST TkTextIndex *index, int what)); 324,326c250,274 < static void TextGetText _ANSI_ARGS_((TkTextIndex * index1, < TkTextIndex * index2, Tcl_DString *dsPtr)); < static void updateDirtyFlag _ANSI_ARGS_((TkText *textPtr)); --- > static Tcl_Obj* TextGetText _ANSI_ARGS_((CONST TkTextIndex * index1, > CONST TkTextIndex * index2)); > static void UpdateDirtyFlag _ANSI_ARGS_((TkText *textPtr)); > static void TextPushUndoAction _ANSI_ARGS_((TkText *textPtr, > Tcl_Obj *undoString, int insert, > CONST TkTextIndex *index1Ptr, > CONST TkTextIndex *index2Ptr)); > static int SearchFoundMatch _ANSI_ARGS_((int lineNum, > TkLineSearchSpec *searchSpecPtr, > ClientData clientData, Tcl_Obj *theLine, > int matchOffset, int matchLength)); > static ClientData SearchAddNextLine _ANSI_ARGS_((int lineNum, > TkLineSearchSpec *searchSpecPtr, > Tcl_Obj *theLine, int *lenPtr)); > static int SearchIndexInLine _ANSI_ARGS_(( > CONST TkLineSearchSpec *searchSpecPtr, > TkTextLine *linePtr, int byteIndex)); > static int SearchGetLineIndex _ANSI_ARGS_((Tcl_Interp *interp, > Tcl_Obj *objPtr, TkLineSearchSpec *searchSpecPtr, > int forwardWrap, int *linePosPtr, int *offsetPosPtr)); > static int PerformSearch _ANSI_ARGS_((Tcl_Interp *interp, > TkLineSearchSpec *searchSpecPtr, Tcl_Obj *patObj)); > > > 342c290 < * Tk_TextCmd -- --- > * Tk_TextObjCmd -- 357c305 < Tk_TextCmd(clientData, interp, argc, argv) --- > Tk_TextObjCmd(clientData, interp, objc, objv) 361,362c309,310 < int argc; /* Number of arguments. */ < CONST char **argv; /* Argument strings. */ --- > int objc; /* Number of arguments. */ > Tcl_Obj *CONST objv[]; /* Argument objects. */ 365a314 > Tk_OptionTable optionTable; 369,371c318,319 < if (argc < 2) { < Tcl_AppendResult(interp, "wrong # args: should be \"", < argv[0], " pathName ?options?\"", (char *) NULL); --- > if (objc < 2) { > Tcl_WrongNumArgs(interp, 1, objv, "pathName ?options?"); 379c327,328 < new = Tk_CreateWindowFromPath(interp, tkwin, argv[1], (char *) NULL); --- > new = Tk_CreateWindowFromPath(interp, tkwin, Tcl_GetString(objv[1]), > (char *) NULL); 395,396c344,345 < textPtr->widgetCmd = Tcl_CreateCommand(interp, < Tk_PathName(textPtr->tkwin), TextWidgetCmd, --- > textPtr->widgetCmd = Tcl_CreateObjCommand(interp, > Tk_PathName(textPtr->tkwin), TextWidgetObjCmd, 403c352 < textPtr->state = TK_STATE_NORMAL; --- > textPtr->state = TK_TEXT_STATE_NORMAL; 420c369,372 < --- > textPtr->tabOptionPtr = NULL; > textPtr->stateEpoch = 0; > textPtr->refCount = 1; > 424a377,380 > textPtr->selBorder = NULL; > textPtr->selBorderWidth = 0; > textPtr->selBorderWidthPtr = NULL; > textPtr->selFgColorPtr = NULL; 432a389,395 > /* > * Create the option table for this widget class. If it has already > * been created, the cached pointer will be returned. > */ > > optionTable = Tk_CreateOptionTable(interp, optionSpecs); > 434a398,399 > textPtr->optionTable = optionTable; > 444c409,415 < if (ConfigureText(interp, textPtr, argc-2, argv+2, 0) != TCL_OK) { --- > > if (Tk_InitOptions(interp, (char *) textPtr, optionTable, textPtr->tkwin) > != TCL_OK) { > Tk_DestroyWindow(textPtr->tkwin); > return TCL_ERROR; > } > if (ConfigureText(interp, textPtr, objc-2, objv+2) != TCL_OK) { 448d418 < Tcl_SetResult(interp, Tk_PathName(textPtr->tkwin), TCL_STATIC); 449a420,421 > Tcl_SetStringObj(Tcl_GetObjResult(interp), Tk_PathName(textPtr->tkwin), > -1); 456c428 < * TextWidgetCmd -- --- > * TextWidgetObjCmd -- 472c444 < TextWidgetCmd(clientData, interp, argc, argv) --- > TextWidgetObjCmd(clientData, interp, objc, objv) 475,476c447,448 < int argc; /* Number of arguments. */ < CONST char **argv; /* Argument strings. */ --- > int objc; /* Number of arguments. */ > Tcl_Obj *CONST objv[]; /* Argument objects. */ 479,481c451,470 < int c, result = TCL_OK; < size_t length; < TkTextIndex index1, index2; --- > int result = TCL_OK; > int index; > > static CONST char *optionStrings[] = { > "bbox", "cget", "compare", "configure", "debug", "delete", > "dlineinfo", "dump", "edit", "get", "image", "index", > "insert", "mark", "scan", "search", "see", "tag", > "window", "xview", "yview", (char *) NULL > }; > enum options { > TEXT_BBOX, TEXT_CGET, TEXT_COMPARE, TEXT_CONFIGURE, TEXT_DEBUG, > TEXT_DELETE, TEXT_DLINEINFO, TEXT_DUMP, TEXT_EDIT, TEXT_GET, > TEXT_IMAGE, TEXT_INDEX, TEXT_INSERT, TEXT_MARK, TEXT_SCAN, > TEXT_SEARCH, TEXT_SEE, TEXT_TAG, TEXT_WINDOW, TEXT_XVIEW, TEXT_YVIEW > }; > > if (objc < 2) { > Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?"); > return TCL_ERROR; > } 483,485c472,473 < if (argc < 2) { < Tcl_AppendResult(interp, "wrong # args: should be \"", < argv[0], " option ?arg arg ...?\"", (char *) NULL); --- > if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0, > &index) != TCL_OK) { 489,505c477,481 < c = argv[1][0]; < length = strlen(argv[1]); < if ((c == 'b') && (strncmp(argv[1], "bbox", length) == 0)) { < int x, y, width, height; < < if (argc != 3) { < Tcl_AppendResult(interp, "wrong # args: should be \"", < argv[0], " bbox index\"", (char *) NULL); < result = TCL_ERROR; < goto done; < } < if (TkTextGetIndex(interp, textPtr, argv[2], &index1) != TCL_OK) { < result = TCL_ERROR; < goto done; < } < if (TkTextCharBbox(textPtr, &index1, &x, &y, &width, &height) == 0) { < char buf[TCL_INTEGER_SPACE * 4]; --- > > switch ((enum options) index) { > case TEXT_BBOX: { > int x, y, width, height; > CONST TkTextIndex *indexPtr; 507,508c483,500 < sprintf(buf, "%d %d %d %d", x, y, width, height); < Tcl_SetResult(interp, buf, TCL_VOLATILE); --- > if (objc != 3) { > Tcl_WrongNumArgs(interp, 2, objv, "index"); > result = TCL_ERROR; > goto done; > } > indexPtr = TkTextGetIndexFromObj(interp, textPtr, objv[2]); > if (indexPtr == NULL) { > result = TCL_ERROR; > goto done; > } > if (TkTextCharBbox(textPtr, indexPtr, &x, &y, > &width, &height) == 0) { > char buf[TCL_INTEGER_SPACE * 4]; > > sprintf(buf, "%d %d %d %d", x, y, width, height); > Tcl_SetResult(interp, buf, TCL_VOLATILE); > } > break; 510,548c502,532 < } else if ((c == 'c') && (strncmp(argv[1], "cget", length) == 0) < && (length >= 2)) { < if (argc != 3) { < Tcl_AppendResult(interp, "wrong # args: should be \"", < argv[0], " cget option\"", < (char *) NULL); < result = TCL_ERROR; < goto done; < } < result = Tk_ConfigureValue(interp, textPtr->tkwin, configSpecs, < (char *) textPtr, argv[2], 0); < } else if ((c == 'c') && (strncmp(argv[1], "compare", length) == 0) < && (length >= 3)) { < int relation, value; < CONST char *p; < < if (argc != 5) { < Tcl_AppendResult(interp, "wrong # args: should be \"", < argv[0], " compare index1 op index2\"", (char *) NULL); < result = TCL_ERROR; < goto done; < } < if ((TkTextGetIndex(interp, textPtr, argv[2], &index1) != TCL_OK) < || (TkTextGetIndex(interp, textPtr, argv[4], &index2) < != TCL_OK)) { < result = TCL_ERROR; < goto done; < } < relation = TkTextIndexCmp(&index1, &index2); < p = argv[3]; < if (p[0] == '<') { < value = (relation < 0); < if ((p[1] == '=') && (p[2] == 0)) { < value = (relation <= 0); < } else if (p[1] != 0) { < compareError: < Tcl_AppendResult(interp, "bad comparison operator \"", < argv[3], "\": must be <, <=, ==, >=, >, or !=", < (char *) NULL); --- > case TEXT_CGET: { > if (objc != 3) { > Tcl_WrongNumArgs(interp, 2, objv, "option"); > result = TCL_ERROR; > goto done; > } else { > Tcl_Obj *objPtr = Tk_GetOptionValue(interp, (char *) textPtr, > textPtr->optionTable, objv[2], textPtr->tkwin); > if (objPtr == NULL) { > result = TCL_ERROR; > goto done; > } else { > Tcl_SetObjResult(interp, objPtr); > result = TCL_OK; > } > } > break; > } > case TEXT_COMPARE: { > int relation, value; > CONST char *p; > CONST TkTextIndex *index1Ptr, *index2Ptr; > > if (objc != 5) { > Tcl_WrongNumArgs(interp, 2, objv, "index1 op index2"); > result = TCL_ERROR; > goto done; > } > index1Ptr = TkTextGetIndexFromObj(interp, textPtr, objv[2]); > index2Ptr = TkTextGetIndexFromObj(interp, textPtr, objv[4]); > if (index1Ptr == NULL || index2Ptr == NULL) { 552,556c536,562 < } else if (p[0] == '>') { < value = (relation > 0); < if ((p[1] == '=') && (p[2] == 0)) { < value = (relation >= 0); < } else if (p[1] != 0) { --- > relation = TkTextIndexCmp(index1Ptr, index2Ptr); > p = Tcl_GetString(objv[3]); > if (p[0] == '<') { > value = (relation < 0); > if ((p[1] == '=') && (p[2] == 0)) { > value = (relation <= 0); > } else if (p[1] != 0) { > compareError: > Tcl_AppendResult(interp, "bad comparison operator \"", > Tcl_GetString(objv[3]), > "\": must be <, <=, ==, >=, >, or !=", > (char *) NULL); > result = TCL_ERROR; > goto done; > } > } else if (p[0] == '>') { > value = (relation > 0); > if ((p[1] == '=') && (p[2] == 0)) { > value = (relation >= 0); > } else if (p[1] != 0) { > goto compareError; > } > } else if ((p[0] == '=') && (p[1] == '=') && (p[2] == 0)) { > value = (relation == 0); > } else if ((p[0] == '!') && (p[1] == '=') && (p[2] == 0)) { > value = (relation != 0); > } else { 559,564c565,566 < } else if ((p[0] == '=') && (p[1] == '=') && (p[2] == 0)) { < value = (relation == 0); < } else if ((p[0] == '!') && (p[1] == '=') && (p[2] == 0)) { < value = (relation != 0); < } else { < goto compareError; --- > Tcl_SetObjResult(interp, Tcl_NewBooleanObj(value)); > break; 566,577c568,583 < Tcl_SetResult(interp, ((value) ? "1" : "0"), TCL_STATIC); < } else if ((c == 'c') && (strncmp(argv[1], "configure", length) == 0) < && (length >= 3)) { < if (argc == 2) { < result = Tk_ConfigureInfo(interp, textPtr->tkwin, configSpecs, < (char *) textPtr, (char *) NULL, 0); < } else if (argc == 3) { < result = Tk_ConfigureInfo(interp, textPtr->tkwin, configSpecs, < (char *) textPtr, argv[2], 0); < } else { < result = ConfigureText(interp, textPtr, argc-2, argv+2, < TK_CONFIG_ARGV_ONLY); --- > case TEXT_CONFIGURE: { > if (objc <= 3) { > Tcl_Obj* objPtr = Tk_GetOptionInfo(interp, (char *) textPtr, > textPtr->optionTable, > (objc == 3) ? objv[2] : (Tcl_Obj *) NULL, > textPtr->tkwin); > if (objPtr == NULL) { > result = TCL_ERROR; > goto done; > } else { > Tcl_SetObjResult(interp, objPtr); > } > } else { > result = ConfigureText(interp, textPtr, objc-2, objv+2); > } > break; 579,585c585,601 < } else if ((c == 'd') && (strncmp(argv[1], "debug", length) == 0) < && (length >= 3)) { < if (argc > 3) { < Tcl_AppendResult(interp, "wrong # args: should be \"", < argv[0], " debug boolean\"", (char *) NULL); < result = TCL_ERROR; < goto done; --- > case TEXT_DEBUG: { > if (objc > 3) { > Tcl_WrongNumArgs(interp, 2, objv, "boolean"); > result = TCL_ERROR; > goto done; > } > if (objc == 2) { > Tcl_SetObjResult(interp, Tcl_NewBooleanObj(tkBTreeDebug)); > } else { > if (Tcl_GetBooleanFromObj(interp, objv[2], > &tkBTreeDebug) != TCL_OK) { > result = TCL_ERROR; > goto done; > } > tkTextDebug = tkBTreeDebug; > } > break; 587,590c603,730 < if (argc == 2) { < Tcl_SetResult(interp, ((tkBTreeDebug) ? "1" : "0"), TCL_STATIC); < } else { < if (Tcl_GetBoolean(interp, argv[2], &tkBTreeDebug) != TCL_OK) { --- > case TEXT_DELETE: { > if (objc < 3) { > Tcl_WrongNumArgs(interp, 2, objv, "index1 ?index2 ...?"); > result = TCL_ERROR; > goto done; > } > if (textPtr->state == TK_TEXT_STATE_NORMAL) { > if (objc < 5) { > /* > * Simple case requires no predetermination of indices. > */ > result = DeleteChars(textPtr, objv[2], > (objc == 4) ? objv[3] : NULL, NULL, NULL); > } else { > int i; > /* > * Multi-index pair case requires that we prevalidate > * the indices and sort from last to first so that > * deletes occur in the exact (unshifted) text. It > * also needs to handle partial and fully overlapping > * ranges. We have to do this with multiple passes. > */ > TkTextIndex *indices, *ixStart, *ixEnd; > TkTextIndex *lastStart, *lastEnd; > char *useIdx; > > objc -= 2; > objv += 2; > indices = (TkTextIndex *) > ckalloc((objc + 1) * sizeof(TkTextIndex)); > > /* > * First pass verifies that all indices are valid. > */ > for (i = 0; i < objc; i++) { > CONST TkTextIndex *indexPtr = > TkTextGetIndexFromObj(interp, textPtr, objv[i]); > > if (indexPtr == NULL) { > result = TCL_ERROR; > ckfree((char *) indices); > goto done; > } > indices[i] = *indexPtr; > } > /* > * Pad out the pairs evenly to make later code easier. > */ > if (objc & 1) { > indices[i] = indices[i-1]; > TkTextIndexForwChars(&indices[i], 1, &indices[i]); > objc++; > } > useIdx = (char *) ckalloc((unsigned) objc); > memset(useIdx, 0, (unsigned) objc); > /* > * Do a decreasing order sort so that we delete the end > * ranges first to maintain index consistency. > */ > qsort((VOID *) indices, (unsigned) (objc / 2), > 2 * sizeof(TkTextIndex), TextIndexSortProc); > lastStart = lastEnd = NULL; > /* > * Second pass will handle bogus ranges (end < start) and > * overlapping ranges. > */ > for (i = 0; i < objc; i += 2) { > ixStart = &indices[i]; > ixEnd = &indices[i+1]; > if (TkTextIndexCmp(ixEnd, ixStart) <= 0) { > continue; > } > if (lastStart) { > if (TkTextIndexCmp(ixStart, lastStart) == 0) { > /* > * Start indices were equal, and the sort > * placed the longest range first, so > * skip this one. > */ > continue; > } else if (TkTextIndexCmp(lastStart, ixEnd) < 0) { > /* > * The next pair has a start range before > * the end point of the last range. > * Constrain the delete range, but use > * the pointer values. > */ > *ixEnd = *lastStart; > if (TkTextIndexCmp(ixEnd, ixStart) <= 0) { > continue; > } > } > } > lastStart = ixStart; > lastEnd = ixEnd; > useIdx[i] = 1; > } > /* > * Final pass take the input from the previous and > * deletes the ranges which are flagged to be > * deleted. > */ > for (i = 0; i < objc; i += 2) { > if (useIdx[i]) { > /* > * We don't need to check the return value > * because all indices are preparsed above. > */ > DeleteChars(textPtr, NULL, NULL, > &indices[i], &indices[i+1]); > } > } > ckfree((char *) indices); > } > } > break; > } > case TEXT_DLINEINFO: { > int x, y, width, height, base; > CONST TkTextIndex *indexPtr; > > if (objc != 3) { > Tcl_WrongNumArgs(interp, 2, objv, "index"); > result = TCL_ERROR; > goto done; > } > indexPtr = TkTextGetIndexFromObj(interp, textPtr, objv[2]); > if (indexPtr == NULL) { 594c734,741 < tkTextDebug = tkBTreeDebug; --- > if (TkTextDLineInfo(textPtr, indexPtr, &x, &y, &width, > &height, &base) == 0) { > char buf[TCL_INTEGER_SPACE * 5]; > > sprintf(buf, "%d %d %d %d %d", x, y, width, height, base); > Tcl_SetResult(interp, buf, TCL_VOLATILE); > } > break; 596,604c743,745 < } else if ((c == 'd') && (strncmp(argv[1], "delete", length) == 0) < && (length >= 3)) { < int i; < < if (argc < 3) { < Tcl_AppendResult(interp, "wrong # args: should be \"", < argv[0], " delete index1 ?index2 ...?\"", (char *) NULL); < result = TCL_ERROR; < goto done; --- > case TEXT_DUMP: { > result = TextDumpCmd(textPtr, interp, objc, objv); > break; 606,627c747,753 < if (textPtr->state == TK_STATE_NORMAL) { < if (argc < 5) { < /* < * Simple case requires no predetermination of indices. < */ < result = DeleteChars(textPtr, argv[2], < (argc == 4) ? argv[3] : NULL, NULL, NULL); < } else { < /* < * Multi-index pair case requires that we prevalidate the < * indices and sort from last to first so that deletes < * occur in the exact (unshifted) text. It also needs to < * handle partial and fully overlapping ranges. We have to < * do this with multiple passes. < */ < TkTextIndex *indices, *ixStart, *ixEnd, *lastStart, *lastEnd; < char *useIdx; < < argc -= 2; < argv += 2; < indices = (TkTextIndex *) < ckalloc((argc + 1) * sizeof(TkTextIndex)); --- > case TEXT_EDIT: { > result = TextEditCmd(textPtr, interp, objc, objv); > break; > } > case TEXT_GET: { > Tcl_Obj *objPtr = NULL; > int i, found = 0; 629,634c755,781 < /* < * First pass verifies that all indices are valid. < */ < for (i = 0; i < argc; i++) { < if (TkTextGetIndex(interp, textPtr, argv[i], < &indices[i]) != TCL_OK) { --- > if (objc < 3) { > Tcl_WrongNumArgs(interp, 2, objv, "index1 ?index2 ...?"); > result = TCL_ERROR; > goto done; > } > for (i = 2; i < objc; i += 2) { > CONST TkTextIndex *index1Ptr, *index2Ptr; > TkTextIndex index2; > > index1Ptr = TkTextGetIndexFromObj(interp, textPtr, objv[i]); > if (index1Ptr == NULL) { > if (objPtr) { > Tcl_DecrRefCount(objPtr); > } > result = TCL_ERROR; > goto done; > } > if (i+1 == objc) { > TkTextIndexForwChars(index1Ptr, 1, &index2); > index2Ptr = &index2; > } else { > index2Ptr = TkTextGetIndexFromObj(interp, textPtr, > objv[i+1]); > if (index2Ptr == NULL) { > if (objPtr) { > Tcl_DecrRefCount(objPtr); > } 636d782 < ckfree((char *) indices); 640,674c786,798 < /* < * Pad out the pairs evenly to make later code easier. < */ < if (argc & 1) { < indices[i] = indices[i-1]; < TkTextIndexForwChars(&indices[i], 1, &indices[i]); < argc++; < } < useIdx = (char *) ckalloc((unsigned) argc); < memset(useIdx, 0, (unsigned) argc); < /* < * Do a decreasing order sort so that we delete the end < * ranges first to maintain index consistency. < */ < qsort((VOID *) indices, (unsigned) (argc / 2), < 2 * sizeof(TkTextIndex), TextIndexSortProc); < lastStart = lastEnd = NULL; < /* < * Second pass will handle bogus ranges (end < start) and < * overlapping ranges. < */ < for (i = 0; i < argc; i += 2) { < ixStart = &indices[i]; < ixEnd = &indices[i+1]; < if (TkTextIndexCmp(ixEnd, ixStart) <= 0) { < continue; < } < if (lastStart) { < if (TkTextIndexCmp(ixStart, lastStart) == 0) { < /* < * Start indices were equal, and the sort placed < * the longest range first, so skip this one. < */ < continue; < } else if (TkTextIndexCmp(lastStart, ixEnd) < 0) { --- > if (TkTextIndexCmp(index1Ptr, index2Ptr) < 0) { > /* > * We want to move the text we get from the window > * into the result, but since this could in principle > * be a megabyte or more, we want to do it > * efficiently! > */ > Tcl_Obj *get = TextGetText(index1Ptr, index2Ptr); > found++; > if (found == 1) { > Tcl_SetObjResult(interp, get); > } else { > if (found == 2) { 676,678c800,801 < * The next pair has a start range before the end < * point of the last range. Constrain the delete < * range, but use the pointer values. --- > * Move the first item we put into the result into > * the first element of the list object. 680,683c803,805 < *ixEnd = *lastStart; < if (TkTextIndexCmp(ixEnd, ixStart) <= 0) { < continue; < } --- > objPtr = Tcl_NewObj(); > Tcl_ListObjAppendElement(NULL, objPtr, > Tcl_GetObjResult(interp)); 685,701c807 < } < lastStart = ixStart; < lastEnd = ixEnd; < useIdx[i] = 1; < } < /* < * Final pass take the input from the previous and deletes < * the ranges which are flagged to be deleted. < */ < for (i = 0; i < argc; i += 2) { < if (useIdx[i]) { < /* < * We don't need to check the return value because all < * indices are preparsed above. < */ < DeleteChars(textPtr, NULL, NULL, < &indices[i], &indices[i+1]); --- > Tcl_ListObjAppendElement(NULL, objPtr, get); 704d809 < ckfree((char *) indices); 705a811,814 > if (found > 1) { > Tcl_SetObjResult(interp, objPtr); > } > break; 707,726c816,818 < } else if ((c == 'd') && (strncmp(argv[1], "dlineinfo", length) == 0) < && (length >= 2)) { < int x, y, width, height, base; < < if (argc != 3) { < Tcl_AppendResult(interp, "wrong # args: should be \"", < argv[0], " dlineinfo index\"", (char *) NULL); < result = TCL_ERROR; < goto done; < } < if (TkTextGetIndex(interp, textPtr, argv[2], &index1) != TCL_OK) { < result = TCL_ERROR; < goto done; < } < if (TkTextDLineInfo(textPtr, &index1, &x, &y, &width, &height, &base) < == 0) { < char buf[TCL_INTEGER_SPACE * 5]; < < sprintf(buf, "%d %d %d %d %d", x, y, width, height, base); < Tcl_SetResult(interp, buf, TCL_VOLATILE); --- > case TEXT_IMAGE: { > result = TkTextImageCmd(textPtr, interp, objc, objv); > break; 728,739c820,835 < } else if ((c == 'e') && (strncmp(argv[1], "edit", length) == 0)) { < result = TextEditCmd(textPtr, interp, argc, argv); < } else if ((c == 'g') && (strncmp(argv[1], "get", length) == 0)) { < Tcl_Obj *objPtr = NULL; < Tcl_DString ds; < int i, found = 0; < < if (argc < 3) { < Tcl_AppendResult(interp, "wrong # args: should be \"", < argv[0], " get index1 ?index2 ...?\"", (char *) NULL); < result = TCL_ERROR; < goto done; --- > case TEXT_INDEX: { > CONST TkTextIndex *indexPtr; > > if (objc != 3) { > Tcl_WrongNumArgs(interp, 2, objv, "index"); > result = TCL_ERROR; > goto done; > } > > indexPtr = TkTextGetIndexFromObj(interp, textPtr, objv[2]); > if (indexPtr == NULL) { > result = TCL_ERROR; > goto done; > } > Tcl_SetObjResult(interp, TkTextNewIndexObj(textPtr, indexPtr)); > break; 741,742c837,846 < for (i = 2; i < argc; i += 2) { < if (TkTextGetIndex(interp, textPtr, argv[i], &index1) != TCL_OK) { --- > case TEXT_INSERT: { > int i, j, numTags; > Tcl_Obj **tagNamePtrs; > TkTextTag **oldTagArrayPtr; > CONST TkTextIndex *indexPtr; > TkTextIndex index1, index2; > > if (objc < 4) { > Tcl_WrongNumArgs(interp, 2, objv, > "index chars ?tagList chars tagList ...?"); 746,753c850,851 < if (i+1 == argc) { < index2 = index1; < TkTextIndexForwChars(&index2, 1, &index2); < } else if (TkTextGetIndex(interp, textPtr, argv[i+1], &index2) < != TCL_OK) { < if (objPtr) { < Tcl_DecrRefCount(objPtr); < } --- > indexPtr = TkTextGetIndexFromObj(interp, textPtr, objv[2]); > if (indexPtr == NULL) { 757,829c855,874 < if (TkTextIndexCmp(&index1, &index2) < 0) { < /* < * Place the text in a DString and move it to the result. < * Since this could in principle be a megabyte or more, we < * want to do it efficiently! < */ < TextGetText(&index1, &index2, &ds); < found++; < if (found == 1) { < Tcl_DStringResult(interp, &ds); < } else { < if (found == 2) { < /* < * Move the first item we put into the result into < * the first element of the list object. < */ < objPtr = Tcl_NewObj(); < Tcl_ListObjAppendElement(NULL, objPtr, < Tcl_GetObjResult(interp)); < } < Tcl_ListObjAppendElement(NULL, objPtr, < Tcl_NewStringObj(Tcl_DStringValue(&ds), < Tcl_DStringLength(&ds))); < } < Tcl_DStringFree(&ds); < } < } < if (found > 1) { < Tcl_SetObjResult(interp, objPtr); < } < } else if ((c == 'i') && (strncmp(argv[1], "index", length) == 0) < && (length >= 3)) { < char buf[200]; < < if (argc != 3) { < Tcl_AppendResult(interp, "wrong # args: should be \"", < argv[0], " index index\"", < (char *) NULL); < result = TCL_ERROR; < goto done; < } < if (TkTextGetIndex(interp, textPtr, argv[2], &index1) != TCL_OK) { < result = TCL_ERROR; < goto done; < } < TkTextPrintIndex(&index1, buf); < Tcl_SetResult(interp, buf, TCL_VOLATILE); < } else if ((c == 'i') && (strncmp(argv[1], "insert", length) == 0) < && (length >= 3)) { < int i, j, numTags; < CONST char **tagNames; < TkTextTag **oldTagArrayPtr; < < if (argc < 4) { < Tcl_AppendResult(interp, "wrong # args: should be \"", < argv[0], < " insert index chars ?tagList chars tagList ...?\"", < (char *) NULL); < result = TCL_ERROR; < goto done; < } < if (TkTextGetIndex(interp, textPtr, argv[2], &index1) != TCL_OK) { < result = TCL_ERROR; < goto done; < } < if (textPtr->state == TK_STATE_NORMAL) { < for (j = 3; j < argc; j += 2) { < InsertChars(textPtr, &index1, argv[j]); < if (argc > (j+1)) { < TkTextIndexForwBytes(&index1, (int) strlen(argv[j]), < &index2); < oldTagArrayPtr = TkBTreeGetTags(&index1, &numTags); < if (oldTagArrayPtr != NULL) { --- > if (textPtr->state == TK_TEXT_STATE_NORMAL) { > index1 = *indexPtr; > for (j = 3; j < objc; j += 2) { > int length = InsertChars(textPtr, &index1, objv[j]); > if (objc > (j+1)) { > TkTextIndexForwBytes(&index1, length, &index2); > oldTagArrayPtr = TkBTreeGetTags(&index1, &numTags); > if (oldTagArrayPtr != NULL) { > for (i = 0; i < numTags; i++) { > TkBTreeTag(&index1, &index2, > oldTagArrayPtr[i], 0); > } > ckfree((char *) oldTagArrayPtr); > } > if (Tcl_ListObjGetElements(interp, objv[j+1], > &numTags, &tagNamePtrs) > != TCL_OK) { > result = TCL_ERROR; > goto done; > } 831c876,878 < TkBTreeTag(&index1, &index2, oldTagArrayPtr[i], 0); --- > TkBTreeTag(&index1, &index2, > TkTextCreateTag(textPtr, > Tcl_GetString(tagNamePtrs[i])), 1); 833,842c880 < ckfree((char *) oldTagArrayPtr); < } < if (Tcl_SplitList(interp, argv[j+1], &numTags, &tagNames) < != TCL_OK) { < result = TCL_ERROR; < goto done; < } < for (i = 0; i < numTags; i++) { < TkBTreeTag(&index1, &index2, < TkTextCreateTag(textPtr, tagNames[i]), 1); --- > index1 = index2; 844,845d881 < ckfree((char *) tagNames); < index1 = index2; 847a884,916 > break; > } > case TEXT_MARK: { > result = TkTextMarkCmd(textPtr, interp, objc, objv); > break; > } > case TEXT_SCAN: { > result = TkTextScanCmd(textPtr, interp, objc, objv); > break; > } > case TEXT_SEARCH: { > result = TextSearchCmd(textPtr, interp, objc, objv); > break; > } > case TEXT_SEE: { > result = TkTextSeeCmd(textPtr, interp, objc, objv); > break; > } > case TEXT_TAG: { > result = TkTextTagCmd(textPtr, interp, objc, objv); > break; > } > case TEXT_WINDOW: { > result = TkTextWindowCmd(textPtr, interp, objc, objv); > break; > } > case TEXT_XVIEW: { > result = TkTextXviewCmd(textPtr, interp, objc, objv); > break; > } > case TEXT_YVIEW: { > result = TkTextYviewCmd(textPtr, interp, objc, objv); > break; 849,877d917 < } else if ((c == 'd') && (strncmp(argv[1], "dump", length) == 0)) { < result = TextDumpCmd(textPtr, interp, argc, argv); < } else if ((c == 'i') && (strncmp(argv[1], "image", length) == 0)) { < result = TkTextImageCmd(textPtr, interp, argc, argv); < } else if ((c == 'm') && (strncmp(argv[1], "mark", length) == 0)) { < result = TkTextMarkCmd(textPtr, interp, argc, argv); < } else if ((c == 's') && (strcmp(argv[1], "scan") == 0) && (length >= 2)) { < result = TkTextScanCmd(textPtr, interp, argc, argv); < } else if ((c == 's') && (strcmp(argv[1], "search") == 0) < && (length >= 3)) { < result = TextSearchCmd(textPtr, interp, argc, argv); < } else if ((c == 's') && (strcmp(argv[1], "see") == 0) && (length >= 3)) { < result = TkTextSeeCmd(textPtr, interp, argc, argv); < } else if ((c == 't') && (strcmp(argv[1], "tag") == 0)) { < result = TkTextTagCmd(textPtr, interp, argc, argv); < } else if ((c == 'w') && (strncmp(argv[1], "window", length) == 0)) { < result = TkTextWindowCmd(textPtr, interp, argc, argv); < } else if ((c == 'x') && (strncmp(argv[1], "xview", length) == 0)) { < result = TkTextXviewCmd(textPtr, interp, argc, argv); < } else if ((c == 'y') && (strncmp(argv[1], "yview", length) == 0) < && (length >= 2)) { < result = TkTextYviewCmd(textPtr, interp, argc, argv); < } else { < Tcl_AppendResult(interp, "bad option \"", argv[1], < "\": must be bbox, cget, compare, configure, debug, delete, ", < "dlineinfo, dump, edit, get, image, index, insert, mark, ", < "scan, search, see, tag, window, xview, or yview", < (char *) NULL); < result = TCL_ERROR; 879c919 < --- > 956,960c996,1001 < * Free up all the stuff that requires special handling, then < * let Tk_FreeOptions handle all the standard option-related < * stuff. Special note: free up display-related information < * before deleting the B-tree, since display-related stuff < * may refer to stuff in the B-tree. --- > * Free up all the stuff that requires special handling. We have > * already called let Tk_FreeConfigOptions to handle all the standard > * option-related stuff (and so none of that exists when we are > * called). Special note: free up display-related information before > * deleting the B-tree, since display-related stuff may refer to > * stuff in the B-tree. 987,997c1028,1031 < /* < * NOTE: do NOT free up selBorder, selBdString, or selFgColorPtr: < * they are duplicates of information in the "sel" tag, which was < * freed up as part of deleting the tags above. < */ < < textPtr->selBorder = NULL; < textPtr->selBdString = NULL; < textPtr->selFgColorPtr = NULL; < Tk_FreeOptions(configSpecs, (char *) textPtr, textPtr->display, 0); < ckfree((char *) textPtr); --- > textPtr->refCount--; > if (textPtr->refCount == 0) { > ckfree((char *) textPtr); > } 1005c1039 < * This procedure is called to process an argv/argc list, plus --- > * This procedure is called to process an objv/objc list, plus 1022c1056 < ConfigureText(interp, textPtr, argc, argv, flags) --- > ConfigureText(interp, textPtr, objc, objv) 1026,1028c1060,1061 < int argc; /* Number of valid entries in argv. */ < CONST char **argv; /* Arguments. */ < int flags; /* Flags to pass to Tk_ConfigureWidget. */ --- > int objc; /* Number of arguments. */ > Tcl_Obj *CONST objv[]; /* Argument objects. */ 1029a1063 > Tk_SavedOptions savedOptions; 1032,1033c1066,1067 < if (Tk_ConfigureWidget(interp, textPtr->tkwin, configSpecs, < argc, argv, (char *) textPtr, flags) != TCL_OK) { --- > if (Tk_SetOptions(interp, (char*)textPtr, textPtr->optionTable, > objc, objv, textPtr->tkwin, &savedOptions, NULL) != TCL_OK) { 1068c1102 < if (textPtr->tabOptionString != NULL) { --- > if (textPtr->tabOptionPtr != NULL) { 1070c1104 < textPtr->tabOptionString); --- > textPtr->tabOptionPtr); 1072a1107 > Tk_RestoreSavedOptions(&savedOptions); 1086,1096c1121,1123 < if (textPtr->selTagPtr->bdString != textPtr->selBdString) { < textPtr->selTagPtr->bdString = textPtr->selBdString; < if (textPtr->selBdString != NULL) { < if (Tk_GetPixels(interp, textPtr->tkwin, textPtr->selBdString, < &textPtr->selTagPtr->borderWidth) != TCL_OK) { < return TCL_ERROR; < } < if (textPtr->selTagPtr->borderWidth < 0) { < textPtr->selTagPtr->borderWidth = 0; < } < } --- > if (textPtr->selTagPtr->borderWidthPtr != textPtr->selBorderWidthPtr) { > textPtr->selTagPtr->borderWidthPtr = textPtr->selBorderWidthPtr; > textPtr->selTagPtr->borderWidth = textPtr->selBorderWidth; 1101c1128 < || (textPtr->selTagPtr->bdString != NULL) --- > || (textPtr->selTagPtr->borderWidth != 0) 1116c1143 < || (textPtr->selTagPtr->tabString != NULL) --- > || (textPtr->selTagPtr->tabStringPtr != NULL) 1166a1194 > Tk_FreeSavedOptions(&savedOptions); 1184c1212 < * Configures all tags in the Text with a empty argc/argv, for --- > * Configures all tags in the Text with a empty objc/objv, for 1262a1291,1302 > /* > * NOTE: we must zero out selBorder, selBorderWidthPtr and > * selFgColorPtr: they are duplicates of information in the > * "sel" tag, which will be freed up when we delete all tags. > * Hence we don't want the automatic config options freeing > * process to delete them as well. > */ > > textPtr->selBorder = NULL; > textPtr->selBorderWidthPtr = NULL; > textPtr->selBorderWidth = 0; > textPtr->selFgColorPtr = NULL; 1265a1306,1307 > Tk_FreeConfigOptions((char *) textPtr, textPtr->optionTable, > textPtr->tkwin); 1349c1391 < * None. --- > * The length of the inserted string. 1352c1394 < * The characters in "string" get added to the text just before --- > * The characters in "stringPtr" get added to the text just before 1358,1359c1400,1401 < static void < InsertChars(textPtr, indexPtr, string) --- > static int > InsertChars(textPtr, cIndexPtr, stringPtr) 1361c1403 < TkTextIndex *indexPtr; /* Where to insert new characters. May be --- > CONST TkTextIndex *cIndexPtr;/* Where to insert new characters. May be 1363c1405 < CONST char *string; /* Null-terminated string containing new --- > Tcl_Obj *stringPtr; /* Null-terminated string containing new 1367,1369c1409,1414 < TkTextIndex newTop; < char indexBuffer[TK_POS_CHARS]; < --- > TkTextIndex tempIndex; > TkTextIndex *indexPtr; > int length; > > CONST char *string = Tcl_GetStringFromObj(stringPtr, &length); > 1374c1419 < lineIndex = TkBTreeLineIndex(indexPtr->linePtr); --- > lineIndex = TkBTreeLineIndex(cIndexPtr->linePtr); 1377c1422,1424 < TkTextMakeByteIndex(textPtr->tree, lineIndex, 1000000, indexPtr); --- > TkTextMakeByteIndex(textPtr->tree, lineIndex, 1000000, &tempIndex); > } else { > tempIndex = *cIndexPtr; 1379c1426,1427 < --- > indexPtr = &tempIndex; > 1392c1440 < offset += strlen(string); --- > offset += length; 1395a1444 > textPtr->stateEpoch ++; 1402,1407c1451,1453 < if ( textPtr->undo ) { < TkTextIndex toIndex; < < Tcl_DString actionCommand; < Tcl_DString revertCommand; < --- > if (textPtr->undo) { > TkTextIndex toIndex; > 1414,1454d1459 < < Tcl_DStringInit(&actionCommand); < Tcl_DStringInit(&revertCommand); < < Tcl_DStringAppend(&actionCommand,Tcl_GetCommandName(textPtr->interp,textPtr->widgetCmd),-1); < Tcl_DStringAppend(&actionCommand," insert ",-1); < TkTextPrintIndex(indexPtr,indexBuffer); < Tcl_DStringAppend(&actionCommand,indexBuffer,-1); < Tcl_DStringAppend(&actionCommand," ",-1); < Tcl_DStringAppendElement(&actionCommand,string); < Tcl_DStringAppend(&actionCommand,";",-1); < Tcl_DStringAppend(&actionCommand,Tcl_GetCommandName(textPtr->interp,textPtr->widgetCmd),-1); < Tcl_DStringAppend(&actionCommand," mark set insert ",-1); < TkTextIndexForwBytes(indexPtr, (int) strlen(string), < &toIndex); < TkTextPrintIndex(&toIndex, indexBuffer); < Tcl_DStringAppend(&actionCommand,indexBuffer,-1); < Tcl_DStringAppend(&actionCommand,"; ",-1); < Tcl_DStringAppend(&actionCommand,Tcl_GetCommandName(textPtr->interp,textPtr->widgetCmd),-1); < Tcl_DStringAppend(&actionCommand," see insert",-1); < < Tcl_DStringAppend(&revertCommand,Tcl_GetCommandName(textPtr->interp,textPtr->widgetCmd),-1); < Tcl_DStringAppend(&revertCommand," delete ",-1); < TkTextPrintIndex(indexPtr,indexBuffer); < Tcl_DStringAppend(&revertCommand,indexBuffer,-1); < Tcl_DStringAppend(&revertCommand," ",-1); < TkTextPrintIndex(&toIndex, indexBuffer); < Tcl_DStringAppend(&revertCommand,indexBuffer,-1); < Tcl_DStringAppend(&revertCommand," ;",-1); < Tcl_DStringAppend(&revertCommand,Tcl_GetCommandName(textPtr->interp,textPtr->widgetCmd),-1); < Tcl_DStringAppend(&revertCommand," mark set insert ",-1); < TkTextPrintIndex(indexPtr,indexBuffer); < Tcl_DStringAppend(&revertCommand,indexBuffer,-1); < Tcl_DStringAppend(&revertCommand,"; ",-1); < Tcl_DStringAppend(&revertCommand,Tcl_GetCommandName(textPtr->interp,textPtr->widgetCmd),-1); < Tcl_DStringAppend(&revertCommand," see insert",-1); < < TkUndoPushAction(textPtr->undoStack,&actionCommand, &revertCommand); < < Tcl_DStringFree(&actionCommand); < Tcl_DStringFree(&revertCommand); 1455a1461,1462 > TkTextIndexForwBytes(indexPtr, length, &toIndex); > TextPushUndoAction(textPtr, stringPtr, 1, indexPtr, &toIndex); 1457c1464,1465 < updateDirtyFlag(textPtr); --- > > UpdateDirtyFlag(textPtr); 1459a1468 > TkTextIndex newTop; 1469a1479,1585 > > /* For convenience, return the length of the string */ > return length; > } > > /* > *---------------------------------------------------------------------- > * > * TextPushUndoAction -- > * > * Shared by insert and delete actions. Stores the appropriate > * scripts into our undo stack. We will add a single refCount to > * the 'undoString' object, so, if it previously had a refCount of > * zero, the caller should not free it. > * > * Results: > * None. > * > * Side effects: > * Items pushed onto stack. > * > *---------------------------------------------------------------------- > */ > > static void > TextPushUndoAction (textPtr, undoString, insert, index1Ptr, index2Ptr) > TkText *textPtr; /* Overall information about text widget. */ > Tcl_Obj *undoString; /* New text */ > int insert; /* 1 if insert, else delete */ > CONST TkTextIndex *index1Ptr;/* Index describing first location */ > CONST TkTextIndex *index2Ptr;/* Index describing second location */ > { > /* Create the helpers */ > Tcl_Obj *cmdNameObj = Tcl_NewObj(); > Tcl_Obj *seeInsertObj = Tcl_NewObj(); > Tcl_Obj *markSet1InsertObj = Tcl_NewObj(); > Tcl_Obj *markSet2InsertObj = Tcl_NewObj(); > Tcl_Obj *insertCmdObj = Tcl_NewObj(); > Tcl_Obj *deleteCmdObj = Tcl_NewObj(); > > Tcl_Obj *insertCmd = Tcl_NewObj(); > Tcl_Obj *deleteCmd = Tcl_NewObj(); > > /* Get the index positions */ > Tcl_Obj *index1Obj = TkTextNewIndexObj(textPtr, index1Ptr); > Tcl_Obj *index2Obj = TkTextNewIndexObj(textPtr, index2Ptr); > > /* Get the fully qualified name */ > Tcl_GetCommandFullName(textPtr->interp, textPtr->widgetCmd, cmdNameObj); > > /* These need refCounts, because they are used more than once below */ > Tcl_IncrRefCount(cmdNameObj); > Tcl_IncrRefCount(seeInsertObj); > Tcl_IncrRefCount(index1Obj); > Tcl_IncrRefCount(index2Obj); > > Tcl_ListObjAppendElement(NULL, seeInsertObj, cmdNameObj); > Tcl_ListObjAppendElement(NULL, seeInsertObj, Tcl_NewStringObj("see",3)); > Tcl_ListObjAppendElement(NULL, seeInsertObj, Tcl_NewStringObj("insert",6)); > > Tcl_ListObjAppendElement(NULL, markSet1InsertObj, cmdNameObj); > Tcl_ListObjAppendElement(NULL, markSet1InsertObj, > Tcl_NewStringObj("mark",4)); > Tcl_ListObjAppendElement(NULL, markSet1InsertObj, > Tcl_NewStringObj("set",3)); > Tcl_ListObjAppendElement(NULL, markSet1InsertObj, > Tcl_NewStringObj("insert",6)); > markSet2InsertObj = Tcl_DuplicateObj(markSet1InsertObj); > Tcl_ListObjAppendElement(NULL, markSet1InsertObj, index1Obj); > Tcl_ListObjAppendElement(NULL, markSet2InsertObj, index2Obj); > > Tcl_ListObjAppendElement(NULL, insertCmdObj, cmdNameObj); > Tcl_ListObjAppendElement(NULL, insertCmdObj, Tcl_NewStringObj("insert",6)); > Tcl_ListObjAppendElement(NULL, insertCmdObj, index1Obj); > /* Only use of 'undoString' */ > Tcl_ListObjAppendElement(NULL, insertCmdObj, undoString); > > Tcl_ListObjAppendElement(NULL, deleteCmdObj, cmdNameObj); > Tcl_ListObjAppendElement(NULL, deleteCmdObj, Tcl_NewStringObj("delete",6)); > Tcl_ListObjAppendElement(NULL, deleteCmdObj, index1Obj); > Tcl_ListObjAppendElement(NULL, deleteCmdObj, index2Obj); > > Tcl_ListObjAppendElement(NULL, insertCmd, insertCmdObj); > Tcl_ListObjAppendElement(NULL, insertCmd, markSet2InsertObj); > Tcl_ListObjAppendElement(NULL, insertCmd, seeInsertObj); > Tcl_ListObjAppendElement(NULL, deleteCmd, deleteCmdObj); > Tcl_ListObjAppendElement(NULL, deleteCmd, markSet1InsertObj); > Tcl_ListObjAppendElement(NULL, deleteCmd, seeInsertObj); > > Tcl_DecrRefCount(cmdNameObj); > Tcl_DecrRefCount(seeInsertObj); > Tcl_DecrRefCount(index1Obj); > Tcl_DecrRefCount(index2Obj); > > /* > * Depending whether the action is to insert or delete, we provide > * the appropriate second and third arguments to TkUndoPushAction. > * (The first is the 'actionCommand', and the second the > * 'revertCommand'). The final '1' says we are providing a list > * of scripts to execute rather than a single script. > */ > if (insert) { > TkUndoPushAction(textPtr->undoStack, insertCmd, deleteCmd, 1); > } else { > TkUndoPushAction(textPtr->undoStack, deleteCmd, insertCmd, 1); > } > 1491,1504c1607,1620 < DeleteChars(textPtr, index1String, index2String, indexPtr1, indexPtr2) < TkText *textPtr; /* Overall information about text widget. */ < CONST char *index1String; /* String describing location of first < * character to delete. */ < CONST char *index2String; /* String describing location of last < * character to delete. NULL means just < * delete the one character given by < * index1String. */ < TkTextIndex *indexPtr1; /* index describing location of first < * character to delete. */ < TkTextIndex *indexPtr2; /* index describing location of last < * character to delete. NULL means just < * delete the one character given by < * indexPtr1. */ --- > DeleteChars(textPtr, index1Obj, index2Obj, indexPtr1, indexPtr2) > TkText *textPtr; /* Overall information about text widget. */ > Tcl_Obj *index1Obj; /* Object describing location of first > * character to delete. */ > Tcl_Obj *index2Obj; /* Object describing location of last > * character to delete. NULL means just > * delete the one character given by > * index1Obj. */ > CONST TkTextIndex *indexPtr1;/* Index describing location of first > * character to delete. */ > CONST TkTextIndex *indexPtr2;/* Index describing location of last > * character to delete. NULL means just > * delete the one character given by > * indexPtr1. */ 1508d1623 < char indexBuffer[TK_POS_CHARS]; 1514,1516c1629,1631 < if (index1String != NULL) { < if (TkTextGetIndex(textPtr->interp, textPtr, index1String, &index1) < != TCL_OK) { --- > if (index1Obj != NULL) { > indexPtr1 = TkTextGetIndexFromObj(textPtr->interp, textPtr, index1Obj); > if (indexPtr1 == NULL) { 1519,1521c1634,1638 < if (index2String != NULL) { < if (TkTextGetIndex(textPtr->interp, textPtr, index2String, &index2) < != TCL_OK) { --- > index1 = *indexPtr1; > if (index2Obj != NULL) { > indexPtr2 = TkTextGetIndexFromObj(textPtr->interp, textPtr, > index2Obj); > if (indexPtr2 == NULL) { 1523a1641 > index2 = *indexPtr2; 1636,1639c1754,1755 < Tcl_DString ds; < Tcl_DString actionCommand; < Tcl_DString revertCommand; < --- > Tcl_Obj *get; > 1647,1688c1763,1764 < Tcl_DStringInit(&actionCommand); < Tcl_DStringInit(&revertCommand); < < Tcl_DStringAppend(&actionCommand,Tcl_GetCommandName(textPtr->interp,textPtr->widgetCmd),-1); < Tcl_DStringAppend(&actionCommand," delete ",-1); < TkTextPrintIndex(&index1,indexBuffer); < Tcl_DStringAppend(&actionCommand,indexBuffer,-1); < Tcl_DStringAppend(&actionCommand," ",-1); < TkTextPrintIndex(&index2, indexBuffer); < Tcl_DStringAppend(&actionCommand,indexBuffer,-1); < Tcl_DStringAppend(&actionCommand,"; ",-1); < Tcl_DStringAppend(&actionCommand,Tcl_GetCommandName(textPtr->interp,textPtr->widgetCmd),-1); < Tcl_DStringAppend(&actionCommand," mark set insert ",-1); < TkTextPrintIndex(&index1,indexBuffer); < Tcl_DStringAppend(&actionCommand,indexBuffer,-1); < < Tcl_DStringAppend(&actionCommand,"; ",-1); < Tcl_DStringAppend(&actionCommand,Tcl_GetCommandName(textPtr->interp,textPtr->widgetCmd),-1); < Tcl_DStringAppend(&actionCommand," see insert",-1); < < TextGetText(&index1, &index2, &ds); < < Tcl_DStringAppend(&revertCommand,Tcl_GetCommandName(textPtr->interp,textPtr->widgetCmd),-1); < Tcl_DStringAppend(&revertCommand," insert ",-1); < TkTextPrintIndex(&index1,indexBuffer); < Tcl_DStringAppend(&revertCommand,indexBuffer,-1); < Tcl_DStringAppend(&revertCommand," ",-1); < Tcl_DStringAppendElement(&revertCommand,Tcl_DStringValue(&ds)); < Tcl_DStringAppend(&revertCommand,"; ",-1); < Tcl_DStringAppend(&revertCommand,Tcl_GetCommandName(textPtr->interp,textPtr->widgetCmd),-1); < Tcl_DStringAppend(&revertCommand," mark set insert ",-1); < TkTextPrintIndex(&index2, indexBuffer); < Tcl_DStringAppend(&revertCommand,indexBuffer,-1); < Tcl_DStringAppend(&revertCommand,"; ",-1); < Tcl_DStringAppend(&revertCommand,Tcl_GetCommandName(textPtr->interp,textPtr->widgetCmd),-1); < Tcl_DStringAppend(&revertCommand," see insert",-1); < < TkUndoPushAction(textPtr->undoStack,&actionCommand, &revertCommand); < < Tcl_DStringFree(&actionCommand); < Tcl_DStringFree(&revertCommand); < --- > get = TextGetText(&index1, &index2); > TextPushUndoAction(textPtr, get, 0, &index1, &index2); 1690c1766 < updateDirtyFlag(textPtr); --- > UpdateDirtyFlag(textPtr); 1691a1768 > textPtr->stateEpoch ++; 1800c1877 < goto done; --- > goto fetchDone; 1841c1918 < done: --- > fetchDone: 1934c2011 < if ((textPtr->state == TK_STATE_DISABLED) || --- > if ((textPtr->state == TK_TEXT_STATE_DISABLED) || 1973c2050 < TextSearchCmd(textPtr, interp, argc, argv) --- > TextSearchCmd(textPtr, interp, objc, objv) 1976,1977c2053,2054 < int argc; /* Number of arguments. */ < CONST char **argv; /* Argument strings. */ --- > int objc; /* Number of arguments. */ > Tcl_Obj *CONST objv[]; /* Argument objects. */ 1979,1994c2056,2058 < int backwards, exact, searchElide, c, i, argsLeft, noCase, leftToScan; < size_t length; < int numLines, startingLine, startingByte, lineNum, firstByte, lastByte; < int code, matchLength, matchByte, passes, stopLine, searchWholeText; < int patLength; < CONST char *arg, *pattern, *varName, *p, *startOfLine; < char buffer[20]; < TkTextIndex index, stopIndex; < Tcl_DString line, patDString; < TkTextSegment *segPtr; < TkTextLine *linePtr; < TkTextIndex curIndex; < Tcl_Obj *patObj = NULL; < Tcl_RegExp regexp = NULL; /* Initialization needed only to < * prevent compiler warning. */ < --- > int i, argsLeft, code; > TkLineSearchSpec searchSpec; > 1999,2006c2063,2079 < exact = 1; < searchElide = 0; < curIndex.tree = textPtr->tree; < backwards = 0; < noCase = 0; < varName = NULL; < for (i = 2; i < argc; i++) { < arg = argv[i]; --- > searchSpec.exact = 1; > searchSpec.noCase = 0; > searchSpec.all = 0; > searchSpec.backwards = 0; > searchSpec.textPtr = textPtr; > searchSpec.varPtr = NULL; > searchSpec.countPtr = NULL; > searchSpec.resPtr = NULL; > searchSpec.searchElide = 0; > searchSpec.numLines = TkBTreeNumLines(textPtr->tree); > > for (i = 2; i < objc; i++) { > size_t length; > char c; > > CONST char *arg = Tcl_GetStringFromObj(objv[i],&length); > 2010d2082 < length = strlen(arg); 2014c2086 < "\": must be --, -backward, -count, -elide, -exact, ", --- > "\": must be --, -all, -backward, -count, -elide, -exact, ", 2019,2022c2091,2096 < if ((c == 'b') && (strncmp(argv[i], "-backwards", length) == 0)) { < backwards = 1; < } else if ((c == 'c') && (strncmp(argv[i], "-count", length) == 0)) { < if (i >= (argc-1)) { --- > if ((c == 'a') && (strncmp(arg, "-all", length) == 0)) { > searchSpec.all = 1; > } else if ((c == 'b') && (strncmp(arg, "-backwards", length) == 0)) { > searchSpec.backwards = 1; > } else if ((c == 'c') && (strncmp(arg, "-count", length) == 0)) { > if (i >= (objc-1)) { 2028c2102,2106 < varName = argv[i]; --- > /* > * Assumption objv[i] isn't going to disappear on us during > * this procedure, which is fair. > */ > searchSpec.varPtr = objv[i]; 2030,2031c2108,2109 < && (strncmp(argv[i], "-exact", length) == 0)) { < exact = 1; --- > && (strncmp(arg, "-exact", length) == 0)) { > searchSpec.exact = 1; 2033,2035c2111,2113 < && (strncmp(argv[i], "-elide", length) == 0)) { < searchElide = 1; < } else if ((c == 'h') && (strncmp(argv[i], "-hidden", length) == 0)) { --- > && (strncmp(arg, "-elide", length) == 0)) { > searchSpec.searchElide = 1; > } else if ((c == 'h') && (strncmp(arg, "-hidden", length) == 0)) { 2040,2047c2118,2125 < searchElide = 1; < } else if ((c == 'f') && (strncmp(argv[i], "-forwards", length) == 0)) { < backwards = 0; < } else if ((c == 'n') && (strncmp(argv[i], "-nocase", length) == 0)) { < noCase = 1; < } else if ((c == 'r') && (strncmp(argv[i], "-regexp", length) == 0)) { < exact = 0; < } else if ((c == '-') && (strncmp(argv[i], "--", length) == 0)) { --- > searchSpec.searchElide = 1; > } else if ((c == 'f') && (strncmp(arg, "-forwards", length) == 0)) { > searchSpec.backwards = 0; > } else if ((c == 'n') && (strncmp(arg, "-nocase", length) == 0)) { > searchSpec.noCase = 1; > } else if ((c == 'r') && (strncmp(arg, "-regexp", length) == 0)) { > searchSpec.exact = 0; > } else if ((c == '-') && (strncmp(arg, "--", length) == 0)) { 2054c2132 < argsLeft = argc - (i+2); --- > argsLeft = objc - (i+2); 2056,2058c2134,2135 < Tcl_AppendResult(interp, "wrong # args: should be \"", < argv[0], " search ?switches? pattern index ?stopIndex?\"", < (char *) NULL); --- > Tcl_WrongNumArgs(interp, 2, objv, > "?switches? pattern index ?stopIndex?"); 2061d2137 < pattern = argv[i]; 2063,2064c2139,2141 < /* < * Convert the pattern to lower-case if we're supposed to ignore case. --- > /* > * Find the starting line and starting offset (measured in Unicode > * chars for regexp search, utf-8 bytes for exact search) 2066,2075c2143,2144 < < if (noCase && exact) { < Tcl_DStringInit(&patDString); < Tcl_DStringAppend(&patDString, pattern, -1); < Tcl_UtfToLower(Tcl_DStringValue(&patDString)); < pattern = Tcl_DStringValue(&patDString); < } < < Tcl_DStringInit(&line); < if (TkTextGetIndex(interp, textPtr, argv[i+1], &index) != TCL_OK) { --- > if (SearchGetLineIndex(interp, objv[i+1], &searchSpec, 1, > &searchSpec.startLine, &searchSpec.startOffset) != TCL_OK) { 2077,2090c2146 < goto done; < } < numLines = TkBTreeNumLines(textPtr->tree); < startingLine = TkBTreeLineIndex(index.linePtr); < startingByte = index.byteIndex; < if (startingLine >= numLines) { < if (backwards) { < startingLine = TkBTreeNumLines(textPtr->tree) - 1; < startingByte = TkBTreeBytesInLine(TkBTreeFindLine(textPtr->tree, < startingLine)); < } else { < startingLine = 0; < startingByte = 0; < } --- > goto cleanup; 2091a2148,2151 > > /* > * Find the optional end location, similarly. > */ 2093c2153,2154 < if (TkTextGetIndex(interp, textPtr, argv[i+2], &stopIndex) != TCL_OK) { --- > if (SearchGetLineIndex(interp, objv[i+2], &searchSpec, 0, > &searchSpec.stopLine, &searchSpec.stopOffset) != TCL_OK) { 2095,2099c2156 < goto done; < } < stopLine = TkBTreeLineIndex(stopIndex.linePtr); < if (!backwards && (stopLine == numLines)) { < stopLine = numLines-1; --- > goto cleanup; 2101d2157 < searchWholeText = 0; 2103,2104c2159 < stopLine = 0; < searchWholeText = 1; --- > searchSpec.stopLine = -1; 2106c2161 < --- > 2112,2121c2167,2173 < matchLength = patLength = 0; /* Only needed to prevent compiler < * warnings. */ < if (exact) { < patLength = strlen(pattern); < } else { < patObj = Tcl_NewStringObj(pattern, -1); < Tcl_IncrRefCount(patObj); < regexp = Tcl_GetRegExpFromObj(interp, patObj, < (noCase ? TCL_REG_NOCASE : 0) | TCL_REG_ADVANCED); < if (regexp == NULL) { --- > code = PerformSearch(interp, &searchSpec, objv[i]); > > /* Set the '-count' variable, if given */ > if (searchSpec.varPtr != NULL && searchSpec.countPtr != NULL) { > Tcl_IncrRefCount(searchSpec.countPtr); > if (Tcl_ObjSetVar2(interp, searchSpec.varPtr, NULL, > searchSpec.countPtr, TCL_LEAVE_ERR_MSG) == NULL) { 2123c2175 < goto done; --- > goto cleanup; 2126,2134c2178,2253 < lineNum = startingLine; < code = TCL_OK; < for (passes = 0; passes < 2; ) { < if (lineNum >= numLines) { < /* < * Don't search the dummy last line of the text. < */ < < goto nextLine; --- > > /* Set the result */ > if (searchSpec.resPtr != NULL) { > Tcl_SetObjResult(interp, searchSpec.resPtr); > searchSpec.resPtr = NULL; > } > > cleanup: > if (searchSpec.countPtr != NULL) { > Tcl_DecrRefCount(searchSpec.countPtr); > } > if (searchSpec.resPtr != NULL) { > Tcl_DecrRefCount(searchSpec.resPtr); > } > return code; > } > > /* > *---------------------------------------------------------------------- > * > * SearchGetLineIndex -- > * > * Extract a row, text offset index position from an objPtr > * > * This means we ignore any embedded windows/images and > * elidden text (unless we are searching that). > * > * Results: > * Standard Tcl error code (with a message in the interpreter > * on error conditions). > * > * The returned offset is a utf-8 char* byte index for exact > * searches, and a Unicode character index for regexp searches. > * > * Side effects: > * None. > * > *---------------------------------------------------------------------- > */ > static int > SearchGetLineIndex(interp, objPtr, searchSpecPtr, forwardWrap, > linePosPtr, offsetPosPtr) > Tcl_Interp *interp; /* For error messages */ > Tcl_Obj *objPtr; /* Contains a textual index > * like "1.2" */ > TkLineSearchSpec *searchSpecPtr; /* Contains other search > * parameters */ > int forwardWrap; /* If the given position is at or > * beyond the end of the text, if 1 > * then wrap to the beginning (0,0), > * else find the very last textual > * position. This logic is reversed > * if the search is backwards */ > int *linePosPtr; /* For returning the line number */ > int *offsetPosPtr; /* For returning the text offset in > * the line */ > { > CONST TkTextIndex *indexPtr; > int line; > > indexPtr = TkTextGetIndexFromObj(interp, searchSpecPtr->textPtr, objPtr); > if (indexPtr == NULL) { > return TCL_ERROR; > } > > line = TkBTreeLineIndex(indexPtr->linePtr); > if (line >= searchSpecPtr->numLines) { > if (searchSpecPtr->backwards ^ forwardWrap) { > line = 0; > *offsetPosPtr = 0; > } else { > TkTextLine *linePtr; > line = searchSpecPtr->numLines-1; > linePtr = TkBTreeFindLine(searchSpecPtr->textPtr->tree, line); > *offsetPosPtr = SearchIndexInLine(searchSpecPtr, linePtr, > TkBTreeBytesInLine(linePtr)); 2135a2255,2260 > } else { > *offsetPosPtr = SearchIndexInLine(searchSpecPtr, > indexPtr->linePtr, indexPtr->byteIndex); > } > > *linePosPtr = line; 2137,2141c2262,2284 < /* < * Extract the text from the line. If we're doing regular < * expression matching, drop the newline from the line, so < * that "$" can be used to match the end of the line. < */ --- > return TCL_OK; > } > > /* > *---------------------------------------------------------------------- > * > * SearchIndexInLine -- > * > * Find textual index of 'byteIndex' in the searchable > * characters of 'linePtr'. > * > * This means we ignore any embedded windows/images and > * elidden text (unless we are searching that). > * > * Results: > * The returned index is a utf-8 char* byte index for exact > * searches, and a Unicode character index for regexp searches. > * > * Side effects: > * None. > * > *---------------------------------------------------------------------- > */ 2143,2149c2286,2316 < linePtr = TkBTreeFindLine(textPtr->tree, lineNum); < curIndex.linePtr = linePtr; curIndex.byteIndex = 0; < for (segPtr = linePtr->segPtr; segPtr != NULL; < curIndex.byteIndex += segPtr->size, segPtr = segPtr->nextPtr) { < if ((segPtr->typePtr != &tkTextCharType) < || (!searchElide && TkTextIsElided(textPtr, &curIndex))) { < continue; --- > static int > SearchIndexInLine(searchSpecPtr, linePtr, byteIndex) > CONST TkLineSearchSpec *searchSpecPtr; > TkTextLine *linePtr; > int byteIndex; > { > TkTextSegment *segPtr; > TkTextIndex curIndex; > int index, leftToScan; > > index = 0; > curIndex.tree = searchSpecPtr->textPtr->tree; > curIndex.linePtr = linePtr; curIndex.byteIndex = 0; > for (segPtr = linePtr->segPtr, leftToScan = byteIndex; > leftToScan > 0; > curIndex.byteIndex += segPtr->size, segPtr = segPtr->nextPtr) { > if ((segPtr->typePtr == &tkTextCharType) > && (searchSpecPtr->searchElide || > !TkTextIsElided(searchSpecPtr->textPtr, &curIndex))) { > if (leftToScan < segPtr->size) { > if (searchSpecPtr->exact) { > index += leftToScan; > } else { > index += Tcl_NumUtfChars(segPtr->body.chars, leftToScan); > } > } else { > if (searchSpecPtr->exact) { > index += segPtr->size; > } else { > index += Tcl_NumUtfChars(segPtr->body.chars, -1); > } 2151d2317 < Tcl_DStringAppend(&line, segPtr->body.chars, segPtr->size); 2153,2156c2319,2343 < if (!exact) { < Tcl_DStringSetLength(&line, Tcl_DStringLength(&line)-1); < } < startOfLine = Tcl_DStringValue(&line); --- > leftToScan -= segPtr->size; > } > return index; > } > > /* > *---------------------------------------------------------------------- > * > * SearchAddNextLine -- > * > * Adds a line from the text widget to the object 'theLine'. > * > * Results: > * A pointer to the TkTextLine corresponding to the given line. > * Also 'lenPtr' (if non-NULL) is filled in with the total length of > * 'theLine' (not just what we added to it, but the length including > * what was already in there). This is in bytes for an exact search > * and in chars for a regexp search. > * > * Side effects: > * Memory may be allocated or re-allocated for theLine's string > * representation. > * > *---------------------------------------------------------------------- > */ 2158,2160c2345,2357 < /* < * If we're ignoring case, convert the line to lower case. < */ --- > static ClientData > SearchAddNextLine(lineNum, searchSpecPtr, theLine, lenPtr) > int lineNum; > TkLineSearchSpec *searchSpecPtr; > Tcl_Obj *theLine; > int *lenPtr; > { > TkTextLine *linePtr; > TkTextIndex curIndex; > TkTextSegment *segPtr; > /* > * Extract the text from the line. > */ 2162,2164c2359,2370 < if (noCase) { < Tcl_DStringSetLength(&line, < Tcl_UtfToLower(Tcl_DStringValue(&line))); --- > linePtr = TkBTreeFindLine(searchSpecPtr->textPtr->tree, lineNum); > if (linePtr == NULL) { > return NULL; > } > curIndex.tree = searchSpecPtr->textPtr->tree; > curIndex.linePtr = linePtr; curIndex.byteIndex = 0; > for (segPtr = linePtr->segPtr; segPtr != NULL; > curIndex.byteIndex += segPtr->size, segPtr = segPtr->nextPtr) { > if ((segPtr->typePtr != &tkTextCharType) > || (!searchSpecPtr->searchElide > && TkTextIsElided(searchSpecPtr->textPtr, &curIndex))) { > continue; 2165a2372,2382 > #if 1 > /* Workaround Tcl bug 635200. Remove this line as soon as > * that bug is fixed! */ > Tcl_GetString(theLine); > #endif > Tcl_AppendToObj(theLine, segPtr->body.chars, segPtr->size); > } > > /* > * If we're ignoring case, convert the line to lower case. > */ 2167,2203c2384,2416 < /* < * Check for matches within the current line. If so, and if we're < * searching backwards, repeat the search to find the last match < * in the line. (Note: The lastByte should include the NULL char < * so we can handle searching for end of line easier.) < */ < < matchByte = -1; < firstByte = 0; < lastByte = Tcl_DStringLength(&line) + 1; < if (lineNum == startingLine) { < int indexInDString; < < /* < * The starting line is tricky: the first time we see it < * we check one part of the line, and the second pass through < * we check the other part of the line. We have to be very < * careful here because there could be embedded windows or < * other things that are not in the extracted line. Rescan < * the original line to compute the index in it of the first < * character. < */ < < indexInDString = startingByte; < for (segPtr = linePtr->segPtr, leftToScan = startingByte; < leftToScan > 0; segPtr = segPtr->nextPtr) { < if (segPtr->typePtr != &tkTextCharType) { < indexInDString -= segPtr->size; < } < leftToScan -= segPtr->size; < } < < passes++; < if ((passes == 1) ^ backwards) { < /* < * Only use the last part of the line. < */ --- > if (searchSpecPtr->noCase) { > Tcl_SetObjLength(theLine, Tcl_UtfToLower(Tcl_GetString(theLine))); > } > if (lenPtr != NULL) { > if (searchSpecPtr->exact) { > Tcl_GetStringFromObj(theLine, lenPtr); > } else { > *lenPtr = Tcl_GetCharLength(theLine); > } > } > return (ClientData)linePtr; > } > > /* > *---------------------------------------------------------------------- > * > * SearchFoundMatch -- > * > * Stores information from a successful search. > * > * Results: > * 1 if the information was stored, 0 if it actually goes beyond > * the allowable search region (and therefore the search is actually > * complete). > * > * Side effects: > * Memory may be allocated in the 'countPtr' and 'resPtr' fields > * of 'searchSpecPtr'. Each of those objects will have refCount > * zero and must eventually be freed or stored elsewhere as > * appropriate. > * > *---------------------------------------------------------------------- > */ 2205,2213c2418,2435 < firstByte = indexInDString; < if ((firstByte >= Tcl_DStringLength(&line)) < && !((Tcl_DStringLength(&line) == 0) && !exact)) { < goto nextLine; < } < } else { < /* < * Use only the first part of the line. < */ --- > static int > SearchFoundMatch(lineNum, searchSpecPtr, clientData, theLine, > matchOffset, matchLength) > int lineNum; /* Line on which match was found */ > TkLineSearchSpec *searchSpecPtr;/* Search parameters */ > ClientData clientData; /* Token returned by SearchAddNextLine */ > Tcl_Obj *theLine; /* Text from current line */ > int matchOffset; /* Offset of found item in utf-8 bytes > * for exact search, Unicode chars > * for regexp */ > int matchLength; /* Length also in bytes/chars as per > * search type. */ > { > int numChars; > int leftToScan; > TkTextIndex curIndex, foundIndex; > TkTextSegment *segPtr; > TkTextLine *linePtr; 2215,2216c2437,2445 < lastByte = indexInDString; < } --- > if (lineNum == searchSpecPtr->stopLine) { > /* > * If the current index is on the wrong side of the stopIndex, > * then the item we just found is actually outside the acceptable > * range, and the search is over. > */ > if (searchSpecPtr->backwards ^ > (matchOffset >= searchSpecPtr->stopOffset)) { > return 0; 2218,2220c2447,2452 < do { < int thisLength; < Tcl_UniChar ch; --- > } > > /* > * Calculate the character count, which may need augmenting > * if there are embedded windows or elidden text. > */ 2222,2229c2454,2485 < if (exact) { < p = strstr(startOfLine + firstByte, /* INTL: Native. */ < pattern); < if (p == NULL) { < break; < } < i = p - startOfLine; < thisLength = patLength; --- > if (searchSpecPtr->exact) { > CONST char *startOfLine = Tcl_GetString(theLine); > numChars = Tcl_NumUtfChars(startOfLine + matchOffset, matchLength); > } else { > numChars = matchLength; > } > > /* > * The index information returned by the regular expression > * parser only considers textual information: it doesn't > * account for embedded windows, elided text (when we are not > * searching elided text) or any other non-textual info. > * Scan through the line's segments again to adjust both > * matchChar and matchCount. > * > * We will walk through the segments of this line until we > * have either reached the end of the match or we have > * reached the end of the line. > */ > > linePtr = (TkTextLine *)clientData; > curIndex.tree = searchSpecPtr->textPtr->tree; > curIndex.linePtr = linePtr; curIndex.byteIndex = 0; > /* Find the starting point */ > for (segPtr = linePtr->segPtr, leftToScan = matchOffset; > leftToScan >= 0 && segPtr; segPtr = segPtr->nextPtr) { > if (segPtr->typePtr != &tkTextCharType) { > matchOffset += segPtr->size; > } else if (!searchSpecPtr->searchElide > && TkTextIsElided(searchSpecPtr->textPtr, &curIndex)) { > if (searchSpecPtr->exact) { > matchOffset += segPtr->size; 2231,2248c2487 < CONST char *start, *end; < int match; < < match = Tcl_RegExpExec(interp, regexp, < startOfLine + firstByte, startOfLine); < if (match < 0) { < code = TCL_ERROR; < goto done; < } < if (!match) { < break; < } < Tcl_RegExpRange(regexp, 0, &start, &end); < i = start - startOfLine; < thisLength = end - start; < } < if (i >= lastByte) { < break; --- > matchOffset += Tcl_NumUtfChars(segPtr->body.chars, -1); 2250,2281c2489,2524 < matchByte = i; < matchLength = thisLength; < firstByte = i + Tcl_UtfToUniChar(startOfLine + matchByte, &ch); < } while (backwards); < < /* < * If we found a match then we're done. Make sure that < * the match occurred before the stopping index, if one was < * specified. < */ < < if (matchByte >= 0) { < int numChars; < < /* < * Convert the byte length to a character count. < */ < < numChars = Tcl_NumUtfChars(startOfLine + matchByte, < matchLength); < < /* < * The index information returned by the regular expression < * parser only considers textual information: it doesn't < * account for embedded windows, elided text (when we are not < * searching elided text) or any other non-textual info. < * Scan through the line's segments again to adjust both < * matchChar and matchCount. < * < * We will walk through the segments of this line until we have < * either reached the end of the match or we have reached the end < * of the line. --- > } else { > leftToScan -= segPtr->size; > } > curIndex.byteIndex += segPtr->size; > } > /* Calculate and store the found index in the result */ > if (searchSpecPtr->exact) { > TkTextMakeByteIndex(searchSpecPtr->textPtr->tree, lineNum, > matchOffset, &foundIndex); > } else { > TkTextMakeCharIndex(searchSpecPtr->textPtr->tree, lineNum, > matchOffset, &foundIndex); > } > if (searchSpecPtr->all) { > if (searchSpecPtr->resPtr == NULL) { > searchSpecPtr->resPtr = Tcl_NewObj(); > } > Tcl_ListObjAppendElement(NULL, searchSpecPtr->resPtr, > TkTextNewIndexObj(searchSpecPtr->textPtr, &foundIndex)); > } else { > searchSpecPtr->resPtr = > TkTextNewIndexObj(searchSpecPtr->textPtr, &foundIndex); > } > /* > * Find the end point. Here 'leftToScan' could be negative already > * as a result of the above loop if the segment we reached spanned > * the start of the string. When we add matchLength it will become > * non-negative. > */ > for (leftToScan += matchLength; leftToScan > 0; > curIndex.byteIndex += segPtr->size, segPtr = segPtr->nextPtr) { > if (segPtr == NULL) { > /* > * We are on the next line -- this of course should only > * ever happen with searches which have matched across > * multiple lines 2283c2526,2527 < --- > linePtr = TkBTreeNextLine(linePtr); > segPtr = linePtr->segPtr; 2285,2322d2528 < for (segPtr = linePtr->segPtr, leftToScan = matchByte; < leftToScan >= 0 && segPtr; segPtr = segPtr->nextPtr) { < if (segPtr->typePtr != &tkTextCharType || \ < (!searchElide && TkTextIsElided(textPtr, &curIndex))) { < matchByte += segPtr->size; < } else { < leftToScan -= segPtr->size; < } < curIndex.byteIndex += segPtr->size; < } < for (leftToScan += matchLength; leftToScan > 0; < segPtr = segPtr->nextPtr) { < if (segPtr->typePtr != &tkTextCharType) { < numChars += segPtr->size; < continue; < } < leftToScan -= segPtr->size; < } < TkTextMakeByteIndex(textPtr->tree, lineNum, matchByte, &index); < if (!searchWholeText) { < if (!backwards && (TkTextIndexCmp(&index, &stopIndex) >= 0)) { < goto done; < } < if (backwards && (TkTextIndexCmp(&index, &stopIndex) < 0)) { < goto done; < } < } < if (varName != NULL) { < sprintf(buffer, "%d", numChars); < if (Tcl_SetVar(interp, varName, buffer, TCL_LEAVE_ERR_MSG) < == NULL) { < code = TCL_ERROR; < goto done; < } < } < TkTextPrintIndex(&index, buffer); < Tcl_SetResult(interp, buffer, TCL_VOLATILE); < goto done; 2324,2338c2530,2540 < < /* < * Go to the next (or previous) line; < */ < < nextLine: < if (backwards) { < lineNum--; < if (!searchWholeText) { < if (lineNum < stopLine) { < break; < } < } else if (lineNum < 0) { < lineNum = numLines-1; < } --- > if (segPtr->typePtr != &tkTextCharType) { > /* Anything we didn't count in the search needs adding */ > numChars += segPtr->size; > continue; > } else if (!searchSpecPtr->searchElide > && TkTextIsElided(searchSpecPtr->textPtr, &curIndex)) { > numChars += Tcl_NumUtfChars(segPtr->body.chars, -1); > continue; > } > if (searchSpecPtr->exact) { > leftToScan -= segPtr->size; 2340,2347c2542 < lineNum++; < if (!searchWholeText) { < if (lineNum > stopLine) { < break; < } < } else if (lineNum >= numLines) { < lineNum = 0; < } --- > leftToScan -= Tcl_NumUtfChars(segPtr->body.chars, -1); 2349,2354d2543 < Tcl_DStringSetLength(&line, 0); < } < done: < Tcl_DStringFree(&line); < if (noCase && exact) { < Tcl_DStringFree(&patDString); 2356,2357c2545,2557 < if (patObj != NULL) { < Tcl_DecrRefCount(patObj); --- > /* > * Now store the count result, if it is wanted > */ > if (searchSpecPtr->varPtr != NULL) { > Tcl_Obj *tmpPtr = Tcl_NewIntObj(numChars); > if (searchSpecPtr->all) { > if (searchSpecPtr->countPtr == NULL) { > searchSpecPtr->countPtr = Tcl_NewObj(); > } > Tcl_ListObjAppendElement(NULL, searchSpecPtr->countPtr, tmpPtr); > } else { > searchSpecPtr->countPtr = tmpPtr; > } 2359c2559 < return code; --- > return 1; 2384c2584 < TkTextGetTabs(interp, tkwin, string) --- > TkTextGetTabs(interp, tkwin, stringPtr) 2388,2389c2588,2590 < char *string; /* Description of the tab stops. See < * the text manual entry for details. */ --- > Tcl_Obj *stringPtr; /* Description of the tab stops. > * See the text manual entry for > * details. */ 2391,2392c2592,2593 < int argc, i, count, c; < CONST char **argv; --- > int objc, i, count; > Tcl_Obj **objv; 2397c2598,2604 < if (Tcl_SplitList(interp, string, &argc, &argv) != TCL_OK) { --- > /* Map these strings to TkTextTabAlign values */ > > static CONST char *tabOptionStrings[] = { > "left", "right", "center", "numeric", (char *) NULL > }; > > if (Tcl_ListObjGetElements(interp, stringPtr, &objc, &objv) != TCL_OK) { 2407,2408c2614,2615 < for (i = 0; i < argc; i++) { < c = argv[i][0]; --- > for (i = 0; i < objc; i++) { > char c = Tcl_GetString(objv[i])[0]; 2422,2423c2629,2632 < for (i = 0, tabPtr = &tabArrayPtr->tabs[0]; i < argc; i++, tabPtr++) { < if (Tk_GetPixels(interp, tkwin, argv[i], &tabPtr->location) --- > for (i = 0, tabPtr = &tabArrayPtr->tabs[0]; i < objc; i++, tabPtr++) { > int index; > > if (Tk_GetPixelsFromObj(interp, tkwin, objv[i], &tabPtr->location) 2435c2644 < if ((i+1) == argc) { --- > if ((i+1) == objc) { 2438c2647,2648 < Tcl_UtfToUniChar(argv[i+1], &ch); --- > /* There may be a more efficient way of getting this */ > Tcl_UtfToUniChar(Tcl_GetString(objv[i+1]), &ch); 2443,2459c2653,2655 < c = argv[i][0]; < if ((c == 'l') && (strncmp(argv[i], "left", < strlen(argv[i])) == 0)) { < tabPtr->alignment = LEFT; < } else if ((c == 'r') && (strncmp(argv[i], "right", < strlen(argv[i])) == 0)) { < tabPtr->alignment = RIGHT; < } else if ((c == 'c') && (strncmp(argv[i], "center", < strlen(argv[i])) == 0)) { < tabPtr->alignment = CENTER; < } else if ((c == 'n') && (strncmp(argv[i], < "numeric", strlen(argv[i])) == 0)) { < tabPtr->alignment = NUMERIC; < } else { < Tcl_AppendResult(interp, "bad tab alignment \"", < argv[i], "\": must be left, right, center, or numeric", < (char *) NULL); --- > > if (Tcl_GetIndexFromObj(interp, objv[i], tabOptionStrings, > "tab alignment", 0, &index) != TCL_OK) { 2461a2658 > tabPtr->alignment = ((TkTextTabAlign)index); 2463d2659 < ckfree((char *) argv); 2468d2663 < ckfree((char *) argv); 2492c2687 < TextDumpCmd(textPtr, interp, argc, argv) --- > TextDumpCmd(textPtr, interp, objc, objv) 2495,2496c2690,2691 < int argc; /* Number of arguments. */ < CONST char **argv; /* Argument strings. Someone else has already --- > int objc; /* Number of arguments. */ > Tcl_Obj *CONST objv[]; /* Argument objects. Someone else has already 2498c2693 < * argv[1] is "dump". */ --- > * objv[1] is "dump". */ 2515c2710 < for (arg=2 ; argv[arg] != (char *) NULL ; arg++) { --- > for (arg=2 ; objv[arg] != NULL ; arg++) { 2517c2712,2713 < if (argv[arg][0] != '-') { --- > char *str = Tcl_GetStringFromObj(objv[arg],&len); > if (str[0] != '-') { 2520,2521c2716 < len = strlen(argv[arg]); < if (strncmp("-all", argv[arg], len) == 0) { --- > if (strncmp("-all", str, len) == 0) { 2523c2718 < } else if (strncmp("-text", argv[arg], len) == 0) { --- > } else if (strncmp("-text", str, len) == 0) { 2525c2720 < } else if (strncmp("-tag", argv[arg], len) == 0) { --- > } else if (strncmp("-tag", str, len) == 0) { 2527c2722 < } else if (strncmp("-mark", argv[arg], len) == 0) { --- > } else if (strncmp("-mark", str, len) == 0) { 2529c2724 < } else if (strncmp("-image", argv[arg], len) == 0) { --- > } else if (strncmp("-image", str, len) == 0) { 2531c2726 < } else if (strncmp("-window", argv[arg], len) == 0) { --- > } else if (strncmp("-window", str, len) == 0) { 2533c2728 < } else if (strncmp("-command", argv[arg], len) == 0) { --- > } else if (strncmp("-command", str, len) == 0) { 2535,2536c2730,2732 < if (arg >= argc) { < Tcl_AppendResult(interp, "Usage: ", argv[0], " dump ?-all -image -text -mark -tag -window? ?-command script? index ?index2?", NULL); --- > if (arg >= objc) { > Tcl_AppendResult(interp, "Usage: ", Tcl_GetString(objv[0]), > " dump ?-all -image -text -mark -tag -window? ?-command script? index ?index2?", NULL); 2539c2735 < command = argv[arg]; --- > command = Tcl_GetString(objv[arg]); 2541c2737,2738 < Tcl_AppendResult(interp, "Usage: ", argv[0], " dump ?-all -image -text -mark -tag -window? ?-command script? index ?index2?", NULL); --- > Tcl_AppendResult(interp, "Usage: ", Tcl_GetString(objv[0]), > " dump ?-all -image -text -mark -tag -window? ?-command script? index ?index2?", NULL); 2545,2546c2742,2744 < if (arg >= argc) { < Tcl_AppendResult(interp, "Usage: ", argv[0], " dump ?-all -image -text -mark -tag -window? ?-command script? index ?index2?", NULL); --- > if (arg >= objc) { > Tcl_AppendResult(interp, "Usage: ", Tcl_GetString(objv[0]), > " dump ?-all -image -text -mark -tag -window? ?-command script? index ?index2?", NULL); 2552c2750 < if (TkTextGetIndex(interp, textPtr, argv[arg], &index1) != TCL_OK) { --- > if (TkTextGetObjIndex(interp, textPtr, objv[arg], &index1) != TCL_OK) { 2558c2756 < if (argc == arg) { --- > if (objc == arg) { 2561c2759 < if (TkTextGetIndex(interp, textPtr, argv[arg], &index2) != TCL_OK) { --- > if (TkTextGetObjIndex(interp, textPtr, objv[arg], &index2) != TCL_OK) { 2564c2762,2763 < if (strncmp(argv[arg], "end", strlen(argv[arg])) == 0) { --- > if (strncmp(Tcl_GetString(objv[arg]), "end", > strlen(Tcl_GetString(objv[arg]))) == 0) { 2600a2800,2801 > *---------------------------------------------------------------------- > * 2601a2803 > * 2609a2812,2813 > * > *---------------------------------------------------------------------- 2697a2902,2903 > *---------------------------------------------------------------------- > * 2698a2905 > * 2706a2914,2915 > * > *---------------------------------------------------------------------- 2714c2923 < TkTextIndex *index; /* index with line/byte position info */ --- > CONST TkTextIndex *index; /* index with line/byte position info */ 2717c2926 < char buffer[TCL_INTEGER_SPACE*2]; --- > char buffer[TK_POS_CHARS]; 2739a2949,2950 > *---------------------------------------------------------------------- > * 2740a2952 > * 2747a2960,2961 > * > *---------------------------------------------------------------------- 2752c2966 < TkText * textPtr; /* Overall information about text widget. */ --- > TkText *textPtr; /* Overall information about text widget. */ 2778a2993,2994 > *---------------------------------------------------------------------- > * 2779a2996 > * 2786a3004,3005 > * > *---------------------------------------------------------------------- 2791c3010 < TkText * textPtr; /* Overall information about text widget. */ --- > TkText *textPtr; /* Overall information about text widget. */ 2811a3031,3032 > *---------------------------------------------------------------------- > * 2821a3043,3044 > * > *---------------------------------------------------------------------- 2825c3048 < TextEditCmd(textPtr, interp, argc, argv) --- > TextEditCmd(textPtr, interp, objc, objv) 2828,2829c3051,3052 < int argc; /* Number of arguments. */ < CONST char **argv; /* Argument strings. */ --- > int objc; /* Number of arguments. */ > Tcl_Obj *CONST objv[]; /* Argument objects. */ 2831,2836c3054,3069 < int c, setModified; < size_t length; < < if (argc < 3) { < Tcl_AppendResult(interp, "wrong # args: should be \"", < argv[0], " edit option ?arg arg ...?\"", (char *) NULL); --- > int index; > > static CONST char *editOptionStrings[] = { > "modified", "redo", "reset", "separator", "undo", (char *) NULL > }; > enum editOptions { > EDIT_MODIFIED, EDIT_REDO, EDIT_RESET, EDIT_SEPARATOR, EDIT_UNDO > }; > > if (objc < 3) { > Tcl_WrongNumArgs(interp, 2, objv, "option ?arg arg ...?"); > return TCL_ERROR; > } > > if (Tcl_GetIndexFromObj(interp, objv[2], editOptionStrings, > "edit option", 0, &index) != TCL_OK) { 2839,2855d3071 < c = argv[2][0]; < length = strlen(argv[2]); < if ((c == 'm') && (strncmp(argv[2], "modified", length) == 0)) { < if (argc == 3) { < Tcl_SetObjResult(interp, Tcl_NewBooleanObj(textPtr->isDirty)); < } else if (argc != 4) { < Tcl_AppendResult(interp, "wrong # args: should be \"", < argv[0], " edit modified ?boolean?\"", (char *) NULL); < return TCL_ERROR; < } else { < XEvent event; < if (Tcl_GetBoolean(interp, argv[3], &setModified) != TCL_OK) { < return TCL_ERROR; < } < /* < * Set or reset the dirty info and trigger a Modified event. < */ 2857,2859c3073,3079 < if (setModified) { < textPtr->isDirty = 1; < textPtr->modifiedSet = 1; --- > switch ((enum editOptions)index) { > case EDIT_MODIFIED: { > if (objc == 3) { > Tcl_SetObjResult(interp, Tcl_NewBooleanObj(textPtr->isDirty)); > } else if (objc != 4) { > Tcl_WrongNumArgs(interp, 3, objv, "?boolean?"); > return TCL_ERROR; 2861,2863c3081,3089 < textPtr->isDirty = 0; < textPtr->modifiedSet = 0; < } --- > int setModified; > XEvent event; > if (Tcl_GetBooleanFromObj(interp, objv[3], &setModified) > != TCL_OK) { > return TCL_ERROR; > } > /* > * Set or reset the dirty info and trigger a Modified event. > */ 2865,2868c3091,3097 < /* < * Send an event that the text was modified. This is equivalent to < * "event generate $textWidget <>" < */ --- > if (setModified) { > textPtr->isDirty = 1; > textPtr->modifiedSet = 1; > } else { > textPtr->isDirty = 0; > textPtr->modifiedSet = 0; > } 2870,2884c3099,3113 < memset((VOID *) &event, 0, sizeof(event)); < event.xany.type = VirtualEvent; < event.xany.serial = NextRequest(Tk_Display(textPtr->tkwin)); < event.xany.send_event = False; < event.xany.window = Tk_WindowId(textPtr->tkwin); < event.xany.display = Tk_Display(textPtr->tkwin); < ((XVirtualEvent *) &event)->name = Tk_GetUid("Modified"); < Tk_HandleEvent(&event); < } < } else if ((c == 'r') && (strncmp(argv[2], "redo", length) == 0) < && (length >= 3)) { < if (argc != 3) { < Tcl_AppendResult(interp, "wrong # args: should be \"", < argv[0], " edit redo\"", (char *) NULL); < return TCL_ERROR; --- > /* > * Send an event that the text was modified. This is > * equivalent to "event generate $textWidget <>" > */ > > memset((VOID *) &event, 0, sizeof(event)); > event.xany.type = VirtualEvent; > event.xany.serial = NextRequest(Tk_Display(textPtr->tkwin)); > event.xany.send_event = False; > event.xany.window = Tk_WindowId(textPtr->tkwin); > event.xany.display = Tk_Display(textPtr->tkwin); > ((XVirtualEvent *) &event)->name = Tk_GetUid("Modified"); > Tk_HandleEvent(&event); > } > break; 2886,2895c3115,3124 < if ( TextEditRedo(textPtr) ) { < Tcl_AppendResult(interp, "nothing to redo", (char *) NULL); < return TCL_ERROR; < } < } else if ((c == 'r') && (strncmp(argv[2], "reset", length) == 0) < && (length >= 3)) { < if (argc != 3) { < Tcl_AppendResult(interp, "wrong # args: should be \"", < argv[0], " edit reset\"", (char *) NULL); < return TCL_ERROR; --- > case EDIT_REDO: { > if (objc != 3) { > Tcl_WrongNumArgs(interp, 3, objv, NULL); > return TCL_ERROR; > } > if (TextEditRedo(textPtr)) { > Tcl_AppendResult(interp, "nothing to redo", (char *) NULL); > return TCL_ERROR; > } > break; 2897,2902c3126,3132 < TkUndoClearStacks(textPtr->undoStack); < } else if ((c == 's') && (strncmp(argv[2], "separator", length) == 0)) { < if (argc != 3) { < Tcl_AppendResult(interp, "wrong # args: should be \"", < argv[0], " edit separator\"", (char *) NULL); < return TCL_ERROR; --- > case EDIT_RESET: { > if (objc != 3) { > Tcl_WrongNumArgs(interp, 3, objv, NULL); > return TCL_ERROR; > } > TkUndoClearStacks(textPtr->undoStack); > break; 2904,2909c3134,3140 < TkUndoInsertUndoSeparator(textPtr->undoStack); < } else if ((c == 'u') && (strncmp(argv[2], "undo", length) == 0)) { < if (argc != 3) { < Tcl_AppendResult(interp, "wrong # args: should be \"", < argv[0], " edit undo\"", (char *) NULL); < return TCL_ERROR; --- > case EDIT_SEPARATOR: { > if (objc != 3) { > Tcl_WrongNumArgs(interp, 3, objv, NULL); > return TCL_ERROR; > } > TkUndoInsertUndoSeparator(textPtr->undoStack); > break; 2911,2920c3142,3153 < if ( TextEditUndo(textPtr) ) { < Tcl_AppendResult(interp, "nothing to undo", < (char *) NULL); < return TCL_ERROR; < } < } else { < Tcl_AppendResult(interp, "bad edit option \"", argv[2], < "\": must be modified, redo, reset, separator or undo", < (char *) NULL); < return TCL_ERROR; --- > case EDIT_UNDO: { > if (objc != 3) { > Tcl_WrongNumArgs(interp, 3, objv, NULL); > return TCL_ERROR; > } > if (TextEditUndo(textPtr)) { > Tcl_AppendResult(interp, "nothing to undo", > (char *) NULL); > return TCL_ERROR; > } > break; > } 2922d3154 < 2926a3159,3160 > *---------------------------------------------------------------------- > * 2927a3162 > * 2929c3164,3171 < * in the Tcl_DString given. That DString should be free or uninitialized. --- > * in a string object which is returned with a refCount of zero. > * > * Since the amount of text may potentially be several megabytes (e.g. > * in text editors built on the text widget), efficiency is very > * important. We may want to investigate the efficiency of the > * Tcl_AppendToObj more carefully (e.g. if we know we are going to be > * appending several thousand lines, we could attempt to pre-allocate > * a larger space). 2932c3174 < * None. --- > * Tcl_Obj of string type containing the specified text. 2935c3177,3180 < * Memory will be allocated for the DString. Remember to free it. --- > * Memory will be allocated for the new object. Remember to free it if > * it isn't going to be stored appropriately. > * > *---------------------------------------------------------------------- 2938,2942c3183,3186 < static void < TextGetText(indexPtr1,indexPtr2, dsPtr) < TkTextIndex *indexPtr1; < TkTextIndex *indexPtr2; < Tcl_DString *dsPtr; --- > static Tcl_Obj* > TextGetText(indexPtr1,indexPtr2) > CONST TkTextIndex *indexPtr1; > CONST TkTextIndex *indexPtr2; 2945c3189 < Tcl_DStringInit(dsPtr); --- > Tcl_Obj *resultPtr = Tcl_NewObj(); 2958,2959c3202,3206 < int last2; < --- > /* > * The last line that was requested must be handled > * carefully, because we may need to break out of this > * loop in the middle of the line > */ 2962,2965c3209,3214 < } < last2 = indexPtr2->byteIndex - tmpIndex.byteIndex + offset; < if (last2 < last) { < last = last2; --- > } else { > int last2; > last2 = indexPtr2->byteIndex - tmpIndex.byteIndex + offset; > if (last2 < last) { > last = last2; > } 2969,2970c3218,3219 < Tcl_DStringAppend(dsPtr, segPtr->body.chars + offset, < last - offset); --- > Tcl_AppendToObj(resultPtr, segPtr->body.chars + offset, > last - offset); 2974a3224 > return resultPtr; 2978,2979c3228,3232 < * updateDirtyFlag -- < * increases the dirtyness of the text widget --- > *---------------------------------------------------------------------- > * > * UpdateDirtyFlag -- > * > * Increases the dirtyness of the text widget 2985a3239,3240 > * > *---------------------------------------------------------------------- 2988c3243,3244 < static void updateDirtyFlag (textPtr) --- > static void > UpdateDirtyFlag (textPtr) 3013a3270,3705 > } > > /* > *---------------------------------------------------------------------- > * > * PerformSearch -- > * > * The core of the search procedure. This procedure is actually > * completely indepent of Tk, and could in the future be split > * off, along with one or two other procedures above. > * > * Results: > * Standard Tcl result code. > * > * Side effects: > * Only those of 'SearchFoundMatch' which is called whenever a > * match is found. > * > * Note that the way matching across multiple lines is implemented, > * we start afresh with each line we have available, even though we > * may already have examined the contents of that line (and further > * ones) if we were attempting a multi-line match using the previous > * line. This means there may be ways to speed this up a lot by not > * throwing away all the multi-line information one has accumulated. > * Profiling should be done to see where the bottlenecks lie before > * attempting this, however. > * > *---------------------------------------------------------------------- > */ > > static int > PerformSearch(interp, searchSpecPtr, patObj) > Tcl_Interp *interp; /* For error messages */ > TkLineSearchSpec *searchSpecPtr;/* Search parameters */ > Tcl_Obj *patObj; /* Contains an exact string or a > * regexp pattern. Must have a > * refCount > 0 */ > { > int passes; > /* > * For exact searches these are utf-8 char* offsets, for regexp > * searches they are Unicode char offsets > */ > int firstOffset, lastOffset, matchOffset, matchLength; > int lineNum = searchSpecPtr->startLine; > int code = TCL_OK; > Tcl_Obj *theLine; > > /* For regexp searches only */ > Tcl_RegExp regexp = NULL; > /* For exact searches only */ > CONST char *pattern = NULL; > int patLength = 0; > int firstNewLine; > > if (searchSpecPtr->exact) { > /* > * Convert the pattern to lower-case if we're supposed to ignore > * case. > */ > if (searchSpecPtr->noCase) { > patObj = Tcl_DuplicateObj(patObj); > /* > * This can change the length of the string behind the > * object's back, so ensure it is correctly synchronised. > */ > Tcl_SetObjLength(patObj, Tcl_UtfToLower(Tcl_GetString(patObj))); > } > } else { > /* > * Compile the regular expression. We want '^$' to match after and > * before \n respectively, so use the TCL_REG_NLANCH flag. > */ > regexp = Tcl_GetRegExpFromObj(interp, patObj, > (searchSpecPtr->noCase ? TCL_REG_NOCASE : 0) > | TCL_REG_ADVANCED | TCL_REG_CANMATCH > | TCL_REG_NLSTOP| TCL_REG_NLANCH); > if (regexp == NULL) { > return TCL_ERROR; > } > } > > /* > * For exact strings, we want to know where the first newline is, > * and we will also use this as a flag to test whether it is even > * possible to match the pattern on a single line. If not we > * will have to search across multiple lines. > */ > if (searchSpecPtr->exact) { > char *nl; > > pattern = Tcl_GetStringFromObj(patObj, &patLength); > nl = strchr(pattern, '\n'); > /* > * If there is no newline, or it is the very end of the string, > * then we don't need any special treatment, since single-line > * matching will work fine. > */ > if (nl == NULL || nl[1] == '\0') { > firstNewLine = -1; > } else { > firstNewLine = (nl - pattern); > } > } else { > firstNewLine = -1; > } > > /* > * Keep a reference here, so that we can be sure the object > * doesn't disappear behind our backs and invalidate its > * contents which we are using. > */ > Tcl_IncrRefCount(patObj); > > /* For building up the current line being checked */ > theLine = Tcl_NewObj(); > Tcl_IncrRefCount(theLine); > > matchLength = 0; /* Only needed to prevent compiler warnings. */ > > for (passes = 0; passes < 2; ) { > ClientData lineInfo; > int linesSearched = 1; > > if (lineNum >= searchSpecPtr->numLines) { > /* Don't search the dummy last line of the text. */ > goto nextLine; > } > > /* > * Extract the text from the line, storing its length in > * 'lastOffset' (in bytes if exact, chars if regexp). > */ > > lineInfo = SearchAddNextLine(lineNum, searchSpecPtr, theLine, > &lastOffset); > > firstOffset = 0; > if (lineNum == searchSpecPtr->startLine) { > /* > * The starting line is tricky: the first time we see it > * we check one part of the line, and the second pass through > * we check the other part of the line. > */ > passes++; > if ((passes == 1) ^ searchSpecPtr->backwards) { > /* > * Only use the last part of the line. > */ > > if ((searchSpecPtr->startOffset >= lastOffset) > && ((lastOffset != 0) || searchSpecPtr->exact)) { > goto nextLine; > } > > firstOffset = searchSpecPtr->startOffset; > } else { > /* > * Use only the first part of the line. > */ > > lastOffset = searchSpecPtr->startOffset -1; > } > } > > /* > * Check for matches within the current line. If so, and if > * we're searching backwards, repeat the search to find the last > * match in the line. (Note: The lastOffset should include the > * NULL char so we can handle searching for end of line easier.) > */ > > matchOffset = -1; > > if (searchSpecPtr->exact) { > int maxExtraLines = 0; > CONST char *startOfLine = Tcl_GetString(theLine); > /* > * Only need to set this once for exact searches; it will be > * ignored if we don't actually find anything > */ > matchLength = patLength; > > do { > Tcl_UniChar ch; > CONST char *p; > > p = strstr(startOfLine + firstOffset, pattern); > if (p == NULL) { > if (firstNewLine == -1) break; > if (firstNewLine >= (lastOffset - firstOffset)) break; > p = startOfLine + lastOffset - firstNewLine - 1; > if (strncmp(p, pattern, firstNewLine + 1)) { > break; > } else { > int extraLines = 1; > int skipFirst = lastOffset - firstNewLine -1; > /* We may be able to match if given more text */ > while (1) { > int len; > ClientData clientData; > > if (lineNum + extraLines > >= searchSpecPtr->numLines) { > p = NULL; > break; > } > > /* > * Only add the line if we haven't already > * done so already. > */ > if (extraLines > maxExtraLines) { > clientData = SearchAddNextLine( > lineNum + extraLines, > searchSpecPtr, theLine, &len); > maxExtraLines = extraLines; > if (clientData == NULL) { > p = NULL; > break; > } > } > > startOfLine = Tcl_GetString(theLine); > p = startOfLine + skipFirst; > if ((len - skipFirst) >= patLength) { > /* We now have enough text to match */ > if (strncmp(p, pattern, patLength)) { > p = NULL; > } > break; > } else { > /* Not enough text yet, but check the prefix */ > if (strncmp(p, pattern, (len - skipFirst))) { > p = NULL; > break; > } > /* The prefix matches, so keep looking */ > } > extraLines++; > } > /* > * If we reach here, with p != NULL, we've found a > * multi-line match, else we started a multi-match > * but didn't finish it off, so we go to the next line. > */ > if (p == NULL) break; > } > } > firstOffset = p - startOfLine; > if (firstOffset > lastOffset) { > break; > } > > /* Remember the match */ > matchOffset = firstOffset; > > /* > * Move the starting point one character on from the > * previous match, in case we are doing repeated or > * backwards searches (for the latter, we actually do > * repeated forward searches). > */ > firstOffset += Tcl_UtfToUniChar(startOfLine + matchOffset, &ch); > if (searchSpecPtr->all) { > if (!SearchFoundMatch(lineNum, searchSpecPtr, lineInfo, > theLine, matchOffset, matchLength)) { > /* We reached the end of the search */ > goto searchDone; > } > } > } while (searchSpecPtr->backwards || searchSpecPtr->all); > > } else { > > int maxExtraLines = 0; > > do { > Tcl_RegExpInfo info; > int match; > > match = Tcl_RegExpExecObj(interp, regexp, theLine, > firstOffset, 1, > ((firstOffset > 0) ? TCL_REG_NOTBOL : 0)); > if (match < 0) { > code = TCL_ERROR; > goto searchDone; > } > Tcl_RegExpGetInfo(regexp, &info); > > if (!match) { > int extraLines = 1; > int found = 0; > int curLen = 0; > > if (info.extendStart < 0) { break; } > > /* We might be able to match if we had more text */ > > while (1) { > ClientData clientData; > > /* Move firstOffset to first possible start */ > firstOffset += info.extendStart; > if (firstOffset >= lastOffset) { > /* > * We're being told that the only possible > * new match is starting after the end of > * the line. But, that is the next line which > * we will handle when we look at that line. > */ > if (!searchSpecPtr->backwards > && (firstOffset == curLen)) { > linesSearched = extraLines + 1; > } > break; > } > > if (lineNum + extraLines >= searchSpecPtr->numLines) { > break; > } > /* Add next line, provided we haven't already done so */ > if (extraLines > maxExtraLines) { > clientData = SearchAddNextLine(lineNum + extraLines, > searchSpecPtr, theLine, NULL); > maxExtraLines = extraLines; > if (clientData == NULL) { > break; > } > } > > match = Tcl_RegExpExecObj(interp, regexp, theLine, > firstOffset, 1, > ((firstOffset > 0) ? TCL_REG_NOTBOL : 0)); > if (match < 0) { > code = TCL_ERROR; > goto searchDone; > } > Tcl_RegExpGetInfo(regexp, &info); > if (match) { > /* We found a match! */ > found = 1; > break; > } > if (info.extendStart < 0) { break; } > /* The prefix matches, so keep looking */ > extraLines++; > } > /* > * If we reach here, with found == 1, we've found a > * multi-line match, else we started a multi-match > * but didn't finish it off, so we go to the next line. > */ > if (!found) break; > } > > firstOffset += info.matches[0].start; > if (firstOffset >= lastOffset) { > break; > } > > /* Remember the match */ > matchOffset = firstOffset; > matchLength = info.matches[0].end - info.matches[0].start; > > /* > * Move the starting point one character on, in case > * we are doing repeated or backwards searches (for the > * latter, we actually do repeated forward searches). > */ > firstOffset++; > if (searchSpecPtr->all) { > if (!SearchFoundMatch(lineNum, searchSpecPtr, lineInfo, > theLine, matchOffset, matchLength)) { > /* We reached the end of the search */ > goto searchDone; > } > } > } while (searchSpecPtr->backwards || searchSpecPtr->all); > > } > > /* > * If the 'all' flag is set, we will already have stored all > * matches, so we just proceed to the next line. > * > * If not, and there is a match we need to store that information > * and we are done. > */ > > if ((matchOffset >= 0) && !searchSpecPtr->all) { > SearchFoundMatch(lineNum, searchSpecPtr, lineInfo, theLine, > matchOffset, matchLength); > goto searchDone; > } > > /* > * Go to the next (or previous) line; > */ > > nextLine: > > for (;linesSearched > 0;linesSearched--) { > /* If we have just completed the stopLine, we are done */ > if (lineNum == searchSpecPtr->stopLine) { > goto searchDone; > } > > if (searchSpecPtr->backwards) { > lineNum--; > if ((searchSpecPtr->stopLine == -1) && (lineNum < 0)) { > lineNum = searchSpecPtr->numLines-1; > } > } else { > lineNum++; > if ((searchSpecPtr->stopLine == -1) > && (lineNum >= searchSpecPtr->numLines)) { > lineNum = 0; > } > } > } > > #ifndef FIXED_STRINGS > Tcl_DecrRefCount(theLine); > theLine = Tcl_NewObj(); > #else > Tcl_SetObjLength(theLine,0); > #endif > } > searchDone: > > /* Free up the cached line and pattern */ > Tcl_DecrRefCount(theLine); > Tcl_DecrRefCount(patObj); > > return code; Index: generic/tkText.h =================================================================== RCS file: /cvsroot/tktoolkit/tk/generic/tkText.h,v retrieving revision 1.12 diff -r1.12 tkText.h 34c34 < * file: --- > * file. 119a120,121 > Tk_OptionTable optionTable; /* Token representing the > * configuration specifications. */ 189a192 > struct TkText *textPtr; 281,282c284,285 < typedef enum { TEXT_WRAPMODE_NULL, TEXT_WRAPMODE_NONE, < TEXT_WRAPMODE_CHAR, TEXT_WRAPMODE_WORD --- > typedef enum { TEXT_WRAPMODE_CHAR, TEXT_WRAPMODE_NONE, > TEXT_WRAPMODE_WORD, TEXT_WRAPMODE_NULL 285,286d287 < EXTERN Tk_CustomOption textWrapModeOption; < 314,315d314 < char *bdString; /* -borderwidth option string (malloc-ed). < * NULL means option not specified. */ 316a316 > Tcl_Obj* borderWidthPtr; /* Width of 3-D border for background. */ 374c374 < char *tabString; /* -tabs option string (malloc-ed). --- > Tcl_Obj *tabStringPtr; /* -tabs option string. 395a396,397 > Tk_OptionTable optionTable; /* Token representing the configuration > * specifications. */ 438c440,442 < * The following data structure describes a single tab stop. --- > * The following data structure describes a single tab stop. It must be > * kept in sync with the 'tabOptionStrings' array in the function > * 'TkTextGetTabs' 466a471,479 > * The following enum is used to define a type for the -state option > * of the Text widget. > */ > > typedef enum { > TK_TEXT_STATE_DISABLED, TK_TEXT_STATE_NORMAL > } TkTextState; > > /* 534c547 < char *tabOptionString; /* Value of -tabs option string (malloc'ed). */ --- > Tcl_Obj *tabOptionPtr; /* Value of -tabs option string */ 567,568c580,581 < char *selBdString; /* Value of -selectborderwidth option, or NULL < * if not specified (malloc'ed). */ --- > int selBorderWidth; /* Width of border around selection. */ > Tcl_Obj* selBorderWidthPtr; /* Width of border around selection. */ 640a654,662 > Tk_OptionTable optionTable; /* Token representing the configuration > * specifications. */ > > int stateEpoch; /* This is incremented each time the widget's > * contents change, and means that any cached > * TkTextIndex objects are no longer valid. */ > int refCount; /* Number of cached TkTextIndex objects > * refering to us */ > 645c667 < TkUndoRedoStack * undoStack; /* The undo/redo stack */ --- > TkUndoRedoStack *undoStack; /* The undo/redo stack */ 647c669 < int undo; /* non zero means the undo/redo behaviour is --- > int undo; /* Non-zero means the undo/redo behaviour is 650,651c672,674 < int maxUndo; /* The maximum depth of the undo stack expressed < * as the maximum number of compound statements */ --- > int maxUndo; /* The maximum depth of the undo stack > * expressed as the maximum number of > * compound statements */ 653c676 < int autoSeparators; /* non zero means the separatorss will be --- > int autoSeparators; /* Non-zero means the separators will be 666,667c689 < * incremented every edit action < */ --- > * incremented every edit action */ 669c691 < TkTextEditMode lastEditMode; /* Keeps track of what the last edit mode was --- > TkTextEditMode lastEditMode;/* Keeps track of what the last edit mode was 784c806 < EXTERN int TkBTreeCharTagged _ANSI_ARGS_((TkTextIndex *indexPtr, --- > EXTERN int TkBTreeCharTagged _ANSI_ARGS_((CONST TkTextIndex *indexPtr, 795c817 < EXTERN TkTextTag ** TkBTreeGetTags _ANSI_ARGS_((TkTextIndex *indexPtr, --- > EXTERN TkTextTag ** TkBTreeGetTags _ANSI_ARGS_((CONST TkTextIndex *indexPtr, 823c845 < TkTextIndex *indexPtr, int *xPtr, int *yPtr, --- > CONST TkTextIndex *indexPtr, int *xPtr, int *yPtr, 831c853 < TkTextIndex *indexPtr, int *xPtr, int *yPtr, --- > CONST TkTextIndex *indexPtr, int *xPtr, int *yPtr, 840a863,867 > EXTERN int TkTextGetObjIndex _ANSI_ARGS_((Tcl_Interp *interp, > TkText *textPtr, Tcl_Obj *idxPtr, > TkTextIndex *indexPtr)); > EXTERN CONST TkTextIndex* TkTextGetIndexFromObj _ANSI_ARGS_((Tcl_Interp *interp, > TkText *textPtr, Tcl_Obj *objPtr)); 842c869 < Tk_Window tkwin, char *string)); --- > Tk_Window tkwin, Tcl_Obj *stringPtr)); 870c897 < TkTextIndex *indexPtr)); --- > CONST TkTextIndex *indexPtr)); 875c902 < Tcl_Interp *interp, int argc, CONST char **argv)); --- > Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); 885c912 < EXTERN void TkTextPrintIndex _ANSI_ARGS_(( --- > EXTERN int TkTextPrintIndex _ANSI_ARGS_(( 886a914,915 > EXTERN Tcl_Obj* TkTextNewIndexObj _ANSI_ARGS_((TkText *textPtr, > CONST TkTextIndex *indexPtr)); 894c923 < Tcl_Interp *interp, int argc, CONST char **argv)); --- > Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); 896c925 < Tcl_Interp *interp, int argc, CONST char **argv)); --- > Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); 905c934 < Tcl_Interp *interp, int argc, CONST char **argv)); --- > Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); 907c936 < Tcl_Interp *interp, int argc, CONST char **argv)); --- > Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); 911c940 < Tcl_Interp *interp, int argc, CONST char **argv)); --- > Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); 915c944 < Tcl_Interp *interp, int argc, CONST char **argv)); --- > Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); 917c946,949 < Tcl_Interp *interp, int argc, CONST char **argv)); --- > Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); > /* Use a helper from tkCanvas.c */ > EXTERN CONST char** GetStringsFromObjs _ANSI_ARGS_((int argc, > Tcl_Obj *CONST *objv)); Index: generic/tkTextBTree.c =================================================================== RCS file: /cvsroot/tktoolkit/tk/generic/tkTextBTree.c,v retrieving revision 1.6 diff -r1.6 tkTextBTree.c 2226c2226 < TkTextIndex *indexPtr; /* Indicates a character position at --- > CONST TkTextIndex *indexPtr; /* Indicates a character position at 2338c2338 < TkTextIndex *indexPtr; /* Indicates a particular position in --- > CONST TkTextIndex *indexPtr;/* Indicates a particular position in 2455c2455 < TkTextIndex *indexPtr; /* The character in the text for which --- > CONST TkTextIndex *indexPtr;/* The character in the text for which Index: generic/tkTextDisp.c =================================================================== RCS file: /cvsroot/tktoolkit/tk/generic/tkTextDisp.c,v retrieving revision 1.13 diff -r1.13 tkTextDisp.c 353c353 < TkTextIndex *indexPtr)); --- > CONST TkTextIndex *indexPtr)); 563c563,564 < if ((tagPtr->bdString != NULL) --- > if ((tagPtr->borderWidthPtr != NULL) > && (Tcl_GetString(tagPtr->borderWidthPtr)[0] != '\0') 639c640 < if ((tagPtr->tabString != NULL) --- > if ((tagPtr->tabStringPtr != NULL) 1709c1710 < if (textPtr->state == TK_STATE_NORMAL) { --- > if (textPtr->state == TK_TEXT_STATE_NORMAL) { 3298c3299 < TkTextSeeCmd(textPtr, interp, argc, argv) --- > TkTextSeeCmd(textPtr, interp, objc, objv) 3301,3302c3302,3303 < int argc; /* Number of arguments. */ < CONST char **argv; /* Argument strings. Someone else has already --- > int objc; /* Number of arguments. */ > Tcl_Obj *CONST objv[]; /* Argument objects. Someone else has already 3304c3305 < * argv[1] is "see". */ --- > * objv[1] is "see". */ 3312c3313 < if (argc != 3) { --- > if (objc != 3) { 3314c3315 < argv[0], " see index\"", (char *) NULL); --- > Tcl_GetString(objv[0]), " see index\"", (char *) NULL); 3317c3318 < if (TkTextGetIndex(interp, textPtr, argv[2], &index) != TCL_OK) { --- > if (TkTextGetObjIndex(interp, textPtr, objv[2], &index) != TCL_OK) { 3366,3367c3367,3369 < if (chunkPtr!=NULL) { /* chunkPtr==NULL iff trying to see in elided region */ < (*chunkPtr->bboxProc)(chunkPtr, byteCount, dlPtr->y + dlPtr->spaceAbove, --- > if (chunkPtr != NULL) { > /* chunkPtr==NULL iff trying to see in elided region */ > (*chunkPtr->bboxProc)(chunkPtr, byteCount, dlPtr->y + dlPtr->spaceAbove, 3371,3383c3373,3376 < delta = x - dInfoPtr->curPixelOffset; < oneThird = lineWidth/3; < if (delta < 0) { < if (delta < -oneThird) { < dInfoPtr->newByteOffset = (x - lineWidth/2)/textPtr->charWidth; < } else { < dInfoPtr->newByteOffset -= ((-delta) + textPtr->charWidth - 1) < / textPtr->charWidth; < } < } else { < delta -= (lineWidth - width); < if (delta > 0) { < if (delta > oneThird) { --- > delta = x - dInfoPtr->curPixelOffset; > oneThird = lineWidth/3; > if (delta < 0) { > if (delta < -oneThird) { 3386c3379 < dInfoPtr->newByteOffset += (delta + textPtr->charWidth - 1) --- > dInfoPtr->newByteOffset -= ((-delta) + textPtr->charWidth - 1) 3390c3383,3393 < return TCL_OK; --- > delta -= (lineWidth - width); > if (delta > 0) { > if (delta > oneThird) { > dInfoPtr->newByteOffset = (x - lineWidth/2)/textPtr->charWidth; > } else { > dInfoPtr->newByteOffset += (delta + textPtr->charWidth - 1) > / textPtr->charWidth; > } > } else { > return TCL_OK; > } 3392c3395 < }} --- > } 3420c3423 < TkTextXviewCmd(textPtr, interp, argc, argv) --- > TkTextXviewCmd(textPtr, interp, objc, objv) 3423,3424c3426,3427 < int argc; /* Number of arguments. */ < CONST char **argv; /* Argument strings. Someone else has already --- > int objc; /* Number of arguments. */ > Tcl_Obj *CONST objv[]; /* Argument objects. Someone else has already 3426c3429 < * argv[1] is "xview". */ --- > * objv[1] is "xview". */ 3436c3439 < if (argc == 2) { --- > if (objc == 2) { 3442c3445 < type = Tk_GetScrollInfo(interp, argc, argv, &fraction, &count); --- > type = Tk_GetScrollInfoObj(interp, objc, objv, &fraction, &count); 3608c3611 < TkTextYviewCmd(textPtr, interp, argc, argv) --- > TkTextYviewCmd(textPtr, interp, objc, objv) 3611,3612c3614,3615 < int argc; /* Number of arguments. */ < CONST char **argv; /* Argument strings. Someone else has already --- > int objc; /* Number of arguments. */ > Tcl_Obj *CONST objv[]; /* Argument objects. Someone else has already 3614c3617 < * argv[1] is "yview". */ --- > * objv[1] is "yview". */ 3630c3633 < if (argc == 2) { --- > if (objc == 2) { 3640,3641c3643,3644 < if (argv[2][0] == '-') { < switchLength = strlen(argv[2]); --- > if (Tcl_GetString(objv[2])[0] == '-') { > switchLength = strlen(Tcl_GetString(objv[2])); 3643c3646 < && (strncmp(argv[2], "-pickplace", switchLength) == 0)) { --- > && (strncmp(Tcl_GetString(objv[2]), "-pickplace", switchLength) == 0)) { 3645c3648 < if (argc != 4) { --- > if (objc != 4) { 3647c3650,3651 < argv[0], " yview -pickplace lineNum|index\"", --- > Tcl_GetString(objv[0]), > " yview -pickplace lineNum|index\"", 3653,3654c3657,3658 < if ((argc == 3) || pickPlace) { < if (Tcl_GetInt(interp, argv[2+pickPlace], &lineNum) == TCL_OK) { --- > if ((objc == 3) || pickPlace) { > if (Tcl_GetIntFromObj(interp, objv[2+pickPlace], &lineNum) == TCL_OK) { 3665c3669 < if (TkTextGetIndex(interp, textPtr, argv[2+pickPlace], --- > if (TkTextGetObjIndex(interp, textPtr, objv[2+pickPlace], 3674c3678 < * New syntax: dispatch based on argv[2]. --- > * New syntax: dispatch based on objv[2]. 3677c3681 < type = Tk_GetScrollInfo(interp, argc, argv, &fraction, &count); --- > type = Tk_GetScrollInfoObj(interp, objc, objv, &fraction, &count); 3774c3778 < TkTextScanCmd(textPtr, interp, argc, argv) --- > TkTextScanCmd(textPtr, interp, objc, objv) 3777,3778c3781,3782 < int argc; /* Number of arguments. */ < CONST char **argv; /* Argument strings. Someone else has already --- > int objc; /* Number of arguments. */ > Tcl_Obj *CONST objv[]; /* Argument objects. Someone else has already 3780c3784 < * argv[1] is "scan". */ --- > * objv[1] is "scan". */ 3788c3792 < if ((argc != 5) && (argc != 6)) { --- > if ((objc != 5) && (objc != 6)) { 3790,3791c3794,3795 < argv[0], " scan mark x y\" or \"", < argv[0], " scan dragto x y ?gain?\"", (char *) NULL); --- > Tcl_GetString(objv[0]), " scan mark x y\" or \"", > Tcl_GetString(objv[0]), " scan dragto x y ?gain?\"", (char *) NULL); 3794c3798 < if (Tcl_GetInt(interp, argv[3], &x) != TCL_OK) { --- > if (Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK) { 3797c3801 < if (Tcl_GetInt(interp, argv[4], &y) != TCL_OK) { --- > if (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK) { 3800c3804 < if ((argc == 6) && (Tcl_GetInt(interp, argv[5], &gain) != TCL_OK)) --- > if ((objc == 6) && (Tcl_GetIntFromObj(interp, objv[5], &gain) != TCL_OK)) 3802,3804c3806,3808 < c = argv[2][0]; < length = strlen(argv[2]); < if ((c == 'd') && (strncmp(argv[2], "dragto", length) == 0)) { --- > c = Tcl_GetString(objv[2])[0]; > length = strlen(Tcl_GetString(objv[2])); > if ((c == 'd') && (strncmp(Tcl_GetString(objv[2]), "dragto", length) == 0)) { 3844c3848 < } else if ((c == 'm') && (strncmp(argv[2], "mark", length) == 0)) { --- > } else if ((c == 'm') && (strncmp(Tcl_GetString(objv[2]), "mark", length) == 0)) { 3850c3854 < Tcl_AppendResult(interp, "bad scan option \"", argv[2], --- > Tcl_AppendResult(interp, "bad scan option \"", Tcl_GetString(objv[2]), 4043c4047 < TkTextIndex *indexPtr; /* Index of desired character. */ --- > CONST TkTextIndex *indexPtr;/* Index of desired character. */ 4221c4225 < TkTextIndex *indexPtr; /* Index of character whose bounding --- > CONST TkTextIndex *indexPtr;/* Index of character whose bounding 4330c4334 < TkTextIndex *indexPtr; /* Index of character whose bounding --- > CONST TkTextIndex *indexPtr;/* Index of character whose bounding Index: generic/tkTextImage.c =================================================================== RCS file: /cvsroot/tktoolkit/tk/generic/tkTextImage.c,v retrieving revision 1.5 diff -r1.5 tkTextImage.c 55c55 < TkTextSegment *eiPtr, int argc, CONST char **argv)); --- > TkTextSegment *eiPtr, int objc, Tcl_Obj *CONST objv[])); 131c131 < TkTextImageCmd(textPtr, interp, argc, argv) --- > TkTextImageCmd(textPtr, interp, objc, objv) 134,135c134,135 < int argc; /* Number of arguments. */ < CONST char **argv; /* Argument strings. Someone else has already --- > int objc; /* Number of arguments. */ > Tcl_Obj *CONST objv[]; /* Argument objects. Someone else has already 137c137 < * argv[1] is "image". */ --- > * objv[1] is "image". */ 141,144c141,144 < < if (argc < 3) { < Tcl_AppendResult(interp, "wrong # args: should be \"", < argv[0], " image option ?arg arg ...?\"", (char *) NULL); --- > CONST char *str; > > if (objc < 3) { > Tcl_WrongNumArgs(interp, 2, objv, "option ?arg arg ...?"); 147,148c147,148 < length = strlen(argv[2]); < if ((strncmp(argv[2], "cget", length) == 0) && (length >= 2)) { --- > str = Tcl_GetStringFromObj(objv[2],&length); > if ((strncmp(str, "cget", length) == 0) && (length >= 2)) { 152,155c152,153 < if (argc != 5) { < Tcl_AppendResult(interp, "wrong # args: should be \"", < argv[0], " image cget index option\"", < (char *) NULL); --- > if (objc != 5) { > Tcl_WrongNumArgs(interp, 3, objv, "index option"); 158c156 < if (TkTextGetIndex(interp, textPtr, argv[3], &index) != TCL_OK) { --- > if (TkTextGetObjIndex(interp, textPtr, objv[3], &index) != TCL_OK) { 164c162 < argv[3], "\"", (char *) NULL); --- > Tcl_GetString(objv[3]), "\"", (char *) NULL); 168,169c166,167 < (char *) &eiPtr->body.ei, argv[4], 0); < } else if ((strncmp(argv[2], "configure", length) == 0) && (length >= 2)) { --- > (char *) &eiPtr->body.ei, Tcl_GetString(objv[4]), 0); > } else if ((strncmp(str, "configure", length) == 0) && (length >= 2)) { 173,176c171,172 < if (argc < 4) { < Tcl_AppendResult(interp, "wrong # args: should be \"", < argv[0], " image configure index ?option value ...?\"", < (char *) NULL); --- > if (objc < 4) { > Tcl_WrongNumArgs(interp, 3, objv, "index ?option value ...?"); 179c175 < if (TkTextGetIndex(interp, textPtr, argv[3], &index) != TCL_OK) { --- > if (TkTextGetObjIndex(interp, textPtr, objv[3], &index) != TCL_OK) { 185c181 < argv[3], "\"", (char *) NULL); --- > Tcl_GetString(objv[3]), "\"", (char *) NULL); 188c184 < if (argc == 4) { --- > if (objc == 4) { 191c187 < } else if (argc == 5) { --- > } else if (objc == 5) { 193c189 < (char *) &eiPtr->body.ei, argv[4], 0); --- > (char *) &eiPtr->body.ei, Tcl_GetString(objv[4]), 0); 196c192 < return EmbImageConfigure(textPtr, eiPtr, argc-4, argv+4); --- > return EmbImageConfigure(textPtr, eiPtr, objc-4, objv+4); 198c194 < } else if ((strncmp(argv[2], "create", length) == 0) && (length >= 2)) { --- > } else if ((strncmp(str, "create", length) == 0) && (length >= 2)) { 207,210c203,204 < if (argc < 4) { < Tcl_AppendResult(interp, "wrong # args: should be \"", < argv[0], " image create index ?option value ...?\"", < (char *) NULL); --- > if (objc < 4) { > Tcl_WrongNumArgs(interp, 3, objv, "index ?option value ...?"); 213c207 < if (TkTextGetIndex(interp, textPtr, argv[3], &index) != TCL_OK) { --- > if (TkTextGetObjIndex(interp, textPtr, objv[3], &index) != TCL_OK) { 251c245 < if (EmbImageConfigure(textPtr, eiPtr, argc-4, argv+4) != TCL_OK) { --- > if (EmbImageConfigure(textPtr, eiPtr, objc-4, objv+4) != TCL_OK) { 258c252 < } else if (strncmp(argv[2], "names", length) == 0) { --- > } else if (strncmp(str, "names", length) == 0) { 262,264c256,257 < if (argc != 3) { < Tcl_AppendResult(interp, "wrong # args: should be \"", < argv[0], " image names\"", (char *) NULL); --- > if (objc != 3) { > Tcl_WrongNumArgs(interp, 3, objv, NULL); 273c266 < Tcl_AppendResult(interp, "bad image option \"", argv[2], --- > Tcl_AppendResult(interp, "bad image option \"", str, 287c280 < * for an embedded image, using an argc/argv list. --- > * for an embedded image, using an objc/objv list. 301c294 < EmbImageConfigure(textPtr, eiPtr, argc, argv) --- > EmbImageConfigure(textPtr, eiPtr, objc, objv) 305,306c298,299 < int argc; /* Number of strings in argv. */ < CONST char **argv; /* Array of strings describing configuration --- > int objc; /* Number of strings in objv. */ > Tcl_Obj *CONST objv[]; /* Array of strings describing configuration 318c311,313 < --- > CONST char **argv; > > argv = GetStringsFromObjs(objc, objv); 320c315 < argc, argv, (char *) &eiPtr->body.ei,TK_CONFIG_ARGV_ONLY) --- > objc, argv, (char *) &eiPtr->body.ei,TK_CONFIG_ARGV_ONLY) 321a317 > if (argv) ckfree((char *) argv); 323a320 > if (argv) ckfree((char *) argv); Index: generic/tkTextIndex.c =================================================================== RCS file: /cvsroot/tktoolkit/tk/generic/tkTextIndex.c,v retrieving revision 1.6 diff -r1.6 tkTextIndex.c 34a35,272 > static int GetIndex _ANSI_ARGS_((Tcl_Interp *interp, > TkText *textPtr, CONST char *string, > TkTextIndex *indexPtr, int *canCachePtr)); > > > static void DupTextIndexInternalRep _ANSI_ARGS_((Tcl_Obj *srcPtr, > Tcl_Obj *copyPtr)); > static void FreeTextIndexInternalRep _ANSI_ARGS_((Tcl_Obj *listPtr)); > static int SetTextIndexFromAny _ANSI_ARGS_((Tcl_Interp *interp, > Tcl_Obj *objPtr)); > static void UpdateStringOfTextIndex _ANSI_ARGS_((Tcl_Obj *objPtr)); > > #define GET_TEXTINDEX(objPtr) \ > ((TkTextIndex *) (objPtr)->internalRep.twoPtrValue.ptr1) > #define GET_INDEXEPOCH(objPtr) \ > ((int) (objPtr)->internalRep.twoPtrValue.ptr2) > #define SET_TEXTINDEX(objPtr, indexPtr) \ > (objPtr)->internalRep.twoPtrValue.ptr1 = (VOID*) (indexPtr) > #define SET_INDEXEPOCH(objPtr, epoch) \ > (objPtr)->internalRep.twoPtrValue.ptr2 = (VOID*) (epoch) > /* > * Define the 'textindex' object type, which Tk uses to represent > * indices in text widgets internally. > */ > Tcl_ObjType tclTextIndexType = { > "textindex", /* name */ > FreeTextIndexInternalRep, /* freeIntRepProc */ > DupTextIndexInternalRep, /* dupIntRepProc */ > NULL, /* updateStringProc */ > SetTextIndexFromAny /* setFromAnyProc */ > }; > > static void > FreeTextIndexInternalRep(indexObjPtr) > Tcl_Obj *indexObjPtr; /* TextIndex object with internal rep to free. */ > { > TkTextIndex *indexPtr = GET_TEXTINDEX(indexObjPtr); > if (indexPtr->textPtr != NULL) { > if (--indexPtr->textPtr->refCount == 0) { > /* The text widget has been deleted and we need to free it now */ > ckfree((char *) (indexPtr->textPtr)); > } > } > ckfree((char*)indexPtr); > } > > static void > DupTextIndexInternalRep(srcPtr, copyPtr) > Tcl_Obj *srcPtr; /* TextIndex obj with internal rep to copy. */ > Tcl_Obj *copyPtr; /* TextIndex obj with internal rep to set. */ > { > int epoch; > TkTextIndex *dupIndexPtr, *indexPtr; > dupIndexPtr = (TkTextIndex*) ckalloc(sizeof(TkTextIndex)); > indexPtr = GET_TEXTINDEX(srcPtr); > epoch = GET_INDEXEPOCH(srcPtr); > > dupIndexPtr->tree = indexPtr->tree; > dupIndexPtr->linePtr = indexPtr->linePtr; > dupIndexPtr->byteIndex = indexPtr->byteIndex; > > SET_TEXTINDEX(copyPtr, dupIndexPtr); > SET_INDEXEPOCH(copyPtr, epoch); > } > > /* > * This will not be called except by TkTextNewIndexObj below. > * This is because if a TkTextIndex is no longer valid, it is > * not possible to regenerate the string representation. > */ > static void > UpdateStringOfTextIndex(objPtr) > Tcl_Obj *objPtr; > { > char buffer[TK_POS_CHARS]; > register int len; > > CONST TkTextIndex *indexPtr = GET_TEXTINDEX(objPtr); > > len = TkTextPrintIndex(indexPtr, buffer); > > objPtr->bytes = ckalloc((unsigned) len + 1); > strcpy(objPtr->bytes, buffer); > objPtr->length = len; > } > > static int > SetTextIndexFromAny(interp, objPtr) > Tcl_Interp *interp; /* Used for error reporting if not NULL. */ > Tcl_Obj *objPtr; /* The object to convert. */ > { > Tcl_AppendToObj(Tcl_GetObjResult(interp), > "can't convert value to textindex except via TkTextGetIndexFromObj API", > -1); > return TCL_ERROR; > } > > /* > *--------------------------------------------------------------------------- > * > * MakeObjIndex -- > * > * This procedure generates a Tcl_Obj description of an index, > * suitable for reading in again later. If the 'textPtr' is NULL > * then we still generate an index object, but it's internal > * description is deemed non-cacheable, and therefore effectively > * useless (apart from as a temporary memory storage). This is used > * for indices whose meaning is very temporary (like @0,0 or the > * name of a mark or tag). The mapping from such strings/objects to > * actual TkTextIndex pointers is not stable to minor text widget > * changes which we do not track (we track insertions/deletions). > * > * Results: > * A pointer to an allocated TkTextIndex which will be freed > * automatically when the Tcl_Obj is used for other purposes. > * > * Side effects: > * A small amount of memory is allocated. > * > *--------------------------------------------------------------------------- > */ > static TkTextIndex* > MakeObjIndex(textPtr, objPtr, origPtr) > TkText *textPtr; /* Information about text widget. */ > Tcl_Obj *objPtr; /* Object containing description of position. */ > CONST TkTextIndex *origPtr; /* Pointer to index. */ > { > TkTextIndex *indexPtr = (TkTextIndex*) ckalloc(sizeof(TkTextIndex)); > > indexPtr->tree = origPtr->tree; > indexPtr->linePtr = origPtr->linePtr; > indexPtr->byteIndex = origPtr->byteIndex; > SET_TEXTINDEX(objPtr, indexPtr); > objPtr->typePtr = &tclTextIndexType; > indexPtr->textPtr = textPtr; > > if (textPtr != NULL) { > textPtr->refCount++; > SET_INDEXEPOCH(objPtr, textPtr->stateEpoch); > } else { > SET_INDEXEPOCH(objPtr, 0); > } > return indexPtr; > } > > CONST TkTextIndex* > TkTextGetIndexFromObj(interp, textPtr, objPtr) > Tcl_Interp *interp; /* Use this for error reporting. */ > TkText *textPtr; /* Information about text widget. */ > Tcl_Obj *objPtr; /* Object containing description of position. */ > { > TkTextIndex index; > TkTextIndex *indexPtr = NULL; > int cache; > > if (objPtr->typePtr == &tclTextIndexType) { > int epoch; > > indexPtr = GET_TEXTINDEX(objPtr); > epoch = GET_INDEXEPOCH(objPtr); > > if (epoch == textPtr->stateEpoch) { > if (indexPtr->textPtr == textPtr) { > return indexPtr; > } > } > } > > /* > * The object is either not an index type or referred to a different > * text widget, or referred to the correct widget, but it is out of > * date (text has been added/deleted since). > */ > > if (GetIndex(interp, textPtr, Tcl_GetString(objPtr), > &index, &cache) != TCL_OK) { > return NULL; > } > > if (objPtr->typePtr != NULL) { > if (objPtr->bytes == NULL) { > objPtr->typePtr->updateStringProc(objPtr); > } > if ((objPtr->typePtr->freeIntRepProc) != NULL) { > (*objPtr->typePtr->freeIntRepProc)(objPtr); > } > } > > if (cache) { > return MakeObjIndex(textPtr, objPtr, &index); > } else { > return MakeObjIndex(NULL, objPtr, &index); > } > } > > /* > *--------------------------------------------------------------------------- > * > * TkTextNewIndexObj -- > * > * This procedure generates a Tcl_Obj description of an index, > * suitable for reading in again later. The index generated is > * effectively stable to all except insertion/deletion operations on > * the widget. > * > * Results: > * A new Tcl_Obj with refCount zero. > * > * Side effects: > * A small amount of memory is allocated. > * > *--------------------------------------------------------------------------- > */ > > Tcl_Obj* > TkTextNewIndexObj(textPtr, indexPtr) > TkText *textPtr; /* text widget for this index */ > CONST TkTextIndex *indexPtr; /* Pointer to index. */ > { > Tcl_Obj *retVal; > > retVal = Tcl_NewObj(); > retVal->bytes = NULL; > > /* > * Assumption that the above call returns an object with > * retVal->typePtr == NULL > */ > MakeObjIndex(textPtr, retVal, indexPtr); > > /* > * Unfortunately, it isn't possible for us to regenerate the > * string representation so we have to create it here, while we > * can be sure the contents of the index are still valid. > */ > UpdateStringOfTextIndex(retVal); > return retVal; > } 296a535,562 > * TkTextGetObjIndex -- > * > * Simpler wrapper around the string based function, but could be > * enhanced with a new object type in the future. > * > * Results: > * see TkTextGetIndex > * > * Side effects: > * None. > * > *--------------------------------------------------------------------------- > */ > > int > TkTextGetObjIndex(interp, textPtr, idxObj, indexPtr) > Tcl_Interp *interp; /* Use this for error reporting. */ > TkText *textPtr; /* Information about text widget. */ > Tcl_Obj *idxObj; /* Object containing textual description > * of position. */ > TkTextIndex *indexPtr; /* Index structure to fill in. */ > { > return GetIndex(interp, textPtr, Tcl_GetString(idxObj), indexPtr, NULL); > } > > /* > *--------------------------------------------------------------------------- > * 319a586,620 > return GetIndex(interp, textPtr, string, indexPtr, NULL); > } > > /* > *--------------------------------------------------------------------------- > * > * GetIndex -- > * > * Given a string, return the index that is described. > * > * Results: > * The return value is a standard Tcl return result. If TCL_OK is > * returned, then everything went well and the index at *indexPtr is > * filled in; otherwise TCL_ERROR is returned and an error message > * is left in the interp's result. > * > * If *canCachePtr is non-NULL, and everything went well, the > * integer it points to is set to 1 if the indexPtr is something > * which can be cached, and zero otherwise. > * > * Side effects: > * None. > * > *--------------------------------------------------------------------------- > */ > > static int > GetIndex(interp, textPtr, string, indexPtr, canCachePtr) > Tcl_Interp *interp; /* Use this for error reporting. */ > TkText *textPtr; /* Information about text widget. */ > CONST char *string; /* Textual description of position. */ > TkTextIndex *indexPtr; /* Index structure to fill in. */ > int *canCachePtr; /* Pointer to integer to store whether > * we can cache the index (or NULL) */ > { 329c630,631 < --- > int canCache = 0; > 445a748 > canCache = 1; 476a780 > canCache = 1; 534a839,841 > if (canCachePtr != NULL) { > *canCachePtr = canCache; > } 554c861,862 < * The characters pointed to by string are modified. --- > * The characters pointed to by string are modified. Returns the > * number of characters in the string. 562c870 < void --- > int 589c897 < sprintf(string, "%d.%d", TkBTreeLineIndex(indexPtr->linePtr) + 1, --- > return sprintf(string, "%d.%d", TkBTreeLineIndex(indexPtr->linePtr) + 1, Index: generic/tkTextMark.c =================================================================== RCS file: /cvsroot/tktoolkit/tk/generic/tkTextMark.c,v retrieving revision 1.6 diff -r1.6 tkTextMark.c 98c98 < TkTextMarkCmd(textPtr, interp, argc, argv) --- > TkTextMarkCmd(textPtr, interp, objc, objv) 101,102c101,102 < int argc; /* Number of arguments. */ < CONST char **argv; /* Argument strings. Someone else has already --- > int objc; /* Number of arguments. */ > Tcl_Obj *CONST objv[]; /* Argument objects. Someone else has already 104c104 < * argv[1] is "mark". */ --- > * objv[1] is "mark". */ 106,107d105 < int c, i; < size_t length; 114,116c112,128 < if (argc < 3) { < Tcl_AppendResult(interp, "wrong # args: should be \"", < argv[0], " mark option ?arg arg ...?\"", (char *) NULL); --- > int optionIndex; > > static CONST char *markOptionStrings[] = { > "gravity", "names", "next", "previous", "set", > "unset", (char *) NULL > }; > enum markOptions { > MARK_GRAVITY, MARK_NAMES, MARK_NEXT, MARK_PREVIOUS, > MARK_SET, MARK_UNSET > }; > > if (objc < 3) { > Tcl_WrongNumArgs(interp, 2, objv, "option ?arg arg ...?"); > return TCL_ERROR; > } > if (Tcl_GetIndexFromObj(interp, objv[2], markOptionStrings, > "mark option", 0, &optionIndex) != TCL_OK) { 119,137c131,162 < c = argv[2][0]; < length = strlen(argv[2]); < if ((c == 'g') && (strncmp(argv[2], "gravity", length) == 0)) { < if (argc < 4 || argc > 5) { < Tcl_AppendResult(interp, "wrong # args: should be \"", < argv[0], " mark gravity markName ?gravity?\"", < (char *) NULL); < return TCL_ERROR; < } < hPtr = Tcl_FindHashEntry(&textPtr->markTable, argv[3]); < if (hPtr == NULL) { < Tcl_AppendResult(interp, "there is no mark named \"", < argv[3], "\"", (char *) NULL); < return TCL_ERROR; < } < markPtr = (TkTextSegment *) Tcl_GetHashValue(hPtr); < if (argc == 4) { < if (markPtr->typePtr == &tkTextRightMarkType) { < Tcl_SetResult(interp, "right", TCL_STATIC); --- > > switch ((enum markOptions)optionIndex) { > case MARK_GRAVITY: { > char c; > size_t length; > char *str; > > if (objc < 4 || objc > 5) { > Tcl_WrongNumArgs(interp, 3, objv, "markName ?gravity?"); > return TCL_ERROR; > } > hPtr = Tcl_FindHashEntry(&textPtr->markTable, Tcl_GetString(objv[3])); > if (hPtr == NULL) { > Tcl_AppendResult(interp, "there is no mark named \"", > Tcl_GetString(objv[3]), "\"", (char *) NULL); > return TCL_ERROR; > } > markPtr = (TkTextSegment *) Tcl_GetHashValue(hPtr); > if (objc == 4) { > if (markPtr->typePtr == &tkTextRightMarkType) { > Tcl_SetResult(interp, "right", TCL_STATIC); > } else { > Tcl_SetResult(interp, "left", TCL_STATIC); > } > return TCL_OK; > } > str = Tcl_GetStringFromObj(objv[4],&length); > c = str[0]; > if ((c == 'l') && (strncmp(str, "left", length) == 0)) { > newTypePtr = &tkTextLeftMarkType; > } else if ((c == 'r') && (strncmp(str, "right", length) == 0)) { > newTypePtr = &tkTextRightMarkType; 139c164,178 < Tcl_SetResult(interp, "left", TCL_STATIC); --- > Tcl_AppendResult(interp, "bad mark gravity \"", str, > "\": must be left or right", (char *) NULL); > return TCL_ERROR; > } > TkTextMarkSegToIndex(textPtr, markPtr, &index); > TkBTreeUnlinkSegment(textPtr->tree, markPtr, > markPtr->body.mark.linePtr); > markPtr->typePtr = newTypePtr; > TkBTreeLinkSegment(markPtr, &index); > break; > } > case MARK_NAMES: { > if (objc != 3) { > Tcl_WrongNumArgs(interp, 3, objv, NULL); > return TCL_ERROR; 140a180,209 > for (hPtr = Tcl_FirstHashEntry(&textPtr->markTable, &search); > hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { > Tcl_AppendElement(interp, > Tcl_GetHashKey(&textPtr->markTable, hPtr)); > } > break; > } > case MARK_NEXT: { > if (objc != 4) { > Tcl_WrongNumArgs(interp, 3, objv, "index"); > return TCL_ERROR; > } > return MarkFindNext(interp, textPtr, Tcl_GetString(objv[3])); > } > case MARK_PREVIOUS: { > if (objc != 4) { > Tcl_WrongNumArgs(interp, 3, objv, "index"); > return TCL_ERROR; > } > return MarkFindPrev(interp, textPtr, Tcl_GetString(objv[3])); > } > case MARK_SET: { > if (objc != 5) { > Tcl_WrongNumArgs(interp, 3, objv, "markName index"); > return TCL_ERROR; > } > if (TkTextGetObjIndex(interp, textPtr, objv[4], &index) != TCL_OK) { > return TCL_ERROR; > } > TkTextSetMark(textPtr, Tcl_GetString(objv[3]), &index); 143,201c212,225 < length = strlen(argv[4]); < c = argv[4][0]; < if ((c == 'l') && (strncmp(argv[4], "left", length) == 0)) { < newTypePtr = &tkTextLeftMarkType; < } else if ((c == 'r') && (strncmp(argv[4], "right", length) == 0)) { < newTypePtr = &tkTextRightMarkType; < } else { < Tcl_AppendResult(interp, "bad mark gravity \"", < argv[4], "\": must be left or right", (char *) NULL); < return TCL_ERROR; < } < TkTextMarkSegToIndex(textPtr, markPtr, &index); < TkBTreeUnlinkSegment(textPtr->tree, markPtr, < markPtr->body.mark.linePtr); < markPtr->typePtr = newTypePtr; < TkBTreeLinkSegment(markPtr, &index); < } else if ((c == 'n') && (strncmp(argv[2], "names", length) == 0)) { < if (argc != 3) { < Tcl_AppendResult(interp, "wrong # args: should be \"", < argv[0], " mark names\"", (char *) NULL); < return TCL_ERROR; < } < for (hPtr = Tcl_FirstHashEntry(&textPtr->markTable, &search); < hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { < Tcl_AppendElement(interp, < Tcl_GetHashKey(&textPtr->markTable, hPtr)); < } < } else if ((c == 'n') && (strncmp(argv[2], "next", length) == 0)) { < if (argc != 4) { < Tcl_AppendResult(interp, "wrong # args: should be \"", < argv[0], " mark next index\"", (char *) NULL); < return TCL_ERROR; < } < return MarkFindNext(interp, textPtr, argv[3]); < } else if ((c == 'p') && (strncmp(argv[2], "previous", length) == 0)) { < if (argc != 4) { < Tcl_AppendResult(interp, "wrong # args: should be \"", < argv[0], " mark previous index\"", (char *) NULL); < return TCL_ERROR; < } < return MarkFindPrev(interp, textPtr, argv[3]); < } else if ((c == 's') && (strncmp(argv[2], "set", length) == 0)) { < if (argc != 5) { < Tcl_AppendResult(interp, "wrong # args: should be \"", < argv[0], " mark set markName index\"", (char *) NULL); < return TCL_ERROR; < } < if (TkTextGetIndex(interp, textPtr, argv[4], &index) != TCL_OK) { < return TCL_ERROR; < } < TkTextSetMark(textPtr, argv[3], &index); < } else if ((c == 'u') && (strncmp(argv[2], "unset", length) == 0)) { < for (i = 3; i < argc; i++) { < hPtr = Tcl_FindHashEntry(&textPtr->markTable, argv[i]); < if (hPtr != NULL) { < markPtr = (TkTextSegment *) Tcl_GetHashValue(hPtr); < if ((markPtr == textPtr->insertMarkPtr) < || (markPtr == textPtr->currentMarkPtr)) { < continue; --- > case MARK_UNSET: { > int i; > for (i = 3; i < objc; i++) { > hPtr = Tcl_FindHashEntry(&textPtr->markTable, Tcl_GetString(objv[i])); > if (hPtr != NULL) { > markPtr = (TkTextSegment *) Tcl_GetHashValue(hPtr); > if ((markPtr == textPtr->insertMarkPtr) > || (markPtr == textPtr->currentMarkPtr)) { > continue; > } > TkBTreeUnlinkSegment(textPtr->tree, markPtr, > markPtr->body.mark.linePtr); > Tcl_DeleteHashEntry(hPtr); > ckfree((char *) markPtr); 203,206d226 < TkBTreeUnlinkSegment(textPtr->tree, markPtr, < markPtr->body.mark.linePtr); < Tcl_DeleteHashEntry(hPtr); < ckfree((char *) markPtr); 207a228 > break; 209,213c230 < } else { < Tcl_AppendResult(interp, "bad mark option \"", argv[2], < "\": must be gravity, names, next, previous, set, or unset", < (char *) NULL); < return TCL_ERROR; --- > Index: generic/tkTextTag.c =================================================================== RCS file: /cvsroot/tktoolkit/tk/generic/tkTextTag.c,v retrieving revision 1.8 diff -r1.8 tkTextTag.c 22,69c22,79 < static Tk_ConfigSpec tagConfigSpecs[] = { < {TK_CONFIG_BORDER, "-background", (char *) NULL, (char *) NULL, < (char *) NULL, Tk_Offset(TkTextTag, border), TK_CONFIG_NULL_OK}, < {TK_CONFIG_BITMAP, "-bgstipple", (char *) NULL, (char *) NULL, < (char *) NULL, Tk_Offset(TkTextTag, bgStipple), TK_CONFIG_NULL_OK}, < {TK_CONFIG_STRING, "-borderwidth", (char *) NULL, (char *) NULL, < "0", Tk_Offset(TkTextTag, bdString), < TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK}, < {TK_CONFIG_STRING, "-elide", (char *) NULL, (char *) NULL, < "0", Tk_Offset(TkTextTag, elideString), < TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK}, < {TK_CONFIG_BITMAP, "-fgstipple", (char *) NULL, (char *) NULL, < (char *) NULL, Tk_Offset(TkTextTag, fgStipple), TK_CONFIG_NULL_OK}, < {TK_CONFIG_FONT, "-font", (char *) NULL, (char *) NULL, < (char *) NULL, Tk_Offset(TkTextTag, tkfont), TK_CONFIG_NULL_OK}, < {TK_CONFIG_COLOR, "-foreground", (char *) NULL, (char *) NULL, < (char *) NULL, Tk_Offset(TkTextTag, fgColor), TK_CONFIG_NULL_OK}, < {TK_CONFIG_STRING, "-justify", (char *) NULL, (char *) NULL, < (char *) NULL, Tk_Offset(TkTextTag, justifyString), TK_CONFIG_NULL_OK}, < {TK_CONFIG_STRING, "-lmargin1", (char *) NULL, (char *) NULL, < (char *) NULL, Tk_Offset(TkTextTag, lMargin1String), TK_CONFIG_NULL_OK}, < {TK_CONFIG_STRING, "-lmargin2", (char *) NULL, (char *) NULL, < (char *) NULL, Tk_Offset(TkTextTag, lMargin2String), TK_CONFIG_NULL_OK}, < {TK_CONFIG_STRING, "-offset", (char *) NULL, (char *) NULL, < (char *) NULL, Tk_Offset(TkTextTag, offsetString), TK_CONFIG_NULL_OK}, < {TK_CONFIG_STRING, "-overstrike", (char *) NULL, (char *) NULL, < (char *) NULL, Tk_Offset(TkTextTag, overstrikeString), < TK_CONFIG_NULL_OK}, < {TK_CONFIG_STRING, "-relief", (char *) NULL, (char *) NULL, < (char *) NULL, Tk_Offset(TkTextTag, reliefString), TK_CONFIG_NULL_OK}, < {TK_CONFIG_STRING, "-rmargin", (char *) NULL, (char *) NULL, < (char *) NULL, Tk_Offset(TkTextTag, rMarginString), TK_CONFIG_NULL_OK}, < {TK_CONFIG_STRING, "-spacing1", (char *) NULL, (char *) NULL, < (char *) NULL, Tk_Offset(TkTextTag, spacing1String), TK_CONFIG_NULL_OK}, < {TK_CONFIG_STRING, "-spacing2", (char *) NULL, (char *) NULL, < (char *) NULL, Tk_Offset(TkTextTag, spacing2String), TK_CONFIG_NULL_OK}, < {TK_CONFIG_STRING, "-spacing3", (char *) NULL, (char *) NULL, < (char *) NULL, Tk_Offset(TkTextTag, spacing3String), TK_CONFIG_NULL_OK}, < {TK_CONFIG_STRING, "-tabs", (char *) NULL, (char *) NULL, < (char *) NULL, Tk_Offset(TkTextTag, tabString), TK_CONFIG_NULL_OK}, < {TK_CONFIG_STRING, "-underline", (char *) NULL, (char *) NULL, < (char *) NULL, Tk_Offset(TkTextTag, underlineString), < TK_CONFIG_NULL_OK}, < {TK_CONFIG_CUSTOM, "-wrap", (char *) NULL, (char *) NULL, < (char *) NULL, Tk_Offset(TkTextTag, wrapMode), < TK_CONFIG_NULL_OK, &textWrapModeOption}, < {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL, < (char *) NULL, 0, 0} --- > /* > * The 'TkWrapMode' enum in tkText.h is used to define a type for the > * -wrap option of tags in a Text widget. These values are used as > * indices into the string table below. Tags are allowed an empty wrap > * value, but the widget as a whole is not. > */ > > static char *wrapStrings[] = { > "char", "none", "word", "", (char *) NULL > }; > > static Tk_OptionSpec tagOptionSpecs[] = { > {TK_OPTION_BORDER, "-background", (char *) NULL, (char *) NULL, > (char *) NULL, -1, Tk_Offset(TkTextTag, border), TK_OPTION_NULL_OK, 0, 0}, > {TK_OPTION_BITMAP, "-bgstipple", (char *) NULL, (char *) NULL, > (char *) NULL, -1, Tk_Offset(TkTextTag, bgStipple), TK_OPTION_NULL_OK, 0, 0}, > {TK_OPTION_PIXELS, "-borderwidth", (char *) NULL, (char *) NULL, > "0", Tk_Offset(TkTextTag, borderWidthPtr), Tk_Offset(TkTextTag, borderWidth), > TK_OPTION_DONT_SET_DEFAULT|TK_OPTION_NULL_OK, 0, 0}, > {TK_OPTION_STRING, "-elide", (char *) NULL, (char *) NULL, > "0", -1, Tk_Offset(TkTextTag, elideString), > TK_OPTION_DONT_SET_DEFAULT|TK_OPTION_NULL_OK, 0, 0}, > {TK_OPTION_BITMAP, "-fgstipple", (char *) NULL, (char *) NULL, > (char *) NULL, -1, Tk_Offset(TkTextTag, fgStipple), TK_OPTION_NULL_OK, 0, 0}, > {TK_OPTION_FONT, "-font", (char *) NULL, (char *) NULL, > (char *) NULL, -1, Tk_Offset(TkTextTag, tkfont), TK_OPTION_NULL_OK, 0, 0}, > {TK_OPTION_COLOR, "-foreground", (char *) NULL, (char *) NULL, > (char *) NULL, -1, Tk_Offset(TkTextTag, fgColor), TK_OPTION_NULL_OK, 0, 0}, > {TK_OPTION_STRING, "-justify", (char *) NULL, (char *) NULL, > (char *) NULL, -1, Tk_Offset(TkTextTag, justifyString), TK_OPTION_NULL_OK, 0, 0}, > {TK_OPTION_STRING, "-lmargin1", (char *) NULL, (char *) NULL, > (char *) NULL, -1, Tk_Offset(TkTextTag, lMargin1String), TK_OPTION_NULL_OK, 0, 0}, > {TK_OPTION_STRING, "-lmargin2", (char *) NULL, (char *) NULL, > (char *) NULL, -1, Tk_Offset(TkTextTag, lMargin2String), TK_OPTION_NULL_OK, 0, 0}, > {TK_OPTION_STRING, "-offset", (char *) NULL, (char *) NULL, > (char *) NULL, -1, Tk_Offset(TkTextTag, offsetString), TK_OPTION_NULL_OK, 0, 0}, > {TK_OPTION_STRING, "-overstrike", (char *) NULL, (char *) NULL, > (char *) NULL, -1, Tk_Offset(TkTextTag, overstrikeString), > TK_OPTION_NULL_OK, 0, 0}, > {TK_OPTION_STRING, "-relief", (char *) NULL, (char *) NULL, > (char *) NULL, -1, Tk_Offset(TkTextTag, reliefString), TK_OPTION_NULL_OK, 0, 0}, > {TK_OPTION_STRING, "-rmargin", (char *) NULL, (char *) NULL, > (char *) NULL, -1, Tk_Offset(TkTextTag, rMarginString), TK_OPTION_NULL_OK, 0, 0}, > {TK_OPTION_STRING, "-spacing1", (char *) NULL, (char *) NULL, > (char *) NULL, -1, Tk_Offset(TkTextTag, spacing1String), TK_OPTION_NULL_OK, 0, 0}, > {TK_OPTION_STRING, "-spacing2", (char *) NULL, (char *) NULL, > (char *) NULL, -1, Tk_Offset(TkTextTag, spacing2String), TK_OPTION_NULL_OK, 0, 0}, > {TK_OPTION_STRING, "-spacing3", (char *) NULL, (char *) NULL, > (char *) NULL, -1, Tk_Offset(TkTextTag, spacing3String), TK_OPTION_NULL_OK, 0, 0}, > {TK_OPTION_STRING, "-tabs", (char *) NULL, (char *) NULL, > (char *) NULL, Tk_Offset(TkTextTag, tabStringPtr), -1, TK_OPTION_NULL_OK, 0, 0}, > {TK_OPTION_STRING, "-underline", (char *) NULL, (char *) NULL, > (char *) NULL, -1, Tk_Offset(TkTextTag, underlineString), > TK_OPTION_NULL_OK, 0, 0}, > {TK_OPTION_STRING_TABLE, "-wrap", (char *) NULL, (char *) NULL, > (char *) NULL, -1, Tk_Offset(TkTextTag, wrapMode), > TK_OPTION_NULL_OK, (ClientData) wrapStrings, 0}, > {TK_OPTION_END} 79c89 < TkText *textPtr, CONST char *tagName)); --- > TkText *textPtr, Tcl_Obj *tagName)); 104c114 < TkTextTagCmd(textPtr, interp, argc, argv) --- > TkTextTagCmd(textPtr, interp, objc, objv) 107,108c117,118 < int argc; /* Number of arguments. */ < CONST char **argv; /* Argument strings. Someone else has already --- > int objc; /* Number of arguments. */ > Tcl_Obj *CONST objv[]; /* Argument objects. Someone else has already 110c120 < * argv[1] is "tag". */ --- > * objv[1] is "tag". */ 112,114c122,135 < int c, i, addTag; < size_t length; < char *fullOption; --- > int optionIndex; > > static CONST char *tagOptionStrings[] = { > "add", "bind", "cget", "configure", "delete", "lower", > "names", "nextrange", "prevrange", "raise", "ranges", > "remove", (char *) NULL > }; > enum tagOptions { > TAG_ADD, TAG_BIND, TAG_CGET, TAG_CONFIGURE, TAG_DELETE, > TAG_LOWER, TAG_NAMES, TAG_NEXTRANGE, TAG_PREVRANGE, > TAG_RAISE, TAG_RANGES, TAG_REMOVE > }; > > int i; 118,120c139,140 < if (argc < 3) { < Tcl_AppendResult(interp, "wrong # args: should be \"", < argv[0], " tag option ?arg arg ...?\"", (char *) NULL); --- > if (objc < 3) { > Tcl_WrongNumArgs(interp, 2, objv, "option ?arg arg ...?"); 123,139c143,160 < c = argv[2][0]; < length = strlen(argv[2]); < if ((c == 'a') && (strncmp(argv[2], "add", length) == 0)) { < fullOption = "add"; < addTag = 1; < < addAndRemove: < if (argc < 5) { < Tcl_AppendResult(interp, "wrong # args: should be \"", < argv[0], " tag ", fullOption, < " tagName index1 ?index2 index1 index2 ...?\"", < (char *) NULL); < return TCL_ERROR; < } < tagPtr = TkTextCreateTag(textPtr, argv[3]); < for (i = 4; i < argc; i += 2) { < if (TkTextGetIndex(interp, textPtr, argv[i], &index1) != TCL_OK) { --- > > if (Tcl_GetIndexFromObj(interp, objv[2], tagOptionStrings, > "tag option", 0, &optionIndex) != TCL_OK) { > return TCL_ERROR; > } > > switch ((enum tagOptions)optionIndex) { > case TAG_ADD: > case TAG_REMOVE: { > int addTag; > if (((enum tagOptions)optionIndex) == TAG_ADD) { > addTag = 1; > } else { > addTag = 0; > } > if (objc < 5) { > Tcl_WrongNumArgs(interp, 3, objv, > "tagName index1 ?index2 index1 index2 ...?"); 142,144c163,165 < if (argc > (i+1)) { < if (TkTextGetIndex(interp, textPtr, argv[i+1], &index2) < != TCL_OK) { --- > tagPtr = TkTextCreateTag(textPtr, Tcl_GetString(objv[3])); > for (i = 4; i < objc; i += 2) { > if (TkTextGetObjIndex(interp, textPtr, objv[i], &index1) != TCL_OK) { 147,148c168,178 < if (TkTextIndexCmp(&index1, &index2) >= 0) { < return TCL_OK; --- > if (objc > (i+1)) { > if (TkTextGetObjIndex(interp, textPtr, objv[i+1], &index2) > != TCL_OK) { > return TCL_ERROR; > } > if (TkTextIndexCmp(&index1, &index2) >= 0) { > return TCL_OK; > } > } else { > index2 = index1; > TkTextIndexForwChars(&index2, 1, &index2); 150,153d179 < } else { < index2 = index1; < TkTextIndexForwChars(&index2, 1, &index2); < } 155,157c181,192 < if (tagPtr->affectsDisplay) { < TkTextRedrawTag(textPtr, &index1, &index2, tagPtr, !addTag); < } else { --- > if (tagPtr->affectsDisplay) { > TkTextRedrawTag(textPtr, &index1, &index2, tagPtr, !addTag); > } else { > /* > * Still need to trigger enter/leave events on tags that > * have changed. > */ > > TkTextEventuallyRepick(textPtr); > } > TkBTreeTag(&index1, &index2, tagPtr, addTag); > 159,160c194,196 < * Still need to trigger enter/leave events on tags that < * have changed. --- > * If the tag is "sel" then grab the selection if we're supposed > * to export it and don't already have it. Also, invalidate > * partially-completed selection retrievals. 163c199,230 < TkTextEventuallyRepick(textPtr); --- > if (tagPtr == textPtr->selTagPtr) { > XEvent event; > /* > * Send an event that the selection changed. > * This is equivalent to > * "event generate $textWidget <>" > */ > > memset((VOID *) &event, 0, sizeof(event)); > event.xany.type = VirtualEvent; > event.xany.serial = NextRequest(Tk_Display(textPtr->tkwin)); > event.xany.send_event = False; > event.xany.window = Tk_WindowId(textPtr->tkwin); > event.xany.display = Tk_Display(textPtr->tkwin); > ((XVirtualEvent *) &event)->name = Tk_GetUid("Selection"); > Tk_HandleEvent(&event); > > if (addTag && textPtr->exportSelection > && !(textPtr->flags & GOT_SELECTION)) { > Tk_OwnSelection(textPtr->tkwin, XA_PRIMARY, > TkTextLostSelection, (ClientData) textPtr); > textPtr->flags |= GOT_SELECTION; > } > textPtr->abortSelections = 1; > } > } > break; > } > case TAG_BIND: { > if ((objc < 4) || (objc > 6)) { > Tcl_WrongNumArgs(interp, 3, objv, "tagName ?sequence? ?command?"); > return TCL_ERROR; 165c232 < TkBTreeTag(&index1, &index2, tagPtr, addTag); --- > tagPtr = TkTextCreateTag(textPtr, Tcl_GetString(objv[3])); 168,170c235,236 < * If the tag is "sel" then grab the selection if we're supposed < * to export it and don't already have it. Also, invalidate < * partially-completed selection retrievals. --- > * Make a binding table if the widget doesn't already have > * one. 173,245c239,240 < if (tagPtr == textPtr->selTagPtr) { < XEvent event; < /* < * Send an event that the selection changed. < * This is equivalent to < * "event generate $textWidget <>" < */ < < memset((VOID *) &event, 0, sizeof(event)); < event.xany.type = VirtualEvent; < event.xany.serial = NextRequest(Tk_Display(textPtr->tkwin)); < event.xany.send_event = False; < event.xany.window = Tk_WindowId(textPtr->tkwin); < event.xany.display = Tk_Display(textPtr->tkwin); < ((XVirtualEvent *) &event)->name = Tk_GetUid("Selection"); < Tk_HandleEvent(&event); < < if (addTag && textPtr->exportSelection < && !(textPtr->flags & GOT_SELECTION)) { < Tk_OwnSelection(textPtr->tkwin, XA_PRIMARY, < TkTextLostSelection, (ClientData) textPtr); < textPtr->flags |= GOT_SELECTION; < } < textPtr->abortSelections = 1; < } < } < } else if ((c == 'b') && (strncmp(argv[2], "bind", length) == 0)) { < if ((argc < 4) || (argc > 6)) { < Tcl_AppendResult(interp, "wrong # args: should be \"", < argv[0], " tag bind tagName ?sequence? ?command?\"", < (char *) NULL); < return TCL_ERROR; < } < tagPtr = TkTextCreateTag(textPtr, argv[3]); < < /* < * Make a binding table if the widget doesn't already have < * one. < */ < < if (textPtr->bindingTable == NULL) { < textPtr->bindingTable = Tk_CreateBindingTable(interp); < } < < if (argc == 6) { < int append = 0; < unsigned long mask; < < if (argv[5][0] == 0) { < return Tk_DeleteBinding(interp, textPtr->bindingTable, < (ClientData) tagPtr, argv[4]); < } < if (argv[5][0] == '+') { < argv[5]++; < append = 1; < } < mask = Tk_CreateBinding(interp, textPtr->bindingTable, < (ClientData) tagPtr, argv[4], argv[5], append); < if (mask == 0) { < return TCL_ERROR; < } < if (mask & (unsigned) ~(ButtonMotionMask|Button1MotionMask < |Button2MotionMask|Button3MotionMask|Button4MotionMask < |Button5MotionMask|ButtonPressMask|ButtonReleaseMask < |EnterWindowMask|LeaveWindowMask|KeyPressMask < |KeyReleaseMask|PointerMotionMask|VirtualEventMask)) { < Tk_DeleteBinding(interp, textPtr->bindingTable, < (ClientData) tagPtr, argv[4]); < Tcl_ResetResult(interp); < Tcl_AppendResult(interp, "requested illegal events; ", < "only key, button, motion, enter, leave, and virtual ", < "events may be used", (char *) NULL); < return TCL_ERROR; --- > if (textPtr->bindingTable == NULL) { > textPtr->bindingTable = Tk_CreateBindingTable(interp); 247,259d241 < } else if (argc == 5) { < CONST char *command; < < command = Tk_GetBinding(interp, textPtr->bindingTable, < (ClientData) tagPtr, argv[4]); < if (command == NULL) { < CONST char *string = Tcl_GetStringResult(interp); < < /* < * Ignore missing binding errors. This is a special hack < * that relies on the error message returned by FindSequence < * in tkBind.c. < */ 261c243,272 < if (string[0] != '\0') { --- > if (objc == 6) { > int append = 0; > unsigned long mask; > char *fifth = Tcl_GetString(objv[5]); > > if (fifth[0] == 0) { > return Tk_DeleteBinding(interp, textPtr->bindingTable, > (ClientData) tagPtr, Tcl_GetString(objv[4])); > } > if (fifth[0] == '+') { > fifth++; > append = 1; > } > mask = Tk_CreateBinding(interp, textPtr->bindingTable, > (ClientData) tagPtr, Tcl_GetString(objv[4]), > fifth, append); > if (mask == 0) { > return TCL_ERROR; > } > if (mask & (unsigned) ~(ButtonMotionMask|Button1MotionMask > |Button2MotionMask|Button3MotionMask|Button4MotionMask > |Button5MotionMask|ButtonPressMask|ButtonReleaseMask > |EnterWindowMask|LeaveWindowMask|KeyPressMask > |KeyReleaseMask|PointerMotionMask|VirtualEventMask)) { > Tk_DeleteBinding(interp, textPtr->bindingTable, > (ClientData) tagPtr, Tcl_GetString(objv[4])); > Tcl_ResetResult(interp); > Tcl_AppendResult(interp, "requested illegal events; ", > "only key, button, motion, enter, leave, and virtual ", > "events may be used", (char *) NULL); 262a274,293 > } > } else if (objc == 5) { > CONST char *command; > > command = Tk_GetBinding(interp, textPtr->bindingTable, > (ClientData) tagPtr, Tcl_GetString(objv[4])); > if (command == NULL) { > CONST char *string = Tcl_GetStringResult(interp); > > /* > * Ignore missing binding errors. This is a special hack > * that relies on the error message returned by FindSequence > * in tkBind.c. > */ > > if (string[0] != '\0') { > return TCL_ERROR; > } else { > Tcl_ResetResult(interp); > } 264c295 < Tcl_ResetResult(interp); --- > Tcl_SetResult(interp, (char *) command, TCL_STATIC); 267c298,299 < Tcl_SetResult(interp, (char *) command, TCL_STATIC); --- > Tk_GetAllBindings(interp, textPtr->bindingTable, > (ClientData) tagPtr); 269,316c301,311 < } else { < Tk_GetAllBindings(interp, textPtr->bindingTable, < (ClientData) tagPtr); < } < } else if ((c == 'c') && (strncmp(argv[2], "cget", length) == 0) < && (length >= 2)) { < if (argc != 5) { < Tcl_AppendResult(interp, "wrong # args: should be \"", < argv[0], " tag cget tagName option\"", < (char *) NULL); < return TCL_ERROR; < } < tagPtr = FindTag(interp, textPtr, argv[3]); < if (tagPtr == NULL) { < return TCL_ERROR; < } < return Tk_ConfigureValue(interp, textPtr->tkwin, tagConfigSpecs, < (char *) tagPtr, argv[4], 0); < } else if ((c == 'c') && (strncmp(argv[2], "configure", length) == 0) < && (length >= 2)) { < if (argc < 4) { < Tcl_AppendResult(interp, "wrong # args: should be \"", < argv[0], " tag configure tagName ?option? ?value? ", < "?option value ...?\"", (char *) NULL); < return TCL_ERROR; < } < tagPtr = TkTextCreateTag(textPtr, argv[3]); < if (argc == 4) { < return Tk_ConfigureInfo(interp, textPtr->tkwin, tagConfigSpecs, < (char *) tagPtr, (char *) NULL, 0); < } else if (argc == 5) { < return Tk_ConfigureInfo(interp, textPtr->tkwin, tagConfigSpecs, < (char *) tagPtr, argv[4], 0); < } else { < int result; < < result = Tk_ConfigureWidget(interp, textPtr->tkwin, tagConfigSpecs, < argc-4, argv+4, (char *) tagPtr, 0); < /* < * Some of the configuration options, like -underline < * and -justify, require additional translation (this is < * needed because we need to distinguish a particular value < * of an option from "unspecified"). < */ < < if (tagPtr->bdString != NULL) { < if (Tk_GetPixels(interp, textPtr->tkwin, tagPtr->bdString, < &tagPtr->borderWidth) != TCL_OK) { --- > break; > } > case TAG_CGET: { > if (objc != 5) { > Tcl_WrongNumArgs(interp, 1, objv, "tag cget tagName option"); > return TCL_ERROR; > } else { > Tcl_Obj *objPtr; > > tagPtr = FindTag(interp, textPtr, objv[3]); > if (tagPtr == NULL) { 319,325c314,316 < if (tagPtr->borderWidth < 0) { < tagPtr->borderWidth = 0; < } < } < if (tagPtr->reliefString != NULL) { < if (Tk_GetRelief(interp, tagPtr->reliefString, < &tagPtr->relief) != TCL_OK) { --- > objPtr = Tk_GetOptionValue(interp, (char *) tagPtr, > tagPtr->optionTable, objv[4], textPtr->tkwin); > if (objPtr == NULL) { 326a318,320 > } else { > Tcl_SetObjResult(interp, objPtr); > return TCL_OK; 329,333c323,328 < if (tagPtr->justifyString != NULL) { < if (Tk_GetJustify(interp, tagPtr->justifyString, < &tagPtr->justify) != TCL_OK) { < return TCL_ERROR; < } --- > break; > } > case TAG_CONFIGURE: { > if (objc < 4) { > Tcl_WrongNumArgs(interp, 3, objv, "tagName ?option? ?value? ?option value ...?"); > return TCL_ERROR; 335,337c330,336 < if (tagPtr->lMargin1String != NULL) { < if (Tk_GetPixels(interp, textPtr->tkwin, < tagPtr->lMargin1String, &tagPtr->lMargin1) != TCL_OK) { --- > tagPtr = TkTextCreateTag(textPtr, Tcl_GetString(objv[3])); > if (objc <= 5) { > Tcl_Obj* objPtr = Tk_GetOptionInfo(interp, (char *) tagPtr, > tagPtr->optionTable, > (objc == 5) ? objv[4] : (Tcl_Obj *) NULL, > textPtr->tkwin); > if (objPtr == NULL) { 338a338,340 > } else { > Tcl_SetObjResult(interp, objPtr); > return TCL_OK; 340,343c342,346 < } < if (tagPtr->lMargin2String != NULL) { < if (Tk_GetPixels(interp, textPtr->tkwin, < tagPtr->lMargin2String, &tagPtr->lMargin2) != TCL_OK) { --- > } else { > int result = TCL_OK; > > if (Tk_SetOptions(interp, (char*)tagPtr, tagPtr->optionTable, > objc-4, objv+4, textPtr->tkwin, NULL, NULL) != TCL_OK) { 346,350c349,357 < } < if (tagPtr->offsetString != NULL) { < if (Tk_GetPixels(interp, textPtr->tkwin, tagPtr->offsetString, < &tagPtr->offset) != TCL_OK) { < return TCL_ERROR; --- > /* > * Some of the configuration options, like -underline > * and -justify, require additional translation (this is > * needed because we need to distinguish a particular value > * of an option from "unspecified"). > */ > > if (tagPtr->borderWidth < 0) { > tagPtr->borderWidth = 0; 352,356c359,449 < } < if (tagPtr->overstrikeString != NULL) { < if (Tcl_GetBoolean(interp, tagPtr->overstrikeString, < &tagPtr->overstrike) != TCL_OK) { < return TCL_ERROR; --- > if (tagPtr->reliefString != NULL) { > if (Tk_GetRelief(interp, tagPtr->reliefString, > &tagPtr->relief) != TCL_OK) { > return TCL_ERROR; > } > } > if (tagPtr->justifyString != NULL) { > if (Tk_GetJustify(interp, tagPtr->justifyString, > &tagPtr->justify) != TCL_OK) { > return TCL_ERROR; > } > } > if (tagPtr->lMargin1String != NULL) { > if (Tk_GetPixels(interp, textPtr->tkwin, > tagPtr->lMargin1String, &tagPtr->lMargin1) != TCL_OK) { > return TCL_ERROR; > } > } > if (tagPtr->lMargin2String != NULL) { > if (Tk_GetPixels(interp, textPtr->tkwin, > tagPtr->lMargin2String, &tagPtr->lMargin2) != TCL_OK) { > return TCL_ERROR; > } > } > if (tagPtr->offsetString != NULL) { > if (Tk_GetPixels(interp, textPtr->tkwin, tagPtr->offsetString, > &tagPtr->offset) != TCL_OK) { > return TCL_ERROR; > } > } > if (tagPtr->overstrikeString != NULL) { > if (Tcl_GetBoolean(interp, tagPtr->overstrikeString, > &tagPtr->overstrike) != TCL_OK) { > return TCL_ERROR; > } > } > if (tagPtr->rMarginString != NULL) { > if (Tk_GetPixels(interp, textPtr->tkwin, > tagPtr->rMarginString, &tagPtr->rMargin) != TCL_OK) { > return TCL_ERROR; > } > } > if (tagPtr->spacing1String != NULL) { > if (Tk_GetPixels(interp, textPtr->tkwin, > tagPtr->spacing1String, &tagPtr->spacing1) != TCL_OK) { > return TCL_ERROR; > } > if (tagPtr->spacing1 < 0) { > tagPtr->spacing1 = 0; > } > } > if (tagPtr->spacing2String != NULL) { > if (Tk_GetPixels(interp, textPtr->tkwin, > tagPtr->spacing2String, &tagPtr->spacing2) != TCL_OK) { > return TCL_ERROR; > } > if (tagPtr->spacing2 < 0) { > tagPtr->spacing2 = 0; > } > } > if (tagPtr->spacing3String != NULL) { > if (Tk_GetPixels(interp, textPtr->tkwin, > tagPtr->spacing3String, &tagPtr->spacing3) != TCL_OK) { > return TCL_ERROR; > } > if (tagPtr->spacing3 < 0) { > tagPtr->spacing3 = 0; > } > } > if (tagPtr->tabArrayPtr != NULL) { > ckfree((char *) tagPtr->tabArrayPtr); > tagPtr->tabArrayPtr = NULL; > } > if (tagPtr->tabStringPtr != NULL) { > tagPtr->tabArrayPtr = TkTextGetTabs(interp, textPtr->tkwin, > tagPtr->tabStringPtr); > if (tagPtr->tabArrayPtr == NULL) { > return TCL_ERROR; > } > } > if (tagPtr->underlineString != NULL) { > if (Tcl_GetBoolean(interp, tagPtr->underlineString, > &tagPtr->underline) != TCL_OK) { > return TCL_ERROR; > } > } > if (tagPtr->elideString != NULL) { > if (Tcl_GetBoolean(interp, tagPtr->elideString, > &tagPtr->elide) != TCL_OK) { > return TCL_ERROR; > } 358,362c451,485 < } < if (tagPtr->rMarginString != NULL) { < if (Tk_GetPixels(interp, textPtr->tkwin, < tagPtr->rMarginString, &tagPtr->rMargin) != TCL_OK) { < return TCL_ERROR; --- > > /* > * If the "sel" tag was changed, be sure to mirror information > * from the tag back into the text widget record. NOTE: we > * don't have to free up information in the widget record > * before overwriting it, because it was mirrored in the tag > * and hence freed when the tag field was overwritten. > */ > > if (tagPtr == textPtr->selTagPtr) { > textPtr->selBorder = tagPtr->border; > textPtr->selBorderWidth = tagPtr->borderWidth; > textPtr->selBorderWidthPtr = tagPtr->borderWidthPtr; > textPtr->selFgColorPtr = tagPtr->fgColor; > } > tagPtr->affectsDisplay = 0; > if ((tagPtr->border != NULL) > || (tagPtr->reliefString != NULL) > || (tagPtr->bgStipple != None) > || (tagPtr->fgColor != NULL) || (tagPtr->tkfont != None) > || (tagPtr->fgStipple != None) > || (tagPtr->justifyString != NULL) > || (tagPtr->lMargin1String != NULL) > || (tagPtr->lMargin2String != NULL) > || (tagPtr->offsetString != NULL) > || (tagPtr->overstrikeString != NULL) > || (tagPtr->rMarginString != NULL) > || (tagPtr->spacing1String != NULL) > || (tagPtr->spacing2String != NULL) > || (tagPtr->spacing3String != NULL) > || (tagPtr->tabStringPtr != NULL) > || (tagPtr->underlineString != NULL) > || (tagPtr->elideString != NULL) > || (tagPtr->wrapMode != TEXT_WRAPMODE_NULL)) { > tagPtr->affectsDisplay = 1; 363a487,489 > TkTextRedrawTag(textPtr, (TkTextIndex *) NULL, > (TkTextIndex *) NULL, tagPtr, 1); > return result; 365,371c491,539 < if (tagPtr->spacing1String != NULL) { < if (Tk_GetPixels(interp, textPtr->tkwin, < tagPtr->spacing1String, &tagPtr->spacing1) != TCL_OK) { < return TCL_ERROR; < } < if (tagPtr->spacing1 < 0) { < tagPtr->spacing1 = 0; --- > break; > } > case TAG_DELETE: { > Tcl_HashEntry *hPtr; > > if (objc < 4) { > Tcl_WrongNumArgs(interp, 3, objv, "tagName ?tagName ...?"); > return TCL_ERROR; > } > for (i = 3; i < objc; i++) { > hPtr = Tcl_FindHashEntry(&textPtr->tagTable, Tcl_GetString(objv[i])); > if (hPtr == NULL) { > continue; > } > tagPtr = (TkTextTag *) Tcl_GetHashValue(hPtr); > if (tagPtr == textPtr->selTagPtr) { > continue; > } > if (tagPtr->affectsDisplay) { > TkTextRedrawTag(textPtr, (TkTextIndex *) NULL, > (TkTextIndex *) NULL, tagPtr, 1); > } > TkTextMakeByteIndex(textPtr->tree, 0, 0, &first); > TkTextMakeByteIndex(textPtr->tree, TkBTreeNumLines(textPtr->tree), > 0, &last), > TkBTreeTag(&first, &last, tagPtr, 0); > > if (tagPtr == textPtr->selTagPtr) { > XEvent event; > /* > * Send an event that the selection changed. > * This is equivalent to > * "event generate $textWidget <>" > */ > > memset((VOID *) &event, 0, sizeof(event)); > event.xany.type = VirtualEvent; > event.xany.serial = NextRequest(Tk_Display(textPtr->tkwin)); > event.xany.send_event = False; > event.xany.window = Tk_WindowId(textPtr->tkwin); > event.xany.display = Tk_Display(textPtr->tkwin); > ((XVirtualEvent *) &event)->name = Tk_GetUid("Selection"); > Tk_HandleEvent(&event); > } > > Tcl_DeleteHashEntry(hPtr); > if (textPtr->bindingTable != NULL) { > Tk_DeleteAllBindings(textPtr->bindingTable, > (ClientData) tagPtr); 372a541,562 > > /* > * Update the tag priorities to reflect the deletion of this tag. > */ > > ChangeTagPriority(textPtr, tagPtr, textPtr->numTags-1); > textPtr->numTags -= 1; > TkTextFreeTag(textPtr, tagPtr); > } > break; > } > case TAG_LOWER: { > TkTextTag *tagPtr2; > int prio; > > if ((objc != 4) && (objc != 5)) { > Tcl_WrongNumArgs(interp, 3, objv, "tagName ?belowThis?"); > return TCL_ERROR; > } > tagPtr = FindTag(interp, textPtr, objv[3]); > if (tagPtr == NULL) { > return TCL_ERROR; 374,376c564,566 < if (tagPtr->spacing2String != NULL) { < if (Tk_GetPixels(interp, textPtr->tkwin, < tagPtr->spacing2String, &tagPtr->spacing2) != TCL_OK) { --- > if (objc == 5) { > tagPtr2 = FindTag(interp, textPtr, objv[4]); > if (tagPtr2 == NULL) { 379,380c569,572 < if (tagPtr->spacing2 < 0) { < tagPtr->spacing2 = 0; --- > if (tagPtr->priority < tagPtr2->priority) { > prio = tagPtr2->priority - 1; > } else { > prio = tagPtr2->priority; 381a574,588 > } else { > prio = 0; > } > ChangeTagPriority(textPtr, tagPtr, prio); > TkTextRedrawTag(textPtr, (TkTextIndex *) NULL, (TkTextIndex *) NULL, > tagPtr, 1); > break; > } > case TAG_NAMES: { > TkTextTag **arrayPtr; > int arraySize; > > if ((objc != 3) && (objc != 4)) { > Tcl_WrongNumArgs(interp, 3, objv, "?index?"); > return TCL_ERROR; 383,385c590,603 < if (tagPtr->spacing3String != NULL) { < if (Tk_GetPixels(interp, textPtr->tkwin, < tagPtr->spacing3String, &tagPtr->spacing3) != TCL_OK) { --- > if (objc == 3) { > Tcl_HashSearch search; > Tcl_HashEntry *hPtr; > > arrayPtr = (TkTextTag **) ckalloc((unsigned) > (textPtr->numTags * sizeof(TkTextTag *))); > for (i = 0, hPtr = Tcl_FirstHashEntry(&textPtr->tagTable, &search); > hPtr != NULL; i++, hPtr = Tcl_NextHashEntry(&search)) { > arrayPtr[i] = (TkTextTag *) Tcl_GetHashValue(hPtr); > } > arraySize = textPtr->numTags; > } else { > if (TkTextGetObjIndex(interp, textPtr, objv[3], &index1) > != TCL_OK) { 388,389c606,608 < if (tagPtr->spacing3 < 0) { < tagPtr->spacing3 = 0; --- > arrayPtr = TkBTreeGetTags(&index1, &arraySize); > if (arrayPtr == NULL) { > return TCL_OK; 392,401c611,625 < if (tagPtr->tabArrayPtr != NULL) { < ckfree((char *) tagPtr->tabArrayPtr); < tagPtr->tabArrayPtr = NULL; < } < if (tagPtr->tabString != NULL) { < tagPtr->tabArrayPtr = TkTextGetTabs(interp, textPtr->tkwin, < tagPtr->tabString); < if (tagPtr->tabArrayPtr == NULL) { < return TCL_ERROR; < } --- > SortTags(arraySize, arrayPtr); > for (i = 0; i < arraySize; i++) { > tagPtr = arrayPtr[i]; > Tcl_AppendElement(interp, tagPtr->name); > } > ckfree((char *) arrayPtr); > break; > } > case TAG_NEXTRANGE: { > TkTextSearch tSearch; > char position[TK_POS_CHARS]; > > if ((objc != 5) && (objc != 6)) { > Tcl_WrongNumArgs(interp, 3, objv, "tagName index1 ?index2?"); > return TCL_ERROR; 403,407c627,629 < if (tagPtr->underlineString != NULL) { < if (Tcl_GetBoolean(interp, tagPtr->underlineString, < &tagPtr->underline) != TCL_OK) { < return TCL_ERROR; < } --- > tagPtr = FindTag((Tcl_Interp *) NULL, textPtr, objv[3]); > if (tagPtr == NULL) { > return TCL_OK; 409,413c631,640 < if (tagPtr->elideString != NULL) { < if (Tcl_GetBoolean(interp, tagPtr->elideString, < &tagPtr->elide) != TCL_OK) { < return TCL_ERROR; < } --- > if (TkTextGetObjIndex(interp, textPtr, objv[4], &index1) != TCL_OK) { > return TCL_ERROR; > } > TkTextMakeByteIndex(textPtr->tree, TkBTreeNumLines(textPtr->tree), > 0, &last); > if (objc == 5) { > index2 = last; > } else if (TkTextGetObjIndex(interp, textPtr, objv[5], &index2) > != TCL_OK) { > return TCL_ERROR; 417,421c644,650 < * If the "sel" tag was changed, be sure to mirror information < * from the tag back into the text widget record. NOTE: we < * don't have to free up information in the widget record < * before overwriting it, because it was mirrored in the tag < * and hence freed when the tag field was overwritten. --- > * The search below is a bit tricky. Rather than use the B-tree > * facilities to stop the search at index2, let it search up > * until the end of the file but check for a position past index2 > * ourselves. The reason for doing it this way is that we only > * care whether the *start* of the range is before index2; once > * we find the start, we don't want TkBTreeNextTag to abort the > * search because the end of the range is after index2. 424,480c653,656 < if (tagPtr == textPtr->selTagPtr) { < textPtr->selBorder = tagPtr->border; < textPtr->selBdString = tagPtr->bdString; < textPtr->selFgColorPtr = tagPtr->fgColor; < } < tagPtr->affectsDisplay = 0; < if ((tagPtr->border != NULL) < || (tagPtr->bdString != NULL) < || (tagPtr->reliefString != NULL) < || (tagPtr->bgStipple != None) < || (tagPtr->fgColor != NULL) || (tagPtr->tkfont != None) < || (tagPtr->fgStipple != None) < || (tagPtr->justifyString != NULL) < || (tagPtr->lMargin1String != NULL) < || (tagPtr->lMargin2String != NULL) < || (tagPtr->offsetString != NULL) < || (tagPtr->overstrikeString != NULL) < || (tagPtr->rMarginString != NULL) < || (tagPtr->spacing1String != NULL) < || (tagPtr->spacing2String != NULL) < || (tagPtr->spacing3String != NULL) < || (tagPtr->tabString != NULL) < || (tagPtr->underlineString != NULL) < || (tagPtr->elideString != NULL) < || (tagPtr->wrapMode != TEXT_WRAPMODE_NULL)) { < tagPtr->affectsDisplay = 1; < } < TkTextRedrawTag(textPtr, (TkTextIndex *) NULL, < (TkTextIndex *) NULL, tagPtr, 1); < return result; < } < } else if ((c == 'd') && (strncmp(argv[2], "delete", length) == 0)) { < Tcl_HashEntry *hPtr; < < if (argc < 4) { < Tcl_AppendResult(interp, "wrong # args: should be \"", < argv[0], " tag delete tagName tagName ...\"", < (char *) NULL); < return TCL_ERROR; < } < for (i = 3; i < argc; i++) { < hPtr = Tcl_FindHashEntry(&textPtr->tagTable, argv[i]); < if (hPtr == NULL) { < continue; < } < tagPtr = (TkTextTag *) Tcl_GetHashValue(hPtr); < if (tagPtr == textPtr->selTagPtr) { < continue; < } < if (tagPtr->affectsDisplay) { < TkTextRedrawTag(textPtr, (TkTextIndex *) NULL, < (TkTextIndex *) NULL, tagPtr, 1); < } < TkTextMakeByteIndex(textPtr->tree, 0, 0, &first); < TkTextMakeByteIndex(textPtr->tree, TkBTreeNumLines(textPtr->tree), < 0, &last), < TkBTreeTag(&first, &last, tagPtr, 0); --- > TkBTreeStartSearch(&index1, &last, tagPtr, &tSearch); > if (TkBTreeCharTagged(&index1, tagPtr)) { > TkTextSegment *segPtr; > int offset; 482,483d657 < if (tagPtr == textPtr->selTagPtr) { < XEvent event; 485,487c659,661 < * Send an event that the selection changed. < * This is equivalent to < * "event generate $textWidget <>" --- > * The first character is tagged. See if there is an > * on-toggle just before the character. If not, then > * skip to the end of this tagged range. 490,497c664,674 < memset((VOID *) &event, 0, sizeof(event)); < event.xany.type = VirtualEvent; < event.xany.serial = NextRequest(Tk_Display(textPtr->tkwin)); < event.xany.send_event = False; < event.xany.window = Tk_WindowId(textPtr->tkwin); < event.xany.display = Tk_Display(textPtr->tkwin); < ((XVirtualEvent *) &event)->name = Tk_GetUid("Selection"); < Tk_HandleEvent(&event); --- > for (segPtr = index1.linePtr->segPtr, offset = index1.byteIndex; > offset >= 0; > offset -= segPtr->size, segPtr = segPtr->nextPtr) { > if ((offset == 0) && (segPtr->typePtr == &tkTextToggleOnType) > && (segPtr->body.toggle.tagPtr == tagPtr)) { > goto gotStart; > } > } > if (!TkBTreeNextTag(&tSearch)) { > return TCL_OK; > } 500,505d676 < Tcl_DeleteHashEntry(hPtr); < if (textPtr->bindingTable != NULL) { < Tk_DeleteAllBindings(textPtr->bindingTable, < (ClientData) tagPtr); < } < 507c678 < * Update the tag priorities to reflect the deletion of this tag. --- > * Find the start of the tagged range. 510,531c681,682 < ChangeTagPriority(textPtr, tagPtr, textPtr->numTags-1); < textPtr->numTags -= 1; < TkTextFreeTag(textPtr, tagPtr); < } < } else if ((c == 'l') && (strncmp(argv[2], "lower", length) == 0)) { < TkTextTag *tagPtr2; < int prio; < < if ((argc != 4) && (argc != 5)) { < Tcl_AppendResult(interp, "wrong # args: should be \"", < argv[0], " tag lower tagName ?belowThis?\"", < (char *) NULL); < return TCL_ERROR; < } < tagPtr = FindTag(interp, textPtr, argv[3]); < if (tagPtr == NULL) { < return TCL_ERROR; < } < if (argc == 5) { < tagPtr2 = FindTag(interp, textPtr, argv[4]); < if (tagPtr2 == NULL) { < return TCL_ERROR; --- > if (!TkBTreeNextTag(&tSearch)) { > return TCL_OK; 533,536c684,686 < if (tagPtr->priority < tagPtr2->priority) { < prio = tagPtr2->priority - 1; < } else { < prio = tagPtr2->priority; --- > gotStart: > if (TkTextIndexCmp(&tSearch.curIndex, &index2) >= 0) { > return TCL_OK; 538,553c688,693 < } else { < prio = 0; < } < ChangeTagPriority(textPtr, tagPtr, prio); < TkTextRedrawTag(textPtr, (TkTextIndex *) NULL, (TkTextIndex *) NULL, < tagPtr, 1); < } else if ((c == 'n') && (strncmp(argv[2], "names", length) == 0) < && (length >= 2)) { < TkTextTag **arrayPtr; < int arraySize; < < if ((argc != 3) && (argc != 4)) { < Tcl_AppendResult(interp, "wrong # args: should be \"", < argv[0], " tag names ?index?\"", < (char *) NULL); < return TCL_ERROR; --- > TkTextPrintIndex(&tSearch.curIndex, position); > Tcl_AppendElement(interp, position); > TkBTreeNextTag(&tSearch); > TkTextPrintIndex(&tSearch.curIndex, position); > Tcl_AppendElement(interp, position); > break; 555,557c695,698 < if (argc == 3) { < Tcl_HashSearch search; < Tcl_HashEntry *hPtr; --- > case TAG_PREVRANGE: { > TkTextSearch tSearch; > char position1[TK_POS_CHARS]; > char position2[TK_POS_CHARS]; 559,568c700,701 < arrayPtr = (TkTextTag **) ckalloc((unsigned) < (textPtr->numTags * sizeof(TkTextTag *))); < for (i = 0, hPtr = Tcl_FirstHashEntry(&textPtr->tagTable, &search); < hPtr != NULL; i++, hPtr = Tcl_NextHashEntry(&search)) { < arrayPtr[i] = (TkTextTag *) Tcl_GetHashValue(hPtr); < } < arraySize = textPtr->numTags; < } else { < if (TkTextGetIndex(interp, textPtr, argv[3], &index1) < != TCL_OK) { --- > if ((objc != 5) && (objc != 6)) { > Tcl_WrongNumArgs(interp, 3, objv, "tagName index1 ?index2?"); 571,572c704,705 < arrayPtr = TkBTreeGetTags(&index1, &arraySize); < if (arrayPtr == NULL) { --- > tagPtr = FindTag((Tcl_Interp *) NULL, textPtr, objv[3]); > if (tagPtr == NULL) { 575,622c708,716 < } < SortTags(arraySize, arrayPtr); < for (i = 0; i < arraySize; i++) { < tagPtr = arrayPtr[i]; < Tcl_AppendElement(interp, tagPtr->name); < } < ckfree((char *) arrayPtr); < } else if ((c == 'n') && (strncmp(argv[2], "nextrange", length) == 0) < && (length >= 2)) { < TkTextSearch tSearch; < char position[TK_POS_CHARS]; < < if ((argc != 5) && (argc != 6)) { < Tcl_AppendResult(interp, "wrong # args: should be \"", < argv[0], " tag nextrange tagName index1 ?index2?\"", < (char *) NULL); < return TCL_ERROR; < } < tagPtr = FindTag((Tcl_Interp *) NULL, textPtr, argv[3]); < if (tagPtr == NULL) { < return TCL_OK; < } < if (TkTextGetIndex(interp, textPtr, argv[4], &index1) != TCL_OK) { < return TCL_ERROR; < } < TkTextMakeByteIndex(textPtr->tree, TkBTreeNumLines(textPtr->tree), < 0, &last); < if (argc == 5) { < index2 = last; < } else if (TkTextGetIndex(interp, textPtr, argv[5], &index2) < != TCL_OK) { < return TCL_ERROR; < } < < /* < * The search below is a bit tricky. Rather than use the B-tree < * facilities to stop the search at index2, let it search up < * until the end of the file but check for a position past index2 < * ourselves. The reason for doing it this way is that we only < * care whether the *start* of the range is before index2; once < * we find the start, we don't want TkBTreeNextTag to abort the < * search because the end of the range is after index2. < */ < < TkBTreeStartSearch(&index1, &last, tagPtr, &tSearch); < if (TkBTreeCharTagged(&index1, tagPtr)) { < TkTextSegment *segPtr; < int offset; --- > if (TkTextGetObjIndex(interp, textPtr, objv[4], &index1) != TCL_OK) { > return TCL_ERROR; > } > if (objc == 5) { > TkTextMakeByteIndex(textPtr->tree, 0, 0, &index2); > } else if (TkTextGetObjIndex(interp, textPtr, objv[5], &index2) > != TCL_OK) { > return TCL_ERROR; > } 625,627c719,722 < * The first character is tagged. See if there is an < * on-toggle just before the character. If not, then < * skip to the end of this tagged range. --- > * The search below is a bit weird. The previous toggle can be > * either an on or off toggle. If it is an on toggle, then we > * need to turn around and search forward for the end toggle. > * Otherwise we keep searching backwards. 630,636c725,728 < for (segPtr = index1.linePtr->segPtr, offset = index1.byteIndex; < offset >= 0; < offset -= segPtr->size, segPtr = segPtr->nextPtr) { < if ((offset == 0) && (segPtr->typePtr == &tkTextToggleOnType) < && (segPtr->body.toggle.tagPtr == tagPtr)) { < goto gotStart; < } --- > TkBTreeStartSearchBack(&index1, &index2, tagPtr, &tSearch); > > if (!TkBTreePrevTag(&tSearch)) { > return TCL_OK; 638,639c730,743 < if (!TkBTreeNextTag(&tSearch)) { < return TCL_OK; --- > if (tSearch.segPtr->typePtr == &tkTextToggleOnType) { > TkTextPrintIndex(&tSearch.curIndex, position1); > TkTextMakeByteIndex(textPtr->tree, TkBTreeNumLines(textPtr->tree), > 0, &last); > TkBTreeStartSearch(&tSearch.curIndex, &last, tagPtr, &tSearch); > TkBTreeNextTag(&tSearch); > TkTextPrintIndex(&tSearch.curIndex, position2); > } else { > TkTextPrintIndex(&tSearch.curIndex, position2); > TkBTreePrevTag(&tSearch); > if (TkTextIndexCmp(&tSearch.curIndex, &index2) < 0) { > return TCL_OK; > } > TkTextPrintIndex(&tSearch.curIndex, position1); 641,690c745,751 < } < < /* < * Find the start of the tagged range. < */ < < if (!TkBTreeNextTag(&tSearch)) { < return TCL_OK; < } < gotStart: < if (TkTextIndexCmp(&tSearch.curIndex, &index2) >= 0) { < return TCL_OK; < } < TkTextPrintIndex(&tSearch.curIndex, position); < Tcl_AppendElement(interp, position); < TkBTreeNextTag(&tSearch); < TkTextPrintIndex(&tSearch.curIndex, position); < Tcl_AppendElement(interp, position); < } else if ((c == 'p') && (strncmp(argv[2], "prevrange", length) == 0) < && (length >= 2)) { < TkTextSearch tSearch; < char position1[TK_POS_CHARS]; < char position2[TK_POS_CHARS]; < < if ((argc != 5) && (argc != 6)) { < Tcl_AppendResult(interp, "wrong # args: should be \"", < argv[0], " tag prevrange tagName index1 ?index2?\"", < (char *) NULL); < return TCL_ERROR; < } < tagPtr = FindTag((Tcl_Interp *) NULL, textPtr, argv[3]); < if (tagPtr == NULL) { < return TCL_OK; < } < if (TkTextGetIndex(interp, textPtr, argv[4], &index1) != TCL_OK) { < return TCL_ERROR; < } < if (argc == 5) { < TkTextMakeByteIndex(textPtr->tree, 0, 0, &index2); < } else if (TkTextGetIndex(interp, textPtr, argv[5], &index2) < != TCL_OK) { < return TCL_ERROR; < } < < /* < * The search below is a bit weird. The previous toggle can be < * either an on or off toggle. If it is an on toggle, then we < * need to turn around and search forward for the end toggle. < * Otherwise we keep searching backwards. < */ --- > Tcl_AppendElement(interp, position1); > Tcl_AppendElement(interp, position2); > break; > } > case TAG_RAISE: { > TkTextTag *tagPtr2; > int prio; 692,708c753,755 < TkBTreeStartSearchBack(&index1, &index2, tagPtr, &tSearch); < < if (!TkBTreePrevTag(&tSearch)) { < return TCL_OK; < } < if (tSearch.segPtr->typePtr == &tkTextToggleOnType) { < TkTextPrintIndex(&tSearch.curIndex, position1); < TkTextMakeByteIndex(textPtr->tree, TkBTreeNumLines(textPtr->tree), < 0, &last); < TkBTreeStartSearch(&tSearch.curIndex, &last, tagPtr, &tSearch); < TkBTreeNextTag(&tSearch); < TkTextPrintIndex(&tSearch.curIndex, position2); < } else { < TkTextPrintIndex(&tSearch.curIndex, position2); < TkBTreePrevTag(&tSearch); < if (TkTextIndexCmp(&tSearch.curIndex, &index2) < 0) { < return TCL_OK; --- > if ((objc != 4) && (objc != 5)) { > Tcl_WrongNumArgs(interp, 3, objv, "tagName ?aboveThis?"); > return TCL_ERROR; 710,731c757,758 < TkTextPrintIndex(&tSearch.curIndex, position1); < } < Tcl_AppendElement(interp, position1); < Tcl_AppendElement(interp, position2); < } else if ((c == 'r') && (strncmp(argv[2], "raise", length) == 0) < && (length >= 3)) { < TkTextTag *tagPtr2; < int prio; < < if ((argc != 4) && (argc != 5)) { < Tcl_AppendResult(interp, "wrong # args: should be \"", < argv[0], " tag raise tagName ?aboveThis?\"", < (char *) NULL); < return TCL_ERROR; < } < tagPtr = FindTag(interp, textPtr, argv[3]); < if (tagPtr == NULL) { < return TCL_ERROR; < } < if (argc == 5) { < tagPtr2 = FindTag(interp, textPtr, argv[4]); < if (tagPtr2 == NULL) { --- > tagPtr = FindTag(interp, textPtr, objv[3]); > if (tagPtr == NULL) { 734,735c761,770 < if (tagPtr->priority <= tagPtr2->priority) { < prio = tagPtr2->priority; --- > if (objc == 5) { > tagPtr2 = FindTag(interp, textPtr, objv[4]); > if (tagPtr2 == NULL) { > return TCL_ERROR; > } > if (tagPtr->priority <= tagPtr2->priority) { > prio = tagPtr2->priority; > } else { > prio = tagPtr2->priority + 1; > } 737c772 < prio = tagPtr2->priority + 1; --- > prio = textPtr->numTags-1; 739,769c774,803 < } else { < prio = textPtr->numTags-1; < } < ChangeTagPriority(textPtr, tagPtr, prio); < TkTextRedrawTag(textPtr, (TkTextIndex *) NULL, (TkTextIndex *) NULL, < tagPtr, 1); < } else if ((c == 'r') && (strncmp(argv[2], "ranges", length) == 0) < && (length >= 3)) { < TkTextSearch tSearch; < char position[TK_POS_CHARS]; < < if (argc != 4) { < Tcl_AppendResult(interp, "wrong # args: should be \"", < argv[0], " tag ranges tagName\"", (char *) NULL); < return TCL_ERROR; < } < tagPtr = FindTag((Tcl_Interp *) NULL, textPtr, argv[3]); < if (tagPtr == NULL) { < return TCL_OK; < } < TkTextMakeByteIndex(textPtr->tree, 0, 0, &first); < TkTextMakeByteIndex(textPtr->tree, TkBTreeNumLines(textPtr->tree), < 0, &last); < TkBTreeStartSearch(&first, &last, tagPtr, &tSearch); < if (TkBTreeCharTagged(&first, tagPtr)) { < TkTextPrintIndex(&first, position); < Tcl_AppendElement(interp, position); < } < while (TkBTreeNextTag(&tSearch)) { < TkTextPrintIndex(&tSearch.curIndex, position); < Tcl_AppendElement(interp, position); --- > ChangeTagPriority(textPtr, tagPtr, prio); > TkTextRedrawTag(textPtr, (TkTextIndex *) NULL, (TkTextIndex *) NULL, > tagPtr, 1); > break; > } > case TAG_RANGES: { > TkTextSearch tSearch; > char position[TK_POS_CHARS]; > > if (objc != 4) { > Tcl_WrongNumArgs(interp, 3, objv, "tagName"); > return TCL_ERROR; > } > tagPtr = FindTag((Tcl_Interp *) NULL, textPtr, objv[3]); > if (tagPtr == NULL) { > return TCL_OK; > } > TkTextMakeByteIndex(textPtr->tree, 0, 0, &first); > TkTextMakeByteIndex(textPtr->tree, TkBTreeNumLines(textPtr->tree), > 0, &last); > TkBTreeStartSearch(&first, &last, tagPtr, &tSearch); > if (TkBTreeCharTagged(&first, tagPtr)) { > TkTextPrintIndex(&first, position); > Tcl_AppendElement(interp, position); > } > while (TkBTreeNextTag(&tSearch)) { > TkTextPrintIndex(&tSearch.curIndex, position); > Tcl_AppendElement(interp, position); > } > break; 771,781d804 < } else if ((c == 'r') && (strncmp(argv[2], "remove", length) == 0) < && (length >= 2)) { < fullOption = "remove"; < addTag = 0; < goto addAndRemove; < } else { < Tcl_AppendResult(interp, "bad tag option \"", argv[2], < "\": must be add, bind, cget, configure, delete, lower, ", < "names, nextrange, raise, ranges, or remove", < (char *) NULL); < return TCL_ERROR; 829d851 < tagPtr->bdString = NULL; 830a853 > tagPtr->borderWidthPtr = NULL; 855c878 < tagPtr->tabString = NULL; --- > tagPtr->tabStringPtr = NULL; 864a888 > tagPtr->optionTable = Tk_CreateOptionTable(textPtr->interp, tagOptionSpecs); 893c917 < CONST char *tagName; /* Name of desired tag. */ --- > Tcl_Obj *tagName; /* Name of desired tag. */ 897c921 < hPtr = Tcl_FindHashEntry(&textPtr->tagTable, tagName); --- > hPtr = Tcl_FindHashEntry(&textPtr->tagTable, Tcl_GetString(tagName)); 902c926 < Tcl_AppendResult(interp, "tag \"", tagName, --- > Tcl_AppendResult(interp, "tag \"", Tcl_GetString(tagName), 930,978c954,957 < if (tagPtr->border != None) { < Tk_Free3DBorder(tagPtr->border); < } < if (tagPtr->bdString != NULL) { < ckfree(tagPtr->bdString); < } < if (tagPtr->reliefString != NULL) { < ckfree(tagPtr->reliefString); < } < if (tagPtr->bgStipple != None) { < Tk_FreeBitmap(textPtr->display, tagPtr->bgStipple); < } < if (tagPtr->fgColor != None) { < Tk_FreeColor(tagPtr->fgColor); < } < Tk_FreeFont(tagPtr->tkfont); < if (tagPtr->fgStipple != None) { < Tk_FreeBitmap(textPtr->display, tagPtr->fgStipple); < } < if (tagPtr->justifyString != NULL) { < ckfree(tagPtr->justifyString); < } < if (tagPtr->lMargin1String != NULL) { < ckfree(tagPtr->lMargin1String); < } < if (tagPtr->lMargin2String != NULL) { < ckfree(tagPtr->lMargin2String); < } < if (tagPtr->offsetString != NULL) { < ckfree(tagPtr->offsetString); < } < if (tagPtr->overstrikeString != NULL) { < ckfree(tagPtr->overstrikeString); < } < if (tagPtr->rMarginString != NULL) { < ckfree(tagPtr->rMarginString); < } < if (tagPtr->spacing1String != NULL) { < ckfree(tagPtr->spacing1String); < } < if (tagPtr->spacing2String != NULL) { < ckfree(tagPtr->spacing2String); < } < if (tagPtr->spacing3String != NULL) { < ckfree(tagPtr->spacing3String); < } < if (tagPtr->tabString != NULL) { < ckfree(tagPtr->tabString); < } --- > /* Let Tk do most of the hard work for us */ > Tk_FreeConfigOptions((char *) tagPtr, tagPtr->optionTable, > textPtr->tkwin); > /* This associated information is managed by us */ 981,983d959 < } < if (tagPtr->underlineString != NULL) { < ckfree(tagPtr->underlineString); Index: generic/tkTextWind.c =================================================================== RCS file: /cvsroot/tktoolkit/tk/generic/tkTextWind.c,v retrieving revision 1.6 diff -r1.6 tkTextWind.c 38,46d37 < * Definitions for alignment values: < */ < < #define ALIGN_BOTTOM 0 < #define ALIGN_CENTER 1 < #define ALIGN_TOP 2 < #define ALIGN_BASELINE 3 < < /* 57,62d47 < static int AlignParseProc _ANSI_ARGS_((ClientData clientData, < Tcl_Interp *interp, Tk_Window tkwin, < CONST char *value, char *widgRec, int offset)); < static char * AlignPrintProc _ANSI_ARGS_((ClientData clientData, < Tk_Window tkwin, char *widgRec, int offset, < Tcl_FreeProc **freeProcPtr)); 72c57 < TkTextSegment *ewPtr, int argc, CONST char **argv)); --- > TkTextSegment *ewPtr, int objc, Tcl_Obj *CONST objv[])); 107c92 < * Information used for parsing window configuration options: --- > * Definitions for alignment values: 110,111c95,101 < static Tk_CustomOption alignOption = {AlignParseProc, AlignPrintProc, < (ClientData) NULL}; --- > static char *alignStrings[] = { > "baseline", "bottom", "center", "top", (char *) NULL > }; > > typedef enum { > ALIGN_BASELINE, ALIGN_BOTTOM, ALIGN_CENTER, ALIGN_TOP > } alignMode; 113,132c103,126 < static Tk_ConfigSpec configSpecs[] = { < {TK_CONFIG_CUSTOM, "-align", (char *) NULL, (char *) NULL, < "center", 0, TK_CONFIG_DONT_SET_DEFAULT, &alignOption}, < {TK_CONFIG_STRING, "-create", (char *) NULL, (char *) NULL, < (char *) NULL, Tk_Offset(TkTextEmbWindow, create), < TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK}, < {TK_CONFIG_INT, "-padx", (char *) NULL, (char *) NULL, < "0", Tk_Offset(TkTextEmbWindow, padX), < TK_CONFIG_DONT_SET_DEFAULT}, < {TK_CONFIG_INT, "-pady", (char *) NULL, (char *) NULL, < "0", Tk_Offset(TkTextEmbWindow, padY), < TK_CONFIG_DONT_SET_DEFAULT}, < {TK_CONFIG_BOOLEAN, "-stretch", (char *) NULL, (char *) NULL, < "0", Tk_Offset(TkTextEmbWindow, stretch), < TK_CONFIG_DONT_SET_DEFAULT}, < {TK_CONFIG_WINDOW, "-window", (char *) NULL, (char *) NULL, < (char *) NULL, Tk_Offset(TkTextEmbWindow, tkwin), < TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK}, < {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL, < (char *) NULL, 0, 0} --- > /* > * Information used for parsing window configuration options: > */ > > static Tk_OptionSpec optionSpecs[] = { > {TK_OPTION_STRING_TABLE, "-align", (char *) NULL, (char *) NULL, > "center", -1, Tk_Offset(TkTextEmbWindow, align), > 0, (ClientData) alignStrings, 0}, > {TK_OPTION_STRING, "-create", (char *) NULL, (char *) NULL, > (char *) NULL, -1, Tk_Offset(TkTextEmbWindow, create), > TK_OPTION_NULL_OK, 0, 0}, > {TK_OPTION_PIXELS, "-padx", (char *) NULL, (char *) NULL, > "0", -1, Tk_Offset(TkTextEmbWindow, padX), > 0, 0, 0}, > {TK_OPTION_PIXELS, "-pady", (char *) NULL, (char *) NULL, > "0", -1, Tk_Offset(TkTextEmbWindow, padY), > 0, 0, 0}, > {TK_OPTION_BOOLEAN, "-stretch", (char *) NULL, (char *) NULL, > "0", -1, Tk_Offset(TkTextEmbWindow, stretch), > 0, 0, 0}, > {TK_OPTION_WINDOW, "-window", (char *) NULL, (char *) NULL, > (char *) NULL, -1, Tk_Offset(TkTextEmbWindow, tkwin), > TK_OPTION_NULL_OK, 0, 0}, > {TK_OPTION_END} 154c148 < TkTextWindowCmd(textPtr, interp, argc, argv) --- > TkTextWindowCmd(textPtr, interp, objc, objv) 157,158c151,152 < int argc; /* Number of arguments. */ < CONST char **argv; /* Argument strings. Someone else has already --- > int objc; /* Number of arguments. */ > Tcl_Obj *CONST objv[]; /* Argument objects. Someone else has already 160c154 < * argv[1] is "window". */ --- > * objv[1] is "window". */ 162c156,164 < size_t length; --- > int optionIndex; > > static CONST char *windOptionStrings[] = { > "cget", "configure", "create", "names", (char *) NULL > }; > enum windOptions { > WIND_CGET, WIND_CONFIGURE, WIND_CREATE, WIND_NAMES > }; > 165,167c167,168 < if (argc < 3) { < Tcl_AppendResult(interp, "wrong # args: should be \"", < argv[0], " window option ?arg arg ...?\"", (char *) NULL); --- > if (objc < 3) { > Tcl_WrongNumArgs(interp, 2, objv, "option ?arg arg ...?"); 170,209c171,202 < length = strlen(argv[2]); < if ((strncmp(argv[2], "cget", length) == 0) && (length >= 2)) { < TkTextIndex index; < TkTextSegment *ewPtr; < < if (argc != 5) { < Tcl_AppendResult(interp, "wrong # args: should be \"", < argv[0], " window cget index option\"", < (char *) NULL); < return TCL_ERROR; < } < if (TkTextGetIndex(interp, textPtr, argv[3], &index) != TCL_OK) { < return TCL_ERROR; < } < ewPtr = TkTextIndexToSeg(&index, (int *) NULL); < if (ewPtr->typePtr != &tkTextEmbWindowType) { < Tcl_AppendResult(interp, "no embedded window at index \"", < argv[3], "\"", (char *) NULL); < return TCL_ERROR; < } < return Tk_ConfigureValue(interp, textPtr->tkwin, configSpecs, < (char *) &ewPtr->body.ew, argv[4], 0); < } else if ((strncmp(argv[2], "configure", length) == 0) && (length >= 2)) { < TkTextIndex index; < TkTextSegment *ewPtr; < < if (argc < 4) { < Tcl_AppendResult(interp, "wrong # args: should be \"", < argv[0], " window configure index ?option value ...?\"", < (char *) NULL); < return TCL_ERROR; < } < if (TkTextGetIndex(interp, textPtr, argv[3], &index) != TCL_OK) { < return TCL_ERROR; < } < ewPtr = TkTextIndexToSeg(&index, (int *) NULL); < if (ewPtr->typePtr != &tkTextEmbWindowType) { < Tcl_AppendResult(interp, "no embedded window at index \"", < argv[3], "\"", (char *) NULL); < return TCL_ERROR; --- > if (Tcl_GetIndexFromObj(interp, objv[2], windOptionStrings, > "window option", 0, &optionIndex) != TCL_OK) { > return TCL_ERROR; > } > switch ((enum windOptions)optionIndex) { > case WIND_CGET: { > TkTextIndex index; > TkTextSegment *ewPtr; > Tcl_Obj *objPtr; > > if (objc != 5) { > Tcl_WrongNumArgs(interp, 3, objv, "index option"); > return TCL_ERROR; > } > if (TkTextGetObjIndex(interp, textPtr, objv[3], &index) != TCL_OK) { > return TCL_ERROR; > } > ewPtr = TkTextIndexToSeg(&index, (int *) NULL); > if (ewPtr->typePtr != &tkTextEmbWindowType) { > Tcl_AppendResult(interp, "no embedded window at index \"", > Tcl_GetString(objv[3]), "\"", (char *) NULL); > return TCL_ERROR; > } > objPtr = Tk_GetOptionValue(interp, (char *) &ewPtr->body.ew, > ewPtr->body.ew.optionTable, objv[4], textPtr->tkwin); > if (objPtr == NULL) { > return TCL_ERROR; > } else { > Tcl_SetObjResult(interp, objPtr); > return TCL_OK; > } > break; 211,219c204,236 < if (argc == 4) { < return Tk_ConfigureInfo(interp, textPtr->tkwin, configSpecs, < (char *) &ewPtr->body.ew, (char *) NULL, 0); < } else if (argc == 5) { < return Tk_ConfigureInfo(interp, textPtr->tkwin, configSpecs, < (char *) &ewPtr->body.ew, argv[4], 0); < } else { < TkTextChanged(textPtr, &index, &index); < return EmbWinConfigure(textPtr, ewPtr, argc-4, argv+4); --- > case WIND_CONFIGURE: { > TkTextIndex index; > TkTextSegment *ewPtr; > > if (objc < 4) { > Tcl_WrongNumArgs(interp, 3, objv, "index ?option value ...?"); > return TCL_ERROR; > } > if (TkTextGetObjIndex(interp, textPtr, objv[3], &index) != TCL_OK) { > return TCL_ERROR; > } > ewPtr = TkTextIndexToSeg(&index, (int *) NULL); > if (ewPtr->typePtr != &tkTextEmbWindowType) { > Tcl_AppendResult(interp, "no embedded window at index \"", > Tcl_GetString(objv[3]), "\"", (char *) NULL); > return TCL_ERROR; > } > if (objc <= 5) { > Tcl_Obj* objPtr = Tk_GetOptionInfo(interp, (char *) &ewPtr->body.ew, > ewPtr->body.ew.optionTable, > (objc == 5) ? objv[4] : (Tcl_Obj *) NULL, > textPtr->tkwin); > if (objPtr == NULL) { > return TCL_ERROR; > } else { > Tcl_SetObjResult(interp, objPtr); > return TCL_OK; > } > } else { > TkTextChanged(textPtr, &index, &index); > return EmbWinConfigure(textPtr, ewPtr, objc-4, objv+4); > } > break; 221,228c238,240 < } else if ((strncmp(argv[2], "create", length) == 0) && (length >= 2)) { < TkTextIndex index; < int lineIndex; < < /* < * Add a new window. Find where to put the new window, and < * mark that position for redisplay. < */ --- > case WIND_CREATE: { > TkTextIndex index; > int lineIndex; 230,238c242,245 < if (argc < 4) { < Tcl_AppendResult(interp, "wrong # args: should be \"", < argv[0], " window create index ?option value ...?\"", < (char *) NULL); < return TCL_ERROR; < } < if (TkTextGetIndex(interp, textPtr, argv[3], &index) != TCL_OK) { < return TCL_ERROR; < } --- > /* > * Add a new window. Find where to put the new window, and > * mark that position for redisplay. > */ 240,248c247,253 < /* < * Don't allow insertions on the last (dummy) line of the text. < */ < < lineIndex = TkBTreeLineIndex(index.linePtr); < if (lineIndex == TkBTreeNumLines(textPtr->tree)) { < lineIndex--; < TkTextMakeByteIndex(textPtr->tree, lineIndex, 1000000, &index); < } --- > if (objc < 4) { > Tcl_WrongNumArgs(interp, 3, objv, "index ?option value ...?"); > return TCL_ERROR; > } > if (TkTextGetObjIndex(interp, textPtr, objv[3], &index) != TCL_OK) { > return TCL_ERROR; > } 250,252c255,263 < /* < * Create the new window segment and initialize it. < */ --- > /* > * Don't allow insertions on the last (dummy) line of the text. > */ > > lineIndex = TkBTreeLineIndex(index.linePtr); > if (lineIndex == TkBTreeNumLines(textPtr->tree)) { > lineIndex--; > TkTextMakeByteIndex(textPtr->tree, lineIndex, 1000000, &index); > } 254,265c265,267 < ewPtr = (TkTextSegment *) ckalloc(EW_SEG_SIZE); < ewPtr->typePtr = &tkTextEmbWindowType; < ewPtr->size = 1; < ewPtr->body.ew.textPtr = textPtr; < ewPtr->body.ew.linePtr = NULL; < ewPtr->body.ew.tkwin = NULL; < ewPtr->body.ew.create = NULL; < ewPtr->body.ew.align = ALIGN_CENTER; < ewPtr->body.ew.padX = ewPtr->body.ew.padY = 0; < ewPtr->body.ew.stretch = 0; < ewPtr->body.ew.chunkCount = 0; < ewPtr->body.ew.displayed = 0; --- > /* > * Create the new window segment and initialize it. > */ 267,270c269,285 < /* < * Link the segment into the text widget, then configure it (delete < * it again if the configuration fails). < */ --- > ewPtr = (TkTextSegment *) ckalloc(EW_SEG_SIZE); > ewPtr->typePtr = &tkTextEmbWindowType; > ewPtr->size = 1; > ewPtr->body.ew.textPtr = textPtr; > ewPtr->body.ew.linePtr = NULL; > ewPtr->body.ew.tkwin = NULL; > ewPtr->body.ew.create = NULL; > ewPtr->body.ew.align = ALIGN_CENTER; > ewPtr->body.ew.padX = ewPtr->body.ew.padY = 0; > ewPtr->body.ew.stretch = 0; > ewPtr->body.ew.chunkCount = 0; > ewPtr->body.ew.displayed = 0; > ewPtr->body.ew.optionTable = Tk_CreateOptionTable(interp, optionSpecs); > /* > * Link the segment into the text widget, then configure it (delete > * it again if the configuration fails). > */ 272,288c287,296 < TkTextChanged(textPtr, &index, &index); < TkBTreeLinkSegment(ewPtr, &index); < if (EmbWinConfigure(textPtr, ewPtr, argc-4, argv+4) != TCL_OK) { < TkTextIndex index2; < < TkTextIndexForwChars(&index, 1, &index2); < TkBTreeDeleteChars(&index, &index2); < return TCL_ERROR; < } < } else if (strncmp(argv[2], "names", length) == 0) { < Tcl_HashSearch search; < Tcl_HashEntry *hPtr; < < if (argc != 3) { < Tcl_AppendResult(interp, "wrong # args: should be \"", < argv[0], " window names\"", (char *) NULL); < return TCL_ERROR; --- > TkTextChanged(textPtr, &index, &index); > TkBTreeLinkSegment(ewPtr, &index); > if (EmbWinConfigure(textPtr, ewPtr, objc-4, objv+4) != TCL_OK) { > TkTextIndex index2; > > TkTextIndexForwChars(&index, 1, &index2); > TkBTreeDeleteChars(&index, &index2); > return TCL_ERROR; > } > break; 290,293c298,311 < for (hPtr = Tcl_FirstHashEntry(&textPtr->windowTable, &search); < hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { < Tcl_AppendElement(interp, < Tcl_GetHashKey(&textPtr->markTable, hPtr)); --- > case WIND_NAMES: { > Tcl_HashSearch search; > Tcl_HashEntry *hPtr; > > if (objc != 3) { > Tcl_WrongNumArgs(interp, 3, objv, NULL); > return TCL_ERROR; > } > for (hPtr = Tcl_FirstHashEntry(&textPtr->windowTable, &search); > hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { > Tcl_AppendElement(interp, > Tcl_GetHashKey(&textPtr->markTable, hPtr)); > } > break; 295,299d312 < } else { < Tcl_AppendResult(interp, "bad window option \"", argv[2], < "\": must be cget, configure, create, or names", < (char *) NULL); < return TCL_ERROR; 310c323 < * for an embedded window, using an argc/argv list. --- > * for an embedded window, using an objc/objv list. 325c338 < EmbWinConfigure(textPtr, ewPtr, argc, argv) --- > EmbWinConfigure(textPtr, ewPtr, objc, objv) 329,330c342,343 < int argc; /* Number of strings in argv. */ < CONST char **argv; /* Array of strings describing configuration --- > int objc; /* Number of strings in objv. */ > Tcl_Obj *CONST objv[]; /* Array of objects describing configuration 338,340c351,353 < if (Tk_ConfigureWidget(textPtr->interp, textPtr->tkwin, configSpecs, < argc, argv, (char *) &ewPtr->body.ew, TK_CONFIG_ARGV_ONLY) < != TCL_OK) { --- > if (Tk_SetOptions(textPtr->interp, (char*)&ewPtr->body.ew, > ewPtr->body.ew.optionTable, > objc, objv, textPtr->tkwin, NULL, NULL) != TCL_OK) { 417,509d429 < * AlignParseProc -- < * < * This procedure is invoked by Tk_ConfigureWidget during < * option processing to handle "-align" options for embedded < * windows. < * < * Results: < * A standard Tcl return value. < * < * Side effects: < * The alignment for the embedded window may change. < * < *-------------------------------------------------------------- < */ < < /* ARGSUSED */ < static int < AlignParseProc(clientData, interp, tkwin, value, widgRec, offset) < ClientData clientData; /* Not used.*/ < Tcl_Interp *interp; /* Used for reporting errors. */ < Tk_Window tkwin; /* Window for text widget. */ < CONST char *value; /* Value of option. */ < char *widgRec; /* Pointer to TkTextEmbWindow < * structure. */ < int offset; /* Offset into item (ignored). */ < { < register TkTextEmbWindow *embPtr = (TkTextEmbWindow *) widgRec; < < if (strcmp(value, "baseline") == 0) { < embPtr->align = ALIGN_BASELINE; < } else if (strcmp(value, "bottom") == 0) { < embPtr->align = ALIGN_BOTTOM; < } else if (strcmp(value, "center") == 0) { < embPtr->align = ALIGN_CENTER; < } else if (strcmp(value, "top") == 0) { < embPtr->align = ALIGN_TOP; < } else { < Tcl_AppendResult(interp, "bad alignment \"", value, < "\": must be baseline, bottom, center, or top", < (char *) NULL); < return TCL_ERROR; < } < return TCL_OK; < } < < /* < *-------------------------------------------------------------- < * < * AlignPrintProc -- < * < * This procedure is invoked by the Tk configuration code < * to produce a printable string for the "-align" configuration < * option for embedded windows. < * < * Results: < * The return value is a string describing the embedded < * window's current alignment. < * < * Side effects: < * None. < * < *-------------------------------------------------------------- < */ < < /* ARGSUSED */ < static char * < AlignPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr) < ClientData clientData; /* Ignored. */ < Tk_Window tkwin; /* Window for text widget. */ < char *widgRec; /* Pointer to TkTextEmbWindow < * structure. */ < int offset; /* Ignored. */ < Tcl_FreeProc **freeProcPtr; /* Pointer to variable to fill in with < * information about how to reclaim < * storage for return string. */ < { < switch (((TkTextEmbWindow *) widgRec)->align) { < case ALIGN_BASELINE: < return "baseline"; < case ALIGN_BOTTOM: < return "bottom"; < case ALIGN_CENTER: < return "center"; < case ALIGN_TOP: < return "top"; < default: < return "??"; < } < } < < /* < *-------------------------------------------------------------- < * 681,682c601,602 < Tk_FreeOptions(configSpecs, (char *) &ewPtr->body.ew, < ewPtr->body.ew.textPtr->display, 0); --- > Tk_FreeConfigOptions((char *) &ewPtr->body.ew, ewPtr->body.ew.optionTable, > ewPtr->body.ew.tkwin); Index: generic/tkUndo.c =================================================================== RCS file: /cvsroot/tktoolkit/tk/generic/tkUndo.c,v retrieving revision 1.1 diff -r1.1 tkUndo.c 15a16,18 > static int UndoScriptsEvaluate _ANSI_ARGS_ ((Tcl_Interp *interp, > Tcl_Obj *objPtr, TkUndoAtomType type)); > 115c118,120 < * action and revert are given through Tcl_DStrings --- > * action and revert are given through Tcl_Obj's to which > * we will retain a reference. (So they can be passed in > * with a zero refCount if desired). 124,127c129,133 < void TkUndoPushAction ( stack, actionScript, revertScript ) < TkUndoRedoStack * stack; /* An Undo or Redo stack */ < Tcl_DString * actionScript; /* The script to get the action (redo) */ < Tcl_DString * revertScript; /* The script to revert the action (undo) */ --- > void TkUndoPushAction ( stack, actionScript, revertScript, isList ) > TkUndoRedoStack *stack; /* An Undo or Redo stack */ > Tcl_Obj *actionScript; /* The script to get the action (redo) */ > Tcl_Obj *revertScript; /* The script to revert the action (undo) */ > int isList; /* Are the given objects lists of scripts? */ 132c138,142 < atom->type = TK_UNDO_ACTION; --- > if (isList) { > atom->type = TK_UNDO_ACTION_LIST; > } else { > atom->type = TK_UNDO_ACTION; > } 134c144 < atom->apply = Tcl_NewStringObj(Tcl_DStringValue(actionScript),Tcl_DStringLength(actionScript)); --- > atom->apply = actionScript; 137c147 < atom->revert = Tcl_NewStringObj(Tcl_DStringValue(revertScript),Tcl_DStringLength(revertScript)); --- > atom->revert = revertScript; 336c346 < Tcl_EvalObjEx(stack->interp,elem->revert,TCL_EVAL_GLOBAL); --- > UndoScriptsEvaluate(stack->interp,elem->revert,elem->type); 350d359 < 386c395 < Tcl_EvalObjEx(stack->interp,elem->apply,TCL_EVAL_GLOBAL); --- > UndoScriptsEvaluate(stack->interp,elem->apply,elem->type); 398a408,444 > } > > > /* > * UndoScriptsEvaluate -- > * Execute either a single script, or a set of scripts > * > * Results: > * A TCL status code > * > * Side effects: > * None. > */ > static int > UndoScriptsEvaluate(interp, objPtr, type) > Tcl_Interp *interp; > Tcl_Obj *objPtr; > TkUndoAtomType type; > { > if (type == TK_UNDO_ACTION_LIST) { > int objc; > Tcl_Obj **objv; > int res, i; > res = Tcl_ListObjGetElements(interp, objPtr, &objc, &objv); > if (res != TCL_OK) { > return res; > } > for (i=0;i res = Tcl_EvalObjEx(interp, objv[i], TCL_EVAL_GLOBAL); > if (res != TCL_OK) { > return res; > } > } > return res; > } else { > return Tcl_EvalObjEx(interp, objPtr, TCL_EVAL_GLOBAL); > } Index: generic/tkUndo.h =================================================================== RCS file: /cvsroot/tktoolkit/tk/generic/tkUndo.h,v retrieving revision 1.1 diff -r1.1 tkUndo.h 31c31,32 < TK_UNDO_ACTION /* Command */ --- > TK_UNDO_ACTION, /* Command */ > TK_UNDO_ACTION_LIST /* Command list */ 37,40c38,42 < TkUndoAtomType type; /* The type that will trigger the < * required action*/ < Tcl_Obj * apply; /* Command to apply the action that was taken */ < Tcl_Obj * revert; /* The command to undo the action */ --- > TkUndoAtomType type; /* The type that will trigger the > * required action*/ > Tcl_Obj *apply; /* Command to apply the action that > * was taken */ > Tcl_Obj *revert; /* The command to undo the action */ 42c44 < * stack */ --- > * stack */ 48,50c50,53 < TkUndoAtom * undoStack; /* The undo stack */ < TkUndoAtom * redoStack; /* The redo stack */ < Tcl_Interp * interp ; /* The interpreter in which to execute the revert and apply scripts */ --- > TkUndoAtom * undoStack; /* The undo stack */ > TkUndoAtom * redoStack; /* The redo stack */ > Tcl_Interp * interp ; /* The interpreter in which to execute > * the revert and apply scripts */ 81c84 < Tcl_DString * actionScript, Tcl_DString * revertScript)); --- > Tcl_Obj *actionScript, Tcl_Obj *revertScript, int isList)); Index: generic/tkWindow.c =================================================================== RCS file: /cvsroot/tktoolkit/tk/generic/tkWindow.c,v retrieving revision 1.54 diff -r1.54 tkWindow.c 151c151 < {"text", Tk_TextCmd, NULL, 1, 1}, --- > {"text", NULL, Tk_TextObjCmd, 1, 1}, Index: tests/text.test =================================================================== RCS file: /cvsroot/tktoolkit/tk/tests/text.test,v retrieving revision 1.19 diff -r1.19 text.test 225c225 < } {1 {bad option "co": must be bbox, cget, compare, configure, debug, delete, dlineinfo, dump, edit, get, image, index, insert, mark, scan, search, see, tag, window, xview, or yview}} --- > } {1 {ambiguous option "co": must be bbox, cget, compare, configure, debug, delete, dlineinfo, dump, edit, get, image, index, insert, mark, scan, search, see, tag, window, xview, or yview}} 234c234 < } {1 {bad option "de": must be bbox, cget, compare, configure, debug, delete, dlineinfo, dump, edit, get, image, index, insert, mark, scan, search, see, tag, window, xview, or yview}} --- > } {1 {ambiguous option "de": must be bbox, cget, compare, configure, debug, delete, dlineinfo, dump, edit, get, image, index, insert, mark, scan, search, see, tag, window, xview, or yview}} 394c394 < } {1 {bad option "in": must be bbox, cget, compare, configure, debug, delete, dlineinfo, dump, edit, get, image, index, insert, mark, scan, search, see, tag, window, xview, or yview}} --- > } {1 {ambiguous option "in": must be bbox, cget, compare, configure, debug, delete, dlineinfo, dump, edit, get, image, index, insert, mark, scan, search, see, tag, window, xview, or yview}} 457c457 < } {1 {bad state value "foobar": must be normal or disabled}} --- > } {1 {bad state "foobar": must be disabled or normal}} 485c485 < } {1 {bad wrap mode "bogus": must be char, none, or word}} --- > } {1 {bad wrap "bogus": must be char, none, or word}} 938c938 < } {1 {bad switch "-": must be --, -backward, -count, -elide, -exact, -forward, -nocase, or -regexp}} --- > } {1 {bad switch "-": must be --, -all, -backward, -count, -elide, -exact, -forward, -nocase, or -regexp}} 1012c1012 < test text-20.25 {TextSearchCmd procedure, stripping newlines} { --- > test text-20.25 {TextSearchCmd procedure, handling newlines} { 1014c1014 < } {} --- > } {1.12} 1018c1018 < test text-20.27 {TextSearchCmd procedure, stripping newlines} { --- > test text-20.27 {TextSearchCmd procedure, handling newlines} { 1020c1020 < } {} --- > } {1.15} 1247c1247,1503 < --- > test text-20.73 {TextSearchCmd, hidden text and start index} { > deleteWindows > pack [text .t2] > .t2 insert end "foobar\nfoobar\nfoobar" > .t2 search bar 1.3 > } 1.3 > test text-20.74 {TextSearchCmd, hidden text shouldn't influence start index} { > deleteWindows > pack [text .t2] > .t2 insert end "foobar\nfoobar\nfoobar" > .t2 tag configure hidden -elide true > .t2 tag add hidden 1.0 1.2 > .t2 search bar 1.3 > } 1.3 > test text-20.75 {TextSearchCmd, hidden text inside match must count in length} { > deleteWindows > pack [text .t2] > .t2 insert end "foobar\nfoobar\nfoobar" > .t2 tag configure hidden -elide true > .t2 tag add hidden 1.2 1.4 > list [.t2 search -count foo foar 1.3] $foo > } {1.0 6} > test text-20.76 {TextSearchCmd, hidden text and start index} { > deleteWindows > pack [text .t2] > .t2 insert end "foobar\nfoobar\nfoobar" > .t2 search -regexp bar 1.3 > } 1.3 > test text-20.77 {TextSearchCmd, hidden text shouldn't influence start index} { > deleteWindows > pack [text .t2] > .t2 insert end "foobar\nfoobar\nfoobar" > .t2 tag configure hidden -elide true > .t2 tag add hidden 1.0 1.2 > .t2 search -regexp bar 1.3 > } 1.3 > test text-20.78 {TextSearchCmd, hidden text inside match must count in length} { > deleteWindows > pack [text .t2] > .t2 insert end "foobar\nfoobar\nfoobar" > .t2 tag configure hidden -elide true > .t2 tag add hidden 1.2 1.4 > list [.t2 search -regexp -count foo foar 1.3] $foo > } {1.0 6} > > test text-20.79 {TextSearchCmd, multiline matching} { > deleteWindows > pack [text .t2] > .t2 insert end "foobar\nfoobar\nfoobar" > list [.t2 search -count foo foobar\nfoo 1.0] $foo > } {1.0 10} > > test text-20.80 {TextSearchCmd, multiline matching} { > deleteWindows > pack [text .t2] > .t2 insert end "foobar\nfoobar\nfoobar" > list [.t2 search -count foo bar\nfoo 1.0] $foo > } {1.3 7} > > test text-20.81 {TextSearchCmd, multiline matching} { > deleteWindows > pack [text .t2] > .t2 insert end "foobar\nfoobar\nfoobar" > list [.t2 search -count foo \nfoo 1.0] $foo > } {1.6 4} > > test text-20.82 {TextSearchCmd, multiline matching} { > deleteWindows > pack [text .t2] > .t2 insert end "foobar\nfoobar\nfoobar" > list [.t2 search -count foo bar\nfoobar\nfoo 1.0] $foo > } {1.3 14} > > test text-20.83 {TextSearchCmd, multiline matching} { > deleteWindows > pack [text .t2] > .t2 insert end "foobar\nfoobar\nfoobar" > .t2 search -count foo bar\nfoobar\nfoobanearly 1.0 > } {} > > test text-20.84 {TextSearchCmd, multiline matching} { > deleteWindows > pack [text .t2] > .t2 insert end "foobar\nfoobar\nfoobar" > list [.t2 search -regexp -count foo foobar\nfoo 1.0] $foo > } {1.0 10} > > test text-20.85 {TextSearchCmd, multiline matching} { > deleteWindows > pack [text .t2] > .t2 insert end "foobar\nfoobar\nfoobar" > list [.t2 search -regexp -count foo bar\nfoo 1.0] $foo > } {1.3 7} > > test text-20.86 {TextSearchCmd, multiline matching} { > deleteWindows > pack [text .t2] > .t2 insert end "foobar\nfoobar\nfoobar" > list [.t2 search -regexp -count foo \nfoo 1.0] $foo > } {1.6 4} > > test text-20.87 {TextSearchCmd, multiline matching} { > deleteWindows > pack [text .t2] > .t2 insert end "foobar\nfoobar\nfoobar" > list [.t2 search -regexp -count foo bar\nfoobar\nfoo 1.0] $foo > } {1.3 14} > > test text-20.88 {TextSearchCmd, multiline matching} { > deleteWindows > pack [text .t2] > .t2 insert end "foobar\nfoobar\nfoobar" > .t2 search -regexp -count foo bar\nfoobar\nfoobanearly 1.0 > } {} > > test text-20.89 {TextSearchCmd, multiline matching} { > deleteWindows > pack [text .t2] > .t2 insert end "foobar\nfaoobar\nfoobar" > .t2 search -regexp -count foo bar\nfoo 1.0 > } {2.4} > > test text-20.90 {TextSearchCmd, multiline matching end of window} { > deleteWindows > pack [text .t2] > .t2 insert end "foobar\nfaoobar\nfoobar" > .t2 search -regexp -count foo bar\nfoobar\n\n 1.0 > } {} > > test text-20.91 {TextSearchCmd, multiline matching end of window} { > deleteWindows > pack [text .t2] > .t2 search "\n\n" 1.0 > } {} > > test text-20.92 {TextSearchCmd, multiline matching} { > deleteWindows > pack [text .t2] > .t2 insert end "foobar\nfoobar\nfoobar" > list [.t2 search -backwards -count foo foobar\nfoo end] $foo > } {2.0 10} > > test text-20.93 {TextSearchCmd, multiline matching} { > deleteWindows > pack [text .t2] > .t2 insert end "foobar\nfoobar\nfoobar" > list [.t2 search -backwards -count foo bar\nfoo 1.0] $foo > } {2.3 7} > > test text-20.94 {TextSearchCmd, multiline matching} { > deleteWindows > pack [text .t2] > .t2 insert end "foobar\nfoobar\nfoobar" > list [.t2 search -backwards -count foo \nfoo 1.0] $foo > } {2.6 4} > > test text-20.95 {TextSearchCmd, multiline matching} { > deleteWindows > pack [text .t2] > .t2 insert end "foobar\nfoobar\nfoobar" > list [.t2 search -backwards -count foo bar\nfoobar\nfoo 1.0] $foo > } {1.3 14} > > test text-20.96 {TextSearchCmd, multiline matching} { > deleteWindows > pack [text .t2] > .t2 insert end "foobar\nfoobar\nfoobar" > .t2 search -backwards -count foo bar\nfoobar\nfoobanearly 1.0 > } {} > > test text-20.97 {TextSearchCmd, multiline matching} { > deleteWindows > pack [text .t2] > .t2 insert end "foobar\nfoobar\nfoobar" > list [.t2 search -backwards -regexp -count foo foobar\nfoo 1.0] $foo > } {2.0 10} > > test text-20.98 {TextSearchCmd, multiline matching} { > deleteWindows > pack [text .t2] > .t2 insert end "foobar\nfoobar\nfoobar" > list [.t2 search -backwards -regexp -count foo bar\nfoo 1.0] $foo > } {2.3 7} > > test text-20.99 {TextSearchCmd, multiline matching} { > deleteWindows > pack [text .t2] > .t2 insert end "foobar\nfoobar\nfoobar" > list [.t2 search -backwards -regexp -count foo \nfoo 1.0] $foo > } {2.6 4} > > test text-20.100 {TextSearchCmd, multiline matching} { > deleteWindows > pack [text .t2] > .t2 insert end "foobar\nfoobar\nfoobar" > list [.t2 search -backwards -regexp -count foo bar\nfoobar\nfoo 1.0] $foo > } {1.3 14} > > test text-20.101 {TextSearchCmd, multiline matching} { > deleteWindows > pack [text .t2] > .t2 insert end "foobar\nfoobar\nfoobar" > .t2 search -backwards -regexp -count foo bar\nfoobar\nfoobanearly 1.0 > } {} > > test text-20.102 {TextSearchCmd, multiline matching} { > deleteWindows > pack [text .t2] > .t2 insert end "foobar\nfaoobar\nfoobar" > .t2 search -backwards -regexp -count foo bar\nfoo 1.0 > } {2.4} > > test text-20.103 {TextSearchCmd, multiline matching end of window} { > deleteWindows > pack [text .t2] > .t2 insert end "foobar\nfaoobar\nfoobar" > .t2 search -backwards -regexp -count foo bar\nfoobar\n\n 1.0 > } {} > > test text-20.104 {TextSearchCmd, multiline matching end of window} { > deleteWindows > pack [text .t2] > .t2 search -backwards "\n\n" 1.0 > } {} > > test text-20.105 {TextSearchCmd, multiline regexp matching} { > # This practical test is ok, but the similar 20.106 crashes > return > deleteWindows > pack [text .t2] > .t2 insert 1.0 { Tcl_Obj *objPtr)); > static Tcl_Obj* FSNormalizeAbsolutePath > _ANSI_ARGS_((Tcl_Interp* interp, Tcl_Obj *pathPtr));} > set markExpr "^(\[A-Za-z0-9~_\]+\[ \t\n\r\]*\\(|(\[^ \t\(#\n\r/@:\*\]\[^=\(\r\n\]*\[ \t\]+\\*?)?" > append markExpr "(\[A-Za-z0-9~_\]+(<\[^>\]*>)?(::)?(\[A-Za-z0-9~_\]+::)*\[-A-Za-z0-9~_+ <>\|\\*/\]+|\[A-Za-z0-9~_\]+)" > append markExpr "\[ \n\t\r\]*\\()" > .t2 search -forwards -regexp $markExpr 1.41 end > } {} > > test text-20.106 {TextSearchCmd, multiline regexp matching} { > # Practical example which crashes Tk, but only after the > # search is complete. This is memory corruption caused by > # a bug in Tcl's handling of string objects. > deleteWindows > pack [text .t2] > .t2 insert 1.0 {static int SetFsPathFromAny _ANSI_ARGS_((Tcl_Interp *interp, > Tcl_Obj *objPtr)); > static Tcl_Obj* FSNormalizeAbsolutePath > _ANSI_ARGS_((Tcl_Interp* interp, Tcl_Obj *pathPtr));} > set markExpr "^(\[A-Za-z0-9~_\]+\[ \t\n\r\]*\\(|(\[^ \t\(#\n\r/@:\*\]\[^=\(\r\n\]*\[ \t\]+\\*?)?" > append markExpr "(\[A-Za-z0-9~_\]+(<\[^>\]*>)?(::)?(\[A-Za-z0-9~_\]+::)*\[-A-Za-z0-9~_+ <>\|\\*/\]+|\[A-Za-z0-9~_\]+)" > append markExpr "\[ \n\t\r\]*\\()" > .t2 search -forwards -regexp $markExpr 1.41 end > } {} > > > 1456c1712 < } {1 {bad edit option "gorp": must be modified, redo, reset, separator or undo}} --- > } {1 {bad edit option "gorp": must be modified, redo, reset, separator, or undo}} Index: tests/textIndex.test =================================================================== RCS file: /cvsroot/tktoolkit/tk/tests/textIndex.test,v retrieving revision 1.7 diff -r1.7 textIndex.test 660d659 < 668a668,685 > > test testIndex-17.1 {Object indices} { > set res {} > set t [text .t2 -height 20] > for {set i 0} {$i < 100} {incr i} { > $t insert end $i\n > } > pack $t > update > set idx @0,0 > lappend res $idx [$t index $idx] > $t yview scroll 2 pages > lappend res $idx [$t index $idx] > catch {destroy $t} > unset i > unset idx > list $res > } {{@0,0 1.0 @0,0 37.0}} Index: tests/textMark.test =================================================================== RCS file: /cvsroot/tktoolkit/tk/tests/textMark.test,v retrieving revision 1.5 diff -r1.5 textMark.test 85c85 < lsort [.t mark n] --- > lsort [.t mark na] Index: tests/textTag.test =================================================================== RCS file: /cvsroot/tktoolkit/tk/tests/textTag.test,v retrieving revision 1.6 diff -r1.6 textTag.test 107c107 < } {1 {bad tag option "gorp": must be add, bind, cget, configure, delete, lower, names, nextrange, raise, ranges, or remove}} --- > } {1 {bad tag option "gorp": must be add, bind, cget, configure, delete, lower, names, nextrange, prevrange, raise, ranges, or remove}} 319c319 < } {1 {wrong # args: should be ".t tag delete tagName tagName ..."}} --- > } {1 {wrong # args: should be ".t tag delete tagName ?tagName ...?"}} Index: tests/textWind.test =================================================================== RCS file: /cvsroot/tktoolkit/tk/tests/textWind.test,v retrieving revision 1.5 diff -r1.5 textWind.test 24c24 < option add *Text.font {Courier -14} --- > option add *Text.font {Courier -12} 197c197 < } {1 {bad window option "c": must be cget, configure, create, or names}} --- > } {1 {ambiguous window option "c": must be cget, configure, create, or names}} 314c314 < } {1 {bad alignment "gorp": must be baseline, bottom, center, or top} {-align {} {} center top}} --- > } {1 {bad align "gorp": must be baseline, bottom, center, or top} {-align {} {} center top}} Index: win/makefile.vc =================================================================== RCS file: /cvsroot/tktoolkit/tk/win/makefile.vc,v retrieving revision 1.65 diff -r1.65 makefile.vc 209,210c209 < $(TMP_DIR)\tkWinTest.obj \ < $(TCLTMP_DIR)\tclThreadTest.obj --- > $(TMP_DIR)\tkWinTest.obj 453c452 < $(TKTEST) $(ROOT)/tests/all.tcl $(TESTFLAGS) | $(CAT32) --- > $(TKTEST) $(ROOT)\tests\all.tcl $(TESTFLAGS) | $(CAT32) 455c454 < $(TKTEST) $(ROOT)/tests/all.tcl $(TESTFLAGS) | $(CAT32) --- > $(TKTEST) $(ROOT)\tests\all.tcl $(TESTFLAGS) | $(CAT32)