📄 tkoption.c
字号:
Tk_OptionCmd(clientData, interp, argc, argv) ClientData clientData; /* Main window associated with * interpreter. */ Tcl_Interp *interp; /* Current interpreter. */ int argc; /* Number of arguments. */ char **argv; /* Argument strings. */{ Tk_Window tkwin = (Tk_Window) clientData; size_t length; char c; if (argc < 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " cmd arg ?arg ...?\"", (char *) NULL); return TCL_ERROR; } c = argv[1][0]; length = strlen(argv[1]); if ((c == 'a') && (strncmp(argv[1], "add", length) == 0)) { int priority; if ((argc != 4) && (argc != 5)) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " add pattern value ?priority?\"", (char *) NULL); return TCL_ERROR; } if (argc == 4) { priority = TK_INTERACTIVE_PRIO; } else { priority = ParsePriority(interp, argv[4]); if (priority < 0) { return TCL_ERROR; } } Tk_AddOption(tkwin, argv[2], argv[3], priority); return TCL_OK; } else if ((c == 'c') && (strncmp(argv[1], "clear", length) == 0)) { TkMainInfo *mainPtr; if (argc != 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " clear\"", (char *) NULL); return TCL_ERROR; } mainPtr = ((TkWindow *) tkwin)->mainPtr; if (mainPtr->optionRootPtr != NULL) { ClearOptionTree(mainPtr->optionRootPtr); mainPtr->optionRootPtr = NULL; } cachedWindow = NULL; return TCL_OK; } else if ((c == 'g') && (strncmp(argv[1], "get", length) == 0)) { Tk_Window window; Tk_Uid value; if (argc != 5) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " get window name class\"", (char *) NULL); return TCL_ERROR; } window = Tk_NameToWindow(interp, argv[2], tkwin); if (window == NULL) { return TCL_ERROR; } value = Tk_GetOption(window, argv[3], argv[4]); if (value != NULL) { interp->result = value; } return TCL_OK; } else if ((c == 'r') && (strncmp(argv[1], "readfile", length) == 0)) { int priority; if ((argc != 3) && (argc != 4)) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " readfile fileName ?priority?\"", (char *) NULL); return TCL_ERROR; } if (argc == 4) { priority = ParsePriority(interp, argv[3]); if (priority < 0) { return TCL_ERROR; } } else { priority = TK_INTERACTIVE_PRIO; } return ReadOptionFile(interp, tkwin, argv[2], priority); } else { Tcl_AppendResult(interp, "bad option \"", argv[1], "\": must be add, clear, get, or readfile", (char *) NULL); return TCL_ERROR; }}/* *-------------------------------------------------------------- * * TkOptionDeadWindow -- * * This procedure is called whenever a window is deleted. * It cleans up any option-related stuff associated with * the window. * * Results: * None. * * Side effects: * Option-related resources are freed. See code below * for details. * *-------------------------------------------------------------- */voidTkOptionDeadWindow(winPtr) register TkWindow *winPtr; /* Window to be cleaned up. */{ /* * If this window is in the option stacks, then clear the stacks. */ if (winPtr->optionLevel != -1) { int i; for (i = 1; i <= curLevel; i++) { levels[i].winPtr->optionLevel = -1; } curLevel = -1; cachedWindow = NULL; } /* * If this window was a main window, then delete its option * database. */ if ((winPtr->mainPtr->winPtr == winPtr) && (winPtr->mainPtr->optionRootPtr != NULL)) { ClearOptionTree(winPtr->mainPtr->optionRootPtr); winPtr->mainPtr->optionRootPtr = NULL; }}/* *---------------------------------------------------------------------- * * TkOptionClassChanged -- * * This procedure is invoked when a window's class changes. If * the window is on the option cache, this procedure flushes * any information for the window, since the new class could change * what is relevant. * * Results: * None. * * Side effects: * The option cache may be flushed in part or in whole. * *---------------------------------------------------------------------- */voidTkOptionClassChanged(winPtr) TkWindow *winPtr; /* Window whose class changed. */{ int i, j, *basePtr; ElArray *arrayPtr; if (winPtr->optionLevel == -1) { return; } /* * Find the lowest stack level that refers to this window, then * flush all of the levels above the matching one. */ for (i = 1; i <= curLevel; i++) { if (levels[i].winPtr == winPtr) { for (j = i; j <= curLevel; j++) { levels[j].winPtr->optionLevel = -1; } curLevel = i-1; basePtr = levels[i].bases; for (j = 0; j < NUM_STACKS; j++) { arrayPtr = stacks[j]; arrayPtr->numUsed = basePtr[j]; arrayPtr->nextToUse = &arrayPtr->els[arrayPtr->numUsed]; } if (curLevel <= 0) { cachedWindow = NULL; } else { cachedWindow = levels[curLevel].winPtr; } break; } }}/* *---------------------------------------------------------------------- * * ParsePriority -- * * Parse a string priority value. * * Results: * The return value is the integer priority level corresponding * to string, or -1 if string doesn't point to a valid priority level. * In this case, an error message is left in interp->result. * * Side effects: * None. * *---------------------------------------------------------------------- */static intParsePriority(interp, string) Tcl_Interp *interp; /* Interpreter to use for error reporting. */ char *string; /* Describes a priority level, either * symbolically or numerically. */{ int priority, c; size_t length; c = string[0]; length = strlen(string); if ((c == 'w') && (strncmp(string, "widgetDefault", length) == 0)) { return TK_WIDGET_DEFAULT_PRIO; } else if ((c == 's') && (strncmp(string, "startupFile", length) == 0)) { return TK_STARTUP_FILE_PRIO; } else if ((c == 'u') && (strncmp(string, "userDefault", length) == 0)) { return TK_USER_DEFAULT_PRIO; } else if ((c == 'i') && (strncmp(string, "interactive", length) == 0)) { return TK_INTERACTIVE_PRIO; } else { char *end; priority = strtoul(string, &end, 0); if ((end == string) || (*end != 0) || (priority < 0) || (priority > 100)) { Tcl_AppendResult(interp, "bad priority level \"", string, "\": must be widgetDefault, startupFile, userDefault, ", "interactive, or a number between 0 and 100", (char *) NULL); return -1; } } return priority;}/* *---------------------------------------------------------------------- * * AddFromString -- * * Given a string containing lines in the standard format for * X resources (see other documentation for details on what this * is), parse the resource specifications and enter them as options * for tkwin's main window. * * Results: * The return value is a standard Tcl return code. In the case of * an error in parsing string, TCL_ERROR will be returned and an * error message will be left in interp->result. The memory at * string is totally trashed by this procedure. If you care about * its contents, make a copy before calling here. * * Side effects: * None. * *---------------------------------------------------------------------- */static intAddFromString(interp, tkwin, string, priority) Tcl_Interp *interp; /* Interpreter to use for reporting results. */ Tk_Window tkwin; /* Token for window: options are entered * for this window's main window. */ char *string; /* String containing option specifiers. */ int priority; /* Priority level to use for options in * this string, such as TK_USER_DEFAULT_PRIO * or TK_INTERACTIVE_PRIO. Must be between * 0 and TK_MAX_PRIO. */{ register char *src, *dst; char *name, *value; int lineNum; src = string; lineNum = 1; while (1) { /* * Skip leading white space and empty lines and comment lines, and * check for the end of the spec. */ while ((*src == ' ') || (*src == '\t')) { src++; } if ((*src == '#') || (*src == '!')) { do { src++; if ((src[0] == '\\') && (src[1] == '\n')) { src += 2; lineNum++; } } while ((*src != '\n') && (*src != 0)); } if (*src == '\n') { src++; lineNum++; continue; } if (*src == '\0') { break; } /* * Parse off the option name, collapsing out backslash-newline * sequences of course. */ dst = name = src; while (*src != ':') { if ((*src == '\0') || (*src == '\n')) { sprintf(interp->result, "missing colon on line %d", lineNum); return TCL_ERROR; } if ((src[0] == '\\') && (src[1] == '\n')) { src += 2; lineNum++; } else { *dst = *src; dst++; src++; } } /* * Eliminate trailing white space on the name, and null-terminate * it. */ while ((dst != name) && ((dst[-1] == ' ') || (dst[-1] == '\t'))) { dst--; } *dst = '\0'; /* * Skip white space between the name and the value. */ src++; while ((*src == ' ') || (*src == '\t')) { src++; } if (*src == '\0') { sprintf(interp->result, "missing value on line %d", lineNum); return TCL_ERROR; } /* * Parse off the value, squeezing out backslash-newline sequences * along the way. */ dst = value = src; while (*src != '\n') { if (*src == '\0') { sprintf(interp->result, "missing newline on line %d", lineNum); return TCL_ERROR; } if ((src[0] == '\\') && (src[1] == '\n')) { src += 2; lineNum++; } else { *dst = *src; dst++; src++; } } *dst = 0; /* * Enter the option into the database. */ Tk_AddOption(tkwin, name, value, priority); src++; lineNum++; } return TCL_OK;}/* *---------------------------------------------------------------------- * * ReadOptionFile -- * * Read a file of options ("resources" in the old X terminology) * and load them into the option database. * * Results: * The return value is a standard Tcl return code. In the case of * an error in parsing string, TCL_ERROR will be returned and an * error message will be left in interp->result. * * Side effects: * None. * *---------------------------------------------------------------------- */static intReadOptionFile(interp, tkwin, fileName, priority) Tcl_Interp *interp; /* Interpreter to use for reporting results. */ Tk_Window tkwin; /* Token for window: options are entered * for this window's main window. */ char *fileName; /* Name of file containing options. */ int priority; /* Priority level to use for options in * this file, such as TK_USER_DEFAULT_PRIO * or TK_INTERACTIVE_PRIO. Must be between * 0 and TK_MAX_PRIO. */{ char *realName, *buffer; int result, bufferSize; Tcl_Channel chan; Tcl_DString newName; /* * Prevent file system access in a safe interpreter. */ if (Tcl_IsSafe(interp)) { Tcl_AppendResult(interp, "can't read options from a file in a", " safe interpreter", (char *) NULL); return TCL_ERROR; } realName = Tcl_TranslateFileName(interp, fileName, &newName); if (realName == NULL) { return TCL_ERROR; } chan = Tcl_OpenFileChannel(interp, realName, "r", 0); Tcl_DStringFree(&newName); if (chan == NULL) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "couldn't open \"", fileName, "\": ", Tcl_PosixError(interp), (char *) NULL); return TCL_ERROR; } /* * Compute size of file by seeking to the end of the file. This will * overallocate if we are performing CRLF translation. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -