summaryrefslogtreecommitdiff
path: root/systems/knuth/local/web/tangext.c
diff options
context:
space:
mode:
Diffstat (limited to 'systems/knuth/local/web/tangext.c')
-rw-r--r--systems/knuth/local/web/tangext.c106
1 files changed, 106 insertions, 0 deletions
diff --git a/systems/knuth/local/web/tangext.c b/systems/knuth/local/web/tangext.c
new file mode 100644
index 0000000000..2a8a88d292
--- /dev/null
+++ b/systems/knuth/local/web/tangext.c
@@ -0,0 +1,106 @@
+/* External procedures for tangle/weave */
+/* Written by Don Knuth, 29 April 2000, based on Howard Trickey's code of 83 */
+
+/* Note: The input files are read directly with C routines, instead
+ of using the Pascal runtime system. So we do our own EOF testing.
+ The GNU Pascal routines are used only to open ("reset") the files. */
+
+#define BUF_SIZE 500 /* should agree with long_buf_size in weave.web */
+#define max_file_name_length 60 /* should agree with tangle.ch */
+
+#include "GPCtypes.h" /* defines GNU Pascal I/O structure */
+#include <string.h>
+
+void Argv(int n, char* str)
+{
+ register char *s,*t;
+ if (n<0 || n>=_p_argc) return;
+ s=_p_argv[n];
+ if (strlen(s) >= max_file_name_length-5) {
+ str[0]='\0'; return; /* TANGLE doesn't want it too long */
+ }
+ for (t=str; *s; s++,t++) *t=*s;
+ *t='\0';
+}
+
+void Flushstdout()
+{
+ fflush(stdout);
+}
+
+#define buffer Buffer /* GNU Pascal likes to capitalize */
+#define xord Xord
+#define xchr Xchr
+#define limit Limit
+
+unsigned char buffer[BUF_SIZE+1]; /* 0..BUF_SIZE. Input goes here */
+unsigned char xord[256];
+unsigned char xchr[256]; /* character translation arrays */
+int limit; /* index into buffer */
+
+/*
+ * lineread reads from the Pascal text file with iorec pointer filep
+ * into buffer[0], buffer[1],..., buffer[limit-1] (and
+ * setting "limit").
+ * Characters are read until a newline is found (which isn't put in the
+ * buffer) or until the next character would go into buffer[BUF_SIZE].
+ * And trailing blanks are to be ignored, so limit is really set to
+ * one past the last non-blank.
+ * The characters need to be translated, so really xord[c] is put into
+ * the buffer when c is read.
+ * If end-of-file is encountered, the FilSta field of *filep is set
+ * appropriately.
+ */
+void Lineread(FDR filep)
+{
+ register int c;
+ register unsigned char *cs; /* points to where next char goes */
+ register unsigned char *cnb; /* last non-blank character input */
+ register FILE *iop; /* stdio-style FILE pointer */
+ register int l; /* how many chars before buffer overflow */
+
+ iop = filep->FilJfn;
+ cnb = cs = &buffer[0];
+ l = BUF_SIZE;
+
+ /* overflow when next char would go into buffer[BUF_SIZE] */
+ while ((--l >= 0) && ((c = getc(iop)) != EOF) && (c != '\n')) {
+ if ((*cs++ = xord[c]) != ' ')
+ cnb = cs;
+ }
+
+ if (c == EOF)
+ filep->FilSta |= FiEof; /* we hit end-of-file */
+ /* actually that wasn't necessary, since testeof uses feof */
+
+ limit = (cnb - &buffer[0]);
+}
+
+/*
+ * testeof(filep)
+ *
+ * Test whether or not the Pascal text file with iorec pointer filep
+ * has reached end-of-file (when the only I/O on it is done with
+ * lineread, above).
+ * We may have to read the next character and unget it to see if perhaps
+ * the end-of-file is next.
+ */
+bool Testeof(FDR filep)
+{
+ register int c;
+ register FILE *iop; /* stdio-style FILE pointer */
+
+ iop = filep->FilJfn;
+ if (feof(iop)) return TRUE;
+ c = getc(iop);
+ if (c == EOF) return TRUE;
+ else {
+ ungetc(c,iop);
+ return FALSE;
+ }
+}
+
+void Exit(int c)
+{
+ exit(c);
+}