1 /*
2 ** Copyright 2011 Double Precision, Inc.
3 ** See COPYING for distribution information.
4 **
5 */
6 
7 #include	"unicode_config.h"
8 #include	"courier-unicode.h"
9 #include	<string.h>
10 #include	<stdlib.h>
11 #include	<stdio.h>
12 #include	<errno.h>
13 
14 struct collect_buf {
15 	char *ptr;
16 	size_t cnt;
17 	size_t size;
18 };
19 
save_output(const char * p,size_t n,void * ptr)20 static int save_output(const char *p, size_t n, void *ptr)
21 {
22 	struct collect_buf *cb=(struct collect_buf *)ptr;
23 
24 	while (n)
25 	{
26 		if (cb->cnt < cb->size)
27 			cb->ptr[cb->cnt++]=*p;
28 		++p;
29 		--n;
30 	}
31 	return 0;
32 }
33 
test1()34 static void test1()
35 {
36 	static const char teststr[]= {
37 		0x00, 0x00, 0x00, 0x41,
38 		0x00, 0x00, 0x04, 0x14,
39 		0x00, 0x00, 0x04, 0x30,
40 		0x00, 0x00, 0x00, 0x42};
41 	char outputbuf[12];
42 	struct collect_buf cb;
43 	unicode_convert_handle_t h;
44 	int checkflag;
45 
46 	cb.ptr=outputbuf;
47 	cb.cnt=0;
48 	cb.size=sizeof(outputbuf);
49 
50 	if ((h=unicode_convert_init("UCS-4BE", "ISO-8859-1",
51 				      save_output, &cb)) == NULL)
52 	{
53 		perror("unicode_convert_init");
54 		exit(1);
55 	}
56 
57 	unicode_convert(h, teststr, sizeof(teststr));
58 
59 	if (unicode_convert_deinit(h, &checkflag))
60 	{
61 		perror("unicode_convert_deinit");
62 		exit(1);
63 	}
64 	if (cb.cnt != 2 || memcmp(cb.ptr, "AB", 2) || !checkflag)
65 	{
66 		fprintf(stderr, "Unexpected result from convert()\n");
67 		exit(1);
68 	}
69 }
70 
test2()71 static void test2()
72 {
73 	char32_t *ucptr;
74 	size_t ucsize;
75 	unicode_convert_handle_t h=
76 		unicode_convert_tou_init("utf-8", &ucptr, &ucsize, 1);
77 	char *cptr;
78 	size_t csize;
79 
80 	if (h)
81 	{
82 		size_t i;
83 
84 		for (i=0; i<1024/32; ++i)
85 			unicode_convert(h, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
86 					  32);
87 
88 		if (unicode_convert_deinit(h, NULL) == 0 &&
89 		    ucsize == 1024+1)
90 		{
91 			for (i=0; i<1024; i++)
92 				if (ucptr[i] != 'A')
93 					break;
94 
95 			if (i == 1024)
96 			{
97 				h=unicode_convert_fromu_init("utf-8",
98 							       &cptr, &csize,
99 							       1);
100 
101 				if (h)
102 				{
103 					unicode_convert_uc(h, ucptr, 1024);
104 					if (unicode_convert_deinit(h, NULL)
105 					    == 0 && csize == 1024+1)
106 					{
107 						for (i=0; i<1024; i++)
108 							if (cptr[i] != 'A')
109 								break;
110 
111 						free(ucptr);
112 						free(cptr);
113 						if (i == 1024)
114 							return;
115 					}
116 				}
117 			}
118 		}
119 		fprintf(stderr, "test2: failed");
120 		errno=EINVAL;
121 	}
122 	perror("test2");
123 	exit(1);
124 }
125 
testunicodebuf()126 void testunicodebuf()
127 {
128 	struct unicode_buf buf;
129 
130 	unicode_buf_init(&buf, -1);
131 	unicode_buf_append_char(&buf, "01234567", 8);
132 	unicode_buf_remove(&buf, 1, 6);
133 
134 	if (unicode_buf_len(&buf) != 2 ||
135 	    unicode_buf_ptr(&buf)[0] != '0' ||
136 	    unicode_buf_ptr(&buf)[1] != '7')
137 	{
138 		fprintf(stderr, "unicode_buf_remove failed\n");
139 		exit(1);
140 	}
141 	unicode_buf_deinit(&buf);
142 }
143 
main(int argc,char ** argv)144 int main(int argc, char **argv)
145 {
146 	const char *chset=unicode_x_imap_modutf7;
147 	int argn=1;
148 
149 	testunicodebuf();
150 	if (argn < argc && strcmp(argv[argn], "--smap") == 0)
151 	{
152 		chset=unicode_x_imap_modutf7 " ./~:";
153 		++argn;
154 	}
155 
156 	if (argn < argc && strcmp(argv[argn], "--smaputf8") == 0)
157 	{
158 		chset=unicode_x_smap_modutf8;
159 		++argn;
160 	}
161 
162 	if (argn < argc && strcmp(argv[argn], "--modutf7toutf8") == 0)
163 	{
164 		while (++argn < argc)
165 		{
166 			int error=0;
167 			char *p=unicode_convert_tobuf(argv[argn],
168 						      unicode_x_imap_modutf7,
169 						      unicode_x_smap_modutf8,
170 						      &error);
171 
172 			if (p)
173 			{
174 				printf("%s\n", p);
175 				free(p);
176 			}
177 			else
178 			{
179 				printf("[error]\n");
180 			}
181 		}
182 	}
183 
184 	if (argn < argc && strcmp(argv[argn], "--totitle") == 0)
185 	{
186 		++argn;
187 
188 		if (argn < argc)
189 		{
190 			char *p=unicode_convert_tocase(argv[argn],
191 							 "utf-8",
192 							 unicode_tc,
193 							 unicode_lc);
194 
195 			if (p)
196 			{
197 				printf("%s\n", p);
198 				free(p);
199 				exit(0);
200 			}
201 		}
202 		exit(1);
203 	}
204 
205 	if (argn < argc)
206 	{
207 		int errflag;
208 		char *p=unicode_convert_tobuf(argv[argn],
209 						"utf-8",
210 						chset,
211 						&errflag);
212 		char *q;
213 
214 		if (!p)
215 		{
216 			perror("unicode_convert");
217 			exit(1);
218 		}
219 
220 		if (errflag)
221 		{
222 			fprintf(stderr, "Conversion error?\n");
223 			exit(1);
224 		}
225 
226 		q=unicode_convert_tobuf(p, chset, "utf-8", &errflag);
227 		if (!q)
228 		{
229 			perror("unicode_convert");
230 			exit(1);
231 		}
232 
233 		if (errflag)
234 		{
235 			fprintf(stderr, "Conversion error?\n");
236 			exit(1);
237 		}
238 		if (strcmp(q, argv[argn]))
239 		{
240 			fprintf(stderr, "Round trip error\n");
241 			exit(1);
242 		}
243 		printf("%s\n", p);
244 		free(p);
245 		free(q);
246 	}
247 	else
248 	{
249 		test1();
250 		test2();
251 	}
252 	return 0;
253 }
254