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

📄 tclglob.c

📁 tcl源码详细资料
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifndef EXCLUDE_TCL/*  * tclGlob.c -- * *	This file provides procedures and commands for file name *	manipulation, such as tilde expansion and globbing. * * Copyright 1990-1991 Regents of the University of California * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies.  The University of California * makes no representations about the suitability of this * software for any purpose.  It is provided "as is" without * express or implied warranty. */#include "tclInt.h"#include "tclUnix.h"/* * The structure below is used to keep track of a globbing result * being built up (i.e. a partial list of file names).  The list * grows dynamically to be as big as needed. */typedef struct {    char *result;		/* Pointer to result area. */    int totalSpace;		/* Total number of characters allocated				 * for result. */    int spaceUsed;		/* Number of characters currently in use				 * to hold the partial result (not including				 * the terminating NULL). */    int dynamic;		/* 0 means result is static space, 1 means				 * it's dynamic. */} GlobResult;/* * Declarations for procedures local to this file: */static void		AppendResult _ANSI_ARGS_((Tcl_Interp *interp,			    char *dir, char *separator, char *name,			    int nameLength));static int		DoGlob _ANSI_ARGS_((Tcl_Interp *interp, char *dir,			    char *rem));/* *---------------------------------------------------------------------- * * AppendResult -- * *	Given two parts of a file name (directory and element within *	directory), concatenate the two together and append them to *	the result building up in interp. * * Results: *	There is no return value. * * Side effects: *	Interp->result gets extended. * *---------------------------------------------------------------------- */static voidAppendResult(interp, dir, separator, name, nameLength)    Tcl_Interp *interp;		/* Interpreter whose result should be				 * appended to. */    char *dir;			/* Name of directory, without trailing				 * slash except for root directory. */    char *separator;		/* Separator string so use between dir and				 * name:  either "/" or "" depending on dir. */    char *name;			/* Name of file withing directory (NOT				 * necessarily null-terminated!). */    int nameLength;		/* Number of characters in name. */{    int dirFlags, nameFlags;    char *p, saved;    /*     * Next, see if we can put together a valid list element from dir     * and name by calling Tcl_AppendResult.     */    if (*dir == 0) {	dirFlags = 0;    } else {	Tcl_ScanElement(dir, &dirFlags);    }    saved = name[nameLength];    name[nameLength] = 0;    Tcl_ScanElement(name, &nameFlags);    if ((dirFlags == 0) && (nameFlags == 0)) {	if (*interp->result != 0) {	    Tcl_AppendResult(interp, " ", dir, separator, name, (char *) NULL);	} else {	    Tcl_AppendResult(interp, dir, separator, name, (char *) NULL);	}	name[nameLength] = saved;	return;    }    /*     * This name has weird characters in it, so we have to convert it to     * a list element.  To do that, we have to merge the characters     * into a single name.  To do that, malloc a buffer to hold everything.     */    p = (char *) ckalloc((unsigned) (strlen(dir) + strlen(separator)	    + nameLength + 1));    sprintf(p, "%s%s%s", dir, separator, name);    name[nameLength] = saved;    Tcl_AppendElement(interp, p, 0);    ckfree(p);}/* *---------------------------------------------------------------------- * * DoGlob -- * *	This recursive procedure forms the heart of the globbing *	code.  It performs a depth-first traversal of the tree *	given by the path name to be globbed. * * Results: *	The return value is a standard Tcl result indicating whether *	an error occurred in globbing.  After a normal return the *	result in interp will be set to hold all of the file names *	given by the dir and rem arguments.  After an error the *	result in interp will hold an error message. * * Side effects: *	None. * *---------------------------------------------------------------------- */static intDoGlob(interp, dir, rem)    Tcl_Interp *interp;			/* Interpreter to use for error					 * reporting (e.g. unmatched brace). */    char *dir;				/* Name of a directory at which to					 * start glob expansion.  This name					 * is fixed: it doesn't contain any					 * globbing chars. */    char *rem;				/* Path to glob-expand. */{    /*     * When this procedure is entered, the name to be globbed may     * already have been partly expanded by ancestor invocations of     * DoGlob.  The part that's already been expanded is in "dir"     * (this may initially be empty), and the part still to expand     * is in "rem".  This procedure expands "rem" one level, making     * recursive calls to itself if there's still more stuff left     * in the remainder.     */    register char *p;    register char c;    char *openBrace, *closeBrace;    int gotSpecial, result;    char *separator;    /*     * Figure out whether we'll need to add a slash between the directory     * name and file names within the directory when concatenating them     * together.     */    if ((dir[0] == 0) || ((dir[0] == '/') && (dir[1] == 0))) {	separator = "";    } else {	separator = "/";    }    /*     * When generating information for the next lower call,     * use static areas if the name is short, and malloc if the name     * is longer.     */#define STATIC_SIZE 200    /*     * First, find the end of the next element in rem, checking     * along the way for special globbing characters.     */    gotSpecial = 0;    openBrace = closeBrace = NULL;    for (p = rem; ; p++) {	c = *p;	if ((c == '\0') || (c == '/')) {	    break;	}	if ((c == '{') && (openBrace == NULL)) {	    openBrace = p;	}	if ((c == '}') && (closeBrace == NULL)) {	    closeBrace = p;	}	if ((c == '*') || (c == '[') || (c == '\\') || (c == '?')) {	    gotSpecial = 1;	}    }    /*     * If there is an open brace in the argument, then make a recursive     * call for each element between the braces.  In this case, the     * recursive call to DoGlob uses the same "dir" that we got.     * If there are several brace-pairs in a single name, we just handle     * one here, and the others will be handled in recursive calls.     */    if (openBrace != NULL) {	int remLength, l1, l2;	char static1[STATIC_SIZE];	char *element, *newRem;	if (closeBrace == NULL) {	    Tcl_ResetResult(interp);	    interp->result = "unmatched open-brace in file name";	    return TCL_ERROR;	}	remLength = strlen(rem) + 1;	if (remLength <= STATIC_SIZE) {	    newRem = static1;	} else {	    newRem = (char *) ckalloc((unsigned) remLength);	}	l1 = openBrace-rem;	strncpy(newRem, rem, l1);	p = openBrace;	for (p = openBrace; *p != '}'; ) {	    element = p+1;	    for (p = element; ((*p != '}') && (*p != ',')); p++) {		/* Empty loop body:  just find end of this element. */	    }	    l2 = p - element;	    strncpy(newRem+l1, element, l2);	    strcpy(newRem+l1+l2, closeBrace+1);	    if (DoGlob(interp, dir, newRem) != TCL_OK) {		return TCL_ERROR;	    }	}	if (remLength > STATIC_SIZE) {	    ckfree(newRem);	}	return TCL_OK;    }    /*     * If there were any pattern-matching characters, then scan through     * the directory to find all the matching names.     */    if (gotSpecial) {	yaffs_DIR *d;	yaffs_dirent *entryPtr;	int l1, l2;	char *pattern, *newDir, *dirName, *path;	char static1[STATIC_SIZE], static2[STATIC_SIZE];	struct yaffs_stat statBuf;	/*	 * Be careful not to do any actual file system operations on a	 * directory named "";  instead, use ".".  This is needed because	 * some versions of UNIX don't treat "" like "." automatically.	 */	if (*dir == '\0') {	    dirName = ".";	} else {	    dirName = dir;	}	if (strcmp(".", dirName) == 0) {	    path = "./";	}	else if (strcmp("..", dirName) == 0) {	    path = "../";	}	else {	    path = dirName;	}	if ((yaffs_stat(path, &statBuf) != 0) || !S_ISDIR(statBuf.st_mode)) {	    return TCL_OK;	}	d = yaffs_opendir(path);	if (d == NULL) {

⌨️ 快捷键说明

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