From: Laurent MAZET Date: Tue, 6 Oct 2026 17:26:45 +0000 (+0200) Subject: support c codes X-Git-Url: https://secure.softndesign.org/git/?a=commitdiff_plain;h=657bc360349a92344eb0ab08e9c669235bd550bc;p=html2txt.git support c codes --- diff --git a/element.c b/element.c index 618ea52..a7153ee 100644 --- a/element.c +++ b/element.c @@ -6,9 +6,9 @@ typedef struct { char *name; char *glyph; -} nchar_t; +} nstring_t; -nchar_t elements[] = { +nstring_t html_elements[] = { { "Aacute;", "Á" }, { "Aacute", "Á" }, { "aacute;", "á" }, @@ -2243,10 +2243,10 @@ nchar_t elements[] = { { NULL, NULL } }; -/* check element */ -int check_element (char *str, char **glyph) +/* check Html element */ +int check_html_element (char *str, char **glyph) { - nchar_t *pt = elements; + nstring_t *pt = html_elements; while (pt->name) { int len = strlen (pt->name); if (strncmp (str, pt->name, len) == 0) { @@ -2258,6 +2258,41 @@ int check_element (char *str, char **glyph) return 0; } +typedef struct { + char letter; + char *glyph; +} nchar_t; + +nchar_t c_elements[] = { + { 'a', "\a" }, + { 'b', "\b" }, + { 'e', "\e" }, + { 'f', "\f" }, + { 'n', "\n" }, + { 'r', "\r" }, + { 't', "\t" }, + { 'v', "\v" }, + { '\\', "\\" }, + { '\'', "'" }, + { '"', "\"" }, + { '?', "\?" }, + { '\0', NULL } +}; + +/* check C element */ +int check_c_element (char c, char **glyph) +{ + nchar_t *pt = c_elements; + while (pt->letter) { + if (c == pt->letter) { + *glyph = pt->glyph; + return 1; + } + pt++; + } + return 0; +} + /* check hexa character */ int is_hexa (char c) { @@ -2272,8 +2307,8 @@ int is_hexa (char c) return ret; } -/* check code */ -int check_code (char *str, char *out) +/* check Html code */ +int check_html_code (char *str, char *out) { int i = 0, l = 0; while (str[i] != ';') { @@ -2294,4 +2329,46 @@ int check_code (char *str, char *out) return i + 1; } +/* check C code in octal */ +int check_c_code_octal (char *str, char *out) +{ + for (int i = 0; i < 3; i++) { + if ((str[i] < '0') || (str[i] > '7')) { + out[0] = '\0'; + return 0; + } + out[0] = (out[0] << 3) + str[i] - '0'; + } + return 3; +} + +/* check C code in hexa */ +int check_c_code_hexa (char *str, char *out, int len) +{ + int i = 0, l = 0; + while (len-- != 0) { + int v = 0; + if ((str[i] == '\0') || ((v = is_hexa(str[i])) < 0)) { + if (len < 0) { + if ((i > 1) && (i % 2 == 1)) { + i = 2 * (i / 2); + out[l] = '\0'; + } + return i; + } + *out = '\0'; + return 0; + } + + out[l] = (out[l] << 4) + v; + if (i % 2 == 1) { + if (out[l] != 0) { + l++; + } + } + i++; + } + return i; +} + /* vim: set ts=4 sw=4 et: */ diff --git a/element.h b/element.h index 4cd8c10..e56cb5e 100644 --- a/element.h +++ b/element.h @@ -1,9 +1,15 @@ #ifndef __ELEMENT_H__ #define __ELEMENT_H__ -int check_element (char *str, char **glyph); +int check_html_element (char *str, char **glyph); -int check_code (char *str, char *out); +int check_c_element (char c, char **glyph); + +int check_html_code (char *str, char *out); + +int check_c_code_octal (char *str, char *out); + +int check_c_code_hexa (char *str, char *out, int len); #endif /* __ELEMENT_H__ */ diff --git a/html2txt.c b/html2txt.c index 2b5183f..614ed04 100644 --- a/html2txt.c +++ b/html2txt.c @@ -31,17 +31,18 @@ /* static variables */ char *progname = NULL; char *version = "0.1"; - +int ccode = 0; char *fin = NULL; /* usage function */ int usage (int ret) { FILE *fd = ret ? stderr : stdout; - fprintf (fd, "usage: %s [-v int] [-h] [-i file]\n", progname); + fprintf (fd, "usage: %s [-c] [-i file] [-v int] [-h]\n", progname); + fprintf (fd, " -c: translate c code (%s)\n", ccode ? "true" : "false"); fprintf (fd, " -h: help message\n"); - fprintf (fd, " -v: verbose level(%d)\n", verbose); fprintf (fd, " -i file: input file (%s)\n", fin ? fin : ""); + fprintf (fd, " -v: verbose level(%d)\n", verbose); fprintf (fd, "%s version %s\n", progname, version); return ret; @@ -69,6 +70,9 @@ int main (int argc, char *argv[]) } char c = arg[1]; switch (c) { + case 'c': + ccode = 1; + break; case 'i': arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL; if (arg == NULL) { @@ -129,19 +133,20 @@ int main (int argc, char *argv[]) while (*pt) { char *glyph = NULL; char out[5] = {0}; + VERBOSE (DEBUG, "::: %c(%d) 0x%p", *pt, *pt, pt); switch (*pt) { case '<': while ((*pt) && (*pt != '>')) pt++; break; case '&': if (pt[1] == '#') { - pt += check_code (pt + 2, out); + pt += check_html_code (pt + 2, out); if (*out != '\0') { glyph = out; pt++; } } else { - pt += check_element (pt + 1, &glyph); + pt += check_html_element (pt + 1, &glyph); } if (glyph) { if (glyph != out) { @@ -152,6 +157,41 @@ int main (int argc, char *argv[]) out[1] = '\0'; } break; + case '\\': + if (ccode) { + int offset = 0; + if ((pt[1] >= '0') && (pt[1] <= '7')) { + pt += check_c_code_octal (pt + 1, out); + } else if (pt[1] == 'x') { + pt += check_c_code_hexa (pt + 2, out, -1); + offset++; + } else if (pt[1] == 'u') { + pt += check_c_code_hexa (pt + 2, out, 4); + offset++; + } else if (pt[1] == 'U') { + pt += check_c_code_hexa (pt + 2, out, 8); + offset++; + } else { + VERBOSE (DEBUG, " 0x%p -> ", pt); + pt += check_c_element (pt[1], &glyph); + VERBOSE (DEBUG, " 0x%p %d", pt, offset); + } + if (*out != '\0') { + glyph = out; + } + if (glyph) { + if (glyph != out) { + strcpy (out, glyph); + } + pt += offset; + VERBOSE (DEBUG, " 0x%p", pt); + } else { + strncpy (out, pt, 1); + out[1] = '\0'; + } + break; + } + // fallthrough default: strncpy (out, pt, 1); } @@ -159,6 +199,7 @@ int main (int argc, char *argv[]) printf ("%s", out); } pt++; + VERBOSE (DEBUG, " %p\n", pt); } free (buffer); @@ -177,6 +218,16 @@ int main (int argc, char *argv[]) /* test: echo 'f6F' | html2txt.exe -v 1| grep '^f6F$' */ /* test: echo '&#foobar' | html2txt.exe -v 1| grep '^&#foobar$' */ /* test: echo '&foobar' | html2txt.exe -v 2 | grep '^&foobar' */ +/* test: echo '\nx\tx\z' | html2txt.exe -c | grep '^x.x\\z$' */ +/* test: echo '\101b\102a' | html2txt.exe -c | grep '^AbBa$' */ +/* test: echo 'a\108b' | html2txt.exe -c | grep '^a\\108b$' */ +/* test: echo '\x41b\x62a' | html2txt.exe -c | grep '^Abba$' */ +/* test: echo '\x41 b\x62 a' | html2txt.exe -c | grep '^A bb a$' */ +/* test: echo '\x41b\xa\x62a' | html2txt.exe -c | grep '^Ab$' */ +/* test: echo '\x41b\xa\x62a' | html2txt.exe -c | grep '^ba$' */ +/* test: echo '\u0041b\u0062a' | html2txt.exe -c | grep '^Abba$' */ +/* test: echo '\u004xb\u62a' | html2txt.exe -c | grep '^\\u004xb\\u62a$' */ +/* test: echo '\U00000041b\U00000062a' | html2txt.exe -c | grep '^Abba$' */ /* test: html2txt.exe -i test.html >/dev/null */ /* vim: set ts=4 sw=4 et: */