]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - cups/string.c
License change: Apache License, Version 2.0.
[thirdparty/cups.git] / cups / string.c
index 9e60076a2c85331ad1db86e9b7117dfbe5f85c33..5d5c3bff70e8febfcdc8b10d255055254b1474df 100644 (file)
@@ -1,60 +1,28 @@
 /*
- * "$Id: string.c 7460 2008-04-16 02:19:54Z mike $"
+ * String functions for CUPS.
  *
- *   String functions for CUPS.
+ * Copyright 2007-2014 by Apple Inc.
+ * Copyright 1997-2007 by Easy Software Products.
  *
- *   Copyright 2007-2010 by Apple Inc.
- *   Copyright 1997-2007 by Easy Software Products.
- *
- *   These coded instructions, statements, and computer programs are the
- *   property of Apple Inc. and are protected by Federal copyright
- *   law.  Distribution and use rights are outlined in the file "LICENSE.txt"
- *   which should have been included with this file.  If this file is
- *   file is missing or damaged, see the license at "http://www.cups.org/".
- *
- *   This file is subject to the Apple OS-Developed Software exception.
- *
- * Contents:
- *
- *   _cupsStrAlloc()      - Allocate/reference a string.
- *   _cupsStrFlush()      - Flush the string pool.
- *   _cupsStrFormatd()    - Format a floating-point number.
- *   _cupsStrFree()       - Free/dereference a string.
- *   _cupsStrRetain()     - Increment the reference count of a string.
- *   _cupsStrScand()      - Scan a string for a floating-point number.
- *   _cupsStrStatistics() - Return allocation statistics for string pool.
- *   _cups_strcpy()       - Copy a string allowing for overlapping strings.
- *   _cups_strdup()       - Duplicate a string.
- *   _cups_strcasecmp()   - Do a case-insensitive comparison.
- *   _cups_strncasecmp()  - Do a case-insensitive comparison on up to N chars.
- *   _cups_strlcat()      - Safely concatenate two strings.
- *   _cups_strlcpy()      - Safely copy two strings.
- *   compare_sp_items()   - Compare two string pool items...
+ * Licensed under Apache License v2.0.  See the file "LICENSE" for more information.
  */
 
 /*
  * Include necessary headers...
  */
 
-#include "string-private.h"
-#include "debug-private.h"
-#include "array.h"
-#include <stdlib.h>
+#define _CUPS_STRING_C_
+#include "cups-private.h"
 #include <stddef.h>
 #include <limits.h>
-#ifdef HAVE_PTHREAD_H
-#  include <pthread.h>
-#endif /* HAVE_PTHREAD_H */
 
 
 /*
  * Local globals...
  */
 
-#ifdef HAVE_PTHREAD_H
-static pthread_mutex_t sp_mutex = PTHREAD_MUTEX_INITIALIZER;
+static _cups_mutex_t   sp_mutex = _CUPS_MUTEX_INITIALIZER;
                                        /* Mutex to control access to pool */
-#endif /* HAVE_PTHREAD_H */
 static cups_array_t    *stringpool = NULL;
                                        /* Global string pool */
 
@@ -73,6 +41,7 @@ static int    compare_sp_items(_cups_sp_item_t *a, _cups_sp_item_t *b);
 char *                                 /* O - String pointer */
 _cupsStrAlloc(const char *s)           /* I - String */
 {
+  size_t               slen;           /* Length of string */
   _cups_sp_item_t      *item,          /* String pool item */
                        *key;           /* Search key */
 
@@ -88,18 +57,14 @@ _cupsStrAlloc(const char *s)                /* I - String */
   * Get the string pool...
   */
 
-#ifdef HAVE_PTHREAD_H
-  pthread_mutex_lock(&sp_mutex);
-#endif /* HAVE_PTHREAD_H */
+  _cupsMutexLock(&sp_mutex);
 
   if (!stringpool)
     stringpool = cupsArrayNew((cups_array_func_t)compare_sp_items, NULL);
 
   if (!stringpool)
   {
-#ifdef HAVE_PTHREAD_H
-    pthread_mutex_unlock(&sp_mutex);
-#endif /* HAVE_PTHREAD_H */
+    _cupsMutexUnlock(&sp_mutex);
 
     return (NULL);
   }
@@ -127,9 +92,7 @@ _cupsStrAlloc(const char *s)         /* I - String */
       abort();
 #endif /* DEBUG_GUARDS */
 
-#ifdef HAVE_PTHREAD_H
-    pthread_mutex_unlock(&sp_mutex);
-#endif /* HAVE_PTHREAD_H */
+    _cupsMutexUnlock(&sp_mutex);
 
     return (item->str);
   }
@@ -138,18 +101,17 @@ _cupsStrAlloc(const char *s)              /* I - String */
   * Not found, so allocate a new one...
   */
 
-  item = (_cups_sp_item_t *)calloc(1, sizeof(_cups_sp_item_t) + strlen(s));
+  slen = strlen(s);
+  item = (_cups_sp_item_t *)calloc(1, sizeof(_cups_sp_item_t) + slen);
   if (!item)
   {
-#ifdef HAVE_PTHREAD_H
-    pthread_mutex_unlock(&sp_mutex);
-#endif /* HAVE_PTHREAD_H */
+    _cupsMutexUnlock(&sp_mutex);
 
     return (NULL);
   }
 
   item->ref_count = 1;
-  strcpy(item->str, s);
+  memcpy(item->str, s, slen + 1);
 
 #ifdef DEBUG_GUARDS
   item->guard = _CUPS_STR_GUARD;
@@ -165,14 +127,45 @@ _cupsStrAlloc(const char *s)              /* I - String */
 
   cupsArrayAdd(stringpool, item);
 
-#ifdef HAVE_PTHREAD_H
-  pthread_mutex_unlock(&sp_mutex);
-#endif /* HAVE_PTHREAD_H */
+  _cupsMutexUnlock(&sp_mutex);
 
   return (item->str);
 }
 
 
+/*
+ * '_cupsStrDate()' - Return a localized date for a given time value.
+ *
+ * This function works around the locale encoding issues of strftime...
+ */
+
+char *                                 /* O - Buffer */
+_cupsStrDate(char   *buf,              /* I - Buffer */
+             size_t bufsize,           /* I - Size of buffer */
+            time_t timeval)            /* I - Time value */
+{
+  struct tm    *dateval;               /* Local date/time */
+  char         temp[1024];             /* Temporary buffer */
+  _cups_globals_t *cg = _cupsGlobals();        /* Per-thread globals */
+
+
+  if (!cg->lang_default)
+    cg->lang_default = cupsLangDefault();
+
+  dateval = localtime(&timeval);
+
+  if (cg->lang_default->encoding != CUPS_UTF8)
+  {
+    strftime(temp, sizeof(temp), "%c", dateval);
+    cupsCharsetToUTF8((cups_utf8_t *)buf, temp, (int)bufsize, cg->lang_default->encoding);
+  }
+  else
+    strftime(buf, bufsize, "%c", dateval);
+
+  return (buf);
+}
+
+
 /*
  * '_cupsStrFlush()' - Flush the string pool.
  */
@@ -186,9 +179,7 @@ _cupsStrFlush(void)
   DEBUG_printf(("4_cupsStrFlush: %d strings in array",
                 cupsArrayCount(stringpool)));
 
-#ifdef HAVE_PTHREAD_H
-  pthread_mutex_lock(&sp_mutex);
-#endif /* HAVE_PTHREAD_H */
+  _cupsMutexLock(&sp_mutex);
 
   for (item = (_cups_sp_item_t *)cupsArrayFirst(stringpool);
        item;
@@ -198,9 +189,7 @@ _cupsStrFlush(void)
   cupsArrayDelete(stringpool);
   stringpool = NULL;
 
-#ifdef HAVE_PTHREAD_H
-  pthread_mutex_unlock(&sp_mutex);
-#endif /* HAVE_PTHREAD_H */
+  _cupsMutexUnlock(&sp_mutex);
 }
 
 
@@ -276,7 +265,7 @@ _cupsStrFormatd(char         *buf,  /* I - String */
   }
   else
   {
-    strlcpy(buf, temp, bufend - buf + 1);
+    strlcpy(buf, temp, (size_t)(bufend - buf + 1));
     bufptr = buf + strlen(buf);
   }
 
@@ -317,9 +306,7 @@ _cupsStrFree(const char *s)         /* I - String to free */
   * See if the string is already in the pool...
   */
 
-#ifdef HAVE_PTHREAD_H
-  pthread_mutex_lock(&sp_mutex);
-#endif /* HAVE_PTHREAD_H */
+  _cupsMutexLock(&sp_mutex);
 
   key = (_cups_sp_item_t *)(s - offsetof(_cups_sp_item_t, str));
 
@@ -353,9 +340,7 @@ _cupsStrFree(const char *s)         /* I - String to free */
     }
   }
 
-#ifdef HAVE_PTHREAD_H
-  pthread_mutex_unlock(&sp_mutex);
-#endif /* HAVE_PTHREAD_H */
+  _cupsMutexUnlock(&sp_mutex);
 }
 
 
@@ -386,15 +371,11 @@ _cupsStrRetain(const char *s)             /* I - String to retain */
     }
 #endif /* DEBUG_GUARDS */
 
-#ifdef HAVE_PTHREAD_H
-    pthread_mutex_lock(&sp_mutex);
-#endif /* HAVE_PTHREAD_H */
+    _cupsMutexLock(&sp_mutex);
 
     item->ref_count ++;
 
-#ifdef HAVE_PTHREAD_H
-    pthread_mutex_unlock(&sp_mutex);
-#endif /* HAVE_PTHREAD_H */
+    _cupsMutexUnlock(&sp_mutex);
   }
 
   return ((char *)s);
@@ -428,7 +409,7 @@ _cupsStrScand(const char   *buf,    /* I - Pointer to number */
   * Skip leading whitespace...
   */
 
-  while (isspace(*buf & 255))
+  while (_cups_isspace(*buf))
     buf ++;
 
  /*
@@ -460,7 +441,7 @@ _cupsStrScand(const char   *buf,    /* I - Pointer to number */
 
     if (loc && loc->decimal_point)
     {
-      strlcpy(tempptr, loc->decimal_point, sizeof(temp) - (tempptr - temp));
+      strlcpy(tempptr, loc->decimal_point, sizeof(temp) - (size_t)(tempptr - temp));
       tempptr += strlen(tempptr);
     }
     else if (tempptr < (temp + sizeof(temp) - 1))
@@ -558,9 +539,7 @@ _cupsStrStatistics(size_t *alloc_bytes,     /* O - Allocated bytes */
   * Loop through strings in pool, counting everything up...
   */
 
-#ifdef HAVE_PTHREAD_H
-  pthread_mutex_lock(&sp_mutex);
-#endif /* HAVE_PTHREAD_H */
+  _cupsMutexLock(&sp_mutex);
 
   for (count = 0, abytes = 0, tbytes = 0,
            item = (_cups_sp_item_t *)cupsArrayFirst(stringpool);
@@ -572,14 +551,12 @@ _cupsStrStatistics(size_t *alloc_bytes,   /* O - Allocated bytes */
     */
 
     count  += item->ref_count;
-    len    = (strlen(item->str) + 8) & ~7;
+    len    = (strlen(item->str) + 8) & (size_t)~7;
     abytes += sizeof(_cups_sp_item_t) + len;
     tbytes += item->ref_count * len;
   }
 
-#ifdef HAVE_PTHREAD_H
-  pthread_mutex_unlock(&sp_mutex);
-#endif /* HAVE_PTHREAD_H */
+  _cupsMutexUnlock(&sp_mutex);
 
  /*
   * Return values...
@@ -601,7 +578,7 @@ _cupsStrStatistics(size_t *alloc_bytes,     /* O - Allocated bytes */
 
 void
 _cups_strcpy(char       *dst,          /* I - Destination string */
-            const char *src)           /* I - Source string */
+             const char *src)          /* I - Source string */
 {
   while (*src)
     *dst++ = *src++;
@@ -618,16 +595,18 @@ _cups_strcpy(char       *dst,             /* I - Destination string */
 char   *                               /* O - New string pointer */
 _cups_strdup(const char *s)            /* I - String to duplicate */
 {
-  char *t;                             /* New string pointer */
+  char         *t;                     /* New string pointer */
+  size_t       slen;                   /* Length of string */
 
 
-  if (s == NULL)
+  if (!s)
     return (NULL);
 
-  if ((t = malloc(strlen(s) + 1)) == NULL)
+  slen = strlen(s);
+  if ((t = malloc(slen + 1)) == NULL)
     return (NULL);
 
-  return (strcpy(t, s));
+  return (memcpy(t, s, slen + 1));
 }
 #endif /* !HAVE_STRDUP */
 
@@ -636,16 +615,15 @@ _cups_strdup(const char *s)               /* I - String to duplicate */
  * '_cups_strcasecmp()' - Do a case-insensitive comparison.
  */
 
-#ifndef HAVE_STRCASECMP
 int                            /* O - Result of comparison (-1, 0, or 1) */
 _cups_strcasecmp(const char *s,        /* I - First string */
-                const char *t) /* I - Second string */
+                 const char *t)        /* I - Second string */
 {
   while (*s != '\0' && *t != '\0')
   {
-    if (tolower(*s & 255) < tolower(*t & 255))
+    if (_cups_tolower(*s) < _cups_tolower(*t))
       return (-1);
-    else if (tolower(*s & 255) > tolower(*t & 255))
+    else if (_cups_tolower(*s) > _cups_tolower(*t))
       return (1);
 
     s ++;
@@ -659,13 +637,11 @@ _cups_strcasecmp(const char *s,   /* I - First string */
   else
     return (-1);
 }
-#endif /* !HAVE_STRCASECMP */
 
 /*
  * '_cups_strncasecmp()' - Do a case-insensitive comparison on up to N chars.
  */
 
-#ifndef HAVE_STRNCASECMP
 int                                    /* O - Result of comparison (-1, 0, or 1) */
 _cups_strncasecmp(const char *s,       /* I - First string */
                   const char *t,       /* I - Second string */
@@ -673,9 +649,9 @@ _cups_strncasecmp(const char *s,    /* I - First string */
 {
   while (*s != '\0' && *t != '\0' && n > 0)
   {
-    if (tolower(*s & 255) < tolower(*t & 255))
+    if (_cups_tolower(*s) < _cups_tolower(*t))
       return (-1);
-    else if (tolower(*s & 255) > tolower(*t & 255))
+    else if (_cups_tolower(*s) > _cups_tolower(*t))
       return (1);
 
     s ++;
@@ -692,7 +668,6 @@ _cups_strncasecmp(const char *s,    /* I - First string */
   else
     return (-1);
 }
-#endif /* !HAVE_STRNCASECMP */
 
 
 #ifndef HAVE_STRLCAT
@@ -714,10 +689,11 @@ _cups_strlcat(char       *dst,            /* O - Destination string */
   */
 
   dstlen = strlen(dst);
-  size   -= dstlen + 1;
 
-  if (!size)
-    return (dstlen);           /* No room, return immediately... */
+  if (size < (dstlen + 1))
+    return (dstlen);                   /* No room, return immediately... */
+
+  size -= dstlen + 1;
 
  /*
   * Figure out how much room is needed...
@@ -732,7 +708,7 @@ _cups_strlcat(char       *dst,              /* O - Destination string */
   if (srclen > size)
     srclen = size;
 
-  memcpy(dst + dstlen, src, srclen);
+  memmove(dst + dstlen, src, srclen);
   dst[dstlen + srclen] = '\0';
 
   return (dstlen + srclen);
@@ -768,7 +744,7 @@ _cups_strlcpy(char       *dst,              /* O - Destination string */
   if (srclen > size)
     srclen = size;
 
-  memcpy(dst, src, srclen);
+  memmove(dst, src, srclen);
   dst[srclen] = '\0';
 
   return (srclen);
@@ -786,8 +762,3 @@ compare_sp_items(_cups_sp_item_t *a,        /* I - First item */
 {
   return (strcmp(a->str, b->str));
 }
-
-
-/*
- * End of "$Id: string.c 7460 2008-04-16 02:19:54Z mike $".
- */