source: trunk/libs/newlib/src/newlib/libc/locale/duplocale.c @ 444

Last change on this file since 444 was 444, checked in by satin@…, 6 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 2.6 KB
Line 
1/*
2FUNCTION
3        <<duplocale>>---duplicate a locale object
4
5INDEX
6        duplocale
7
8INDEX
9        _duplocale_r
10
11SYNOPSIS
12        #include <locale.h>
13        locale_t duplocale(locale_t <[locobj]>);
14
15        locale_t _duplocale_r(void *<[reent]>, locale_t <[locobj]>);
16
17DESCRIPTION
18The <<duplocale>> function shall create a duplicate copy of the locale
19object referenced by the <[locobj]> argument.
20
21If the <[locobj]> argument is LC_GLOBAL_LOCALE, duplocale() shall create
22a new locale object containing a copy of the global locale determined by
23the setlocale() function.
24
25The behavior is undefined if the <[locobj]> argument is not a valid locale
26object handle.
27
28RETURNS
29Upon successful completion, the <<duplocale>> function shall return a
30handle for a new locale object.  Otherwise <<duplocale>> shall return
31(locale_t) <<0>> and set errno to indicate the error.
32
33PORTABILITY
34<<duplocale>> is POSIX-1.2008.
35*/
36
37#include <newlib.h>
38#include <reent.h>
39#include <stdlib.h>
40#include "setlocale.h"
41
42struct __locale_t *
43_duplocale_r (struct _reent *p, struct __locale_t *locobj)
44{
45  struct __locale_t tmp_locale, *new_locale;
46  int i;
47
48#ifndef _MB_CAPABLE
49  return __get_C_locale ();
50#else /* _MB_CAPABLE */
51  /* LC_GLOBAL_LOCALE denotes the global locale. */
52  if (locobj == LC_GLOBAL_LOCALE)
53    locobj = __get_global_locale ();
54  /* The "C" locale is used statically, never copied. */
55  else if (locobj == __get_C_locale ())
56    return __get_C_locale ();
57  /* Copy locale content. */
58  tmp_locale = *locobj;
59#ifdef __HAVE_LOCALE_INFO__
60  for (i = 1; i < _LC_LAST; ++i)
61    if (locobj->lc_cat[i].buf)
62      {
63        /* If the object is not a "C" locale category, copy it.  Just call
64           __loadlocale.  It knows what to do to replicate the category. */
65        tmp_locale.lc_cat[i].ptr = NULL;
66        tmp_locale.lc_cat[i].buf = NULL;
67        tmp_locale.categories[i][0] = '\0';     /* __loadlocale tests this! */
68        if (!__loadlocale (&tmp_locale, i, locobj->categories[i]))
69          goto error;
70      }
71#endif /* __HAVE_LOCALE_INFO__ */
72  /* Allocate new locale_t. */
73  new_locale = (struct __locale_t *) _calloc_r (p, 1, sizeof *new_locale);
74  if (!new_locale)
75    goto error;
76
77  *new_locale = tmp_locale;
78  return new_locale;
79
80error:
81  /* An error occured while we had already (potentially) allocated memory.
82     Free memory and return NULL.  errno is supposed to be set already. */
83#ifdef __HAVE_LOCALE_INFO__
84  while (--i > 0)
85    if (tmp_locale.lc_cat[i].buf)
86      {
87        _free_r (p, (void *) tmp_locale.lc_cat[i].ptr);
88        _free_r (p, tmp_locale.lc_cat[i].buf);
89      }
90#endif /* __HAVE_LOCALE_INFO__ */
91
92  return NULL;
93#endif /* _MB_CAPABLE */
94}
95
96#ifndef _REENT_ONLY
97struct __locale_t *
98duplocale (struct __locale_t *locobj)
99{
100  return _duplocale_r (_REENT, locobj);
101}
102#endif
Note: See TracBrowser for help on using the repository browser.