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

📄 tclutil.c

📁 CMX990 demonstration board (DE9901)
💻 C
📖 第 1 页 / 共 3 页
字号:
   */

  nestingLevel = 0;
  flags = 0;
  if (string == NULL) {
    string = "";
  }
  p = string;
  if ((*p == '{') || (*p == '"') || (*p == 0)) {
    flags |= USE_BRACES;
  }
  for ( ; *p != 0; p++) {
    switch (*p) {
    case '{':
      nestingLevel++;
      break;
    case '}':
      nestingLevel--;
      if (nestingLevel < 0) {
        flags |= TCL_DONT_USE_BRACES|BRACES_UNMATCHED;
      }
      break;
    case '[':
    case '$':
    case ';':
    case ' ':
    case '\f':
    case '\n':
    case '\r':
    case '\t':
    case '\v':
      flags |= USE_BRACES;
      break;
    case '\\':
      if ((p[1] == 0) || (p[1] == '\n')) {
        flags = TCL_DONT_USE_BRACES;
      } else {
        int size;

        (void) Tcl_Backslash(p, &size);
        p += size-1;
        flags |= USE_BRACES;
      }
      break;
    }
  }
  if (nestingLevel != 0) {
    flags = TCL_DONT_USE_BRACES | BRACES_UNMATCHED;
  }
  *flagPtr = flags;

  /*
   * Allow enough space to backslash every character plus leave
   * two spaces for braces.
   */

  return 2*(p-string) + 2;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ConvertElement --
 *
 *	This is a companion procedure to Tcl_ScanElement.  Given the
 *	information produced by Tcl_ScanElement, this procedure converts
 *	a string to a list element equal to that string.
 *
 * Results:
 *	Information is copied to *dst in the form of a list element
 *	identical to src (i.e. if Tcl_SplitList is applied to dst it
 *	will produce a string identical to src).  The return value is
 *	a count of the number of characters copied (not including the
 *	terminating NULL character).
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int Tcl_ConvertElement(char *src, char *dst, int flags)
  //  register char *src;		/* Source information for list element. */
  //char *dst;			/* Place to put list-ified element. */
  //int flags;			/* Flags produced by Tcl_ScanElement. */
{
  register char *p = dst;

  /*
   * See the comment block at the beginning of the Tcl_ScanElement
   * code for details of how this works.
   */

  if (src == NULL) {
    src = "";
  }
  if ((flags & USE_BRACES) && !(flags & TCL_DONT_USE_BRACES)) {
    *p = '{';
    p++;
    for ( ; *src != 0; src++, p++) {
      *p = *src;
    }
    *p = '}';
    p++;
  } else if (*src == 0) {
    /*
     * If string is empty but can't use braces, then use special
     * backslash sequence that maps to empty string.
     */

    p[0] = '\\';
    p[1] = '0';
    p += 2;
  } else {
    for (; *src != 0 ; src++) {
      switch (*src) {
      case ']':
      case '[':
      case '$':
      case ';':
      case ' ':
      case '\\':
      case '"':
        *p = '\\';
        p++;
        break;
      case '{':
      case '}':
        if (flags & BRACES_UNMATCHED) {
          *p = '\\';
          p++;
        }
        break;
      case '\f':
        *p = '\\';
        p++;
        *p = 'f';
        p++;
        continue;
      case '\n':
        *p = '\\';
        p++;
        *p = 'n';
        p++;
        continue;
      case '\r':
        *p = '\\';
        p++;
        *p = 'r';
        p++;
        continue;
      case '\t':
        *p = '\\';
        p++;
        *p = 't';
        p++;
        continue;
      case '\v':
        *p = '\\';
        p++;
        *p = 'v';
        p++;
        continue;
      }
      *p = *src;
      p++;
    }
  }
  *p = '\0';
  return p-dst;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_Merge --
 *
 *	Given a collection of strings, merge them together into a
 *	single string that has proper Tcl list structured (i.e.
 *	Tcl_SplitList may be used to retrieve strings equal to the
 *	original elements, and Tcl_Eval will parse the string back
 *	into its original elements).
 *
 * Results:
 *	The return value is the address of a dynamically-allocated
 *	string containing the merged list.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

char *Tcl_Merge(int argc, char **argv)
  //  int argc;			/* How many strings to merge. */
  //char **argv;		/* Array of string values. */
{
#   define LOCAL_SIZE 20
  int localFlags[LOCAL_SIZE], *flagPtr;
  int numChars;
  char *result;
  register char *dst;
  int i;

  /*
   * Pass 1: estimate space, gather flags.
   */

  if (argc <= LOCAL_SIZE) {
    flagPtr = localFlags;
  } else {
    flagPtr = (int *) ckalloc((unsigned) argc*sizeof(int));
  }
  numChars = 1;
  for (i = 0; i < argc; i++) {
    numChars += Tcl_ScanElement(argv[i], &flagPtr[i]) + 1;
  }

  /*
   * Pass two: copy into the result area.
   */

  result = (char *) ckalloc((unsigned) numChars);
  dst = result;
  for (i = 0; i < argc; i++) {
    numChars = Tcl_ConvertElement(argv[i], dst, flagPtr[i]);
    dst += numChars;
    *dst = ' ';
    dst++;
  }
  if (dst == result) {
    *dst = 0;
  } else {
    dst[-1] = 0;
  }

  if (flagPtr != localFlags) {
    ckfree((char *) flagPtr);
  }
  return result;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_Concat --
 *
 *	Concatenate a set of strings into a single large string.
 *
 * Results:
 *	The return value is dynamically-allocated string containing
 *	a concatenation of all the strings in argv, with spaces between
 *	the original argv elements.
 *
 * Side effects:
 *	Memory is allocated for the result;  the caller is responsible
 *	for freeing the memory.
 *
 *----------------------------------------------------------------------
 */

char *Tcl_Concat(int argc, char **argv)
  //int argc;			/* Number of strings to concatenate. */
  //char **argv;		/* Array of strings to concatenate. */
{
  int totalSize, i;
  register char *p;
  char *result;

  for (totalSize = 1, i = 0; i < argc; i++) {
    totalSize += strlen(argv[i]) + 1;
  }
  result = (char *) ckalloc((unsigned) totalSize);
  if (argc == 0) {
    *result = '\0';
    return result;
  }
  for (p = result, i = 0; i < argc; i++) {
    char *element;
    int length;

    /*
     * Clip white space off the front and back of the string
     * to generate a neater result, and ignore any empty
     * elements.
     */

    element = argv[i];
    while (isspace(*element)) {
      element++;
    }
    for (length = strlen(element);
         (length > 0) && (isspace(element[length-1]));
         length--) {
      /* Null loop body. */
    }
    if (length == 0) {
      continue;
    }
    (void) strncpy(p, element, length);
    p += length;
    *p = ' ';
    p++;
  }
  if (p != result) {
    p[-1] = 0;
  } else {
    *p = 0;
  }
  return result;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_StringMatch --
 *
 *	See if a particular string matches a particular pattern.
 *
 * Results:
 *	The return value is 1 if string matches pattern, and
 *	0 otherwise.  The matching operation permits the following
 *	special characters in the pattern: *?\[] (see the manual
 *	entry for details on what these mean).
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */
int Tcl_StringMatch(char *string, char *pattern)
  //  register char *string;	/* String. */
  //register char *pattern;	/* Pattern, which may contain
  //                       * special characters. */
{
  char c2;

  while (1) {
    /* See if we're at the end of both the pattern and the string.
     * If so, we succeeded.  If we're at the end of the pattern
     * but not at the end of the string, we failed.
     */
	
    if (*pattern == 0) {
      if (*string == 0) {
        return 1;
      } else {
        return 0;
      }
    }
    if ((*string == 0) && (*pattern != '*')) {
      return 0;
    }

    /* Check for a "*" as the next pattern character.  It matches
     * any substring.  We handle this by calling ourselves
     * recursively for each postfix of string, until either we
     * match or we reach the end of the string.
     */
	
    if (*pattern == '*') {
      pattern += 1;
      if (*pattern == 0) {
        return 1;
      }
      while (1) {
        if (Tcl_StringMatch(string, pattern)) {
          return 1;
        }
        if (*string == 0) {
          return 0;
        }
        string += 1;
      }
    }
    
    /* Check for a "?" as the next pattern character.  It matches
     * any single character.
     */

    if (*pattern == '?') {
      goto thisCharOK;
    }

    /* Check for a "[" as the next pattern character.  It is followed
     * by a list of characters that are acceptable, or by a range
     * (two characters separated by "-").
     */
	
    if (*pattern == '[') {
      pattern += 1;
      while (1) {
        if ((*pattern == ']') || (*pattern == 0)) {
          return 0;
        }
        if (*pattern == *string) {
          break;
        }
        if (pattern[1] == '-') {
          c2 = pattern[2];
          if (c2 == 0) {
            return 0;
          }
          if ((*pattern <= *string) && (c2 >= *string)) {
            break;
          }
          if ((*pattern >= *string) && (c2 <= *string)) {
            break;
          }
          pattern += 2;
        }
        pattern += 1;
      }
      while ((*pattern != ']') && (*pattern != 0)) {
        pattern += 1;
      }
      goto thisCharOK;
    }
    
    /* If the next pattern character is '/', just strip off the '/'
     * so we do exact matching on the character that follows.
     */
	
    if (*pattern == '\\') {
      pattern += 1;
      if (*pattern == 0) {
        return 0;
      }
    }

    /* There's no special character.  Just make sure that the next
     * characters of each string match.
     */
	
    if (*pattern != *string) {
      return 0;
    }

  thisCharOK: pattern += 1;
    string += 1;
  }
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_SetResult --
 *
 *	Arrange for "string" to be the Tcl return value.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	interp->result is left pointing either to "string" (if "copy" is 0)
 *	or to a copy of string.
 *
 *----------------------------------------------------------------------
 */
void Tcl_SetResult(Tcl_Interp *interp, char *string, Tcl_FreeProc *freeProc)
  //  Tcl_Interp *interp;		/* Interpreter with which to associate the
  //				 * return value. */
  //char *string;		/* Value to be returned.  If NULL,
  //                         * the result is set to an empty string. */
  //Tcl_FreeProc *freeProc;	/* Gives information about the string:
  //                        * TCL_STATIC, TCL_VOLATILE, or the address
  //                       * of a Tcl_FreeProc such as free. */
{
  register Interp *iPtr = (Interp *) interp;
  int length;
  Tcl_FreeProc *oldFreeProc = iPtr->freeProc;
  char *oldResult = iPtr->result;

⌨️ 快捷键说明

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