1 /* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 12 /* 13 * Copyright 2010 Nexenta Systems, Inc. All rights reserved. 14 * Copyright 2013 David Hoeppner. All rights reserved. 15 */ 16 17 /* 18 * Character map handling for iconv. 19 */ 20 21 #include <sys/avl.h> 22 23 #include <stddef.h> 24 25 #include "iconv.h" 26 #include "parser.tab.h" 27 28 /* 29 * AVL trees for the from and to charmaps. 30 */ 31 static avl_tree_t from_cmap_sym; 32 static avl_tree_t from_cmap_wc; 33 static avl_tree_t to_cmap_sym; 34 static avl_tree_t to_cmap_wc; 35 36 static avl_tree_t *current_cmap_sym = &from_cmap_sym; 37 static avl_tree_t *current_cmap_wc = &from_cmap_wc; 38 39 typedef struct charmap { 40 const char *name; 41 wchar_t wc; 42 avl_node_t avl_sym; 43 avl_node_t avl_wc; 44 } charmap_t; 45 46 static int 47 cmap_compare_sym(const void *n1, const void *n2) 48 { 49 const charmap_t *c1 = n1; 50 const charmap_t *c2 = n2; 51 int rv; 52 53 rv = strcmp(c1->name, c2->name); 54 return ((rv < 0) ? -1 : (rv > 0) ? 1 : 0); 55 } 56 57 static int 58 cmap_compare_wc(const void *n1, const void *n2) 59 { 60 const charmap_t *c1 = n1; 61 const charmap_t *c2 = n2; 62 63 return ((c1->wc < c2->wc) ? -1 : (c1->wc > c2->wc) ? 1 : 0); 64 } 65 66 void 67 init_charmap(void) 68 { 69 avl_create(&from_cmap_sym, cmap_compare_sym, sizeof (charmap_t), 70 offsetof(charmap_t, avl_sym)); 71 72 avl_create(&from_cmap_wc, cmap_compare_wc, sizeof (charmap_t), 73 offsetof(charmap_t, avl_wc)); 74 75 avl_create(&to_cmap_sym, cmap_compare_sym, sizeof (charmap_t), 76 offsetof(charmap_t, avl_sym)); 77 78 avl_create(&to_cmap_wc, cmap_compare_wc, sizeof (charmap_t), 79 offsetof(charmap_t, avl_wc)); 80 } 81 82 /* 83 * Switches from fromcharmap to tocharmap. 84 */ 85 void 86 switch_charmap(void) 87 { 88 current_cmap_sym = &to_cmap_sym; 89 current_cmap_wc = &to_cmap_wc; 90 } 91 92 static void 93 add_charmap_impl(char *sym, wchar_t wc, int nodups) 94 { 95 charmap_t srch; 96 charmap_t *n = NULL; 97 avl_index_t where; 98 99 srch.wc = wc; 100 srch.name = sym; 101 102 /* 103 * Also possibly insert the wide mapping, although note that there 104 * can only be one of these per wide character code. 105 */ 106 if ((wc != -1) && ((avl_find(current_cmap_wc, &srch, &where)) == NULL)) { 107 if ((n = calloc(1, sizeof (*n))) == NULL) { 108 errf(_("out of memory")); 109 return; 110 } 111 112 n->wc = wc; 113 avl_insert(current_cmap_wc, n, where); 114 } 115 116 if (sym != NULL) { 117 if (avl_find(current_cmap_sym, &srch, &where) != NULL) { 118 if (nodups == 1) { 119 errf(_("duplicate character definition")); 120 } 121 122 return; 123 } 124 125 if ((n == NULL) && ((n = calloc(1, sizeof (*n))) == NULL)) { 126 errf(_("out of memory")); 127 return; 128 } 129 130 n->wc = wc; 131 n->name = sym; 132 printf("ADDING %s\n", sym); 133 avl_insert(current_cmap_sym, n, where); 134 } 135 } 136 137 void 138 add_charmap(char *sym, int c) 139 { 140 add_charmap_impl(sym, c, 1); 141 } 142 143 void 144 add_charmap_range(char *s, char *e, int wc) 145 { 146 147 }