|
|
|
|
//
|
|
|
|
|
// Character entity support code for Mini-XML, a small XML file parsing library.
|
|
|
|
|
//
|
|
|
|
|
// https://www.msweet.org/mxml
|
|
|
|
|
//
|
|
|
|
|
// Copyright © 2003-2024 by Michael R Sweet.
|
|
|
|
|
//
|
|
|
|
|
// Licensed under Apache License v2.0. See the file "LICENSE" for more
|
|
|
|
|
// information.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
#include "mxml-private.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// 'mxmlEntityAddCallback()' - Add a callback to convert entities to Unicode.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
int // O - 0 on success, -1 on failure
|
|
|
|
|
mxmlEntityAddCallback(
|
|
|
|
|
mxml_entity_cb_t cb) // I - Callback function to add
|
|
|
|
|
{
|
|
|
|
|
_mxml_global_t *global = _mxml_global();
|
|
|
|
|
// Global data
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (global->num_entity_cbs < (int)(sizeof(global->entity_cbs) / sizeof(global->entity_cbs[0])))
|
|
|
|
|
{
|
|
|
|
|
global->entity_cbs[global->num_entity_cbs] = cb;
|
|
|
|
|
global->num_entity_cbs ++;
|
|
|
|
|
|
|
|
|
|
return (0);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
mxml_error("Unable to add entity callback!");
|
|
|
|
|
|
|
|
|
|
return (-1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// 'mxmlEntityGetName()' - Get the name that corresponds to the character value.
|
|
|
|
|
//
|
|
|
|
|
// If val does not need to be represented by a named entity, @code NULL@ is returned.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
const char * // O - Entity name or @code NULL@
|
|
|
|
|
mxmlEntityGetName(int val) // I - Character value
|
|
|
|
|
{
|
|
|
|
|
switch (val)
|
|
|
|
|
{
|
|
|
|
|
case '&' :
|
|
|
|
|
return ("amp");
|
|
|
|
|
|
|
|
|
|
case '<' :
|
|
|
|
|
return ("lt");
|
|
|
|
|
|
|
|
|
|
case '>' :
|
|
|
|
|
return ("gt");
|
|
|
|
|
|
|
|
|
|
case '\"' :
|
|
|
|
|
return ("quot");
|
|
|
|
|
|
|
|
|
|
default :
|
|
|
|
|
return (NULL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// 'mxmlEntityGetValue()' - Get the character corresponding to a named entity.
|
|
|
|
|
//
|
|
|
|
|
// The entity name can also be a numeric constant. -1 is returned if the
|
|
|
|
|
// name is not known.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
int // O - Character value or -1 on error
|
|
|
|
|
mxmlEntityGetValue(const char *name) // I - Entity name
|
|
|
|
|
{
|
|
|
|
|
int i; // Looping var
|
|
|
|
|
int ch; // Character value
|
|
|
|
|
_mxml_global_t *global = _mxml_global();
|
|
|
|
|
// Global data
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < global->num_entity_cbs; i ++)
|
|
|
|
|
{
|
|
|
|
|
if ((ch = (global->entity_cbs[i])(name)) >= 0)
|
|
|
|
|
return (ch);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (-1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// 'mxmlEntityRemoveCallback()' - Remove a callback.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
mxmlEntityRemoveCallback(
|
|
|
|
|
mxml_entity_cb_t cb) // I - Callback function to remove
|
|
|
|
|
{
|
|
|
|
|
int i; // Looping var
|
|
|
|
|
_mxml_global_t *global = _mxml_global();
|
|
|
|
|
// Global data
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < global->num_entity_cbs; i ++)
|
|
|
|
|
{
|
|
|
|
|
if (cb == global->entity_cbs[i])
|
|
|
|
|
{
|
|
|
|
|
// Remove the callback...
|
|
|
|
|
global->num_entity_cbs --;
|
|
|
|
|
|
|
|
|
|
if (i < global->num_entity_cbs)
|
|
|
|
|
memmove(global->entity_cbs + i, global->entity_cbs + i + 1, (global->num_entity_cbs - i) * sizeof(global->entity_cbs[0]));
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// '_mxml_entity_cb()' - Lookup standard (X)HTML entities.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
int // O - Unicode value or -1
|
|
|
|
|
_mxml_entity_cb(const char *name) // I - Entity name
|
|
|
|
|
{
|
|
|
|
|
int diff, // Difference between names
|
|
|
|
|
current, // Current entity in search
|
|
|
|
|
first, // First entity in search
|
|
|
|
|
last; // Last entity in search
|
|
|
|
|
static const struct
|
|
|
|
|
{
|
|
|
|
|
const char *name; // Entity name
|
|
|
|
|
int val; // Character value
|
|
|
|
|
} entities[] =
|
|
|
|
|
{
|
|
|
|
|
{ "AElig", 198 },
|
|
|
|
|
{ "Aacute", 193 },
|
|
|
|
|
{ "Acirc", 194 },
|
|
|
|
|
{ "Agrave", 192 },
|
|
|
|
|
{ "Alpha", 913 },
|
|
|
|
|
{ "Aring", 197 },
|
|
|
|
|
{ "Atilde", 195 },
|
|
|
|
|
{ "Auml", 196 },
|
|
|
|
|
{ "Beta", 914 },
|
|
|
|
|
{ "Ccedil", 199 },
|
|
|
|
|
{ "Chi", 935 },
|
|
|
|
|
{ "Dagger", 8225 },
|
|
|
|
|
{ "Delta", 916 },
|
|
|
|
|
{ "Dstrok", 208 },
|
|
|
|
|
{ "ETH", 208 },
|
|
|
|
|
{ "Eacute", 201 },
|
|
|
|
|
{ "Ecirc", 202 },
|
|
|
|
|
{ "Egrave", 200 },
|
|
|
|
|
{ "Epsilon", 917 },
|
|
|
|
|
{ "Eta", 919 },
|
|
|
|
|
{ "Euml", 203 },
|
|
|
|
|
{ "Gamma", 915 },
|
|
|
|
|
{ "Iacute", 205 },
|
|
|
|
|
{ "Icirc", 206 },
|
|
|
|
|
{ "Igrave", 204 },
|
|
|
|
|
{ "Iota", 921 },
|
|
|
|
|
{ "Iuml", 207 },
|
|
|
|
|
{ "Kappa", 922 },
|
|
|
|
|
{ "Lambda", 923 },
|
|
|
|
|
{ "Mu", 924 },
|
|
|
|
|
{ "Ntilde", 209 },
|
|
|
|
|
{ "Nu", 925 },
|
|
|
|
|
{ "OElig", 338 },
|
|
|
|
|
{ "Oacute", 211 },
|
|
|
|
|
{ "Ocirc", 212 },
|
|
|
|
|
{ "Ograve", 210 },
|
|
|
|
|
{ "Omega", 937 },
|
|
|
|
|
{ "Omicron", 927 },
|
|
|
|
|
{ "Oslash", 216 },
|
|
|
|
|
{ "Otilde", 213 },
|
|
|
|
|
{ "Ouml", 214 },
|
|
|
|
|
{ "Phi", 934 },
|
|
|
|
|
{ "Pi", 928 },
|
|
|
|
|
{ "Prime", 8243 },
|
|
|
|
|
{ "Psi", 936 },
|
|
|
|
|
{ "Rho", 929 },
|
|
|
|
|
{ "Scaron", 352 },
|
|
|
|
|
{ "Sigma", 931 },
|
|
|
|
|
{ "THORN", 222 },
|
|
|
|
|
{ "Tau", 932 },
|
|
|
|
|
{ "Theta", 920 },
|
|
|
|
|
{ "Uacute", 218 },
|
|
|
|
|
{ "Ucirc", 219 },
|
|
|
|
|
{ "Ugrave", 217 },
|
|
|
|
|
{ "Upsilon", 933 },
|
|
|
|
|
{ "Uuml", 220 },
|
|
|
|
|
{ "Xi", 926 },
|
|
|
|
|
{ "Yacute", 221 },
|
|
|
|
|
{ "Yuml", 376 },
|
|
|
|
|
{ "Zeta", 918 },
|
|
|
|
|
{ "aacute", 225 },
|
|
|
|
|
{ "acirc", 226 },
|
|
|
|
|
{ "acute", 180 },
|
|
|
|
|
{ "aelig", 230 },
|
|
|
|
|
{ "agrave", 224 },
|
|
|
|
|
{ "alefsym", 8501 },
|
|
|
|
|
{ "alpha", 945 },
|
|
|
|
|
{ "amp", '&' },
|
|
|
|
|
{ "and", 8743 },
|
|
|
|
|
{ "ang", 8736 },
|
|
|
|
|
{ "apos", '\'' },
|
|
|
|
|
{ "aring", 229 },
|
|
|
|
|
{ "asymp", 8776 },
|
|
|
|
|
{ "atilde", 227 },
|
|
|
|
|
{ "auml", 228 },
|
|
|
|
|
{ "bdquo", 8222 },
|
|
|
|
|
{ "beta", 946 },
|
|
|
|
|
{ "brkbar", 166 },
|
|
|
|
|
{ "brvbar", 166 },
|
|
|
|
|
{ "bull", 8226 },
|
|
|
|
|
{ "cap", 8745 },
|
|
|
|
|
{ "ccedil", 231 },
|
|
|
|
|
{ "cedil", 184 },
|
|
|
|
|
{ "cent", 162 },
|
|
|
|
|
{ "chi", 967 },
|
|
|
|
|
{ "circ", 710 },
|
|
|
|
|
{ "clubs", 9827 },
|
|
|
|
|
{ "cong", 8773 },
|
|
|
|
|
{ "copy", 169 },
|
|
|
|
|
{ "crarr", 8629 },
|
|
|
|
|
{ "cup", 8746 },
|
|
|
|
|
{ "curren", 164 },
|
|
|
|
|
{ "dArr", 8659 },
|
|
|
|
|
{ "dagger", 8224 },
|
|
|
|
|
{ "darr", 8595 },
|
|
|
|
|
{ "deg", 176 },
|
|
|
|
|
{ "delta", 948 },
|
|
|
|
|
{ "diams", 9830 },
|
|
|
|
|
{ "die", 168 },
|
|
|
|
|
{ "divide", 247 },
|
|
|
|
|
{ "eacute", 233 },
|
|
|
|
|
{ "ecirc", 234 },
|
|
|
|
|
{ "egrave", 232 },
|
|
|
|
|
{ "empty", 8709 },
|
|
|
|
|
{ "emsp", 8195 },
|
|
|
|
|
{ "ensp", 8194 },
|
|
|
|
|
{ "epsilon", 949 },
|
|
|
|
|
{ "equiv", 8801 },
|
|
|
|
|
{ "eta", 951 },
|
|
|
|
|
{ "eth", 240 },
|
|
|
|
|
{ "euml", 235 },
|
|
|
|
|
{ "euro", 8364 },
|
|
|
|
|
{ "exist", 8707 },
|
|
|
|
|
{ "fnof", 402 },
|
|
|
|
|
{ "forall", 8704 },
|
|
|
|
|
{ "frac12", 189 },
|
|
|
|
|
{ "frac14", 188 },
|
|
|
|
|
{ "frac34", 190 },
|
|
|
|
|
{ "frasl", 8260 },
|
|
|
|
|
{ "gamma", 947 },
|
|
|
|
|
{ "ge", 8805 },
|
|
|
|
|
{ "gt", '>' },
|
|
|
|
|
{ "hArr", 8660 },
|
|
|
|
|
{ "harr", 8596 },
|
|
|
|
|
{ "hearts", 9829 },
|
|
|
|
|
{ "hellip", 8230 },
|
|
|
|
|
{ "hibar", 175 },
|
|
|
|
|
{ "iacute", 237 },
|
|
|
|
|
{ "icirc", 238 },
|
|
|
|
|
{ "iexcl", 161 },
|
|
|
|
|
{ "igrave", 236 },
|
|
|
|
|
{ "image", 8465 },
|
|
|
|
|
{ "infin", 8734 },
|
|
|
|
|
{ "int", 8747 },
|
|
|
|
|
{ "iota", 953 },
|
|
|
|
|
{ "iquest", 191 },
|
|
|
|
|
{ "isin", 8712 },
|
|
|
|
|
{ "iuml", 239 },
|
|
|
|
|
{ "kappa", 954 },
|
|
|
|
|
{ "lArr", 8656 },
|
|
|
|
|
{ "lambda", 955 },
|
|
|
|
|
{ "lang", 9001 },
|
|
|
|
|
{ "laquo", 171 },
|
|
|
|
|
{ "larr", 8592 },
|
|
|
|
|
{ "lceil", 8968 },
|
|
|
|
|
{ "ldquo", 8220 },
|
|
|
|
|
{ "le", 8804 },
|
|
|
|
|
{ "lfloor", 8970 },
|
|
|
|
|
{ "lowast", 8727 },
|
|
|
|
|
{ "loz", 9674 },
|
|
|
|
|
{ "lrm", 8206 },
|
|
|
|
|
{ "lsaquo", 8249 },
|
|
|
|
|
{ "lsquo", 8216 },
|
|
|
|
|
{ "lt", '<' },
|
|
|
|
|
{ "macr", 175 },
|
|
|
|
|
{ "mdash", 8212 },
|
|
|
|
|
{ "micro", 181 },
|
|
|
|
|
{ "middot", 183 },
|
|
|
|
|
{ "minus", 8722 },
|
|
|
|
|
{ "mu", 956 },
|
|
|
|
|
{ "nabla", 8711 },
|
|
|
|
|
{ "nbsp", 160 },
|
|
|
|
|
{ "ndash", 8211 },
|
|
|
|
|
{ "ne", 8800 },
|
|
|
|
|
{ "ni", 8715 },
|
|
|
|
|
{ "not", 172 },
|
|
|
|
|
{ "notin", 8713 },
|
|
|
|
|
{ "nsub", 8836 },
|
|
|
|
|
{ "ntilde", 241 },
|
|
|
|
|
{ "nu", 957 },
|
|
|
|
|
{ "oacute", 243 },
|
|
|
|
|
{ "ocirc", 244 },
|
|
|
|
|
{ "oelig", 339 },
|
|
|
|
|
{ "ograve", 242 },
|
|
|
|
|
{ "oline", 8254 },
|
|
|
|
|
{ "omega", 969 },
|
|
|
|
|
{ "omicron", 959 },
|
|
|
|
|
{ "oplus", 8853 },
|
|
|
|
|
{ "or", 8744 },
|
|
|
|
|
{ "ordf", 170 },
|
|
|
|
|
{ "ordm", 186 },
|
|
|
|
|
{ "oslash", 248 },
|
|
|
|
|
{ "otilde", 245 },
|
|
|
|
|
{ "otimes", 8855 },
|
|
|
|
|
{ "ouml", 246 },
|
|
|
|
|
{ "para", 182 },
|
|
|
|
|
{ "part", 8706 },
|
|
|
|
|
{ "permil", 8240 },
|
|
|
|
|
{ "perp", 8869 },
|
|
|
|
|
{ "phi", 966 },
|
|
|
|
|
{ "pi", 960 },
|
|
|
|
|
{ "piv", 982 },
|
|
|
|
|
{ "plusmn", 177 },
|
|
|
|
|
{ "pound", 163 },
|
|
|
|
|
{ "prime", 8242 },
|
|
|
|
|
{ "prod", 8719 },
|
|
|
|
|
{ "prop", 8733 },
|
|
|
|
|
{ "psi", 968 },
|
|
|
|
|
{ "quot", '\"' },
|
|
|
|
|
{ "rArr", 8658 },
|
|
|
|
|
{ "radic", 8730 },
|
|
|
|
|
{ "rang", 9002 },
|
|
|
|
|
{ "raquo", 187 },
|
|
|
|
|
{ "rarr", 8594 },
|
|
|
|
|
{ "rceil", 8969 },
|
|
|
|
|
{ "rdquo", 8221 },
|
|
|
|
|
{ "real", 8476 },
|
|
|
|
|
{ "reg", 174 },
|
|
|
|
|
{ "rfloor", 8971 },
|
|
|
|
|
{ "rho", 961 },
|
|
|
|
|
{ "rlm", 8207 },
|
|
|
|
|
{ "rsaquo", 8250 },
|
|
|
|
|
{ "rsquo", 8217 },
|
|
|
|
|
{ "sbquo", 8218 },
|
|
|
|
|
{ "scaron", 353 },
|
|
|
|
|
{ "sdot", 8901 },
|
|
|
|
|
{ "sect", 167 },
|
|
|
|
|
{ "shy", 173 },
|
|
|
|
|
{ "sigma", 963 },
|
|
|
|
|
{ "sigmaf", 962 },
|
|
|
|
|
{ "sim", 8764 },
|
|
|
|
|
{ "spades", 9824 },
|
|
|
|
|
{ "sub", 8834 },
|
|
|
|
|
{ "sube", 8838 },
|
|
|
|
|
{ "sum", 8721 },
|
|
|
|
|
{ "sup", 8835 },
|
|
|
|
|
{ "sup1", 185 },
|
|
|
|
|
{ "sup2", 178 },
|
|
|
|
|
{ "sup3", 179 },
|
|
|
|
|
{ "supe", 8839 },
|
|
|
|
|
{ "szlig", 223 },
|
|
|
|
|
{ "tau", 964 },
|
|
|
|
|
{ "there4", 8756 },
|
|
|
|
|
{ "theta", 952 },
|
|
|
|
|
{ "thetasym", 977 },
|
|
|
|
|
{ "thinsp", 8201 },
|
|
|
|
|
{ "thorn", 254 },
|
|
|
|
|
{ "tilde", 732 },
|
|
|
|
|
{ "times", 215 },
|
|
|
|
|
{ "trade", 8482 },
|
|
|
|
|
{ "uArr", 8657 },
|
|
|
|
|
{ "uacute", 250 },
|
|
|
|
|
{ "uarr", 8593 },
|
|
|
|
|
{ "ucirc", 251 },
|
|
|
|
|
{ "ugrave", 249 },
|
|
|
|
|
{ "uml", 168 },
|
|
|
|
|
{ "upsih", 978 },
|
|
|
|
|
{ "upsilon", 965 },
|
|
|
|
|
{ "uuml", 252 },
|
|
|
|
|
{ "weierp", 8472 },
|
|
|
|
|
{ "xi", 958 },
|
|
|
|
|
{ "yacute", 253 },
|
|
|
|
|
{ "yen", 165 },
|
|
|
|
|
{ "yuml", 255 },
|
|
|
|
|
{ "zeta", 950 },
|
|
|
|
|
{ "zwj", 8205 },
|
|
|
|
|
{ "zwnj", 8204 }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Do a binary search for the named entity...
|
|
|
|
|
first = 0;
|
|
|
|
|
last = (int)(sizeof(entities) / sizeof(entities[0]) - 1);
|
|
|
|
|
|
|
|
|
|
while ((last - first) > 1)
|
|
|
|
|
{
|
|
|
|
|
current = (first + last) / 2;
|
|
|
|
|
|
|
|
|
|
if ((diff = strcmp(name, entities[current].name)) == 0)
|
|
|
|
|
return (entities[current].val);
|
|
|
|
|
else if (diff < 0)
|
|
|
|
|
last = current;
|
|
|
|
|
else
|
|
|
|
|
first = current;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If we get here, there is a small chance that there is still a match; check first and last...
|
|
|
|
|
if (!strcmp(name, entities[first].name))
|
|
|
|
|
return (entities[first].val);
|
|
|
|
|
else if (!strcmp(name, entities[last].name))
|
|
|
|
|
return (entities[last].val);
|
|
|
|
|
else
|
|
|
|
|
return (-1);
|
|
|
|
|
}
|