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

📄 fiolib.c

📁 vxworks源码源码解读是学习vxworks的最佳途径
💻 C
📖 第 1 页 / 共 5 页
字号:
** This routine is used by the printf() family of routines to handle the* actual conversion of a format string.  The first argument is a format* string, as described in the entry for printf().  The second argument is a* variable argument list <vaList> that was previously established.** As the format string is processed, the result will be passed to the output* routine whose address is passed as the third parameter, <outRoutine>.* This output routine may output the result to a device, or put it in a* buffer.  In addition to the buffer and length to output, the fourth* argument, <outarg>, will be passed through as the third parameter to the* output routine.  This parameter could be a file descriptor, a buffer * address, or any other value that can be passed in an "int".** The output routine should be declared as follows:* .CS*     STATUS outRoutine*         (*         char *buffer, /@ buffer passed to routine            @/*         int  nchars,  /@ length of buffer                    @/*         int  outarg   /@ arbitrary arg passed to fmt routine @/*         )* .CE* The output routine should return OK if successful, or ERROR if unsuccessful.** RETURNS:* The number of characters output, or ERROR if the output routine * returned ERROR.** INTERNAL* Warning, you are about to read one of the ugliest pieces of shit in modern* programming.  It comes to us from the "ace developers" of the UCB BSD * group.  Please resist the urge to clean up this routine, its integrity* is easily destroyed.  Yes it is impossible to change, but it claims ANSI* compliance (so what are you changing?), and at the time of this writing* it appears to actually be so.  Ah the sweet mysteries of life...*/int fioFormatV    (    FAST const char *fmt, 	/* format string */    va_list	vaList,       	/* pointer to varargs list */    FUNCPTR	outRoutine,   	/* handler for args as they're formatted */    int		outarg          /* argument to routine */    )    {    FAST int	ch;		/* character from fmt */    FAST int	n;		/* handy integer (short term usage) */    FAST char *	cp;		/* handy char pointer (short term usage) */    int		width;		/* width from format (%8d), or 0 */    char	sign;		/* sign prefix (' ', '+', '-', or \0) */    ulong_t	ulongVal; 	/* integer arguments %[diouxX] */    int		prec;		/* precision from format (%.3d), or -1 */    int		oldprec;	/* old precision from format (%.3d), or -1 */    int		dprec;		/* a copy of prec if [diouxX], 0 otherwise */    int		fpprec;		/* `extra' floating precision in [eEfgG] */    int		size;		/* size of converted field or string */    int		fieldsz;	/* field size expanded by sign, etc */    int		realsz;		/* field size expanded by dprec */    BOOL	doLongInt;	/* long integer */    BOOL	doShortInt;	/* short integer */    BOOL	doAlt;		/* alternate form */    BOOL	doLAdjust;	/* left adjustment */    BOOL	doZeroPad;	/* zero (as opposed to blank) pad */    BOOL	doHexPrefix;	/* add 0x or 0X prefix */    BOOL	doSign;		/* change sign to '-' */    char	buf[BUF];	/* space for %c, %[diouxX], %[eEfgG] */#if (CPU_FAMILY != AM29XXX)    char	ox[2];		/* space for 0x hex-prefix */#else    char	ox[3];		/* space for 0x hex-prefix */#endif /*(CPU_FAMILY != AM29XXX)*/    char *	xdigs = NULL;	/* digits for [xX] conversion */    int		ret = 0;	/* return value accumulator */    enum {OCT, DEC, HEX} base;	/* base for [diouxX] conversion */    FOREVER		/* Scan the format for conversions (`%' character) */	{	for (cp = CHAR_FROM_CONST(fmt);((ch=*fmt) != EOS)&&(ch != '%'); fmt++)	    ;	if ((n = fmt - cp) != 0)	    {	    if ((*outRoutine) (cp, n, outarg) != OK)		return (ERROR);	    ret += n;	    }	if (ch == EOS)	    return (ret);		/* return total length */	fmt++;				/* skip over '%' */	doLongInt	= FALSE;	/* long integer */	doShortInt	= FALSE;	/* short integer */	doAlt		= FALSE;	/* alternate form */	doLAdjust	= FALSE;	/* left adjustment */	doZeroPad	= FALSE;	/* zero (as opposed to blank) pad */	doHexPrefix	= FALSE;	/* add 0x or 0X prefix */	doSign		= FALSE;	/* change sign to '-' */	dprec		= 0;	fpprec		= 0;	width		= 0;	prec		= -1;	oldprec		= -1;	sign		= EOS;rflag:		ch = *fmt++;reswitch:		switch (ch) 	    {	    case ' ':		    /* If the space and + flags both appear, the space		     * flag will be ignored. -- ANSI X3J11		     */		    if (!sign)			sign = ' ';		    goto rflag;	    case '#':		    doAlt = TRUE;		    goto rflag;	    case '*':		    /* A negative field width argument is taken as a		     * flag followed by a positive field width.		     *	-- ANSI X3J11		     * They don't exclude field widths read from args.		     */		    if ((width = va_arg(vaList, int)) >= 0)			goto rflag;		    width = -width;			/* FALLTHROUGH */	    case '-':		    doLAdjust = TRUE;		    goto rflag;	    case '+':		    sign = '+';		    goto rflag;	    case '.':		    if ((ch = *fmt++) == '*') 			{			n = va_arg(vaList, int);			prec = (n < 0) ? -1 : n;			goto rflag;			}		    n = 0;		    while (is_digit(ch)) 			{			n = 10 * n + to_digit(ch);			ch = *fmt++;			}		    prec = n < 0 ? -1 : n;		    goto reswitch;	    case '0':		    /* Note that 0 is taken as a flag, not as the		     * beginning of a field width. -- ANSI X3J11		     */		    doZeroPad = TRUE;		    goto rflag;	    case '1':	    case '2':	    case '3':	    case '4':	    case '5':	    case '6':	    case '7':	    case '8':	    case '9':		    n = 0;		    do 			{			n = 10 * n + to_digit(ch);			ch = *fmt++;			} while (is_digit(ch));		    width = n;		    goto reswitch;	    case 'h':		    doShortInt = TRUE;		    goto rflag;	    case 'l':		    doLongInt = TRUE;		    goto rflag;	    case 'c':		    *(cp = buf) = va_arg(vaList, int);		    size = 1;		    sign = EOS;		    break;	    case 'D':		    doLongInt = TRUE; 			/* FALLTHROUGH */	    case 'd':	    case 'i':		    ulongVal = SARG();		    if ((long)ulongVal < 0) 			{			ulongVal = -ulongVal;			sign = '-';			}		    base = DEC;		    goto number;	    case 'n':		    if (doLongInt)			*va_arg(vaList, long *) = ret;		    else if (doShortInt)			*va_arg(vaList, short *) = ret;		    else			*va_arg(vaList, int *) = ret;		    continue;				/* no output */	    case 'O':		    doLongInt = TRUE;			/* FALLTHROUGH */	    case 'o':		    ulongVal = UARG();		    base = OCT;		    goto nosign;	    case 'p':		    /* The argument shall be a pointer to void.  The		     * value of the pointer is converted to a sequence		     * of printable characters, in an implementation		     * defined manner. -- ANSI X3J11		     */		    ulongVal	= (u_long)va_arg(vaList, void *);/* NOSTRICT */		    base	= HEX;		    xdigs	= "0123456789abcdef";		    doHexPrefix = TRUE;		    ch		= 'x';		    goto nosign;	    case 's':		    if ((cp = va_arg(vaList, char *)) == NULL)			cp = "(null)";		    if (prec >= 0) 			{			/* can't use strlen; can only look for the			 * NUL in the first `prec' characters, and			 * strlen() will go further.			 */			char *p = (char *)memchr(cp, 0, prec);			if (p != NULL) 			    {			    size = p - cp;			    if (size > prec)				size = prec;			    }			else			    size = prec;			}		    else			size = strlen(cp);		    sign = EOS;		    break;	    case 'U':		    doLongInt = TRUE;			/* FALLTHROUGH */	    case 'u':		    ulongVal = UARG();		    base = DEC;		    goto nosign;	    case 'X':		    xdigs = "0123456789ABCDEF";		    goto hex;	    case 'x':		    xdigs = "0123456789abcdef";hex:		    ulongVal = UARG();		    base = HEX;		    /* leading 0x/X only if non-zero */		    if (doAlt && (ulongVal != 0))			doHexPrefix = TRUE;		    /* unsigned conversions */nosign:		    sign = EOS;		    /* ... diouXx conversions ... if a precision is		     * specified, the 0 flag will be ignored. -- ANSI X3J11		     */number:		    if ((dprec = prec) >= 0)			doZeroPad = FALSE;		    /* The result of converting a zero value with an		     * explicit precision of zero is no characters. 		     * -- ANSI X3J11		     */		    cp = buf + BUF;		    if ((ulongVal != 0) || (prec != 0)) 			{			/* unsigned mod is hard, and unsigned mod			 * by a constant is easier than that by			 * a variable; hence this switch.			 */			switch (base) 			    {			    case OCT:				do 				    {				    *--cp = to_char(ulongVal & 7);				    ulongVal >>= 3;				    } while (ulongVal);				/* handle octal leading 0 */				if (doAlt && (*cp != '0'))				    *--cp = '0';				break;			    case DEC:				/* many numbers are 1 digit */				while (ulongVal >= 10) 				    {				    *--cp = to_char(ulongVal % 10);				    ulongVal /= 10;				    }				*--cp = to_char(ulongVal);				break;			    case HEX:				do 				    {				    *--cp = xdigs[ulongVal & 15];				    ulongVal >>= 4;				    } while (ulongVal);				break;			    default:				cp = "bug in vfprintf: bad base";				size = strlen(cp);				goto skipsize;			    }			}		    size = buf + BUF - cp;skipsize:		    break;	    case 'L':		    /* NOT IMPLEMENTED */		    goto rflag;	    case 'e':	    case 'E':	    case 'f':	    case 'g':	    case 'G':		    if (fioFltFormatRtn != NULL)			{			oldprec = prec;		/* in case of strange float */			if (prec > MAXFRACT) 	/* do realistic precision */			    {			    if (((ch != 'g') && (ch != 'G')) || doAlt)				fpprec = prec - MAXFRACT;			    prec = MAXFRACT;	/* they asked for it! */			    }			else if (prec == -1)			    prec = 6;		/* ANSI default precision */

⌨️ 快捷键说明

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