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

📄 tclutil.c

📁 linux系统下的音频通信
💻 C
📖 第 1 页 / 共 5 页
字号:
/*  * tclUtil.c -- * *	This file contains utility procedures that are used by many Tcl *	commands. * * Copyright (c) 1987-1993 The Regents of the University of California. * Copyright (c) 1994-1997 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: @(#) tclUtil.c 1.2 98/06/12 16:49:08 */#include "tclInt.h"#include "tclPort.h"/* * The following variable holds the full path name of the binary * from which this application was executed, or NULL if it isn't * know.  The value of the variable is set by the procedure * Tcl_FindExecutable.  The storage space is dynamically allocated. */ char *tclExecutableName = NULL;/* * The following values are used in the flags returned by Tcl_ScanElement * and used by Tcl_ConvertElement.  The value TCL_DONT_USE_BRACES is also * defined in tcl.h;  make sure its value doesn't overlap with any of the * values below. * * TCL_DONT_USE_BRACES -	1 means the string mustn't be enclosed in *				braces (e.g. it contains unmatched braces, *				or ends in a backslash character, or user *				just doesn't want braces);  handle all *				special characters by adding backslashes. * USE_BRACES -			1 means the string contains a special *				character that can be handled simply by *				enclosing the entire argument in braces. * BRACES_UNMATCHED -		1 means that braces aren't properly matched *				in the argument. */#define USE_BRACES		2#define BRACES_UNMATCHED	4/* * The following values determine the precision used when converting * floating-point values to strings.  This information is linked to all * of the tcl_precision variables in all interpreters via the procedure * TclPrecTraceProc. * * NOTE: these variables are not thread-safe. */static char precisionString[10] = "12";				/* The string value of all the tcl_precision				 * variables. */static char precisionFormat[10] = "%.12g";				/* The format string actually used in calls				 * to sprintf. *//* * Function prototypes for local procedures in this file: */static void		SetupAppendBuffer _ANSI_ARGS_((Interp *iPtr,			    int newSpace));/* *---------------------------------------------------------------------- * * TclFindElement -- * *	Given a pointer into a Tcl list, locate the first (or next) *	element in the list. * * Results: *	The return value is normally TCL_OK, which means that the *	element was successfully located.  If TCL_ERROR is returned *	it means that list didn't have proper list structure; *	interp->result contains a more detailed error message. * *	If TCL_OK is returned, then *elementPtr will be set to point to the *	first element of list, and *nextPtr will be set to point to the *	character just after any white space following the last character *	that's part of the element. If this is the last argument in the *	list, then *nextPtr will point just after the last character in the *	list (i.e., at the character at list+listLength). If sizePtr is *	non-NULL, *sizePtr is filled in with the number of characters in the *	element.  If the element is in braces, then *elementPtr will point *	to the character after the opening brace and *sizePtr will not *	include either of the braces. If there isn't an element in the list, *	*sizePtr will be zero, and both *elementPtr and *termPtr will point *	just after the last character in the list. Note: this procedure does *	NOT collapse backslash sequences. * * Side effects: *	None. * *---------------------------------------------------------------------- */intTclFindElement(interp, list, listLength, elementPtr, nextPtr, sizePtr,	       bracePtr)    Tcl_Interp *interp;		/* Interpreter to use for error reporting. 				 * If NULL, then no error message is left				 * after errors. */    char *list;			/* Points to the first byte of a string				 * containing a Tcl list with zero or more				 * elements (possibly in braces). */    int listLength;		/* Number of bytes in the list's string. */    char **elementPtr;		/* Where to put address of first significant				 * character in first element of list. */    char **nextPtr;		/* Fill in with location of character just				 * after all white space following end of				 * argument (next arg or end of list). */    int *sizePtr;		/* If non-zero, fill in with size of				 * element. */    int *bracePtr;		/* If non-zero, fill in with non-zero/zero				 * to indicate that arg was/wasn't				 * in braces. */{    char *p = list;    char *elemStart;		/* Points to first byte of first element. */    char *limit;		/* Points just after list's last byte. */    int openBraces = 0;		/* Brace nesting level during parse. */    int inQuotes = 0;    int size = 0;		/* Init. avoids compiler warning. */    int numChars;    char *p2;        /*     * Skim off leading white space and check for an opening brace or     * quote. We treat embedded NULLs in the list as bytes belonging to     * a list element. Note: use of "isascii" below and elsewhere in this     * procedure is a temporary hack (7/27/90) because Mx uses characters     * with the high-order bit set for some things. This should probably     * be changed back eventually, or all of Tcl should call isascii.     */    limit = (list + listLength);    while ((p < limit) && (isspace(UCHAR(*p)))) {	p++;    }    if (p == limit) {		/* no element found */	elemStart = limit;	goto done;    }    if (*p == '{') {	openBraces = 1;	p++;    } else if (*p == '"') {	inQuotes = 1;	p++;    }    elemStart = p;    if (bracePtr != 0) {	*bracePtr = openBraces;    }    /*     * Find element's end (a space, close brace, or the end of the string).     */    while (p < limit) {	switch (*p) {	    /*	     * Open brace: don't treat specially unless the element is in	     * braces. In this case, keep a nesting count.	     */	    case '{':		if (openBraces != 0) {		    openBraces++;		}		break;	    /*	     * Close brace: if element is in braces, keep nesting count and	     * quit when the last close brace is seen.	     */	    case '}':		if (openBraces > 1) {		    openBraces--;		} else if (openBraces == 1) {		    size = (p - elemStart);		    p++;		    if ((p >= limit) || isspace(UCHAR(*p))) {			goto done;		    }		    /*		     * Garbage after the closing brace; return an error.		     */		    		    if (interp != NULL) {			char buf[100];						p2 = p;			while ((p2 < limit) && (!isspace(UCHAR(*p2)))			        && (p2 < p+20)) {			    p2++;			}			sprintf(buf,				"list element in braces followed by \"%.*s\" instead of space",				(int) (p2-p), p);			Tcl_SetResult(interp, buf, TCL_VOLATILE);		    }		    return TCL_ERROR;		}		break;	    /*	     * Backslash:  skip over everything up to the end of the	     * backslash sequence.	     */	    case '\\': {		(void) Tcl_Backslash(p, &numChars);		p += (numChars - 1);		break;	    }	    /*	     * Space: ignore if element is in braces or quotes; otherwise	     * terminate element.	     */	    case ' ':	    case '\f':	    case '\n':	    case '\r':	    case '\t':	    case '\v':		if ((openBraces == 0) && !inQuotes) {		    size = (p - elemStart);		    goto done;		}		break;	    /*	     * Double-quote: if element is in quotes then terminate it.	     */	    case '"':		if (inQuotes) {		    size = (p - elemStart);		    p++;		    if ((p >= limit) || isspace(UCHAR(*p))) {			goto done;		    }		    /*		     * Garbage after the closing quote; return an error.		     */		    		    if (interp != NULL) {			char buf[100];						p2 = p;			while ((p2 < limit) && (!isspace(UCHAR(*p2)))				 && (p2 < p+20)) {			    p2++;			}			sprintf(buf,				"list element in quotes followed by \"%.*s\" %s",				(int) (p2-p), p, "instead of space");			Tcl_SetResult(interp, buf, TCL_VOLATILE);		    }		    return TCL_ERROR;		}		break;	}	p++;    }    /*     * End of list: terminate element.     */    if (p == limit) {	if (openBraces != 0) {	    if (interp != NULL) {		Tcl_SetResult(interp, "unmatched open brace in list",			TCL_STATIC);	    }	    return TCL_ERROR;	} else if (inQuotes) {	    if (interp != NULL) {		Tcl_SetResult(interp, "unmatched open quote in list",			TCL_STATIC);	    }	    return TCL_ERROR;	}	size = (p - elemStart);    }    done:    while ((p < limit) && (isspace(UCHAR(*p)))) {	p++;    }    *elementPtr = elemStart;    *nextPtr = p;    if (sizePtr != 0) {	*sizePtr = size;    }    return TCL_OK;}/* *---------------------------------------------------------------------- * * TclCopyAndCollapse -- * *	Copy a string and eliminate any backslashes that aren't in braces. * * Results: *	There is no return value. Count characters get copied from src to *	dst. Along the way, if backslash sequences are found outside braces, *	the backslashes are eliminated in the copy. After scanning count *	chars from source, a null character is placed at the end of dst. *	Returns the number of characters that got copied. * * Side effects: *	None. * *---------------------------------------------------------------------- */intTclCopyAndCollapse(count, src, dst)    int count;			/* Number of characters to copy from src. */    char *src;			/* Copy from here... */    char *dst;			/* ... to here. */{    char c;    int numRead;    int newCount = 0;    for (c = *src;  count > 0;  src++, c = *src, count--) {	if (c == '\\') {	    *dst = Tcl_Backslash(src, &numRead);	    dst++;	    src += numRead-1;	    count -= numRead-1;	    newCount++;	} else {	    *dst = c;	    dst++;	    newCount++;	}    }    *dst = 0;    return newCount;}/* *---------------------------------------------------------------------- * * Tcl_SplitList -- * *	Splits a list up into its constituent fields. * * Results *	The return value is normally TCL_OK, which means that *	the list was successfully split up.  If TCL_ERROR is *	returned, it means that "list" didn't have proper list *	structure;  interp->result will contain a more detailed *	error message. * *	*argvPtr will be filled in with the address of an array *	whose elements point to the elements of list, 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 list (with *	backslashes and braces removed in the standard way). *	The caller must eventually free this memory by calling free() *	on *argvPtr.  Note:  *argvPtr and *argcPtr are only modified *	if the procedure returns normally. * * Side effects: *	Memory is allocated. * *---------------------------------------------------------------------- */intTcl_SplitList(interp, list, argcPtr, argvPtr)    Tcl_Interp *interp;		/* Interpreter to use for error reporting. 				 * If NULL, no error message is left. */    char *list;			/* Pointer to string with list structure. */    int *argcPtr;		/* Pointer to location to fill in with				 * the number of elements in the list. */    char ***argvPtr;		/* Pointer to place to store pointer to				 * array of pointers to list elements. */{    char **argv;    char *p;    int length, size, i, result, elSize, brace;    char *element;    /*     * Figure out how much space to allocate.  There must be enough     * space for both the array of pointers and also for a copy of     * the list.  To estimate the number of pointers needed, count     * the number of space characters in the list.     */    for (size = 1, p = list; *p != 0; p++) {	if (isspace(UCHAR(*p))) {	    size++;	}    }    size++;			/* Leave space for final NULL pointer. */    argv = (char **) ckalloc((unsigned)	    ((size * sizeof(char *)) + (p - list) + 1));    length = strlen(list);    for (i = 0, p = ((char *) argv) + size*sizeof(char *);	    *list != 0;  i++) {	char *prevList = list;		result = TclFindElement(interp, list, length, &element,				&list, &elSize, &brace);	length -= (list - prevList);	if (result != TCL_OK) {	    ckfree((char *) argv);	    return result;	}	if (*element == 0) {	    break;	}	if (i >= size) {	    ckfree((char *) argv);	    if (interp != NULL) {		Tcl_SetResult(interp, "internal error in Tcl_SplitList",			TCL_STATIC);	    }	    return TCL_ERROR;	}	argv[i] = p;	if (brace) {	    memcpy((VOID *) p, (VOID *) element, (size_t) elSize);	    p += elSize;	    *p = 0;	    p++;	} else {	    TclCopyAndCollapse(elSize, element, p);	    p += elSize+1;	}    }    argv[i] = NULL;    *argvPtr = argv;    *argcPtr = i;    return TCL_OK;}/* *---------------------------------------------------------------------- * * Tcl_ScanElement -- * *	This procedure is a companion procedure to Tcl_ConvertElement. *	It scans a string to see what needs to be done to it (e.g. add *	backslashes or enclosing braces) to make the string into a *	valid Tcl list element. * * Results: *	The return value is an overestimate of the number of characters *	that will be needed by Tcl_ConvertElement to produce a valid *	list element from string.  The word at *flagPtr is filled in *	with a value needed by Tcl_ConvertElement when doing the actual *	conversion. * * Side effects: *	None. * *---------------------------------------------------------------------- */

⌨️ 快捷键说明

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