source: trunk/third/glib2/glib/gstrfuncs.c @ 21369

Revision 21369, 62.0 KB checked in by ghudson, 20 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r21368, which included commits to RCS files with non-trunk default branches.
Line 
1/* GLIB - Library of useful routines for C programming
2 * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
18 */
19
20/*
21 * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
22 * file for a list of people on the GLib Team.  See the ChangeLog
23 * files for a list of changes.  These files are distributed with
24 * GLib at ftp://ftp.gtk.org/pub/gtk/.
25 */
26
27/*
28 * MT safe
29 */
30
31#include "config.h"
32
33#define _GNU_SOURCE             /* For stpcpy */
34
35#include <stdarg.h>
36#include <stdio.h>
37#include <stdlib.h>
38#include <string.h>
39#include <locale.h>
40#include <errno.h>
41#include <ctype.h>              /* For tolower() */
42#if !defined (HAVE_STRSIGNAL) || !defined(NO_SYS_SIGLIST_DECL)
43#include <signal.h>
44#endif
45
46#include "glib.h"
47#include "gprintf.h"
48#include "gprintfint.h"
49
50#ifdef G_OS_WIN32
51#include <windows.h>
52#endif
53
54/* do not include <unistd.h> in this place since it
55 * interferes with g_strsignal() on some OSes
56 */
57
58static const guint16 ascii_table_data[256] = {
59  0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004,
60  0x004, 0x104, 0x104, 0x004, 0x104, 0x104, 0x004, 0x004,
61  0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004,
62  0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004,
63  0x140, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0,
64  0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0,
65  0x459, 0x459, 0x459, 0x459, 0x459, 0x459, 0x459, 0x459,
66  0x459, 0x459, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0,
67  0x0d0, 0x653, 0x653, 0x653, 0x653, 0x653, 0x653, 0x253,
68  0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253,
69  0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253,
70  0x253, 0x253, 0x253, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0,
71  0x0d0, 0x473, 0x473, 0x473, 0x473, 0x473, 0x473, 0x073,
72  0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073,
73  0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073,
74  0x073, 0x073, 0x073, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x004
75  /* the upper 128 are all zeroes */
76};
77
78const guint16 * const g_ascii_table = ascii_table_data;
79
80gchar*
81g_strdup (const gchar *str)
82{
83  gchar *new_str;
84  gsize length;
85
86  if (str)
87    {
88      length = strlen (str) + 1;
89      new_str = g_new (char, length);
90      memcpy (new_str, str, length);
91    }
92  else
93    new_str = NULL;
94
95  return new_str;
96}
97
98gpointer
99g_memdup (gconstpointer mem,
100          guint         byte_size)
101{
102  gpointer new_mem;
103
104  if (mem)
105    {
106      new_mem = g_malloc (byte_size);
107      memcpy (new_mem, mem, byte_size);
108    }
109  else
110    new_mem = NULL;
111
112  return new_mem;
113}
114
115gchar*
116g_strndup (const gchar *str,
117           gsize        n)   
118{
119  gchar *new_str;
120
121  if (str)
122    {
123      new_str = g_new (gchar, n + 1);
124      strncpy (new_str, str, n);
125      new_str[n] = '\0';
126    }
127  else
128    new_str = NULL;
129
130  return new_str;
131}
132
133gchar*
134g_strnfill (gsize length,     
135            gchar fill_char)
136{
137  gchar *str;
138
139  str = g_new (gchar, length + 1);
140  memset (str, (guchar)fill_char, length);
141  str[length] = '\0';
142
143  return str;
144}
145
146/**
147 * g_stpcpy:
148 * @dest: destination buffer.
149 * @src: source string.
150 *
151 * Copies a nul-terminated string into the dest buffer, include the
152 * trailing nul, and return a pointer to the trailing nul byte.
153 * This is useful for concatenating multiple strings together
154 * without having to repeatedly scan for the end.
155 *
156 * Return value: a pointer to trailing nul byte.
157 **/
158gchar *
159g_stpcpy (gchar       *dest,
160          const gchar *src)
161{
162#ifdef HAVE_STPCPY
163  g_return_val_if_fail (dest != NULL, NULL);
164  g_return_val_if_fail (src != NULL, NULL);
165  return stpcpy (dest, src);
166#else
167  register gchar *d = dest;
168  register const gchar *s = src;
169
170  g_return_val_if_fail (dest != NULL, NULL);
171  g_return_val_if_fail (src != NULL, NULL);
172  do
173    *d++ = *s;
174  while (*s++ != '\0');
175
176  return d - 1;
177#endif
178}
179
180gchar*
181g_strdup_vprintf (const gchar *format,
182                  va_list      args)
183{
184  gchar *string = NULL;
185
186  g_vasprintf (&string, format, args);
187
188  return string;
189}
190
191gchar*
192g_strdup_printf (const gchar *format,
193                 ...)
194{
195  gchar *buffer;
196  va_list args;
197
198  va_start (args, format);
199  buffer = g_strdup_vprintf (format, args);
200  va_end (args);
201
202  return buffer;
203}
204
205gchar*
206g_strconcat (const gchar *string1, ...)
207{
208  gsize   l;     
209  va_list args;
210  gchar   *s;
211  gchar   *concat;
212  gchar   *ptr;
213
214  if (!string1)
215    return NULL;
216
217  l = 1 + strlen (string1);
218  va_start (args, string1);
219  s = va_arg (args, gchar*);
220  while (s)
221    {
222      l += strlen (s);
223      s = va_arg (args, gchar*);
224    }
225  va_end (args);
226
227  concat = g_new (gchar, l);
228  ptr = concat;
229
230  ptr = g_stpcpy (ptr, string1);
231  va_start (args, string1);
232  s = va_arg (args, gchar*);
233  while (s)
234    {
235      ptr = g_stpcpy (ptr, s);
236      s = va_arg (args, gchar*);
237    }
238  va_end (args);
239
240  return concat;
241}
242
243/**
244 * g_strtod:
245 * @nptr:    the string to convert to a numeric value.
246 * @endptr:  if non-%NULL, it returns the character after
247 *           the last character used in the conversion.
248 *
249 * Converts a string to a #gdouble value.
250 * It calls the standard strtod() function to handle the conversion, but
251 * if the string is not completely converted it attempts the conversion
252 * again with g_ascii_strtod(), and returns the best match.
253 *
254 * This function should seldomly be used. The normal situation when reading
255 * numbers not for human consumption is to use g_ascii_strtod(). Only when
256 * you know that you must expect both locale formatted and C formatted numbers
257 * should you use this. Make sure that you don't pass strings such as comma
258 * separated lists of values, since the commas may be interpreted as a decimal
259 * point in some locales, causing unexpected results.
260 *
261 * Return value: the #gdouble value.
262 **/
263gdouble
264g_strtod (const gchar *nptr,
265          gchar      **endptr)
266{
267  gchar *fail_pos_1;
268  gchar *fail_pos_2;
269  gdouble val_1;
270  gdouble val_2 = 0;
271
272  g_return_val_if_fail (nptr != NULL, 0);
273
274  fail_pos_1 = NULL;
275  fail_pos_2 = NULL;
276
277  val_1 = strtod (nptr, &fail_pos_1);
278
279  if (fail_pos_1 && fail_pos_1[0] != 0)
280    val_2 = g_ascii_strtod (nptr, &fail_pos_2);
281
282  if (!fail_pos_1 || fail_pos_1[0] == 0 || fail_pos_1 >= fail_pos_2)
283    {
284      if (endptr)
285        *endptr = fail_pos_1;
286      return val_1;
287    }
288  else
289    {
290      if (endptr)
291        *endptr = fail_pos_2;
292      return val_2;
293    }
294}
295
296/**
297 * g_ascii_strtod:
298 * @nptr:    the string to convert to a numeric value.
299 * @endptr:  if non-%NULL, it returns the character after
300 *           the last character used in the conversion.
301 *
302 * Converts a string to a #gdouble value.
303 * This function behaves like the standard strtod() function
304 * does in the C locale. It does this without actually
305 * changing the current locale, since that would not be
306 * thread-safe.
307 *
308 * This function is typically used when reading configuration
309 * files or other non-user input that should be locale independent.
310 * To handle input from the user you should normally use the
311 * locale-sensitive system strtod() function.
312 *
313 * To convert from a #gdouble to a string in a locale-insensitive
314 * way, use g_ascii_dtostr().
315 *
316 * If the correct value would cause overflow, plus or minus %HUGE_VAL
317 * is returned (according to the sign of the value), and %ERANGE is
318 * stored in %errno. If the correct value would cause underflow,
319 * zero is returned and %ERANGE is stored in %errno.
320 *
321 * This function resets %errno before calling strtod() so that
322 * you can reliably detect overflow and underflow.
323 *
324 * Return value: the #gdouble value.
325 **/
326gdouble
327g_ascii_strtod (const gchar *nptr,
328                gchar      **endptr)
329{
330  gchar *fail_pos;
331  gdouble val;
332  struct lconv *locale_data;
333  const char *decimal_point;
334  int decimal_point_len;
335  const char *p, *decimal_point_pos;
336  const char *end = NULL; /* Silence gcc */
337
338  g_return_val_if_fail (nptr != NULL, 0);
339
340  fail_pos = NULL;
341
342  locale_data = localeconv ();
343  decimal_point = locale_data->decimal_point;
344  decimal_point_len = strlen (decimal_point);
345
346  g_assert (decimal_point_len != 0);
347 
348  decimal_point_pos = NULL;
349  if (decimal_point[0] != '.' ||
350      decimal_point[1] != 0)
351    {
352      p = nptr;
353      /* Skip leading space */
354      while (g_ascii_isspace (*p))
355        p++;
356     
357      /* Skip leading optional sign */
358      if (*p == '+' || *p == '-')
359        p++;
360     
361      if (p[0] == '0' &&
362          (p[1] == 'x' || p[1] == 'X'))
363        {
364          p += 2;
365          /* HEX - find the (optional) decimal point */
366         
367          while (g_ascii_isxdigit (*p))
368            p++;
369         
370          if (*p == '.')
371            {
372              decimal_point_pos = p++;
373             
374              while (g_ascii_isxdigit (*p))
375                p++;
376             
377              if (*p == 'p' || *p == 'P')
378                p++;
379              if (*p == '+' || *p == '-')
380                p++;
381              while (g_ascii_isdigit (*p))
382                p++;
383            }
384        }
385      else
386        {
387          while (g_ascii_isdigit (*p))
388            p++;
389         
390          if (*p == '.')
391            {
392              decimal_point_pos = p++;
393             
394              while (g_ascii_isdigit (*p))
395                p++;
396             
397              if (*p == 'e' || *p == 'E')
398                p++;
399              if (*p == '+' || *p == '-')
400                p++;
401              while (g_ascii_isdigit (*p))
402                p++;
403            }
404        }
405      /* For the other cases, we need not convert the decimal point */
406      end = p;
407    }
408
409  /* Set errno to zero, so that we can distinguish zero results
410     and underflows */
411  errno = 0;
412 
413  if (decimal_point_pos)
414    {
415      char *copy, *c;
416
417      /* We need to convert the '.' to the locale specific decimal point */
418      copy = g_malloc (end - nptr + 1 + decimal_point_len);
419     
420      c = copy;
421      memcpy (c, nptr, decimal_point_pos - nptr);
422      c += decimal_point_pos - nptr;
423      memcpy (c, decimal_point, decimal_point_len);
424      c += decimal_point_len;
425      memcpy (c, decimal_point_pos + 1, end - (decimal_point_pos + 1));
426      c += end - (decimal_point_pos + 1);
427      *c = 0;
428
429      val = strtod (copy, &fail_pos);
430
431      if (fail_pos)
432        {
433          if (fail_pos - copy > decimal_point_pos - nptr)
434            fail_pos = (char *)nptr + (fail_pos - copy) - (decimal_point_len - 1);
435          else
436            fail_pos = (char *)nptr + (fail_pos - copy);
437        }
438     
439      g_free (copy);
440         
441    }
442  else if (decimal_point[0] != '.' ||
443           decimal_point[1] != 0)
444    {
445      char *copy;
446     
447      copy = g_malloc (end - (char *)nptr + 1);
448      memcpy (copy, nptr, end - nptr);
449      *(copy + (end - (char *)nptr)) = 0;
450     
451      val = strtod (copy, &fail_pos);
452     
453      if (fail_pos)
454        {
455          fail_pos = (char *)nptr + (fail_pos - copy);
456        }
457     
458      g_free (copy);
459    }
460  else
461    {
462      val = strtod (nptr, &fail_pos);
463    }
464
465  if (endptr)
466    *endptr = fail_pos;
467 
468  return val;
469}
470
471
472/**
473 * g_ascii_dtostr:
474 * @buffer: A buffer to place the resulting string in
475 * @buf_len: The length of the buffer.
476 * @d: The #gdouble to convert
477 *
478 * Converts a #gdouble to a string, using the '.' as
479 * decimal point.
480 *
481 * This functions generates enough precision that converting
482 * the string back using g_ascii_strtod() gives the same machine-number
483 * (on machines with IEEE compatible 64bit doubles). It is
484 * guaranteed that the size of the resulting string will never
485 * be larger than @G_ASCII_DTOSTR_BUF_SIZE bytes.
486 *
487 * Return value: The pointer to the buffer with the converted string.
488 **/
489gchar *
490g_ascii_dtostr (gchar       *buffer,
491                gint         buf_len,
492                gdouble      d)
493{
494  return g_ascii_formatd (buffer, buf_len, "%.17g", d);
495}
496
497/**
498 * g_ascii_formatd:
499 * @buffer: A buffer to place the resulting string in
500 * @buf_len: The length of the buffer.
501 * @format: The printf()-style format to use for the
502 *          code to use for converting.
503 * @d: The #gdouble to convert
504 *
505 * Converts a #gdouble to a string, using the '.' as
506 * decimal point. To format the number you pass in
507 * a printf()-style format string. Allowed conversion
508 * specifiers are 'e', 'E', 'f', 'F', 'g' and 'G'.
509 *
510 * If you just want to want to serialize the value into a
511 * string, use g_ascii_dtostr().
512 *
513 * Return value: The pointer to the buffer with the converted string.
514 **/
515gchar *
516g_ascii_formatd (gchar       *buffer,
517                 gint         buf_len,
518                 const gchar *format,
519                 gdouble      d)
520{
521  struct lconv *locale_data;
522  const char *decimal_point;
523  int decimal_point_len;
524  gchar *p;
525  int rest_len;
526  gchar format_char;
527
528  g_return_val_if_fail (buffer != NULL, NULL);
529  g_return_val_if_fail (format[0] == '%', NULL);
530  g_return_val_if_fail (strpbrk (format + 1, "'l%") == NULL, NULL);
531 
532  format_char = format[strlen (format) - 1];
533 
534  g_return_val_if_fail (format_char == 'e' || format_char == 'E' ||
535                        format_char == 'f' || format_char == 'F' ||
536                        format_char == 'g' || format_char == 'G',
537                        NULL);
538
539  if (format[0] != '%')
540    return NULL;
541
542  if (strpbrk (format + 1, "'l%"))
543    return NULL;
544
545  if (!(format_char == 'e' || format_char == 'E' ||
546        format_char == 'f' || format_char == 'F' ||
547        format_char == 'g' || format_char == 'G'))
548    return NULL;
549
550     
551  _g_snprintf (buffer, buf_len, format, d);
552
553  locale_data = localeconv ();
554  decimal_point = locale_data->decimal_point;
555  decimal_point_len = strlen (decimal_point);
556
557  g_assert (decimal_point_len != 0);
558
559  if (decimal_point[0] != '.' ||
560      decimal_point[1] != 0)
561    {
562      p = buffer;
563
564      if (*p == '+' || *p == '-')
565        p++;
566
567      while (isdigit ((guchar)*p))
568        p++;
569
570      if (strncmp (p, decimal_point, decimal_point_len) == 0)
571        {
572          *p = '.';
573          p++;
574          if (decimal_point_len > 1) {
575            rest_len = strlen (p + (decimal_point_len-1));
576            memmove (p, p + (decimal_point_len-1),
577                     rest_len);
578            p[rest_len] = 0;
579           
580          }
581        }
582    }
583 
584  return buffer;
585}
586
587/**
588 * g_ascii_strtoull:
589 * @nptr:    the string to convert to a numeric value.
590 * @endptr:  if non-%NULL, it returns the character after
591 *           the last character used in the conversion.
592 * @base:    to be used for the conversion, 2..36 or 0
593 *
594 * Converts a string to a #guint64 value.
595 * This function behaves like the standard strtoull() function
596 * does in the C locale. It does this without actually
597 * changing the current locale, since that would not be
598 * thread-safe.
599 *
600 * This function is typically used when reading configuration
601 * files or other non-user input that should be locale independent.
602 * To handle input from the user you should normally use the
603 * locale-sensitive system strtoull() function.
604 *
605 * If the correct value would cause overflow, %G_MAXUINT64
606 * is returned, and %ERANGE is stored in %errno.
607 *
608 * Return value: the #guint64 value.
609 *
610 * Since: 2.2
611 **/
612guint64
613g_ascii_strtoull (const gchar *nptr,
614                  gchar      **endptr,
615                  guint        base)
616{
617  /* this code is based on on the strtol(3) code from GNU libc released under
618   * the GNU Lesser General Public License.
619   *
620   * Copyright (C) 1991,92,94,95,96,97,98,99,2000,01,02
621   *        Free Software Foundation, Inc.
622   */
623#define ISSPACE(c)              ((c) == ' ' || (c) == '\f' || (c) == '\n' || \
624                                 (c) == '\r' || (c) == '\t' || (c) == '\v')
625#define ISUPPER(c)              ((c) >= 'A' && (c) <= 'Z')
626#define ISLOWER(c)              ((c) >= 'a' && (c) <= 'z')
627#define ISALPHA(c)              (ISUPPER (c) || ISLOWER (c))
628#define TOUPPER(c)              (ISLOWER (c) ? (c) - 'a' + 'A' : (c))
629#define TOLOWER(c)              (ISUPPER (c) ? (c) - 'A' + 'a' : (c))
630  gboolean negative, overflow;
631  guint64 cutoff;
632  guint64 cutlim;
633  guint64 ui64;
634  const gchar *s, *save;
635  guchar c;
636 
637  g_return_val_if_fail (nptr != NULL, 0);
638 
639  if (base == 1 || base > 36)
640    {
641      errno = EINVAL;
642      return 0;
643    }
644 
645  save = s = nptr;
646 
647  /* Skip white space.  */
648  while (ISSPACE (*s))
649    ++s;
650  if (!*s)
651    goto noconv;
652 
653  /* Check for a sign.  */
654  negative = FALSE;
655  if (*s == '-')
656    {
657      negative = TRUE;
658      ++s;
659    }
660  else if (*s == '+')
661    ++s;
662 
663  /* Recognize number prefix and if BASE is zero, figure it out ourselves.  */
664  if (*s == '0')
665    {
666      if ((base == 0 || base == 16) && TOUPPER (s[1]) == 'X')
667        {
668          s += 2;
669          base = 16;
670        }
671      else if (base == 0)
672        base = 8;
673    }
674  else if (base == 0)
675    base = 10;
676 
677  /* Save the pointer so we can check later if anything happened.  */
678  save = s;
679  cutoff = G_MAXUINT64 / base;
680  cutlim = G_MAXUINT64 % base;
681 
682  overflow = FALSE;
683  ui64 = 0;
684  c = *s;
685  for (; c; c = *++s)
686    {
687      if (c >= '0' && c <= '9')
688        c -= '0';
689      else if (ISALPHA (c))
690        c = TOUPPER (c) - 'A' + 10;
691      else
692        break;
693      if (c >= base)
694        break;
695      /* Check for overflow.  */
696      if (ui64 > cutoff || (ui64 == cutoff && c > cutlim))
697        overflow = TRUE;
698      else
699        {
700          ui64 *= base;
701          ui64 += c;
702        }
703    }
704 
705  /* Check if anything actually happened.  */
706  if (s == save)
707    goto noconv;
708 
709  /* Store in ENDPTR the address of one character
710     past the last character we converted.  */
711  if (endptr)
712    *endptr = (gchar*) s;
713 
714  if (overflow)
715    {
716      errno = ERANGE;
717      return G_MAXUINT64;
718    }
719 
720  /* Return the result of the appropriate sign.  */
721  return negative ? -ui64 : ui64;
722 
723 noconv:
724  /* We must handle a special case here: the base is 0 or 16 and the
725     first two characters are '0' and 'x', but the rest are no
726     hexadecimal digits.  This is no error case.  We return 0 and
727     ENDPTR points to the `x`.  */
728  if (endptr)
729    {
730      if (save - nptr >= 2 && TOUPPER (save[-1]) == 'X'
731          && save[-2] == '0')
732        *endptr = (gchar*) &save[-1];
733      else
734        /*  There was no number to convert.  */
735        *endptr = (gchar*) nptr;
736    }
737  return 0;
738}
739
740
741G_CONST_RETURN gchar*
742g_strerror (gint errnum)
743{
744  static GStaticPrivate msg_private = G_STATIC_PRIVATE_INIT;
745  char *msg;
746  int saved_errno = errno;
747
748#ifdef HAVE_STRERROR
749  const char *msg_locale;
750
751  msg_locale = strerror (errnum);
752  if (g_get_charset (NULL))
753    {
754      errno = saved_errno;
755      return msg_locale;
756    }
757  else
758    {
759      gchar *msg_utf8 = g_locale_to_utf8 (msg_locale, -1, NULL, NULL, NULL);
760      if (msg_utf8)
761        {
762          /* Stick in the quark table so that we can return a static result
763           */
764          GQuark msg_quark = g_quark_from_string (msg_utf8);
765          g_free (msg_utf8);
766         
767          msg_utf8 = (gchar *) g_quark_to_string (msg_quark);
768          errno = saved_errno;
769          return msg_utf8;
770        }
771    }
772#elif NO_SYS_ERRLIST
773  switch (errnum)
774    {
775#ifdef E2BIG
776    case E2BIG: return "argument list too long";
777#endif
778#ifdef EACCES
779    case EACCES: return "permission denied";
780#endif
781#ifdef EADDRINUSE
782    case EADDRINUSE: return "address already in use";
783#endif
784#ifdef EADDRNOTAVAIL
785    case EADDRNOTAVAIL: return "can't assign requested address";
786#endif
787#ifdef EADV
788    case EADV: return "advertise error";
789#endif
790#ifdef EAFNOSUPPORT
791    case EAFNOSUPPORT: return "address family not supported by protocol family";
792#endif
793#ifdef EAGAIN
794    case EAGAIN: return "try again";
795#endif
796#ifdef EALIGN
797    case EALIGN: return "EALIGN";
798#endif
799#ifdef EALREADY
800    case EALREADY: return "operation already in progress";
801#endif
802#ifdef EBADE
803    case EBADE: return "bad exchange descriptor";
804#endif
805#ifdef EBADF
806    case EBADF: return "bad file number";
807#endif
808#ifdef EBADFD
809    case EBADFD: return "file descriptor in bad state";
810#endif
811#ifdef EBADMSG
812    case EBADMSG: return "not a data message";
813#endif
814#ifdef EBADR
815    case EBADR: return "bad request descriptor";
816#endif
817#ifdef EBADRPC
818    case EBADRPC: return "RPC structure is bad";
819#endif
820#ifdef EBADRQC
821    case EBADRQC: return "bad request code";
822#endif
823#ifdef EBADSLT
824    case EBADSLT: return "invalid slot";
825#endif
826#ifdef EBFONT
827    case EBFONT: return "bad font file format";
828#endif
829#ifdef EBUSY
830    case EBUSY: return "mount device busy";
831#endif
832#ifdef ECHILD
833    case ECHILD: return "no children";
834#endif
835#ifdef ECHRNG
836    case ECHRNG: return "channel number out of range";
837#endif
838#ifdef ECOMM
839    case ECOMM: return "communication error on send";
840#endif
841#ifdef ECONNABORTED
842    case ECONNABORTED: return "software caused connection abort";
843#endif
844#ifdef ECONNREFUSED
845    case ECONNREFUSED: return "connection refused";
846#endif
847#ifdef ECONNRESET
848    case ECONNRESET: return "connection reset by peer";
849#endif
850#if defined(EDEADLK) && (!defined(EWOULDBLOCK) || (EDEADLK != EWOULDBLOCK))
851    case EDEADLK: return "resource deadlock avoided";
852#endif
853#ifdef EDEADLOCK
854    case EDEADLOCK: return "resource deadlock avoided";
855#endif
856#ifdef EDESTADDRREQ
857    case EDESTADDRREQ: return "destination address required";
858#endif
859#ifdef EDIRTY
860    case EDIRTY: return "mounting a dirty fs w/o force";
861#endif
862#ifdef EDOM
863    case EDOM: return "math argument out of range";
864#endif
865#ifdef EDOTDOT
866    case EDOTDOT: return "cross mount point";
867#endif
868#ifdef EDQUOT
869    case EDQUOT: return "disk quota exceeded";
870#endif
871#ifdef EDUPPKG
872    case EDUPPKG: return "duplicate package name";
873#endif
874#ifdef EEXIST
875    case EEXIST: return "file already exists";
876#endif
877#ifdef EFAULT
878    case EFAULT: return "bad address in system call argument";
879#endif
880#ifdef EFBIG
881    case EFBIG: return "file too large";
882#endif
883#ifdef EHOSTDOWN
884    case EHOSTDOWN: return "host is down";
885#endif
886#ifdef EHOSTUNREACH
887    case EHOSTUNREACH: return "host is unreachable";
888#endif
889#ifdef EIDRM
890    case EIDRM: return "identifier removed";
891#endif
892#ifdef EINIT
893    case EINIT: return "initialization error";
894#endif
895#ifdef EINPROGRESS
896    case EINPROGRESS: return "operation now in progress";
897#endif
898#ifdef EINTR
899    case EINTR: return "interrupted system call";
900#endif
901#ifdef EINVAL
902    case EINVAL: return "invalid argument";
903#endif
904#ifdef EIO
905    case EIO: return "I/O error";
906#endif
907#ifdef EISCONN
908    case EISCONN: return "socket is already connected";
909#endif
910#ifdef EISDIR
911    case EISDIR: return "is a directory";
912#endif
913#ifdef EISNAME
914    case EISNAM: return "is a name file";
915#endif
916#ifdef ELBIN
917    case ELBIN: return "ELBIN";
918#endif
919#ifdef EL2HLT
920    case EL2HLT: return "level 2 halted";
921#endif
922#ifdef EL2NSYNC
923    case EL2NSYNC: return "level 2 not synchronized";
924#endif
925#ifdef EL3HLT
926    case EL3HLT: return "level 3 halted";
927#endif
928#ifdef EL3RST
929    case EL3RST: return "level 3 reset";
930#endif
931#ifdef ELIBACC
932    case ELIBACC: return "can not access a needed shared library";
933#endif
934#ifdef ELIBBAD
935    case ELIBBAD: return "accessing a corrupted shared library";
936#endif
937#ifdef ELIBEXEC
938    case ELIBEXEC: return "can not exec a shared library directly";
939#endif
940#ifdef ELIBMAX
941    case ELIBMAX: return "attempting to link in more shared libraries than system limit";
942#endif
943#ifdef ELIBSCN
944    case ELIBSCN: return ".lib section in a.out corrupted";
945#endif
946#ifdef ELNRNG
947    case ELNRNG: return "link number out of range";
948#endif
949#ifdef ELOOP
950    case ELOOP: return "too many levels of symbolic links";
951#endif
952#ifdef EMFILE
953    case EMFILE: return "too many open files";
954#endif
955#ifdef EMLINK
956    case EMLINK: return "too many links";
957#endif
958#ifdef EMSGSIZE
959    case EMSGSIZE: return "message too long";
960#endif
961#ifdef EMULTIHOP
962    case EMULTIHOP: return "multihop attempted";
963#endif
964#ifdef ENAMETOOLONG
965    case ENAMETOOLONG: return "file name too long";
966#endif
967#ifdef ENAVAIL
968    case ENAVAIL: return "not available";
969#endif
970#ifdef ENET
971    case ENET: return "ENET";
972#endif
973#ifdef ENETDOWN
974    case ENETDOWN: return "network is down";
975#endif
976#ifdef ENETRESET
977    case ENETRESET: return "network dropped connection on reset";
978#endif
979#ifdef ENETUNREACH
980    case ENETUNREACH: return "network is unreachable";
981#endif
982#ifdef ENFILE
983    case ENFILE: return "file table overflow";
984#endif
985#ifdef ENOANO
986    case ENOANO: return "anode table overflow";
987#endif
988#if defined(ENOBUFS) && (!defined(ENOSR) || (ENOBUFS != ENOSR))
989    case ENOBUFS: return "no buffer space available";
990#endif
991#ifdef ENOCSI
992    case ENOCSI: return "no CSI structure available";
993#endif
994#ifdef ENODATA
995    case ENODATA: return "no data available";
996#endif
997#ifdef ENODEV
998    case ENODEV: return "no such device";
999#endif
1000#ifdef ENOENT
1001    case ENOENT: return "no such file or directory";
1002#endif
1003#ifdef ENOEXEC
1004    case ENOEXEC: return "exec format error";
1005#endif
1006#ifdef ENOLCK
1007    case ENOLCK: return "no locks available";
1008#endif
1009#ifdef ENOLINK
1010    case ENOLINK: return "link has be severed";
1011#endif
1012#ifdef ENOMEM
1013    case ENOMEM: return "not enough memory";
1014#endif
1015#ifdef ENOMSG
1016    case ENOMSG: return "no message of desired type";
1017#endif
1018#ifdef ENONET
1019    case ENONET: return "machine is not on the network";
1020#endif
1021#ifdef ENOPKG
1022    case ENOPKG: return "package not installed";
1023#endif
1024#ifdef ENOPROTOOPT
1025    case ENOPROTOOPT: return "bad proocol option";
1026#endif
1027#ifdef ENOSPC
1028    case ENOSPC: return "no space left on device";
1029#endif
1030#ifdef ENOSR
1031    case ENOSR: return "out of stream resources";
1032#endif
1033#ifdef ENOSTR
1034    case ENOSTR: return "not a stream device";
1035#endif
1036#ifdef ENOSYM
1037    case ENOSYM: return "unresolved symbol name";
1038#endif
1039#ifdef ENOSYS
1040    case ENOSYS: return "function not implemented";
1041#endif
1042#ifdef ENOTBLK
1043    case ENOTBLK: return "block device required";
1044#endif
1045#ifdef ENOTCONN
1046    case ENOTCONN: return "socket is not connected";
1047#endif
1048#ifdef ENOTDIR
1049    case ENOTDIR: return "not a directory";
1050#endif
1051#ifdef ENOTEMPTY
1052    case ENOTEMPTY: return "directory not empty";
1053#endif
1054#ifdef ENOTNAM
1055    case ENOTNAM: return "not a name file";
1056#endif
1057#ifdef ENOTSOCK
1058    case ENOTSOCK: return "socket operation on non-socket";
1059#endif
1060#ifdef ENOTTY
1061    case ENOTTY: return "inappropriate device for ioctl";
1062#endif
1063#ifdef ENOTUNIQ
1064    case ENOTUNIQ: return "name not unique on network";
1065#endif
1066#ifdef ENXIO
1067    case ENXIO: return "no such device or address";
1068#endif
1069#ifdef EOPNOTSUPP
1070    case EOPNOTSUPP: return "operation not supported on socket";
1071#endif
1072#ifdef EPERM
1073    case EPERM: return "not owner";
1074#endif
1075#ifdef EPFNOSUPPORT
1076    case EPFNOSUPPORT: return "protocol family not supported";
1077#endif
1078#ifdef EPIPE
1079    case EPIPE: return "broken pipe";
1080#endif
1081#ifdef EPROCLIM
1082    case EPROCLIM: return "too many processes";
1083#endif
1084#ifdef EPROCUNAVAIL
1085    case EPROCUNAVAIL: return "bad procedure for program";
1086#endif
1087#ifdef EPROGMISMATCH
1088    case EPROGMISMATCH: return "program version wrong";
1089#endif
1090#ifdef EPROGUNAVAIL
1091    case EPROGUNAVAIL: return "RPC program not available";
1092#endif
1093#ifdef EPROTO
1094    case EPROTO: return "protocol error";
1095#endif
1096#ifdef EPROTONOSUPPORT
1097    case EPROTONOSUPPORT: return "protocol not suppored";
1098#endif
1099#ifdef EPROTOTYPE
1100    case EPROTOTYPE: return "protocol wrong type for socket";
1101#endif
1102#ifdef ERANGE
1103    case ERANGE: return "math result unrepresentable";
1104#endif
1105#if defined(EREFUSED) && (!defined(ECONNREFUSED) || (EREFUSED != ECONNREFUSED))
1106    case EREFUSED: return "EREFUSED";
1107#endif
1108#ifdef EREMCHG
1109    case EREMCHG: return "remote address changed";
1110#endif
1111#ifdef EREMDEV
1112    case EREMDEV: return "remote device";
1113#endif
1114#ifdef EREMOTE
1115    case EREMOTE: return "pathname hit remote file system";
1116#endif
1117#ifdef EREMOTEIO
1118    case EREMOTEIO: return "remote i/o error";
1119#endif
1120#ifdef EREMOTERELEASE
1121    case EREMOTERELEASE: return "EREMOTERELEASE";
1122#endif
1123#ifdef EROFS
1124    case EROFS: return "read-only file system";
1125#endif
1126#ifdef ERPCMISMATCH
1127    case ERPCMISMATCH: return "RPC version is wrong";
1128#endif
1129#ifdef ERREMOTE
1130    case ERREMOTE: return "object is remote";
1131#endif
1132#ifdef ESHUTDOWN
1133    case ESHUTDOWN: return "can't send afer socket shutdown";
1134#endif
1135#ifdef ESOCKTNOSUPPORT
1136    case ESOCKTNOSUPPORT: return "socket type not supported";
1137#endif
1138#ifdef ESPIPE
1139    case ESPIPE: return "invalid seek";
1140#endif
1141#ifdef ESRCH
1142    case ESRCH: return "no such process";
1143#endif
1144#ifdef ESRMNT
1145    case ESRMNT: return "srmount error";
1146#endif
1147#ifdef ESTALE
1148    case ESTALE: return "stale remote file handle";
1149#endif
1150#ifdef ESUCCESS
1151    case ESUCCESS: return "Error 0";
1152#endif
1153#ifdef ETIME
1154    case ETIME: return "timer expired";
1155#endif
1156#ifdef ETIMEDOUT
1157    case ETIMEDOUT: return "connection timed out";
1158#endif
1159#ifdef ETOOMANYREFS
1160    case ETOOMANYREFS: return "too many references: can't splice";
1161#endif
1162#ifdef ETXTBSY
1163    case ETXTBSY: return "text file or pseudo-device busy";
1164#endif
1165#ifdef EUCLEAN
1166    case EUCLEAN: return "structure needs cleaning";
1167#endif
1168#ifdef EUNATCH
1169    case EUNATCH: return "protocol driver not attached";
1170#endif
1171#ifdef EUSERS
1172    case EUSERS: return "too many users";
1173#endif
1174#ifdef EVERSION
1175    case EVERSION: return "version mismatch";
1176#endif
1177#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
1178    case EWOULDBLOCK: return "operation would block";
1179#endif
1180#ifdef EXDEV
1181    case EXDEV: return "cross-domain link";
1182#endif
1183#ifdef EXFULL
1184    case EXFULL: return "message tables full";
1185#endif
1186    }
1187#else /* NO_SYS_ERRLIST */
1188  extern int sys_nerr;
1189  extern char *sys_errlist[];
1190
1191  if ((errnum > 0) && (errnum <= sys_nerr))
1192    return sys_errlist [errnum];
1193#endif /* NO_SYS_ERRLIST */
1194
1195  msg = g_static_private_get (&msg_private);
1196  if (!msg)
1197    {
1198      msg = g_new (gchar, 64);
1199      g_static_private_set (&msg_private, msg, g_free);
1200    }
1201
1202  _g_sprintf (msg, "unknown error (%d)", errnum);
1203
1204  errno = saved_errno;
1205  return msg;
1206}
1207
1208G_CONST_RETURN gchar*
1209g_strsignal (gint signum)
1210{
1211  static GStaticPrivate msg_private = G_STATIC_PRIVATE_INIT;
1212  char *msg;
1213
1214#ifdef HAVE_STRSIGNAL
1215  const char *msg_locale;
1216 
1217#if defined(G_OS_BEOS) || defined(G_WITH_CYGWIN)
1218extern const char *strsignal(int);
1219#else
1220  /* this is declared differently (const) in string.h on BeOS */
1221  extern char *strsignal (int sig);
1222#endif /* !G_OS_BEOS && !G_WITH_CYGWIN */
1223  msg_locale = strsignal (signum);
1224  if (g_get_charset (NULL))
1225    return msg_locale;
1226  else
1227    {
1228      gchar *msg_utf8 = g_locale_to_utf8 (msg_locale, -1, NULL, NULL, NULL);
1229      if (msg_utf8)
1230        {
1231          /* Stick in the quark table so that we can return a static result
1232           */
1233          GQuark msg_quark = g_quark_from_string (msg_utf8);
1234          g_free (msg_utf8);
1235         
1236          return g_quark_to_string (msg_quark);
1237        }
1238    }
1239#elif NO_SYS_SIGLIST
1240  switch (signum)
1241    {
1242#ifdef SIGHUP
1243    case SIGHUP: return "Hangup";
1244#endif
1245#ifdef SIGINT
1246    case SIGINT: return "Interrupt";
1247#endif
1248#ifdef SIGQUIT
1249    case SIGQUIT: return "Quit";
1250#endif
1251#ifdef SIGILL
1252    case SIGILL: return "Illegal instruction";
1253#endif
1254#ifdef SIGTRAP
1255    case SIGTRAP: return "Trace/breakpoint trap";
1256#endif
1257#ifdef SIGABRT
1258    case SIGABRT: return "IOT trap/Abort";
1259#endif
1260#ifdef SIGBUS
1261    case SIGBUS: return "Bus error";
1262#endif
1263#ifdef SIGFPE
1264    case SIGFPE: return "Floating point exception";
1265#endif
1266#ifdef SIGKILL
1267    case SIGKILL: return "Killed";
1268#endif
1269#ifdef SIGUSR1
1270    case SIGUSR1: return "User defined signal 1";
1271#endif
1272#ifdef SIGSEGV
1273    case SIGSEGV: return "Segmentation fault";
1274#endif
1275#ifdef SIGUSR2
1276    case SIGUSR2: return "User defined signal 2";
1277#endif
1278#ifdef SIGPIPE
1279    case SIGPIPE: return "Broken pipe";
1280#endif
1281#ifdef SIGALRM
1282    case SIGALRM: return "Alarm clock";
1283#endif
1284#ifdef SIGTERM
1285    case SIGTERM: return "Terminated";
1286#endif
1287#ifdef SIGSTKFLT
1288    case SIGSTKFLT: return "Stack fault";
1289#endif
1290#ifdef SIGCHLD
1291    case SIGCHLD: return "Child exited";
1292#endif
1293#ifdef SIGCONT
1294    case SIGCONT: return "Continued";
1295#endif
1296#ifdef SIGSTOP
1297    case SIGSTOP: return "Stopped (signal)";
1298#endif
1299#ifdef SIGTSTP
1300    case SIGTSTP: return "Stopped";
1301#endif
1302#ifdef SIGTTIN
1303    case SIGTTIN: return "Stopped (tty input)";
1304#endif
1305#ifdef SIGTTOU
1306    case SIGTTOU: return "Stopped (tty output)";
1307#endif
1308#ifdef SIGURG
1309    case SIGURG: return "Urgent condition";
1310#endif
1311#ifdef SIGXCPU
1312    case SIGXCPU: return "CPU time limit exceeded";
1313#endif
1314#ifdef SIGXFSZ
1315    case SIGXFSZ: return "File size limit exceeded";
1316#endif
1317#ifdef SIGVTALRM
1318    case SIGVTALRM: return "Virtual time alarm";
1319#endif
1320#ifdef SIGPROF
1321    case SIGPROF: return "Profile signal";
1322#endif
1323#ifdef SIGWINCH
1324    case SIGWINCH: return "Window size changed";
1325#endif
1326#ifdef SIGIO
1327    case SIGIO: return "Possible I/O";
1328#endif
1329#ifdef SIGPWR
1330    case SIGPWR: return "Power failure";
1331#endif
1332#ifdef SIGUNUSED
1333    case SIGUNUSED: return "Unused signal";
1334#endif
1335    }
1336#else /* NO_SYS_SIGLIST */
1337
1338#ifdef NO_SYS_SIGLIST_DECL
1339  extern char *sys_siglist[];   /*(see Tue Jan 19 00:44:24 1999 in changelog)*/
1340#endif
1341
1342  return (char*) /* this function should return const --josh */ sys_siglist [signum];
1343#endif /* NO_SYS_SIGLIST */
1344
1345  msg = g_static_private_get (&msg_private);
1346  if (!msg)
1347    {
1348      msg = g_new (gchar, 64);
1349      g_static_private_set (&msg_private, msg, g_free);
1350    }
1351
1352  _g_sprintf (msg, "unknown signal (%d)", signum);
1353 
1354  return msg;
1355}
1356
1357/* Functions g_strlcpy and g_strlcat were originally developed by
1358 * Todd C. Miller <Todd.Miller@courtesan.com> to simplify writing secure code.
1359 * See ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/strlcpy.3
1360 * for more information.
1361 */
1362
1363#ifdef HAVE_STRLCPY
1364/* Use the native ones, if available; they might be implemented in assembly */
1365gsize
1366g_strlcpy (gchar       *dest,
1367           const gchar *src,
1368           gsize        dest_size)
1369{
1370  g_return_val_if_fail (dest != NULL, 0);
1371  g_return_val_if_fail (src  != NULL, 0);
1372 
1373  return strlcpy (dest, src, dest_size);
1374}
1375
1376gsize
1377g_strlcat (gchar       *dest,
1378           const gchar *src,
1379           gsize        dest_size)
1380{
1381  g_return_val_if_fail (dest != NULL, 0);
1382  g_return_val_if_fail (src  != NULL, 0);
1383 
1384  return strlcat (dest, src, dest_size);
1385}
1386
1387#else /* ! HAVE_STRLCPY */
1388/* g_strlcpy
1389 *
1390 * Copy string src to buffer dest (of buffer size dest_size).  At most
1391 * dest_size-1 characters will be copied.  Always NUL terminates
1392 * (unless dest_size == 0).  This function does NOT allocate memory.
1393 * Unlike strncpy, this function doesn't pad dest (so it's often faster).
1394 * Returns size of attempted result, strlen(src),
1395 * so if retval >= dest_size, truncation occurred.
1396 */
1397gsize
1398g_strlcpy (gchar       *dest,
1399           const gchar *src,
1400           gsize        dest_size)
1401{
1402  register gchar *d = dest;
1403  register const gchar *s = src;
1404  register gsize n = dest_size;
1405 
1406  g_return_val_if_fail (dest != NULL, 0);
1407  g_return_val_if_fail (src  != NULL, 0);
1408 
1409  /* Copy as many bytes as will fit */
1410  if (n != 0 && --n != 0)
1411    do
1412      {
1413        register gchar c = *s++;
1414       
1415        *d++ = c;
1416        if (c == 0)
1417          break;
1418      }
1419    while (--n != 0);
1420 
1421  /* If not enough room in dest, add NUL and traverse rest of src */
1422  if (n == 0)
1423    {
1424      if (dest_size != 0)
1425        *d = 0;
1426      while (*s++)
1427        ;
1428    }
1429 
1430  return s - src - 1;  /* count does not include NUL */
1431}
1432
1433/* g_strlcat
1434 *
1435 * Appends string src to buffer dest (of buffer size dest_size).
1436 * At most dest_size-1 characters will be copied.
1437 * Unlike strncat, dest_size is the full size of dest, not the space left over.
1438 * This function does NOT allocate memory.
1439 * This always NUL terminates (unless siz == 0 or there were no NUL characters
1440 * in the dest_size characters of dest to start with).
1441 * Returns size of attempted result, which is
1442 * MIN (dest_size, strlen (original dest)) + strlen (src),
1443 * so if retval >= dest_size, truncation occurred.
1444 */
1445gsize
1446g_strlcat (gchar       *dest,
1447           const gchar *src,
1448           gsize        dest_size)
1449{
1450  register gchar *d = dest;
1451  register const gchar *s = src;
1452  register gsize bytes_left = dest_size;
1453  gsize dlength;  /* Logically, MIN (strlen (d), dest_size) */
1454 
1455  g_return_val_if_fail (dest != NULL, 0);
1456  g_return_val_if_fail (src  != NULL, 0);
1457 
1458  /* Find the end of dst and adjust bytes left but don't go past end */
1459  while (*d != 0 && bytes_left-- != 0)
1460    d++;
1461  dlength = d - dest;
1462  bytes_left = dest_size - dlength;
1463 
1464  if (bytes_left == 0)
1465    return dlength + strlen (s);
1466 
1467  while (*s != 0)
1468    {
1469      if (bytes_left != 1)
1470        {
1471          *d++ = *s;
1472          bytes_left--;
1473        }
1474      s++;
1475    }
1476  *d = 0;
1477 
1478  return dlength + (s - src);  /* count does not include NUL */
1479}
1480#endif /* ! HAVE_STRLCPY */
1481
1482/**
1483 * g_ascii_strdown:
1484 * @str: a string.
1485 * @len: length of @str in bytes, or -1 if @str is nul-terminated.
1486 *
1487 * Converts all upper case ASCII letters to lower case ASCII letters.
1488 *
1489 * Return value: a newly-allocated string, with all the upper case
1490 *               characters in @str converted to lower case, with
1491 *               semantics that exactly match g_ascii_tolower(). (Note
1492 *               that this is unlike the old g_strdown(), which modified
1493 *               the string in place.)
1494 **/
1495gchar*
1496g_ascii_strdown (const gchar *str,
1497                 gssize       len)
1498{
1499  gchar *result, *s;
1500 
1501  g_return_val_if_fail (str != NULL, NULL);
1502
1503  if (len < 0)
1504    len = strlen (str);
1505
1506  result = g_strndup (str, len);
1507  for (s = result; *s; s++)
1508    *s = g_ascii_tolower (*s);
1509 
1510  return result;
1511}
1512
1513/**
1514 * g_ascii_strup:
1515 * @str: a string.
1516 * @len: length of @str in bytes, or -1 if @str is nul-terminated.
1517 *
1518 * Converts all lower case ASCII letters to upper case ASCII letters.
1519 *
1520 * Return value: a newly allocated string, with all the lower case
1521 *               characters in @str converted to upper case, with
1522 *               semantics that exactly match g_ascii_toupper(). (Note
1523 *               that this is unlike the old g_strup(), which modified
1524 *               the string in place.)
1525 **/
1526gchar*
1527g_ascii_strup (const gchar *str,
1528               gssize       len)
1529{
1530  gchar *result, *s;
1531
1532  g_return_val_if_fail (str != NULL, NULL);
1533
1534  if (len < 0)
1535    len = strlen (str);
1536
1537  result = g_strndup (str, len);
1538  for (s = result; *s; s++)
1539    *s = g_ascii_toupper (*s);
1540
1541  return result;
1542}
1543
1544/**
1545 * g_strdown:
1546 * @string: the string to convert.
1547 *
1548 * Converts a string to lower case. 
1549 *
1550 * Return value: the string
1551 *
1552 * Deprecated: This function is totally broken for the reasons discussed in
1553 * the g_strncasecmp() docs - use g_ascii_strdown() or g_utf8_strdown()
1554 * instead.
1555 **/
1556gchar*
1557g_strdown (gchar *string)
1558{
1559  register guchar *s;
1560 
1561  g_return_val_if_fail (string != NULL, NULL);
1562 
1563  s = (guchar *) string;
1564 
1565  while (*s)
1566    {
1567      if (isupper (*s))
1568        *s = tolower (*s);
1569      s++;
1570    }
1571 
1572  return (gchar *) string;
1573}
1574
1575/**
1576 * g_strup:
1577 * @string: the string to convert.
1578 *
1579 * Converts a string to upper case.
1580 *
1581 * Return value: the string
1582 *
1583 * Deprecated: This function is totally broken for the reasons discussed in
1584 * the g_strncasecmp() docs - use g_ascii_strup() or g_utf8_strup() instead.
1585 **/
1586gchar*
1587g_strup (gchar *string)
1588{
1589  register guchar *s;
1590
1591  g_return_val_if_fail (string != NULL, NULL);
1592
1593  s = (guchar *) string;
1594
1595  while (*s)
1596    {
1597      if (islower (*s))
1598        *s = toupper (*s);
1599      s++;
1600    }
1601
1602  return (gchar *) string;
1603}
1604
1605gchar*
1606g_strreverse (gchar *string)
1607{
1608  g_return_val_if_fail (string != NULL, NULL);
1609
1610  if (*string)
1611    {
1612      register gchar *h, *t;
1613
1614      h = string;
1615      t = string + strlen (string) - 1;
1616
1617      while (h < t)
1618        {
1619          register gchar c;
1620
1621          c = *h;
1622          *h = *t;
1623          h++;
1624          *t = c;
1625          t--;
1626        }
1627    }
1628
1629  return string;
1630}
1631
1632/**
1633 * g_ascii_tolower:
1634 * @c: any character.
1635 *
1636 * Convert a character to ASCII lower case.
1637 *
1638 * Unlike the standard C library tolower() function, this only
1639 * recognizes standard ASCII letters and ignores the locale, returning
1640 * all non-ASCII characters unchanged, even if they are lower case
1641 * letters in a particular character set. Also unlike the standard
1642 * library function, this takes and returns a char, not an int, so
1643 * don't call it on %EOF but no need to worry about casting to #guchar
1644 * before passing a possibly non-ASCII character in.
1645 *
1646 * Return value: the result of converting @c to lower case.
1647 *               If @c is not an ASCII upper case letter,
1648 *               @c is returned unchanged.
1649 **/
1650gchar
1651g_ascii_tolower (gchar c)
1652{
1653  return g_ascii_isupper (c) ? c - 'A' + 'a' : c;
1654}
1655
1656/**
1657 * g_ascii_toupper:
1658 * @c: any character.
1659 *
1660 * Convert a character to ASCII upper case.
1661 *
1662 * Unlike the standard C library toupper() function, this only
1663 * recognizes standard ASCII letters and ignores the locale, returning
1664 * all non-ASCII characters unchanged, even if they are upper case
1665 * letters in a particular character set. Also unlike the standard
1666 * library function, this takes and returns a char, not an int, so
1667 * don't call it on %EOF but no need to worry about casting to #guchar
1668 * before passing a possibly non-ASCII character in.
1669 *
1670 * Return value: the result of converting @c to upper case.
1671 *               If @c is not an ASCII lower case letter,
1672 *               @c is returned unchanged.
1673 **/
1674gchar
1675g_ascii_toupper (gchar c)
1676{
1677  return g_ascii_islower (c) ? c - 'a' + 'A' : c;
1678}
1679
1680/**
1681 * g_ascii_digit_value:
1682 * @c: an ASCII character.
1683 *
1684 * Determines the numeric value of a character as a decimal
1685 * digit. Differs from g_unichar_digit_value() because it takes
1686 * a char, so there's no worry about sign extension if characters
1687 * are signed.
1688 *
1689 * Return value: If @c is a decimal digit (according to
1690 * g_ascii_isdigit()), its numeric value. Otherwise, -1.
1691 **/
1692int
1693g_ascii_digit_value (gchar c)
1694{
1695  if (g_ascii_isdigit (c))
1696    return c - '0';
1697  return -1;
1698}
1699
1700/**
1701 * g_ascii_xdigit_value:
1702 * @c: an ASCII character.
1703 *
1704 * Determines the numeric value of a character as a hexidecimal
1705 * digit. Differs from g_unichar_xdigit_value() because it takes
1706 * a char, so there's no worry about sign extension if characters
1707 * are signed.
1708 *
1709 * Return value: If @c is a hex digit (according to
1710 * g_ascii_isxdigit()), its numeric value. Otherwise, -1.
1711 **/
1712int
1713g_ascii_xdigit_value (gchar c)
1714{
1715  if (c >= 'A' && c <= 'F')
1716    return c - 'A' + 10;
1717  if (c >= 'a' && c <= 'f')
1718    return c - 'a' + 10;
1719  return g_ascii_digit_value (c);
1720}
1721
1722/**
1723 * g_ascii_strcasecmp:
1724 * @s1: string to compare with @s2.
1725 * @s2: string to compare with @s1.
1726 *
1727 * Compare two strings, ignoring the case of ASCII characters.
1728 *
1729 * Unlike the BSD strcasecmp() function, this only recognizes standard
1730 * ASCII letters and ignores the locale, treating all non-ASCII
1731 * characters as if they are not letters.
1732 *
1733 * Return value: an integer less than, equal to, or greater than
1734 *               zero if @s1 is found, respectively, to be less than,
1735 *               to match, or to be greater than @s2.
1736 **/
1737gint
1738g_ascii_strcasecmp (const gchar *s1,
1739                    const gchar *s2)
1740{
1741  gint c1, c2;
1742
1743  g_return_val_if_fail (s1 != NULL, 0);
1744  g_return_val_if_fail (s2 != NULL, 0);
1745
1746  while (*s1 && *s2)
1747    {
1748      c1 = (gint)(guchar) TOLOWER (*s1);
1749      c2 = (gint)(guchar) TOLOWER (*s2);
1750      if (c1 != c2)
1751        return (c1 - c2);
1752      s1++; s2++;
1753    }
1754
1755  return (((gint)(guchar) *s1) - ((gint)(guchar) *s2));
1756}
1757
1758/**
1759 * g_ascii_strncasecmp:
1760 * @s1: string to compare with @s2.
1761 * @s2: string to compare with @s1.
1762 * @n:  number of characters to compare.
1763 *
1764 * Compare @s1 and @s2, ignoring the case of ASCII characters and any
1765 * characters after the first @n in each string.
1766 *
1767 * Unlike the BSD strcasecmp() function, this only recognizes standard
1768 * ASCII letters and ignores the locale, treating all non-ASCII
1769 * characters as if they are not letters.
1770 *
1771 * Return value: an integer less than, equal to, or greater than zero
1772 *               if the first @n bytes of @s1 is found, respectively,
1773 *               to be less than, to match, or to be greater than the
1774 *               first @n bytes of @s2.
1775 **/
1776gint
1777g_ascii_strncasecmp (const gchar *s1,
1778                     const gchar *s2,
1779                     gsize n)
1780{
1781  gint c1, c2;
1782
1783  g_return_val_if_fail (s1 != NULL, 0);
1784  g_return_val_if_fail (s2 != NULL, 0);
1785
1786  while (n && *s1 && *s2)
1787    {
1788      n -= 1;
1789      c1 = (gint)(guchar) TOLOWER (*s1);
1790      c2 = (gint)(guchar) TOLOWER (*s2);
1791      if (c1 != c2)
1792        return (c1 - c2);
1793      s1++; s2++;
1794    }
1795
1796  if (n)
1797    return (((gint) (guchar) *s1) - ((gint) (guchar) *s2));
1798  else
1799    return 0;
1800}
1801
1802/**
1803 * g_strcasecmp:
1804 * @s1: a string.
1805 * @s2: a string to compare with @s1.
1806 *
1807 * A case-insensitive string comparison, corresponding to the standard
1808 * strcasecmp() function on platforms which support it.
1809 *
1810 * Return value: 0 if the strings match, a negative value if @s1 &lt; @s2,
1811 *   or a positive value if @s1 &gt; @s2.
1812 *
1813 * Deprecated: See g_strncasecmp() for a discussion of why this function is
1814 *   deprecated and how to replace it.
1815 **/
1816gint
1817g_strcasecmp (const gchar *s1,
1818              const gchar *s2)
1819{
1820#ifdef HAVE_STRCASECMP
1821  g_return_val_if_fail (s1 != NULL, 0);
1822  g_return_val_if_fail (s2 != NULL, 0);
1823
1824  return strcasecmp (s1, s2);
1825#else
1826  gint c1, c2;
1827
1828  g_return_val_if_fail (s1 != NULL, 0);
1829  g_return_val_if_fail (s2 != NULL, 0);
1830
1831  while (*s1 && *s2)
1832    {
1833      /* According to A. Cox, some platforms have islower's that
1834       * don't work right on non-uppercase
1835       */
1836      c1 = isupper ((guchar)*s1) ? tolower ((guchar)*s1) : *s1;
1837      c2 = isupper ((guchar)*s2) ? tolower ((guchar)*s2) : *s2;
1838      if (c1 != c2)
1839        return (c1 - c2);
1840      s1++; s2++;
1841    }
1842
1843  return (((gint)(guchar) *s1) - ((gint)(guchar) *s2));
1844#endif
1845}
1846
1847/**
1848 * g_strncasecmp:
1849 * @s1: a string.
1850 * @s2: a string to compare with @s1.
1851 * @n: the maximum number of characters to compare.
1852 *
1853 * A case-insensitive string comparison, corresponding to the standard
1854 * strncasecmp() function on platforms which support it.
1855 * It is similar to g_strcasecmp() except it only compares the first @n
1856 * characters of the strings.
1857 *
1858 * Return value: 0 if the strings match, a negative value if @s1 &lt; @s2,
1859 *   or a positive value if @s1 &gt; @s2.
1860 *
1861 * Deprecated: The problem with g_strncasecmp() is that it does the
1862 * comparison by calling toupper()/tolower(). These functions are
1863 * locale-specific and operate on single bytes. However, it is impossible
1864 * to handle things correctly from an I18N standpoint by operating on
1865 * bytes, since characters may be multibyte. Thus g_strncasecmp() is
1866 * broken if your string is guaranteed to be ASCII, since it's
1867 * locale-sensitive, and it's broken if your string is localized, since
1868 * it doesn't work on many encodings at all, including UTF-8, EUC-JP,
1869 * etc.
1870 *
1871 * There are therefore two replacement functions: g_ascii_strncasecmp(),
1872 * which only works on ASCII and is not locale-sensitive, and
1873 * g_utf8_casefold(), which is good for case-insensitive sorting of UTF-8.
1874 **/
1875gint
1876g_strncasecmp (const gchar *s1,
1877               const gchar *s2,
1878               guint n)     
1879{
1880#ifdef HAVE_STRNCASECMP
1881  return strncasecmp (s1, s2, n);
1882#else
1883  gint c1, c2;
1884
1885  g_return_val_if_fail (s1 != NULL, 0);
1886  g_return_val_if_fail (s2 != NULL, 0);
1887
1888  while (n && *s1 && *s2)
1889    {
1890      n -= 1;
1891      /* According to A. Cox, some platforms have islower's that
1892       * don't work right on non-uppercase
1893       */
1894      c1 = isupper ((guchar)*s1) ? tolower ((guchar)*s1) : *s1;
1895      c2 = isupper ((guchar)*s2) ? tolower ((guchar)*s2) : *s2;
1896      if (c1 != c2)
1897        return (c1 - c2);
1898      s1++; s2++;
1899    }
1900
1901  if (n)
1902    return (((gint) (guchar) *s1) - ((gint) (guchar) *s2));
1903  else
1904    return 0;
1905#endif
1906}
1907
1908gchar*
1909g_strdelimit (gchar       *string,
1910              const gchar *delimiters,
1911              gchar        new_delim)
1912{
1913  register gchar *c;
1914
1915  g_return_val_if_fail (string != NULL, NULL);
1916
1917  if (!delimiters)
1918    delimiters = G_STR_DELIMITERS;
1919
1920  for (c = string; *c; c++)
1921    {
1922      if (strchr (delimiters, *c))
1923        *c = new_delim;
1924    }
1925
1926  return string;
1927}
1928
1929gchar*
1930g_strcanon (gchar       *string,
1931            const gchar *valid_chars,
1932            gchar        substitutor)
1933{
1934  register gchar *c;
1935
1936  g_return_val_if_fail (string != NULL, NULL);
1937  g_return_val_if_fail (valid_chars != NULL, NULL);
1938
1939  for (c = string; *c; c++)
1940    {
1941      if (!strchr (valid_chars, *c))
1942        *c = substitutor;
1943    }
1944
1945  return string;
1946}
1947
1948gchar*
1949g_strcompress (const gchar *source)
1950{
1951  const gchar *p = source, *octal;
1952  gchar *dest = g_malloc (strlen (source) + 1);
1953  gchar *q = dest;
1954 
1955  while (*p)
1956    {
1957      if (*p == '\\')
1958        {
1959          p++;
1960          switch (*p)
1961            {
1962            case '0':  case '1':  case '2':  case '3':  case '4':
1963            case '5':  case '6':  case '7':
1964              *q = 0;
1965              octal = p;
1966              while ((p < octal + 3) && (*p >= '0') && (*p <= '7'))
1967                {
1968                  *q = (*q * 8) + (*p - '0');
1969                  p++;
1970                }
1971              q++;
1972              p--;
1973              break;
1974            case 'b':
1975              *q++ = '\b';
1976              break;
1977            case 'f':
1978              *q++ = '\f';
1979              break;
1980            case 'n':
1981              *q++ = '\n';
1982              break;
1983            case 'r':
1984              *q++ = '\r';
1985              break;
1986            case 't':
1987              *q++ = '\t';
1988              break;
1989            default:            /* Also handles \" and \\ */
1990              *q++ = *p;
1991              break;
1992            }
1993        }
1994      else
1995        *q++ = *p;
1996      p++;
1997    }
1998  *q = 0;
1999 
2000  return dest;
2001}
2002
2003gchar *
2004g_strescape (const gchar *source,
2005             const gchar *exceptions)
2006{
2007  const guchar *p;
2008  gchar *dest;
2009  gchar *q;
2010  guchar excmap[256];
2011 
2012  g_return_val_if_fail (source != NULL, NULL);
2013
2014  p = (guchar *) source;
2015  /* Each source byte needs maximally four destination chars (\777) */
2016  q = dest = g_malloc (strlen (source) * 4 + 1);
2017
2018  memset (excmap, 0, 256);
2019  if (exceptions)
2020    {
2021      guchar *e = (guchar *) exceptions;
2022
2023      while (*e)
2024        {
2025          excmap[*e] = 1;
2026          e++;
2027        }
2028    }
2029
2030  while (*p)
2031    {
2032      if (excmap[*p])
2033        *q++ = *p;
2034      else
2035        {
2036          switch (*p)
2037            {
2038            case '\b':
2039              *q++ = '\\';
2040              *q++ = 'b';
2041              break;
2042            case '\f':
2043              *q++ = '\\';
2044              *q++ = 'f';
2045              break;
2046            case '\n':
2047              *q++ = '\\';
2048              *q++ = 'n';
2049              break;
2050            case '\r':
2051              *q++ = '\\';
2052              *q++ = 'r';
2053              break;
2054            case '\t':
2055              *q++ = '\\';
2056              *q++ = 't';
2057              break;
2058            case '\\':
2059              *q++ = '\\';
2060              *q++ = '\\';
2061              break;
2062            case '"':
2063              *q++ = '\\';
2064              *q++ = '"';
2065              break;
2066            default:
2067              if ((*p < ' ') || (*p >= 0177))
2068                {
2069                  *q++ = '\\';
2070                  *q++ = '0' + (((*p) >> 6) & 07);
2071                  *q++ = '0' + (((*p) >> 3) & 07);
2072                  *q++ = '0' + ((*p) & 07);
2073                }
2074              else
2075                *q++ = *p;
2076              break;
2077            }
2078        }
2079      p++;
2080    }
2081  *q = 0;
2082  return dest;
2083}
2084
2085gchar*
2086g_strchug (gchar *string)
2087{
2088  guchar *start;
2089
2090  g_return_val_if_fail (string != NULL, NULL);
2091
2092  for (start = (guchar*) string; *start && g_ascii_isspace (*start); start++)
2093    ;
2094
2095  g_memmove (string, start, strlen ((gchar *) start) + 1);
2096
2097  return string;
2098}
2099
2100gchar*
2101g_strchomp (gchar *string)
2102{
2103  gsize len;
2104
2105  g_return_val_if_fail (string != NULL, NULL);
2106
2107  len = strlen (string);
2108  while (len--)
2109    {
2110      if (g_ascii_isspace ((guchar) string[len]))
2111        string[len] = '\0';
2112      else
2113        break;
2114    }
2115
2116  return string;
2117}
2118
2119/**
2120 * g_strsplit:
2121 * @string: a string to split.
2122 * @delimiter: a string which specifies the places at which to split the string.
2123 *     The delimiter is not included in any of the resulting strings, unless
2124 *     @max_tokens is reached.
2125 * @max_tokens: the maximum number of pieces to split @string into. If this is
2126 *              less than 1, the string is split completely.
2127 *
2128 * Splits a string into a maximum of @max_tokens pieces, using the given
2129 * @delimiter. If @max_tokens is reached, the remainder of @string is appended
2130 * to the last token.
2131 *
2132 * As a special case, the result of splitting the empty string "" is an empty
2133 * vector, not a vector containing a single string. The reason for this
2134 * special case is that being able to represent a empty vector is typically
2135 * more useful than consistent handling of empty elements. If you do need
2136 * to represent empty elements, you'll need to check for the empty string
2137 * before calling g_strsplit().
2138 *
2139 * Return value: a newly-allocated %NULL-terminated array of strings. Use
2140 *    g_strfreev() to free it.
2141 **/
2142gchar**
2143g_strsplit (const gchar *string,
2144            const gchar *delimiter,
2145            gint         max_tokens)
2146{
2147  GSList *string_list = NULL, *slist;
2148  gchar **str_array, *s;
2149  guint n = 0;
2150  const gchar *remainder;
2151
2152  g_return_val_if_fail (string != NULL, NULL);
2153  g_return_val_if_fail (delimiter != NULL, NULL);
2154  g_return_val_if_fail (delimiter[0] != '\0', NULL);
2155
2156  if (max_tokens < 1)
2157    max_tokens = G_MAXINT;
2158
2159  remainder = string;
2160  s = strstr (remainder, delimiter);
2161  if (s)
2162    {
2163      gsize delimiter_len = strlen (delimiter);   
2164
2165      while (--max_tokens && s)
2166        {
2167          gsize len;     
2168          gchar *new_string;
2169
2170          len = s - remainder;
2171          new_string = g_new (gchar, len + 1);
2172          strncpy (new_string, remainder, len);
2173          new_string[len] = 0;
2174          string_list = g_slist_prepend (string_list, new_string);
2175          n++;
2176          remainder = s + delimiter_len;
2177          s = strstr (remainder, delimiter);
2178        }
2179    }
2180  if (*string)
2181    {
2182      n++;
2183      string_list = g_slist_prepend (string_list, g_strdup (remainder));
2184    }
2185
2186  str_array = g_new (gchar*, n + 1);
2187
2188  str_array[n--] = NULL;
2189  for (slist = string_list; slist; slist = slist->next)
2190    str_array[n--] = slist->data;
2191
2192  g_slist_free (string_list);
2193
2194  return str_array;
2195}
2196
2197/**
2198 * g_strsplit_set:
2199 * @string: The string to be tokenized
2200 * @delimiters: A nul-terminated string containing bytes that are used
2201 *              to split the string.
2202 * @max_tokens: The maximum number of tokens to split @string into.
2203 *              If this is less than 1, the string is split completely
2204 *
2205 * Splits @string into a number of tokens not containing any of the characters
2206 * in @delimiter. A token is the (possibly empty) longest string that does not
2207 * contain any of the characters in @delimiters. If @max_tokens is reached, the
2208 * remainder is appended to the last token.
2209 *
2210 * For example the result of g_strsplit_set ("abc:def/ghi", ":/", -1) is a
2211 * %NULL-terminated vector containing the three strings "abc", "def",
2212 * and "ghi".
2213 *
2214 * The result if g_strsplit_set (":def/ghi:", ":/", -1) is a %NULL-terminated
2215 * vector containing the four strings "", "def", "ghi", and "".
2216 *
2217 * As a special case, the result of splitting the empty string "" is an empty
2218 * vector, not a vector containing a single string. The reason for this
2219 * special case is that being able to represent a empty vector is typically
2220 * more useful than consistent handling of empty elements. If you do need
2221 * to represent empty elements, you'll need to check for the empty string
2222 * before calling g_strsplit().
2223 *
2224 * Note that this function works on bytes not characters, so it can't be used
2225 * to delimit UTF-8 strings for anything but ASCII characters.
2226 *
2227 * Return value: a newly-allocated %NULL-terminated array of strings. Use
2228 *    g_strfreev() to free it.
2229 *
2230 * Since: 2.4
2231 **/
2232gchar **
2233g_strsplit_set (const gchar *string,
2234                const gchar *delimiters,
2235                gint         max_tokens)
2236{
2237  gboolean delim_table[256];
2238  GSList *tokens, *list;
2239  gint n_tokens;
2240  const gchar *s;
2241  const gchar *current;
2242  gchar *token;
2243  gchar **result;
2244 
2245  g_return_val_if_fail (string != NULL, NULL);
2246  g_return_val_if_fail (delimiters != NULL, NULL);
2247
2248  if (max_tokens < 1)
2249    max_tokens = G_MAXINT;
2250
2251  if (*string == '\0')
2252    {
2253      result = g_new (char *, 1);
2254      result[0] = NULL;
2255      return result;
2256    }
2257 
2258  memset (delim_table, FALSE, sizeof (delim_table));
2259  for (s = delimiters; *s != '\0'; ++s)
2260    delim_table[*(guchar *)s] = TRUE;
2261
2262  tokens = NULL;
2263  n_tokens = 0;
2264
2265  s = current = string;
2266  while (*s != '\0')
2267    {
2268      if (delim_table[*(guchar *)s] && n_tokens + 1 < max_tokens)
2269        {
2270          gchar *token;
2271
2272          token = g_strndup (current, s - current);
2273          tokens = g_slist_prepend (tokens, token);
2274          ++n_tokens;
2275
2276          current = s + 1;
2277        }
2278     
2279      ++s;
2280    }
2281
2282  token = g_strndup (current, s - current);
2283  tokens = g_slist_prepend (tokens, token);
2284  ++n_tokens;
2285
2286  result = g_new (gchar *, n_tokens + 1);
2287
2288  result[n_tokens] = NULL;
2289  for (list = tokens; list != NULL; list = list->next)
2290    result[--n_tokens] = list->data;
2291
2292  g_slist_free (tokens);
2293 
2294  return result;
2295}
2296
2297/**
2298 * g_strfreev:
2299 * @str_array: a %NULL-terminated array of strings to free.
2300
2301 * Frees a %NULL-terminated array of strings, and the array itself.
2302 * If called on a %NULL value, g_strfreev() simply returns.
2303 **/
2304void
2305g_strfreev (gchar **str_array)
2306{
2307  if (str_array)
2308    {
2309      int i;
2310
2311      for(i = 0; str_array[i] != NULL; i++)
2312        g_free(str_array[i]);
2313
2314      g_free (str_array);
2315    }
2316}
2317
2318/**
2319 * g_strdupv:
2320 * @str_array: %NULL-terminated array of strings.
2321 *
2322 * Copies %NULL-terminated array of strings. The copy is a deep copy;
2323 * the new array should be freed by first freeing each string, then
2324 * the array itself. g_strfreev() does this for you. If called
2325 * on a %NULL value, g_strdupv() simply returns %NULL.
2326 *
2327 * Return value: a new %NULL-terminated array of strings.
2328 **/
2329gchar**
2330g_strdupv (gchar **str_array)
2331{
2332  if (str_array)
2333    {
2334      gint i;
2335      gchar **retval;
2336
2337      i = 0;
2338      while (str_array[i])
2339        ++i;
2340         
2341      retval = g_new (gchar*, i + 1);
2342
2343      i = 0;
2344      while (str_array[i])
2345        {
2346          retval[i] = g_strdup (str_array[i]);
2347          ++i;
2348        }
2349      retval[i] = NULL;
2350
2351      return retval;
2352    }
2353  else
2354    return NULL;
2355}
2356
2357gchar*
2358g_strjoinv (const gchar  *separator,
2359            gchar       **str_array)
2360{
2361  gchar *string;
2362  gchar *ptr;
2363
2364  g_return_val_if_fail (str_array != NULL, NULL);
2365
2366  if (separator == NULL)
2367    separator = "";
2368
2369  if (*str_array)
2370    {
2371      gint i;
2372      gsize len;
2373      gsize separator_len;     
2374
2375      separator_len = strlen (separator);
2376      /* First part, getting length */
2377      len = 1 + strlen (str_array[0]);
2378      for (i = 1; str_array[i] != NULL; i++)
2379        len += strlen (str_array[i]);
2380      len += separator_len * (i - 1);
2381
2382      /* Second part, building string */
2383      string = g_new (gchar, len);
2384      ptr = g_stpcpy (string, *str_array);
2385      for (i = 1; str_array[i] != NULL; i++)
2386        {
2387          ptr = g_stpcpy (ptr, separator);
2388          ptr = g_stpcpy (ptr, str_array[i]);
2389        }
2390      }
2391  else
2392    string = g_strdup ("");
2393
2394  return string;
2395}
2396
2397gchar*
2398g_strjoin (const gchar  *separator,
2399           ...)
2400{
2401  gchar *string, *s;
2402  va_list args;
2403  gsize len;               
2404  gsize separator_len;     
2405  gchar *ptr;
2406
2407  if (separator == NULL)
2408    separator = "";
2409
2410  separator_len = strlen (separator);
2411
2412  va_start (args, separator);
2413
2414  s = va_arg (args, gchar*);
2415
2416  if (s)
2417    {
2418      /* First part, getting length */
2419      len = 1 + strlen (s);
2420
2421      s = va_arg (args, gchar*);
2422      while (s)
2423        {
2424          len += separator_len + strlen (s);
2425          s = va_arg (args, gchar*);
2426        }
2427      va_end (args);
2428
2429      /* Second part, building string */
2430      string = g_new (gchar, len);
2431
2432      va_start (args, separator);
2433
2434      s = va_arg (args, gchar*);
2435      ptr = g_stpcpy (string, s);
2436
2437      s = va_arg (args, gchar*);
2438      while (s)
2439        {
2440          ptr = g_stpcpy (ptr, separator);
2441          ptr = g_stpcpy (ptr, s);
2442          s = va_arg (args, gchar*);
2443        }
2444    }
2445  else
2446    string = g_strdup ("");
2447
2448  va_end (args);
2449
2450  return string;
2451}
2452
2453
2454/**
2455 * g_strstr_len:
2456 * @haystack: a string.
2457 * @haystack_len: the maximum length of @haystack.
2458 * @needle: the string to search for.
2459 *
2460 * Searches the string @haystack for the first occurrence
2461 * of the string @needle, limiting the length of the search
2462 * to @haystack_len.
2463 *
2464 * Return value: a pointer to the found occurrence, or
2465 *    %NULL if not found.
2466 **/
2467gchar *
2468g_strstr_len (const gchar *haystack,
2469              gssize       haystack_len,
2470              const gchar *needle)
2471{
2472  g_return_val_if_fail (haystack != NULL, NULL);
2473  g_return_val_if_fail (needle != NULL, NULL);
2474 
2475  if (haystack_len < 0)
2476    return strstr (haystack, needle);
2477  else
2478    {
2479      const gchar *p = haystack;
2480      gsize needle_len = strlen (needle);
2481      const gchar *end;
2482      gsize i;
2483
2484      if (needle_len == 0)
2485        return (gchar *)haystack;
2486
2487      if (haystack_len < needle_len)
2488        return NULL;
2489     
2490      end = haystack + haystack_len - needle_len;
2491     
2492      while (*p && p <= end)
2493        {
2494          for (i = 0; i < needle_len; i++)
2495            if (p[i] != needle[i])
2496              goto next;
2497         
2498          return (gchar *)p;
2499         
2500        next:
2501          p++;
2502        }
2503     
2504      return NULL;
2505    }
2506}
2507
2508/**
2509 * g_strrstr:
2510 * @haystack: a nul-terminated string.
2511 * @needle: the nul-terminated string to search for.
2512 *
2513 * Searches the string @haystack for the last occurrence
2514 * of the string @needle.
2515 *
2516 * Return value: a pointer to the found occurrence, or
2517 *    %NULL if not found.
2518 **/
2519gchar *
2520g_strrstr (const gchar *haystack,
2521           const gchar *needle)
2522{
2523  gsize i;
2524  gsize needle_len;
2525  gsize haystack_len;
2526  const gchar *p;
2527     
2528  g_return_val_if_fail (haystack != NULL, NULL);
2529  g_return_val_if_fail (needle != NULL, NULL);
2530
2531  needle_len = strlen (needle);
2532  haystack_len = strlen (haystack);
2533
2534  if (needle_len == 0)
2535    return (gchar *)haystack;
2536
2537  if (haystack_len < needle_len)
2538    return NULL;
2539 
2540  p = haystack + haystack_len - needle_len;
2541
2542  while (p >= haystack)
2543    {
2544      for (i = 0; i < needle_len; i++)
2545        if (p[i] != needle[i])
2546          goto next;
2547     
2548      return (gchar *)p;
2549     
2550    next:
2551      p--;
2552    }
2553 
2554  return NULL;
2555}
2556
2557/**
2558 * g_strrstr_len:
2559 * @haystack: a nul-terminated string.
2560 * @haystack_len: the maximum length of @haystack.
2561 * @needle: the nul-terminated string to search for.
2562 *
2563 * Searches the string @haystack for the last occurrence
2564 * of the string @needle, limiting the length of the search
2565 * to @haystack_len.
2566 *
2567 * Return value: a pointer to the found occurrence, or
2568 *    %NULL if not found.
2569 **/
2570gchar *
2571g_strrstr_len (const gchar *haystack,
2572               gssize        haystack_len,
2573               const gchar *needle)
2574{
2575  g_return_val_if_fail (haystack != NULL, NULL);
2576  g_return_val_if_fail (needle != NULL, NULL);
2577 
2578  if (haystack_len < 0)
2579    return g_strrstr (haystack, needle);
2580  else
2581    {
2582      gsize needle_len = strlen (needle);
2583      const gchar *haystack_max = haystack + haystack_len;
2584      const gchar *p = haystack;
2585      gsize i;
2586
2587      while (p < haystack_max && *p)
2588        p++;
2589
2590      if (p < haystack + needle_len)
2591        return NULL;
2592       
2593      p -= needle_len;
2594
2595      while (p >= haystack)
2596        {
2597          for (i = 0; i < needle_len; i++)
2598            if (p[i] != needle[i])
2599              goto next;
2600         
2601          return (gchar *)p;
2602         
2603        next:
2604          p--;
2605        }
2606
2607      return NULL;
2608    }
2609}
2610
2611
2612/**
2613 * g_str_has_suffix:
2614 * @str: a nul-terminated string.
2615 * @suffix: the nul-terminated suffix to look for.
2616 *
2617 * Looks whether the string @str ends with @suffix.
2618 *
2619 * Return value: %TRUE if @str end with @suffix, %FALSE otherwise.
2620 *
2621 * Since: 2.2
2622 **/
2623gboolean
2624g_str_has_suffix (const gchar  *str,
2625                  const gchar  *suffix)
2626{
2627  int str_len;
2628  int suffix_len;
2629 
2630  g_return_val_if_fail (str != NULL, FALSE);
2631  g_return_val_if_fail (suffix != NULL, FALSE);
2632
2633  str_len = strlen (str);
2634  suffix_len = strlen (suffix);
2635
2636  if (str_len < suffix_len)
2637    return FALSE;
2638
2639  return strcmp (str + str_len - suffix_len, suffix) == 0;
2640}
2641
2642/**
2643 * g_str_has_prefix:
2644 * @str: a nul-terminated string.
2645 * @prefix: the nul-terminated prefix to look for.
2646 *
2647 * Looks whether the string @str begins with @prefix.
2648 *
2649 * Return value: %TRUE if @str begins with @prefix, %FALSE otherwise.
2650 *
2651 * Since: 2.2
2652 **/
2653gboolean
2654g_str_has_prefix (const gchar  *str,
2655                  const gchar  *prefix)
2656{
2657  int str_len;
2658  int prefix_len;
2659 
2660  g_return_val_if_fail (str != NULL, FALSE);
2661  g_return_val_if_fail (prefix != NULL, FALSE);
2662
2663  str_len = strlen (str);
2664  prefix_len = strlen (prefix);
2665
2666  if (str_len < prefix_len)
2667    return FALSE;
2668 
2669  return strncmp (str, prefix, prefix_len) == 0;
2670}
2671
2672
2673/**
2674 * g_strip_context:
2675 * @msgid: a string
2676 * @msgval: another string
2677 *
2678 * An auxiliary function for gettext() support (see Q_()).
2679 *
2680 * Return value: @msgval, unless @msgval is identical to @msgid and contains
2681 *   a '|' character, in which case a pointer to the substring of msgid after
2682 *   the first '|' character is returned.
2683 *
2684 * Since: 2.4
2685 **/
2686G_CONST_RETURN gchar *
2687g_strip_context  (const gchar *msgid,
2688                  const gchar *msgval)
2689{
2690  if (msgval == msgid)
2691    {
2692      const char *c = strchr (msgid, '|');
2693      if (c != NULL)
2694        return c + 1;
2695    }
2696 
2697  return msgval;
2698}
Note: See TracBrowser for help on using the repository browser.