Platon Technologies
not logged in Login Registration
EnglishSlovak
open source software development celebrating 10 years of open source development! Friday, March 29, 2024

File: [Platon] / libplaton / platon / html / escape.c (download)

Revision 1.2, Tue Apr 22 14:21:34 2003 UTC (20 years, 11 months ago) by nepto


Changes since 1.1: +94 -38 lines

Implemented unescaping function for HTML entities.
Added extensive and exhaustive Doxygen documentation.

#include <stdlib.h>
#include <string.h>

#include <platon/html/escape.h>

#define HTML_ESCAPE_TABLE_TERMINATOR { '\0', NULL }

static struct html_escape_table html_escape_space[] = { /* {{{ */
    { ' ', "&nbsp;" },
    HTML_ESCAPE_TABLE_TERMINATOR
}; /* }}} */

static struct html_escape_table html_escape_special_chars[] = { /* {{{ */
    { '\x3C', "&lt;"  },
    { '\x3E', "&gt;"  },
    { '\x26', "&amp;" },
    HTML_ESCAPE_TABLE_TERMINATOR
}; /* }}} */

static struct html_escape_table html_escape_quotes[] = { /* {{{ */
    { '\"', "&quot;" },
    { '\'', "&#039;" },
    HTML_ESCAPE_TABLE_TERMINATOR
}; /* }}} */

static struct html_escape_table html_escape_iso8859_1[] = { /* {{{ */
    HTML_ESCAPE_TABLE_TERMINATOR
}; /* }}} */

static struct html_escape_table html_escape_iso8859_2[] = { /* {{{ */
    HTML_ESCAPE_TABLE_TERMINATOR
}; /* }}} */

static struct html_escape_table html_escape_iso8859_15[] = { /* {{{ */
    { '\xE4', "&auml;"  },
    { '\xC4', "&Auml;"  },
    { '\xF6', "&ouml;"  },
    { '\xD6', "&Ouml;"  },
    { '\xFC', "&uuml;"  },
    { '\xDC', "&Uuml;"  },
    { '\xDF', "&szlig;" },
    { '\xA4', "&euro;"  },
    HTML_ESCAPE_TABLE_TERMINATOR
}; /* }}} */

static struct html_escape_table *html_escape_tables[] = { /* {{{ */
    html_escape_space,
    html_escape_special_chars,
    html_escape_quotes,
    html_escape_iso8859_1,
    html_escape_iso8859_2,
    html_escape_iso8859_15,
    NULL
}; /* }}} */

    char *
PLATON_FUNC(html_escape)(str, types)
    const char *str;
    const int types;
{ /* {{{ */
    register int i, ii, j, len = 1;
    struct html_escape_table *current_table;
    char *html;

    if ((html = (char *) malloc(1 * sizeof(char))) == NULL)
        return NULL;

    /* Loop through every character of str */
    for (*html = '\0'; *str != '\0'; str++) {

        /* Loop through every HTML escape table */
        for (i = 0, ii = 1; ; i++, ii *= 2) { /* ii == 2^i */
            if ((current_table = html_escape_tables[i]) == NULL)
                break;

            /* Check if table is selected */
            if (! types & ii)
                continue;

            /* Loop though every entity of HTML escape table */
            for (j = 0; current_table[j].html != NULL; j++) {

                /* If character to escape was found */
                if (*str != current_table[j].code)
                    continue;

                /* Substitute character with appropriate entity */
                len += strlen(current_table[j].html);
                if ((html = (char *) realloc(html, len)) == NULL)
                    return NULL;
                strcat(html, current_table[j].html);
                break;
            }
            if (current_table[j].html != NULL)
                break;
        }

        /* If character was substitued */
        if (current_table != NULL)
            continue;

        /* Just copy character */
        len++;
        if ((html = (char *) realloc(html, len)) == NULL)
            return NULL;
        html[len - 2] = *str;
        html[len - 1] = '\0';
    }

    return html;
} /* }}} */

    char *
PLATON_FUNC(html_unescape)(html, types)
    const char *html;
    const int types;
{ /* {{{ */
    register int i, ii, j, len;
    struct html_escape_table *current_table;
    char *str, *ptr;

    /* String duplication */
    if ((str = strdup(html)) == NULL)
        return NULL;

    /* Loop through every HTML escape table */
    for (i = 0, ii = 1; ; i++, ii *= 2) { /* ii == 2^i */
        if ((current_table = html_escape_tables[i]) == NULL)
            break;

        /* Check if table is selected */
        if (! types & ii)
            continue;

        /* Loop though every entity of HTML escape table */
        for (j = 0; current_table[j].html != NULL; j++) {

            while ((ptr = strstr(str, current_table[j].html)) != NULL) {
                len  = strlen(current_table[j].html);
                if (len <= 0)
                    break;
                *ptr = current_table[j].code;
                memmove((void *) (ptr + 1), (void *) (ptr + len),
                        strlen(ptr + len) + 1);
            }

        }
    }

    return str;
} /* }}} */

#if defined(SELF) || defined(SELFTEST) || defined(SELF_HTML_ESCAPE) /* {{{ */

#include <stdio.h>

#define TEST_STRING        "<<--'//'-->>"

    int
main(argc, argv)
    int argc;
    char **argv;
{
    register char *s1, *s2;

    s1 = htmlspecialchars(TEST_STRING);
    printf("htmlspecialchars(\"%s\") = \"%s\"\n", TEST_STRING, s1);
    s2 = html_unescape(s1, HTML_ESCAPE_HTMLSPECIALCHARS);
    printf("html_unescape(\"%s\", HTML_ESCAPE_HTMLSPECIALCHARS) = \"%s\"\n", s1, s2);
    free(s2);
    free(s1);

    s1 = htmlentities(TEST_STRING);
    printf("htmlentities(\"%s\") = \"%s\"\n", TEST_STRING, s1);
    s2 = html_unescape(s1, HTML_ESCAPE_HTMLENTITIES);
    printf("html_unescape(\"%s\", HTML_ESCAPE_HTMLENTITIES) = \"%s\"\n", s1, s2);
    free(s2);
    free(s1);

    return 0;
}

#endif /* #if defined(SELF) || defined(SELFTEST) || defined(SELF_STRCGI) */ /* }}} */

/* Modeline for ViM {{{
 * vim: set ts=4:
 * vim600: fdm=marker fdl=0 fdc=0:
 * }}} */


Platon Group <platon@platon.org> http://platon.org/
Copyright © 2002-2006 Platon Group
Site powered by Metafox CMS
Go to Top