/* $Id$ Part of SWI-Prolog Author: Jan Wielemaker E-mail: J.Wielemaker@uva.nl WWW: http://www.swi-prolog.org Copyright (C): 1985-2011, University of Amsterdam 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 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "pl-incl.h" #include "pl-string.h" #include "pl-ctype.h" /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String operations that are needed for the shared IO library. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /******************************* * ALLOCATION * *******************************/ #ifdef O_DEBUG #define CHAR_INUSE 0x42 #define CHAR_FREED 0x41 char * store_string(const char *s) { if ( s ) { GET_LD char *copy = (char *)allocHeap(strlen(s)+2); *copy++ = CHAR_INUSE; strcpy(copy, s); return copy; } else { return NULL; } } void remove_string(char *s) { if ( s ) { GET_LD assert(s[-1] == CHAR_INUSE); s[-1] = CHAR_FREED; freeHeap(s-1, strlen(s)+2); } } #else /*O_DEBUG*/ char * store_string(const char *s) { if ( s ) { GET_LD char *copy = (char *)allocHeap(strlen(s)+1); strcpy(copy, s); return copy; } else { return NULL; } } void remove_string(char *s) { if ( s ) { GET_LD freeHeap(s, strlen(s)+1); } } #endif /*O_DEBUG*/ /******************************* * NUMBERS * *******************************/ /* Return the character representing some digit. ** Fri Jun 10 10:45:40 1988 jan@swivax.UUCP (Jan Wielemaker) */ char digitName(int n, int smll) { if (n <= 9) return n + '0'; return n + (smll ? 'a' : 'A') - 10; } /* Return the value of a digit when transforming a number of base 'b'. Return '-1' if it is an illegal digit. ** Fri Jun 10 10:46:40 1988 jan@swivax.UUCP (Jan Wielemaker) */ int digitValue(int b, int c) { int v; if ( b == 0 ) return c; /* 0'c */ if ( b == 1 ) return -1; if ( b <= 10 ) { v = c - '0'; if ( v < b ) return v; return -1; } if ( c <= '9' ) return c - '0'; if (isUpper(c)) c = toLower(c); c = c - 'a' + 10; if ( c < b && c >= 10 ) return c; return -1; } /******************************** * LESS COMMON BASIC FUNCTIONS * *********************************/ bool strprefix(const char *string, const char *prefix) { while(*prefix && *string == *prefix) prefix++, string++; if (*prefix == EOS ) succeed; fail; } bool strpostfix(const char *string, const char *postfix) { intptr_t offset = strlen(string) - strlen(postfix); if ( offset < 0 ) fail; return streq(&string[offset], postfix); } #ifndef HAVE_STRCASECMP int strcasecmp(const char *s1, const char *s2) { #ifdef HAVE_STRICMP return stricmp(s1, s2); #else while(*s1 && makeLower(*s1) == makeLower(*s2)) s1++, s2++; return makeLower(*s1) - makeLower(*s2); #endif } #endif #ifndef HAVE_STRLWR char * strlwr(char *s) { char *q; for(q=s; *q; q++) *q = makeLower(*q); return s; } #endif bool stripostfix(const char *s, const char *e) { size_t ls = strlen(s); size_t le = strlen(e); if ( ls >= le ) return strcasecmp(&s[ls-le], e) == 0; return FALSE; } /******************************* * MULTIBYTE STRINGS * *******************************/ typedef struct { wchar_t *wcp; int len; int malloced; } wbuf; #if !defined(HAVE_MBSCOLL) || !defined(HAVE_MBCASESCOLL) static void wstolower(wchar_t *w, size_t len) { wchar_t *e = &w[len]; for( ; w