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

📄 tclglob.c

📁 CMX990 demonstration board (DE9901)
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (d == NULL) {
	    Tcl_ResetResult(interp);
	    Tcl_AppendResult(interp, "couldn't read directory \"",
		    dirName, "\": ", Tcl_UnixError(interp), (char *) NULL);
	    return TCL_ERROR;
	}
	l1 = strlen(dir);
	l2 = (p - rem);
	if (l2 < STATIC_SIZE) {
	    pattern = static2;
	} else {
	    pattern = (char *) ckalloc((unsigned) (l2+1));
	}
	strncpy(pattern, rem, l2);
	pattern[l2] = '\0';
	result = TCL_OK;
	while (1) {
	    entryPtr = readdir(d);
	    if (entryPtr == NULL) {
		break;
	    }

	    /*
	     * Don't match names starting with "." unless the "." is
	     * present in the pattern.
	     */

	    if ((*entryPtr->d_name == '.') && (*pattern != '.')) {
		continue;
	    }
	    if (Tcl_StringMatch(entryPtr->d_name, pattern)) {
		int nameLength = strlen(entryPtr->d_name);
		if (*p == 0) {
		    AppendResult(interp, dir, separator, entryPtr->d_name,
			    nameLength);
		} else {
		    if ((l1+nameLength+2) <= STATIC_SIZE) {
			newDir = static1;
		    } else {
			newDir = (char *) ckalloc((unsigned) (l1+nameLength+2));
		    }
		    sprintf(newDir, "%s%s%s", dir, separator, entryPtr->d_name);
		    result = DoGlob(interp, newDir, p+1);
		    if (newDir != static1) {
			ckfree(newDir);
		    }
		    if (result != TCL_OK) {
			break;
		    }
		}
	    }
	}
	closedir(d);
	if (pattern != static2) {
	    ckfree(pattern);
	}
	return result;
    }

    /*
     * This is the simplest case:  just another path element.  Move
     * it to the dir side and recurse (or just add the name to the
     * list, if we're at the end of the path).
     */

    if (*p == 0) {
	AppendResult(interp, dir, separator, rem, p-rem);
    } else {
	int l1, l2;
	char *newDir;
	char static1[STATIC_SIZE];

	l1 = strlen(dir);
	l2 = l1 + (p - rem) + 2;
	if (l2 <= STATIC_SIZE) {
	    newDir = static1;
	} else {
	    newDir = (char *) ckalloc((unsigned) l2);
	}
	sprintf(newDir, "%s%s%.*s", dir, separator, (int)(p-rem), rem);
	result = DoGlob(interp, newDir, p+1);
	if (newDir != static1) {
	    ckfree(newDir);
	}
	if (result != TCL_OK) {
	    return TCL_ERROR;
	}
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_TildeSubst --
 *
 *	Given a name starting with a tilde, produce a name where
 *	the tilde and following characters have been replaced by
 *	the home directory location for the named user.
 *
 * Results:
 *	The result is a pointer to a static string containing
 *	the new name.  This name will only persist until the next
 *	call to Tcl_TildeSubst;  save it if you care about it for
 *	the long term.  If there was an error in processing the
 *	tilde, then an error message is left in interp->result
 *	and the return value is NULL.
 *
 * Side effects:
 *	None that the caller needs to worry about.
 *
 *----------------------------------------------------------------------
 */

char *
Tcl_TildeSubst(interp, name)
    Tcl_Interp *interp;		/* Interpreter in which to store error
				 * message (if necessary). */
    char *name;			/* File name, which may begin with "~/"
				 * (to indicate current user's home directory)
				 * or "~<user>/" (to indicate any user's
				 * home directory). */
{
#define STATIC_BUF_SIZE 50
    static char staticBuf[STATIC_BUF_SIZE];
    static int curSize = STATIC_BUF_SIZE;
    static char *curBuf = staticBuf;
    char *dir;
    int length;
    int fromPw = 0;
    register char *p;

    if (name[0] != '~') {
	return name;
    }

    /*
     * First, find the directory name corresponding to the tilde entry.
     */

    if ((name[1] == '/') || (name[1] == '\0')) {
	dir = getenv("HOME");
	if (dir == NULL) {
	    Tcl_ResetResult(interp);
	    Tcl_AppendResult(interp, "couldn't find HOME environment ",
		    "variable to expand \"", name, "\"", (char *) NULL);
	    return NULL;
	}
	p = name+1;
    } else {
	struct passwd *pwPtr;

	for (p = &name[1]; (*p != 0) && (*p != '/'); p++) {
	    /* Null body;  just find end of name. */
	}
	length = p-&name[1];
	if (length >= curSize) {
	    length = curSize-1;
	}
	memcpy((VOID *) curBuf, (VOID *) (name+1), length);
	curBuf[length] = '\0';
	//pwPtr = getpwnam(curBuf);
	pwPtr = NULL;
	if (pwPtr == NULL) {
          //endpwent();
	    Tcl_ResetResult(interp);
	    Tcl_AppendResult(interp, "user \"", curBuf,
		    "\" doesn't exist", (char *) NULL);
	    return NULL;
	}
	dir = pwPtr->pw_dir;
	fromPw = 1;
    }

    /*
     * Grow the buffer if necessary to make enough space for the
     * full file name.
     */

    length = strlen(dir) + strlen(p);
    if (length >= curSize) {
	if (curBuf != staticBuf) {
	    ckfree(curBuf);
	}
	curSize = length + 1;
	curBuf = (char *) ckalloc((unsigned) curSize);
    }

    /*
     * Finally, concatenate the directory name with the remainder
     * of the path in the buffer.
     */

    strcpy(curBuf, dir);
    strcat(curBuf, p);
    if (fromPw) {
      //endpwent();
    }
    return curBuf;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_GlobCmd --
 *
 *	This procedure is invoked to process the "glob" 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_GlobCmd(dummy, interp, argc, argv)
    ClientData dummy;			/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int argc;				/* Number of arguments. */
    char **argv;			/* Argument strings. */
{
    int i, result, noComplain;

    if (argc < 2) {
	notEnoughArgs:
	Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
		" ?-nocomplain? name ?name ...?\"", (char *) NULL);
	return TCL_ERROR;
    }
    noComplain = 0;
    if ((argv[1][0] == '-') && (strcmp(argv[1], "-nocomplain") == 0)) {
	if (argc < 3) {
	    goto notEnoughArgs;
	}
	noComplain = 1;
    }

    for (i = 1 + noComplain; i < argc; i++) {
	char *thisName;

	/*
	 * Do special checks for names starting at the root and for
	 * names beginning with ~.  Then let DoGlob do the rest.
	 */

	thisName = argv[i];
	if (*thisName == '~') {
	    thisName = Tcl_TildeSubst(interp, thisName);
	    if (thisName == NULL) {
		return TCL_ERROR;
	    }
	}
	if (*thisName == '/') {
	    result = DoGlob(interp, "/", thisName+1);
	} else {
	    result = DoGlob(interp, "", thisName);
	}
	if (result != TCL_OK) {
	    return result;
	}
    }
    if ((*interp->result == 0) && !noComplain) {
	char *sep = "";

	Tcl_AppendResult(interp, "no files matched glob pattern",
		(argc == 2) ? " \"" : "s \"", (char *) NULL);
	for (i = 1; i < argc; i++) {
	    Tcl_AppendResult(interp, sep, argv[i], (char *) NULL);
	    sep = " ";
	}
	Tcl_AppendResult(interp, "\"", (char *) NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}

⌨️ 快捷键说明

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