rpm 5.2.1

- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List
- Globals

strtolocale.c
Go to the documentation of this file.
1
5 #include "system.h"
6 #ifdef HAVE_LANGINFO_H
7 #include <langinfo.h>
8 #endif
9 #ifdef HAVE_ICONV
10 #include <iconv.h>
11 #endif
12 #include <rpmiotypes.h>
13 #include "debug.h"
14
15 const char * xstrtolocale(const char *str)
16 {
17 #ifdef HAVE_ICONV
18 /*@only@*/
19 static char *locale_encoding = NULL;
20 static int locale_encoding_is_utf8 = 0;
21 iconv_t cd;
22 size_t src_size, dest_size;
23 char *result, *dest;
24 const char *src;
25
26 if (locale_encoding == NULL) {
27 #ifdef HAVE_LANGINFO_H
28 const char *encoding = nl_langinfo(CODESET);
29 #else
30 const char *encoding = "char";
31 #endif
32 locale_encoding = xmalloc(strlen(encoding) + 11);
33 sprintf(locale_encoding, "%s//TRANSLIT", encoding);
34 locale_encoding_is_utf8 = strcasecmp(encoding, "UTF-8") == 0;
35 }
36
37 if (!str || !*str || locale_encoding_is_utf8)
38 return str;
39
40 cd = iconv_open(locale_encoding, "UTF-8");
41 if (cd == (iconv_t)-1)
42 return str;
43
44 src_size = strlen(str);
45 dest_size = src_size + 1;
46 result = xmalloc(dest_size);
47 src = str;
48 dest = result;
49 for(;;) {
50 size_t status = iconv(cd, (char **)&src, &src_size, &dest, &dest_size);
51 if (status == (size_t)-1) {
52 size_t dest_offset;
53 if (errno != E2BIG) {
54 free(result);
55 (void) iconv_close(cd);
56 return str;
57 }
58 dest_offset = dest - result;
59 dest_size += 16;
60 result = xrealloc(result, dest_offset + dest_size);
61 dest = result + dest_offset;
62 } else if (src_size == 0) {
63 if (src == NULL) break;
64 src = NULL;
65 }
66 }
67 (void) iconv_close(cd);
68 free((void *)str);
69 if (dest_size == 0) {
70 size_t dest_offset = dest - result;
71 result = xrealloc(result, dest_offset + 1);
72 dest = result + dest_offset;
73 }
74 *dest = '\0';
75 return result;
76 #else
77 return str;
78 #endif
79 }