123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589 |
- /*
- * CDE - Common Desktop Environment
- *
- * Copyright (c) 1993-2012, The Open Group. All rights reserved.
- *
- * These libraries and programs are free software; you can
- * redistribute them and/or modify them under the terms of the GNU
- * Lesser General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * These libraries and programs are distributed in the hope that
- * they 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 these libraries and programs; if not, write
- * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
- * Floor, Boston, MA 02110-1301 USA
- */
- /* $XConsortium: CvString.c /main/4 1996/08/30 15:28:00 cde-hp $ */
- /************************************<+>*************************************
- ****************************************************************************
- **
- ** File: CvString.c
- **
- ** Project: Cde DtHelp
- **
- ** Description: Semi private string functions - can be platform dependent.
- ** These routines are straight C code. They do not require
- ** includes to know about the Canvas Engine, the Help
- ** dialogs or anything else.
- **
- **
- ** (c) Copyright 1987, 1988, 1989, 1990, 1991, 1992 Hewlett-Packard Company
- **
- ** (c) Copyright 1993, 1994 Hewlett-Packard Company
- ** (c) Copyright 1993, 1994 International Business Machines Corp.
- ** (c) Copyright 1993, 1994 Sun Microsystems, Inc.
- ** (c) Copyright 1993, 1994 Novell, Inc.
- **
- **
- **
- ****************************************************************************
- ************************************<+>*************************************/
- /*
- * system includes
- */
- #include <stdlib.h>
- #include <string.h>
- /*
- * private includes
- */
- #include "CvStringI.h"
- /******************************************************************************
- *
- * Private variables and defines.
- *
- *****************************************************************************/
- #define REALLOC_INCR 10
- /******************************************************************************
- *
- * Semi Public Functions
- *
- *****************************************************************************/
- /******************************************************************************
- * Function: _DtCvStrLen (const void *p1, int type)
- *
- * Paramenters:
- * p1 Specifies the string or wide char array to process.
- * type Specifies the type p1 is. 0 indicaates a string.
- * non-zero indicates a wide char array.
- * Returns:
- * >= 0 If p1 is non-null.
- * -1 If p1 is null.
- *
- * Purpose:
- * Returns in number of characters in p1.
- *
- *****************************************************************************/
- int
- _DtCvStrLen (
- const void *p1,
- int type )
- {
- int len = 0;
- const wchar_t *wcs;
- if (0 == type)
- return (strlen((const char *) p1));
- wcs = (wchar_t *) p1;
- while (0 != *wcs)
- {
- wcs++;
- len++;
- }
- return len;
- }
- /******************************************************************************
- * Function: _DtCvStrPtr (const void *p1, int type, int count)
- *
- * Paramenters:
- * p1 Specifies the string or wide char array to process.
- * type Specifies the type p1 is. 0 indicaates a string.
- * non-zero indicates a wide char array.
- * count Specifies an index into p1.
- * Returns:
- * ptr If everything works okay.
- * NULL If problems.
- *
- * Purpose:
- * Get to a point in the wide character or char string.
- *
- *****************************************************************************/
- void *
- _DtCvStrPtr (
- const void *p1,
- int type,
- int count)
- {
- if (0 == type)
- return ((void *) (((char *) p1) + count));
- return ((void *) (((wchar_t *) p1) + count));
- }
- /******************************************************************************
- * Function: _DtCvChar (const void *p1, int type, int count)
- *
- * Paramenters:
- * p1 Specifies the string or wide char array to process.
- * type Specifies the type p1 is. 0 indicaates a string.
- * non-zero indicates a wide char array.
- * count Specifies an index into p1.
- * Returns:
- * value If everything works okay.
- * (wchar_t) -1 If problems.
- *
- * Purpose:
- * Get a character value.
- *
- *****************************************************************************/
- wchar_t
- _DtCvChar (
- const void *p1,
- int type,
- int count)
- {
- int i, len;
- char *ptr;
- char str[MB_CUR_MAX];
- wchar_t value;
- if (0 == type) {
- ptr = (char *) p1 + count;
- if (MB_CUR_MAX > 1) {
- len = mbtowc(&value, ptr, MB_CUR_MAX);
- if (len == -1) {
- for (i = 1; i < MB_CUR_MAX; ++i) {
- ptr -= i;
- if (ptr < (char *) p1) {
- len = -1;
- break;
- }
- len = mbtowc(&value, ptr, MB_CUR_MAX);
- if (len == -1) continue;
- }
- if (len == -1) value = (wchar_t) -1;
- }
- }
- else value = *ptr;
- }
- else value = *(((wchar_t *) p1) + count);
- return (value);
- }
- /******************************************************************************
- * Function: _DtCvStrcspn (const void *s1, const char *s2, type, &ret_len)
- *
- * Returns in 'ret_len' the length of the initial segment of string
- * s1 which consists entirely of characters not found in string s2.
- *
- * if type is 0, then s1 is a char* string.
- * if type is not 0, then s1 is a wchar_t* string.
- *
- * s2 cannot be more than 15 characters if looking a wide character
- * string in s1.
- *
- * Returns:
- * -1 If found an invalid character.
- * 0 If found a character in string s2
- * 1 If found the null byte character.
- * 2 s2 contained more than 15 characters, but found one of the
- * first fifteen characters in string s2.
- * 3 s2 contained more than 15 characters, and didn't find any
- * of the first fifteen characters in string s2.
- *****************************************************************************/
- int
- _DtCvStrcspn (
- const void *s1,
- const char *s2,
- int type,
- int *ret_len )
- {
- int i, len1, len2;
- char *p1, *p2;
- size_t num;
- wchar_t widec[16];
- const wchar_t *wcp;
- const wchar_t *wcp2;
- if (NULL == s1)
- {
- *ret_len = 0;
- return 0;
- }
- if ((0 == type && '\0' == *((char *) s1)) ||
- (0 != type && 0 == *((wchar_t *) s1)))
- {
- *ret_len = 0;
- return 1;
- }
- if (NULL == s2 || '\0' == *s2)
- {
- *ret_len = _DtCvStrLen (s1, type);
- return 1;
- }
- if (0 == type)
- {
- if (MB_CUR_MAX > 1) {
- p1 = (char *) s1;
- while (*p1) {
- len1 = mblen(p1, MB_CUR_MAX);
- if (len1 == -1) {
- ++p1;
- continue;
- }
- p2 = (char *) s2;
- while (*p2) {
- len2 = mblen(p2, MB_CUR_MAX);
- if (len2 == -1) {
- ++p2;
- continue;
- }
- if (len1 == len2) {
- for (i = 0; i < len2; ++i) if (p1[i] != p2[i]) break;
- if (i == len2) {
- *ret_len = p1 - (char *) s1;
- return 0;
- }
- }
- p2 += len2;
- }
- p1 += len1;
- }
- *ret_len = p1 - (char *) s1;
- return 1;
- }
- else {
- /*
- * no need to go through any hassle, just use the 3C function
- */
- *ret_len = strcspn ((char *) s1, s2);
- if ('\0' == ((char *) s1)[*ret_len])
- return 1;
- return 0;
- }
- }
- /*
- * convert the test string into a wide char array
- */
- num = mbstowcs(widec, s2, 16);
- if ((size_t) -1 == num)
- return -1;
- /*
- * force a null termination of the array
- */
- widec[15] = 0;
- /*
- * if greater than 15 characters were converted, set the flag to 2
- */
- num = ((num > 15) ? 2 : 0);
- wcp = s1;
- while (0 != *wcp)
- {
- wcp2 = widec;
- while (0 != *wcp2)
- {
- if (*wcp2 == *wcp)
- {
- *ret_len = wcp - (wchar_t *) s1;
- return 0 + num;
- }
- wcp2++;
- }
- wcp++;
- }
- *ret_len = wcp - (wchar_t *) s1;
- return 1 + num;
- }
- /****************************************************************************
- * Function: void **_DtCvAddPtrToArray (void **array, void *ptr)
- *
- * Parameters: array A pointer to a NULL-terminated array
- * of pointers.
- * ptr The pointer which is to be added to
- * the end of the array.
- *
- * Returns: A pointer to the NULL-terminated array created
- * by adding 'ptr' to the end of 'array'.
- *
- * Purpose: Add a new element to a NULL-terminated array of pointers.
- * These are typed as "void *" so that they can be used with
- * pointers to any type of data.
- *
- ****************************************************************************/
- void **
- _DtCvAddPtrToArray (
- void **array,
- void *ptr)
- {
- void **nextP = NULL;
- int numElements;
- /* If this is the first item for the array, malloc the array and set
- nextP to point to the first element. */
- if (array == NULL || *array == NULL) {
- array = (void **) malloc (REALLOC_INCR * sizeof (void *));
- nextP = array;
- }
- else {
- /* Find the NULL pointer at the end of the array. */
- numElements = 0;
- for (nextP = array; *nextP != NULL; nextP++)
- numElements++;
- /* The array always grows by chunks of size REALLOC_INCR. So see if
- it currently is an exact multiple of REALLOC_INCR size (remember to
- count the NULL pointer). If it is then it must be full, so realloc
- another chunk. Also remember to move 'nextP' because the array
- will probably move in memory. */
- if ((numElements + 1) % REALLOC_INCR == 0) {
- array = (void **) realloc (array,
- (numElements + 1 + REALLOC_INCR) * sizeof (void *));
- if (array)
- nextP = array + numElements;
- else
- nextP = NULL;
- }
- }
- if (nextP)
- {
- *nextP++ = ptr;
- *nextP = NULL;
- }
- return (array);
- }
- /******************************************************************************
- * Function: int _DtCvFreeArray (void **array)
- *
- * Parameters: array A pointer to the NULL-terminated
- * string array which is to be freed.
- *
- * Return Value: 0 if successful, -1 if a failure occurs
- *
- * Purpose: Free the memory used for a NULL-terminated string array.
- *
- ******************************************************************************/
- int
- _DtCvFreeArray (void **array)
- {
- void **next;
- if (array == NULL)
- return -1;
- for (next = array; *next != NULL; next++)
- free (*next);
- free (array);
- return (0);
- }
- #if defined(_AIX)
- /*****************************************************************************
- * Function: _DtCvStrCaseCmp
- *
- * Parameters:
- *
- * Return Value:
- *
- * Purpose: IBM does not support the 'strcasecmp' routine. This takes it's
- * place.
- *****************************************************************************/
- int
- _DtCvStrCaseCmp (
- const char *s1,
- const char *s2)
- {
- int c1;
- int c2;
- int result = 0;
- if (s1 == s2) return 0;
- if (NULL == s1) return -1;
- if (NULL == s2) return 1;
- while (result == 0 && *s1 != '\0' && *s2 != '\0')
- {
- c1 = (unsigned char) *s1;
- c2 = (unsigned char) *s2;
- if (isupper(c1))
- c1 = _tolower(c1);
- if (isupper(c2))
- c2 = _tolower(c2);
- result = c1 - c2;
- s1++;
- s2++;
- }
- if (result == 0 && (*s1 != '\0' || *s2 != '\0'))
- {
- c1 = (unsigned char) *s1;
- c2 = (unsigned char) *s2;
- if (isupper(c1))
- c1 = _tolower(c1);
- if (isupper(c2))
- c2 = _tolower(c2);
- result = c1 - c2;
- }
- return result;
- }
- #endif /* _AIX */
- /*****************************************************************************
- * Function: _DtCvStrNCaseCmpLatin1()
- *
- * Purpose: Does not use the tolower() functions to determine the lower
- * case of a character. On some platforms, using tolower() on
- * the upper case of a typical Latin1 character does not match
- * it's Latin1 one lower case.
- *
- * This routine is to be used only when we want to map strict
- * Latin1 characters to it's lower case. I.e. when we -know-
- * the data is in English.
- *****************************************************************************/
- int
- _DtCvStrNCaseCmpLatin1 (
- const char *s1,
- const char *s2,
- size_t n)
- {
- int c1;
- int c2;
- int result = 0;
- if (s1 == s2 || n < 1) return 0;
- if (NULL == s1) return -1;
- if (NULL == s2) return 1;
- while (result == 0 && *s1 != '\0' && *s2 != '\0' && n > 0)
- {
- c1 = (unsigned char) *s1;
- c2 = (unsigned char) *s2;
- c1 = _DtCvToLower(c1);
- c2 = _DtCvToLower(c2);
- result = c1 - c2;
- s1++;
- s2++;
- n--;
- }
- if (result == 0 && n > 0 && (*s1 != '\0' || *s2 != '\0'))
- {
- c1 = (unsigned char) *s1;
- c2 = (unsigned char) *s2;
- c1 = _DtCvToLower(c1);
- c2 = _DtCvToLower(c2);
- result = c1 - c2;
- }
- return result;
- }
- /*****************************************************************************
- * Function: _DtCvStrCaseCmpLatin1
- *
- * Purpose: Does not use the tolower() functions to determine the lower
- * case of a character. On some platforms, using tolower() on
- * the upper case of a typical Latin1 character does not match
- * it's Latin1 one lower case.
- *
- * This routine is to be used only when we want to map strict
- * Latin1 characters to it's lower case. I.e. when we -know-
- * the data is in English.
- *****************************************************************************/
- int
- _DtCvStrCaseCmpLatin1 (
- const char *s1,
- const char *s2)
- {
- int c1;
- int c2;
- int result = 0;
- if (s1 == s2) return 0;
- if (NULL == s1) return -1;
- if (NULL == s2) return 1;
- while (result == 0 && *s1 != '\0' && *s2 != '\0')
- {
- c1 = (unsigned char) *s1;
- c2 = (unsigned char) *s2;
- c1 = _DtCvToLower(c1);
- c2 = _DtCvToLower(c2);
- result = c1 - c2;
- s1++;
- s2++;
- }
- if (result == 0 && (*s1 != '\0' || *s2 != '\0'))
- {
- c1 = (unsigned char) *s1;
- c2 = (unsigned char) *s2;
- c1 = _DtCvToLower(c1);
- c2 = _DtCvToLower(c2);
- result = c1 - c2;
- }
- return result;
- }
|