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