Ignore:
Timestamp:
Apr 7, 2003, 8:40:53 PM (22 years ago)
Author:
sandervl
Message:

PF: NTDLL update for GCC 3.2.1 + resync with Wine

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/NTDLL/wcstring.c

    r8429 r9986  
    44 * Copyright 2000 Alexandre Julliard
    55 * Copyright 2000 Jon Griffiths
     6 * Copyright 2003 Thomas Mertes
    67 *
    78 * This library is free software; you can redistribute it and/or
     
    2324
    2425#include <ctype.h>
    25 #include <limits.h>
    2626#include <stdlib.h>
    2727#include <string.h>
    2828#include <stdio.h>
    29 
    30 #include "ntddk.h"
     29#include <limits.h>
     30
     31#include "winternl.h"
    3132#include "wine/unicode.h"
    3233#include "wine/debug.h"
     
    304305/*********************************************************************
    305306 *                  wcstol  (NTDLL.@)
    306  * Like strtol, but for wide character strings.
    307  */
    308 INT __cdecl NTDLL_wcstol(LPCWSTR s,LPWSTR *end,INT base)
    309 {
    310     UNICODE_STRING uni;
    311     ANSI_STRING ansi;
    312     INT ret;
    313     LPSTR endA;
    314 
    315     RtlInitUnicodeString( &uni, s );
    316     RtlUnicodeStringToAnsiString( &ansi, &uni, TRUE );
    317     ret = strtol( ansi.Buffer, &endA, base );
    318     if (end)
    319     {
    320         DWORD len;
    321         RtlMultiByteToUnicodeSize( &len, ansi.Buffer, endA - ansi.Buffer );
    322         *end = (LPWSTR)s + len/sizeof(WCHAR);
    323     }
    324     RtlFreeAnsiString( &ansi );
    325     return ret;
     307 */
     308long __cdecl NTDLL_wcstol(LPCWSTR s,LPWSTR *end,INT base)
     309{
     310    return strtolW( s, end, base );
    326311}
    327312
     
    329314/*********************************************************************
    330315 *                  wcstoul  (NTDLL.@)
    331  * Like strtoul, but for wide character strings.
    332  */
    333 INT __cdecl NTDLL_wcstoul(LPCWSTR s,LPWSTR *end,INT base)
    334 {
    335     UNICODE_STRING uni;
    336     ANSI_STRING ansi;
    337     INT ret;
    338     LPSTR endA;
    339 
    340     RtlInitUnicodeString( &uni, s );
    341     RtlUnicodeStringToAnsiString( &ansi, &uni, TRUE );
    342     ret = strtoul( ansi.Buffer, &endA, base );
    343     if (end)
    344     {
    345         DWORD len;
    346         RtlMultiByteToUnicodeSize( &len, ansi.Buffer, endA - ansi.Buffer );
    347         *end = (LPWSTR)s + len/sizeof(WCHAR);
    348     }
    349     RtlFreeAnsiString( &ansi );
    350     return ret;
     316 */
     317unsigned long __cdecl NTDLL_wcstoul(LPCWSTR s,LPWSTR *end,INT base)
     318{
     319    return strtoulW( s, end, base );
    351320}
    352321
     
    369338}
    370339
    371 
    372 /*********************************************************************
    373  *           _ultow    (NTDLL.@)
    374  * Like _ultoa, but for wide character strings.
    375  */
    376 LPWSTR __cdecl _ultow(ULONG value, LPWSTR string, INT radix)
    377 {
    378     WCHAR tmp[33];
    379     LPWSTR tp = tmp;
    380     LPWSTR sp;
    381     LONG i;
    382     ULONG v = value;
    383 
    384     if (radix > 36 || radix <= 1)
    385         return 0;
    386 
    387     while (v || tp == tmp)
    388     {
    389         i = v % radix;
    390         v = v / radix;
    391         if (i < 10)
    392             *tp++ = i + '0';
    393         else
    394             *tp++ = i + 'a' - 10;
    395     }
    396 
    397     sp = string;
    398     while (tp > tmp)
    399         *sp++ = *--tp;
    400     *sp = 0;
    401     return string;
    402 }
    403 
    404 /*********************************************************************
    405  *           _wtol    (NTDLL.@)
    406  * Like atol, but for wide character strings.
    407  */
    408 LONG __cdecl _wtol(LPWSTR string)
    409 {
    410     char buffer[30];
    411     NTDLL_wcstombs( buffer, string, sizeof(buffer) );
    412     return atol( buffer );
    413 }
    414 
    415 /*********************************************************************
    416  *           _wtoi    (NTDLL.@)
    417  */
    418 INT __cdecl _wtoi(LPWSTR string)
     340/*********************************************************************
     341 *              iswdigit (NTDLL.@)
     342 *
     343 * Checks if an unicode char wc is a digit
     344 *
     345 * RETURNS
     346 *  TRUE: The unicode char wc is a digit.
     347 *  FALSE: Otherwise
     348 */
     349INT __cdecl NTDLL_iswdigit( WCHAR wc )
     350{
     351    return isdigitW(wc);
     352}
     353
     354
     355/*********************************************************************
     356 *              iswlower (NTDLL.@)
     357 *
     358 * Checks if an unicode char wc is a lower case letter
     359 *
     360 * RETURNS
     361 *  TRUE: The unicode char wc is a lower case letter.
     362 *  FALSE: Otherwise
     363 */
     364INT __cdecl NTDLL_iswlower( WCHAR wc )
     365{
     366    return islowerW(wc);
     367}
     368
     369
     370/*********************************************************************
     371 *              iswspace (NTDLL.@)
     372 *
     373 * Checks if an unicode char wc is a white space character
     374 *
     375 * RETURNS
     376 *  TRUE: The unicode char wc is a white space character.
     377 *  FALSE: Otherwise
     378 */
     379INT __cdecl NTDLL_iswspace( WCHAR wc )
     380{
     381    return isspaceW(wc);
     382}
     383
     384
     385/*********************************************************************
     386 *              iswxdigit (NTDLL.@)
     387 *
     388 * Checks if an unicode char wc is an extended digit
     389 *
     390 * RETURNS
     391 *  TRUE: The unicode char wc is an extended digit.
     392 *  FALSE: Otherwise
     393 */
     394INT __cdecl NTDLL_iswxdigit( WCHAR wc )
     395{
     396    return isxdigitW(wc);
     397}
     398
     399
     400/*********************************************************************
     401 *      _ultow   (NTDLL.@)
     402 *
     403 * Converts an unsigned long integer to an unicode string.
     404 *
     405 * Assigns a '\0' terminated string to str and returns str.
     406 * Does not check if radix is in the range of 2 to 36 (as native DLL).
     407 * For str == NULL just returns NULL (as native DLL).
     408 */
     409LPWSTR __cdecl _ultow( unsigned long value, LPWSTR str, INT radix )
     410{
     411    WCHAR buffer[33];
     412    PWCHAR pos;
     413    WCHAR digit;
     414
     415    pos = &buffer[32];
     416    *pos = '\0';
     417
     418    do {
     419        digit = value % radix;
     420        value = value / radix;
     421        if (digit < 10) {
     422            *--pos = '0' + digit;
     423        } else {
     424            *--pos = 'a' + digit - 10;
     425        } /* if */
     426    } while (value != 0L);
     427
     428    if (str != NULL) {
     429        memcpy(str, pos, (&buffer[32] - pos + 1) * sizeof(WCHAR));
     430    } /* if */
     431    return str;
     432}
     433
     434
     435/*********************************************************************
     436 *      _ltow   (NTDLL.@)
     437 *
     438 * Converts a long integer to an unicode string.
     439 *
     440 * RETURNS
     441 *  Always returns str.
     442 *
     443 * NOTES
     444 *  Converts value to a '\0' terminated wstring which is copied to str.
     445 *  The maximum length of the copied str is 33 bytes. If radix
     446 *  is 10 and value is negative, the value is converted with sign.
     447 *  Does not check if radix is in the range of 2 to 36.
     448 *  If str is NULL it just returns NULL.
     449 */
     450LPWSTR __cdecl _ltow(
     451    long value, /* [I] Value to be converted */
     452    LPWSTR str, /* [O] Destination for the converted value */
     453    INT radix)  /* [I] Number base for conversion */
     454{
     455    unsigned long val;
     456    int negative;
     457    WCHAR buffer[33];
     458    PWCHAR pos;
     459    WCHAR digit;
     460
     461    if (value < 0 && radix == 10) {
     462        negative = 1;
     463        val = -value;
     464    } else {
     465        negative = 0;
     466        val = value;
     467    } /* if */
     468
     469    pos = &buffer[32];
     470    *pos = '\0';
     471
     472    do {
     473        digit = val % radix;
     474        val = val / radix;
     475        if (digit < 10) {
     476            *--pos = '0' + digit;
     477        } else {
     478            *--pos = 'a' + digit - 10;
     479        } /* if */
     480    } while (val != 0L);
     481
     482    if (negative) {
     483        *--pos = '-';
     484    } /* if */
     485
     486    if (str != NULL) {
     487        memcpy(str, pos, (&buffer[32] - pos + 1) * sizeof(WCHAR));
     488    } /* if */
     489    return str;
     490}
     491
     492
     493
     494/*********************************************************************
     495 *      _itow    (NTDLL.@)
     496 *
     497 * Converts an integer to an unicode string.
     498 *
     499 * RETURNS
     500 *  Always returns str.
     501 *
     502 * NOTES
     503 *  Converts value to a '\0' terminated wstring which is copied to str.
     504 *  The maximum length of the copied str is 33 bytes. If radix
     505 *  is 10 and value is negative, the value is converted with sign.
     506 *  Does not check if radix is in the range of 2 to 36.
     507 *  If str is NULL it just returns NULL.
     508 *
     509 * DIFFERENCES
     510 * - The native function crashes when the string is longer than 19 chars.
     511 *   This function does not have this bug.
     512 */
     513LPWSTR __cdecl _itow(
     514    int value,  /* [I] Value to be converted */
     515    LPWSTR str, /* [O] Destination for the converted value */
     516    INT radix)  /* [I] Number base for conversion */
     517{
     518    return _ltow(value, str, radix);
     519}
     520
     521
     522/*********************************************************************
     523 *      _ui64tow   (NTDLL.@)
     524 *
     525 * Converts a large unsigned integer to an unicode string.
     526 *
     527 * Assigns a '\0' terminated wstring to str and returns str.
     528 * Does not check if radix is in the range of 2 to 36 (as native DLL).
     529 * For str == NULL just returns NULL (as native DLL).
     530 *
     531 * Difference:
     532 * - This function does not exist in the native DLL (but in msvcrt).
     533 *   But since the maintenance of all these functions is better done
     534 *   in one place we implement it here.
     535 */
     536LPWSTR __cdecl _ui64tow( ULONGLONG value, LPWSTR str, INT radix )
     537{
     538    WCHAR buffer[65];
     539    PWCHAR pos;
     540    WCHAR digit;
     541
     542    pos = &buffer[64];
     543    *pos = '\0';
     544
     545    do {
     546        digit = value % radix;
     547        value = value / radix;
     548        if (digit < 10) {
     549            *--pos = '0' + digit;
     550        } else {
     551            *--pos = 'a' + digit - 10;
     552        } /* if */
     553    } while (value != 0L);
     554
     555    if (str != NULL) {
     556        memcpy(str, pos, (&buffer[64] - pos + 1) * sizeof(WCHAR));
     557    } /* if */
     558    return str;
     559}
     560
     561
     562/*********************************************************************
     563 *      _i64tow   (NTDLL.@)
     564 *
     565 * Converts a large integer to an unicode string.
     566 *
     567 * Assigns a '\0' terminated wstring to str and returns str. If radix
     568 * is 10 and value is negative, the value is converted with sign.
     569 * Does not check if radix is in the range of 2 to 36 (as native DLL).
     570 * For str == NULL just returns NULL (as native DLL).
     571 *
     572 * Difference:
     573 * - The native DLL converts negative values (for base 10) wrong:
     574 *                     -1 is converted to -18446744073709551615
     575 *                     -2 is converted to -18446744073709551614
     576 *   -9223372036854775807 is converted to  -9223372036854775809
     577 *   -9223372036854775808 is converted to  -9223372036854775808
     578 *   The native msvcrt _i64tow function and our ntdll function do
     579 *   not have this bug.
     580 */
     581LPWSTR __cdecl _i64tow( LONGLONG value, LPWSTR str, INT radix )
     582{
     583    ULONGLONG val;
     584    int negative;
     585    WCHAR buffer[65];
     586    PWCHAR pos;
     587    WCHAR digit;
     588
     589    if (value < 0 && radix == 10) {
     590        negative = 1;
     591        val = -value;
     592    } else {
     593        negative = 0;
     594        val = value;
     595    } /* if */
     596
     597    pos = &buffer[64];
     598    *pos = '\0';
     599
     600    do {
     601        digit = val % radix;
     602        val = val / radix;
     603        if (digit < 10) {
     604            *--pos = '0' + digit;
     605        } else {
     606            *--pos = 'a' + digit - 10;
     607        } /* if */
     608    } while (val != 0L);
     609
     610    if (negative) {
     611        *--pos = '-';
     612    } /* if */
     613
     614    if (str != NULL) {
     615        memcpy(str, pos, (&buffer[64] - pos + 1) * sizeof(WCHAR));
     616    } /* if */
     617    return str;
     618}
     619
     620
     621/*********************************************************************
     622 *      _wtol    (NTDLL.@)
     623 *
     624 * Converts an unicode string to a long integer.
     625 *
     626 * On success it returns the integer value otherwise it returns 0.
     627 * Accepts: {whitespace} [+|-] {digits}
     628 * No check of overflow: Just assigns lower 32 bits (as native DLL).
     629 * Does not check for str != NULL (as native DLL).
     630 */
     631LONG __cdecl _wtol( LPWSTR str )
     632{
     633    ULONG RunningTotal = 0;
     634    char bMinus = 0;
     635
     636    while (isspaceW(*str)) {
     637        str++;
     638    } /* while */
     639
     640    if (*str == '+') {
     641        str++;
     642    } else if (*str == '-') {
     643        bMinus = 1;
     644        str++;
     645    } /* if */
     646
     647    while (*str >= '0' && *str <= '9') {
     648        RunningTotal = RunningTotal * 10 + *str - '0';
     649        str++;
     650    } /* while */
     651
     652    return bMinus ? -RunningTotal : RunningTotal;
     653}
     654
     655
     656/*********************************************************************
     657 *      _wtoi    (NTDLL.@)
     658 *
     659 * Converts an unicode string to an integer.
     660 *
     661 * On success it returns the integer value otherwise it returns 0.
     662 * Accepts: {whitespace} [+|-] {digits}
     663 * No check of overflow: Just assigns lower 32 bits (as native DLL).
     664 * Does not check for str != NULL (as native DLL).
     665 */
     666int __cdecl _wtoi( LPWSTR string )
    419667{
    420668    return _wtol(string);
    421669}
    422670
    423 /* INTERNAL: Wide char snprintf
    424  * If you fix a bug in this function, fix it in msvcrt/wcs.c also!
    425  */
    426 static int __cdecl NTDLL_vsnwprintf(WCHAR *str, unsigned int len,
    427                                     const WCHAR *format, va_list valist)
    428 {
    429   unsigned int written = 0;
    430   const WCHAR *iter = format;
    431   char bufa[256], fmtbufa[64], *fmta;
    432 
    433   TRACE("(%d,%s)\n",len,debugstr_w(format));
    434 
    435   while (*iter)
    436   {
    437     while (*iter && *iter != (WCHAR)L'%')
    438     {
    439      if (written++ >= len)
    440        return -1;
    441      *str++ = *iter++;
    442     }
    443     if (*iter == (WCHAR)L'%')
    444     {
    445       fmta = fmtbufa;
    446       *fmta++ = *iter++;
    447       while (*iter == (WCHAR)L'0' ||
    448              *iter == (WCHAR)L'+' ||
    449              *iter == (WCHAR)L'-' ||
    450              *iter == (WCHAR)L' ' ||
    451              *iter == (WCHAR)L'0' ||
    452              *iter == (WCHAR)L'*' ||
    453              *iter == (WCHAR)L'#')
    454       {
    455         if (*iter == (WCHAR)L'*')
    456         {
    457           char *buffiter = bufa;
    458           int fieldlen = va_arg(valist, int);
    459           sprintf(buffiter, "%d", fieldlen);
    460           while (*buffiter)
    461             *fmta++ = *buffiter++;
    462         }
    463         else
    464           *fmta++ = *iter;
    465         iter++;
    466       }
    467 
    468       while (isdigit(*iter))
    469         *fmta++ = *iter++;
    470 
    471       if (*iter == (WCHAR)L'.')
    472       {
    473         *fmta++ = *iter++;
    474         if (*iter == (WCHAR)L'*')
    475         {
    476           char *buffiter = bufa;
    477           int fieldlen = va_arg(valist, int);
    478           sprintf(buffiter, "%d", fieldlen);
    479           while (*buffiter)
    480             *fmta++ = *buffiter++;
    481         }
    482         else
    483           while (isdigit(*iter))
    484             *fmta++ = *iter++;
    485       }
    486       if (*iter == (WCHAR)L'h' ||
    487           *iter == (WCHAR)L'l')
    488       {
    489           *fmta++ = *iter++;
    490           *fmta++ = *iter++;
    491       }
    492 
    493       switch (*iter)
    494       {
    495       case (WCHAR)L's':
    496         {
    497           static const WCHAR none[] = { '(', 'n', 'u', 'l', 'l', ')', 0 };
    498           const WCHAR *wstr = va_arg(valist, const WCHAR *);
    499           const WCHAR *striter = wstr ? wstr : none;
    500           while (*striter)
    501           {
    502             if (written++ >= len)
    503               return -1;
    504             *str++ = *striter++;
    505           }
    506           iter++;
    507           break;
    508         }
    509 
    510       case (WCHAR)L'c':
    511         if (written++ >= len)
    512           return -1;
    513         *str++ = (WCHAR)va_arg(valist, int);
    514         iter++;
    515         break;
    516 
    517       default:
    518         {
    519           /* For non wc types, use system sprintf and append to wide char output */
    520           /* FIXME: for unrecognised types, should ignore % when printing */
    521           char *bufaiter = bufa;
    522           if (*iter == (WCHAR)L'p')
    523             sprintf(bufaiter, "%08lX", va_arg(valist, long));
    524           else
    525           {
    526             *fmta++ = *iter;
    527             *fmta = '\0';
    528             if (*iter == (WCHAR)L'f')
    529               sprintf(bufaiter, fmtbufa, va_arg(valist, double));
    530             else
    531               sprintf(bufaiter, fmtbufa, va_arg(valist, void *));
    532           }
    533           while (*bufaiter)
    534           {
    535             if (written++ >= len)
    536               return -1;
    537             *str++ = *bufaiter++;
    538           }
    539           iter++;
    540           break;
    541         }
    542       }
    543     }
    544   }
    545   if (written >= len)
    546     return -1;
    547   *str++ = (WCHAR)L'\0';
    548   return (int)written;
    549 }
     671
     672/*********************************************************************
     673 *      _wtoi64   (NTDLL.@)
     674 *
     675 * Converts an unicode string to a large integer.
     676 *
     677 * On success it returns the integer value otherwise it returns 0.
     678 * Accepts: {whitespace} [+|-] {digits}
     679 * No check of overflow: Just assigns lower 64 bits (as native DLL).
     680 * Does not check for str != NULL (as native DLL).
     681 */
     682LONGLONG  __cdecl _wtoi64( LPWSTR str )
     683{
     684    ULONGLONG RunningTotal = 0;
     685    char bMinus = 0;
     686
     687    while (isspaceW(*str)) {
     688        str++;
     689    } /* while */
     690
     691    if (*str == '+') {
     692        str++;
     693    } else if (*str == '-') {
     694        bMinus = 1;
     695        str++;
     696    } /* if */
     697
     698    while (*str >= '0' && *str <= '9') {
     699        RunningTotal = RunningTotal * 10 + *str - '0';
     700        str++;
     701    } /* while */
     702
     703    return bMinus ? -RunningTotal : RunningTotal;
     704}
     705
    550706
    551707
     
    558714  va_list valist;
    559715  va_start(valist, format);
    560   retval = NTDLL_vsnwprintf(str, len, format, valist);
     716  retval = vsnprintfW(str, len, format, valist);
    561717  va_end(valist);
    562718  return retval;
     
    572728  va_list valist;
    573729  va_start(valist, format);
    574   retval = NTDLL_vsnwprintf(str, INT_MAX, format, valist);
     730  retval = vsnprintfW(str, INT_MAX, format, valist);
    575731  va_end(valist);
    576732  return retval;
Note: See TracChangeset for help on using the changeset viewer.