| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: chartype.c,v 1.10 2011/08/16 16:25:15 christos Exp $ */ | | 1 | /* $NetBSD: chartype.c,v 1.10.20.1 2015/04/14 05:30:24 snj Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2009 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 2009 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
| @@ -28,136 +28,144 @@ | | | @@ -28,136 +28,144 @@ |
28 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | 28 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
29 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | 29 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
30 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | 30 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
31 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 31 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
32 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 32 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
33 | * POSSIBILITY OF SUCH DAMAGE. | | 33 | * POSSIBILITY OF SUCH DAMAGE. |
34 | */ | | 34 | */ |
35 | | | 35 | |
36 | /* | | 36 | /* |
37 | * chartype.c: character classification and meta information | | 37 | * chartype.c: character classification and meta information |
38 | */ | | 38 | */ |
39 | #include "config.h" | | 39 | #include "config.h" |
40 | #if !defined(lint) && !defined(SCCSID) | | 40 | #if !defined(lint) && !defined(SCCSID) |
41 | __RCSID("$NetBSD: chartype.c,v 1.10 2011/08/16 16:25:15 christos Exp $"); | | 41 | __RCSID("$NetBSD: chartype.c,v 1.10.20.1 2015/04/14 05:30:24 snj Exp $"); |
42 | #endif /* not lint && not SCCSID */ | | 42 | #endif /* not lint && not SCCSID */ |
43 | #include "el.h" | | 43 | #include "el.h" |
44 | #include <stdlib.h> | | 44 | #include <stdlib.h> |
45 | | | 45 | |
46 | #define CT_BUFSIZ ((size_t)1024) | | 46 | #define CT_BUFSIZ ((size_t)1024) |
47 | | | 47 | |
48 | #ifdef WIDECHAR | | 48 | #ifdef WIDECHAR |
49 | protected void | | 49 | protected int |
50 | ct_conv_buff_resize(ct_buffer_t *conv, size_t mincsize, size_t minwsize) | | 50 | ct_conv_cbuff_resize(ct_buffer_t *conv, size_t csize) |
51 | { | | 51 | { |
52 | void *p; | | 52 | void *p; |
53 | if (mincsize > conv->csize) { | | 53 | |
54 | conv->csize = mincsize; | | 54 | if (csize <= conv->csize) |
55 | p = el_realloc(conv->cbuff, conv->csize * sizeof(*conv->cbuff)); | | 55 | return 0; |
56 | if (p == NULL) { | | 56 | |
57 | conv->csize = 0; | | 57 | conv->csize = csize; |
58 | el_free(conv->cbuff); | | 58 | |
59 | conv->cbuff = NULL; | | 59 | p = el_realloc(conv->cbuff, conv->csize * sizeof(*conv->cbuff)); |
60 | } else | | 60 | if (p == NULL) { |
61 | conv->cbuff = p; | | 61 | conv->csize = 0; |
| | | 62 | el_free(conv->cbuff); |
| | | 63 | conv->cbuff = NULL; |
| | | 64 | return -1; |
62 | } | | 65 | } |
| | | 66 | conv->cbuff = p; |
| | | 67 | return 0; |
| | | 68 | } |
63 | | | 69 | |
64 | if (minwsize > conv->wsize) { | | 70 | protected int |
65 | conv->wsize = minwsize; | | 71 | ct_conv_wbuff_resize(ct_buffer_t *conv, size_t wsize) |
66 | p = el_realloc(conv->wbuff, conv->wsize * sizeof(*conv->wbuff)); | | 72 | { |
67 | if (p == NULL) { | | 73 | void *p; |
68 | conv->wsize = 0; | | 74 | |
69 | el_free(conv->wbuff); | | 75 | if (wsize <= conv->wsize) |
70 | conv->wbuff = NULL; | | 76 | return 0; |
71 | } else | | 77 | |
72 | conv->wbuff = p; | | 78 | conv->wsize = wsize; |
| | | 79 | |
| | | 80 | p = el_realloc(conv->wbuff, conv->wsize * sizeof(*conv->wbuff)); |
| | | 81 | if (p == NULL) { |
| | | 82 | conv->wsize = 0; |
| | | 83 | el_free(conv->wbuff); |
| | | 84 | conv->wbuff = NULL; |
| | | 85 | return -1; |
73 | } | | 86 | } |
| | | 87 | conv->wbuff = p; |
| | | 88 | return 0; |
74 | } | | 89 | } |
75 | | | 90 | |
76 | | | 91 | |
77 | public char * | | 92 | public char * |
78 | ct_encode_string(const Char *s, ct_buffer_t *conv) | | 93 | ct_encode_string(const Char *s, ct_buffer_t *conv) |
79 | { | | 94 | { |
80 | char *dst; | | 95 | char *dst; |
81 | ssize_t used = 0; | | 96 | ssize_t used; |
82 | | | 97 | |
83 | if (!s) | | 98 | if (!s) |
84 | return NULL; | | 99 | return NULL; |
85 | if (!conv->cbuff) | | | |
86 | ct_conv_buff_resize(conv, CT_BUFSIZ, (size_t)0); | | | |
87 | if (!conv->cbuff) | | | |
88 | return NULL; | | | |
89 | | | 100 | |
90 | dst = conv->cbuff; | | 101 | dst = conv->cbuff; |
91 | while (*s) { | | 102 | for (;;) { |
92 | used = (ssize_t)(conv->csize - (size_t)(dst - conv->cbuff)); | | 103 | used = (ssize_t)(dst - conv->cbuff); |
93 | if (used < 5) { | | 104 | if ((conv->csize - (size_t)used) < 5) { |
94 | used = dst - conv->cbuff; | | 105 | if (ct_conv_cbuff_resize(conv, |
95 | ct_conv_buff_resize(conv, conv->csize + CT_BUFSIZ, | | 106 | conv->csize + CT_BUFSIZ) == -1) |
96 | (size_t)0); | | | |
97 | if (!conv->cbuff) | | | |
98 | return NULL; | | 107 | return NULL; |
99 | dst = conv->cbuff + used; | | 108 | dst = conv->cbuff + used; |
100 | } | | 109 | } |
| | | 110 | if (!*s) |
| | | 111 | break; |
101 | used = ct_encode_char(dst, (size_t)5, *s); | | 112 | used = ct_encode_char(dst, (size_t)5, *s); |
102 | if (used == -1) /* failed to encode, need more buffer space */ | | 113 | if (used == -1) /* failed to encode, need more buffer space */ |
103 | abort(); | | 114 | abort(); |
104 | ++s; | | 115 | ++s; |
105 | dst += used; | | 116 | dst += used; |
106 | } | | 117 | } |
107 | *dst = '\0'; | | 118 | *dst = '\0'; |
108 | return conv->cbuff; | | 119 | return conv->cbuff; |
109 | } | | 120 | } |
110 | | | 121 | |
111 | public Char * | | 122 | public Char * |
112 | ct_decode_string(const char *s, ct_buffer_t *conv) | | 123 | ct_decode_string(const char *s, ct_buffer_t *conv) |
113 | { | | 124 | { |
114 | size_t len = 0; | | 125 | size_t len; |
115 | | | 126 | |
116 | if (!s) | | 127 | if (!s) |
117 | return NULL; | | 128 | return NULL; |
118 | if (!conv->wbuff) | | | |
119 | ct_conv_buff_resize(conv, (size_t)0, CT_BUFSIZ); | | | |
120 | if (!conv->wbuff) | | | |
121 | return NULL; | | | |
122 | | | 129 | |
123 | len = ct_mbstowcs(NULL, s, (size_t)0); | | 130 | len = ct_mbstowcs(NULL, s, (size_t)0); |
124 | if (len == (size_t)-1) | | 131 | if (len == (size_t)-1) |
125 | return NULL; | | 132 | return NULL; |
126 | if (len > conv->wsize) | | 133 | |
127 | ct_conv_buff_resize(conv, (size_t)0, len + 1); | | 134 | if (conv->wsize < ++len) |
128 | if (!conv->wbuff) | | 135 | if (ct_conv_wbuff_resize(conv, len + CT_BUFSIZ) == -1) |
129 | return NULL; | | 136 | return NULL; |
| | | 137 | |
130 | ct_mbstowcs(conv->wbuff, s, conv->wsize); | | 138 | ct_mbstowcs(conv->wbuff, s, conv->wsize); |
131 | return conv->wbuff; | | 139 | return conv->wbuff; |
132 | } | | 140 | } |
133 | | | 141 | |
134 | | | 142 | |
135 | protected Char ** | | 143 | protected Char ** |
136 | ct_decode_argv(int argc, const char *argv[], ct_buffer_t *conv) | | 144 | ct_decode_argv(int argc, const char *argv[], ct_buffer_t *conv) |
137 | { | | 145 | { |
138 | size_t bufspace; | | 146 | size_t bufspace; |
139 | int i; | | 147 | int i; |
140 | Char *p; | | 148 | Char *p; |
141 | Char **wargv; | | 149 | Char **wargv; |
142 | ssize_t bytes; | | 150 | ssize_t bytes; |
143 | | | 151 | |
144 | /* Make sure we have enough space in the conversion buffer to store all | | 152 | /* Make sure we have enough space in the conversion buffer to store all |
145 | * the argv strings. */ | | 153 | * the argv strings. */ |
146 | for (i = 0, bufspace = 0; i < argc; ++i) | | 154 | for (i = 0, bufspace = 0; i < argc; ++i) |
147 | bufspace += argv[i] ? strlen(argv[i]) + 1 : 0; | | 155 | bufspace += argv[i] ? strlen(argv[i]) + 1 : 0; |
148 | ct_conv_buff_resize(conv, (size_t)0, bufspace); | | 156 | if (conv->wsize < ++bufspace) |
149 | if (!conv->wsize) | | 157 | if (ct_conv_wbuff_resize(conv, bufspace + CT_BUFSIZ) == -1) |
150 | return NULL; | | 158 | return NULL; |
151 | | | 159 | |
152 | wargv = el_malloc((size_t)argc * sizeof(*wargv)); | | 160 | wargv = el_malloc((size_t)argc * sizeof(*wargv)); |
153 | | | 161 | |
154 | for (i = 0, p = conv->wbuff; i < argc; ++i) { | | 162 | for (i = 0, p = conv->wbuff; i < argc; ++i) { |
155 | if (!argv[i]) { /* don't pass null pointers to mbstowcs */ | | 163 | if (!argv[i]) { /* don't pass null pointers to mbstowcs */ |
156 | wargv[i] = NULL; | | 164 | wargv[i] = NULL; |
157 | continue; | | 165 | continue; |
158 | } else { | | 166 | } else { |
159 | wargv[i] = p; | | 167 | wargv[i] = p; |
160 | bytes = (ssize_t)mbstowcs(p, argv[i], bufspace); | | 168 | bytes = (ssize_t)mbstowcs(p, argv[i], bufspace); |
161 | } | | 169 | } |
162 | if (bytes == -1) { | | 170 | if (bytes == -1) { |
163 | el_free(wargv); | | 171 | el_free(wargv); |