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

📄 tclcmdmz.c

📁 CMX990 demonstration board (DE9901)
💻 C
📖 第 1 页 / 共 3 页
字号:
 *----------------------------------------------------------------------
 *
 * Tcl_ReturnCmd --
 *
 *	This procedure is invoked to process the "return" 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_ReturnCmd(dummy, interp, argc, argv)
  ClientData dummy;			/* Not used. */
Tcl_Interp *interp;			/* Current interpreter. */
int argc;				/* Number of arguments. */
char **argv;			/* Argument strings. */
{
  if (argc > 2) {
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                     " ?value?\"", (char *) NULL);
    return TCL_ERROR;
  }
  if (argc == 2) {
    Tcl_SetResult(interp, argv[1], TCL_VOLATILE);
  }
  return TCL_RETURN;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ScanCmd --
 *
 *	This procedure is invoked to process the "scan" 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_ScanCmd(dummy, interp, argc, argv)
  ClientData dummy;			/* Not used. */
Tcl_Interp *interp;			/* Current interpreter. */
int argc;				/* Number of arguments. */
char **argv;			/* Argument strings. */
{
  int arg1Length;			/* Number of bytes in argument to be
					 * scanned.  This gives an upper limit
					 * on string field sizes. */
#   define MAX_FIELDS 20
  typedef struct {
    char fmt;			/* Format for field. */
    int size;			/* How many bytes to allow for
                                 * field. */
    char *location;			/* Where field will be stored. */
  } Field;
  Field fields[MAX_FIELDS];		/* Info about all the fields in the
					 * format string. */
  register Field *curField;
  int numFields = 0;			/* Number of fields actually
					 * specified. */
  int suppress;			/* Current field is assignment-
                                 * suppressed. */
  int totalSize = 0;			/* Number of bytes needed to store
					 * all results combined. */
  char *results;			/* Where scanned output goes.  */
  int numScanned;			/* sscanf's result. */
  register char *fmt;
  int i, widthSpecified;

  if (argc < 3) {
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                     " string format ?varName varName ...?\"", (char *) NULL);
    return TCL_ERROR;
  }

  /*
   * This procedure operates in four stages:
   * 1. Scan the format string, collecting information about each field.
   * 2. Allocate an array to hold all of the scanned fields.
   * 3. Call sscanf to do all the dirty work, and have it store the
   *    parsed fields in the array.
   * 4. Pick off the fields from the array and assign them to variables.
   */

  arg1Length = (strlen(argv[1]) + 4) & ~03;
  for (fmt = argv[2]; *fmt != 0; fmt++) {
    if (*fmt != '%') {
      continue;
    }
    fmt++;
    if (*fmt == '*') {
      suppress = 1;
      fmt++;
    } else {
      suppress = 0;
    }
    widthSpecified = 0;
    while (isdigit(*fmt)) {
      widthSpecified = 1;
      fmt++;
    }
    if (suppress) {
      continue;
    }
    if (numFields == MAX_FIELDS) {
      interp->result = "too many fields to scan";
      return TCL_ERROR;
    }
    curField = &fields[numFields];
    numFields++;
    switch (*fmt) {
    case 'D':
    case 'O':
    case 'X':
    case 'd':
    case 'o':
    case 'x':
      curField->fmt = 'd';
      curField->size = sizeof(int);
      break;

    case 's':
      curField->fmt = 's';
      curField->size = arg1Length;
      break;

    case 'c':
      if (widthSpecified) {
        interp->result = 
          "field width may not be specified in %c conversion";
        return TCL_ERROR;
      }
      curField->fmt = 'c';
      curField->size = sizeof(int);
      break;

    case 'E':
    case 'F':
      curField->fmt = 'F';
      curField->size = sizeof(double);
      break;

    case 'e':
    case 'f':
      curField->fmt = 'f';
      curField->size = sizeof(float);
      break;

    case '[':
      curField->fmt = 's';
      curField->size = arg1Length;
      do {
        fmt++;
      } while (*fmt != ']');
      break;

    default:
      sprintf(interp->result, "bad scan conversion character \"%c\"",
              *fmt);
      return TCL_ERROR;
    }
    totalSize += curField->size;
  }

  if (numFields != (argc-3)) {
    interp->result =
      "different numbers of variable names and field specifiers";
    return TCL_ERROR;
  }

  /*
   * Step 2:
   */

  results = (char *) ckalloc((unsigned) totalSize);
  for (i = 0, totalSize = 0, curField = fields;
       i < numFields; i++, curField++) {
    curField->location = results + totalSize;
    totalSize += curField->size;
  }

  /*
   * Fill in the remaining fields with NULL;  the only purpose of
   * this is to keep some memory analyzers, like Purify, from
   * complaining.
   */

  for ( ; i < MAX_FIELDS; i++, curField++) {
    curField->location = NULL;
  }

  /*
   * Step 3:
   */

  numScanned = sscanf(argv[1], argv[2],
                      fields[0].location, fields[1].location, fields[2].location,
                      fields[3].location, fields[4].location, fields[5].location,
                      fields[6].location, fields[7].location, fields[8].location,
                      fields[9].location, fields[10].location, fields[11].location,
                      fields[12].location, fields[13].location, fields[14].location,
                      fields[15].location, fields[16].location, fields[17].location,
                      fields[18].location, fields[19].location);

  /*
   * Step 4:
   */

  if (numScanned < numFields) {
    numFields = numScanned;
  }
  for (i = 0, curField = fields; i < numFields; i++, curField++) {
    switch (curField->fmt) {
      char string[120];

    case 'd':
      sprintf(string, "%d", *((int *) curField->location));
      if (Tcl_SetVar(interp, argv[i+3], string, 0) == NULL) {
      storeError:
        Tcl_AppendResult(interp,
                         "couldn't set variable \"", argv[i+3], "\"",
                         (char *) NULL);
        ckfree((char *) results);
        return TCL_ERROR;
      }
      break;

    case 'c':
      sprintf(string, "%d", *((char *) curField->location) & 0xff);
      if (Tcl_SetVar(interp, argv[i+3], string, 0) == NULL) {
        goto storeError;
      }
      break;

    case 's':
      if (Tcl_SetVar(interp, argv[i+3], curField->location, 0)
          == NULL) {
        goto storeError;
      }
      break;

    case 'F':
      sprintf(string, "%g", *((double *) curField->location));
      if (Tcl_SetVar(interp, argv[i+3], string, 0) == NULL) {
        goto storeError;
      }
      break;

    case 'f':
      sprintf(string, "%g", *((float *) curField->location));
      if (Tcl_SetVar(interp, argv[i+3], string, 0) == NULL) {
        goto storeError;
      }
      break;
    }
  }
  ckfree(results);
  sprintf(interp->result, "%d", numScanned);
  return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_SplitCmd --
 *
 *	This procedure is invoked to process the "split" 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_SplitCmd(dummy, interp, argc, argv)
  ClientData dummy;			/* Not used. */
Tcl_Interp *interp;			/* Current interpreter. */
int argc;				/* Number of arguments. */
char **argv;			/* Argument strings. */
{
  char *splitChars;
  register char *p, *p2;
  char *elementStart;

  if (argc == 2) {
    splitChars = " \n\t\r";
  } else if (argc == 3) {
    splitChars = argv[2];
  } else {
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                     " string ?splitChars?\"", (char *) NULL);
    return TCL_ERROR;
  }

  /*
   * Handle the special case of splitting on every character.
   */

  if (*splitChars == 0) {
    char string[2];
    string[1] = 0;
    for (p = argv[1]; *p != 0; p++) {
      string[0] = *p;
      Tcl_AppendElement(interp, string, 0);
    }
    return TCL_OK;
  }

  /*
   * Normal case: split on any of a given set of characters.
   * Discard instances of the split characters.
   */

  for (p = elementStart = argv[1]; *p != 0; p++) {
    char c = *p;
    for (p2 = splitChars; *p2 != 0; p2++) {
      if (*p2 == c) {
        *p = 0;
        Tcl_AppendElement(interp, elementStart, 0);
        *p = c;
        elementStart = p+1;
        break;
      }
    }
  }
  if (p != argv[1]) {
    Tcl_AppendElement(interp, elementStart, 0);
  }
  return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_StringCmd --
 *
 *	This procedure is invoked to process the "string" 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_StringCmd(dummy, interp, argc, argv)
  ClientData dummy;			/* Not used. */
Tcl_Interp *interp;			/* Current interpreter. */
int argc;				/* Number of arguments. */
char **argv;			/* Argument strings. */
{
  int length;
  register char *p, c;
  int match;
  int first;
  int left = 0, right = 0;

  if (argc < 2) {
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                     " option arg ?arg ...?\"", (char *) NULL);
    return TCL_ERROR;
  }
  c = argv[1][0];
  length = strlen(argv[1]);
  if ((c == 'c') && (strncmp(argv[1], "compare", length) == 0)) {
    if (argc != 4) {
      Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                       " compare string1 string2\"", (char *) NULL);
      return TCL_ERROR;
    }
    match = strcmp(argv[2], argv[3]);
    if (match > 0) {
      interp->result = "1";
    } else if (match < 0) {
      interp->result = "-1";
    } else {
      interp->result = "0";
    }
    return TCL_OK;
  } else if ((c == 'f') && (strncmp(argv[1], "first", length) == 0)) {
    if (argc != 4) {
      Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                       " first string1 string2\"", (char *) NULL);
      return TCL_ERROR;
    }
    first = 1;

  firstLast:
    match = -1;
    c = *argv[2];
    length = strlen(argv[2]);
    for (p = argv[3]; *p != 0; p++) {
      if (*p != c) {
        continue;
      }
      if (strncmp(argv[2], p, length) == 0) {
        match = p-argv[3];
        if (first) {
          break;
        }
      }
    }
    sprintf(interp->result, "%d", match);
    return TCL_OK;
  } else if ((c == 'i') && (strncmp(argv[1], "index", length) == 0)) {
    int index;

    if (argc != 4) {
      Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                       " index string charIndex\"", (char *) NULL);
      return TCL_ERROR;
    }
    if (Tcl_GetInt(interp, argv[3], &index) != TCL_OK) {
      return TCL_ERROR;
    }
    if ((index >= 0) && (index < strlen(argv[2]))) {
      interp->result[0] = argv[2][index];
      interp->result[1] = 0;
    }
    return TCL_OK;
  } else if ((c == 'l') && (strncmp(argv[1], "last", length) == 0)
             && (length >= 2)) {
    if (argc != 4) {
      Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                       " last string1 string2\"", (char *) NULL);
      return TCL_ERROR;
    }
    first = 0;
    goto firstLast;
  } else if ((c == 'l') && (strncmp(argv[1], "length", length) == 0)
             && (length >= 2)) {
    if (argc != 3) {
      Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                       " length string\"", (char *) NULL);
      return TCL_ERROR;
    }
    sprintf(interp->result, "%d", (int)strlen(argv[2]));
    return TCL_OK;
  } else if ((c == 'm') && (strncmp(argv[1], "match", length) == 0)) {
    if (argc != 4) {
      Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                       " match pattern string\"", (char *) NULL);
      return TCL_ERROR;
    }
    if (Tcl_StringMatch(argv[3], argv[2]) != 0) {
      interp->result = "1";
    } else {
      interp->result = "0";
    }
    return TCL_OK;
  } else if ((c == 'r') && (strncmp(argv[1], "range", length) == 0)) {

⌨️ 快捷键说明

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