Thanks to the fine work of Russell Bryant and Dancho Lazarov, we now have autoconf...
[asterisk/asterisk.git] / mxml / mxml-entity.c
1 /*
2  * "$Id$"
3  *
4  * Character entity support code for Mini-XML, a small XML-like
5  * file parsing library.
6  *
7  * Copyright 2003-2005 by Michael Sweet.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Library General Public
11  * License as published by the Free Software Foundation; either
12  * version 2, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * Contents:
20  *
21  *   mxmlEntityAddCallback()    - Add a callback to convert entities to
22  *                                Unicode.
23  *   mxmlEntityGetName()        - Get the name that corresponds to the
24  *                                character value.
25  *   mxmlEntityGetValue()       - Get the character corresponding to a named
26  *                                entity.
27  *   mxmlEntityRemoveCallback() - Remove a callback.
28  *   default_callback()         - Lookup standard (X)HTML entities.
29  */
30
31 /*
32  * Include necessary headers...
33  */
34
35 #include "config.h"
36 #include "mxml.h"
37
38
39 /*
40  * Local functions...
41  */
42
43 static int      default_callback(const char *name);
44
45
46 /*
47  * Callback array...
48  */
49
50 static int      num_callbacks = 1;
51 static int      (*callbacks[100])(const char *name) =
52                 {
53                   default_callback
54                 };
55
56
57 /*
58  * 'mxmlEntityAddCallback()' - Add a callback to convert entities to Unicode.
59  */
60
61 int                                     /* O - 0 on success, -1 on failure */
62 mxmlEntityAddCallback(int (*cb)(const char *name))
63                                         /* I - Callback function to add */
64 {
65   if (num_callbacks < (int)(sizeof(callbacks) / sizeof(callbacks[0])))
66   {
67     callbacks[num_callbacks] = cb;
68     num_callbacks ++;
69
70     return (0);
71   }
72   else
73   {
74     mxml_error("Unable to add entity callback!");
75
76     return (-1);
77   }
78 }
79
80
81 /*
82  * 'mxmlEntityGetName()' - Get the name that corresponds to the character value.
83  *
84  * If val does not need to be represented by a named entity, NULL is returned.
85  */
86
87 const char *                            /* O - Entity name or NULL */
88 mxmlEntityGetName(int val)              /* I - Character value */
89 {
90   switch (val)
91   {
92     case '&' :
93         return ("amp");
94
95     case '<' :
96         return ("lt");
97
98     case '>' :
99         return ("gt");
100
101     case '\"' :
102         return ("quot");
103
104     default :
105         return (NULL);
106   }
107 }
108
109
110 /*
111  * 'mxmlEntityGetValue()' - Get the character corresponding to a named entity.
112  *
113  * The entity name can also be a numeric constant. -1 is returned if the
114  * name is not known.
115  */
116
117 int                                     /* O - Character value or -1 on error */
118 mxmlEntityGetValue(const char *name)    /* I - Entity name */
119 {
120   int   i;                              /* Looping var */
121   int   ch;                             /* Character value */
122
123
124   for (i = 0; i < num_callbacks; i ++)
125     if ((ch = (callbacks[i])(name)) >= 0)
126       return (ch);
127
128   return (-1);
129 }
130
131
132 /*
133  * 'mxmlEntityRemoveCallback()' - Remove a callback.
134  */
135
136 void
137 mxmlEntityRemoveCallback(int (*cb)(const char *name))
138                                         /* I - Callback function to remove */
139 {
140   int   i;                              /* Looping var */
141
142
143   for (i = 0; i < num_callbacks; i ++)
144     if (cb == callbacks[i])
145     {
146      /*
147       * Remove the callback...
148       */
149
150       num_callbacks --;
151
152       if (i < num_callbacks)
153         memmove(callbacks + i, callbacks + i + 1,
154                 (num_callbacks - i) * sizeof(callbacks[0]));
155
156       return;
157     }
158 }
159
160
161 /*
162  * 'default_callback()' - Lookup standard (X)HTML entities.
163  */
164
165 static int                              /* O - Unicode value or -1 */
166 default_callback(const char *name)      /* I - Entity name */
167 {
168   int   diff,                           /* Difference between names */
169         current,                        /* Current entity in search */
170         first,                          /* First entity in search */
171         last;                           /* Last entity in search */
172   static const struct
173   {
174     const char  *name;                  /* Entity name */
175     int         val;                    /* Character value */
176   }     entities[] =
177   {
178     { "AElig",          198 },
179     { "Aacute",         193 },
180     { "Acirc",          194 },
181     { "Agrave",         192 },
182     { "Alpha",          913 },
183     { "Aring",          197 },
184     { "Atilde",         195 },
185     { "Auml",           196 },
186     { "Beta",           914 },
187     { "Ccedil",         199 },
188     { "Chi",            935 },
189     { "Dagger",         8225 },
190     { "Delta",          916 },
191     { "Dstrok",         208 },
192     { "ETH",            208 },
193     { "Eacute",         201 },
194     { "Ecirc",          202 },
195     { "Egrave",         200 },
196     { "Epsilon",        917 },
197     { "Eta",            919 },
198     { "Euml",           203 },
199     { "Gamma",          915 },
200     { "Iacute",         205 },
201     { "Icirc",          206 },
202     { "Igrave",         204 },
203     { "Iota",           921 },
204     { "Iuml",           207 },
205     { "Kappa",          922 },
206     { "Lambda",         923 },
207     { "Mu",             924 },
208     { "Ntilde",         209 },
209     { "Nu",             925 },
210     { "OElig",          338 },
211     { "Oacute",         211 },
212     { "Ocirc",          212 },
213     { "Ograve",         210 },
214     { "Omega",          937 },
215     { "Omicron",        927 },
216     { "Oslash",         216 },
217     { "Otilde",         213 },
218     { "Ouml",           214 },
219     { "Phi",            934 },
220     { "Pi",             928 },
221     { "Prime",          8243 },
222     { "Psi",            936 },
223     { "Rho",            929 },
224     { "Scaron",         352 },
225     { "Sigma",          931 },
226     { "THORN",          222 },
227     { "Tau",            932 },
228     { "Theta",          920 },
229     { "Uacute",         218 },
230     { "Ucirc",          219 },
231     { "Ugrave",         217 },
232     { "Upsilon",        933 },
233     { "Uuml",           220 },
234     { "Xi",             926 },
235     { "Yacute",         221 },
236     { "Yuml",           376 },
237     { "Zeta",           918 },
238     { "aacute",         225 },
239     { "acirc",          226 },
240     { "acute",          180 },
241     { "aelig",          230 },
242     { "agrave",         224 },
243     { "alefsym",        8501 },
244     { "alpha",          945 },
245     { "amp",            '&' },
246     { "and",            8743 },
247     { "ang",            8736 },
248     { "aring",          229 },
249     { "asymp",          8776 },
250     { "atilde",         227 },
251     { "auml",           228 },
252     { "bdquo",          8222 },
253     { "beta",           946 },
254     { "brkbar",         166 },
255     { "brvbar",         166 },
256     { "bull",           8226 },
257     { "cap",            8745 },
258     { "ccedil",         231 },
259     { "cedil",          184 },
260     { "cent",           162 },
261     { "chi",            967 },
262     { "circ",           710 },
263     { "clubs",          9827 },
264     { "cong",           8773 },
265     { "copy",           169 },
266     { "crarr",          8629 },
267     { "cup",            8746 },
268     { "curren",         164 },
269     { "dArr",           8659 },
270     { "dagger",         8224 },
271     { "darr",           8595 },
272     { "deg",            176 },
273     { "delta",          948 },
274     { "diams",          9830 },
275     { "die",            168 },
276     { "divide",         247 },
277     { "eacute",         233 },
278     { "ecirc",          234 },
279     { "egrave",         232 },
280     { "empty",          8709 },
281     { "emsp",           8195 },
282     { "ensp",           8194 },
283     { "epsilon",        949 },
284     { "equiv",          8801 },
285     { "eta",            951 },
286     { "eth",            240 },
287     { "euml",           235 },
288     { "euro",           8364 },
289     { "exist",          8707 },
290     { "fnof",           402 },
291     { "forall",         8704 },
292     { "frac12",         189 },
293     { "frac14",         188 },
294     { "frac34",         190 },
295     { "frasl",          8260 },
296     { "gamma",          947 },
297     { "ge",             8805 },
298     { "gt",             '>' },
299     { "hArr",           8660 },
300     { "harr",           8596 },
301     { "hearts",         9829 },
302     { "hellip",         8230 },
303     { "hibar",          175 },
304     { "iacute",         237 },
305     { "icirc",          238 },
306     { "iexcl",          161 },
307     { "igrave",         236 },
308     { "image",          8465 },
309     { "infin",          8734 },
310     { "int",            8747 },
311     { "iota",           953 },
312     { "iquest",         191 },
313     { "isin",           8712 },
314     { "iuml",           239 },
315     { "kappa",          954 },
316     { "lArr",           8656 },
317     { "lambda",         955 },
318     { "lang",           9001 },
319     { "laquo",          171 },
320     { "larr",           8592 },
321     { "lceil",          8968 },
322     { "ldquo",          8220 },
323     { "le",             8804 },
324     { "lfloor",         8970 },
325     { "lowast",         8727 },
326     { "loz",            9674 },
327     { "lrm",            8206 },
328     { "lsaquo",         8249 },
329     { "lsquo",          8216 },
330     { "lt",             '<' },
331     { "macr",           175 },
332     { "mdash",          8212 },
333     { "micro",          181 },
334     { "middot",         183 },
335     { "minus",          8722 },
336     { "mu",             956 },
337     { "nabla",          8711 },
338     { "nbsp",           160 },
339     { "ndash",          8211 },
340     { "ne",             8800 },
341     { "ni",             8715 },
342     { "not",            172 },
343     { "notin",          8713 },
344     { "nsub",           8836 },
345     { "ntilde",         241 },
346     { "nu",             957 },
347     { "oacute",         243 },
348     { "ocirc",          244 },
349     { "oelig",          339 },
350     { "ograve",         242 },
351     { "oline",          8254 },
352     { "omega",          969 },
353     { "omicron",        959 },
354     { "oplus",          8853 },
355     { "or",             8744 },
356     { "ordf",           170 },
357     { "ordm",           186 },
358     { "oslash",         248 },
359     { "otilde",         245 },
360     { "otimes",         8855 },
361     { "ouml",           246 },
362     { "para",           182 },
363     { "part",           8706 },
364     { "permil",         8240 },
365     { "perp",           8869 },
366     { "phi",            966 },
367     { "pi",             960 },
368     { "piv",            982 },
369     { "plusmn",         177 },
370     { "pound",          163 },
371     { "prime",          8242 },
372     { "prod",           8719 },
373     { "prop",           8733 },
374     { "psi",            968 },
375     { "quot",           '\"' },
376     { "rArr",           8658 },
377     { "radic",          8730 },
378     { "rang",           9002 },
379     { "raquo",          187 },
380     { "rarr",           8594 },
381     { "rceil",          8969 },
382     { "rdquo",          8221 },
383     { "real",           8476 },
384     { "reg",            174 },
385     { "rfloor",         8971 },
386     { "rho",            961 },
387     { "rlm",            8207 },
388     { "rsaquo",         8250 },
389     { "rsquo",          8217 },
390     { "sbquo",          8218 },
391     { "scaron",         353 },
392     { "sdot",           8901 },
393     { "sect",           167 },
394     { "shy",            173 },
395     { "sigma",          963 },
396     { "sigmaf",         962 },
397     { "sim",            8764 },
398     { "spades",         9824 },
399     { "sub",            8834 },
400     { "sube",           8838 },
401     { "sum",            8721 },
402     { "sup",            8835 },
403     { "sup1",           185 },
404     { "sup2",           178 },
405     { "sup3",           179 },
406     { "supe",           8839 },
407     { "szlig",          223 },
408     { "tau",            964 },
409     { "there4",         8756 },
410     { "theta",          952 },
411     { "thetasym",       977 },
412     { "thinsp",         8201 },
413     { "thorn",          254 },
414     { "tilde",          732 },
415     { "times",          215 },
416     { "trade",          8482 },
417     { "uArr",           8657 },
418     { "uacute",         250 },
419     { "uarr",           8593 },
420     { "ucirc",          251 },
421     { "ugrave",         249 },
422     { "uml",            168 },
423     { "upsih",          978 },
424     { "upsilon",        965 },
425     { "uuml",           252 },
426     { "weierp",         8472 },
427     { "xi",             958 },
428     { "yacute",         253 },
429     { "yen",            165 },
430     { "yuml",           255 },
431     { "zeta",           950 },
432     { "zwj",            8205 },
433     { "zwnj",           8204 }
434   };
435
436
437  /*
438   * Do a binary search for the named entity...
439   */
440
441   first = 0;
442   last  = (int)(sizeof(entities) / sizeof(entities[0]) - 1);
443
444   while ((last - first) > 1)
445   {
446     current = (first + last) / 2;
447
448     if ((diff = strcmp(name, entities[current].name)) == 0)
449       return (entities[current].val);
450     else if (diff < 0)
451       last = current;
452     else
453       first = current;
454   }
455
456  /*
457   * If we get here, there is a small chance that there is still
458   * a match; check first and last...
459   */
460
461   if (!strcmp(name, entities[first].name))
462     return (entities[first].val);
463   else if (!strcmp(name, entities[last].name))
464     return (entities[last].val);
465   else
466     return (-1);
467 }
468
469
470 /*
471  * End of "$Id$".
472  */