From: John Hodge Date: Mon, 15 Jul 2013 02:14:38 +0000 (+0800) Subject: Usermode/libc - Changed printf to work in strings instead of chars X-Git-Tag: rel0.15~354 X-Git-Url: https://git.ucc.asn.au/?a=commitdiff_plain;h=5228a990933853fc5f5df7083ff458cdaddac371;p=tpg%2Facess2.git Usermode/libc - Changed printf to work in strings instead of chars --- diff --git a/Usermode/Libraries/libc.so_src/printf.c b/Usermode/Libraries/libc.so_src/printf.c index 1b61cba8..4d1a3d46 100644 --- a/Usermode/Libraries/libc.so_src/printf.c +++ b/Usermode/Libraries/libc.so_src/printf.c @@ -1,4 +1,4 @@ -#include /* +/* * Acess2 C Library * - By John Hodge (thePowersGang) * @@ -18,7 +18,7 @@ typedef char BOOL; #define FALSE 0 // === TYPES === -typedef void (*printf_putch_t)(void *h, char ch); +typedef void (*printf_puts_t)(void *h, const char *s, size_t len); enum eFPN { FPN_STD, FPN_SCI, @@ -27,12 +27,12 @@ enum eFPN { // === PROTOTYPES === void itoa(char *buf, uint64_t num, size_t base, int minLength, char pad, int bSigned); -size_t _printf_itoa(printf_putch_t putch_cb, void *putch_h, uint64_t num, +size_t _printf_itoa(printf_puts_t puts_cb, void *puts_h, uint64_t num, size_t base, int bUpper, int bSigned, char SignChar, int Precision, int PadLength, char PadChar, int bPadRight); -size_t _printf_ftoa_hex(printf_putch_t putch_cb, void *putch_h, long double num, int Precision, int bForcePoint, int bForceSign, int bCapitals); -size_t _printf_ftoa(printf_putch_t putch_cb, void *putch_h, long double num, size_t Base, enum eFPN Notation, int Precision, int bForcePoint, int bForceSign, int bCapitals); +size_t _printf_ftoa_hex(printf_puts_t puts_cb, void *puts_h, long double num, int Precision, int bForcePoint, int bForceSign, int bCapitals); +size_t _printf_ftoa(printf_puts_t puts_cb, void *puts_h, long double num, size_t Base, enum eFPN Notation, int Precision, int bForcePoint, int bForceSign, int bCapitals); // === CODE === /** @@ -42,7 +42,7 @@ size_t _printf_ftoa(printf_putch_t putch_cb, void *putch_h, long double num, siz * \param format String - Format String * \param args VarArgs List - Arguments */ -EXPORT int _vcprintf_int(printf_putch_t putch_cb, void *putch_h, const char *format, va_list args) +EXPORT int _vcprintf_int(printf_puts_t puts_cb, void *puts_h, const char *format, va_list args) { char tmp[65]; int c, minSize, precision, len; @@ -55,7 +55,8 @@ EXPORT int _vcprintf_int(printf_putch_t putch_cb, void *putch_h, const char *for char cNumPad, cPlus; #define _addchar(ch) do { \ - putch_cb(putch_h, ch); \ + char _ch = ch; \ + puts_cb(puts_h, &_ch, 1); \ pos ++; \ } while(0) @@ -65,7 +66,11 @@ EXPORT int _vcprintf_int(printf_putch_t putch_cb, void *putch_h, const char *for { // Non-control character if (c != '%') { - _addchar(c); + const char *start = format-1; + while( (c = *format) != 0 && c != '%' ) + format ++; + puts_cb(puts_h, start, format - start); + pos += format - start; continue; } @@ -173,14 +178,14 @@ EXPORT int _vcprintf_int(printf_putch_t putch_cb, void *putch_h, const char *for arg = bLongLong ? va_arg(args, int64_t) : va_arg(args, int32_t); if( arg == 0 && precision == 0 ) break; - pos += _printf_itoa(putch_cb, putch_h, arg, 10, FALSE, + pos += _printf_itoa(puts_cb, puts_h, arg, 10, FALSE, TRUE, cPlus, precision, minSize, cNumPad, bJustifyLeft); break; // Unsigned Integer case 'u': arg = bLongLong ? va_arg(args, int64_t) : va_arg(args, int32_t); - pos += _printf_itoa(putch_cb, putch_h, arg, 10, FALSE, + pos += _printf_itoa(puts_cb, puts_h, arg, 10, FALSE, FALSE, '\0', precision, minSize, cNumPad, bJustifyLeft); break; @@ -190,7 +195,7 @@ EXPORT int _vcprintf_int(printf_putch_t putch_cb, void *putch_h, const char *for _addchar('0'); _addchar('x'); arg = va_arg(args, intptr_t); - pos += _printf_itoa(putch_cb, putch_h, arg, 16, FALSE, + pos += _printf_itoa(puts_cb, puts_h, arg, 16, FALSE, FALSE, '\0', sizeof(intptr_t)*2, 0,'\0',FALSE); break; // Unsigned Hexadecimal @@ -201,7 +206,7 @@ EXPORT int _vcprintf_int(printf_putch_t putch_cb, void *putch_h, const char *for _addchar(c); } arg = bLongLong ? va_arg(args, uint64_t) : va_arg(args, uint32_t); - pos += _printf_itoa(putch_cb, putch_h, arg, 16, c=='X', + pos += _printf_itoa(puts_cb, puts_h, arg, 16, c=='X', FALSE, '\0', precision, minSize,cNumPad,bJustifyLeft); break; @@ -211,7 +216,7 @@ EXPORT int _vcprintf_int(printf_putch_t putch_cb, void *putch_h, const char *for _addchar('0'); } arg = bLongLong ? va_arg(args, int64_t) : va_arg(args, int32_t); - pos += _printf_itoa(putch_cb, putch_h, arg, 8, FALSE, + pos += _printf_itoa(puts_cb, puts_h, arg, 8, FALSE, FALSE, '\0', precision, minSize,cNumPad,bJustifyLeft); break; @@ -222,7 +227,7 @@ EXPORT int _vcprintf_int(printf_putch_t putch_cb, void *putch_h, const char *for _addchar('b'); } arg = bLongLong ? va_arg(args, int64_t) : va_arg(args, int32_t); - pos += _printf_itoa(putch_cb, putch_h, arg, 2, FALSE, + pos += _printf_itoa(puts_cb, puts_h, arg, 2, FALSE, FALSE, '\0', precision, minSize,cNumPad,bJustifyLeft); break; @@ -230,28 +235,28 @@ EXPORT int _vcprintf_int(printf_putch_t putch_cb, void *putch_h, const char *for case 'f': case 'F': arg_f = bLong ? va_arg(args, long double) : va_arg(args, double); - pos += _printf_ftoa(putch_cb, putch_h, arg_f, 10, FPN_STD, + pos += _printf_ftoa(puts_cb, puts_h, arg_f, 10, FPN_STD, precision, 0, bJustifyLeft, c == 'F'); break; // Scientific Float case 'e': case 'E': arg_f = bLong ? va_arg(args, long double) : va_arg(args, double); - pos += _printf_ftoa(putch_cb, putch_h, arg_f, 10, FPN_SCI, + pos += _printf_ftoa(puts_cb, puts_h, arg_f, 10, FPN_SCI, precision, 0, bJustifyLeft, c == 'E'); break; // Scientific Float case 'g': case 'G': arg_f = bLong ? va_arg(args, long double) : va_arg(args, double); - pos += _printf_ftoa(putch_cb, putch_h, arg_f, 10, FPN_SHORTEST, + pos += _printf_ftoa(puts_cb, puts_h, arg_f, 10, FPN_SHORTEST, precision, 0, bJustifyLeft, c == 'G'); break; // Hexadecimal Scientific case 'a': case 'A': arg_f = bLong ? va_arg(args, long double) : va_arg(args, double); - pos += _printf_ftoa_hex(putch_cb, putch_h, arg_f, precision, 0, bJustifyLeft, c == 'A'); + pos += _printf_ftoa_hex(puts_cb, puts_h, arg_f, precision, 0, bJustifyLeft, c == 'A'); break; // String @@ -264,14 +269,10 @@ EXPORT int _vcprintf_int(printf_putch_t putch_cb, void *putch_h, const char *for else len = strlen(p); if(!bJustifyLeft) - while(minSize > len++) _addchar(' '); - while( *p ) { - if(precision >= 0 && precision -- == 0) - break; - _addchar(*p++); - } + while(minSize-- > len) _addchar(' '); + puts_cb(puts_h, p, len); pos += len; if(bJustifyLeft) - while(minSize > len++) _addchar(' '); + while(minSize-- > len) _addchar(' '); break; // Unknown, just treat it as a character @@ -292,19 +293,19 @@ struct s_sprintf_info { size_t maxlen; }; -void _vsnprintf_putch(void *h, char ch) +void _vsnprintf_puts(void *h, const char *str, size_t len) { struct s_sprintf_info *info = h; - if(info->ofs < info->maxlen) - info->dest[info->ofs++] = ch; + while( info->ofs < info->maxlen && len -- ) + info->dest[info->ofs++] = *str++; } EXPORT int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list __args) { struct s_sprintf_info info = {__s, 0, __maxlen}; int ret; - ret = _vcprintf_int(_vsnprintf_putch, &info, __format, __args); - _vsnprintf_putch(&info, '\0'); + ret = _vcprintf_int(_vsnprintf_puts, &info, __format, __args); + _vsnprintf_puts(&info, "", 1); return ret; } @@ -333,14 +334,14 @@ EXPORT int sprintf(char *buf, const char *format, ...) return ret; } -void _vfprintf_putch(void *h, char ch) +void _vfprintf_puts(void *h, const char *str, size_t len) { - fputc(ch, h); + fwrite(str, len, 1, h); } EXPORT int vfprintf(FILE *__fp, const char *__format, va_list __args) { - return _vcprintf_int(_vfprintf_putch, __fp, __format, __args); + return _vcprintf_int(_vfprintf_puts, __fp, __format, __args); } EXPORT int fprintf(FILE *fp, const char *format, ...) @@ -379,7 +380,7 @@ void itoa(char *buf, uint64_t num, size_t base, int minLength, char pad, int bSi { struct s_sprintf_info info = {buf, 0, 1024}; if(!buf) return; - _printf_itoa(_vsnprintf_putch, &info, num, base, FALSE, bSigned, '\0', 0, minLength, pad, FALSE); + _printf_itoa(_vsnprintf_puts, &info, num, base, FALSE, bSigned, '\0', 0, minLength, pad, FALSE); buf[info.ofs] = '\0'; } @@ -394,13 +395,13 @@ const char cUDIGITS[] = "0123456789ABCDEF"; * \param pad Padding used to ensure minLength * \param bSigned Signed number output? */ -size_t _printf_itoa(printf_putch_t putch_cb, void *putch_h, uint64_t num, +size_t _printf_itoa(printf_puts_t puts_cb, void *puts_h, uint64_t num, size_t base, int bUpper, int bSigned, char SignChar, int Precision, int PadLength, char PadChar, int bPadRight) { - char tmpBuf[64]; - int pos = 0; + char tmpBuf[64+1]; + int pos = sizeof(tmpBuf); size_t ret = 0; int sign_is_neg = 0; const char *map = bUpper ? cUDIGITS : cDIGITS; @@ -415,39 +416,42 @@ size_t _printf_itoa(printf_putch_t putch_cb, void *putch_h, uint64_t num, sign_is_neg = 1; } - // Encode into reversed string + // Encode into string while(num > base-1) { - tmpBuf[pos++] = map[ num % base ]; + tmpBuf[--pos] = map[ num % base ]; num = (uint64_t) num / (uint64_t)base; // Shift {number} right 1 digit } + tmpBuf[--pos] = map[ num % base ]; // Most significant digit of {number} - tmpBuf[pos++] = map[ num % base ]; // Last digit of {number} + // Sign + if(sign_is_neg) + tmpBuf[--pos] = '-'; // Negative sign character + else if(SignChar) + tmpBuf[--pos] = SignChar; // positive sign character + else { + } // length of number, minus the sign character - PadLength -= pos + (sign_is_neg || SignChar != '\0'); - Precision -= pos + (sign_is_neg || SignChar != '\0'); + size_t len = sizeof(tmpBuf)-pos; + PadLength -= len; + Precision -= len; if( !bPadRight ) { while(PadLength-- > 0) - putch_cb(putch_h, PadChar), ret ++; - } - - if(sign_is_neg) - putch_cb(putch_h, '-'), ret++; // Negative sign character - else if(SignChar) - putch_cb(putch_h, SignChar), ret++; // positive sign character - else { + puts_cb(puts_h, &PadChar, 1), ret ++; } - + + // TODO: Will {Precision} ever be > size while( Precision-- > 0 ) - putch_cb(putch_h, '0'), ret++; - while(pos--) - putch_cb(putch_h, tmpBuf[pos]), ret++; // Reverse the order of characters + puts_cb(puts_h, "0", 1), ret++; + + puts_cb(puts_h, tmpBuf+pos, len); + ret += len; if( bPadRight ) { while(PadLength-- > 0) - putch_cb(putch_h, PadChar), ret ++; + puts_cb(puts_h, &PadChar, 1), ret ++; } return ret; @@ -507,7 +511,7 @@ double _longdiv(double num, double den, int *quot) return num; } -size_t _printf_ftoa_hex(printf_putch_t putch_cb, void *putch_h, long double num, int Precision, int bForcePoint, int bForceSign, int bCapitals) +size_t _printf_ftoa_hex(printf_puts_t puts_cb, void *puts_h, long double num, int Precision, int bForcePoint, int bForceSign, int bCapitals) { uint64_t significand; int16_t exponent; @@ -516,10 +520,8 @@ size_t _printf_ftoa_hex(printf_putch_t putch_cb, void *putch_h, long double num, size_t ret = 0; #define _putch(_ch) do{\ - if(bCapitals)\ - putch_cb(putch_h, toupper(_ch));\ - else\ - putch_cb(putch_h, _ch);\ + char __ch = (bCapitals ? toupper(_ch) : _ch);\ + puts_cb(puts_h, &__ch, 1); \ ret ++;\ }while(0) @@ -538,14 +540,10 @@ size_t _printf_ftoa_hex(printf_putch_t putch_cb, void *putch_h, long double num, break; // 2: Infinity case 2: - _putch('i'); - _putch('n'); - _putch('f'); + puts_cb(puts_h, "inf", 3); return 3; case 3: - _putch('N'); - _putch('a'); - _putch('N'); + puts_cb(puts_h, "NaN", 3); return 3; } @@ -574,8 +572,8 @@ size_t _printf_ftoa_hex(printf_putch_t putch_cb, void *putch_h, long double num, significand <<= 4; } _putch('p'); - //ret += _printf_itoa(putch_cb, putch_h, exp_16, 16, bCapitals, TRUE, '+', 0, 0, '\0', 0); - ret += _printf_itoa(putch_cb, putch_h, exponent, 10, bCapitals, TRUE, '+', 0, 0, '\0', 0); + //ret += _printf_itoa(puts_cb, puts_h, exp_16, 16, bCapitals, TRUE, '+', 0, 0, '\0', 0); + ret += _printf_itoa(puts_cb, puts_h, exponent, 10, bCapitals, TRUE, '+', 0, 0, '\0', 0); #undef _putch return ret; @@ -680,7 +678,7 @@ size_t _printf_ftoa_dec(printf_putch_t putch_cb, void *putch_h, long double num, } #endif -size_t _printf_ftoa(printf_putch_t putch_cb, void *putch_h, long double num, size_t Base, enum eFPN Notation, int Precision, int bForcePoint, int bForceSign, int bCapitals) +size_t _printf_ftoa(printf_puts_t puts_cb, void *puts_h, long double num, size_t Base, enum eFPN Notation, int Precision, int bForcePoint, int bForceSign, int bCapitals) { uint64_t significand; int16_t exponent; @@ -689,10 +687,8 @@ size_t _printf_ftoa(printf_putch_t putch_cb, void *putch_h, long double num, siz size_t ret = 0; #define _putch(_ch) do{\ - if(bCapitals)\ - putch_cb(putch_h, toupper(_ch));\ - else\ - putch_cb(putch_h, _ch);\ + char __ch = (bCapitals ? toupper(_ch) : _ch);\ + puts_cb(puts_h, &__ch, 1); \ ret ++;\ }while(0) @@ -828,7 +824,7 @@ size_t _printf_ftoa(printf_putch_t putch_cb, void *putch_h, long double num, siz _putch('p'); else _putch('e'); - ret += _printf_itoa(putch_cb, putch_h, sci_exponent, Base, FALSE, TRUE, '+', 3, 0, '\0', FALSE); + ret += _printf_itoa(puts_cb, puts_h, sci_exponent, Base, FALSE, TRUE, '+', 3, 0, '\0', FALSE); } #undef _putch