Initial import of binutils 2.22 on the new vendor branch
[dragonfly.git] / contrib / groff / src / libs / libgroff / glyphuni.cpp
1 // -*- C++ -*-
2 /* Copyright (C) 2002, 2003, 2004, 2006, 2009
3    Free Software Foundation, Inc.
4      Written by Werner Lemberg <wl@gnu.org>
5
6 This file is part of groff.
7
8 groff is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 groff is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20
21 #include "lib.h"
22 #include "stringclass.h"
23 #include "ptable.h"
24
25 #include "unicode.h"
26
27 struct glyph_to_unicode {
28   char *value;
29 };
30
31 declare_ptable(glyph_to_unicode)
32 implement_ptable(glyph_to_unicode)
33
34 PTABLE(glyph_to_unicode) glyph_to_unicode_table;
35
36 // The entries commented out in the table below can't be used in glyph
37 // names.
38
39 struct S {
40   const char *key;
41   const char *value;
42 } glyph_to_unicode_list[] = {
43   { "!", "0021" },
44   { "\"", "0022" },
45   { "dq", "0022" },
46   { "#", "0023" },
47   { "sh", "0023" },
48   { "$", "0024" },
49   { "Do", "0024" },
50   { "%", "0025" },
51   { "&", "0026" },
52   { "aq", "0027" },
53   { "(", "0028" },
54   { ")", "0029" },
55   { "*", "002A" },
56   { "+", "002B" },
57   { "pl", "002B" },
58   { ",", "002C" },
59   { ".", "002E" },
60   { "/", "002F" },
61   { "sl", "002F" },
62   { "0", "0030" },
63   { "1", "0031" },
64   { "2", "0032" },
65   { "3", "0033" },
66   { "4", "0034" },
67   { "5", "0035" },
68   { "6", "0036" },
69   { "7", "0037" },
70   { "8", "0038" },
71   { "9", "0039" },
72   { ":", "003A" },
73   { ";", "003B" },
74   { "<", "003C" },
75   { "=", "003D" },
76   { "eq", "003D" },
77   { ">", "003E" },
78   { "?", "003F" },
79   { "@", "0040" },
80   { "at", "0040" },
81   { "A", "0041" },
82   { "B", "0042" },
83   { "C", "0043" },
84   { "D", "0044" },
85   { "E", "0045" },
86   { "F", "0046" },
87   { "G", "0047" },
88   { "H", "0048" },
89   { "I", "0049" },
90   { "J", "004A" },
91   { "K", "004B" },
92   { "L", "004C" },
93   { "M", "004D" },
94   { "N", "004E" },
95   { "O", "004F" },
96   { "P", "0050" },
97   { "Q", "0051" },
98   { "R", "0052" },
99   { "S", "0053" },
100   { "T", "0054" },
101   { "U", "0055" },
102   { "V", "0056" },
103   { "W", "0057" },
104   { "X", "0058" },
105   { "Y", "0059" },
106   { "Z", "005A" },
107 //{ "[", "005B" },
108   { "lB", "005B" },
109 //{ "\\", "005C" },
110   { "rs", "005C" },
111 //{ "]", "005D" },
112   { "rB", "005D" },
113   { "a^", "005E" },
114   { "^", "005E" },
115   { "ha", "005E" },
116   { "_", "005F" },
117   { "ru", "005F" },
118   { "ul", "005F" },
119   { "ga", "0060" },
120   { "a", "0061" },
121   { "b", "0062" },
122   { "c", "0063" },
123   { "d", "0064" },
124   { "e", "0065" },
125   { "f", "0066" },
126   { "ff", "0066_0066" },
127   { "Fi", "0066_0066_0069" },
128   { "Fl", "0066_0066_006C" },
129   { "fi", "0066_0069" },
130   { "fl", "0066_006C" },
131   { "g", "0067" },
132   { "h", "0068" },
133   { "i", "0069" },
134   { "j", "006A" },
135   { "k", "006B" },
136   { "l", "006C" },
137   { "m", "006D" },
138   { "n", "006E" },
139   { "o", "006F" },
140   { "p", "0070" },
141   { "q", "0071" },
142   { "r", "0072" },
143   { "s", "0073" },
144   { "t", "0074" },
145   { "u", "0075" },
146   { "v", "0076" },
147   { "w", "0077" },
148   { "x", "0078" },
149   { "y", "0079" },
150   { "z", "007A" },
151   { "lC", "007B" },
152   { "{", "007B" },
153   { "ba", "007C" },
154   { "or", "007C" },
155   { "|", "007C" },
156   { "rC", "007D" },
157   { "}", "007D" },
158   { "a~", "007E" },
159   { "~", "007E" },
160   { "ti", "007E" },
161   { "r!", "00A1" },
162   { "ct", "00A2" },
163   { "Po", "00A3" },
164   { "Cs", "00A4" },
165   { "Ye", "00A5" },
166   { "bb", "00A6" },
167   { "sc", "00A7" },
168   { "ad", "00A8" },
169   { "co", "00A9" },
170   { "Of", "00AA" },
171   { "Fo", "00AB" },
172   { "no", "00AC" },
173   { "tno", "00AC" },
174   // The soft hypen U+00AD is meaningful only in the input file,
175   // not in the output.
176   { "rg", "00AE" },
177   { "a-", "00AF" },
178   { "de", "00B0" },
179   { "+-", "00B1" },
180   { "t+-", "00B1" },
181   { "S2", "00B2" },
182   { "S3", "00B3" },
183   { "aa", "00B4" },
184   { "mc", "00B5" },
185   { "ps", "00B6" },
186   { "pc", "00B7" },
187   { "ac", "00B8" },
188   { "S1", "00B9" },
189   { "Om", "00BA" },
190   { "Fc", "00BB" },
191   { "14", "00BC" },
192   { "12", "00BD" },
193   { "34", "00BE" },
194   { "r?", "00BF" },
195   { "`A", "00C0" },
196   { "'A", "00C1" },
197   { "^A", "00C2" },
198   { "~A", "00C3" },
199   { ":A", "00C4" },
200   { "oA", "00C5" },
201   { "AE", "00C6" },
202   { ",C", "00C7" },
203   { "`E", "00C8" },
204   { "'E", "00C9" },
205   { "^E", "00CA" },
206   { ":E", "00CB" },
207   { "`I", "00CC" },
208   { "'I", "00CD" },
209   { "^I", "00CE" },
210   { ":I", "00CF" },
211   { "-D", "00D0" },
212   { "~N", "00D1" },
213   { "`O", "00D2" },
214   { "'O", "00D3" },
215   { "^O", "00D4" },
216   { "~O", "00D5" },
217   { ":O", "00D6" },
218   { "mu", "00D7" },
219   { "tmu", "00D7" },
220   { "/O", "00D8" },
221   { "`U", "00D9" },
222   { "'U", "00DA" },
223   { "^U", "00DB" },
224   { ":U", "00DC" },
225   { "'Y", "00DD" },
226   { "TP", "00DE" },
227   { "ss", "00DF" },
228   { "`a", "00E0" },
229   { "'a", "00E1" },
230   { "^a", "00E2" },
231   { "~a", "00E3" },
232   { ":a", "00E4" },
233   { "oa", "00E5" },
234   { "ae", "00E6" },
235   { ",c", "00E7" },
236   { "`e", "00E8" },
237   { "'e", "00E9" },
238   { "^e", "00EA" },
239   { ":e", "00EB" },
240   { "`i", "00EC" },
241   { "'i", "00ED" },
242   { "^i", "00EE" },
243   { ":i", "00EF" },
244   { "Sd", "00F0" },
245   { "~n", "00F1" },
246   { "`o", "00F2" },
247   { "'o", "00F3" },
248   { "^o", "00F4" },
249   { "~o", "00F5" },
250   { ":o", "00F6" },
251   { "di", "00F7" },
252   { "tdi", "00F7" },
253   { "/o", "00F8" },
254   { "`u", "00F9" },
255   { "'u", "00FA" },
256   { "^u", "00FB" },
257   { ":u", "00FC" },
258   { "'y", "00FD" },
259   { "Tp", "00FE" },
260   { ":y", "00FF" },
261   { "'C", "0106" },
262   { "'c", "0107" },
263   { ".i", "0131" },
264   { "IJ", "0132" },
265   { "ij", "0133" },
266   { "/L", "0141" },
267   { "/l", "0142" },
268   { "OE", "0152" },
269   { "oe", "0153" },
270   { "vS", "0160" },
271   { "vs", "0161" },
272   { ":Y", "0178" },
273   { "vZ", "017D" },
274   { "vz", "017E" },
275   { "Fn", "0192" },
276   { "ah", "02C7" },
277   { "ab", "02D8" },
278   { "a.", "02D9" },
279   { "ao", "02DA" },
280   { "ho", "02DB" },
281   { "a\"", "02DD" },
282   { "*A", "0391" },
283   { "*B", "0392" },
284   { "*G", "0393" },
285   { "*D", "0394" },
286   { "*E", "0395" },
287   { "*Z", "0396" },
288   { "*Y", "0397" },
289   { "*H", "0398" },
290   { "*I", "0399" },
291   { "*K", "039A" },
292   { "*L", "039B" },
293   { "*M", "039C" },
294   { "*N", "039D" },
295   { "*C", "039E" },
296   { "*O", "039F" },
297   { "*P", "03A0" },
298   { "*R", "03A1" },
299   { "*S", "03A3" },
300   { "*T", "03A4" },
301   { "*U", "03A5" },
302   { "*F", "03A6" },
303   { "*X", "03A7" },
304   { "*Q", "03A8" },
305   { "*W", "03A9" },
306   { "*a", "03B1" },
307   { "*b", "03B2" },
308   { "*g", "03B3" },
309   { "*d", "03B4" },
310   { "*e", "03B5" },
311   { "*z", "03B6" },
312   { "*y", "03B7" },
313   { "*h", "03B8" },
314   { "*i", "03B9" },
315   { "*k", "03BA" },
316   { "*l", "03BB" },
317   { "*m", "03BC" },
318   { "*n", "03BD" },
319   { "*c", "03BE" },
320   { "*o", "03BF" },
321   { "*p", "03C0" },
322   { "*r", "03C1" },
323   { "ts", "03C2" },
324   { "*s", "03C3" },
325   { "*t", "03C4" },
326   { "*u", "03C5" },
327   // the curly phi variant
328   { "+f", "03C6" },
329   { "*x", "03C7" },
330   { "*q", "03C8" },
331   { "*w", "03C9" },
332   { "+h", "03D1" },
333   // the stroked phi variant
334   { "*f", "03D5" },
335   { "+p", "03D6" },
336   { "+e", "03F5" },
337   // `-' and `hy' denote a HYPHEN, usually a glyph with a smaller width than
338   // the MINUS sign.  Users who are viewing broken man pages that assume
339   // that `-' denotes a U+002D character can either fix the broken man pages
340   // or apply the workaround described in the PROBLEMS file.
341   { "-", "2010" },
342   { "hy", "2010" },
343   { "en", "2013" },
344   { "em", "2014" },
345   { "`", "2018" },
346   { "oq", "2018" },
347   { "'", "2019" },
348   { "cq", "2019" },
349   { "bq", "201A" },
350   { "lq", "201C" },
351   { "rq", "201D" },
352   { "Bq", "201E" },
353   { "dg", "2020" },
354   { "dd", "2021" },
355   { "bu", "2022" },
356   { "%0", "2030" },
357   { "fm", "2032" },
358   { "sd", "2033" },
359   { "fo", "2039" },
360   { "fc", "203A" },
361   { "rn", "203E" },
362   { "f/", "2044" },
363   { "eu", "20AC" },
364   { "Eu", "20AC" },
365   { "-h", "210F" },
366   { "hbar", "210F" },
367   { "Im", "2111" },
368   { "wp", "2118" },
369   { "Re", "211C" },
370   { "tm", "2122" },
371   { "Ah", "2135" },
372   { "18", "215B" },
373   { "38", "215C" },
374   { "58", "215D" },
375   { "78", "215E" },
376   { "<-", "2190" },
377   { "ua", "2191" },
378   { "->", "2192" },
379   { "da", "2193" },
380   { "<>", "2194" },
381   { "va", "2195" },
382   { "CR", "21B5" },
383   { "lA", "21D0" },
384   { "uA", "21D1" },
385   { "rA", "21D2" },
386   { "dA", "21D3" },
387   { "hA", "21D4" },
388   { "vA", "21D5" },
389   { "fa", "2200" },
390   { "pd", "2202" },
391   { "te", "2203" },
392   { "es", "2205" },
393   { "gr", "2207" },
394   { "mo", "2208" },
395   { "nm", "2209" },
396   { "st", "220B" },
397   { "product", "220F" },
398   { "coproduct", "2210" },
399   { "sum", "2211" },
400   // `mi' and `\-' represent a MINUS sign.  But it is used in many man pages
401   // to denote the U+002D character that introduces a command-line option. 
402   // For devices that support copy&paste, such as devhtml and devutf8, the
403   // user can apply the workaround described in the PROBLEMS file.
404   { "\\-", "2212" },
405   { "mi", "2212" },
406   { "-+", "2213" },
407   { "**", "2217" },
408   { "sqrt", "221A" },
409   { "sr", "221A" },
410   { "pt", "221D" },
411   { "if", "221E" },
412   { "/_", "2220" },
413   { "AN", "2227" },
414   { "OR", "2228" },
415   { "ca", "2229" },
416   { "cu", "222A" },
417   { "is", "222B" },
418   { "integral", "222B" },
419   { "tf", "2234" },
420   { "3d", "2234" },
421   { "ap", "223C" },
422   { "|=", "2243" },
423   { "=~", "2245" },
424   { "~~", "2248" },
425   { "~=", "2248" },
426   { "!=", "2260" },
427   { "==", "2261" },
428   { "ne", "2262" },
429   { "<=", "2264" },
430   { ">=", "2265" },
431   { "<<", "226A" },
432   { ">>", "226B" },
433   { "sb", "2282" },
434   { "sp", "2283" },
435   { "nb", "2284" },
436   { "nc", "2285" },
437   { "ib", "2286" },
438   { "ip", "2287" },
439   { "c+", "2295" },
440   { "c*", "2297" },
441   { "pp", "22A5" },
442   { "md", "22C5" },
443   { "lc", "2308" },
444   { "rc", "2309" },
445   { "lf", "230A" },
446   { "rf", "230B" },
447   { "parenlefttp", "239B" },
448   { "parenleftex", "239C" },
449   { "parenleftbt", "239D" },
450   { "parenrighttp", "239E" },
451   { "parenrightex", "239F" },
452   { "parenrightbt", "23A0" },
453   { "bracketlefttp", "23A1" },
454   { "bracketleftex", "23A2" },
455   { "bracketleftbt", "23A3" },
456   { "bracketrighttp", "23A4" },
457   { "bracketrightex", "23A5" },
458   { "bracketrightbt", "23A6" },
459   { "lt", "23A7" },
460   { "bracelefttp", "23A7" },
461   { "lk", "23A8" },
462   { "braceleftmid", "23A8" },
463   { "lb", "23A9" },
464   { "braceleftbt", "23A9" },
465   { "bv", "23AA" },
466   { "braceex", "23AA" },
467   { "braceleftex", "23AA" },
468   { "bracerightex", "23AA" },
469   { "rt", "23AB" },
470   { "bracerighttp", "23AB" },
471   { "rk", "23AC" },
472   { "bracerightmid", "23AC" },
473   { "rb", "23AD" },
474   { "bracerightbt", "23AD" },
475   { "an", "23AF" },
476   { "br", "2502" },
477   { "rk", "251D" },
478   { "lk", "2525" },
479   { "lt", "256D" },
480   { "rt", "256E" },
481   { "rb", "256F" },
482   { "lb", "2570" },
483   { "sq", "25A1" },
484   { "lz", "25CA" },
485   { "ci", "25CB" },
486   { "lh", "261C" },
487   { "rh", "261E" },
488   { "SP", "2660" },
489   { "CL", "2663" },
490   { "HE", "2665" },
491   { "DI", "2666" },
492   { "OK", "2713" },
493   // The `left angle bracket' and `right angle bracket' could be mapped to
494   // either U+2329,U+232A or U+3008,U+3009 or U+27E8,U+27E9.  But the first
495   // and second possibility are double-width characters (see Unicode's
496   // `DerivedEastAsianWidth.txt' file) and are therefore not suitable for
497   // general use, whereas the third possibility is single-width.
498   //
499   // The devhtml device overrides this mapping, because
500   //
501   //   http://www.w3.org/TR/html401/sgml/entities.html
502   //
503   // says that in HTML, `&lang;' and `&rang;' are U+2329,U+232A,
504   // respectively.
505   { "la", "27E8" },
506   { "ra", "27E9" },
507 };
508
509 // global constructor
510 static struct glyph_to_unicode_init {
511   glyph_to_unicode_init();
512 } _glyph_to_unicode_init;
513
514 glyph_to_unicode_init::glyph_to_unicode_init()
515 {
516   for (unsigned int i = 0;
517        i < sizeof(glyph_to_unicode_list)/sizeof(glyph_to_unicode_list[0]);
518        i++) {
519     glyph_to_unicode *gtu = new glyph_to_unicode[1];
520     gtu->value = (char *)glyph_to_unicode_list[i].value;
521     glyph_to_unicode_table.define(glyph_to_unicode_list[i].key, gtu);
522   }
523 }
524
525 const char *glyph_name_to_unicode(const char *s)
526 {
527   glyph_to_unicode *result = glyph_to_unicode_table.lookup(s);
528   return result ? result->value : 0;
529 }