Smarter presentation. Bug fix in email header interpretation.
[egate.git] / kernel / ttyemit.c
diff --git a/kernel/ttyemit.c b/kernel/ttyemit.c
new file mode 100644 (file)
index 0000000..4473db0
--- /dev/null
@@ -0,0 +1,110 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include "kernel.h"
+static char line_buf[256];
+static int  line_col = 0;
+static int  esc_flag = 0;
+
+static int  line_min = 30;
+static int  line_max = 76;
+static FILE *out_f = stdout;
+
+void tty_init (FILE *out, int min, int max)
+{
+    out_f = out;
+    if (min > 0)
+        line_min = min;
+    if (max > 2)
+        line_max = max;
+    line_col = 0;
+    esc_flag = 0;
+}
+
+static void flush (void)
+{
+    int j;
+
+    for (j = 0; j<line_col; j++)
+        putc (line_buf[j], out_f);
+    putc ('\n', out_f);
+    line_col = 0;
+}
+
+static void split (int ch)
+{
+    int i = line_col, j;
+
+    while (1)
+        if (line_buf[--i] == ' ')
+        {
+            int extra = 0;
+
+            for (j = 0; j<i; j++)
+            {
+#if 1
+                if (j>1 && line_buf[j] >= 'A'&& line_buf[j] <= 'Z'
+                     && line_buf[j-1] == ' '
+                     && (line_buf[j-2] == '.' || line_buf[j-2] == ';')
+                     && extra < line_max-i )
+                {
+                    extra++;
+                    putc (' ', out_f);
+                }
+#endif
+                putc (line_buf[j], out_f);
+            }
+            putc ('\n', out_f);
+            j = 0;
+            ++i;
+            while (i < line_col)
+                line_buf[j++] = line_buf[i++];
+            line_col = j;
+            break;
+        }
+        else if (i < line_min)
+            flush ();
+}
+
+static void escape (int ch)
+{
+    switch (ch)
+    {
+    case 'n':
+       if (line_col >= line_max)
+           split (' ');
+       else
+            flush ();
+        break;
+    case 't':
+        do
+            line_buf[line_col++] = ' ';
+        while (line_col & 7);
+        break;
+    case 's':
+        line_buf[line_col++] = ' ';
+        break;
+    default:
+        line_buf[line_col++] = ch;
+    }
+}
+
+void tty_emit (int ch)
+{
+    if (esc_flag)
+    {
+        escape (ch);
+        esc_flag = 0;
+    }
+    else if (ch == '\\')
+        esc_flag = 1;
+    else if (ch == '\n')
+        flush ();
+    else if (line_col || ch != ' ')
+    {
+        line_buf[line_col++] = ch;
+        if (line_col >= line_max)
+            split (ch);
+    }
+}