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