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

📄 tclfilename.c

📁 linux系统下的音频通信
💻 C
📖 第 1 页 / 共 3 页
字号:
/*  * tclFileName.c -- * *	This file contains routines for converting file names betwen *	native and network form. * * Copyright (c) 1995-1996 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * SCCS: @(#) tclFileName.c 1.32 97/08/19 18:44:03 */#include "tclInt.h"#include "tclPort.h"#include "tclRegexp.h"/* * This variable indicates whether the cleanup procedure has been * registered for this file yet. */static int initialized = 0;/* * The following regular expression matches the root portion of a Windows * absolute or volume relative path.  It will match both UNC and drive relative * paths. */#define WIN_ROOT_PATTERN "^(([a-zA-Z]:)|[/\\][/\\]+([^/\\]+)[/\\]+([^/\\]+)|([/\\]))([/\\])*"/* * The following regular expression matches the root portion of a Macintosh * absolute path.  It will match degenerate Unix-style paths, tilde paths, * Unix-style paths, and Mac paths. */#define MAC_ROOT_PATTERN "^((/+([.][.]?/+)*([.][.]?)?)|(~[^:/]*)(/[^:]*)?|(~[^:]*)(:.*)?|/+([.][.]?/+)*([^:/]+)(/[^:]*)?|([^:]+):.*)$"/* * The following variables are used to hold precompiled regular expressions * for use in filename matching. */static regexp *winRootPatternPtr = NULL;static regexp *macRootPatternPtr = NULL;/* * The following variable is set in the TclPlatformInit call to one * of: TCL_PLATFORM_UNIX, TCL_PLATFORM_MAC, or TCL_PLATFORM_WINDOWS. */TclPlatformType tclPlatform = TCL_PLATFORM_UNIX;/* * Prototypes for local procedures defined in this file: */static char *		DoTildeSubst _ANSI_ARGS_((Tcl_Interp *interp,			    char *user, Tcl_DString *resultPtr));static char *		ExtractWinRoot _ANSI_ARGS_((char *path,			    Tcl_DString *resultPtr, int offset));static void		FileNameCleanup _ANSI_ARGS_((ClientData clientData));static int		SkipToChar _ANSI_ARGS_((char **stringPtr,			    char *match));static char *		SplitMacPath _ANSI_ARGS_((char *path,			    Tcl_DString *bufPtr));static char *		SplitWinPath _ANSI_ARGS_((char *path,			    Tcl_DString *bufPtr));static char *		SplitUnixPath _ANSI_ARGS_((char *path,			    Tcl_DString *bufPtr));/* *---------------------------------------------------------------------- * * FileNameCleanup -- * *	This procedure is a Tcl_ExitProc used to clean up the static *	data structures used in this file. * * Results: *	None. * * Side effects: *	Deallocates storage used by the procedures in this file. * *---------------------------------------------------------------------- */static voidFileNameCleanup(clientData)    ClientData clientData;	/* Not used. */{    if (winRootPatternPtr != NULL) {	ckfree((char *)winRootPatternPtr);        winRootPatternPtr = (regexp *) NULL;    }    if (macRootPatternPtr != NULL) {	ckfree((char *)macRootPatternPtr);        macRootPatternPtr = (regexp *) NULL;    }    initialized = 0;}/* *---------------------------------------------------------------------- * * ExtractWinRoot -- * *	Matches the root portion of a Windows path and appends it *	to the specified Tcl_DString. *	 * Results: *	Returns the position in the path immediately after the root *	including any trailing slashes. *	Appends a cleaned up version of the root to the Tcl_DString *	at the specified offest. * * Side effects: *	Modifies the specified Tcl_DString. * *---------------------------------------------------------------------- */static char *ExtractWinRoot(path, resultPtr, offset)    char *path;			/* Path to parse. */    Tcl_DString *resultPtr;	/* Buffer to hold result. */    int offset;			/* Offset in buffer where result should be				 * stored. */{    int length;    /*     * Initialize the path name parser for Windows path names.     */    if (winRootPatternPtr == NULL) {	winRootPatternPtr = TclRegComp(WIN_ROOT_PATTERN);	if (!initialized) {	    Tcl_CreateExitHandler(FileNameCleanup, NULL);	    initialized = 1;	}    }    /*     * Match the root portion of a Windows path name.     */    if (!TclRegExec(winRootPatternPtr, path, path)) {	return path;    }    Tcl_DStringSetLength(resultPtr, offset);    if (winRootPatternPtr->startp[2] != NULL) {	Tcl_DStringAppend(resultPtr, winRootPatternPtr->startp[2], 2);	if (winRootPatternPtr->startp[6] != NULL) {	    Tcl_DStringAppend(resultPtr, "/", 1);	}    } else if (winRootPatternPtr->startp[4] != NULL) {	Tcl_DStringAppend(resultPtr, "//", 2);	length = winRootPatternPtr->endp[3]	    - winRootPatternPtr->startp[3];	Tcl_DStringAppend(resultPtr, winRootPatternPtr->startp[3], length);	Tcl_DStringAppend(resultPtr, "/", 1);	length = winRootPatternPtr->endp[4]	    - winRootPatternPtr->startp[4];	Tcl_DStringAppend(resultPtr, winRootPatternPtr->startp[4], length);    } else {	Tcl_DStringAppend(resultPtr, "/", 1);    }    return winRootPatternPtr->endp[0];}/* *---------------------------------------------------------------------- * * Tcl_GetPathType -- * *	Determines whether a given path is relative to the current *	directory, relative to the current volume, or absolute. * * Results: *	Returns one of TCL_PATH_ABSOLUTE, TCL_PATH_RELATIVE, or *	TCL_PATH_VOLUME_RELATIVE. * * Side effects: *	None. * *---------------------------------------------------------------------- */Tcl_PathTypeTcl_GetPathType(path)    char *path;{    Tcl_PathType type = TCL_PATH_ABSOLUTE;    switch (tclPlatform) {   	case TCL_PLATFORM_UNIX:	    /*	     * Paths that begin with / or ~ are absolute.	     */	    if ((path[0] != '/') && (path[0] != '~')) {		type = TCL_PATH_RELATIVE;	    }	    break;	case TCL_PLATFORM_MAC:	    if (path[0] == ':') {		type = TCL_PATH_RELATIVE;	    } else if (path[0] != '~') {		/*		 * Since we have eliminated the easy cases, use the		 * root pattern to look for the other types.		 */		if (!macRootPatternPtr) {		    macRootPatternPtr = TclRegComp(MAC_ROOT_PATTERN);		    if (!initialized) {			Tcl_CreateExitHandler(FileNameCleanup, NULL);			initialized = 1;		    }		}		if (!TclRegExec(macRootPatternPtr, path, path)			|| (macRootPatternPtr->startp[2] != NULL)) {		    type = TCL_PATH_RELATIVE;		}	    }	    break;		case TCL_PLATFORM_WINDOWS:	    if (path[0] != '~') {		/*		 * Since we have eliminated the easy cases, check for		 * drive relative paths using the regular expression.		 */		if (!winRootPatternPtr) {		    winRootPatternPtr = TclRegComp(WIN_ROOT_PATTERN);		    if (!initialized) {			Tcl_CreateExitHandler(FileNameCleanup, NULL);			initialized = 1;		    }		}		if (TclRegExec(winRootPatternPtr, path, path)) {		    if (winRootPatternPtr->startp[5]			    || (winRootPatternPtr->startp[2]				    && !(winRootPatternPtr->startp[6]))) {			type = TCL_PATH_VOLUME_RELATIVE;		    }		} else {		    type = TCL_PATH_RELATIVE;		}	    }	    break;    }    return type;}/* *---------------------------------------------------------------------- * * Tcl_SplitPath -- * *	Split a path into a list of path components.  The first element *	of the list will have the same path type as the original path. * * Results: *	Returns a standard Tcl result.  The interpreter result contains *	a list of path components. *	*argvPtr will be filled in with the address of an array *	whose elements point to the elements of path, in order. *	*argcPtr will get filled in with the number of valid elements *	in the array.  A single block of memory is dynamically allocated *	to hold both the argv array and a copy of the path elements. *	The caller must eventually free this memory by calling ckfree() *	on *argvPtr.  Note:  *argvPtr and *argcPtr are only modified *	if the procedure returns normally. * * Side effects: *	Allocates memory. * *---------------------------------------------------------------------- */voidTcl_SplitPath(path, argcPtr, argvPtr)    char *path;			/* Pointer to string containing a path. */    int *argcPtr;		/* Pointer to location to fill in with				 * the number of elements in the path. */    char ***argvPtr;		/* Pointer to place to store pointer to array				 * of pointers to path elements. */{    int i, size;    char *p;    Tcl_DString buffer;    Tcl_DStringInit(&buffer);    /*     * Perform platform specific splitting.  These routines will leave the     * result in the specified buffer.  Individual elements are terminated     * with a null character.     */    p = NULL;			/* Needed only to prevent gcc warnings. */    switch (tclPlatform) {   	case TCL_PLATFORM_UNIX:	    p = SplitUnixPath(path, &buffer);	    break;	case TCL_PLATFORM_WINDOWS:	    p = SplitWinPath(path, &buffer);	    break;	    	case TCL_PLATFORM_MAC:	    p = SplitMacPath(path, &buffer);	    break;    }    /*     * Compute the number of elements in the result.     */    size = Tcl_DStringLength(&buffer);    *argcPtr = 0;    for (i = 0; i < size; i++) {	if (p[i] == '\0') {	    (*argcPtr)++;	}    }        /*     * Allocate a buffer large enough to hold the contents of the     * DString plus the argv pointers and the terminating NULL pointer.     */    *argvPtr = (char **) ckalloc((unsigned)	    ((((*argcPtr) + 1) * sizeof(char *)) + size));    /*     * Position p after the last argv pointer and copy the contents of     * the DString.     */    p = (char *) &(*argvPtr)[(*argcPtr) + 1];    memcpy((VOID *) p, (VOID *) Tcl_DStringValue(&buffer), (size_t) size);    /*     * Now set up the argv pointers.     */    for (i = 0; i < *argcPtr; i++) {	(*argvPtr)[i] = p;	while ((*p++) != '\0') {}    }    (*argvPtr)[i] = NULL;    Tcl_DStringFree(&buffer);}/* *---------------------------------------------------------------------- * * SplitUnixPath -- * *	This routine is used by Tcl_SplitPath to handle splitting *	Unix paths. * * Results: *	Stores a null separated array of strings in the specified *	Tcl_DString. * * Side effects: *	None. * *---------------------------------------------------------------------- */static char *SplitUnixPath(path, bufPtr)    char *path;			/* Pointer to string containing a path. */    Tcl_DString *bufPtr;	/* Pointer to DString to use for the result. */{    int length;    char *p, *elementStart;    /*     * Deal with the root directory as a special case.     */    if (path[0] == '/') {	Tcl_DStringAppend(bufPtr, "/", 2);	p = path+1;    } else {	p = path;    }    /*     * Split on slashes.  Embedded elements that start with tilde will be     * prefixed with "./" so they are not affected by tilde substitution.     */    for (;;) {	elementStart = p;	while ((*p != '\0') && (*p != '/')) {	    p++;	}	length = p - elementStart;	if (length > 0) {	    if ((elementStart[0] == '~') && (elementStart != path)) {		Tcl_DStringAppend(bufPtr, "./", 2);	    }	    Tcl_DStringAppend(bufPtr, elementStart, length);	    Tcl_DStringAppend(bufPtr, "", 1);	}	if (*p++ == '\0') {	    break;	}    }    return Tcl_DStringValue(bufPtr);}/* *---------------------------------------------------------------------- * * SplitWinPath -- * *	This routine is used by Tcl_SplitPath to handle splitting *	Windows paths. * * Results: *	Stores a null separated array of strings in the specified *	Tcl_DString. * * Side effects: *	None. * *---------------------------------------------------------------------- */static char *SplitWinPath(path, bufPtr)    char *path;			/* Pointer to string containing a path. */    Tcl_DString *bufPtr;	/* Pointer to DString to use for the result. */{    int length;    char *p, *elementStart;    p = ExtractWinRoot(path, bufPtr, 0);    /*     * Terminate the root portion, if we matched something.     */    if (p != path) {	Tcl_DStringAppend(bufPtr, "", 1);    }    /*     * Split on slashes.  Embedded elements that start with tilde will be     * prefixed with "./" so they are not affected by tilde substitution.     */    do {	elementStart = p;	while ((*p != '\0') && (*p != '/') && (*p != '\\')) {	    p++;	}	length = p - elementStart;	if (length > 0) {	    if ((elementStart[0] == '~') && (elementStart != path)) {		Tcl_DStringAppend(bufPtr, "./", 2);	    }	    Tcl_DStringAppend(bufPtr, elementStart, length);	    Tcl_DStringAppend(bufPtr, "", 1);	}    } while (*p++ != '\0');    return Tcl_DStringValue(bufPtr);}/* *---------------------------------------------------------------------- * * SplitMacPath -- * *	This routine is used by Tcl_SplitPath to handle splitting *	Macintosh paths. * * Results: *	Returns a newly allocated argv array. * * Side effects: *	None. * *---------------------------------------------------------------------- */static char *SplitMacPath(path, bufPtr)    char *path;			/* Pointer to string containing a path. */    Tcl_DString *bufPtr;	/* Pointer to DString to use for the result. */{    int isMac = 0;		/* 1 if is Mac-style, 0 if Unix-style path. */    int i, length;    char *p, *elementStart;    /*     * Initialize the path name parser for Macintosh path names.     */    if (macRootPatternPtr == NULL) {	macRootPatternPtr = TclRegComp(MAC_ROOT_PATTERN);	if (!initialized) {	    Tcl_CreateExitHandler(FileNameCleanup, NULL);	    initialized = 1;	}    }    /*     * Match the root portion of a Mac path name.     */    i = 0;			/* Needed only to prevent gcc warnings. */    if (TclRegExec(macRootPatternPtr, path, path) == 1) {	/*	 * Treat degenerate absolute paths like / and /../.. as	 * Mac relative file names for lack of anything else to do.	 */	if (macRootPatternPtr->startp[2] != NULL) {	    Tcl_DStringAppend(bufPtr, ":", 1);	    Tcl_DStringAppend(bufPtr, path, macRootPatternPtr->endp[0]		    - macRootPatternPtr->startp[0] + 1);	    return Tcl_DStringValue(bufPtr);

⌨️ 快捷键说明

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