/* ARGSUSED */ int Tcl_ScanObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { const char *format; int numVars, nconversions, totalVars = -1; int objIndex, offset, i, result, code; long value; const char *string, *end, *baseString; char op = 0; int width, underflow = 0; Tcl_WideInt wideValue; Tcl_UniChar ch, sch; Tcl_Obj **objs = NULL, *objPtr = NULL; int flags; char buf[513]; /* Temporary buffer to hold scanned number * strings before they are passed to * strtoul. */ if (objc < 3) { Tcl_WrongNumArgs(interp, 1, objv, "string format ?varName ...?"); return TCL_ERROR; } format = Tcl_GetStringFromObj(objv[2], NULL); numVars = objc-3; /* * Check for errors in the format string. */ if (ValidateFormat(interp, format, numVars, &totalVars) == TCL_ERROR) { return TCL_ERROR; } /* * Allocate space for the result objects. */ if (totalVars > 0) { objs = ckalloc(sizeof(Tcl_Obj *) * totalVars); for (i = 0; i < totalVars; i++) { objs[i] = NULL; } } string = Tcl_GetStringFromObj(objv[1], NULL); baseString = string; /* * Iterate over the format string filling in the result objects until we * reach the end of input, the end of the format string, or there is a * mismatch. */ objIndex = 0; nconversions = 0; while (*format != '\0') { int parseFlag = TCL_PARSE_NO_WHITESPACE; format += Tcl_UtfToUniChar(format, &ch); flags = 0; /* * If we see whitespace in the format, skip whitespace in the string. */ if (Tcl_UniCharIsSpace(ch)) { offset = Tcl_UtfToUniChar(string, &sch); while (Tcl_UniCharIsSpace(sch)) { if (*string == '\0') { goto done; } string += offset; offset = Tcl_UtfToUniChar(string, &sch); } continue; } if (ch != '%') { literal: if (*string == '\0') { underflow = 1; goto done; } string += Tcl_UtfToUniChar(string, &sch); if (ch != sch) { goto done; } continue; } format += Tcl_UtfToUniChar(format, &ch); if (ch == '%') { goto literal; } /* * Check for assignment suppression ('*') or an XPG3-style assignment * ('%n$'). */ if (ch == '*') { flags |= SCAN_SUPPRESS; format += Tcl_UtfToUniChar(format, &ch); } else if ((ch < 0x80) && isdigit(UCHAR(ch))) { /* INTL: "C" locale. */ char *formatEnd; value = strtoul(format-1, &formatEnd, 10);/* INTL: "C" locale. */ if (*formatEnd == '$') { format = formatEnd+1; format += Tcl_UtfToUniChar(format, &ch); objIndex = (int) value - 1; } } /* * Parse any width specifier. */ if ((ch < 0x80) && isdigit(UCHAR(ch))) { /* INTL: "C" locale. */ width = (int) strtoul(format-1, (char **) &format, 10);/* INTL: "C" locale. */ format += Tcl_UtfToUniChar(format, &ch); } else { width = 0; } /* * Handle any size specifier. */ switch (ch) { case 'l': if (*format == 'l') { flags |= SCAN_BIG; format += 1; format += Tcl_UtfToUniChar(format, &ch); break; } case 'L': flags |= SCAN_LONGER; /* * Fall through so we skip to the next character. */ case 'h': format += Tcl_UtfToUniChar(format, &ch); } /* * Handle the various field types. */ switch (ch) { case 'n': if (!(flags & SCAN_SUPPRESS)) { objPtr = Tcl_NewIntObj(string - baseString); Tcl_IncrRefCount(objPtr); CLANG_ASSERT(objs); objs[objIndex++] = objPtr; } nconversions++; continue; case 'd': op = 'i'; parseFlag |= TCL_PARSE_DECIMAL_ONLY; break; case 'i': op = 'i'; parseFlag |= TCL_PARSE_SCAN_PREFIXES; break; case 'o': op = 'i'; parseFlag |= TCL_PARSE_OCTAL_ONLY | TCL_PARSE_SCAN_PREFIXES; break; case 'x': case 'X': op = 'i'; parseFlag |= TCL_PARSE_HEXADECIMAL_ONLY; break; case 'b': op = 'i'; parseFlag |= TCL_PARSE_BINARY_ONLY; break; case 'u': op = 'i'; parseFlag |= TCL_PARSE_DECIMAL_ONLY; flags |= SCAN_UNSIGNED; break; case 'f': case 'e': case 'E': case 'g': case 'G': op = 'f'; break; case 's': op = 's'; break; case 'c': op = 'c'; flags |= SCAN_NOSKIP; break; case '[': op = '['; flags |= SCAN_NOSKIP; break; } /* * At this point, we will need additional characters from the string * to proceed. */ if (*string == '\0') { underflow = 1; goto done; } /* * Skip any leading whitespace at the beginning of a field unless the * format suppresses this behavior. */ if (!(flags & SCAN_NOSKIP)) { while (*string != '\0') { offset = Tcl_UtfToUniChar(string, &sch); if (!Tcl_UniCharIsSpace(sch)) { break; } string += offset; } if (*string == '\0') { underflow = 1; goto done; } } /* * Perform the requested scanning operation. */ switch (op) { case 's': /* * Scan a string up to width characters or whitespace. */ if (width == 0) { width = ~0; } end = string; while (*end != '\0') { offset = Tcl_UtfToUniChar(end, &sch); if (Tcl_UniCharIsSpace(sch)) { break; } end += offset; if (--width == 0) { break; } } if (!(flags & SCAN_SUPPRESS)) { objPtr = Tcl_NewStringObj(string, end-string); Tcl_IncrRefCount(objPtr); CLANG_ASSERT(objs); objs[objIndex++] = objPtr; } string = end; break; case '[': { CharSet cset; if (width == 0) { width = ~0; } end = string; format = BuildCharSet(&cset, format); while (*end != '\0') { offset = Tcl_UtfToUniChar(end, &sch); if (!CharInSet(&cset, (int)sch)) { break; } end += offset; if (--width == 0) { break; } } ReleaseCharSet(&cset); if (string == end) { /* * Nothing matched the range, stop processing. */ goto done; } if (!(flags & SCAN_SUPPRESS)) { objPtr = Tcl_NewStringObj(string, end-string); Tcl_IncrRefCount(objPtr); objs[objIndex++] = objPtr; } string = end; break; } case 'c': /* * Scan a single Unicode character. */ string += Tcl_UtfToUniChar(string, &sch); if (!(flags & SCAN_SUPPRESS)) { objPtr = Tcl_NewIntObj((int)sch); Tcl_IncrRefCount(objPtr); CLANG_ASSERT(objs); objs[objIndex++] = objPtr; } break; case 'i': /* * Scan an unsigned or signed integer. */ objPtr = Tcl_NewLongObj(0); Tcl_IncrRefCount(objPtr); if (width == 0) { width = ~0; } if (TCL_OK != TclParseNumber(NULL, objPtr, NULL, string, width, &end, TCL_PARSE_INTEGER_ONLY | parseFlag)) { Tcl_DecrRefCount(objPtr); if (width < 0) { if (*end == '\0') { underflow = 1; } } else { if (end == string + width) { underflow = 1; } } goto done; } string = end; if (flags & SCAN_SUPPRESS) { Tcl_DecrRefCount(objPtr); break; } if (flags & SCAN_LONGER) { if (Tcl_GetWideIntFromObj(NULL, objPtr, &wideValue) != TCL_OK) { wideValue = ~(Tcl_WideUInt)0 >> 1; /* WIDE_MAX */ if (TclGetString(objPtr)[0] == '-') { wideValue++; /* WIDE_MAX + 1 = WIDE_MIN */ } } if ((flags & SCAN_UNSIGNED) && (wideValue < 0)) { sprintf(buf, "%" TCL_LL_MODIFIER "u", (Tcl_WideUInt)wideValue); Tcl_SetStringObj(objPtr, buf, -1); } else { Tcl_SetWideIntObj(objPtr, wideValue); } } else if (!(flags & SCAN_BIG)) { if (TclGetLongFromObj(NULL, objPtr, &value) != TCL_OK) { if (TclGetString(objPtr)[0] == '-') { value = LONG_MIN; } else { value = LONG_MAX; } } if ((flags & SCAN_UNSIGNED) && (value < 0)) { sprintf(buf, "%lu", value); /* INTL: ISO digit */ Tcl_SetStringObj(objPtr, buf, -1); } else { Tcl_SetLongObj(objPtr, value); } } objs[objIndex++] = objPtr; break; case 'f': /* * Scan a floating point number */ objPtr = Tcl_NewDoubleObj(0.0); Tcl_IncrRefCount(objPtr); if (width == 0) { width = ~0; } if (TCL_OK != TclParseNumber(NULL, objPtr, NULL, string, width, &end, TCL_PARSE_DECIMAL_ONLY | TCL_PARSE_NO_WHITESPACE)) { Tcl_DecrRefCount(objPtr); if (width < 0) { if (*end == '\0') { underflow = 1; } } else { if (end == string + width) { underflow = 1; } } goto done; } else if (flags & SCAN_SUPPRESS) { Tcl_DecrRefCount(objPtr); string = end; } else { double dvalue; if (Tcl_GetDoubleFromObj(NULL, objPtr, &dvalue) != TCL_OK) { #ifdef ACCEPT_NAN if (objPtr->typePtr == &tclDoubleType) { dvalue = objPtr->internalRep.doubleValue; } else #endif { Tcl_DecrRefCount(objPtr); goto done; } } Tcl_SetDoubleObj(objPtr, dvalue); CLANG_ASSERT(objs); objs[objIndex++] = objPtr; string = end; } }
static int ConsoleObjCmd( ClientData clientData, /* Access to the console interp */ Tcl_Interp *interp, /* Current interpreter */ int objc, /* Number of arguments */ Tcl_Obj *const objv[]) /* Argument objects */ { int index, result; static const char *const options[] = { "eval", "hide", "show", "title", NULL}; enum option {CON_EVAL, CON_HIDE, CON_SHOW, CON_TITLE}; Tcl_Obj *cmd = NULL; ConsoleInfo *info = clientData; Tcl_Interp *consoleInterp = info->consoleInterp; if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "option ?arg?"); return TCL_ERROR; } if (Tcl_GetIndexFromObjStruct(interp, objv[1], options, sizeof(char *), "option", 0, &index) != TCL_OK) { return TCL_ERROR; } switch ((enum option) index) { case CON_EVAL: if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "script"); return TCL_ERROR; } cmd = objv[2]; break; case CON_HIDE: if (objc != 2) { Tcl_WrongNumArgs(interp, 2, objv, NULL); return TCL_ERROR; } cmd = Tcl_NewStringObj("wm withdraw .", -1); break; case CON_SHOW: if (objc != 2) { Tcl_WrongNumArgs(interp, 2, objv, NULL); return TCL_ERROR; } cmd = Tcl_NewStringObj("wm deiconify .", -1); break; case CON_TITLE: if (objc > 3) { Tcl_WrongNumArgs(interp, 2, objv, "?title?"); return TCL_ERROR; } cmd = Tcl_NewStringObj("wm title .", -1); if (objc == 3) { Tcl_ListObjAppendElement(NULL, cmd, objv[2]); } break; default: CLANG_ASSERT(0); } Tcl_IncrRefCount(cmd); if (consoleInterp && !Tcl_InterpDeleted(consoleInterp)) { Tcl_Preserve(consoleInterp); result = Tcl_EvalObjEx(consoleInterp, cmd, TCL_EVAL_GLOBAL); Tcl_SetReturnOptions(interp, Tcl_GetReturnOptions(consoleInterp, result)); Tcl_SetObjResult(interp, Tcl_GetObjResult(consoleInterp)); Tcl_Release(consoleInterp); } else { Tcl_SetObjResult(interp, Tcl_NewStringObj( "no active console interp", -1)); Tcl_SetErrorCode(interp, "TK", "CONSOLE", "NONE", NULL); result = TCL_ERROR; } Tcl_DecrRefCount(cmd); return result; }
TkTextTag * TkTextCreateTag( TkText *textPtr, /* Widget in which tag is being used. */ const char *tagName, /* Name of desired tag. */ int *newTag) /* If non-NULL, then return 1 if new, or 0 if * already exists. */ { register TkTextTag *tagPtr; Tcl_HashEntry *hPtr = NULL; int isNew; const char *name; if (!strcmp(tagName, "sel")) { if (textPtr->selTagPtr != NULL) { if (newTag != NULL) { *newTag = 0; } return textPtr->selTagPtr; } if (newTag != NULL) { *newTag = 1; } name = "sel"; } else { hPtr = Tcl_CreateHashEntry(&textPtr->sharedTextPtr->tagTable, tagName, &isNew); if (newTag != NULL) { *newTag = isNew; } if (!isNew) { return Tcl_GetHashValue(hPtr); } name = Tcl_GetHashKey(&textPtr->sharedTextPtr->tagTable, hPtr); } /* * No existing entry. Create a new one, initialize it, and add a pointer * to it to the hash table entry. */ tagPtr = ckalloc(sizeof(TkTextTag)); tagPtr->name = name; tagPtr->textPtr = NULL; tagPtr->toggleCount = 0; tagPtr->tagRootPtr = NULL; tagPtr->priority = textPtr->sharedTextPtr->numTags; tagPtr->border = NULL; tagPtr->borderWidth = 0; tagPtr->borderWidthPtr = NULL; tagPtr->reliefString = NULL; tagPtr->relief = TK_RELIEF_FLAT; tagPtr->bgStipple = None; tagPtr->fgColor = NULL; tagPtr->tkfont = NULL; tagPtr->fgStipple = None; tagPtr->justifyString = NULL; tagPtr->justify = TK_JUSTIFY_LEFT; tagPtr->lMargin1String = NULL; tagPtr->lMargin1 = 0; tagPtr->lMargin2String = NULL; tagPtr->lMargin2 = 0; tagPtr->offsetString = NULL; tagPtr->offset = 0; tagPtr->overstrikeString = NULL; tagPtr->overstrike = 0; tagPtr->rMarginString = NULL; tagPtr->rMargin = 0; tagPtr->spacing1String = NULL; tagPtr->spacing1 = 0; tagPtr->spacing2String = NULL; tagPtr->spacing2 = 0; tagPtr->spacing3String = NULL; tagPtr->spacing3 = 0; tagPtr->tabStringPtr = NULL; tagPtr->tabArrayPtr = NULL; tagPtr->tabStyle = TK_TEXT_TABSTYLE_NONE; tagPtr->underlineString = NULL; tagPtr->underline = 0; tagPtr->elideString = NULL; tagPtr->elide = 0; tagPtr->wrapMode = TEXT_WRAPMODE_NULL; tagPtr->affectsDisplay = 0; tagPtr->affectsDisplayGeometry = 0; textPtr->sharedTextPtr->numTags++; if (!strcmp(tagName, "sel")) { tagPtr->textPtr = textPtr; textPtr->refCount++; } else { CLANG_ASSERT(hPtr); Tcl_SetHashValue(hPtr, tagPtr); } tagPtr->optionTable = Tk_CreateOptionTable(textPtr->interp, tagOptionSpecs); return tagPtr; }