summaryrefslogtreecommitdiff
path: root/dviware/quicspool/libprofile
diff options
context:
space:
mode:
Diffstat (limited to 'dviware/quicspool/libprofile')
-rw-r--r--dviware/quicspool/libprofile/boolean.c79
-rw-r--r--dviware/quicspool/libprofile/free.c62
-rw-r--r--dviware/quicspool/libprofile/has.c63
-rw-r--r--dviware/quicspool/libprofile/makefile29
-rw-r--r--dviware/quicspool/libprofile/makefile.trw29
-rw-r--r--dviware/quicspool/libprofile/profile.h63
-rw-r--r--dviware/quicspool/libprofile/read.c834
-rw-r--r--dviware/quicspool/libprofile/space.c60
-rw-r--r--dviware/quicspool/libprofile/write.c206
9 files changed, 1425 insertions, 0 deletions
diff --git a/dviware/quicspool/libprofile/boolean.c b/dviware/quicspool/libprofile/boolean.c
new file mode 100644
index 0000000000..a26df19a38
--- /dev/null
+++ b/dviware/quicspool/libprofile/boolean.c
@@ -0,0 +1,79 @@
+static char *rcs = "$Header: boolean.c,v 1.1 88/01/15 12:16:56 simpson Rel $";
+/*
+$Log: boolean.c,v $
+ * Revision 1.1 88/01/15 12:16:56 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 17:02:10 simpson
+ * beta test
+ *
+*/
+#include <ctype.h>
+#include "profile.h"
+
+static char *Yes[] = {
+ "yes",
+ "on",
+ "true",
+ "enable",
+ "available",
+ "present",
+ 0
+};
+
+static char *No[] = {
+ "no",
+ "off",
+ "false",
+ "disable",
+ "unavailable",
+ "absent",
+ 0
+};
+
+int profile_boolean (v)
+PROFILE_VALUE *v;
+{
+ char x[16];
+ int i;
+
+ if (v == 0)
+ return(0);
+
+ switch (v->class) {
+ case PROFILE_OTHER:
+ case PROFILE_STRING:
+ strncpy(x, v->value.s, sizeof(x)-1);
+ x[sizeof(x)-1] = 0;
+ downshift(x);
+ for (i = 0; Yes[i]; i++)
+ if (strcmp(x, Yes[i]) == 0)
+ return(1);
+ else if (strcmp(x, No[i]) == 0)
+ return(0);
+ return(-1); /* unknown string */
+
+ case PROFILE_HEX:
+ case PROFILE_INTEGER:
+ case PROFILE_OCTAL:
+ return(v->value.i != 0);
+
+ case PROFILE_CHARACTER:
+ return(v->value.c != 0);
+
+ case PROFILE_FLOAT:
+ return(v->value.f != 0.0);
+
+ default:
+ return(-1); /* unknown class */
+ }
+}
+
+/* downshift a string in place */
+static downshift (s)
+char *s;
+{
+ for (; *s; s++)
+ if (isupper(*s))
+ *s = tolower(*s);
+}
diff --git a/dviware/quicspool/libprofile/free.c b/dviware/quicspool/libprofile/free.c
new file mode 100644
index 0000000000..1832e0c88f
--- /dev/null
+++ b/dviware/quicspool/libprofile/free.c
@@ -0,0 +1,62 @@
+static char *rcs = "$Header: free.c,v 1.1 88/01/15 12:16:58 simpson Rel $";
+/*
+$Log: free.c,v $
+ * Revision 1.1 88/01/15 12:16:58 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 17:02:11 simpson
+ * beta test
+ *
+*/
+#include "profile.h"
+
+profile_free_profile (s)
+PROFILE_STANZA *s;
+{
+ PROFILE_STANZA *x;
+
+ for (x = s; x != (PROFILE_STANZA *)0 && x != s; x = x->next)
+ profile_free_stanza(x);
+}
+
+profile_free_stanza (s)
+PROFILE_STANZA *s;
+{
+ free_markers(s->marker);
+ free_bindings(s->binding);
+ free(s);
+}
+
+static free_markers (m)
+PROFILE_MARKER *m;
+{
+ PROFILE_MARKER *x;
+
+ for (; m; m = x) {
+ x = m->next;
+ free(m);
+ }
+}
+
+static free_bindings (b)
+PROFILE_BINDING *b;
+{
+ PROFILE_BINDING *x;
+
+ for (; b; b = x) {
+ x = b->next;
+ free_values(b->value);
+ free(b);
+ }
+}
+
+static free_values (v)
+PROFILE_VALUE *v;
+{
+ PROFILE_VALUE *x;
+
+ for (; v; v = x) {
+ x = v->next;
+ free(v);
+ }
+}
diff --git a/dviware/quicspool/libprofile/has.c b/dviware/quicspool/libprofile/has.c
new file mode 100644
index 0000000000..a215cd3674
--- /dev/null
+++ b/dviware/quicspool/libprofile/has.c
@@ -0,0 +1,63 @@
+static char *rcs = "$Header: has.c,v 1.1 88/01/15 12:17:00 simpson Rel $";
+/*
+$Log: has.c,v $
+ * Revision 1.1 88/01/15 12:17:00 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 17:02:12 simpson
+ * beta test
+ *
+*/
+#include <stdio.h>
+#include "profile.h"
+
+PROFILE_MARKER *profile_has_marker (s, m)
+PROFILE_STANZA *s;
+char *m;
+{
+ PROFILE_MARKER *x;
+ int result;
+
+ for (x = s->marker; x; x = x->next)
+ if(glob_match(x->text, m) > 0)
+ return(x);
+ return((PROFILE_MARKER *)0);
+}
+
+/*
+ * read down a linked list of stanzas looking
+ * for a stanza that has the requested markers
+ */
+PROFILE_STANZA *profile_has_stanza(s, marker)
+PROFILE_STANZA *s;
+char *marker[]; /* terminated by a null pointer */
+{
+ int i;
+ PROFILE_STANZA *x;
+
+ if (s == NULL)
+ return(s);
+ x = s;
+ do {
+ for (i = 0; marker[i] != NULL; i++)
+ if (profile_has_marker(x, marker[i]) == NULL)
+ break;
+ if (marker[i] == NULL)
+ return(x);
+ x = x->next;
+ } while (x != s && x != NULL);
+
+ return((PROFILE_STANZA *)NULL);
+}
+
+PROFILE_BINDING *profile_has_binding (s, b)
+PROFILE_STANZA *s;
+char *b;
+{
+ PROFILE_BINDING *x;
+
+ for (x = s->binding; x; x = x->next)
+ if (glob_match(x->name, b) > 0)
+ return(x);
+ return((PROFILE_BINDING *)0);
+}
diff --git a/dviware/quicspool/libprofile/makefile b/dviware/quicspool/libprofile/makefile
new file mode 100644
index 0000000000..369b5bc101
--- /dev/null
+++ b/dviware/quicspool/libprofile/makefile
@@ -0,0 +1,29 @@
+# $Header: Makefile,v 1.1 88/01/15 12:16:52 simpson Rel $
+# $Log: Makefile,v $
+#Revision 1.1 88/01/15 12:16:52 simpson
+#initial release
+#
+#Revision 0.1 87/12/11 17:20:06 simpson
+#beta test
+#
+INCLUDE=/usr/include/local
+LIB=/usr/local/lib
+
+all: libprofile.a
+
+# This system include file is needed right away
+configure:
+ install -c -m 644 profile.h $(INCLUDE)
+
+libprofile.a: boolean.o free.o has.o read.o space.o write.o
+ ar cr libprofile.a boolean.o free.o has.o read.o space.o write.o
+ ranlib libprofile.a
+
+install:
+ install -c -m 644 profile.h $(INCLUDE)
+ install -m 644 libprofile.a $(LIB)
+
+clean:
+ -rm *.o libprofile.a
+
+boolean.o free.o has.o read.o space.o write.o: profile.h
diff --git a/dviware/quicspool/libprofile/makefile.trw b/dviware/quicspool/libprofile/makefile.trw
new file mode 100644
index 0000000000..ce136b7693
--- /dev/null
+++ b/dviware/quicspool/libprofile/makefile.trw
@@ -0,0 +1,29 @@
+# $Header: Makefile.TRW,v 1.1 88/01/15 12:16:54 simpson Rel $
+# $Log: Makefile.TRW,v $
+#Revision 1.1 88/01/15 12:16:54 simpson
+#initial release
+#
+#Revision 0.1 87/12/11 17:20:07 simpson
+#beta test
+#
+INCLUDE=/usr/include/local
+LIB=/usr/local/lib
+
+all: libprofile.a
+
+# This system include file is needed right away
+configure:
+ install -c -m 644 profile.h $(INCLUDE)
+
+libprofile.a: boolean.o free.o has.o read.o space.o write.o
+ ar cr libprofile.a boolean.o free.o has.o read.o space.o write.o
+ ranlib libprofile.a
+
+install:
+ install -c -m 644 profile.h $(INCLUDE)
+ install -m 644 libprofile.a $(LIB)
+
+clean:
+ -rm *.o libprofile.a
+
+boolean.o free.o has.o read.o space.o write.o: profile.h
diff --git a/dviware/quicspool/libprofile/profile.h b/dviware/quicspool/libprofile/profile.h
new file mode 100644
index 0000000000..7e30a81e22
--- /dev/null
+++ b/dviware/quicspool/libprofile/profile.h
@@ -0,0 +1,63 @@
+/* $Header: profile.h,v 1.1 88/01/15 12:17:02 simpson Rel $ */
+/*
+$Log: profile.h,v $
+ * Revision 1.1 88/01/15 12:17:02 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 17:02:13 simpson
+ * beta test
+ *
+*/
+typedef struct PROFILE_VALUE {
+ char class;
+ union {
+ long int i;
+ double f;
+ char c;
+ char *s;
+ } value;
+ struct PROFILE_VALUE *previous;
+ struct PROFILE_VALUE *next;
+} PROFILE_VALUE;
+
+typedef struct PROFILE_BINDING {
+ char *name;
+ PROFILE_VALUE *value;
+ struct PROFILE_BINDING *previous;
+ struct PROFILE_BINDING *next;
+} PROFILE_BINDING;
+
+typedef struct PROFILE_MARKER {
+ char *text;
+ struct PROFILE_MARKER *previous;
+ struct PROFILE_MARKER *next;
+} PROFILE_MARKER;
+
+typedef struct PROFILE_STANZA {
+ PROFILE_MARKER *marker;
+ PROFILE_BINDING *binding;
+ struct PROFILE_STANZA *previous;
+ struct PROFILE_STANZA *next;
+} PROFILE_STANZA;
+
+/* classes */
+#define PROFILE_INTEGER 01
+#define PROFILE_FLOAT 02
+#define PROFILE_STRING 03
+#define PROFILE_CHARACTER 04
+#define PROFILE_OTHER 05
+#define PROFILE_OCTAL 06
+#define PROFILE_HEX 07
+
+/* no single lexical element may exceed this size in characters */
+#define PROFILE_MAX_TEXT 255
+
+PROFILE_STANZA *profile_read_stanza();
+PROFILE_STANZA *profile_read_profile();
+PROFILE_MARKER *profile_has_marker();
+PROFILE_STANZA *profile_has_stanza();
+PROFILE_BINDING *profile_has_binding();
+PROFILE_STANZA *profile_stanza_space();
+PROFILE_MARKER *profile_marker_space();
+PROFILE_BINDING *profile_binding_space();
+PROFILE_VALUE *profile_value_space();
diff --git a/dviware/quicspool/libprofile/read.c b/dviware/quicspool/libprofile/read.c
new file mode 100644
index 0000000000..3ab17765bf
--- /dev/null
+++ b/dviware/quicspool/libprofile/read.c
@@ -0,0 +1,834 @@
+static char *rcs = "$Header: read.c,v 1.1 88/01/15 12:17:05 simpson Rel $";
+/*
+$Log: read.c,v $
+ * Revision 1.1 88/01/15 12:17:05 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 17:02:13 simpson
+ * beta test
+ *
+*/
+#include <stdio.h>
+#include <ctype.h>
+#include "profile.h"
+
+#define isoctal(d) ('0' <= d && d <= '7')
+#define ishex(x) (isdigit(x) || ('a' <= x && x <= 'f') || ('A' <= x && x <= 'F'))
+#define isprime(c) (c == '\'')
+#define isbackslash(c) (c == '\\')
+#define iscaret(c) (c == '^')
+
+extern char *strcpy();
+extern PROFILE_STANZA *profile_stanza_space();
+extern PROFILE_MARKER *profile_marker_space();
+extern PROFILE_BINDING *profile_binding_space();
+extern PROFILE_VALUE *profile_value_space();
+
+static PROFILE_BINDING *get_binding();
+static PROFILE_BINDING *get_bindings();
+static PROFILE_MARKER *get_marker();
+static PROFILE_MARKER *get_markers();
+static PROFILE_VALUE *get_value();
+static PROFILE_VALUE *get_values();
+static char parse_character();
+static PROFILE_VALUE *parse_value();
+
+PROFILE_STANZA *profile_read_stanza (f)
+FILE *f;
+{
+ PROFILE_STANZA *stanza;
+
+ stanza = profile_stanza_space();
+ if (stanza == NULL)
+ return(NULL);
+ stanza->marker = get_markers(f);
+ if (get_open_bindings(f))
+ stanza->binding = get_bindings(f);
+ else {
+ profile_free_stanza(stanza);
+ return(NULL);
+ }
+ if (get_close_bindings(f))
+ return(stanza);
+ else {
+ profile_free_stanza(stanza);
+ return(NULL);
+ }
+}
+
+/* Returns the list of markers at the head of a stanza. */
+static PROFILE_MARKER *get_markers (f)
+FILE *f;
+{
+ PROFILE_MARKER *head, *tail, *m;
+
+ head = tail = NULL;
+ while (m = get_marker(f))
+ if (tail) {
+ tail->next = m;
+ m->previous = tail;
+ tail = m;
+ } else
+ head = tail = m;
+ return(head);
+}
+
+/* Returns the next marker from the head of the stanza. */
+static PROFILE_MARKER *get_marker (f)
+FILE *f;
+{
+ int n;
+ PROFILE_MARKER *m;
+ char scratch[PROFILE_MAX_TEXT+1];
+
+ for (;;)
+ if (n = get_name_text(f, scratch)) {
+ if ((m = profile_marker_space(n)) == NULL)
+ return(NULL);
+ strcpy(m->text, scratch);
+ return(m);
+ } else if (get_end_of_line(f))
+ continue;
+ else
+ return(NULL);
+}
+
+/* Returns the list of bindings in the body of the stanza. */
+static PROFILE_BINDING *get_bindings (f)
+FILE *f;
+{
+ PROFILE_BINDING *head, *tail, *b;
+
+ head = tail = NULL;
+ while (b = get_binding(f))
+ if (tail) {
+ tail->next = b;
+ b->previous = tail;
+ tail = b;
+ } else
+ head = tail = b;
+ return(head);
+}
+
+/* Returns the next binding in the body of the stanza. */
+static PROFILE_BINDING *get_binding (f)
+FILE *f;
+{
+ int n;
+ PROFILE_BINDING *b;
+ char scratch[PROFILE_MAX_TEXT+1];
+
+ for (;;)
+ if (n = get_name_text(f, scratch)) {
+ if ((b = profile_binding_space(n)) == NULL)
+ return(NULL);
+ strcpy(b->name, scratch);
+ break;
+ } else if (get_end_of_line(f))
+ continue;
+ else
+ return(NULL);
+ b->value = get_values(f);
+ return(b);
+}
+
+/* Returns the list of values following the name of the binding. */
+static PROFILE_VALUE *get_values (f)
+FILE *f;
+{
+ PROFILE_VALUE *head, *tail, *v;
+
+ head = tail = NULL;
+ while (v = get_value(f))
+ if (tail) {
+ tail->next = v;
+ v->previous = tail;
+ tail = v;
+ } else
+ head = tail = v;
+ return(head);
+}
+
+/* Returns the next value in the binding. */
+static PROFILE_VALUE *get_value (f)
+FILE *f;
+{
+ char text[PROFILE_MAX_TEXT+1];
+ int n;
+
+ for (;;)
+ if (n = get_value_text(f, text))
+ return(parse_value(text, n));
+ else if (get_end_of_line(f))
+ return(NULL);
+ else
+ return(NULL);
+}
+
+/*
+ * Reads the text of the next value (if any) in the binding. Returns
+ * the length of the literal text in characters.
+ */
+static int get_value_text (f, text)
+FILE *f;
+char *text;
+{
+ register int c;
+ char *s = text;
+
+ while ((c = getc(f)) != EOF)
+ switch (c) {
+ case '\b': case '\f':
+ case '\r': case '\t': case ' ':
+ /* white space terminates any text gathered so far */
+ if (s > text) {
+ *s = '\0';
+ return(s - text);
+ }
+ continue;
+
+ case '\n':
+ /* newline terminates a binding */
+ ungetc(c, f);
+ *s = '\0';
+ return(s - text);
+
+ case '#':
+ /* gobble up the comment */
+ while ((c = getc(f)) != EOF && c != '\n')
+ continue;
+ if (c == '\n')
+ ungetc(c, f);
+ *s = '\0';
+ return(s - text);
+
+ case '{': case '}':
+ ungetc(c, f);
+ *s = '\0';
+ return(s - text);
+
+ case '"': /* string quotes */
+ ungetc(c, f);
+ if (s > text) {
+ *s = '\0';
+ return(s - text);
+ } else
+ return(get_string(f, s));
+
+ case '\'': /* character quotes */
+ ungetc(c, f);
+ if (s > text) {
+ *s = '\0';
+ return(s - text);
+ } else
+ return(get_character(f, s));
+
+ case '\\': /* newline escape */
+ c = getc(f);
+ if (c == '\n') {
+ if (s > text) {
+ *s = '\0';
+ return(s - text);
+ }
+ continue; /* just like a blank */
+ }
+ ungetc(c, f);
+ if (s < &text[PROFILE_MAX_TEXT])
+ *s++ = '\\';
+ continue;
+
+ default:
+ if (s < &text[PROFILE_MAX_TEXT])
+ *s++ = c;
+ continue;
+ }
+ *s = '\0';
+ return(s - text);
+}
+
+/* Digests the raw value text returning a new value structure. */
+static PROFILE_VALUE *parse_value (s, length)
+char *s; /* literal text */
+int length; /* in characters */
+{
+ PROFILE_VALUE *v;
+
+ if (is_integer(s)) {
+ if ((v = profile_value_space(0)) == NULL)
+ return(NULL);
+ v->class = PROFILE_INTEGER;
+ sscanf(s, "%D", &v->value.i);
+ } else if (is_octal(s)) {
+ if ((v = profile_value_space(0)) == NULL)
+ return(NULL);
+ v->class = PROFILE_OCTAL;
+ /* skip the `0o' prefix */
+ sscanf(s+2, "%O", &v->value.i);
+ } else if (is_hex(s)) {
+ if ((v = profile_value_space(0)) == NULL)
+ return(NULL);
+ v->class = PROFILE_HEX;
+ /* skip the `0x' prefix */
+ sscanf(s+2, "%X", &v->value.i);
+ } else if (is_string(s)) {
+ /* be careful when dealing with the empty string "" */
+ if ((v = profile_value_space(length > 2 ? length - 2 : 1)) == NULL)
+ return(NULL);
+ v->class = PROFILE_STRING;
+ /* erase the terminating double quote */
+ s[length - 1] = '\0';
+ /* skip past the initial quote */
+ parse_string(s + 1, v->value.s);
+ } else if (is_character(s)) {
+ if ((v = profile_value_space(0)) == NULL)
+ return(NULL);
+ v->class = PROFILE_CHARACTER;
+ /* erase the end single quote */
+ s[length - 1] = '\0';
+ v->value.c = parse_character(s + 1);
+ } else if (is_float(s)) {
+ if ((v = profile_value_space(0)) == NULL)
+ return(NULL);
+ v->class = PROFILE_FLOAT;
+ sscanf(s, "%E", &v->value.f);
+ } else {
+ if ((v = profile_value_space(length)) == NULL)
+ return(NULL);
+ v->class = PROFILE_OTHER;
+ strcpy(v->value.s, s);
+ }
+ return(v);
+}
+
+/* Converts a string literal to the internal representation. */
+static parse_string (source, result)
+char *source;
+char *result;
+{
+ for (; *source; source++)
+ if (*source == '\\')
+ switch (*++source) {
+ case 'b': /* backspace */
+ *result++ = '\b';
+ continue;
+ case 'f': /* formfeed */
+ *result++ = '\f';
+ continue;
+ case 'n': /* newline */
+ *result++ = '\n';
+ continue;
+ case 'r': /* carriage return */
+ *result++ = '\r';
+ continue;
+ case 't': /* horizontal tab */
+ *result++ = '\t';
+ continue;
+ case '\'': /* single quote */
+ *result++ = '\'';
+ continue;
+ case '"': /* double quote */
+ *result++ = '"';
+ continue;
+ case '\\': /* backslash */
+ *result++ = '\\';
+ continue;
+ case '^': /* caret */
+ *result++ = '^';
+ continue;
+ case '0': case '1': /* octal constant */
+ case '2': case '3':
+ case '4': case '5':
+ case '6': case '7':
+ source += parse_octal(source, result) - 2;
+ result++;
+ continue;
+ default:
+ *result++ = *source; /* ignore backslash */
+ }
+ else if (*source == '^') { /* control escape */
+ char c = *++source;
+ *result++ = ('@' <= c && c <= '_') ? c - '@' :
+ (c == '?') ? '\177' : c;
+ continue;
+ } else
+ *result++ = *source;
+ *result = '\0';
+}
+
+/* Converts a character literal to the internal representation. */
+static char parse_character (source)
+char *source;
+{
+ char c;
+
+ if (*source == '\\')
+ switch (*++source) {
+ case 'b': /* backspace */
+ return('\b');
+ case 'f': /* formfeed */
+ return('\f');
+ case 'n': /* newline */
+ return('\n');
+ case 'r': /* carriage return */
+ return('\r');
+ case 't': /* horizontal tab */
+ return('\t');
+ case '\'': /* single quote */
+ return('\'');
+ case '\\': /* backslash */
+ return('\\');
+ case '^':
+ return('^');
+ case '0': case '1': /* octal constant */
+ case '2': case '3':
+ case '4': case '5':
+ case '6': case '7':
+ parse_octal(source, &c);
+ return(c);
+ default:
+ return(*source); /* ignore backslash */
+ }
+ else if (*source == '^') { /* control escape */
+ c = *++source;
+ return(('@' <= c && c <= '_') ? c - '@' : (c == '?') ? '\177' : c);
+ } else
+ return(*source);
+}
+
+/* Converts an octal escape `\ddd' to its byte representation. */
+static int parse_octal (source, result)
+char *source;
+char *result;
+{
+ int count;
+ char byte = '\0';
+ char digit;
+
+ for (count = 1; count <= 3; count++) {
+ digit = *source++;
+ if ('0' <= digit && digit <= '7')
+ byte = (byte * 8) + (digit - '0');
+ else
+ break;
+ }
+ *result = byte;
+ return(count);
+}
+
+/*
+ * Reads the literal text for markers and binding names. Returns the
+ * length in characters of the literal text.
+ */
+static int get_name_text (f, text)
+FILE *f;
+char *text;
+{
+ register int c;
+ char *s = text;
+
+ while ((c = getc(f)) != EOF)
+ switch (c) {
+ case '\b': case '\f':
+ case '\r': case '\t': case ' ':
+ /* white space terminates text gathered so far */
+ if (s > text) {
+ *s = '\0';
+ return(s - text);
+ }
+ continue;
+
+ case '\n':
+ ungetc(c, f);
+ *s = '\0';
+ return(s - text);
+
+ case '#':
+ /* gobble up the comment */
+ while ((c = getc(f)) != EOF && c != '\n')
+ continue;
+ if (c == '\n')
+ ungetc(c, f);
+ *s = '\0';
+ return(s - text);
+
+ case '{': case '}':
+ ungetc(c, f);
+ *s = '\0';
+ return(s - text);
+
+ case '[':
+ /* sets may contain embedded white space */
+ if (s + 1 < &text[PROFILE_MAX_TEXT]) {
+ *s++ = '[';
+ if ((c = getc(f)) != EOF)
+ *s++ = c;
+ }
+ while ((c = getc(f)) != EOF) {
+ if (s < &text[PROFILE_MAX_TEXT])
+ *s++ = c;
+ if (c == ']')
+ break;
+ }
+ continue;
+
+ case '\\':
+ c = getc(f);
+ if (c == '\n') {
+ if (s > text) {
+ *s = '\0';
+ return(s - text);
+ }
+ continue; /* just like a blank */
+ }
+ ungetc(c, f);
+ if (s < &text[PROFILE_MAX_TEXT])
+ *s++ = '\\';
+ continue;
+
+ default:
+ if (s < &text[PROFILE_MAX_TEXT])
+ *s++ = c;
+ continue;
+ }
+ *s = '\0';
+ return(s - text);
+}
+
+/* Returns non-zero on end of line and zero otherwise. */
+static int get_end_of_line (f)
+FILE *f;
+{
+ int c;
+
+ if ((c = getc(f)) == '\n')
+ return(1);
+ ungetc(c, f);
+ return(0);
+}
+
+/* Returns non-zero on seeing `{' and zero otherwise. */
+static int get_open_bindings (f)
+FILE *f;
+{
+ int c;
+
+ if ((c = getc(f)) == '{')
+ return(1);
+ ungetc(c, f);
+ return(0);
+}
+
+/* Returns non-zero on seeing `}' and zero otherwise. */
+static int get_close_bindings (f)
+FILE *f;
+{
+ int c;
+
+ if ((c = getc(f)) == '}')
+ return(1);
+ ungetc(c, f);
+ return(0);
+}
+
+/* Reads a string literal returning the length of the literal text in characters */
+static int get_string (f, text)
+FILE *f;
+char *text;
+{
+ register int c;
+ char *s = text;
+
+ /* the first double quote is guaranteed */
+ *s++ = getc(f);
+ while ((c = getc(f)) != EOF)
+ switch (c) {
+ case '\\':
+ if (s < &text[PROFILE_MAX_TEXT])
+ *s++ = c;
+ c = getc(f);
+ if (c == EOF)
+ return(s - text);
+ else if (c == '\n') {
+ ungetc(c, f);
+ return(s - text);
+ } else if (s < &text[PROFILE_MAX_TEXT])
+ *s++ = c;
+ continue;
+
+ case '"':
+ if (s < &text[PROFILE_MAX_TEXT])
+ *s++ = c;
+ *s = '\0';
+ return(s - text);
+
+ case '\n':
+ ungetc(c, f);
+ *s = '\0';
+ return(s - text);
+
+ default:
+ if (s < &text[PROFILE_MAX_TEXT])
+ *s++ = c;
+ continue;
+ }
+ *s = '\0';
+ return(s - text);
+}
+
+/* Reads a character literal returning the length of the literal text in characters. */
+static int get_character (f, text)
+FILE *f;
+char *text;
+{
+ register int c;
+ char *s = text;
+
+ /* the first single quote is guaranteed */
+ *s++ = getc(f);
+ while ((c = getc(f)) != EOF)
+ switch (c) {
+ case '\\':
+ if (s < &text[PROFILE_MAX_TEXT])
+ *s++ = c;
+ c = getc(f);
+ if (c == EOF)
+ return(s - text);
+ else if (c == '\n') {
+ ungetc(c, f);
+ return(s - text);
+ } else if (s < &text[PROFILE_MAX_TEXT])
+ *s++ = c;
+ continue;
+ case '\'':
+ if (s < &text[PROFILE_MAX_TEXT])
+ *s++ = c;
+ *s = '\0';
+ return(s - text);
+ case '\n':
+ ungetc(c, f);
+ *s = '\0';
+ return(s - text);
+ default:
+ if (s < &text[PROFILE_MAX_TEXT])
+ *s++ = c;
+ continue;
+ }
+ *s = '\0';
+ return(s - text);
+}
+
+/* all regular expressions below are in lex notation */
+
+/* returns non-zero iff -?[0-9]+ matches */
+static int is_integer (s)
+char *s;
+{
+ char *x;
+
+ /* -? */
+ if (*s == '-')
+ s++;
+ /* [0-9]+ */
+ for (x = s; isdigit(*s); s++)
+ continue;
+ return(s > x && !*s);
+}
+
+/* returns non-zero iff 0[oO][0-7]+ matches */
+static int is_octal (s)
+char *s;
+{
+ char *x;
+
+ /* 0 */
+ if (*s == '0')
+ s++;
+ else
+ return(0);
+ /* [oO] */
+ if (*s == 'o' || *s == 'O')
+ s++;
+ else
+ return(0);
+ /* [0-7]+ */
+ for (x = s; isoctal(*s); s++)
+ continue;
+ return(s > x && !*s);
+}
+
+/* returns non-zero iff 0[xX][0-9a-fA-F]+ matches */
+static int is_hex (s)
+char *s;
+{
+ char *x;
+
+ /* 0 */
+ if (*s == '0')
+ s++;
+ else
+ return(0);
+ /* [xX] */
+ if (*s == 'x' || *s == 'X')
+ s++;
+ else
+ return(0);
+ /* [0-9a-fA-F]+ */
+ for (x = s; ishex(*s); s++)
+ continue;
+ return(s > x && !*s);
+}
+
+/* returns non-zero iff [eE][-+]?[0-9]+ matches */
+static int is_exponent (s)
+char *s;
+{
+ char *x;
+
+ /* [eE] */
+ if (*s == 'e' || *s == 'E')
+ s++;
+ else
+ return(0);
+ /* [-+]? */
+ if (*s == '-' || *s == '+')
+ s++;
+ /* [0-9]+ */
+ for (x = s; isdigit(*s); s++)
+ continue;
+ return(s > x && !*s);
+}
+
+static int is_float (s)
+char *s;
+{
+ return(is_integer_part_float(s) ||
+ is_fractional_part_float(s) ||
+ is_power_float(s));
+}
+
+/* returns non-zero iff -?[0-9]+"."[0-9]*({exponent})? matches */
+static int is_integer_part_float (s)
+char *s;
+{
+ char *x;
+
+ /* -? */
+ if (*s == '-')
+ s++;
+ /* [0-9]+"." */
+ for (x = s; isdigit(*s); s++)
+ continue;
+ if (x == s || *s != '.')
+ return(0);
+ /* [0-9]* */
+ for (s++; isdigit(*s); s++)
+ continue;
+ /* ({exponent})? */
+ return(*s ? is_exponent(s) : 1);
+}
+
+/* returns non-zero iff -?"."[0-9]+({exponent})? matches */
+static int is_fractional_part_float (s)
+char *s;
+{
+ char *x;
+
+ /* -? */
+ if (*s == '-')
+ s++;
+ /* "." */
+ if (*s == '.')
+ s++;
+ else
+ return(0);
+ /* [0-9]+({exponent})? */
+ for (x = s; isdigit(*s); s++)
+ continue;
+ return(s > x ? !*s || is_exponent(s) : 0);
+}
+
+/* returns non-zero iff -?[0-9]+{exponent} matches */
+static int is_power_float (s)
+char *s;
+{
+ char *x;
+
+ /* -? */
+ if (*s == '-')
+ s++;
+ /* [0-9]+{exponent} */
+ for (x = s; isdigit(*s); s++)
+ continue;
+ return(s > x ? is_exponent(s) : 0);
+}
+
+/* returns non-zero iff '[^^\]' | '\^.' | '\\\\' | '\\'' | '\[0-7]{1-3}' matches */
+static int is_character (s)
+char *s;
+{
+ char *x;
+
+ if (isprime(*s))
+ s++;
+ else
+ return(0);
+ if (isbackslash(*s)) {
+ s++;
+ if ((isbackslash(s[0]) || isprime(s[0]) || !isdigit(s[0])) &&
+ isprime(s[1]) && !s[2])
+ return(1);
+ for (x = s; isoctal(*s); s++)
+ continue;
+ return(x < s && s < (x+4) && isprime(s[0]) && !s[1]);
+ } else if (iscaret(*s))
+ s++;
+ return(isprint(s[0]) && isprime(s[1]) && !s[2]);
+}
+
+/* returns non-zero iff s is a string constant */
+static int is_string (s)
+char *s;
+{
+ char *x;
+
+ if (*s != '"')
+ return(0);
+ for (s++; *s; s++) {
+ if (*s == '"')
+ return(!*++s); /* quote must be followed by null */
+ if (isbackslash(*s) || iscaret(*s)) {
+ if (*++s)
+ continue; /* legal escape */
+ return(0); /* null follows \ or ^ */
+ }
+ }
+ return(0);
+}
+
+/*
+ * read an entire profile, making a bidirectional
+ * circularly linked list
+ * returns pointer to the first stanza or NULL on error
+ */
+PROFILE_STANZA *profile_read_profile(f)
+FILE *f;
+{
+ PROFILE_STANZA *head = NULL;
+ PROFILE_STANZA *tail = NULL;
+ PROFILE_STANZA *x = NULL;
+
+ while ((x = profile_read_stanza(f)) != NULL) {
+ if (head == NULL)
+ head = tail = x;
+ else {
+ tail->next = x;
+ x->previous = tail;
+ tail = x;
+ }
+ }
+ if (head != NULL) {
+ tail->next = head;
+ head->previous = tail;
+ }
+ return(head);
+}
diff --git a/dviware/quicspool/libprofile/space.c b/dviware/quicspool/libprofile/space.c
new file mode 100644
index 0000000000..8bca164ae2
--- /dev/null
+++ b/dviware/quicspool/libprofile/space.c
@@ -0,0 +1,60 @@
+static char *rcs = "$Header: space.c,v 1.1 88/01/15 12:17:10 simpson Rel $";
+/*
+$Log: space.c,v $
+ * Revision 1.1 88/01/15 12:17:10 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 17:02:15 simpson
+ * beta test
+ *
+*/
+#include "profile.h"
+
+extern char *calloc();
+
+PROFILE_STANZA *profile_stanza_space ()
+{
+ return((PROFILE_STANZA *)calloc(1, sizeof(PROFILE_STANZA)));
+}
+
+PROFILE_MARKER *profile_marker_space (n)
+int n;
+{
+ char *space;
+ PROFILE_MARKER *m = (PROFILE_MARKER *)0;
+
+ if (space = calloc(1, sizeof(PROFILE_MARKER) + n + 1)) {
+ m = (PROFILE_MARKER *)space;
+ m->text = space + sizeof(PROFILE_MARKER);
+ }
+ return(m);
+}
+
+PROFILE_BINDING *profile_binding_space (n)
+int n; /* length of binding name in characters */
+{
+ char *space;
+ PROFILE_BINDING *b = (PROFILE_BINDING *)0;
+
+ if (space = calloc(1, sizeof(PROFILE_BINDING) + n + 1)) {
+ b = (PROFILE_BINDING *)space;
+ b->name = space + sizeof(PROFILE_BINDING);
+ }
+ return(b);
+}
+
+PROFILE_VALUE *profile_value_space (n)
+int n;
+{
+ char *space;
+ PROFILE_VALUE *v = (PROFILE_VALUE *)0;
+
+ if (n > 0) {
+ if (space = calloc(1, sizeof(PROFILE_VALUE) + n + 1)) {
+ v = (PROFILE_VALUE *)space;
+ v->value.s = space + sizeof(PROFILE_VALUE);
+ }
+ } else
+ v = (PROFILE_VALUE *)calloc(1, sizeof(PROFILE_VALUE));
+ return(v);
+}
diff --git a/dviware/quicspool/libprofile/write.c b/dviware/quicspool/libprofile/write.c
new file mode 100644
index 0000000000..af25db2c50
--- /dev/null
+++ b/dviware/quicspool/libprofile/write.c
@@ -0,0 +1,206 @@
+static char *rcs = "$Header: write.c,v 1.1 88/01/15 12:17:13 simpson Rel $";
+/*
+$Log: write.c,v $
+ * Revision 1.1 88/01/15 12:17:13 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 17:02:16 simpson
+ * beta test
+ *
+*/
+#include <stdio.h>
+#include <ctype.h>
+#include "profile.h"
+
+profile_write_stanza (f, s)
+FILE *f;
+PROFILE_STANZA *s;
+{
+ write_markers(f, s->marker);
+ fprintf(f, "{\n");
+ write_bindings(f, s->binding);
+ fprintf(f, "}\n");
+}
+
+static write_markers (f, m)
+FILE *f;
+PROFILE_MARKER *m;
+{
+ for (; m; m = m->next)
+ fprintf(f, "%s\n", m->text);
+}
+
+static write_bindings (f, b)
+FILE *f;
+PROFILE_BINDING *b;
+{
+ while (b) {
+ fprintf(f, "\t%s", b->name);
+ write_values(f, b->value);
+ fputc('\n', f);
+ b = b->next;
+ }
+}
+
+static write_values (f, v)
+FILE *f;
+PROFILE_VALUE *v;
+{
+ char scratch[PROFILE_MAX_TEXT+1];
+
+ for (; v; v = v->next)
+ switch (v->class) {
+ case PROFILE_INTEGER:
+ fprintf(f, " %D", v->value.i);
+ continue;
+ case PROFILE_FLOAT:
+ fprintf(f, " %G", v->value.f);
+ continue;
+ case PROFILE_STRING:
+ unparse_string(v->value.s, scratch);
+ fprintf(f, " \"%s\"", scratch);
+ continue;
+ case PROFILE_CHARACTER:
+ unparse_character(v->value.c, scratch);
+ fprintf(f, " '%s'", scratch);
+ continue;
+ case PROFILE_OCTAL:
+ fprintf(f, " 0o%O", v->value.i);
+ continue;
+ case PROFILE_HEX:
+ fprintf(f, " 0x%X", v->value.i);
+ continue;
+ case PROFILE_OTHER:
+ fprintf(f, " %s", v->value.s);
+ continue;
+ }
+}
+
+static int unparse_string (from, to)
+char *from;
+char *to;
+{
+ char *x = to;
+
+ for (; *from; from++)
+ switch (*from) {
+ case '\b': /* backspace */
+ *x++ = '\\';
+ *x++ = 'b';
+ continue;
+ case '\f': /* formfeed */
+ *x++ = '\\';
+ *x++ = 'f';
+ continue;
+ case '\n': /* newline */
+ *x++ = '\\';
+ *x++ = 'n';
+ continue;
+ case '\r':
+ *x++ = '\\';
+ *x++ = 'r';
+ continue;
+ case '\t': /* horizontal tab */
+ *x++ = '\\';
+ *x++ = 't';
+ continue;
+ case '\\': /* backslash */
+ *x++ = '\\';
+ *x++ = '\\';
+ continue;
+ case '"': /* double quote */
+ *x++ = '\\';
+ *x++ = '"';
+ continue;
+ case '^':
+ *x++ = '\\';
+ *x++ = '^';
+ continue;
+ default:
+ if (isascii(*from))
+ if (iscntrl(*from)) {
+ sprintf(x, "^%c", *from == '\177' ? '?' : *from + '@');
+ x += 2;
+ } else
+ *x++ = *from;
+ else {
+ sprintf(x, "\\%03o", *from);
+ x += 4;
+ }
+ continue;
+ }
+ *x = '\0';
+ return(x - to);
+}
+
+static int unparse_character (from, to)
+char from;
+char *to;
+{
+ char *x = to;
+
+ switch (from) {
+ case '\b': /* backspace */
+ *x++ = '\\';
+ *x++ = 'b';
+ break;
+ case '\f': /* formfeed */
+ *x++ = '\\';
+ *x++ = 'f';
+ break;
+ case '\n': /* newline */
+ *x++ = '\\';
+ *x++ = 'n';
+ break;
+ case '\r':
+ *x++ = '\\';
+ *x++ = 'r';
+ break;
+ case '\t': /* horizontal tab */
+ *x++ = '\\';
+ *x++ = 't';
+ break;
+ case '\\': /* backslash */
+ *x++ = '\\';
+ *x++ = '\\';
+ break;
+ case '\'': /* single quote */
+ *x++ = '\\';
+ *x++ = '\'';
+ break;
+ case '^':
+ *x++ = '\\';
+ *x++ = '^';
+ break;
+ default:
+ if (isascii(from))
+ if (iscntrl(from)) {
+ sprintf(x, "^%c", from == '\177' ? '?' : from + '@');
+ x += 2;
+ } else
+ *x++ = from;
+ else {
+ sprintf(x, "\\%03o", from);
+ x += 4;
+ }
+ break;
+ }
+ *x = '\0';
+ return(x - to);
+}
+
+/*
+ * write out a linked list of stanzas
+ */
+profile_write_profile(f, s)
+FILE *f;
+PROFILE_STANZA *s;
+{
+ PROFILE_STANZA *x;
+
+ for (x = s; x != NULL; x = x->next) {
+ profile_write_stanza(f, x);
+ if (x->next == s)
+ break;
+ }
+}