string.c 5.68 KB
Newer Older
1 2 3 4 5 6
/*
 * String manipulation functions
 *
 * Copyright 1998 Eric Kohl
 *           1998 Juergen Schmied <j.schmied@metronet.de>
 *           2000 Eric Kohl for CodeWeavers
7
 * Copyright 2002 Jon Griffiths
8 9 10 11 12 13 14 15 16 17 18 19 20
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
21
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 23 24 25 26 27 28 29 30 31 32 33
 *
 */

#include <stdarg.h>
#include <string.h>
#include <stdlib.h> /* atoi */

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winnls.h"

34
#include "comctl32.h"
35 36 37 38
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(commctrl);

39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
/**************************************************************************
 * Str_GetPtrA [COMCTL32.233]
 *
 * Copies a string into a destination buffer.
 *
 * PARAMS
 *     lpSrc   [I] Source string
 *     lpDest  [O] Destination buffer
 *     nMaxLen [I] Size of buffer in characters
 *
 * RETURNS
 *     The number of characters copied.
 */
INT WINAPI Str_GetPtrA (LPCSTR lpSrc, LPSTR lpDest, INT nMaxLen)
{
    INT len;

    TRACE("(%p %p %d)\n", lpSrc, lpDest, nMaxLen);

58 59
    if ((!lpDest || nMaxLen == 0) && lpSrc)
        return (strlen(lpSrc) + 1);
60 61 62 63 64 65 66 67 68

    if (nMaxLen == 0)
        return 0;

    if (lpSrc == NULL) {
        lpDest[0] = '\0';
        return 0;
    }

69
    len = strlen(lpSrc) + 1;
70
    if (len >= nMaxLen)
71
        len = nMaxLen;
72

73 74
    RtlMoveMemory (lpDest, lpSrc, len - 1);
    lpDest[len - 1] = '\0';
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107

    return len;
}

/**************************************************************************
 * Str_SetPtrA [COMCTL32.234]
 *
 * Makes a copy of a string, allocating memory if necessary.
 *
 * PARAMS
 *     lppDest [O] Pointer to destination string
 *     lpSrc   [I] Source string
 *
 * RETURNS
 *     Success: TRUE
 *     Failure: FALSE
 *
 * NOTES
 *     Set lpSrc to NULL to free the memory allocated by a previous call
 *     to this function.
 */
BOOL WINAPI Str_SetPtrA (LPSTR *lppDest, LPCSTR lpSrc)
{
    TRACE("(%p %p)\n", lppDest, lpSrc);

    if (lpSrc) {
        LPSTR ptr = ReAlloc (*lppDest, strlen (lpSrc) + 1);
        if (!ptr)
            return FALSE;
        strcpy (ptr, lpSrc);
        *lppDest = ptr;
    }
    else {
108 109
        Free (*lppDest);
        *lppDest = NULL;
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
    }

    return TRUE;
}

/**************************************************************************
 * Str_GetPtrW [COMCTL32.235]
 *
 * See Str_GetPtrA.
 */
INT WINAPI Str_GetPtrW (LPCWSTR lpSrc, LPWSTR lpDest, INT nMaxLen)
{
    INT len;

    TRACE("(%p %p %d)\n", lpSrc, lpDest, nMaxLen);

    if (!lpDest && lpSrc)
127
        return lstrlenW (lpSrc);
128 129 130 131 132

    if (nMaxLen == 0)
        return 0;

    if (lpSrc == NULL) {
133
        lpDest[0] = '\0';
134 135 136
        return 0;
    }

137
    len = lstrlenW (lpSrc);
138 139 140 141
    if (len >= nMaxLen)
        len = nMaxLen - 1;

    RtlMoveMemory (lpDest, lpSrc, len*sizeof(WCHAR));
142
    lpDest[len] = '\0';
143 144 145 146 147 148 149 150 151 152 153

    return len;
}

/**************************************************************************
 * Str_SetPtrW [COMCTL32.236]
 *
 * See Str_SetPtrA.
 */
BOOL WINAPI Str_SetPtrW (LPWSTR *lppDest, LPCWSTR lpSrc)
{
154
    TRACE("(%p %s)\n", lppDest, debugstr_w(lpSrc));
155 156

    if (lpSrc) {
157
        INT len = lstrlenW (lpSrc) + 1;
158 159 160
        LPWSTR ptr = ReAlloc (*lppDest, len * sizeof(WCHAR));
        if (!ptr)
            return FALSE;
161
        lstrcpyW (ptr, lpSrc);
162 163 164
        *lppDest = ptr;
    }
    else {
165 166
        Free (*lppDest);
        *lppDest = NULL;
167 168 169 170 171
    }

    return TRUE;
}

172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
/*************************************************************************
 * IntlStrEqWorkerA	[COMCTL32.376]
 *
 * Compare two strings.
 *
 * PARAMS
 *  bCase    [I] Whether to compare case sensitively
 *  lpszStr  [I] First string to compare
 *  lpszComp [I] Second string to compare
 *  iLen     [I] Length to compare
 *
 * RETURNS
 *  TRUE  If the strings are equal.
 *  FALSE Otherwise.
 */
BOOL WINAPI IntlStrEqWorkerA(BOOL bCase, LPCSTR lpszStr, LPCSTR lpszComp,
                             int iLen)
{
190
  DWORD dwFlags;
191 192 193 194 195
  int iRet;

  TRACE("(%d,%s,%s,%d)\n", bCase,
        debugstr_a(lpszStr), debugstr_a(lpszComp), iLen);

196
  /* FIXME: This flag is undocumented and unknown by our CompareString.
197
   */
198
  dwFlags = LOCALE_RETURN_GENITIVE_NAMES;
199
  if (!bCase) dwFlags |= NORM_IGNORECASE;
200 201 202 203 204 205 206

  iRet = CompareStringA(GetThreadLocale(),
                        dwFlags, lpszStr, iLen, lpszComp, iLen);

  if (!iRet)
    iRet = CompareStringA(2048, dwFlags, lpszStr, iLen, lpszComp, iLen);

207
  return iRet == CSTR_EQUAL;
208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
}

/*************************************************************************
 * IntlStrEqWorkerW	[COMCTL32.377]
 *
 * See IntlStrEqWorkerA.
 */
BOOL WINAPI IntlStrEqWorkerW(BOOL bCase, LPCWSTR lpszStr, LPCWSTR lpszComp,
                             int iLen)
{
  DWORD dwFlags;
  int iRet;

  TRACE("(%d,%s,%s,%d)\n", bCase,
        debugstr_w(lpszStr),debugstr_w(lpszComp), iLen);
223

224
  /* FIXME: This flag is undocumented and unknown by our CompareString.
225
   */
226
  dwFlags = LOCALE_RETURN_GENITIVE_NAMES;
227
  if (!bCase) dwFlags |= NORM_IGNORECASE;
228

229 230
  iRet = CompareStringW(GetThreadLocale(),
                        dwFlags, lpszStr, iLen, lpszComp, iLen);
231

232 233
  if (!iRet)
    iRet = CompareStringW(2048, dwFlags, lpszStr, iLen, lpszComp, iLen);
234

235
  return iRet == CSTR_EQUAL;
236
}