Commit 98ca7e9c authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

resolve_xml_special_chars: don't reinvent bsearch()

parent cc23bbdc
...@@ -236,7 +236,7 @@ static const struct xml_entity_s ...@@ -236,7 +236,7 @@ static const struct xml_entity_s
{ {
char psz_entity[8]; char psz_entity[8];
char psz_char[4]; char psz_char[4];
} p_xml_entities[] = { } xml_entities[] = {
/* Important: this list has to be in alphabetical order (psz_entity-wise) */ /* Important: this list has to be in alphabetical order (psz_entity-wise) */
{ "AElig;", "Æ" }, { "AElig;", "Æ" },
{ "Aacute;", "Á" }, { "Aacute;", "Á" },
...@@ -277,6 +277,8 @@ static const struct xml_entity_s ...@@ -277,6 +277,8 @@ static const struct xml_entity_s
{ "acute;", "´" }, { "acute;", "´" },
{ "aelig;", "æ" }, { "aelig;", "æ" },
{ "agrave;", "à" }, { "agrave;", "à" },
{ "amp;", "&" },
{ "apos;" "'" },
{ "aring;", "å" }, { "aring;", "å" },
{ "atilde;", "ã" }, { "atilde;", "ã" },
{ "auml;", "ä" }, { "auml;", "ä" },
...@@ -300,6 +302,7 @@ static const struct xml_entity_s ...@@ -300,6 +302,7 @@ static const struct xml_entity_s
{ "frac12;", "½" }, { "frac12;", "½" },
{ "frac14;", "¼" }, { "frac14;", "¼" },
{ "frac34;", "¾" }, { "frac34;", "¾" },
{ "gt;", ">" },
{ "hellip;", "…" }, { "hellip;", "…" },
{ "iacute;", "í" }, { "iacute;", "í" },
{ "icirc;", "î" }, { "icirc;", "î" },
...@@ -311,6 +314,7 @@ static const struct xml_entity_s ...@@ -311,6 +314,7 @@ static const struct xml_entity_s
{ "ldquo;", "“" }, { "ldquo;", "“" },
{ "lsaquo;", "‹" }, { "lsaquo;", "‹" },
{ "lsquo;", "‘" }, { "lsquo;", "‘" },
{ "lt;" "<" },
{ "macr;", "¯" }, { "macr;", "¯" },
{ "mdash;", "—" }, { "mdash;", "—" },
{ "micro;", "µ" }, { "micro;", "µ" },
...@@ -332,6 +336,7 @@ static const struct xml_entity_s ...@@ -332,6 +336,7 @@ static const struct xml_entity_s
{ "permil;", "‰" }, { "permil;", "‰" },
{ "plusmn;", "±" }, { "plusmn;", "±" },
{ "pound;", "£" }, { "pound;", "£" },
{ "quot;", "\"" },
{ "raquo;", "»" }, { "raquo;", "»" },
{ "rdquo;", "”" }, { "rdquo;", "”" },
{ "reg;", "®" }, { "reg;", "®" },
...@@ -359,6 +364,14 @@ static const struct xml_entity_s ...@@ -359,6 +364,14 @@ static const struct xml_entity_s
{ "yuml;", "ÿ" }, { "yuml;", "ÿ" },
}; };
static int cmp_entity (const void *key, const void *elem)
{
const struct xml_entity_s *ent = elem;
const char *name = key;
return strncmp (name, ent->psz_entity, strlen (ent->psz_entity));
}
/** /**
* Converts "&lt;", "&gt;" and "&amp;" to "<", ">" and "&" * Converts "&lt;", "&gt;" and "&amp;" to "<", ">" and "&"
* \param string to convert * \param string to convert
...@@ -371,20 +384,8 @@ void resolve_xml_special_chars( char *psz_value ) ...@@ -371,20 +384,8 @@ void resolve_xml_special_chars( char *psz_value )
{ {
if( *psz_value == '&' ) if( *psz_value == '&' )
{ {
char *psz_value1 = psz_value + 1; const char *psz_value1 = psz_value + 1;
#define TRY_CHAR( src, dst ) \ if( *psz_value1 == '#' )
if( !strncmp( psz_value1, src";", strlen( src";" ) ) ) \
{ \
*p_pos = dst; \
psz_value += strlen( src ) + 2; \
}
TRY_CHAR( "lt", '<' )
else TRY_CHAR( "amp", '&' )
else TRY_CHAR( "apos", '\'' )
else TRY_CHAR( "gt", '>' )
else TRY_CHAR( "quot", '"' )
#undef TRY_CHAR
else if( *psz_value1 == '#' )
{ {
char *psz_end; char *psz_end;
int i = strtol( psz_value+2, &psz_end, 10 ); int i = strtol( psz_value+2, &psz_end, 10 );
...@@ -411,37 +412,20 @@ void resolve_xml_special_chars( char *psz_value ) ...@@ -411,37 +412,20 @@ void resolve_xml_special_chars( char *psz_value )
} }
else else
{ {
const size_t i_entities = sizeof( p_xml_entities ) / const struct xml_entity_s *ent;
sizeof( p_xml_entities[0] );
assert( i_entities < 128 ); ent = bsearch (psz_value1, xml_entities,
size_t step = 128>>1; sizeof (xml_entities) / sizeof (*ent),
size_t i = step-1; sizeof (*ent), cmp_entity);
int cmp = -1; if (ent != NULL)
while( step )
{ {
size_t ilen = strlen( p_xml_entities[i].psz_entity ); size_t olen = strlen (ent->psz_char);
step >>= 1; memcpy (p_pos, ent->psz_char, olen);
if( i >= i_entities ) p_pos += olen - 1;
cmp = -1; psz_value += strlen (ent->psz_entity) + 1;
else
cmp = strncmp( psz_value1, /* Skip the & */
p_xml_entities[i].psz_entity,
strlen( p_xml_entities[i].psz_entity ) );
if( cmp == 0 )
{
size_t olen = strlen( p_xml_entities[i].psz_char );
memcpy( p_pos, p_xml_entities[i].psz_char, olen );
p_pos += olen - 1;
psz_value += ilen+1;
break;
}
else if( cmp < 0 )
i -= step;
else
i += step;
} }
if( cmp != 0 ) else
{ { /* No match */
*p_pos = *psz_value; *p_pos = *psz_value;
psz_value++; psz_value++;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment