Annotation of mandoc/chars.c, Revision 1.77
1.77 ! schwarze 1: /* $Id: chars.c,v 1.76 2018/08/21 16:06:48 schwarze Exp $ */
1.1 kristaps 2: /*
1.51 schwarze 3: * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
1.70 schwarze 4: * Copyright (c) 2011, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
1.1 kristaps 5: *
6: * Permission to use, copy, modify, and distribute this software for any
7: * purpose with or without fee is hereby granted, provided that the above
8: * copyright notice and this permission notice appear in all copies.
9: *
10: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17: */
1.14 kristaps 18: #include "config.h"
1.59 schwarze 19:
20: #include <sys/types.h>
1.14 kristaps 21:
1.1 kristaps 22: #include <assert.h>
1.40 kristaps 23: #include <ctype.h>
1.68 schwarze 24: #include <stddef.h>
25: #include <stdint.h>
1.77 ! schwarze 26: #include <stdio.h>
1.1 kristaps 27: #include <stdlib.h>
28: #include <string.h>
29:
1.18 kristaps 30: #include "mandoc.h"
1.56 schwarze 31: #include "mandoc_aux.h"
1.68 schwarze 32: #include "mandoc_ohash.h"
1.43 kristaps 33: #include "libmandoc.h"
1.1 kristaps 34:
35: struct ln {
1.68 schwarze 36: const char roffcode[16];
1.2 kristaps 37: const char *ascii;
1.21 kristaps 38: int unicode;
1.1 kristaps 39: };
40:
1.68 schwarze 41: /* Special break control characters. */
42: static const char ascii_nbrsp[2] = { ASCII_NBRSP, '\0' };
43: static const char ascii_break[2] = { ASCII_BREAK, '\0' };
44:
45: static struct ln lines[] = {
46:
47: /* Spacing. */
48: { " ", ascii_nbrsp, 0x00a0 },
49: { "~", ascii_nbrsp, 0x00a0 },
50: { "0", " ", 0x2002 },
51: { "|", "", 0 },
52: { "^", "", 0 },
53: { "&", "", 0 },
1.74 schwarze 54: { ")", "", 0 },
1.68 schwarze 55: { "%", "", 0 },
56: { ":", ascii_break, 0 },
57: /* XXX The following three do not really belong here. */
58: { "t", "", 0 },
59: { "c", "", 0 },
60: { "}", "", 0 },
61:
62: /* Lines. */
63: { "ba", "|", 0x007c },
64: { "br", "|", 0x2502 },
65: { "ul", "_", 0x005f },
1.71 schwarze 66: { "ru", "_", 0x005f },
1.68 schwarze 67: { "rn", "-", 0x203e },
68: { "bb", "|", 0x00a6 },
69: { "sl", "/", 0x002f },
70: { "rs", "\\", 0x005c },
71:
72: /* Text markers. */
73: { "ci", "O", 0x25cb },
74: { "bu", "+\bo", 0x2022 },
1.72 schwarze 75: { "dd", "<**>", 0x2021 },
76: { "dg", "<*>", 0x2020 },
1.68 schwarze 77: { "lz", "<>", 0x25ca },
78: { "sq", "[]", 0x25a1 },
1.72 schwarze 79: { "ps", "<paragraph>", 0x00b6 },
80: { "sc", "<section>", 0x00a7 },
1.68 schwarze 81: { "lh", "<=", 0x261c },
82: { "rh", "=>", 0x261e },
83: { "at", "@", 0x0040 },
84: { "sh", "#", 0x0023 },
1.72 schwarze 85: { "CR", "<cr>", 0x21b5 },
1.68 schwarze 86: { "OK", "\\/", 0x2713 },
1.76 schwarze 87: { "CL", "C", 0x2663 },
88: { "SP", "S", 0x2660 },
89: { "HE", "H", 0x2665 },
90: { "DI", "D", 0x2666 },
1.68 schwarze 91:
92: /* Legal symbols. */
93: { "co", "(C)", 0x00a9 },
94: { "rg", "(R)", 0x00ae },
95: { "tm", "tm", 0x2122 },
96:
97: /* Punctuation. */
98: { "em", "--", 0x2014 },
99: { "en", "-", 0x2013 },
100: { "hy", "-", 0x2010 },
101: { "e", "\\", 0x005c },
102: { ".", ".", 0x002e },
103: { "r!", "!", 0x00a1 },
104: { "r?", "?", 0x00bf },
105:
106: /* Quotes. */
107: { "Bq", ",,", 0x201e },
108: { "bq", ",", 0x201a },
109: { "lq", "\"", 0x201c },
110: { "rq", "\"", 0x201d },
1.69 schwarze 111: { "Lq", "\"", 0x201c },
112: { "Rq", "\"", 0x201d },
1.68 schwarze 113: { "oq", "`", 0x2018 },
114: { "cq", "\'", 0x2019 },
115: { "aq", "\'", 0x0027 },
116: { "dq", "\"", 0x0022 },
117: { "Fo", "<<", 0x00ab },
118: { "Fc", ">>", 0x00bb },
119: { "fo", "<", 0x2039 },
120: { "fc", ">", 0x203a },
121:
122: /* Brackets. */
123: { "lB", "[", 0x005b },
124: { "rB", "]", 0x005d },
125: { "lC", "{", 0x007b },
126: { "rC", "}", 0x007d },
127: { "la", "<", 0x27e8 },
128: { "ra", ">", 0x27e9 },
129: { "bv", "|", 0x23aa },
130: { "braceex", "|", 0x23aa },
131: { "bracketlefttp", "|", 0x23a1 },
132: { "bracketleftbt", "|", 0x23a3 },
133: { "bracketleftex", "|", 0x23a2 },
134: { "bracketrighttp", "|", 0x23a4 },
135: { "bracketrightbt", "|", 0x23a6 },
136: { "bracketrightex", "|", 0x23a5 },
137: { "lt", ",-", 0x23a7 },
138: { "bracelefttp", ",-", 0x23a7 },
139: { "lk", "{", 0x23a8 },
140: { "braceleftmid", "{", 0x23a8 },
141: { "lb", "`-", 0x23a9 },
142: { "braceleftbt", "`-", 0x23a9 },
143: { "braceleftex", "|", 0x23aa },
144: { "rt", "-.", 0x23ab },
145: { "bracerighttp", "-.", 0x23ab },
146: { "rk", "}", 0x23ac },
147: { "bracerightmid", "}", 0x23ac },
148: { "rb", "-\'", 0x23ad },
149: { "bracerightbt", "-\'", 0x23ad },
150: { "bracerightex", "|", 0x23aa },
151: { "parenlefttp", "/", 0x239b },
152: { "parenleftbt", "\\", 0x239d },
153: { "parenleftex", "|", 0x239c },
154: { "parenrighttp", "\\", 0x239e },
155: { "parenrightbt", "/", 0x23a0 },
156: { "parenrightex", "|", 0x239f },
157:
158: /* Arrows and lines. */
159: { "<-", "<-", 0x2190 },
160: { "->", "->", 0x2192 },
161: { "<>", "<->", 0x2194 },
162: { "da", "|\bv", 0x2193 },
163: { "ua", "|\b^", 0x2191 },
164: { "va", "^v", 0x2195 },
165: { "lA", "<=", 0x21d0 },
166: { "rA", "=>", 0x21d2 },
167: { "hA", "<=>", 0x21d4 },
168: { "uA", "=\b^", 0x21d1 },
169: { "dA", "=\bv", 0x21d3 },
170: { "vA", "^=v", 0x21d5 },
1.70 schwarze 171: { "an", "-", 0x23af },
1.68 schwarze 172:
173: /* Logic. */
174: { "AN", "^", 0x2227 },
175: { "OR", "v", 0x2228 },
176: { "no", "~", 0x00ac },
177: { "tno", "~", 0x00ac },
1.72 schwarze 178: { "te", "<there\037exists>", 0x2203 },
179: { "fa", "<for\037all>", 0x2200 },
180: { "st", "<such\037that>", 0x220b },
181: { "tf", "<therefore>", 0x2234 },
182: { "3d", "<therefore>", 0x2234 },
1.68 schwarze 183: { "or", "|", 0x007c },
184:
185: /* Mathematicals. */
186: { "pl", "+", 0x002b },
187: { "mi", "-", 0x2212 },
188: { "-", "-", 0x002d },
189: { "-+", "-+", 0x2213 },
190: { "+-", "+-", 0x00b1 },
191: { "t+-", "+-", 0x00b1 },
192: { "pc", ".", 0x00b7 },
193: { "md", ".", 0x22c5 },
194: { "mu", "x", 0x00d7 },
195: { "tmu", "x", 0x00d7 },
196: { "c*", "O\bx", 0x2297 },
197: { "c+", "O\b+", 0x2295 },
1.72 schwarze 198: { "di", "/", 0x00f7 },
199: { "tdi", "/", 0x00f7 },
1.68 schwarze 200: { "f/", "/", 0x2044 },
201: { "**", "*", 0x2217 },
202: { "<=", "<=", 0x2264 },
203: { ">=", ">=", 0x2265 },
204: { "<<", "<<", 0x226a },
205: { ">>", ">>", 0x226b },
206: { "eq", "=", 0x003d },
207: { "!=", "!=", 0x2260 },
208: { "==", "==", 0x2261 },
209: { "ne", "!==", 0x2262 },
210: { "ap", "~", 0x223c },
211: { "|=", "-~", 0x2243 },
212: { "=~", "=~", 0x2245 },
213: { "~~", "~~", 0x2248 },
214: { "~=", "~=", 0x2248 },
1.72 schwarze 215: { "pt", "<proportional\037to>", 0x221d },
1.68 schwarze 216: { "es", "{}", 0x2205 },
1.72 schwarze 217: { "mo", "<element\037of>", 0x2208 },
218: { "nm", "<not\037element\037of>", 0x2209 },
219: { "sb", "<proper\037subset>", 0x2282 },
1.73 schwarze 220: { "nb", "<not\037subset>", 0x2284 },
1.72 schwarze 221: { "sp", "<proper\037superset>", 0x2283 },
1.73 schwarze 222: { "nc", "<not\037superset>", 0x2285 },
1.72 schwarze 223: { "ib", "<subset\037or\037equal>", 0x2286 },
224: { "ip", "<superset\037or\037equal>", 0x2287 },
225: { "ca", "<intersection>", 0x2229 },
226: { "cu", "<union>", 0x222a },
227: { "/_", "<angle>", 0x2220 },
228: { "pp", "<perpendicular>", 0x22a5 },
229: { "is", "<integral>", 0x222b },
1.73 schwarze 230: { "integral", "<integral>", 0x222b },
231: { "sum", "<sum>", 0x2211 },
232: { "product", "<product>", 0x220f },
233: { "coproduct", "<coproduct>", 0x2210 },
1.72 schwarze 234: { "gr", "<nabla>", 0x2207 },
235: { "sr", "<sqrt>", 0x221a },
1.73 schwarze 236: { "sqrt", "<sqrt>", 0x221a },
1.68 schwarze 237: { "lc", "|~", 0x2308 },
238: { "rc", "~|", 0x2309 },
239: { "lf", "|_", 0x230a },
240: { "rf", "_|", 0x230b },
1.72 schwarze 241: { "if", "<infinity>", 0x221e },
242: { "Ah", "<Aleph>", 0x2135 },
243: { "Im", "<Im>", 0x2111 },
244: { "Re", "<Re>", 0x211c },
1.75 schwarze 245: { "wp", "p", 0x2118 },
1.72 schwarze 246: { "pd", "<del>", 0x2202 },
1.68 schwarze 247: { "-h", "/h", 0x210f },
1.70 schwarze 248: { "hbar", "/h", 0x210f },
1.68 schwarze 249: { "12", "1/2", 0x00bd },
250: { "14", "1/4", 0x00bc },
251: { "34", "3/4", 0x00be },
1.70 schwarze 252: { "18", "1/8", 0x215B },
253: { "38", "3/8", 0x215C },
254: { "58", "5/8", 0x215D },
255: { "78", "7/8", 0x215E },
1.72 schwarze 256: { "S1", "^1", 0x00B9 },
257: { "S2", "^2", 0x00B2 },
258: { "S3", "^3", 0x00B3 },
1.68 schwarze 259:
260: /* Ligatures. */
261: { "ff", "ff", 0xfb00 },
262: { "fi", "fi", 0xfb01 },
263: { "fl", "fl", 0xfb02 },
264: { "Fi", "ffi", 0xfb03 },
265: { "Fl", "ffl", 0xfb04 },
266: { "AE", "AE", 0x00c6 },
267: { "ae", "ae", 0x00e6 },
268: { "OE", "OE", 0x0152 },
269: { "oe", "oe", 0x0153 },
270: { "ss", "ss", 0x00df },
271: { "IJ", "IJ", 0x0132 },
272: { "ij", "ij", 0x0133 },
273:
274: /* Accents. */
275: { "a\"", "\"", 0x02dd },
276: { "a-", "-", 0x00af },
277: { "a.", ".", 0x02d9 },
278: { "a^", "^", 0x005e },
279: { "aa", "\'", 0x00b4 },
280: { "\'", "\'", 0x00b4 },
281: { "ga", "`", 0x0060 },
282: { "`", "`", 0x0060 },
283: { "ab", "'\b`", 0x02d8 },
284: { "ac", ",", 0x00b8 },
285: { "ad", "\"", 0x00a8 },
286: { "ah", "v", 0x02c7 },
287: { "ao", "o", 0x02da },
288: { "a~", "~", 0x007e },
289: { "ho", ",", 0x02db },
290: { "ha", "^", 0x005e },
291: { "ti", "~", 0x007e },
1.75 schwarze 292: { "u02DC", "~", 0x02dc },
1.68 schwarze 293:
294: /* Accented letters. */
295: { "'A", "'\bA", 0x00c1 },
296: { "'E", "'\bE", 0x00c9 },
297: { "'I", "'\bI", 0x00cd },
298: { "'O", "'\bO", 0x00d3 },
299: { "'U", "'\bU", 0x00da },
1.75 schwarze 300: { "'Y", "'\bY", 0x00dd },
1.68 schwarze 301: { "'a", "'\ba", 0x00e1 },
302: { "'e", "'\be", 0x00e9 },
303: { "'i", "'\bi", 0x00ed },
304: { "'o", "'\bo", 0x00f3 },
305: { "'u", "'\bu", 0x00fa },
1.75 schwarze 306: { "'y", "'\by", 0x00fd },
1.68 schwarze 307: { "`A", "`\bA", 0x00c0 },
308: { "`E", "`\bE", 0x00c8 },
309: { "`I", "`\bI", 0x00cc },
310: { "`O", "`\bO", 0x00d2 },
311: { "`U", "`\bU", 0x00d9 },
312: { "`a", "`\ba", 0x00e0 },
313: { "`e", "`\be", 0x00e8 },
314: { "`i", "`\bi", 0x00ec },
315: { "`o", "`\bo", 0x00f2 },
316: { "`u", "`\bu", 0x00f9 },
317: { "~A", "~\bA", 0x00c3 },
318: { "~N", "~\bN", 0x00d1 },
319: { "~O", "~\bO", 0x00d5 },
320: { "~a", "~\ba", 0x00e3 },
321: { "~n", "~\bn", 0x00f1 },
322: { "~o", "~\bo", 0x00f5 },
323: { ":A", "\"\bA", 0x00c4 },
324: { ":E", "\"\bE", 0x00cb },
325: { ":I", "\"\bI", 0x00cf },
326: { ":O", "\"\bO", 0x00d6 },
327: { ":U", "\"\bU", 0x00dc },
328: { ":a", "\"\ba", 0x00e4 },
329: { ":e", "\"\be", 0x00eb },
330: { ":i", "\"\bi", 0x00ef },
331: { ":o", "\"\bo", 0x00f6 },
332: { ":u", "\"\bu", 0x00fc },
333: { ":y", "\"\by", 0x00ff },
334: { "^A", "^\bA", 0x00c2 },
335: { "^E", "^\bE", 0x00ca },
336: { "^I", "^\bI", 0x00ce },
337: { "^O", "^\bO", 0x00d4 },
338: { "^U", "^\bU", 0x00db },
339: { "^a", "^\ba", 0x00e2 },
340: { "^e", "^\be", 0x00ea },
341: { "^i", "^\bi", 0x00ee },
342: { "^o", "^\bo", 0x00f4 },
343: { "^u", "^\bu", 0x00fb },
344: { ",C", ",\bC", 0x00c7 },
345: { ",c", ",\bc", 0x00e7 },
346: { "/L", "/\bL", 0x0141 },
347: { "/l", "/\bl", 0x0142 },
348: { "/O", "/\bO", 0x00d8 },
349: { "/o", "/\bo", 0x00f8 },
350: { "oA", "o\bA", 0x00c5 },
351: { "oa", "o\ba", 0x00e5 },
352:
353: /* Special letters. */
1.72 schwarze 354: { "-D", "Dh", 0x00d0 },
355: { "Sd", "dh", 0x00f0 },
1.68 schwarze 356: { "TP", "Th", 0x00de },
357: { "Tp", "th", 0x00fe },
358: { ".i", "i", 0x0131 },
359: { ".j", "j", 0x0237 },
360:
361: /* Currency. */
362: { "Do", "$", 0x0024 },
363: { "ct", "/\bc", 0x00a2 },
364: { "Eu", "EUR", 0x20ac },
365: { "eu", "EUR", 0x20ac },
366: { "Ye", "=\bY", 0x00a5 },
1.76 schwarze 367: { "Po", "-\bL", 0x00a3 },
1.68 schwarze 368: { "Cs", "o\bx", 0x00a4 },
369: { "Fn", ",\bf", 0x0192 },
370:
371: /* Units. */
1.72 schwarze 372: { "de", "<degree>", 0x00b0 },
373: { "%0", "<permille>", 0x2030 },
1.68 schwarze 374: { "fm", "\'", 0x2032 },
375: { "sd", "''", 0x2033 },
1.72 schwarze 376: { "mc", "<micro>", 0x00b5 },
1.70 schwarze 377: { "Of", "_\ba", 0x00aa },
378: { "Om", "_\bo", 0x00ba },
1.68 schwarze 379:
380: /* Greek characters. */
381: { "*A", "A", 0x0391 },
382: { "*B", "B", 0x0392 },
1.72 schwarze 383: { "*G", "<Gamma>", 0x0393 },
384: { "*D", "<Delta>", 0x0394 },
1.68 schwarze 385: { "*E", "E", 0x0395 },
386: { "*Z", "Z", 0x0396 },
387: { "*Y", "H", 0x0397 },
1.72 schwarze 388: { "*H", "<Theta>", 0x0398 },
1.68 schwarze 389: { "*I", "I", 0x0399 },
390: { "*K", "K", 0x039a },
1.72 schwarze 391: { "*L", "<Lambda>", 0x039b },
1.68 schwarze 392: { "*M", "M", 0x039c },
393: { "*N", "N", 0x039d },
1.72 schwarze 394: { "*C", "<Xi>", 0x039e },
1.68 schwarze 395: { "*O", "O", 0x039f },
1.72 schwarze 396: { "*P", "<Pi>", 0x03a0 },
1.68 schwarze 397: { "*R", "P", 0x03a1 },
1.72 schwarze 398: { "*S", "<Sigma>", 0x03a3 },
1.68 schwarze 399: { "*T", "T", 0x03a4 },
400: { "*U", "Y", 0x03a5 },
1.72 schwarze 401: { "*F", "<Phi>", 0x03a6 },
1.68 schwarze 402: { "*X", "X", 0x03a7 },
1.72 schwarze 403: { "*Q", "<Psi>", 0x03a8 },
404: { "*W", "<Omega>", 0x03a9 },
405: { "*a", "<alpha>", 0x03b1 },
406: { "*b", "<beta>", 0x03b2 },
407: { "*g", "<gamma>", 0x03b3 },
408: { "*d", "<delta>", 0x03b4 },
409: { "*e", "<epsilon>", 0x03b5 },
410: { "*z", "<zeta>", 0x03b6 },
411: { "*y", "<eta>", 0x03b7 },
412: { "*h", "<theta>", 0x03b8 },
413: { "*i", "<iota>", 0x03b9 },
414: { "*k", "<kappa>", 0x03ba },
415: { "*l", "<lambda>", 0x03bb },
416: { "*m", "<mu>", 0x03bc },
417: { "*n", "<nu>", 0x03bd },
418: { "*c", "<xi>", 0x03be },
1.68 schwarze 419: { "*o", "o", 0x03bf },
1.72 schwarze 420: { "*p", "<pi>", 0x03c0 },
421: { "*r", "<rho>", 0x03c1 },
422: { "*s", "<sigma>", 0x03c3 },
423: { "*t", "<tau>", 0x03c4 },
424: { "*u", "<upsilon>", 0x03c5 },
425: { "*f", "<phi>", 0x03d5 },
426: { "*x", "<chi>", 0x03c7 },
427: { "*q", "<psi>", 0x03c8 },
428: { "*w", "<omega>", 0x03c9 },
429: { "+h", "<theta>", 0x03d1 },
430: { "+f", "<phi>", 0x03c6 },
431: { "+p", "<pi>", 0x03d6 },
432: { "+e", "<epsilon>", 0x03f5 },
433: { "ts", "<sigma>", 0x03c2 },
1.1 kristaps 434: };
435:
1.68 schwarze 436: static struct ohash mchars;
1.1 kristaps 437:
1.57 schwarze 438:
1.1 kristaps 439: void
1.68 schwarze 440: mchars_free(void)
1.1 kristaps 441: {
442:
1.68 schwarze 443: ohash_delete(&mchars);
1.1 kristaps 444: }
445:
1.68 schwarze 446: void
1.38 kristaps 447: mchars_alloc(void)
1.1 kristaps 448: {
1.68 schwarze 449: size_t i;
450: unsigned int slot;
451:
452: mandoc_ohash_init(&mchars, 9, offsetof(struct ln, roffcode));
453: for (i = 0; i < sizeof(lines)/sizeof(lines[0]); i++) {
454: slot = ohash_qlookup(&mchars, lines[i].roffcode);
455: assert(ohash_find(&mchars, slot) == NULL);
456: ohash_insert(&mchars, slot, lines + i);
1.1 kristaps 457: }
458: }
459:
1.21 kristaps 460: int
1.68 schwarze 461: mchars_spec2cp(const char *p, size_t sz)
1.21 kristaps 462: {
463: const struct ln *ln;
1.68 schwarze 464: const char *end;
1.21 kristaps 465:
1.68 schwarze 466: end = p + sz;
467: ln = ohash_find(&mchars, ohash_qlookupi(&mchars, p, &end));
1.67 schwarze 468: return ln != NULL ? ln->unicode : sz == 1 ? (unsigned char)*p : -1;
1.21 kristaps 469: }
470:
1.65 schwarze 471: int
1.36 kristaps 472: mchars_num2char(const char *p, size_t sz)
1.32 schwarze 473: {
1.57 schwarze 474: int i;
1.32 schwarze 475:
1.65 schwarze 476: i = mandoc_strntoi(p, sz, 10);
1.67 schwarze 477: return i >= 0 && i < 256 ? i : -1;
1.44 kristaps 478: }
479:
480: int
481: mchars_num2uc(const char *p, size_t sz)
482: {
1.57 schwarze 483: int i;
1.39 kristaps 484:
1.63 schwarze 485: i = mandoc_strntoi(p, sz, 16);
486: assert(i >= 0 && i <= 0x10FFFF);
1.67 schwarze 487: return i;
1.21 kristaps 488: }
489:
1.1 kristaps 490: const char *
1.68 schwarze 491: mchars_spec2str(const char *p, size_t sz, size_t *rsz)
1.1 kristaps 492: {
1.21 kristaps 493: const struct ln *ln;
1.68 schwarze 494: const char *end;
1.1 kristaps 495:
1.68 schwarze 496: end = p + sz;
497: ln = ohash_find(&mchars, ohash_qlookupi(&mchars, p, &end));
1.60 schwarze 498: if (ln == NULL) {
1.50 schwarze 499: *rsz = 1;
1.67 schwarze 500: return sz == 1 ? p : NULL;
1.50 schwarze 501: }
1.21 kristaps 502:
1.24 kristaps 503: *rsz = strlen(ln->ascii);
1.67 schwarze 504: return ln->ascii;
1.61 schwarze 505: }
506:
507: const char *
508: mchars_uc2str(int uc)
509: {
1.68 schwarze 510: size_t i;
1.61 schwarze 511:
1.68 schwarze 512: for (i = 0; i < sizeof(lines)/sizeof(lines[0]); i++)
1.61 schwarze 513: if (uc == lines[i].unicode)
1.67 schwarze 514: return lines[i].ascii;
515: return "<?>";
1.1 kristaps 516: }
CVSweb