summaryrefslogtreecommitdiff
path: root/support/utf2any/extra/utf7.l
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/utf2any/extra/utf7.l
Initial commit
Diffstat (limited to 'support/utf2any/extra/utf7.l')
-rw-r--r--support/utf2any/extra/utf7.l261
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);
+}