⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tclcmdmz.c

📁 CMX990 demonstration board (DE9901)
💻 C
📖 第 1 页 / 共 3 页
字号:
    int first, last, stringLength;

    if (argc != 5) {
      Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                       " range string first last\"", (char *) NULL);
      return TCL_ERROR;
    }
    stringLength = strlen(argv[2]);
    if (Tcl_GetInt(interp, argv[3], &first) != TCL_OK) {
      return TCL_ERROR;
    }
    if ((*argv[4] == 'e')
        && (strncmp(argv[4], "end", strlen(argv[4])) == 0)) {
      last = stringLength-1;
    } else {
      if (Tcl_GetInt(interp, argv[4], &last) != TCL_OK) {
        Tcl_ResetResult(interp);
        Tcl_AppendResult(interp,
                         "expected integer or \"end\" but got \"",
                         argv[4], "\"", (char *) NULL);
        return TCL_ERROR;
      }
    }
    if (first < 0) {
      first = 0;
    }
    if (last >= stringLength) {
      last = stringLength-1;
    }
    if (last >= first) {
      char saved, *p;

      p = argv[2] + last + 1;
      saved = *p;
      *p = 0;
      Tcl_SetResult(interp, argv[2] + first, TCL_VOLATILE);
      *p = saved;
    }
    return TCL_OK;
  } else if ((c == 't') && (strncmp(argv[1], "tolower", length) == 0)
             && (length >= 3)) {
    register char *p;

    if (argc != 3) {
      Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                       " tolower string\"", (char *) NULL);
      return TCL_ERROR;
    }
    Tcl_SetResult(interp, argv[2], TCL_VOLATILE);
    for (p = interp->result; *p != 0; p++) {
      if (isupper(*p)) {
        *p = tolower(*p);
      }
    }
    return TCL_OK;
  } else if ((c == 't') && (strncmp(argv[1], "toupper", length) == 0)
             && (length >= 3)) {
    register char *p;

    if (argc != 3) {
      Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                       " toupper string\"", (char *) NULL);
      return TCL_ERROR;
    }
    Tcl_SetResult(interp, argv[2], TCL_VOLATILE);
    for (p = interp->result; *p != 0; p++) {
      if (islower(*p)) {
        *p = toupper(*p);
      }
    }
    return TCL_OK;
  } else if ((c == 't') && (strncmp(argv[1], "trim", length) == 0)
             && (length == 4)) {
    char *trimChars;
    register char *p, *checkPtr;

    left = right = 1;

  trim:
    if (argc == 4) {
      trimChars = argv[3];
    } else if (argc == 3) {
      trimChars = " \t\n\r";
    } else {
      Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                       " ", argv[1], " string ?chars?\"", (char *) NULL);
      return TCL_ERROR;
    }
    p = argv[2];
    if (left) {
      for (c = *p; c != 0; p++, c = *p) {
        for (checkPtr = trimChars; *checkPtr != c; checkPtr++) {
          if (*checkPtr == 0) {
            goto doneLeft;
          }
        }
      }
    }
  doneLeft:
    Tcl_SetResult(interp, p, TCL_VOLATILE);
    if (right) {
      char *donePtr;

      p = interp->result + strlen(interp->result) - 1;
      donePtr = &interp->result[-1];
      for (c = *p; p != donePtr; p--, c = *p) {
        for (checkPtr = trimChars; *checkPtr != c; checkPtr++) {
          if (*checkPtr == 0) {
            goto doneRight;
          }
        }
      }
    doneRight:
      p[1] = 0;
    }
    return TCL_OK;
  } else if ((c == 't') && (strncmp(argv[1], "trimleft", length) == 0)
             && (length > 4)) {
    left = 1;
    argv[1] = "trimleft";
    goto trim;
  } else if ((c == 't') && (strncmp(argv[1], "trimright", length) == 0)
             && (length > 4)) {
    right = 1;
    argv[1] = "trimright";
    goto trim;
  } else {
    Tcl_AppendResult(interp, "bad option \"", argv[1],
                     "\": should be compare, first, index, last, length, match, ",
                     "range, tolower, toupper, trim, trimleft, or trimright",
                     (char *) NULL);
    return TCL_ERROR;
  }
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_TraceCmd --
 *
 *	This procedure is invoked to process the "trace" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

/* ARGSUSED */
int
Tcl_TraceCmd(dummy, interp, argc, argv)
  ClientData dummy;			/* Not used. */
Tcl_Interp *interp;			/* Current interpreter. */
int argc;				/* Number of arguments. */
char **argv;			/* Argument strings. */
{
  char c;
  int length;

  if (argc < 2) {
    Tcl_AppendResult(interp, "too few args: should be \"",
                     argv[0], " option [arg arg ...]\"", (char *) NULL);
    return TCL_ERROR;
  }
  c = argv[1][1];
  length = strlen(argv[1]);
  if ((c == 'a') && (strncmp(argv[1], "variable", length) == 0)
      && (length >= 2)) {
    char *p;
    int flags, length;
    TraceVarInfo *tvarPtr;

    if (argc != 5) {
      Tcl_AppendResult(interp, "wrong # args: should be \"",
                       argv[0], " variable name ops command\"", (char *) NULL);
      return TCL_ERROR;
    }

    flags = 0;
    for (p = argv[3] ; *p != 0; p++) {
      if (*p == 'r') {
        flags |= TCL_TRACE_READS;
      } else if (*p == 'w') {
        flags |= TCL_TRACE_WRITES;
      } else if (*p == 'u') {
        flags |= TCL_TRACE_UNSETS;
      } else {
        goto badOps;
      }
    }
    if (flags == 0) {
      goto badOps;
    }

    length = strlen(argv[4]);
    tvarPtr = (TraceVarInfo *) ckalloc((unsigned)
                                       (sizeof(TraceVarInfo) - sizeof(tvarPtr->command) + length + 1));
    tvarPtr->flags = flags;
    tvarPtr->length = length;
    flags |= TCL_TRACE_UNSETS;
    strcpy(tvarPtr->command, argv[4]);
    if (Tcl_TraceVar(interp, argv[2], flags, TraceVarProc,
                     (ClientData) tvarPtr) != TCL_OK) {
      ckfree((char *) tvarPtr);
      return TCL_ERROR;
    }
  } else if ((c == 'd') && (strncmp(argv[1], "vdelete", length)
                            && (length >= 2)) == 0) {
    char *p;
    int flags, length;
    TraceVarInfo *tvarPtr;
    ClientData clientData;

    if (argc != 5) {
      Tcl_AppendResult(interp, "wrong # args: should be \"",
                       argv[0], " vdelete name ops command\"", (char *) NULL);
      return TCL_ERROR;
    }

    flags = 0;
    for (p = argv[3] ; *p != 0; p++) {
      if (*p == 'r') {
        flags |= TCL_TRACE_READS;
      } else if (*p == 'w') {
        flags |= TCL_TRACE_WRITES;
      } else if (*p == 'u') {
        flags |= TCL_TRACE_UNSETS;
      } else {
        goto badOps;
      }
    }
    if (flags == 0) {
      goto badOps;
    }

    /*
     * Search through all of our traces on this variable to
     * see if there's one with the given command.  If so, then
     * delete the first one that matches.
     */

    length = strlen(argv[4]);
    clientData = 0;
    while ((clientData = Tcl_VarTraceInfo(interp, argv[2], 0,
                                          TraceVarProc, clientData)) != 0) {
      tvarPtr = (TraceVarInfo *) clientData;
      if ((tvarPtr->length == length) && (tvarPtr->flags == flags)
          && (strncmp(argv[4], tvarPtr->command, length) == 0)) {
        Tcl_UntraceVar(interp, argv[2], flags | TCL_TRACE_UNSETS,
                       TraceVarProc, clientData);
        ckfree((char *) tvarPtr);
        break;
      }
    }
  } else if ((c == 'i') && (strncmp(argv[1], "vinfo", length) == 0)
             && (length >= 2)) {
    ClientData clientData;
    char ops[4], *p;
    char *prefix = "{";

    if (argc != 3) {
      Tcl_AppendResult(interp, "wrong # args: should be \"",
                       argv[0], " vinfo name\"", (char *) NULL);
      return TCL_ERROR;
    }
    clientData = 0;
    while ((clientData = Tcl_VarTraceInfo(interp, argv[2], 0,
                                          TraceVarProc, clientData)) != 0) {
      TraceVarInfo *tvarPtr = (TraceVarInfo *) clientData;
      p = ops;
      if (tvarPtr->flags & TCL_TRACE_READS) {
        *p = 'r';
        p++;
      }
      if (tvarPtr->flags & TCL_TRACE_WRITES) {
        *p = 'w';
        p++;
      }
      if (tvarPtr->flags & TCL_TRACE_UNSETS) {
        *p = 'u';
        p++;
      }
      *p = '\0';
      Tcl_AppendResult(interp, prefix, (char *) NULL);
      Tcl_AppendElement(interp, ops, 1);
      Tcl_AppendElement(interp, tvarPtr->command, 0);
      Tcl_AppendResult(interp, "}", (char *) NULL);
      prefix = " {";
    }
  } else {
    Tcl_AppendResult(interp, "bad option \"", argv[1],
                     "\": should be variable, vdelete, or vinfo",
                     (char *) NULL);
    return TCL_ERROR;
  }
  return TCL_OK;

 badOps:
  Tcl_AppendResult(interp, "bad operations \"", argv[3],
                   "\": should be one or more of rwu", (char *) NULL);
  return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * TraceVarProc --
 *
 *	This procedure is called to handle variable accesses that have
 *	been traced using the "trace" command.
 *
 * Results:
 *	Normally returns NULL.  If the trace command returns an error,
 *	then this procedure returns an error string.
 *
 * Side effects:
 *	Depends on the command associated with the trace.
 *
 *----------------------------------------------------------------------
 */

/* ARGSUSED */
static char *
TraceVarProc(clientData, interp, name1, name2, flags)
  ClientData clientData;	/* Information about the variable trace. */
Tcl_Interp *interp;		/* Interpreter containing variable. */
char *name1;		/* Name of variable or array. */
char *name2;		/* Name of element within array;  NULL means
                         * scalar variable is being referenced. */
int flags;			/* OR-ed bits giving operation and other
				 * information. */
{
  TraceVarInfo *tvarPtr = (TraceVarInfo *) clientData;
  char *result;
  int code, cmdLength, flags1, flags2;
  Interp dummy;
#define STATIC_SIZE 199
  char staticSpace[STATIC_SIZE+1];
  char *cmdPtr, *p;

  result = NULL;
  if ((tvarPtr->flags & flags) && !(flags & TCL_INTERP_DESTROYED)) {

    /*
     * Generate a command to execute by appending list elements
     * for the two variable names and the operation.  The five
     * extra characters are for three space, the opcode character,
     * and the terminating null.
     */

    if (name2 == NULL) {
      name2 = "";
    }
    cmdLength = tvarPtr->length + Tcl_ScanElement(name1, &flags1) +
      Tcl_ScanElement(name2, &flags2) + 5;
    if (cmdLength < STATIC_SIZE) {
      cmdPtr = staticSpace;
    } else {
      cmdPtr = (char *) ckalloc((unsigned) cmdLength);
    }
    p = cmdPtr;
    strcpy(p, tvarPtr->command);
    p += tvarPtr->length;
    *p = ' ';
    p++;
    p += Tcl_ConvertElement(name1, p, flags1);
    *p = ' ';
    p++;
    p += Tcl_ConvertElement(name2, p, flags2);
    *p = ' ';
    if (flags & TCL_TRACE_READS) {
      p[1] = 'r';
    } else if (flags & TCL_TRACE_WRITES) {
      p[1] = 'w';
    } else if (flags & TCL_TRACE_UNSETS) {
      p[1] = 'u';
    }
    p[2] = '\0';

    /*
     * Execute the command.  Be careful to save and restore the
     * result from the interpreter used for the command.
     */

    if (interp->freeProc == 0) {
      dummy.freeProc = (Tcl_FreeProc *) 0;
      dummy.result = "";
      Tcl_SetResult((Tcl_Interp *) &dummy, interp->result, TCL_VOLATILE);
    } else {
      dummy.freeProc = interp->freeProc;
      dummy.result = interp->result;
    }
    code = Tcl_Eval(interp, cmdPtr, 0, (char **) NULL);
    if (cmdPtr != staticSpace) {
      ckfree(cmdPtr);
    }
    if (code != TCL_OK) {
      result = "access disallowed by trace command";
      Tcl_ResetResult(interp);		/* Must clear error state. */
    }
    Tcl_FreeResult(interp);
    interp->result = dummy.result;
    interp->freeProc = dummy.freeProc;
  }
  if (flags & TCL_TRACE_DESTROYED) {
    ckfree((char *) tvarPtr);
  }
  return result;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_WhileCmd --
 *
 *	This procedure is invoked to process the "while" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

/* ARGSUSED */
int
Tcl_WhileCmd(dummy, interp, argc, argv)
  ClientData dummy;			/* Not used. */
Tcl_Interp *interp;			/* Current interpreter. */
int argc;				/* Number of arguments. */
char **argv;			/* Argument strings. */
{
  int result, value;

  if (argc != 3) {
    Tcl_AppendResult(interp, "wrong # args: should be \"",
                     argv[0], " test command\"", (char *) NULL);
    return TCL_ERROR;
  }

  while (1) {
    result = Tcl_ExprBoolean(interp, argv[1], &value);
    if (result != TCL_OK) {
      return result;
    }
    if (!value) {
      break;
    }
    result = Tcl_Eval(interp, argv[2], 0, (char **) NULL);
    if (result == TCL_CONTINUE) {
      result = TCL_OK;
    } else if (result != TCL_OK) {
      if (result == TCL_ERROR) {
        char msg[60];
        sprintf(msg, "\n    (\"while\" body line %d)",
                interp->errorLine);
        Tcl_AddErrorInfo(interp, msg);
      }
      break;
    }
  }
  if (result == TCL_BREAK) {
    result = TCL_OK;
  }
  if (result == TCL_OK) {
    Tcl_ResetResult(interp);
  }
  return result;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -