1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21: #include <alloca.h>
22: #include <errno.h>
23: #include <iconv.h>
24: #include <stdbool.h>
25: #include <stdlib.h>
26: #include <string.h>
27:
28: #include <gconv_int.h>
29: #include "gconv_charset.h"
30:
31:
32: iconv_t
33: iconv_open (const char *tocode, const char *fromcode)
34: {
35:
36:
37: size_t tocode_len = strlen (tocode) + 3;
38: char *tocode_conv;
39: bool tocode_usealloca = __libc_use_alloca (tocode_len);
40: if (tocode_usealloca)
41: tocode_conv = (char *) alloca (tocode_len);
42: else
43: {
44: tocode_conv = (char *) malloc (tocode_len);
45: if (tocode_conv == NULL)
46: return (iconv_t) -1;
47: }
48: strip (tocode_conv, tocode);
49: tocode = (tocode_conv[2] == '\0' && tocode[0] != '\0'
50: ? upstr (tocode_conv, tocode) : tocode_conv);
51:
52: size_t fromcode_len = strlen (fromcode) + 3;
53: char *fromcode_conv;
54: bool fromcode_usealloca = __libc_use_alloca (fromcode_len);
55: if (fromcode_usealloca)
56: fromcode_conv = (char *) alloca (fromcode_len);
57: else
58: {
59: fromcode_conv = (char *) malloc (fromcode_len);
60: if (fromcode_conv == NULL)
61: {
62: if (! tocode_usealloca)
63: free (tocode_conv);
64: return (iconv_t) -1;
65: }
66: }
67: strip (fromcode_conv, fromcode);
68: fromcode = (fromcode_conv[2] == '\0' && fromcode[0] != '\0'
69: ? upstr (fromcode_conv, fromcode) : fromcode_conv);
70:
71: __gconv_t cd;
72: int res = __gconv_open (tocode, fromcode, &cd, 0);
73:
74: if (! fromcode_usealloca)
75: free (fromcode_conv);
76: if (! tocode_usealloca)
77: free (tocode_conv);
78:
79: if (__builtin_expect (res, __GCONV_OK) != __GCONV_OK)
80: {
81:
82: if (res == __GCONV_NOCONV || res == __GCONV_NODB)
83: __set_errno (EINVAL);
84:
85: cd = (iconv_t) -1;
86: }
87:
88: return (iconv_t) cd;
89: }