1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright (c) 1996, by Sun Microsystems, Inc.
24  * All rights reserved.
25  */
26 
27 /*
28  * Implementation of the mks M_INVARIANT family of mapping macros.
29  * Based on the IBM C/370 getsyntx() and variant.h implementation.
30  *
31  * Copyright 1993 by Mortice Kern Systems Inc.  All rights reserved.
32  *
33  */
34 
35 #ifdef M_RCSID
36 #ifndef lint
37 static char const rcsID[] = "$Header: /rd/src/libc/mks/rcs/m_varian.c 1.14 1994/12/08 23:14:58 ross Exp $";
38 #endif /* lint */
39 #endif /* M_RCSID */
40 
41 #include <mks.h>
42 #include <m_invari.h>
43 
44 #ifdef M_VARIANTS
45 
46 #include <variant.h>
47 
48 #define SHORT_STRING_LEN	100
49 
50 void __m_setinvariant(void);
51 
52 char	__m_invariant[M_CSETSIZE] = {
53 	  0,   1,   2,   3,   4,   5,   6,   7,
54 	  8,   9,  10,  11,  12,  13,  14,  15,
55 	 16,  17,  18,  19,  20,  21,  22,  23,
56 	 24,  25,  26,  27,  28,  29,  30,  31,
57 	 32,  33,  34,  35,  36,  37,  38,  39,
58 	 40,  41,  42,  43,  44,  45,  46,  47,
59 	 48,  49,  50,  51,  52,  53,  54,  55,
60 	 56,  57,  58,  59,  60,  61,  62,  63,
61 	 64,  65,  66,  67,  68,  69,  70,  71,
62 	 72,  73,  74,  75,  76,  77,  78,  79,
63 	 80,  81,  82,  83,  84,  85,  86,  87,
64 	 88,  89,  90,  91,  92,  93,  94,  95,
65 	 96,  97,  98,  99, 100, 101, 102, 103,
66 	104, 105, 106, 107, 108, 109, 110, 111,
67 	112, 113, 114, 115, 116, 117, 118, 119,
68 	120, 121, 122, 123, 124, 125, 126, 127,
69 	128, 129, 130, 131, 132, 133, 134, 135,
70 	136, 137, 138, 139, 140, 141, 142, 143,
71 	144, 145, 146, 147, 148, 149, 150, 151,
72 	152, 153, 154, 155, 156, 157, 158, 159,
73 	160, 161, 162, 163, 164, 165, 166, 167,
74 	168, 169, 170, 171, 172, 173, 174, 175,
75 	176, 177, 178, 179, 180, 181, 182, 183,
76 	184, 185, 186, 187, 188, 189, 190, 191,
77 	192, 193, 194, 195, 196, 197, 198, 199,
78 	200, 201, 202, 203, 204, 205, 206, 207,
79 	208, 209, 210, 211, 212, 213, 214, 215,
80 	216, 217, 218, 219, 220, 221, 222, 223,
81 	224, 225, 226, 227, 228, 229, 230, 231,
82 	232, 233, 234, 235, 236, 237, 238, 239,
83 	240, 241, 242, 243, 244, 245, 246, 247,
84 	248, 249, 250, 251, 252, 253, 254, 255,
85 #if M_CSETSIZE > 256
86 	256, 257, 258, 259, 260, 261, 262, 263,
87 	264, 265, 266, 267, 268, 269, 270, 271,
88 	272, 273, 274, 275, 276, 277, 278, 279,
89 	280, 281, 282, 283, 284, 285, 286, 287,
90 	288, 289, 290, 291, 292, 293, 294, 295,
91 	296, 297, 298, 299, 300, 301, 302, 303,
92 	304, 305, 306, 307, 308, 309, 310, 311,
93 	312, 313, 314, 315, 316, 317, 318, 319,
94 	320, 321, 322, 323, 324, 325, 326, 327,
95 	328, 329, 330, 331, 332, 333, 334, 335,
96 	336, 337, 338, 339, 340, 341, 342, 343,
97 	344, 345, 346, 347, 348, 349, 350, 351,
98 	352, 353, 354, 355, 356, 357, 358, 359,
99 	360, 361, 362, 363, 364, 365, 366, 367,
100 	368, 369, 370, 371, 372, 373, 374, 375,
101 	376, 377, 378, 379, 380, 381, 382, 383,
102 	384, 385, 386, 387, 388, 389, 390, 391,
103 	392, 393, 394, 395, 396, 397, 398, 399,
104 	400, 401, 402, 403, 404, 405, 406, 407,
105 	408, 409, 410, 411, 412, 413, 414, 415,
106 	416, 417, 418, 419, 420, 421, 422, 423,
107 	424, 425, 426, 427, 428, 429, 430, 431,
108 	432, 433, 434, 435, 436, 437, 438, 439,
109 	440, 441, 442, 443, 444, 445, 446, 447,
110 	448, 449, 450, 451, 452, 453, 454, 455,
111 	456, 457, 458, 459, 460, 461, 462, 463,
112 	464, 465, 466, 467, 468, 469, 470, 471,
113 	472, 473, 474, 475, 476, 477, 478, 479,
114 	480, 481, 482, 483, 484, 485, 486, 487,
115 	488, 489, 490, 491, 492, 493, 494, 495,
116 	496, 497, 498, 499, 500, 501, 502, 503,
117 	504, 505, 506, 507, 508, 509, 510, 511
118 #endif
119 #if M_CSETSIZE > 512
120 #error __m_invariant table needs to be extended
121 #endif
122 };
123 char	__m_unvariant[M_CSETSIZE] = {
124 	  0,   1,   2,   3,   4,   5,   6,   7,
125 	  8,   9,  10,  11,  12,  13,  14,  15,
126 	 16,  17,  18,  19,  20,  21,  22,  23,
127 	 24,  25,  26,  27,  28,  29,  30,  31,
128 	 32,  33,  34,  35,  36,  37,  38,  39,
129 	 40,  41,  42,  43,  44,  45,  46,  47,
130 	 48,  49,  50,  51,  52,  53,  54,  55,
131 	 56,  57,  58,  59,  60,  61,  62,  63,
132 	 64,  65,  66,  67,  68,  69,  70,  71,
133 	 72,  73,  74,  75,  76,  77,  78,  79,
134 	 80,  81,  82,  83,  84,  85,  86,  87,
135 	 88,  89,  90,  91,  92,  93,  94,  95,
136 	 96,  97,  98,  99, 100, 101, 102, 103,
137 	104, 105, 106, 107, 108, 109, 110, 111,
138 	112, 113, 114, 115, 116, 117, 118, 119,
139 	120, 121, 122, 123, 124, 125, 126, 127,
140 	128, 129, 130, 131, 132, 133, 134, 135,
141 	136, 137, 138, 139, 140, 141, 142, 143,
142 	144, 145, 146, 147, 148, 149, 150, 151,
143 	152, 153, 154, 155, 156, 157, 158, 159,
144 	160, 161, 162, 163, 164, 165, 166, 167,
145 	168, 169, 170, 171, 172, 173, 174, 175,
146 	176, 177, 178, 179, 180, 181, 182, 183,
147 	184, 185, 186, 187, 188, 189, 190, 191,
148 	192, 193, 194, 195, 196, 197, 198, 199,
149 	200, 201, 202, 203, 204, 205, 206, 207,
150 	208, 209, 210, 211, 212, 213, 214, 215,
151 	216, 217, 218, 219, 220, 221, 222, 223,
152 	224, 225, 226, 227, 228, 229, 230, 231,
153 	232, 233, 234, 235, 236, 237, 238, 239,
154 	240, 241, 242, 243, 244, 245, 246, 247,
155 	248, 249, 250, 251, 252, 253, 254, 255,
156 #if M_CSETSIZE > 256
157 	256, 257, 258, 259, 260, 261, 262, 263,
158 	264, 265, 266, 267, 268, 269, 270, 271,
159 	272, 273, 274, 275, 276, 277, 278, 279,
160 	280, 281, 282, 283, 284, 285, 286, 287,
161 	288, 289, 290, 291, 292, 293, 294, 295,
162 	296, 297, 298, 299, 300, 301, 302, 303,
163 	304, 305, 306, 307, 308, 309, 310, 311,
164 	312, 313, 314, 315, 316, 317, 318, 319,
165 	320, 321, 322, 323, 324, 325, 326, 327,
166 	328, 329, 330, 331, 332, 333, 334, 335,
167 	336, 337, 338, 339, 340, 341, 342, 343,
168 	344, 345, 346, 347, 348, 349, 350, 351,
169 	352, 353, 354, 355, 356, 357, 358, 359,
170 	360, 361, 362, 363, 364, 365, 366, 367,
171 	368, 369, 370, 371, 372, 373, 374, 375,
172 	376, 377, 378, 379, 380, 381, 382, 383,
173 	384, 385, 386, 387, 388, 389, 390, 391,
174 	392, 393, 394, 395, 396, 397, 398, 399,
175 	400, 401, 402, 403, 404, 405, 406, 407,
176 	408, 409, 410, 411, 412, 413, 414, 415,
177 	416, 417, 418, 419, 420, 421, 422, 423,
178 	424, 425, 426, 427, 428, 429, 430, 431,
179 	432, 433, 434, 435, 436, 437, 438, 439,
180 	440, 441, 442, 443, 444, 445, 446, 447,
181 	448, 449, 450, 451, 452, 453, 454, 455,
182 	456, 457, 458, 459, 460, 461, 462, 463,
183 	464, 465, 466, 467, 468, 469, 470, 471,
184 	472, 473, 474, 475, 476, 477, 478, 479,
185 	480, 481, 482, 483, 484, 485, 486, 487,
186 	488, 489, 490, 491, 492, 493, 494, 495,
187 	496, 497, 498, 499, 500, 501, 502, 503,
188 	504, 505, 506, 507, 508, 509, 510, 511
189 #endif
190 #if M_CSETSIZE > 512
191 #error __m_unvariant table needs to be extended
192 #endif
193 };
194 
195 /*f
196  * Initialize the variant <--> invariant tables.
197  * May be called more than once -- successive calls ignored.
198  * Void return -- can't fail.
199  */
200 void
m_invariantinit(void)201 m_invariantinit(void)
202 {
203 	static int first = 1;
204 
205 	if (!first)
206 		return;
207 	first = 0;
208 	__m_setinvariant();
209 	return;
210 }
211 
212 /*f
213  * Initialize the variant -> invariant tables.
214  * Void return -- can't fail.
215  */
216 void
__m_setinvariant(void)217 __m_setinvariant(void)
218 {
219 	int i;
220 	struct variant *v;
221 
222 	/* Initialize to identity mappings */
223 	for (i = 0; i < M_CSETSIZE; i++) {
224 		__m_invariant[i] = i;
225 		__m_unvariant[i] = i;
226 	}
227 
228 	/*
229 	 * Find the set of variant characters
230 	 * On error, return success -- i.e. assume it wasn't specified, and
231 	 * hence it is the identity.
232 	 */
233 	if ((v = getsyntx()) == NULL)
234 		return;
235 
236 	/*
237 	 * Build the invariant mapping tables: map from current codeset's
238 	 * variant locations, to the location that we were compiled in.
239 	 */
240 	__m_invariant[v->backslash] = '\\';
241 	__m_invariant[v->right_bracket] = ']';
242 	__m_invariant[v->left_bracket] = '[';
243 	__m_invariant[v->right_brace] = '}';
244 	__m_invariant[v->left_brace] = '{';
245 	__m_invariant[v->circumflex] = '^';
246 	__m_invariant[v->tilde] = '~';
247 	__m_invariant[v->exclamation_mark] = '!';
248 	__m_invariant[v->number_sign] = '#';
249 	__m_invariant[v->vertical_line] = '|';
250 	__m_invariant[v->dollar_sign] = '$';
251 	__m_invariant[v->commercial_at] = '@';
252 	__m_invariant[v->grave_accent] = '`';
253 
254 	/*
255 	 * Build the unvariant mapping tables: map from compiled codeset
256 	 * to that of the current codeset.
257 	 */
258 	__m_unvariant['\\'] = v->backslash;
259 	__m_unvariant[']'] = v->right_bracket;
260 	__m_unvariant['['] = v->left_bracket;
261 	__m_unvariant['}'] = v->right_brace;
262 	__m_unvariant['{'] = v->left_brace;
263 	__m_unvariant['^'] = v->circumflex;
264 	__m_unvariant['~'] = v->tilde;
265 	__m_unvariant['!'] = v->exclamation_mark;
266 	__m_unvariant['#'] = v->number_sign;
267 	__m_unvariant['|'] = v->vertical_line;
268 	__m_unvariant['$'] = v->dollar_sign;
269 	__m_unvariant['@'] = v->commercial_at;
270 	__m_unvariant['`'] = v->grave_accent;
271 
272 	return;
273 }
274 
275 /*f
276  * Convert a compiled in string to the external form.  Assumes a fixed
277  * length short string which is available until another call to m_unvariantstr.
278  * Uses 10 alternating strings to allow multiple calls on a printf.
279  * The extra buffers are probably only required by yacc.
280  */
281 char *
m_unvariantstr(char const * s)282 m_unvariantstr(char const *s)
283 {
284 	static char str[10][SHORT_STRING_LEN];
285 	static int buf = 0;
286 	char *ret;
287 	char c;
288 	int i = 0;
289 
290 	ret = str[buf++];
291 	if (buf >= 10)
292 		buf = 0;
293 
294 	while((ret[i++] = M_UNVARIANT(*s)) != '\0') {
295 		s++;
296 		if (i >= SHORT_STRING_LEN) {
297 			fprintf(stderr, "m_unvariantstr: internal error.\n"),
298 			abort();
299 		}
300 	}
301 	ret[i] = '\0';
302 	return ret;
303 }
304 
305 /*f
306  * Ditto, for wchar's
307  */
308 wchar_t *
m_wunvariantstr(wchar_t const * s)309 m_wunvariantstr(wchar_t const *s)
310 {
311 	static wchar_t str[SHORT_STRING_LEN];
312 	static wchar_t * const strend = str + sizeof(str);
313 	wchar_t *s1;
314 	int i = 0;
315 
316 	for (s1 = str ; *s != '\0'; s++) {
317 		*s1++ = M_UNVARIANT(*s);
318 		if (str == strend) {
319 			fprintf(stderr, "m_wunvariantstr: internal error.\n"),
320 			abort();
321 		}
322 	}
323 	*s1 = '\0';
324 
325 	return str;
326 }
327 #endif /* M_VARIANTS */
328