diff --git a/reactos/lib/ntdll/makefile b/reactos/lib/ntdll/makefile index aa9ef6cbc47..30372338875 100644 --- a/reactos/lib/ntdll/makefile +++ b/reactos/lib/ntdll/makefile @@ -1,4 +1,4 @@ -# $Id: makefile,v 1.34 2000/01/10 20:34:41 ekohl Exp $ +# $Id: makefile,v 1.35 2000/01/14 02:22:17 ekohl Exp $ # # ReactOS Operating System # @@ -31,7 +31,7 @@ RTL_OBJECTS = rtl/critical.o rtl/error.o rtl/heap.o rtl/largeint.o \ rtl/math.o rtl/mem.o rtl/nls.o rtl/process.o rtl/security.o \ rtl/thread.o rtl/unicode.o rtl/env.o -STDIO_OBJECTS = stdio/swprintf.o stdio/vsprintf.o +STDIO_OBJECTS = stdio/sprintf.o stdio/swprintf.o STDLIB_OBJECTS = stdlib/abs.o stdlib/atoi.o stdlib/atoi64.o stdlib/atol.o \ stdlib/itoa.o stdlib/itow.o stdlib/labs.o stdlib/splitp.o \ diff --git a/reactos/lib/ntdll/stdio/vsprintf.c b/reactos/lib/ntdll/stdio/sprintf.c similarity index 64% rename from reactos/lib/ntdll/stdio/vsprintf.c rename to reactos/lib/ntdll/stdio/sprintf.c index 1faac842cb6..591f91d6ef5 100644 --- a/reactos/lib/ntdll/stdio/vsprintf.c +++ b/reactos/lib/ntdll/stdio/sprintf.c @@ -1,16 +1,14 @@ -/* $Id: vsprintf.c,v 1.6 2000/01/11 17:29:17 ekohl Exp $ +/* $Id: sprintf.c,v 1.1 2000/01/14 02:22:02 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel - * FILE: lib/ntdll/stdio/vsprintf.c - * PURPOSE: Single byte printf functions + * FILE: lib/ntdll/stdio/sprintf.c + * PURPOSE: Single byte sprintf functions * PROGRAMMERS: David Welch * Eric Kohl * * TODO: * - Implement maximum length (cnt) in _vsnprintf(). - * - Add MS specific types 'C', 'S', 'Z'... - * - Add MS specific qualifier 'I64'. */ /* @@ -32,20 +30,6 @@ #include -extern size_t strnlen(const char* string, size_t maxlen); - - -/* we use this so that we can do without the ctype library */ -#define is_digit(c) ((c) >= '0' && (c) <= '9') - -static int skip_atoi(const char **s) -{ - int i=0; - - while (is_digit(**s)) - i = i*10 + *((*s)++) - '0'; - return i; -} #define ZEROPAD 1 /* pad with zero */ #define SIGN 2 /* unsigned/signed long */ @@ -55,14 +39,26 @@ static int skip_atoi(const char **s) #define SPECIAL 32 /* 0x */ #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ + #define do_div(n,base) ({ \ int __res; \ -__res = ((unsigned long) n) % (unsigned) base; \ -n = ((unsigned long) n) / (unsigned) base; \ +__res = ((unsigned long long) n) % (unsigned) base; \ +n = ((unsigned long long) n) / (unsigned) base; \ __res; }) + +static int skip_atoi(const char **s) +{ + int i=0; + + while (isdigit(**s)) + i = i*10 + *((*s)++) - '0'; + return i; +} + + static char * -number (char * str, long num, int base, int size, int precision, int type) +number (char * str, long long num, int base, int size, int precision, int type) { char c,sign,tmp[66]; const char *digits="0123456789abcdefghijklmnopqrstuvwxyz"; @@ -132,21 +128,22 @@ number (char * str, long num, int base, int size, int precision, int type) return str; } + int _vsnprintf(char *buf, size_t cnt, const char *fmt, va_list args) { int len; - unsigned long num; + unsigned long long num; int i, base; char * str; const char *s; - const short int* sw; + const wchar_t *sw; int flags; /* flags to number() */ int field_width; /* width of output field */ int precision; /* min. # of digits for integers; max number of chars for from string */ - int qualifier; /* 'h', 'l', or 'L' for integer fields */ + int qualifier; /* 'h', 'l', 'L', 'I' or 'w' for integer fields */ for (str=buf ; *fmt ; ++fmt) { if (*fmt != '%') { @@ -168,7 +165,7 @@ int _vsnprintf(char *buf, size_t cnt, const char *fmt, va_list args) /* get field width */ field_width = -1; - if (is_digit(*fmt)) + if (isdigit(*fmt)) field_width = skip_atoi(&fmt); else if (*fmt == '*') { ++fmt; @@ -184,7 +181,7 @@ int _vsnprintf(char *buf, size_t cnt, const char *fmt, va_list args) precision = -1; if (*fmt == '.') { ++fmt; - if (is_digit(*fmt)) + if (isdigit(*fmt)) precision = skip_atoi(&fmt); else if (*fmt == '*') { ++fmt; @@ -197,21 +194,23 @@ int _vsnprintf(char *buf, size_t cnt, const char *fmt, va_list args) /* get the conversion qualifier */ qualifier = -1; - if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' /*|| *fmt == 'w'*/ || - (*fmt == 'I' && *(fmt+1) == '6' && *(fmt+2) == '4')) { + if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt == 'w') { qualifier = *fmt; ++fmt; + } else if (*fmt == 'I' && *(fmt+1) == '6' && *(fmt+2) == '4') { + qualifier = *fmt; + fmt += 3; } /* default base */ base = 10; switch (*fmt) { - case 'c': + case 'c': /* finished */ if (!(flags & LEFT)) while (--field_width > 0) *str++ = ' '; - if (qualifier == 'l' /*|| qualifier == 'w'*/) + if (qualifier == 'l' || qualifier == 'w') *str++ = (unsigned char) va_arg(args, wchar_t); else *str++ = (unsigned char) va_arg(args, int); @@ -219,7 +218,7 @@ int _vsnprintf(char *buf, size_t cnt, const char *fmt, va_list args) *str++ = ' '; continue; - case 'C': + case 'C': /* finished */ if (!(flags & LEFT)) while (--field_width > 0) *str++ = ' '; @@ -231,57 +230,108 @@ int _vsnprintf(char *buf, size_t cnt, const char *fmt, va_list args) *str++ = ' '; continue; - case 'w': - sw = va_arg(args,short int *); -// DPRINT("L %x\n",sw); - if (sw==NULL) { -// CHECKPOINT; - s = ""; - while ((*s)!=0) - *str++ = *s++; -// CHECKPOINT; -// DbgPrint("str %x\n",str); - } else { - while ((*sw)!=0) - *str++ = (char)(*sw++); - } -// CHECKPOINT; - continue; + case 's': /* finished */ + if (qualifier == 'l' || qualifier == 'w') { + /* print unicode string */ + sw = va_arg(args, wchar_t *); + if (sw == NULL) + sw = L""; - case 's': - s = va_arg(args, char *); - if (!s) - s = ""; + len = wcslen (sw); + if ((unsigned int)len > (unsigned int)precision) + len = precision; - len = strnlen(s, precision); - - if (!(flags & LEFT)) + if (!(flags & LEFT)) + while (len < field_width--) + *str++ = ' '; + for (i = 0; i < len; ++i) + *str++ = (unsigned char)(*sw++); while (len < field_width--) *str++ = ' '; - for (i = 0; i < len; ++i) - *str++ = *s++; - while (len < field_width--) - *str++ = ' '; + } else { + /* print ascii string */ + s = va_arg(args, char *); + if (s == NULL) + s = ""; + + len = strlen (s); + if ((unsigned int)len > (unsigned int)precision) + len = precision; + + if (!(flags & LEFT)) + while (len < field_width--) + *str++ = ' '; + for (i = 0; i < len; ++i) + *str++ = *s++; + while (len < field_width--) + *str++ = ' '; + } continue; case 'S': - sw = va_arg(args,short int *); - if (sw==NULL) { - s = ""; - while ((*s)!=0) + if (qualifier == 'h') { + /* print ascii string */ + s = va_arg(args, char *); + if (s == NULL) + s = ""; + + len = strlen (s); + if ((unsigned int)len > (unsigned int)precision) + len = precision; + + if (!(flags & LEFT)) + while (len < field_width--) + *str++ = ' '; + for (i = 0; i < len; ++i) *str++ = *s++; + while (len < field_width--) + *str++ = ' '; } else { - while ((*sw)!=0) - *str++ = (char)(*sw++); + /* print unicode string */ + sw = va_arg(args, wchar_t *); + if (sw == NULL) + sw = L""; + + len = wcslen (sw); + if ((unsigned int)len > (unsigned int)precision) + len = precision; + + if (!(flags & LEFT)) + while (len < field_width--) + *str++ = ' '; + for (i = 0; i < len; ++i) + *str++ = (unsigned char)(*sw++); + while (len < field_width--) + *str++ = ' '; } continue; case 'Z': if (qualifier == 'w') { + /* print counted unicode string */ + PUNICODE_STRING pus = va_arg(args, PUNICODE_STRING); + if (pus == NULL) { + s = ""; + while ((*s) != 0) + *str++ = *s++; + } else { + for (i = 0; pus->Buffer[i] && i < pus->Length; i++) + *str++ = (unsigned char)(pus->Buffer[i]); + } } else { + /* print counted ascii string */ + PANSI_STRING pus = va_arg(args, PANSI_STRING); + if (pus == NULL) { + s = ""; + while ((*s) != 0) + *str++ = *s++; + } else { + for (i = 0; pus->Buffer[i] && i < pus->Length; i++) + *str++ = pus->Buffer[i]; + } } - continue; - + continue; + case 'p': if (field_width == -1) { field_width = 2 * sizeof(void *); @@ -332,23 +382,30 @@ int _vsnprintf(char *buf, size_t cnt, const char *fmt, va_list args) --fmt; continue; } - if (qualifier == 'l') + + if (qualifier == 'I') + num = va_arg(args, unsigned long long); + else if (qualifier == 'l') num = va_arg(args, unsigned long); - else if (qualifier == 'h') + else if (qualifier == 'h') { if (flags & SIGN) num = va_arg(args, short); else num = va_arg(args, unsigned short); - else if (flags & SIGN) - num = va_arg(args, int); - else - num = va_arg(args, unsigned int); + } + else { + if (flags & SIGN) + num = va_arg(args, int); + else + num = va_arg(args, unsigned int); + } str = number(str, num, base, field_width, precision, flags); } *str = '\0'; return str-buf; } + int sprintf(char * buf, const char *fmt, ...) { va_list args; @@ -360,6 +417,7 @@ int sprintf(char * buf, const char *fmt, ...) return i; } + int _snprintf(char * buf, size_t cnt, const char *fmt, ...) { va_list args; @@ -371,6 +429,7 @@ int _snprintf(char * buf, size_t cnt, const char *fmt, ...) return i; } + int vsprintf(char *buf, const char *fmt, va_list args) { return _vsnprintf(buf,INT_MAX,fmt,args); diff --git a/reactos/lib/ntdll/stdio/swprintf.c b/reactos/lib/ntdll/stdio/swprintf.c index 59e74a6c5a3..e1864eace51 100644 --- a/reactos/lib/ntdll/stdio/swprintf.c +++ b/reactos/lib/ntdll/stdio/swprintf.c @@ -1,11 +1,15 @@ -/* $Id: swprintf.c,v 1.2 2000/01/11 17:29:17 ekohl Exp $ +/* $Id: swprintf.c,v 1.3 2000/01/14 02:22:02 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * FILE: lib/ntdll/stdio/swprintf.c - * PURPOSE: Unicode printf functions + * PURPOSE: unicode sprintf functions * PROGRAMMERS: David Welch * Eric Kohl + * + * TODO: + * - Implement maximum length (cnt) in _vsnwprintf(). + * - Verify the implementation of '%Z'. */ /* @@ -29,25 +33,6 @@ #include -static size_t wcsnlen(const wchar_t *str, size_t count) -{ - const wchar_t *s; - - if (str == 0) - return 0; - for (s = str; *s && count; ++s, count--); - return s-str; -} - -static int skip_atoi(const wchar_t **s) -{ - int i=0; - - while (iswdigit(**s)) - i = i*10 + *((*s)++) - L'0'; - return i; -} - #define ZEROPAD 1 /* pad with zero */ #define SIGN 2 /* unsigned/signed long */ #define PLUS 4 /* show plus */ @@ -56,15 +41,26 @@ static int skip_atoi(const wchar_t **s) #define SPECIAL 32 /* 0x */ #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ + #define do_div(n,base) ({ \ int __res; \ -__res = ((unsigned long) n) % (unsigned) base; \ -n = ((unsigned long) n) / (unsigned) base; \ +__res = ((unsigned long long) n) % (unsigned) base; \ +n = ((unsigned long long) n) / (unsigned) base; \ __res; }) +static int skip_atoi(const wchar_t **s) +{ + int i=0; + + while (iswdigit(**s)) + i = i*10 + *((*s)++) - L'0'; + return i; +} + + static wchar_t * -number (wchar_t *str, long num, int base, int size, int precision, +number (wchar_t *str, long long num, int base, int size, int precision, int type) { wchar_t c,sign,tmp[66]; @@ -146,21 +142,22 @@ number (wchar_t *str, long num, int base, int size, int precision, return str; } + int _vsnwprintf(wchar_t *buf, size_t cnt, const wchar_t *fmt, va_list args) { int len; - unsigned long num; + unsigned long long num; int i, base; wchar_t * str; - const wchar_t *s; -// const short int* sw; /* needed for '%S' only */ + const char *s; + const wchar_t *sw; int flags; /* flags to number() */ int field_width; /* width of output field */ int precision; /* min. # of digits for integers; max number of chars for from string */ - int qualifier; /* 'h', 'l', or 'L' for integer fields */ + int qualifier; /* 'h', 'l', 'L', 'w' or 'I' for integer fields */ for (str=buf ; *fmt ; ++fmt) { if (*fmt != L'%') { @@ -211,9 +208,12 @@ int _vsnwprintf(wchar_t *buf, size_t cnt, const wchar_t *fmt, va_list args) /* get the conversion qualifier */ qualifier = -1; - if (*fmt == L'h' || *fmt == L'l' || *fmt == L'L') { + if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt == 'w') { qualifier = *fmt; ++fmt; + } else if (*fmt == 'I' && *(fmt+1) == '6' && *(fmt+2) == '4') { + qualifier = *fmt; + fmt += 3; } /* default base */ @@ -224,47 +224,126 @@ int _vsnwprintf(wchar_t *buf, size_t cnt, const wchar_t *fmt, va_list args) if (!(flags & LEFT)) while (--field_width > 0) *str++ = L' '; - *str++ = (wchar_t) va_arg(args, wchar_t); + if (qualifier == 'h') + *str++ = (wchar_t) va_arg(args, int); + else + *str++ = (wchar_t) va_arg(args, wchar_t); while (--field_width > 0) *str++ = L' '; continue; -#if 0 - case 'w': - sw = va_arg(args,short int *); -// DPRINT("L %x\n",sw); - if (sw==NULL) { -// CHECKPOINT; - s = ""; - while ((*s)!=0) - *str++ = *s++; -// CHECKPOINT; -// DbgPrint("str %x\n",str); - } else { - while ((*sw)!=0) - *str++ = (char)(*sw++); - } -// CHECKPOINT; + case L'C': + if (!(flags & LEFT)) + while (--field_width > 0) + *str++ = L' '; + if (qualifier == 'l' || qualifier == 'w') + *str++ = (wchar_t) va_arg(args, wchar_t); + else + *str++ = (wchar_t) va_arg(args, int); + while (--field_width > 0) + *str++ = L' '; continue; -#endif case L's': - s = va_arg(args, wchar_t *); - if (!s) - s = L""; + if (qualifier == 'h') { + /* print ascii string */ + s = va_arg(args, char *); + if (s == NULL) + s = ""; - len = wcsnlen((wchar_t *)s, precision); - len = wcslen((wchar_t *)s); - if (len > precision) - len = precision; + len = strlen (s); + if ((unsigned int)len > (unsigned int)precision) + len = precision; - if (!(flags & LEFT)) + if (!(flags & LEFT)) + while (len < field_width--) + *str++ = L' '; + for (i = 0; i < len; ++i) + *str++ = (wchar_t)(*s++); while (len < field_width--) *str++ = L' '; - for (i = 0; i < len; ++i) - *str++ = *s++; - while (len < field_width--) - *str++ = L' '; + } else { + /* print unicode string */ + sw = va_arg(args, wchar_t *); + if (sw == NULL) + sw = L""; + + len = wcslen (sw); + if ((unsigned int)len > (unsigned int)precision) + len = precision; + + if (!(flags & LEFT)) + while (len < field_width--) + *str++ = L' '; + for (i = 0; i < len; ++i) + *str++ = *sw++; + while (len < field_width--) + *str++ = L' '; + } + continue; + + case L'S': + if (qualifier == 'l' || qualifier == 'w') { + /* print unicode string */ + sw = va_arg(args, wchar_t *); + if (sw == NULL) + sw = L""; + + len = wcslen (sw); + if ((unsigned int)len > (unsigned int)precision) + len = precision; + + if (!(flags & LEFT)) + while (len < field_width--) + *str++ = L' '; + for (i = 0; i < len; ++i) + *str++ = *sw++; + while (len < field_width--) + *str++ = L' '; + } else { + /* print ascii string */ + s = va_arg(args, char *); + if (s == NULL) + s = ""; + + len = strlen (s); + if ((unsigned int)len > (unsigned int)precision) + len = precision; + + if (!(flags & LEFT)) + while (len < field_width--) + *str++ = L' '; + for (i = 0; i < len; ++i) + *str++ = (wchar_t)(*s++); + while (len < field_width--) + *str++ = L' '; + } + continue; + + case 'Z': + if (qualifier == 'h') { + /* print counted ascii string */ + PANSI_STRING pus = va_arg(args, PANSI_STRING); + if (pus == NULL) { + sw = L""; + while ((*sw) != 0) + *str++ = *sw++; + } else { + for (i = 0; pus->Buffer[i] && i < pus->Length; i++) + *str++ = (wchar_t)(pus->Buffer[i]); + } + } else { + /* print counted unicode string */ + PUNICODE_STRING pus = va_arg(args, PUNICODE_STRING); + if (pus == NULL) { + sw = L""; + while ((*sw) != 0) + *str++ = *sw++; + } else { + for (i = 0; pus->Buffer[i] && i < pus->Length; i++) + *str++ = pus->Buffer[i]; + } + } continue; case L'p': @@ -277,7 +356,6 @@ int _vsnwprintf(wchar_t *buf, size_t cnt, const wchar_t *fmt, va_list args) field_width, precision, flags); continue; - case L'n': if (qualifier == 'l') { long * ip = va_arg(args, long *); @@ -319,23 +397,29 @@ int _vsnwprintf(wchar_t *buf, size_t cnt, const wchar_t *fmt, va_list args) continue; } - if (qualifier == 'l') + if (qualifier == 'I') + num = va_arg(args, unsigned long long); + else if (qualifier == 'l') num = va_arg(args, unsigned long); - else if (qualifier == 'h') + else if (qualifier == 'h') { if (flags & SIGN) num = va_arg(args, short); else num = va_arg(args, unsigned short); - else if (flags & SIGN) - num = va_arg(args, int); - else - num = va_arg(args, unsigned int); + } + else { + if (flags & SIGN) + num = va_arg(args, int); + else + num = va_arg(args, unsigned int); + } str = number(str, num, base, field_width, precision, flags); } *str = L'\0'; return str-buf; } + int swprintf(wchar_t *buf, const wchar_t *fmt, ...) { va_list args; @@ -347,6 +431,7 @@ int swprintf(wchar_t *buf, const wchar_t *fmt, ...) return i; } + int _snwprintf(wchar_t *buf, size_t cnt, const wchar_t *fmt, ...) { va_list args; diff --git a/reactos/ntoskrnl/makefile_rex b/reactos/ntoskrnl/makefile_rex index 9ca4c11425e..276bd78e92a 100644 --- a/reactos/ntoskrnl/makefile_rex +++ b/reactos/ntoskrnl/makefile_rex @@ -1,4 +1,4 @@ -# $Id: makefile_rex,v 1.45 2000/01/10 22:46:37 ea Exp $ +# $Id: makefile_rex,v 1.46 2000/01/14 02:22:40 ekohl Exp $ # # ReactOS Operating System # @@ -17,12 +17,12 @@ NT_OBJECTS = nt/port.o nt/channel.o nt/ntevent.o nt/nttimer.o nt/atom.o \ nt/evtpair.o nt/ntsem.o nt/mutant.o nt/misc.o nt/plugplay.o \ nt/profile.o nt/nt.o nt/zw.o -RTL_OBJECTS = rtl/vsprintf.o rtl/lookas.o rtl/unicode.o rtl/time.o \ - rtl/unalign.o rtl/mem.o rtl/largeint.o rtl/ctype.o \ - rtl/list.o rtl/slist.o rtl/interlck.o rtl/return.o \ - rtl/wstring.o rtl/memcpy.o rtl/memmove.o rtl/memset.o \ - rtl/memchr.o rtl/nls.o rtl/string.o rtl/stdlib.o \ - rtl/regio.o +RTL_OBJECTS = rtl/ctype.o rtl/interlck.o rtl/largeint.o rtl/list.o \ + rtl/lookas.o rtl/mem.o rtl/memchr.o rtl/memcpy.o \ + rtl/memmove.o rtl/memset.o rtl/nls.o rtl/regio.o \ + rtl/return.o rtl/slist.o rtl/sprintf.o rtl/swprintf.o \ + rtl/stdlib.o rtl/string.o rtl/time.o rtl/unalign.o \ + rtl/unicode.o rtl/wstring.o KE_OBJECTS = ke/main.o ke/timer.o ke/error.o ke/catch.o \ ke/dpc.o ke/wait.o ke/kqueue.o ke/dispatch.o \ diff --git a/reactos/ntoskrnl/ntoskrnl.def b/reactos/ntoskrnl/ntoskrnl.def index 8aed5afcc87..d73402cf7e6 100644 --- a/reactos/ntoskrnl/ntoskrnl.def +++ b/reactos/ntoskrnl/ntoskrnl.def @@ -1,4 +1,4 @@ -; $Id: ntoskrnl.def,v 1.39 2000/01/12 19:01:56 ekohl Exp $ +; $Id: ntoskrnl.def,v 1.40 2000/01/14 02:22:40 ekohl Exp $ ; ; reactos/ntoskrnl/ntoskrnl.def ; @@ -393,7 +393,7 @@ _itoa ;_local_unwind2 ;_purecall _snprintf -;_snwprintf +_snwprintf _stricmp _strlwr _strnicmp @@ -437,7 +437,7 @@ strcpy strrchr strspn strstr -;swprintf +swprintf tolower toupper towlower diff --git a/reactos/ntoskrnl/ntoskrnl.edf b/reactos/ntoskrnl/ntoskrnl.edf index 9ad87b0fbe8..f4130b715b7 100644 --- a/reactos/ntoskrnl/ntoskrnl.edf +++ b/reactos/ntoskrnl/ntoskrnl.edf @@ -1,4 +1,4 @@ -; $Id: ntoskrnl.edf,v 1.26 2000/01/12 19:01:56 ekohl Exp $ +; $Id: ntoskrnl.edf,v 1.27 2000/01/14 02:22:40 ekohl Exp $ ; ; reactos/ntoskrnl/ntoskrnl.def ; @@ -391,7 +391,7 @@ _itoa ;_local_unwind2 ;_purecall _snprintf -;_snwprintf +_snwprintf _stricmp _strlwr _strnicmp @@ -435,7 +435,7 @@ strcpy strrchr strspn strstr -;swprintf +swprintf tolower toupper towlower diff --git a/reactos/ntoskrnl/rtl/vsprintf.c b/reactos/ntoskrnl/rtl/sprintf.c similarity index 67% rename from reactos/ntoskrnl/rtl/vsprintf.c rename to reactos/ntoskrnl/rtl/sprintf.c index 50e2a9ac203..5c70ed8aa4e 100644 --- a/reactos/ntoskrnl/rtl/vsprintf.c +++ b/reactos/ntoskrnl/rtl/sprintf.c @@ -1,3 +1,16 @@ +/* $Id: sprintf.c,v 1.1 2000/01/14 02:23:25 ekohl Exp $ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/rtl/sprintf.c + * PURPOSE: Single byte sprintf functions + * PROGRAMMERS: David Welch + * Eric Kohl + * + * TODO: + * - Implement maximum length (cnt) in _vsnprintf(). + */ + /* * linux/lib/vsprintf.c * @@ -9,19 +22,31 @@ * Wirzenius wrote this portably, Torvalds fucked it up :-) */ -/* - * Appropiated for the reactos kernel, March 1998 -- David Welch - */ - -#include #include -#include +#include #include +#include +#include -#define NDEBUG #include +#define ZEROPAD 1 /* pad with zero */ +#define SIGN 2 /* unsigned/signed long */ +#define PLUS 4 /* show plus */ +#define SPACE 8 /* space if plus */ +#define LEFT 16 /* left justified */ +#define SPECIAL 32 /* 0x */ +#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ + + +#define do_div(n,base) ({ \ +int __res; \ +__res = ((unsigned long long) n) % (unsigned) base; \ +n = ((unsigned long long) n) / (unsigned) base; \ +__res; }) + + static int skip_atoi(const char **s) { int i=0; @@ -31,22 +56,9 @@ static int skip_atoi(const char **s) return i; } -#define ZEROPAD 1 /* pad with zero */ -#define SIGN 2 /* unsigned/signed long */ -#define PLUS 4 /* show plus */ -#define SPACE 8 /* space if plus */ -#define LEFT 16 /* left justified */ -#define SPECIAL 32 /* 0x */ -#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ - -#define do_div(n,base) ({ \ -int __res; \ -__res = ((unsigned long) n) % (unsigned) base; \ -n = ((unsigned long) n) / (unsigned) base; \ -__res; }) static char * -number (char * str, long num, int base, int size, int precision, int type) +number (char * str, long long num, int base, int size, int precision, int type) { char c,sign,tmp[66]; const char *digits="0123456789abcdefghijklmnopqrstuvwxyz"; @@ -116,21 +128,22 @@ number (char * str, long num, int base, int size, int precision, int type) return str; } + int _vsnprintf(char *buf, size_t cnt, const char *fmt, va_list args) { int len; - unsigned long num; + unsigned long long num; int i, base; char * str; const char *s; - const short int* sw; + const wchar_t *sw; int flags; /* flags to number() */ int field_width; /* width of output field */ int precision; /* min. # of digits for integers; max number of chars for from string */ - int qualifier; /* 'h', 'l', or 'L' for integer fields */ + int qualifier; /* 'h', 'l', 'L', 'I' or 'w' for integer fields */ for (str=buf ; *fmt ; ++fmt) { if (*fmt != '%') { @@ -181,17 +194,19 @@ int _vsnprintf(char *buf, size_t cnt, const char *fmt, va_list args) /* get the conversion qualifier */ qualifier = -1; - if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt == 'w' || - (*fmt == 'I' && *(fmt+1) == '6' && *(fmt+2) == '4')) { + if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt == 'w') { qualifier = *fmt; ++fmt; + } else if (*fmt == 'I' && *(fmt+1) == '6' && *(fmt+2) == '4') { + qualifier = *fmt; + fmt += 3; } /* default base */ base = 10; switch (*fmt) { - case 'c': + case 'c': /* finished */ if (!(flags & LEFT)) while (--field_width > 0) *str++ = ' '; @@ -203,7 +218,7 @@ int _vsnprintf(char *buf, size_t cnt, const char *fmt, va_list args) *str++ = ' '; continue; - case 'C': + case 'C': /* finished */ if (!(flags & LEFT)) while (--field_width > 0) *str++ = ' '; @@ -215,69 +230,85 @@ int _vsnprintf(char *buf, size_t cnt, const char *fmt, va_list args) *str++ = ' '; continue; - case 's': - s = va_arg(args, char *); - if (!s) - s = ""; + case 's': /* finished */ + if (qualifier == 'l' || qualifier == 'w') { + /* print unicode string */ + sw = va_arg(args, wchar_t *); + if (sw == NULL) + sw = L""; - len = strnlen(s, precision); + len = wcslen (sw); + if ((unsigned int)len > (unsigned int)precision) + len = precision; - if (!(flags & LEFT)) + if (!(flags & LEFT)) + while (len < field_width--) + *str++ = ' '; + for (i = 0; i < len; ++i) + *str++ = (unsigned char)(*sw++); while (len < field_width--) *str++ = ' '; - for (i = 0; i < len; ++i) - *str++ = *s++; - while (len < field_width--) - *str++ = ' '; - continue; - -/* - case 'w': - sw = va_arg(args,short int *); -// DPRINT("L %x\n",sw); - if (sw==NULL) { -// CHECKPOINT; - s = ""; - while ((*s)!=0) - *str++ = *s++; -// CHECKPOINT; -// DbgPrint("str %x\n",str); } else { - while ((*sw)!=0) - *str++ = (char)(*sw++); + /* print ascii string */ + s = va_arg(args, char *); + if (s == NULL) + s = ""; + + len = strlen (s); + if ((unsigned int)len > (unsigned int)precision) + len = precision; + + if (!(flags & LEFT)) + while (len < field_width--) + *str++ = ' '; + for (i = 0; i < len; ++i) + *str++ = *s++; + while (len < field_width--) + *str++ = ' '; } -// CHECKPOINT; continue; -*/ case 'S': - sw = va_arg(args,short int *); - if (sw==NULL) { - s = ""; - while ((*s)!=0) - *str++ = *s++; - } else { - while ((*sw)!=0) - *str++ = (char)(*sw++); - } - continue; + if (qualifier == 'h') { + /* print ascii string */ + s = va_arg(args, char *); + if (s == NULL) + s = ""; -/* - case 'W': - pus = va_arg(args, PUNICODE_STRING); - if (pus == NULL) { - s = ""; - while ((*s) != 0) + len = strlen (s); + if ((unsigned int)len > (unsigned int)precision) + len = precision; + + if (!(flags & LEFT)) + while (len < field_width--) + *str++ = ' '; + for (i = 0; i < len; ++i) *str++ = *s++; + while (len < field_width--) + *str++ = ' '; } else { - for (i = 0; pus->Buffer[i] && i < pus->Length; i++) - *str++ = (char)(pus->Buffer[i]); + /* print unicode string */ + sw = va_arg(args, wchar_t *); + if (sw == NULL) + sw = L""; + + len = wcslen (sw); + if ((unsigned int)len > (unsigned int)precision) + len = precision; + + if (!(flags & LEFT)) + while (len < field_width--) + *str++ = ' '; + for (i = 0; i < len; ++i) + *str++ = (unsigned char)(*sw++); + while (len < field_width--) + *str++ = ' '; } continue; -*/ case 'Z': if (qualifier == 'w') { + /* print counted unicode string */ PUNICODE_STRING pus = va_arg(args, PUNICODE_STRING); if (pus == NULL) { s = ""; @@ -285,9 +316,10 @@ int _vsnprintf(char *buf, size_t cnt, const char *fmt, va_list args) *str++ = *s++; } else { for (i = 0; pus->Buffer[i] && i < pus->Length; i++) - *str++ = (char)(pus->Buffer[i]); + *str++ = (unsigned char)(pus->Buffer[i]); } } else { + /* print counted ascii string */ PANSI_STRING pus = va_arg(args, PANSI_STRING); if (pus == NULL) { s = ""; @@ -350,23 +382,30 @@ int _vsnprintf(char *buf, size_t cnt, const char *fmt, va_list args) --fmt; continue; } - if (qualifier == 'l') + + if (qualifier == 'I') + num = va_arg(args, unsigned long long); + else if (qualifier == 'l') num = va_arg(args, unsigned long); - else if (qualifier == 'h') + else if (qualifier == 'h') { if (flags & SIGN) num = va_arg(args, short); else num = va_arg(args, unsigned short); - else if (flags & SIGN) - num = va_arg(args, int); - else - num = va_arg(args, unsigned int); + } + else { + if (flags & SIGN) + num = va_arg(args, int); + else + num = va_arg(args, unsigned int); + } str = number(str, num, base, field_width, precision, flags); } *str = '\0'; return str-buf; } + int sprintf(char * buf, const char *fmt, ...) { va_list args; @@ -378,6 +417,7 @@ int sprintf(char * buf, const char *fmt, ...) return i; } + int _snprintf(char * buf, size_t cnt, const char *fmt, ...) { va_list args; @@ -389,6 +429,7 @@ int _snprintf(char * buf, size_t cnt, const char *fmt, ...) return i; } + int vsprintf(char *buf, const char *fmt, va_list args) { return _vsnprintf(buf,INT_MAX,fmt,args); diff --git a/reactos/ntoskrnl/rtl/swprintf.c b/reactos/ntoskrnl/rtl/swprintf.c new file mode 100644 index 00000000000..18840e44e76 --- /dev/null +++ b/reactos/ntoskrnl/rtl/swprintf.c @@ -0,0 +1,452 @@ +/* $Id: swprintf.c,v 1.1 2000/01/14 02:23:25 ekohl Exp $ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/rtl/swprintf.c + * PURPOSE: unicode sprintf functions + * PROGRAMMERS: David Welch + * Eric Kohl + * + * TODO: + * - Implement maximum length (cnt) in _vsnwprintf(). + * - Verify the implementation of '%Z'. + */ + +/* + * linux/lib/vsprintf.c + * + * Copyright (C) 1991, 1992 Linus Torvalds + */ + +/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */ +/* + * Wirzenius wrote this portably, Torvalds fucked it up :-) + */ + +#include +#include +#include +#include +#include + +#define NDEBUG +#include + + +#define ZEROPAD 1 /* pad with zero */ +#define SIGN 2 /* unsigned/signed long */ +#define PLUS 4 /* show plus */ +#define SPACE 8 /* space if plus */ +#define LEFT 16 /* left justified */ +#define SPECIAL 32 /* 0x */ +#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ + + +#define do_div(n,base) ({ \ +int __res; \ +__res = ((unsigned long long) n) % (unsigned) base; \ +n = ((unsigned long long) n) / (unsigned) base; \ +__res; }) + + +static int skip_atoi(const wchar_t **s) +{ + int i=0; + + while (iswdigit(**s)) + i = i*10 + *((*s)++) - L'0'; + return i; +} + + +static wchar_t * +number (wchar_t *str, long long num, int base, int size, int precision, + int type) +{ + wchar_t c,sign,tmp[66]; + const wchar_t *digits = L"0123456789abcdefghijklmnopqrstuvwxyz"; + int i; + + if (type & LARGE) + digits = L"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + if (type & LEFT) + type &= ~ZEROPAD; + if (base < 2 || base > 36) + return 0; + + c = (type & ZEROPAD) ? L'0' : L' '; + sign = 0; + + if (type & SIGN) + { + if (num < 0) + { + sign = L'-'; + num = -num; + size--; + } + else if (type & PLUS) + { + sign = L'+'; + size--; + } + else if (type & SPACE) + { + sign = L' '; + size--; + } + } + + if (type & SPECIAL) + { + if (base == 16) + size -= 2; + else if (base == 8) + size--; + } + + i = 0; + if (num == 0) + tmp[i++]='0'; + else while (num != 0) + tmp[i++] = digits[do_div(num,base)]; + if (i > precision) + precision = i; + size -= precision; + if (!(type&(ZEROPAD+LEFT))) + while(size-->0) + *str++ = L' '; + if (sign) + *str++ = sign; + if (type & SPECIAL) + { + if (base==8) + { + *str++ = L'0'; + } + else if (base==16) + { + *str++ = L'0'; + *str++ = digits[33]; + } + } + if (!(type & LEFT)) + while (size-- > 0) + *str++ = c; + while (i < precision--) + *str++ = '0'; + while (i-- > 0) + *str++ = tmp[i]; + while (size-- > 0) + *str++ = L' '; + return str; +} + + +int _vsnwprintf(wchar_t *buf, size_t cnt, const wchar_t *fmt, va_list args) +{ + int len; + unsigned long long num; + int i, base; + wchar_t * str; + const char *s; + const wchar_t *sw; + + int flags; /* flags to number() */ + + int field_width; /* width of output field */ + int precision; /* min. # of digits for integers; max + number of chars for from string */ + int qualifier; /* 'h', 'l', 'L', 'w' or 'I' for integer fields */ + + for (str=buf ; *fmt ; ++fmt) { + if (*fmt != L'%') { + *str++ = *fmt; + continue; + } + + /* process flags */ + flags = 0; + repeat: + ++fmt; /* this also skips first '%' */ + switch (*fmt) { + case L'-': flags |= LEFT; goto repeat; + case L'+': flags |= PLUS; goto repeat; + case L' ': flags |= SPACE; goto repeat; + case L'#': flags |= SPECIAL; goto repeat; + case L'0': flags |= ZEROPAD; goto repeat; + } + + /* get field width */ + field_width = -1; + if (iswdigit(*fmt)) + field_width = skip_atoi(&fmt); + else if (*fmt == L'*') { + ++fmt; + /* it's the next argument */ + field_width = va_arg(args, int); + if (field_width < 0) { + field_width = -field_width; + flags |= LEFT; + } + } + + /* get the precision */ + precision = -1; + if (*fmt == L'.') { + ++fmt; + if (iswdigit(*fmt)) + precision = skip_atoi(&fmt); + else if (*fmt == L'*') { + ++fmt; + /* it's the next argument */ + precision = va_arg(args, int); + } + if (precision < 0) + precision = 0; + } + + /* get the conversion qualifier */ + qualifier = -1; + if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt == 'w') { + qualifier = *fmt; + ++fmt; + } else if (*fmt == 'I' && *(fmt+1) == '6' && *(fmt+2) == '4') { + qualifier = *fmt; + fmt += 3; + } + + /* default base */ + base = 10; + + switch (*fmt) { + case L'c': + if (!(flags & LEFT)) + while (--field_width > 0) + *str++ = L' '; + if (qualifier == 'h') + *str++ = (wchar_t) va_arg(args, int); + else + *str++ = (wchar_t) va_arg(args, wchar_t); + while (--field_width > 0) + *str++ = L' '; + continue; + + case L'C': + if (!(flags & LEFT)) + while (--field_width > 0) + *str++ = L' '; + if (qualifier == 'l' || qualifier == 'w') + *str++ = (wchar_t) va_arg(args, wchar_t); + else + *str++ = (wchar_t) va_arg(args, int); + while (--field_width > 0) + *str++ = L' '; + continue; + + case L's': + if (qualifier == 'h') { + /* print ascii string */ + s = va_arg(args, char *); + if (s == NULL) + s = ""; + + len = strlen (s); + if ((unsigned int)len > (unsigned int)precision) + len = precision; + + if (!(flags & LEFT)) + while (len < field_width--) + *str++ = L' '; + for (i = 0; i < len; ++i) + *str++ = (wchar_t)(*s++); + while (len < field_width--) + *str++ = L' '; + } else { + /* print unicode string */ + sw = va_arg(args, wchar_t *); + if (sw == NULL) + sw = L""; + + len = wcslen (sw); + if ((unsigned int)len > (unsigned int)precision) + len = precision; + + if (!(flags & LEFT)) + while (len < field_width--) + *str++ = L' '; + for (i = 0; i < len; ++i) + *str++ = *sw++; + while (len < field_width--) + *str++ = L' '; + } + continue; + + case L'S': + if (qualifier == 'l' || qualifier == 'w') { + /* print unicode string */ + sw = va_arg(args, wchar_t *); + if (sw == NULL) + sw = L""; + + len = wcslen (sw); + if ((unsigned int)len > (unsigned int)precision) + len = precision; + + if (!(flags & LEFT)) + while (len < field_width--) + *str++ = L' '; + for (i = 0; i < len; ++i) + *str++ = *sw++; + while (len < field_width--) + *str++ = L' '; + } else { + /* print ascii string */ + s = va_arg(args, char *); + if (s == NULL) + s = ""; + + len = strlen (s); + if ((unsigned int)len > (unsigned int)precision) + len = precision; + + if (!(flags & LEFT)) + while (len < field_width--) + *str++ = L' '; + for (i = 0; i < len; ++i) + *str++ = (wchar_t)(*s++); + while (len < field_width--) + *str++ = L' '; + } + continue; + + case 'Z': + if (qualifier == 'h') { + /* print counted ascii string */ + PANSI_STRING pus = va_arg(args, PANSI_STRING); + if (pus == NULL) { + sw = L""; + while ((*sw) != 0) + *str++ = *sw++; + } else { + for (i = 0; pus->Buffer[i] && i < pus->Length; i++) + *str++ = (wchar_t)(pus->Buffer[i]); + } + } else { + /* print counted unicode string */ + PUNICODE_STRING pus = va_arg(args, PUNICODE_STRING); + if (pus == NULL) { + sw = L""; + while ((*sw) != 0) + *str++ = *sw++; + } else { + for (i = 0; pus->Buffer[i] && i < pus->Length; i++) + *str++ = pus->Buffer[i]; + } + } + continue; + + case L'p': + if (field_width == -1) { + field_width = 2*sizeof(void *); + flags |= ZEROPAD; + } + str = number(str, + (unsigned long) va_arg(args, void *), 16, + field_width, precision, flags); + continue; + + case L'n': + if (qualifier == 'l') { + long * ip = va_arg(args, long *); + *ip = (str - buf); + } else { + int * ip = va_arg(args, int *); + *ip = (str - buf); + } + continue; + + /* integer number formats - set up the flags and "break" */ + case L'o': + base = 8; + break; + + case L'b': + base = 2; + break; + + case L'X': + flags |= LARGE; + case L'x': + base = 16; + break; + + case L'd': + case L'i': + flags |= SIGN; + case L'u': + break; + + default: + if (*fmt != L'%') + *str++ = L'%'; + if (*fmt) + *str++ = *fmt; + else + --fmt; + continue; + } + + if (qualifier == 'I') + num = va_arg(args, unsigned long long); + else if (qualifier == 'l') + num = va_arg(args, unsigned long); + else if (qualifier == 'h') { + if (flags & SIGN) + num = va_arg(args, short); + else + num = va_arg(args, unsigned short); + } + else { + if (flags & SIGN) + num = va_arg(args, int); + else + num = va_arg(args, unsigned int); + } + str = number(str, num, base, field_width, precision, flags); + } + *str = L'\0'; + return str-buf; +} + + +int swprintf(wchar_t *buf, const wchar_t *fmt, ...) +{ + va_list args; + int i; + + va_start(args, fmt); + i=_vsnwprintf(buf,INT_MAX,fmt,args); + va_end(args); + return i; +} + + +int _snwprintf(wchar_t *buf, size_t cnt, const wchar_t *fmt, ...) +{ + va_list args; + int i; + + va_start(args, fmt); + i=_vsnwprintf(buf,cnt,fmt,args); + va_end(args); + return i; +} + + +int vswprintf(wchar_t *buf, const wchar_t *fmt, va_list args) +{ + return _vsnwprintf(buf,INT_MAX,fmt,args); +} + +/* EOF */