summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/fonts/malayalam/preproc/readfile.c
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/fonts/malayalam/preproc/readfile.c')
-rw-r--r--Master/texmf-dist/source/fonts/malayalam/preproc/readfile.c281
1 files changed, 281 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/fonts/malayalam/preproc/readfile.c b/Master/texmf-dist/source/fonts/malayalam/preproc/readfile.c
new file mode 100644
index 00000000000..5bcb01b32c5
--- /dev/null
+++ b/Master/texmf-dist/source/fonts/malayalam/preproc/readfile.c
@@ -0,0 +1,281 @@
+/*
+
+readfile.c -- read a command file
+
+get lines from a file, split up into "words", separated by spaces
+skip whitespace and comments, treats strings as a unit, interpretes
+C-like escape codes
+
+@ starts command
+% starts comment
+\ starts escape code
+" starts and ends string
+
+everything before the first command is considered comment,
+everything after @end also
+
+HISTORY:
+ 19-NOV-1992 restructuring of program (JH)
+ 22-JUL-1992 removed bug causing COMMENTCHAR in string to be interpreted (JH)
+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "readfile.h"
+
+static char *read_line(FILE *f, char *s, int n);
+static char *read_cline(FILE *f, char *s, int n);
+static char *strlow(char *s);
+static string_list *make_string_list(char *s);
+static void skip_spaces(FILE *f);
+static void skip_line(FILE *f);
+static int getword(char *s, char *d);
+static int getquotedstring(const char *s, char *d);
+static int what_escape(const char *s, char *result);
+static string_list *get_cline(FILE *f);
+
+/********/
+
+char *get_command(FILE *f, char *command, string_list **rest)
+{
+ string_list *l;
+ /* get first line starting with "@" */
+ do
+ { l = get_cline(f);
+ if(l == NULL)
+ { return NULL;
+ }
+ }
+ while(l->s[0] != COMMANDCHAR);
+
+ strcpy(command, &(l->s)[1]);
+ strlow(command);
+ *rest = l->n;
+ free(l);
+ return command;
+}
+
+static char *strlow(char *s)
+{ char *t = s;
+ while(*t!='\0') { *t = tolower(*t); t++; }
+ return s;
+}
+
+static string_list *get_cline(FILE *f)
+{ char buffer[BUFSIZE], *s = buffer;
+ s = read_cline(f, s, BUFSIZE);
+ return make_string_list(s);
+}
+
+string_list *get_line(FILE *f)
+{ char buffer[BUFSIZE], *s = buffer;
+ s = read_line(f, s, BUFSIZE);
+ return make_string_list(s);
+}
+
+static string_list *make_string_list(char *s)
+{
+ char d[BUFSIZE];
+ int i = 0;
+ string_list *result = NULL;
+ string_list **previous = &result;
+ string_list *current = NULL;
+ int empty_quoted_string;
+
+ /* break line up into words */
+ do
+ { empty_quoted_string = FALSE;
+ while(isspace(s[i]) && s[i] != '\0' && s[i] != COMMENTCHAR) i++;
+ if(s[i] == COMMENTCHAR) break;
+ if(s[i] == '"')
+ { i += getquotedstring(&s[i], d);
+ if(d[0]=='\0') empty_quoted_string = TRUE;
+ }
+ else i += getword(&s[i], d);
+ if(d[0] != '\0' || empty_quoted_string)
+ { /* insert at end in string list */
+ long len;
+ *previous = current = (string_list*)malloc(sizeof(string_list));
+ if(current==NULL){fprintf(stderr,"can't allocate");exit(1);}
+ current->n = NULL;
+ len = strlen(d);
+ len = (len==0) ? 1 : len;
+ current->s = (char*)malloc(len);
+ if(current->s==NULL){fprintf(stderr,"can't allocate");exit(1);}
+ strcpy(current->s, d);
+ previous = &(current->n);
+ }
+ }
+ while(s[i] != '\0' && i < BUFSIZE);
+ return result;
+}
+
+
+static char *read_cline(FILE *f, char *s, int n)
+/* read until <EOF> or <NL> */
+{
+ int c;
+ int i = 0;
+
+ skip_spaces(f);
+ do
+ { c=getc(f);
+ s[i++] = (char)c;
+ if(i>=n)
+ { fprintf(stderr, "buffer full, skipping rest of line\n");
+ skip_line(f);
+ break;
+ }
+ }
+ while (c != EOF && c!= '\n');
+ s[--i]='\0';
+
+ return s;
+}
+
+static char *read_line(FILE *f, char *s, int n)
+/* read until <EOF>, COMMANDCHAR or <NL> */
+{
+ int c;
+ int i = 0;
+
+ skip_spaces(f);
+ do
+ { c=getc(f);
+ s[i++] = (char)c;
+ if(i>=n)
+ { fprintf(stderr, "buffer full, skipping rest of line\n");
+ skip_line(f);
+ break;
+ }
+ if(i == 1 && c==COMMANDCHAR)
+ { ungetc(c, f);
+ s[0] = '\0';
+ return s;
+ }
+ }
+ while (c != EOF && c!= '\n');
+ s[--i]='\0';
+
+ return s;
+}
+
+static void skip_spaces(FILE *f)
+/* skip white space and comment */
+{ int c;
+ do
+ { c=getc(f);
+ while(c==COMMENTCHAR) { skip_line(f); c = getc(f); }
+ }
+ while(isspace(c) || c == '\n');
+ ungetc(c, f);
+}
+
+static void skip_line(FILE *f)
+/* skip until <NL> */
+{ int c;
+ do { c=getc(f); } while(c != EOF && c != '\n');
+}
+
+static int getword(char *s, char *d)
+{ int i = 0, j = 0;
+ while(isspace(s[i]) && s[i] != '\0') i++;
+ while(!isspace(s[i]) && s[i] != '\0') { d[j] = s[i]; j++; i++; }
+ d[j] = '\0';
+ return i;
+}
+
+static int getquotedstring(const char *s, char *d)
+{ int i = 0; /* no of chars read in source */
+ int j = 0; /* no of chars inserted in destination */
+ while(isspace(s[i]) && s[i] != '\0') i++;
+
+ if(s[i] == '"')
+ { i++;
+ while(s[i] != '"')
+ { if(s[i] == '\\') /* escape char */
+ i += what_escape(&s[i], &d[j]);
+ else
+ { d[j] = s[i];
+ }
+ j++; i++;
+ }
+ }
+ d[j] = '\0'; /* NULL-terminate */
+ i++; /* skip final " */
+ return i;
+}
+
+/* Find out what escape sequence is used. If non can be found, we just
+ forget about the backslash. Interprete numbers up to 255/177/FF
+*/
+
+#define UNSIGNED(t) (char)(((t) < 0) ? (t) + 256 : (t))
+
+static int what_escape(const char *s, char *result)
+{ int i = 1; /* length of escape sequence read */
+ int ok = TRUE;
+ int t = 0; /* temporary result */
+
+ switch(s[1])
+ { case '"': *result = '"'; break;
+ case '\\': *result = '\\'; break;
+ case 't': *result = '\t'; break;
+ case 'n': *result = '\n'; break;
+ case 'b': *result = '\b'; break;
+ case 'h': /* hexadecimal */
+ while(i < 3 && ok)
+ { i++;
+ if(s[i]>='0' && s[i]<='9') t = t * 16 + (s[i] - '0');
+ else if(s[i]>='A' && s[i]<='F') t = t * 16 + (s[i] - 'A') + 10;
+ else if(s[i]>='a' && s[i]<='f') t = t * 16 + (s[i] - 'a') + 10;
+ else
+ { if(i==2) /* no number after \h */
+ *result = 'h';
+ else /* short number after \h */
+ *result = UNSIGNED(t);
+ i--;
+ ok = FALSE;
+ }
+ }
+ if(ok) *result = UNSIGNED(t);
+ break;
+ case 'd': /* decimal */
+ while(i < 4 && ok)
+ { i++;
+ if(s[i]>='0' && s[i]<='9') t = t * 10 + (s[i] - '0');
+ else
+ { if(i==2) /* no number after \d */
+ *result = 'd';
+ else /* short number after \d */
+ *result = UNSIGNED(t);
+ i--;
+ ok = FALSE;
+ }
+ }
+ if(ok) *result = UNSIGNED(t);
+ break;
+ default: /* try octal interpretation */
+ i--;
+ while(i < 3 && ok)
+ { i++;
+ if(s[i]>='0' && s[i]<='7') t = t * 8 + (s[i] - '0');
+ else
+ { if(i==1) /* no number after \ */
+ *result = s[i];
+ else /* short number after \ */
+ { *result = UNSIGNED(t);
+ i--;
+ }
+ ok = FALSE;
+ }
+ }
+ if(ok) *result = UNSIGNED(t);
+ }
+ return i;
+}
+