diff options
Diffstat (limited to 'dviware/quicspool/libprofile')
-rw-r--r-- | dviware/quicspool/libprofile/boolean.c | 79 | ||||
-rw-r--r-- | dviware/quicspool/libprofile/free.c | 62 | ||||
-rw-r--r-- | dviware/quicspool/libprofile/has.c | 63 | ||||
-rw-r--r-- | dviware/quicspool/libprofile/makefile | 29 | ||||
-rw-r--r-- | dviware/quicspool/libprofile/makefile.trw | 29 | ||||
-rw-r--r-- | dviware/quicspool/libprofile/profile.h | 63 | ||||
-rw-r--r-- | dviware/quicspool/libprofile/read.c | 834 | ||||
-rw-r--r-- | dviware/quicspool/libprofile/space.c | 60 | ||||
-rw-r--r-- | dviware/quicspool/libprofile/write.c | 206 |
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; + } +} |