Add example 5.
[libidn.git] / src / idn.c
blob727d96a26452480fd04db80447182f99237149a2
1 /* idn.c Command line interface to the library
2 * Copyright (C) 2003, 2004 Simon Josefsson
4 * This file is part of GNU Libidn.
6 * GNU Libidn is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * GNU Libidn is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Libidn; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #if HAVE_CONFIG_H
23 # include "config.h"
24 #endif
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
30 #include <stringprep.h>
31 #include <punycode.h>
32 #include <idna.h>
33 #ifdef WITH_TLD
34 # include <tld.h>
35 #endif
37 #include "idn_cmd.h"
39 #define GREETING "Copyright 2002, 2003, 2004 Simon Josefsson.\n" \
40 "GNU Libidn comes with NO WARRANTY, to the extent permitted by law.\n" \
41 "You may redistribute copies of GNU Libidn under the terms of\n" \
42 "the GNU Lesser General Public License. For more information\n" \
43 "about these matters, see the file named COPYING.LIB.\n"
45 int
46 main (int argc, char *argv[])
48 struct gengetopt_args_info args_info;
49 char readbuf[BUFSIZ];
50 char *p, *r;
51 uint32_t *q;
52 unsigned cmdn = 0;
53 int rc;
55 if (cmdline_parser (argc, argv, &args_info) != 0)
56 return 1;
58 if (!args_info.stringprep_given &&
59 !args_info.punycode_encode_given && !args_info.punycode_decode_given &&
60 !args_info.idna_to_ascii_given && !args_info.idna_to_unicode_given)
61 args_info.idna_to_ascii_given = 1;
63 if ((args_info.stringprep_given ? 1 : 0) +
64 (args_info.punycode_encode_given ? 1 : 0) +
65 (args_info.punycode_decode_given ? 1 : 0) +
66 (args_info.idna_to_ascii_given ? 1 : 0) +
67 (args_info.idna_to_unicode_given ? 1 : 0) != 1)
69 fprintf (stderr,
70 "%s: Only one of -s, -e, -d, -a or -u can be specified.\n",
71 argv[0]);
72 cmdline_parser_print_help ();
73 return 1;
76 if (!args_info.quiet_given)
77 fprintf (stderr, "%s %s\n" GREETING, PACKAGE, VERSION);
79 if (args_info.debug_given)
80 fprintf (stderr, "system locale uses charset `%s'.\n",
81 stringprep_locale_charset ());
83 if (!args_info.quiet_given && args_info.inputs_num == 0)
84 fprintf (stderr, "Type each input string on a line by itself, "
85 "terminated by a newline character.\n");
89 if (cmdn < args_info.inputs_num)
91 strncpy (readbuf, args_info.inputs[cmdn++], BUFSIZ - 1);
92 readbuf[BUFSIZ - 1] = '\0';
94 else if (fgets (readbuf, BUFSIZ, stdin) == NULL)
96 sprintf (readbuf, "%s: fgets() failed: ", argv[0]);
97 if (!feof (stdin))
98 perror (readbuf);
99 return 1;
102 if (readbuf[strlen (readbuf) - 1] == '\n')
103 readbuf[strlen (readbuf) - 1] = '\0';
105 if (args_info.stringprep_given)
107 p = stringprep_locale_to_utf8 (readbuf);
108 if (!p)
110 fprintf (stderr, "%s: could not convert from %s to UTF-8.\n",
111 argv[0], stringprep_locale_charset ());
112 return 1;
115 q = stringprep_utf8_to_ucs4 (p, -1, NULL);
116 if (!q)
118 free (p);
119 fprintf (stderr, "%s: could not convert from UTF-8 to UCS-4.\n",
120 argv[0]);
121 return 1;
124 if (args_info.debug_given)
126 size_t i;
127 for (i = 0; q[i]; i++)
128 fprintf (stderr, "input[%d] = U+%04x\n", i, q[i]);
130 free (q);
132 rc = stringprep_profile (p, &r,
133 args_info.profile_given ?
134 args_info.profile_arg : "Nameprep", 0);
135 free (p);
136 if (rc != STRINGPREP_OK)
138 fprintf (stderr,
139 "%s: stringprep_profile() failed with error %d.\n",
140 argv[0], rc);
141 return 1;
144 q = stringprep_utf8_to_ucs4 (r, -1, NULL);
145 if (!q)
147 free (r);
148 fprintf (stderr, "%s: could not convert from UTF-8 to UCS-4.\n",
149 argv[0]);
150 return 1;
153 if (args_info.debug_given)
155 size_t i;
156 for (i = 0; q[i]; i++)
157 fprintf (stderr, "output[%d] = U+%04x\n", i, q[i]);
159 free (q);
161 p = stringprep_utf8_to_locale (r);
162 free (r);
163 if (!p)
165 fprintf (stderr, "%s: could not convert from UTF-8 to %s.\n",
166 argv[0], stringprep_locale_charset ());
167 return 1;
170 fprintf (stdout, "%s\n", p);
172 free (p);
175 if (args_info.punycode_encode_given)
177 size_t len, len2;
179 p = stringprep_locale_to_utf8 (readbuf);
180 if (!p)
182 fprintf (stderr, "%s: could not convert from %s to UTF-8.\n",
183 argv[0], stringprep_locale_charset ());
184 return 1;
187 q = stringprep_utf8_to_ucs4 (p, -1, &len);
188 free (p);
189 if (!q)
191 fprintf (stderr, "%s: could not convert from UTF-8 to UCS-4.\n",
192 argv[0]);
193 return 1;
196 if (args_info.debug_given)
198 size_t i;
199 for (i = 0; i < len; i++)
200 fprintf (stderr, "input[%d] = U+%04x\n", i, q[i]);
203 len2 = BUFSIZ;
204 rc = punycode_encode (len, q, NULL, &len2, readbuf);
205 free (q);
206 if (rc != PUNYCODE_SUCCESS)
208 fprintf (stderr,
209 "%s: punycode_encode() failed with error %d.\n",
210 argv[0], rc);
211 return 1;
214 readbuf[len2] = '\0';
216 p = stringprep_utf8_to_locale (readbuf);
217 if (!p)
219 fprintf (stderr, "%s: could not convert from UTF-8 to %s.\n",
220 argv[0], stringprep_locale_charset ());
221 return 1;
224 fprintf (stdout, "%s\n", p);
226 free (p);
229 if (args_info.punycode_decode_given)
231 size_t len;
233 len = BUFSIZ;
234 q = (uint32_t *) malloc (len * sizeof (q[0]));
235 if (!q)
237 sprintf (readbuf, "%s: malloc() failed: ", argv[0]);
238 perror (readbuf);
239 return 1;
243 rc = punycode_decode (strlen (readbuf), readbuf, &len, q, NULL);
244 if (rc != PUNYCODE_SUCCESS)
246 free (q);
247 fprintf (stderr,
248 "%s: punycode_decode() failed with error %d.\n",
249 argv[0], rc);
250 return 1;
253 if (args_info.debug_given)
255 size_t i;
256 for (i = 0; i < len; i++)
257 fprintf (stderr, "output[%d] = U+%04x\n", i, q[i]);
260 q[len] = 0;
261 r = stringprep_ucs4_to_utf8 (q, -1, NULL, NULL);
262 free (q);
263 if (!r)
265 fprintf (stderr, "%s: could not convert from UCS-4 to UTF-8.\n",
266 argv[0]);
267 return 1;
270 p = stringprep_utf8_to_locale (r);
271 free (r);
272 if (!r)
274 fprintf (stderr, "%s: could not convert from UTF-8 to %s.\n",
275 argv[0], stringprep_locale_charset ());
276 return 1;
279 fprintf (stdout, "%s\n", p);
281 free (p);
284 if (args_info.idna_to_ascii_given)
286 p = stringprep_locale_to_utf8 (readbuf);
287 if (!p)
289 fprintf (stderr, "%s: could not convert from %s to UTF-8.\n",
290 argv[0], stringprep_locale_charset ());
291 return 1;
293 q = stringprep_utf8_to_ucs4 (p, -1, NULL);
294 if (!q)
296 free (p);
297 fprintf (stderr, "%s: could not convert from UCS-4 to UTF-8.\n",
298 argv[0]);
299 return 1;
302 if (args_info.debug_given)
304 size_t i;
305 for (i = 0; q[i]; i++)
306 fprintf (stderr, "input[%d] = U+%04x\n", i, q[i]);
309 #ifdef WITH_TLD
310 if (args_info.tld_flag)
312 const Tld_table *tld;
313 size_t errpos;
315 rc = tld_check_8z (p, &errpos, NULL);
316 if (rc == TLD_INVALID)
318 fprintf (stderr,
319 "%s: string rejected by TLD test (pos %d): %s\n",
320 argv[0], errpos, p);
321 free (p);
322 return 1;
325 if (rc != TLD_SUCCESS)
327 fprintf (stderr,
328 "%s: tld_check_lz(%s) failed with error %d.\n",
329 argv[0], p, rc);
330 free (p);
331 return 1;
334 #endif
335 free (p);
337 rc = idna_to_ascii_4z (q, &p,
338 (args_info.allow_unassigned_given ?
339 IDNA_ALLOW_UNASSIGNED : 0) |
340 (args_info.usestd3asciirules_given ?
341 IDNA_USE_STD3_ASCII_RULES : 0));
342 free (q);
343 if (rc != IDNA_SUCCESS)
345 fprintf (stderr, "%s: idna_to_ascii_4z() failed "
346 "with error %d.\n", argv[0], rc);
347 return 1;
350 if (args_info.debug_given)
352 size_t i;
353 for (i = 0; p[i]; i++)
354 fprintf (stderr, "output[%d] = U+%04x\n", i, p[i]);
357 fprintf (stdout, "%s\n", p);
359 free (p);
362 if (args_info.idna_to_unicode_given)
364 p = stringprep_locale_to_utf8 (readbuf);
365 if (!p)
367 fprintf (stderr, "%s: could not convert from %s to UTF-8.\n",
368 argv[0], stringprep_locale_charset ());
369 return 1;
372 q = stringprep_utf8_to_ucs4 (p, -1, NULL);
373 if (!q)
375 free (p);
376 fprintf (stderr, "%s: could not convert from UCS-4 to UTF-8.\n",
377 argv[0]);
378 return 1;
381 if (args_info.debug_given)
383 size_t i;
384 for (i = 0; q[i]; i++)
385 fprintf (stderr, "input[%d] = U+%04x\n", i, q[i]);
387 free (q);
389 #ifdef WITH_TLD
390 if (args_info.tld_flag)
392 const Tld_table *tld;
393 size_t errpos;
395 rc = tld_check_8z (p, &errpos, NULL);
396 if (rc == TLD_INVALID)
398 fprintf (stderr,
399 "%s: string rejected by TLD test (pos %d): %s\n",
400 argv[0], errpos, p);
401 free (p);
402 return 1;
405 if (rc != TLD_SUCCESS)
407 fprintf (stderr,
408 "%s: tld_check_lz(%s) failed with error %d.\n",
409 argv[0], p, rc);
410 free (p);
411 return 1;
414 #endif
416 rc = idna_to_unicode_8z4z (p, &q,
417 (args_info.allow_unassigned_given ?
418 IDNA_ALLOW_UNASSIGNED : 0) |
419 (args_info.usestd3asciirules_given ?
420 IDNA_USE_STD3_ASCII_RULES : 0));
421 free (p);
422 if (rc != IDNA_SUCCESS)
424 fprintf (stderr, "%s: idna_to_unicode_8z4z() "
425 "failed with error %d.\n", argv[0], rc);
426 return 1;
429 if (args_info.debug_given)
431 size_t i;
432 for (i = 0; q[i]; i++)
433 fprintf (stderr, "output[%d] = U+%04x\n", i, q[i]);
436 r = stringprep_ucs4_to_utf8 (q, -1, NULL, NULL);
437 free (q);
438 if (!r)
440 fprintf (stderr, "%s: could not convert from UTF-8 to UCS-4.\n",
441 argv[0]);
442 return 1;
445 p = stringprep_utf8_to_locale (r);
446 free (r);
447 if (!r)
449 fprintf (stderr, "%s: could not convert from UTF-8 to %s.\n",
450 argv[0], stringprep_locale_charset ());
451 return 1;
454 fprintf (stdout, "%s\n", p);
456 free (p);
459 while (!feof (stdin) && !ferror (stdin) && (args_info.inputs_num == 0 ||
460 cmdn < args_info.inputs_num));
462 return 0;