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

📄 tclfilename.c

📁 linux系统下的音频通信
💻 C
📖 第 1 页 / 共 3 页
字号:
            home_var = "HOME";#endif            dir = TclGetEnv(home_var);            if (dir == NULL) {	    if (interp) {		Tcl_ResetResult(interp);		Tcl_AppendResult(interp, "couldn't find environment variable specifying home directory: ", home_var, (char *) NULL);	    }	    return NULL;	}	Tcl_JoinPath(1, &dir, resultPtr);    } else {		/* lint, TclGetuserHome() always NULL under windows. */	if (TclGetUserHome(user, resultPtr) == NULL) {		    if (interp) {		Tcl_ResetResult(interp);		Tcl_AppendResult(interp, "user \"", user, "\" doesn't exist",			(char *) NULL);	    }	    return NULL;	}    }    return resultPtr->string;}/* *---------------------------------------------------------------------- * * 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 */intTcl_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, noComplain, firstArg;    char c;    int result = TCL_OK;    Tcl_DString buffer;    char *separators, *head, *tail;    noComplain = 0;    for (firstArg = 1; (firstArg < argc) && (argv[firstArg][0] == '-');	    firstArg++) {	if (strcmp(argv[firstArg], "-nocomplain") == 0) {	    noComplain = 1;	} else if (strcmp(argv[firstArg], "--") == 0) {	    firstArg++;	    break;	} else {	    Tcl_AppendResult(interp, "bad switch \"", argv[firstArg],		    "\": must be -nocomplain or --", (char *) NULL);	    return TCL_ERROR;	}    }    if (firstArg >= argc) {	Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],		" ?switches? name ?name ...?\"", (char *) NULL);	return TCL_ERROR;    }    Tcl_DStringInit(&buffer);    separators = NULL;		/* Needed only to prevent gcc warnings. */    for (i = firstArg; i < argc; i++) {	switch (tclPlatform) {	case TCL_PLATFORM_UNIX:	    separators = "/";	    break;	case TCL_PLATFORM_WINDOWS:	    separators = "/\\:";	    break;	case TCL_PLATFORM_MAC:	    separators = (strchr(argv[i], ':') == NULL) ? "/" : ":";	    break;	}	Tcl_DStringSetLength(&buffer, 0);	/*	 * Perform tilde substitution, if needed.	 */	if (argv[i][0] == '~') {	    char *p;	    /*	     * Find the first path separator after the tilde.	     */	    for (tail = argv[i]; *tail != '\0'; tail++) {		if (*tail == '\\') {		    if (strchr(separators, tail[1]) != NULL) {			break;		    }		} else if (strchr(separators, *tail) != NULL) {		    break;		}	    }	    /*	     * Determine the home directory for the specified user.  Note that	     * we don't allow special characters in the user name.	     */	    c = *tail;	    *tail = '\0';	    p = strpbrk(argv[i]+1, "\\[]*?{}");	    if (p == NULL) {		head = DoTildeSubst(interp, argv[i]+1, &buffer);	    } else {		if (!noComplain) {		    Tcl_ResetResult(interp);		    Tcl_AppendResult(interp, "globbing characters not ",			    "supported in user names", (char *) NULL);		}		head = NULL;	    }	    *tail = c;	    if (head == NULL) {		if (noComplain) {		    Tcl_ResetResult(interp);		    continue;		} else {		    result = TCL_ERROR;		    goto done;		}	    }	    if (head != Tcl_DStringValue(&buffer)) {		Tcl_DStringAppend(&buffer, head, -1);	    }	} else {	    tail = argv[i];	}	result = TclDoGlob(interp, separators, &buffer, tail);	if (result != TCL_OK) {	    if (noComplain) {		/*		 * We should in fact pass down the nocomplain flag 		 * or save the interp result or use another mecanism		 * so the interp result is not mangled on errors in that case.		 * but that would a bigger change than reasonable for a patch		 * release.		 * (see fileName.test 15.2-15.4 for expected behaviour)		 */		Tcl_ResetResult(interp);		result = TCL_OK;		continue;	    } else {		goto done;	    }	}    }    if ((*interp->result == 0) && !noComplain) {	char *sep = "";	Tcl_AppendResult(interp, "no files matched glob pattern",		(argc == 2) ? " \"" : "s \"", (char *) NULL);	for (i = firstArg; i < argc; i++) {	    Tcl_AppendResult(interp, sep, argv[i], (char *) NULL);	    sep = " ";	}	Tcl_AppendResult(interp, "\"", (char *) NULL);	result = TCL_ERROR;    }done:    Tcl_DStringFree(&buffer);    return result;}/* *---------------------------------------------------------------------- * * SkipToChar -- * *	This function traverses a glob pattern looking for the next *	unquoted occurance of the specified character at the same braces *	nesting level. * * Results: *	Updates stringPtr to point to the matching character, or to *	the end of the string if nothing matched.  The return value *	is 1 if a match was found at the top level, otherwise it is 0. * * Side effects: *	None. * *---------------------------------------------------------------------- */static intSkipToChar(stringPtr, match)    char **stringPtr;			/* Pointer string to check. */    char *match;			/* Pointer to character to find. */{    int quoted, level;    register char *p;    quoted = 0;    level = 0;    for (p = *stringPtr; *p != '\0'; p++) {	if (quoted) {	    quoted = 0;	    continue;	}	if ((level == 0) && (*p == *match)) {	    *stringPtr = p;	    return 1;	}	if (*p == '{') {	    level++;	} else if (*p == '}') {	    level--;	} else if (*p == '\\') {	    quoted = 1;	}    }    *stringPtr = p;    return 0;}/* *---------------------------------------------------------------------- * * TclDoGlob -- * *	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.  The directory and *	remainder are assumed to be native format paths. * * 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. * *---------------------------------------------------------------------- */intTclDoGlob(interp, separators, headPtr, tail)    Tcl_Interp *interp;		/* Interpreter to use for error reporting				 * (e.g. unmatched brace). */    char *separators;		/* String containing separator characters				 * that should be used to identify globbing				 * boundaries. */    Tcl_DString *headPtr;	/* Completely expanded prefix. */    char *tail;			/* The unexpanded remainder of the path. */{    int baseLength, quoted, count;    int result = TCL_OK;    char *p, *openBrace, *closeBrace, *name, *firstSpecialChar, savedChar;    char lastChar = 0;    int length = Tcl_DStringLength(headPtr);    if (length > 0) {	lastChar = Tcl_DStringValue(headPtr)[length-1];    }    /*     * Consume any leading directory separators, leaving tail pointing     * just past the last initial separator.     */    count = 0;    name = tail;    for (; *tail != '\0'; tail++) {	if ((*tail == '\\') && (strchr(separators, tail[1]) != NULL)) {	    tail++;	} else if (strchr(separators, *tail) == NULL) {	    break;	}	count++;    }    /*     * Deal with path separators.  On the Mac, we have to watch out     * for multiple separators, since they are special in Mac-style     * paths.     */    switch (tclPlatform) {	case TCL_PLATFORM_MAC:	    if (*separators == '/') {		if (((length == 0) && (count == 0))			|| ((length > 0) && (lastChar != ':'))) {		    Tcl_DStringAppend(headPtr, ":", 1);		}	    } else {		if (count == 0) {		    if ((length > 0) && (lastChar != ':')) {			Tcl_DStringAppend(headPtr, ":", 1);		    }		} else {		    if (lastChar == ':') {			count--;		    }		    while (count-- > 0) {			Tcl_DStringAppend(headPtr, ":", 1);		    }		}	    }	    break;	case TCL_PLATFORM_WINDOWS:	    /*	     * If this is a drive relative path, add the colon and the	     * trailing slash if needed.  Otherwise add the slash if	     * this is the first absolute element, or a later relative	     * element.  Add an extra slash if this is a UNC path.	     */	    if (*name == ':') {		Tcl_DStringAppend(headPtr, ":", 1);		if (count > 1) {		    Tcl_DStringAppend(headPtr, "/", 1);		}	    } else if ((*tail != '\0')		    && (((length > 0)			    && (strchr(separators, lastChar) == NULL))			    || ((length == 0) && (count > 0)))) {		Tcl_DStringAppend(headPtr, "/", 1);		if ((length == 0) && (count > 1)) {		    Tcl_DStringAppend(headPtr, "/", 1);		}	    }	    	    break;	case TCL_PLATFORM_UNIX:	    /*	     * Add a separator if this is the first absolute element, or	     * a later relative element.	     */	    if ((*tail != '\0')		    && (((length > 0)			    && (strchr(separators, lastChar) == NULL))			    || ((length == 0) && (count > 0)))) {		Tcl_DStringAppend(headPtr, "/", 1);	    }	    break;    }    /*     * Look for the first matching pair of braces or the first     * directory separator that is not inside a pair of braces.     */    openBrace = closeBrace = NULL;    quoted = 0;    for (p = tail; *p != '\0'; p++) {	if (quoted) {	    quoted = 0;	} else if (*p == '\\') {	    quoted = 1;	    if (strchr(separators, p[1]) != NULL) {		break;			/* Quoted directory separator. */	    }	} else if (strchr(separators, *p) != NULL) {	    break;			/* Unquoted directory separator. */	} else if (*p == '{') {	    openBrace = p;	    p++;	    if (SkipToChar(&p, "}")) {		closeBrace = p;		/* Balanced braces. */		break;	    }	    Tcl_SetResult(interp, "unmatched open-brace in file name",		    TCL_STATIC);	    return TCL_ERROR;	} else if (*p == '}') {	    Tcl_SetResult(interp, "unmatched close-brace in file name",		    TCL_STATIC);	    return TCL_ERROR;	}    }    /*     * Substitute the alternate patterns from the braces and recurse.     */    if (openBrace != NULL) {	char *element;	Tcl_DString newName;	Tcl_DStringInit(&newName);	/*	 * For each element within in the outermost pair of braces,	 * append the element and the remainder to the fixed portion	 * before the first brace and recursively call TclDoGlob.	 */	Tcl_DStringAppend(&newName, tail, openBrace-tail);	baseLength = Tcl_DStringLength(&newName);	length = Tcl_DStringLength(headPtr);	*closeBrace = '\0';	for (p = openBrace; p != closeBrace; ) {	    p++;	    element = p;	    SkipToChar(&p, ",");	    Tcl_DStringSetLength(headPtr, length);	    Tcl_DStringSetLength(&newName, baseLength);	    Tcl_DStringAppend(&newName, element, p-element);	    Tcl_DStringAppend(&newName, closeBrace+1, -1);	    result = TclDoGlob(interp, separators,		    headPtr, Tcl_DStringValue(&newName));	    if (result != TCL_OK) {		break;	    }	}	*closeBrace = '}';	Tcl_DStringFree(&newName);	return result;    }    /*     * At this point, there are no more brace substitutions to perform on     * this path component.  The variable p is pointing at a quoted or     * unquoted directory separator or the end of the string.  So we need     * to check for special globbing characters in the current pattern.     * We avoid modifying tail if p is pointing at the end of the string.     */    if (*p != '\0') {	 savedChar = *p;	 *p = '\0';	 firstSpecialChar = strpbrk(tail, "*[]?\\");	 *p = savedChar;    } else {	firstSpecialChar = strpbrk(tail, "*[]?\\");    }    if (firstSpecialChar != NULL) {	/*	 * Look for matching files in the current directory.  The	 * implementation of this function is platform specific, but may	 * recursively call TclDoGlob.  For each file that matches, it will	 * add the match onto the interp->result, or call TclDoGlob if there	 * are more characters to be processed.	 */	return TclMatchFiles(interp, separators, headPtr, tail, p);    }    Tcl_DStringAppend(headPtr, tail, p-tail);    if (*p != '\0') {	return TclDoGlob(interp, separators, headPtr, p);    }    /*     * There are no more wildcards in the pattern and no more unprocessed     * characters in the tail, so now we can construct the path and verify     * the existence of the file.     */    switch (tclPlatform) {	case TCL_PLATFORM_MAC:	    if (strchr(Tcl_DStringValue(headPtr), ':') == NULL) {		Tcl_DStringAppend(headPtr, ":", 1);	    }	    name = Tcl_DStringValue(headPtr);	    if (TclAccess(name, F_OK) == 0) {		if ((name[1] != '\0') && (strchr(name+1, ':') == NULL)) {		    Tcl_AppendElement(interp, name+1);		} else {		    Tcl_AppendElement(interp, name);		}	    }	    break;	case TCL_PLATFORM_WINDOWS: {	    int exists;	    /*	     * We need to convert slashes to backslashes before checking	     * for the existence of the file.  Once we are done, we need	     * to convert the slashes back.	     */	    if (Tcl_DStringLength(headPtr) == 0) {		if (((*name == '\\') && (name[1] == '/' || name[1] == '\\'))			|| (*name == '/')) {		    Tcl_DStringAppend(headPtr, "\\", 1);		} else {		    Tcl_DStringAppend(headPtr, ".", 1);		}	    } else {		for (p = Tcl_DStringValue(headPtr); *p != '\0'; p++) {		    if (*p == '/') {			*p = '\\';		    }		}	    }	    name = Tcl_DStringValue(headPtr);	    exists = (TclAccess(name, F_OK) == 0);	    for (p = name; *p != '\0'; p++) {		if (*p == '\\') {		    *p = '/';		}	    }	    if (exists) {		Tcl_AppendElement(interp, name);	    }	    break;	}	case TCL_PLATFORM_UNIX:	    if (Tcl_DStringLength(headPtr) == 0) {		if ((*name == '\\' && name[1] == '/') || (*name == '/')) {		    Tcl_DStringAppend(headPtr, "/", 1);		} else {		    Tcl_DStringAppend(headPtr, ".", 1);		}	    }	    name = Tcl_DStringValue(headPtr);	    if (TclAccess(name, F_OK) == 0) {		Tcl_AppendElement(interp, name);	    }	    break;    }    return TCL_OK;}

⌨️ 快捷键说明

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