diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/utf2any/extra/utf7.l |
Initial commit
Diffstat (limited to 'support/utf2any/extra/utf7.l')
-rw-r--r-- | support/utf2any/extra/utf7.l | 261 |
1 files changed, 261 insertions, 0 deletions
diff --git a/support/utf2any/extra/utf7.l b/support/utf2any/extra/utf7.l new file mode 100644 index 0000000000..204d8afc70 --- /dev/null +++ b/support/utf2any/extra/utf7.l @@ -0,0 +1,261 @@ +/* file: utf7.l */ + +%{ + +#ifdef __MSDOS__ +# include <dir.h> +# include <fcntl.h> +# include <io.h> +#else +# include <unistd.h> +#endif +#include <errno.h> +#include <stdarg.h> +#include <stdio.h> +#include <string.h> + +int + printcode = 0; + +unsigned int + outcode [2], + instep, + outstep; + +char + *programname; + +void + get_programname (char const *argv0), + syntax (void), + errit (char const *format, ...), + utf (void), + nextout (void), + outchar (long unsigned); + +#ifdef __MSDOS__ +#define strcasecmp(s1, s2) (stricmp(s1, s2)) +#endif + +#define YY_NO_UNPUT +#define YY_SKIP_YYWRAP +#ifdef yywrap +# undef yywrap +#endif +int yywrap() +{ + return 1; +} + +%} + +%Start _utf + +%% + +<INITIAL>"+-" { fputc ('+', stdout); } +<INITIAL>"+" { instep = outstep = 0; + BEGIN _utf; } + +<_utf>[A-Za-z0-9+/] { utf (); } +<_utf>"-" { BEGIN INITIAL; } +<_utf>.|\n { fputc (yytext [0], stdout); + BEGIN INITIAL; } + +%% + +void utf () +{ + unsigned + i, + c; + + i = yytext [0]; + if (i >= 'A' && i <= 'Z') + c = i - 'A'; + else if (i >= 'a' && i <= 'z') + c = i + 26 - 'a'; + else if (i >= '0' && i <= '9') + c = i + 52 - '0'; + else if (i == '+') + c = 62; + else if (i == '/') + c = 63; + + switch (instep) { + case 0: + outcode [outstep] = (c << 2); + break; + case 1: + outcode [outstep] |= (c >> 4); + nextout (); + outcode [outstep] = (c << 4); + break; + case 2: + outcode [outstep] |= (c >> 2); + nextout (); + outcode [outstep] = (c << 6); + break; + case 3: + outcode [outstep] |= c; + nextout (); + break; + } + if (++instep == 4) + instep = 0; +} + +void nextout () +{ + unsigned + c; + + if (outstep == 0) { + outstep = 1; + } else { + outstep = 0; + c = ((outcode [0] & 0xFF) << 8) | (outcode [1] & 0xFF); + outchar (c); + } +} + +void outchar (long unsigned c) +{ + int + i; + char + *s; + + /* + * iso-8859-1 + */ + if (c < 256) { + fputc (c, stdout); + return; + } + + /* + * iso-8859-15 + */ + i = 0; + switch (c) { + case 0x20Ac: i = 0xA4; break; /* euro */ + case 0x0160: i = 0xA6; break; /* S caron */ + case 0x0161: i = 0xA8; break; /* s caron */ + case 0x017D: i = 0xB4; break; /* Z caron */ + case 0x017E: i = 0xB8; break; /* z caron */ + case 0x0152: i = 0xBC; break; /* OE ligature */ + case 0x0153: i = 0xBD; break; /* oe ligature */ + case 0x0178: i = 0xBE; break; /* Y diaeresis */ + } + if (i) { + fputc (i, stdout); + return; + } + + /* + * substitutions + */ + s = NULL; + switch (c) { + case 0x0132: s = "IJ"; break; + case 0x0133: s = "ij"; break; + } + if (s) { + fputs (s, stdout); + return; + } + + if (printcode) { + if (c < 0x10000) + printf ("U+%04X", (unsigned) c); + else + printf ("U+%08lX", c); + } else + fputc (191, stdout); +} + +int main (int argc, char *argv []) +{ + get_programname (argv [0]); + + while (argc > 1) + if (! strcmp (argv [1], "-c")) { + printcode = 1; + argv++; + argc--; + } else + break; + + switch (argc) { + case 1: + if (isatty (fileno (stdin))) + syntax (); + yyin = stdin; + break; + case 2: + yyin = fopen (argv [1], "r"); + if (! yyin) + errit ("Opening file \"%s\": %s", argv [1], strerror (errno)); + break; + default: + syntax (); + } + + yylex (); + + if (yyin != stdin) + fclose (yyin); + + return 0; +} + +void get_programname (char const *argv0) +{ +#ifdef __MSDOS__ + char + name [MAXFILE]; + fnsplit (argv0, NULL, NULL, name, NULL); + programname = strdup (name); +#else /* unix */ + char + *p; + p = strrchr (argv0, '/'); + if (p) + programname = strdup (p + 1); + else + programname = strdup (argv0); +#endif +} + +void errit (char const *format, ...) +{ + va_list + list; + + fprintf (stderr, "\nError %s: ", programname); + + va_start (list, format); + vfprintf (stderr, format, list); + + fprintf (stderr, "\n\n"); + + exit (1); +} + +void syntax () +{ + fprintf ( + stderr, + "\n" + "Syntax: %s [-c] [utf-7 encoded file]\n" + "\n" + "The file will be translated to iso-8859-1 *and* iso-8859-15\n" + "\n" + " -c : print U+code for characters not in iso-8859-1/15\n" + "\n", + programname + ); + + exit (1); +} |