📄 fiolib.c
字号:
typedef union { __vector unsigned long vul; float f32[4]; unsigned long u32[4]; unsigned short u16[8]; unsigned char u8[16]; signed long s32[4]; signed short s16[8]; signed char s8[16]; } VECTOR;#endif /* _WRS_ALTIVEC_SUPPORT *//********************************************************************************* fioFormatV - convert a format string** 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, this routine is extremely complex and its integrity is easily* destroyed. Do not change this code without absolute understanding of all* ramifications and consequences. */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) */ unsigned long long ulongLongVal; /* unsigned 64 bit 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 */#ifdef _WRS_ALTIVEC_SUPPORT FAST int i; /* handy integer (short term usage) */ FAST char * vp; /* handy char pointer (short term usage) */ char Separator; /* separator for vector elements */ char C_Separator; /* separator for char vector elements */ VECTOR vec; /* vector argument */ BOOL doVector; /* AltiVec vector */#endif /* _WRS_ALTIVEC_SUPPORT */ char FMT[20]; /* To collect fmt info */ FAST char * Collect; /* char pointer to FMT */ BOOL doLongInt; /* long integer */ BOOL doLongLongInt; /* long long integer - 64 bit */ 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 '%' */#ifdef _WRS_ALTIVEC_SUPPORT Separator = ' '; /* the default separator for vector elements */ C_Separator = EOS; /* the default separator for char vector elements */ doVector = FALSE; /* no vector modifier */#endif /* _WRS_ALTIVEC_SUPPORT */ *FMT = EOS; Collect = FMT; doLongInt = FALSE; /* long integer */ doLongLongInt = FALSE; /* 64 bit 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;#define get_CHAR (ch = *Collect++ = *fmt++)#ifdef _WRS_ALTIVEC_SUPPORT#define SET_VECTOR_FMT(VFMT,NO) \ do \ { \ char * to; \ \ vec.vul = va_arg (vaList,__vector unsigned long); \ cp = buf; \ \ *Collect = EOS; \ i = (NO); \ to = VFMT = (char *) malloc (i*20); \ while(i-- > 0) { \ \ char * from = FMT; \ \ *to++ = '%'; \ while (*to++ = *from++); \ *(char*)((int)(to)-1) = Separator; \ } \ *(--to) = EOS; \ } \ while (0)#define RESET_VECTOR_FMT(VFMT) \ \ size = strlen(cp); \ sign = EOS; \ \ free(VFMT)#endif /* _WRS_ALTIVEC_SUPPORT */rflag: get_CHAR;reswitch: switch (ch) { case ' ': /* If the space and + flags both appear, the space * flag will be ignored. -- ANSI X3J11 */ if (!sign) sign = ' '; goto rflag;#ifdef _WRS_ALTIVEC_SUPPORT case ',': case ';': case ':': case '_': Collect--; Separator = C_Separator = ch; goto rflag;#endif /* _WRS_ALTIVEC_SUPPORT */ 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 '.': get_CHAR; if ( ch == '*' ) { n = va_arg(vaList, int); prec = (n < 0) ? -1 : n; goto rflag; } n = 0; while (is_digit(ch)) { n = 10 * n + to_digit(ch); get_CHAR; } 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); get_CHAR; } while (is_digit(ch)); width = n; goto reswitch; case 'h': doShortInt = TRUE; goto rflag; case 'l': get_CHAR; if ( ch == 'l' ) { doLongLongInt = TRUE; goto rflag; } else { doLongInt = TRUE; goto reswitch; }#ifdef _WRS_ALTIVEC_SUPPORT case 'v': Collect--; doVector = TRUE; goto rflag;#endif /* _WRS_ALTIVEC_SUPPORT */ case 'c':#ifdef _WRS_ALTIVEC_SUPPORT if (doVector) { vec.vul = va_arg (vaList,__vector unsigned long); cp = buf; vp = (unsigned char *)&vec.u8; i = 15; while(i-- > 0) { *cp++ = *vp++; if (C_Separator) *cp++ = C_Separator; } *cp++ = *vp++; cp = buf; size = 16 + (C_Separator ? 15:0); sign = EOS; } else {#endif /* _WRS_ALTIVEC_SUPPORT */ *(cp = buf) = va_arg(vaList, int); size = 1; sign = EOS;#ifdef _WRS_ALTIVEC_SUPPORT }#endif /* _WRS_ALTIVEC_SUPPORT */ break; case 'D': doLongInt = TRUE; /* FALLTHROUGH */ case 'd': case 'i':#ifdef _WRS_ALTIVEC_SUPPORT if (doVector) { SET_VECTOR_FMT(vp,doShortInt?8:4); if (doShortInt) sprintf(cp,vp,vec.s16[0],vec.s16[1],vec.s16[2],vec.s16[3], vec.s16[4],vec.s16[5],vec.s16[6],vec.s16[7]); else sprintf(cp,vp,vec.s32[0],vec.s32[1],vec.s32[2],vec.s32[3]); RESET_VECTOR_FMT(vp); break; }#endif /* _WRS_ALTIVEC_SUPPORT */ ulongLongVal = SARG(); if ((long long)ulongLongVal < 0) { ulongLongVal = -ulongLongVal; sign = '-'; } base = DEC; goto number; case 'n': /* ret is int, so effectively %lln = %ln */ if (doLongLongInt) *va_arg(vaList, long long *) = (long long) ret; else 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':#ifdef _WRS_ALTIVEC_SUPPORT if (doVector) { SET_VECTOR_FMT(vp,doShortInt?8:4); if (doShortInt) sprintf(cp,vp,vec.s16[0],vec.s16[1],vec.s16[2],vec.s16[3], vec.s16[4],vec.s16[5],vec.s16[6],vec.s16[7]); else sprintf(cp,vp,vec.s32[0],vec.s32[1],vec.s32[2],vec.s32[3]); RESET_VECTOR_FMT(vp); break; }#endif /* _WRS_ALTIVEC_SUPPORT */ ulongLongVal = 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 */#ifdef _WRS_ALTIVEC_SUPPORT if (doVector) { SET_VECTOR_FMT(vp,4);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -