home *** CD-ROM | disk | FTP | other *** search
- From simpson@trwrb.UUCP (Scott Simpson) Fri May 30 20:19:30 1986
- Path: seismo!lll-crg!styx!nike!cad!ucbvax!sdcsvax!sdcrdcf!trwrb!simpson
- From: simpson@trwrb.UUCP (Scott Simpson)
- Newsgroups: net.sources
- Subject: LaTeX Index Processor (Part 2)
- Message-ID: <1110@trwrb.UUCP>
- Date: 31 May 86 00:19:30 GMT
- Organization: TRW EDS, Redondo Beach, CA
- Lines: 2864
- Keywords: LaTeX, Index Processor
-
- #! /bin/sh
- # To extract, remove mail header lines and type "sh filename"
- if [ ! -d libglob ]
- then
- mkdir libglob
- echo mkdir libglob
- fi
- echo x - libglob/Makefile
- sed -e 's/^X//' > libglob/Makefile << '!FaR!OuT!'
- X# @(#)Makefile 1.1 (TRW) 1/14/86
- X
- XCFLAGS = -O
- XOBJECTS = glob.o
- XDESTDIR = /
- XINCLUDE = /usr/include/local
- X
- X.c.o:
- X ${CC} ${CFLAGS} -c $*.c
- X -ld -x -r $*.o
- X mv a.out $*.o
- X
- Xall: libglob.a
- X
- Xlibglob.a: ${OBJECTS}
- X ar cr libglob.a ${OBJECTS}
- X ranlib libglob.a
- X chmod 644 libglob.a
- X
- Xinstall: all
- X mv libglob.a ${DESTDIR}/usr/local/lib
- X ranlib ${DESTDIR}/usr/local/lib/libglob.a
- X install -c glob.h ${INCLUDE}/glob.h
- X
- Xclean:
- X rm -f *.o
- !FaR!OuT!
- if [ ! -d libglob ]
- then
- mkdir libglob
- echo mkdir libglob
- fi
- echo x - libglob/glob.3
- sed -e 's/^X//' > libglob/glob.3 << '!FaR!OuT!'
- X.\" %W% (TRW) %G%
- X.TH GLOB 3 TRW
- X.UC
- X.SH NAME
- Xglob \- shell style pattern matching
- X.SH SYNOPSIS
- X.nf
- X.B #include <local/glob.h>
- X
- X.B int glob_compile(pattern, buffer)
- X.B char *pattern;
- X.B char *buffer;
- X
- X.B int glob_execute(buffer, s)
- X.B char *buffer;
- X.B char *s;
- X
- X.B int glob_match (pattern, s)
- X.B char *pattern;
- X.B char *s;
- X.fi
- X
- X.B cc
- X[ flags ] files
- X.B -lglob
- X[ libraries ]
- X.fi
- X.SH DESCRIPTION
- X.I Glob
- Xis a pattern matching facility similar to that of
- X.IR sh (1)
- Xand
- X.IR csh (1).
- X.PP
- XA pattern specifies a set of strings of characters.
- XA member of this set of strings is said to be matched by the pattern.
- X.TP
- X(1)
- XAny character except a special character matches itself.
- XThe special characters are [ * and ?.
- X.TP
- X(2)
- XA ? matches any character.
- X.TP
- X(3)
- XA nonempty string
- X.I s
- Xbracketed
- X.RI [ s ]
- Xmatches any character in
- X.IR s .
- XIn
- X.I s
- X] may only appear as the first letter.
- XA substring
- X.IR a \- b ,
- Xwith
- X.I a
- Xand
- X.I b
- Xin ascending ASCII order,
- Xstands for the inclusive range of ASCII characters.
- X.TP
- X(4)
- XA * matches 0 or more characters.
- X.PP
- X.I Glob_compile
- Xcompiles a
- X.I pattern
- Xinto an internal form suitable for matching,
- Xplacing the result in the character array
- X.IR buffer .
- X.I Buffer
- Xmust be a character array of size
- X.BR GLOB_MAX_PATTERN .
- X.I Glob_compile
- Xreturns 0 if the
- X.I pattern
- Xwas compiled successfully;
- Xotherwise a negative error code is returned.
- X.PP
- X.I Glob_execute
- Xchecks the argument string
- X.I s
- Xagainst the compiled
- X.IR pattern .
- X.I Glob_execute
- Xreturns 1 if the string
- X.I s
- Xmatches the compiled pattern in
- X.IR buffer ,
- X0 if the string
- X.I s
- Xfailed to match the compiled pattern in
- X.IR buffer ,
- Xand a negative error code if the compiled pattern was invalid.
- X.PP
- XThe strings passed to both
- X.I glob_compile
- Xand
- X.I glob_execute
- Xmay have trailing or embedded newline characters;
- Xthey are terminated by nulls.
- X.PP
- X.I Glob_match
- Xcompiles
- X.I pattern
- Xand matches it against the argument string
- X.IR s .
- XIt returns 1 if the string
- X.I s
- Xmatches the pattern;
- X0 if the string
- X.I s
- Xfails to match the pattern
- Xand a negative error code if the pattern was invalid.
- X.SH AUTHOR
- XMichael Gorlick, TRW
- X.SH SEE ALSO
- Xregex(3)
- X.SH DIAGNOSTICS
- XThe following diagnostic codes are provided:
- X.TP
- XGLOB_OK
- Xreturned by
- X.I glob_compile
- Xindicating the pattern compiled successfully;
- X.TP
- XGLOB_PATTERN_TOO_BIG
- Xreturned by
- X.I glob_compile
- Xor
- X.I glob_match
- Xindicating the compiled pattern overflowed the buffer;
- X.TP
- XGLOB_PATTERN_EMPTY
- Xreturned by
- X.I glob_compile
- Xor
- X.I glob_match
- Xindicating the pattern is the empty string;
- X.TP
- XGLOB_BRACKET_MISSING
- Xreturned by
- X.I glob_compile
- Xor
- X.I glob_match
- Xindicating that a set expression
- X.RI [ s ]
- Xis missing the terminating bracket ];
- X.TP
- XGLOB_RANGE_INVERTED
- Xreturned by
- X.I glob_compile
- Xor
- X.I glob_match
- Xindicating a range expression in a set
- Xis inverted, for example [z-a];
- X.TP
- XGLOB_SET_TOO_BIG
- Xreturned by
- X.I glob_compile
- Xor
- X.I glob_match
- Xindicating a compiled set requires more than 127 bytes
- X(a single character consumes 2 bytes and a range consumes 3 bytes);
- X.TP
- XGLOB_EXECUTION_ERROR
- Xreturned by
- X.I glob_execute
- Xor
- X.I glob_match
- Xindicating an internal error.
- !FaR!OuT!
- if [ ! -d libglob ]
- then
- mkdir libglob
- echo mkdir libglob
- fi
- echo x - libglob/glob.c
- sed -e 's/^X//' > libglob/glob.c << '!FaR!OuT!'
- Xstatic char *trwsccs= "@(#)glob.c 1.1 (TRW) 1/14/86";
- X#include "glob.h"
- X
- X#define SLOP 5
- X#define MAX_SET 0177
- X
- X/* control codes for regular expression evaluation */
- X#define PATTERN_ANY '?'
- X#define PATTERN_CHARACTER 'X'
- X#define PATTERN_END '$'
- X#define PATTERN_SET '['
- X#define PATTERN_SET_MEMBER 'M'
- X#define PATTERN_SET_RANGE '-'
- X#define PATTERN_STAR '*'
- X
- X/*
- X * Examples (=> denotes `compiles into')
- X *
- X * a => Xa
- X * ? => ?
- X * [x0-9] => [^EMx-09 (^E is control-E)
- X * * => *
- X * END => $
- X *
- X * a?[x0-9]* => Xa?[^EMx-09*$
- X */
- X
- Xglob_compile (pattern, buffer)
- Xchar *pattern;
- Xchar *buffer; /* compiled pattern */
- X{
- X char *x; /* pointer into compiled pattern */
- X int c;
- X int result;
- X
- X if (pattern == 0 || pattern[0] == 0)
- X return(GLOB_PATTERN_EMPTY);
- X
- X x = buffer;
- X while (x < &buffer[GLOB_MAX_PATTERN - SLOP]) {
- X c = *pattern++;
- X if (c == 0) {
- X *x++ = PATTERN_END;
- X return(GLOB_OK);
- X }
- X
- X switch (c) {
- X case '?':
- X *x++ = PATTERN_ANY;
- X continue;
- X
- X case '[':
- X if ((result = compile_set(pattern, x, &buffer[GLOB_MAX_PATTERN - SLOP])) < 0)
- X return(result);
- X pattern += result + 1;
- X x += x[1] + 2;
- X continue;
- X
- X case '*':
- X *x++ = PATTERN_STAR;
- X continue;
- X
- X default:
- X *x++ = PATTERN_CHARACTER;
- X *x++ = c;
- X continue;
- X }
- X }
- X return(GLOB_PATTERN_TOO_BIG);
- X}
- X
- Xint glob_execute (pattern, s)
- Xchar *pattern; /* compiled pattern */
- Xchar *s; /* string to be matched against */
- X{
- X char *current;
- X int result;
- X
- X for (;;)
- X switch (*pattern++) {
- X case PATTERN_ANY:
- X if (*s++)
- X continue;
- X return(0);
- X
- X case PATTERN_CHARACTER:
- X if (*pattern++ == *s++)
- X continue;
- X return(0);
- X
- X case PATTERN_END:
- X return(*s == 0);
- X
- X case PATTERN_SET:
- X if ((result = in_set(pattern, *s++)) == 1) {
- X pattern += *pattern + 1;
- X continue;
- X }
- X return(result);
- X
- X case PATTERN_STAR:
- X current = s;
- X while (*s++)
- X continue;
- X do {
- X s--;
- X if (result = glob_execute(pattern, s))
- X return(result);
- X } while (s > current);
- X return(0);
- X
- X default:
- X return(GLOB_EXECUTION_ERROR);
- X }
- X}
- X
- Xint glob_match (pattern, s)
- Xchar *pattern;
- Xchar *s;
- X{
- X int result;
- X char buffer[GLOB_MAX_PATTERN];
- X
- X if ((result = glob_compile(pattern, buffer)) < 0)
- X return(result);
- X else
- X return(glob_execute(buffer, s));
- X}
- X
- X/* returns 1 if character c is member of set and 0 otherwise */
- Xstatic int in_set (set, c)
- Xchar *set; /* compiled set pattern */
- Xchar c;
- X{
- X int n;
- X
- X if (c == 0)
- X return(0);
- X n = *set++;
- X while (n > 0)
- X switch (*set++) {
- X case PATTERN_SET_MEMBER:
- X if (*set++ == c)
- X return(1);
- X n -= 2;
- X continue;
- X
- X case PATTERN_SET_RANGE:
- X if (*set++ <= c && c <= *set++)
- X return(1);
- X n -= 3;
- X continue;
- X
- X default:
- X return(GLOB_EXECUTION_ERROR);
- X }
- X return(0);
- X}
- X
- X#define IS_RANGE(s) (s[1] && s[2] && s[1] == '-' && s[2] != ']')
- X
- X/* compiles a set returning the number of pattern characters consumed */
- Xstatic int compile_set (pattern, x, limit)
- Xchar *pattern;
- Xchar *x;
- Xchar *limit;
- X{
- X char *slot; /* size of set goes here */
- X int size; /* number of bytes in compiled set */
- X char *start = pattern;
- X
- X if (*pattern == 0)
- X return(GLOB_BRACKET_MISSING);
- X
- X *x++ = PATTERN_SET;
- X slot = x++;
- X size = 0;
- X
- X if (IS_RANGE(pattern)) {
- X if (pattern[0] > pattern[2]) /* pattern[1] == '-' */
- X return(GLOB_RANGE_INVERTED);
- X *x++ = PATTERN_SET_RANGE;
- X *x++ = pattern[0];
- X *x++ = pattern[2];
- X pattern += 3;
- X size += 3;
- X } else {
- X *x++ = PATTERN_SET_MEMBER;
- X *x++ = *pattern++;
- X size += 2;
- X }
- X
- X while (*pattern != ']' && x < limit) {
- X if (*pattern == 0)
- X return(GLOB_BRACKET_MISSING);
- X if (IS_RANGE(pattern)) {
- X if (pattern[0] > pattern[2]) /* pattern[1] == '-' */
- X return(GLOB_RANGE_INVERTED);
- X *x++ = PATTERN_SET_RANGE;
- X *x++ = pattern[0];
- X *x++ = pattern[2];
- X pattern += 3;
- X size += 3;
- X } else {
- X *x++ = PATTERN_SET_MEMBER;
- X *x++ = *pattern++;
- X size += 2;
- X }
- X }
- X if (size > MAX_SET)
- X return(GLOB_SET_TOO_BIG);
- X *slot = size;
- X return(pattern - start);
- X}
- !FaR!OuT!
- if [ ! -d libglob ]
- then
- mkdir libglob
- echo mkdir libglob
- fi
- echo x - libglob/glob.h
- sed -e 's/^X//' > libglob/glob.h << '!FaR!OuT!'
- X/* @(#)glob.h 1.1 (TRW) 1/14/86 */
- X#define GLOB_MAX_PATTERN 1024
- X#define GLOB_OK 0
- X#define GLOB_PATTERN_TOO_BIG -1
- X#define GLOB_PATTERN_EMPTY -2
- X#define GLOB_BRACKET_MISSING -3
- X#define GLOB_RANGE_INVERTED -4
- X#define GLOB_SET_TOO_BIG -5
- X#define GLOB_EXECUTION_ERROR -6
- !FaR!OuT!
- if [ ! -d libprofile ]
- then
- mkdir libprofile
- echo mkdir libprofile
- fi
- echo x - libprofile/Makefile
- sed -e 's/^X//' > libprofile/Makefile << '!FaR!OuT!'
- X# @(#)Makefile 1.1 (TRW) 1/14/86
- XCFLAGS = -O
- XOBJECTS = boolean.o free.o has.o read.o space.o write.o
- XDEST = /usr/local
- X
- X.c.o:
- X ${CC} ${CFLAGS} -c $*.c
- X -ld -r -x $*.o
- X mv a.out $*.o
- X
- Xall: libprofile.a
- X
- Xlibprofile.a: ${OBJECTS}
- X ar cr libprofile.a ${OBJECTS}
- X ranlib libprofile.a
- X chmod 644 libprofile.a
- X
- Xinstall: all
- X mv libprofile.a ${DEST}/lib
- X ranlib ${DEST}/lib/libprofile.a
- X install -c profile.h /usr/include/local
- X
- Xclean:
- X rm -f *.o
- !FaR!OuT!
- if [ ! -d libprofile ]
- then
- mkdir libprofile
- echo mkdir libprofile
- fi
- echo x - libprofile/boolean.c
- sed -e 's/^X//' > libprofile/boolean.c << '!FaR!OuT!'
- Xstatic char *trwsccs = "@(#)boolean.c 1.1 (TRW) 1/14/86";
- X#include <ctype.h>
- X#include "profile.h"
- X
- Xstatic char *Yes[] = {
- X "yes",
- X "on",
- X "true",
- X "enable",
- X "available",
- X "present",
- X 0
- X};
- X
- Xstatic char *No[] = {
- X "no",
- X "off",
- X "false",
- X "disable",
- X "unavailable",
- X "absent",
- X 0
- X};
- X
- Xint profile_boolean (v)
- XPROFILE_VALUE *v;
- X{
- X char x[16];
- X int i;
- X
- X if (v == 0)
- X return(0);
- X
- X switch (v->class) {
- X case PROFILE_OTHER:
- X case PROFILE_STRING:
- X strncpy(x, v->value.s, sizeof(x)-1);
- X x[sizeof(x)-1] = 0;
- X downshift(x);
- X for (i = 0; Yes[i]; i++)
- X if (strcmp(x, Yes[i]) == 0)
- X return(1);
- X else if (strcmp(x, No[i]) == 0)
- X return(0);
- X return(-1); /* unknown string */
- X
- X case PROFILE_HEX:
- X case PROFILE_INTEGER:
- X case PROFILE_OCTAL:
- X return(v->value.i != 0);
- X
- X case PROFILE_CHARACTER:
- X return(v->value.c != 0);
- X
- X case PROFILE_FLOAT:
- X return(v->value.f != 0.0);
- X
- X default:
- X return(-1); /* unknown class */
- X }
- X}
- X
- X/* downshift a string in place */
- Xstatic downshift (s)
- Xchar *s;
- X{
- X for (; *s; s++)
- X if (isupper(*s))
- X *s = tolower(*s);
- X}
- !FaR!OuT!
- if [ ! -d libprofile ]
- then
- mkdir libprofile
- echo mkdir libprofile
- fi
- echo x - libprofile/free.c
- sed -e 's/^X//' > libprofile/free.c << '!FaR!OuT!'
- Xstatic char *trwsccs = "@(#)free.c 1.1 (TRW) 1/14/86";
- X#include "profile.h"
- X
- Xprofile_free_profile (s)
- XPROFILE_STANZA *s;
- X{
- X PROFILE_STANZA *x;
- X
- X for (x = s; x != (PROFILE_STANZA *)0 && x != s; x = x->next)
- X profile_free_stanza(x);
- X}
- X
- Xprofile_free_stanza (s)
- XPROFILE_STANZA *s;
- X{
- X free_markers(s->marker);
- X free_bindings(s->binding);
- X free(s);
- X}
- X
- Xstatic free_markers (m)
- XPROFILE_MARKER *m;
- X{
- X PROFILE_MARKER *x;
- X
- X for (; m; m = x) {
- X x = m->next;
- X free(m);
- X }
- X}
- X
- Xstatic free_bindings (b)
- XPROFILE_BINDING *b;
- X{
- X PROFILE_BINDING *x;
- X
- X for (; b; b = x) {
- X x = b->next;
- X free_values(b->value);
- X free(b);
- X }
- X}
- X
- Xstatic free_values (v)
- XPROFILE_VALUE *v;
- X{
- X PROFILE_VALUE *x;
- X
- X for (; v; v = x) {
- X x = v->next;
- X free(v);
- X }
- X}
- !FaR!OuT!
- if [ ! -d libprofile ]
- then
- mkdir libprofile
- echo mkdir libprofile
- fi
- echo x - libprofile/has.c
- sed -e 's/^X//' > libprofile/has.c << '!FaR!OuT!'
- Xstatic char *trwsccs = "@(#)has.c 1.1 (TRW) 1/14/86";
- X#include <stdio.h>
- X#include "profile.h"
- X
- XPROFILE_MARKER *profile_has_marker (s, m)
- XPROFILE_STANZA *s;
- Xchar *m;
- X{
- X PROFILE_MARKER *x;
- X int result;
- X
- X for (x = s->marker; x; x = x->next)
- X if(glob_match(x->text, m) > 0)
- X return(x);
- X return((PROFILE_MARKER *)0);
- X}
- X
- X/*
- X * read down a linked list of stanzas looking
- X * for a stanza that has the requested markers
- X */
- XPROFILE_STANZA *profile_has_stanza(s, marker)
- XPROFILE_STANZA *s;
- Xchar *marker[]; /* terminated by a null pointer */
- X{
- X int i;
- X PROFILE_STANZA *x;
- X
- X if (s == NULL)
- X return(s);
- X x = s;
- X do {
- X for (i = 0; marker[i] != NULL; i++)
- X if (profile_has_marker(x, marker[i]) == NULL)
- X break;
- X if (marker[i] == NULL)
- X return(x);
- X x = x->next;
- X } while (x != s && x != NULL);
- X
- X return((PROFILE_STANZA *)NULL);
- X}
- X
- XPROFILE_BINDING *profile_has_binding (s, b)
- XPROFILE_STANZA *s;
- Xchar *b;
- X{
- X PROFILE_BINDING *x;
- X
- X for (x = s->binding; x; x = x->next)
- X if (glob_match(x->name, b) > 0)
- X return(x);
- X return((PROFILE_BINDING *)0);
- X}
- !FaR!OuT!
- if [ ! -d libprofile ]
- then
- mkdir libprofile
- echo mkdir libprofile
- fi
- echo x - libprofile/profile.3
- sed -e 's/^X//' > libprofile/profile.3 << '!FaR!OuT!'
- X.\" %W% (TRW) %G%
- X.TH PROFILE 3 TRW
- X.UC 4
- X.SH NAME
- Xprofile \- read/write configuration files
- X.SH SYNOPSIS
- X.nf
- X.B #include <stdio.h>
- X.B #include <local/profile.h>
- X
- X.B PROFILE_STANZA *profile_read_stanza(f)
- X.B FILE *f;
- X
- X.B PROFILE_STANZA *profile_read_profile(f)
- X.B FILE *f;
- X
- X.B profile_write_stanza(f, s)
- X.B FILE *f;
- X.B PROFILE_STANZA *s;
- X
- X.B profile_write_profile(f, s)
- X.B FILE *f;
- X.B PROFILE_STANZA *s;
- X
- X.B profile_free_stanza(s)
- X.B PROFILE_STANZA *s;
- X
- X.B PROFILE_MARKER *profile_has_marker(s, m)
- X.B PROFILE_STANZA *s;
- X.B char *m;
- X
- X.B PROFILE_STANZA *profile_has_stanza(s, marker)
- X.B PROFILE_STANZA *s;
- X.B char *marker[];
- X
- X.B PROFILE_BINDING *profile_has_binding(s, b)
- X.B PROFILE_STANZA *s;
- X.B char *b;
- X
- X.B PROFILE_STANZA *profile_stanza_space()
- X
- X.B PROFILE_MARKER *profile_marker_space(n)
- X.B int n;
- X
- X.B PROFILE_BINDING *profile_binding_space(n)
- X.B int n;
- X
- X.B PROFILE_VALUE *profile_value_space(n)
- X.B int n;
- X.fi
- X.SH DESCRIPTION
- X.I Profile_read_stanza
- Xreads a single stanza from a configuration file returning
- Xa pointer to the stanza if successful and NULL on error or end of file.
- XA stanza is defined as:
- X.nf
- X.ta 1i +\w'typedef 'u
- X
- X typedef struct PROFILE_STANZA {
- X PROFILE_MARKER *marker;
- X PROFILE_BINDING *binding;
- X struct PROFILE_STANZA *previous;
- X struct PROFILE_STANZA *next;
- X } PROFILE_STANZA;
- X.fi
- X.PP
- X.I Marker
- Xand
- X.I binding
- Xpoint to linked lists of markers and bindings respectively.
- XIf
- X.I marker
- Xis
- X.B NULL
- Xthe stanza has no markers.
- XIf
- X.I binding
- Xis
- X.B NULL
- Xthe stanza has no bindings.
- X.I Previous
- Xand
- X.I next
- Xare ignored and may be used to doubly link successive stanzas together.
- X.DT
- X.PP
- XA marker is defined as:
- X.nf
- X.ta 1i +\w'typedef 'u
- X
- X typedef struct PROFILE_MARKER {
- X char *text;
- X struct PROFILE_MARKER *previous;
- X struct PROFILE_MARKER *next;
- X } PROFILE_MARKER;
- X.fi
- X.DT
- X.PP
- X.I Text
- Xis a string containing the literal text of the marker
- Xand is always nonempty.
- X.IR Previous " (" next )
- Xis a pointer to the previous (next) marker in the sequence.
- XIn the first (last) marker
- X.IR previous " (" next )
- Xis
- X.BR NULL .
- X.PP
- XA binding is defined as:
- X.nf
- X.ta 1i +\w'typedef 'u
- X
- X typedef struct PROFILE_BINDING {
- X char *name;
- X PROFILE_VALUE *value;
- X struct PROFILE_BINDING *previous;
- X struct PROFILE_BINDING *next;
- X } PROFILE_BINDING;
- X.fi
- X.DT
- X.PP
- X.I Name
- Xis the literal text of the name of the binding and is always nonempty.
- X.I Value
- Xis a pointer to the list of values associated with the name.
- XIf
- X.I value
- Xis
- X.B NULL
- Xthen the binding consists solely of a name with no associated value.
- X.IR Previous " (" next )
- Xpoints to the previous (next) binding in the sequence.
- XIn the first (last) binding
- X.IR previous " (" next )
- Xis
- X.BR NULL .
- X.PP
- XA value is defined as:
- X.nf
- X.ta 1i +\w'typedef 'u +\w'union { 'u
- X
- X typedef struct PROFILE_VALUE {
- X char class;
- X union {
- X long int i;
- X double f;
- X char c;
- X char *s;
- X } value;
- X struct PROFILE_VALUE *previous;
- X struct PROFILE_VALUE *next;
- X } PROFILE_VALUE;
- X.fi
- X.DT
- X.PP
- X.I Class
- Xis always one of:
- X.TP
- XPROFILE_CHARACTER
- Xthe value is a character constant contained in
- X.IR c .
- X.TP
- XPROFILE_HEX
- Xthe value is a hex constant contained in
- X.IR i .
- X.TP
- XPROFILE_INTEGER
- Xthe value is an integer constant contained in
- X.IR i .
- X.TP
- XPROFILE_FLOAT
- Xthe value is a real constant contained in
- X.IR f .
- X.TP
- XPROFILE_OCTAL
- Xthe value is an octal constant contained in
- X.IR i .
- X.TP
- XPROFILE_STRING
- Xthe value is a string constant contained in
- X.IR s .
- X.TP
- XPROFILE_OTHER
- Xthe value is not recognizably
- Xcharacter,
- Xhex,
- Xinteger,
- Xfloat,
- Xoctal
- Xor string.
- XThe literal text is contained in
- X.IR s .
- X.PP
- X.IR Previous " (" next )
- Xpoints to the previous (next) value in the sequence.
- XIn the first (last) value
- X.IR previous " (" next )
- Xis
- X.BR NULL .
- X.PP
- X.I Profile_read_profile
- Xreads an entire configuration file and builds a bi-directional,
- Xcircularly linked list of stanzas using the
- X.I previous
- Xand
- X.I next
- Xpointers.
- XThe value returned is a pointer to the first stanza in the list.
- X.PP
- X.I Profile_write_stanza
- Xwrites a stanza in a canonical form suitable for input by
- X.IR profile_read_stanza .
- XMarkers are output one to a line.
- XEach binding is indented by a single tab.
- XNames and values are separated, one from the other,
- Xby a single blank.
- X.PP
- X.I Profile_write_profile
- Xwrites all the stanzas in a linked list by applying
- X.I profile_write_stanza
- Xto each stanza in the list.
- XThe list need not be doubly linked.
- X.PP
- X.I Profile_free_stanza
- Xfrees all storage associated with a stanza.
- X.PP
- X.I Profile_has_marker
- Xsearches the marker list of a stanza for a match to the given marker,
- X.IR m .
- XA pointer to the marker is returned on success and
- X.B NULL
- Xon failure.
- X.PP
- X.I Profile_has_stanza
- Xsearches a linked list of stanzas for a stanza that has all the
- Xmarkers in
- X.I marker.
- X.I Marker
- Xmust be terminated by a null entry.
- X.PP
- X.I Profile_has_binding
- Xsearches the binding list of a stanza
- Xfor a binding with a match to the given name.
- XA pointer to the binding is returned on success and
- X.B NULL
- Xon failure.
- X.PP
- XThe following routines are useful for constructing stanzas on the fly.
- X.I Profile_stanza_space
- Xallocates storage for a stanza.
- X.I Profile_marker_space
- Xallocates storage for a marker including sufficient space for
- X.I n
- Xcharacters of text plus a terminating null byte.
- X.I Profile_binding_space
- Xallocates storage for a binding including sufficient space for
- X.I n
- Xcharacters of name text plus a terminating null byte.
- X.I Profile_value_space
- Xallocates storage for a value.
- XIf
- X.I n
- Xis positive and non-zero the component
- X.IR value . s
- Xis initialized as a
- X.IR n +1
- Xcharacter array.
- XAll of the above routines return a pointer on success and
- X.B NULL
- Xon failure.
- XAll storage is zero filled.
- XThe routine
- X.IR free (3)
- Xmay be safely used to release storage allocated by these routines.
- X.SH AUTHOR
- XMichael Gorlick, TRW
- X.SH SEE ALSO
- Xmalloc(3), profile(5)
- !FaR!OuT!
- if [ ! -d libprofile ]
- then
- mkdir libprofile
- echo mkdir libprofile
- fi
- echo x - libprofile/profile.5
- sed -e 's/^X//' > libprofile/profile.5 << '!FaR!OuT!'
- X.\" @(#)profile.5 1.1 (TRW) 6/11/84
- X.TH PROFILE 5 TRW
- X.UC 4
- X.SH NAME
- Xprofile \- configuration file format
- X.SH SYNOPSIS
- X.B #include <local/profile.h>
- X.SH DESCRIPTION
- X.I Profile
- Xis a general purpose configuration file facility.
- X.PP
- XEach profile is an ASCII file containing a sequence of one or more
- X.IR stanzas .
- XEach stanza in turn consists of a sequence of
- X.I markers
- Xfollowed by a sequence of
- X.IR bindings .
- XThe characters `{' (left brace) and `}' (right brace)
- Xdelimit the beginning and end respectively of the stanza bindings.
- XEach binding consists of a name
- Xfollowed by an optional sequence of values.
- X.SH MARKERS
- XMarkers are arbitrary patterns in the style of
- X.IR glob (3)
- Xdelimited by white space.
- XThe list of markers may be empty.
- XThere is no limit to the number of markers.
- XExamples of markers are:
- X.nf
- X
- X queue
- X /usr/lib
- X 1776
- X a_long_marker
- X file[0-9]*.?
- X.fi
- X.SH BINDINGS
- XBindings are the association of names with values.
- XThere is one binding to a line each consisting of a name followed
- Xby an optional sequence of values.
- XNames and values are separated,
- Xone from the other,
- Xby blanks or tabs.
- XHere a newline preceded by a backslash is equivalent to a blank.
- XThe list of bindings may be empty.
- XThere is no limit to the number of bindings.
- XBy convention each binding is indented by a single tab.
- X.SH NAMES
- XNames are arbitrary patterns in the style of
- X.IR glob (3)
- Xdelimited by white space.
- X.SH VALUES
- XValues are
- Xinteger,
- Xreal,
- Xoctal,
- Xhex,
- Xcharacter,
- Xor
- Xstring
- Xconstants.
- XArbitrary text,
- Xnot recognizably one of the aforementioned types,
- Xis classified as
- X.I other
- Xand is a legitimate value.
- X.TP
- Xinteger
- XA sequence of digits optionally preceded by a minus sign.
- XEvery integer constant is taken to be long.
- X.TP
- Xfloating
- XA floating constant consists of an optional minus sign,
- Xan integer part
- Xa decimal point,
- Xa fraction part,
- Xan
- X.B e
- Xor
- X.BR E ,
- Xand an optionally signed integer exponent.
- XThe integer and fraction parts both consist of a sequence of digits.
- XEither the integer part or the fraction part (not both)
- Xmay be missing;
- Xeither the decimal point or the
- X.B e
- Xand the exponent (not both) may be missing.
- XEvery floating constant is taken to be double-precision.
- X.TP
- Xhex
- XA sequence of hexidecimal digits preceded by
- X.B 0x
- Xor
- X.BR 0X .
- XThe hexidecimal digits are 0-9, a-e and A-F.
- XEvery hex constant is taken to be long.
- X.TP
- Xoctal
- XA sequence of octal digits preceded by
- X.B 0o
- Xor
- X.B 0O
- X(digit zero followed by a letter o).
- XThe octal digits are 0-7.
- XEvery octal constant is taken to be long.
- X.TP
- Xcharacter
- XA character constant is a character enclosed in single quotes.
- XCertain non-graphic characters,
- Xthe single quote ',
- Xthe caret ^ and
- Xthe backslash \\,
- Xmay be represented according to the following table of escape sequences:
- X.ta 1i +\w'carriage return 'u
- X.nf
- X
- X newline \\n
- X horizontal tab \\t
- X backspace \\b
- X carriage return \\r
- X form feed \\f
- X escape \\e
- X backslash \\\\
- X single quote \\'
- X caret \\^
- X control-@ ^@
- X control-A ^A
- X ... ...
- X control-Z ^Z
- X control-[ ^[
- X control-\\ ^\\
- X control-^ ^^
- X control-_ ^_
- X delete ^?
- X bit pattern \\\fIddd\fR
- X
- X.fi
- X.DT
- XThe escape \\\fIddd\fR
- Xconsists of the backslash followed by 1, 2, or 3 octal digits
- Xwhich are taken to specify the value of the desired character.
- XIf the character following a backslash (caret) is not one of those
- Xspecified, the backslash (caret) is ignored.
- X.TP
- Xstring
- XA string is a sequence of characters surrounded by double quotes, as in
- X\fB"..."\fR.
- XIn a string,
- Xthe double quote character \fB"\fR must be preceded by a \\;
- Xin addition,
- Xthe same escapes as described for character constants may be used.
- X.PP
- XExamples of values are:
- X.nf
- X
- X 7
- X -1.293e3
- X 0x10a5
- X 0o1273
- X 'x'
- X "a string"
- X an_other_value
- X.fi
- X.SH COMMENTS
- XComments may appear anywhere within a profile.
- XThey are introduced by the character `#' and are terminated by
- Xthe succeeding newline.
- X.SH EXAMPLES
- XThe empty stanza.
- X.nf
- X
- X{
- X}
- X.fi
- X.PP
- XA stanza in the configuration file of a fictitious network server.
- X.nf
- X.ta \w'queue 'u +\w'cost_per_packet 'u +\w'0o125 0x1af 'u
- X
- Xqueue net*
- X{
- X priority 7 # integer
- X expect "who is it" # string
- X send '?' # character
- X flags[0-9] 0o125 0x1af # octal and hex
- X cost_per_packet 0.28 # floating
- X device /dev/net # other
- X homebrew # a name with no associated value
- X}
- X.fi
- X.DT
- X.PP
- XA password file entry recast as a stanza.
- X.nf
- X.ta \w'brown 'u +\w'password 'u
- X
- Xbrown
- X{
- X password /bObOZtyGclMV
- X userid 225
- X groupid 30
- X home /home/brown
- X shell /bin/csh
- X}
- X.fi
- X.DT
- X.PP
- XA termcap entry recast as a stanza.
- X.nf
- X.ta \w'adm3a 'u +\w'mm 'u
- X
- Xadm3a
- X{
- X fullname "lsi adm3a"
- X am
- X bs
- X cm "\\e=%+ %+ "
- X cl "1^Z"
- X co 80
- X li 24
- X ho '^^'
- X ma "^K^P"
- X nd '^L'
- X up '^K'
- X}
- X.fi
- X.SH AUTHOR
- XMichael Gorlick, TRW
- X.SH SEE ALSO
- Xglob(3), profile(3)
- !FaR!OuT!
- if [ ! -d libprofile ]
- then
- mkdir libprofile
- echo mkdir libprofile
- fi
- echo x - libprofile/profile.h
- sed -e 's/^X//' > libprofile/profile.h << '!FaR!OuT!'
- X/* @(#)profile.h 1.1 (TRW) 1/14/86 */
- Xtypedef struct PROFILE_VALUE {
- X char class;
- X union {
- X long int i;
- X double f;
- X char c;
- X char *s;
- X } value;
- X struct PROFILE_VALUE *previous;
- X struct PROFILE_VALUE *next;
- X} PROFILE_VALUE;
- X
- Xtypedef struct PROFILE_BINDING {
- X char *name;
- X PROFILE_VALUE *value;
- X struct PROFILE_BINDING *previous;
- X struct PROFILE_BINDING *next;
- X} PROFILE_BINDING;
- X
- Xtypedef struct PROFILE_MARKER {
- X char *text;
- X struct PROFILE_MARKER *previous;
- X struct PROFILE_MARKER *next;
- X} PROFILE_MARKER;
- X
- Xtypedef struct PROFILE_STANZA {
- X PROFILE_MARKER *marker;
- X PROFILE_BINDING *binding;
- X struct PROFILE_STANZA *previous;
- X struct PROFILE_STANZA *next;
- X} PROFILE_STANZA;
- X
- X/* classes */
- X#define PROFILE_INTEGER 01
- X#define PROFILE_FLOAT 02
- X#define PROFILE_STRING 03
- X#define PROFILE_CHARACTER 04
- X#define PROFILE_OTHER 05
- X#define PROFILE_OCTAL 06
- X#define PROFILE_HEX 07
- X
- X/* no single lexical element may exceed this size in characters */
- X#define PROFILE_MAX_TEXT 255
- X
- XPROFILE_STANZA *profile_read_stanza();
- XPROFILE_STANZA *profile_read_profile();
- XPROFILE_MARKER *profile_has_marker();
- XPROFILE_STANZA *profile_has_stanza();
- XPROFILE_BINDING *profile_has_binding();
- XPROFILE_STANZA *profile_stanza_space();
- XPROFILE_MARKER *profile_marker_space();
- XPROFILE_BINDING *profile_binding_space();
- XPROFILE_VALUE *profile_value_space();
- !FaR!OuT!
- if [ ! -d libprofile ]
- then
- mkdir libprofile
- echo mkdir libprofile
- fi
- echo x - libprofile/read.c
- sed -e 's/^X//' > libprofile/read.c << '!FaR!OuT!'
- Xstatic char *trwsccs = "@(#)read.c 1.1 (TRW) 1/14/86";
- X#include <stdio.h>
- X#include <ctype.h>
- X#include "profile.h"
- X
- X#define isoctal(d) ('0' <= d && d <= '7')
- X#define ishex(x) (isdigit(x) || ('a' <= x && x <= 'f') || ('A' <= x && x <= 'F'))
- X#define isprime(c) (c == '\'')
- X#define isbackslash(c) (c == '\\')
- X#define iscaret(c) (c == '^')
- X
- Xextern char *strcpy();
- Xextern PROFILE_STANZA *profile_stanza_space();
- Xextern PROFILE_MARKER *profile_marker_space();
- Xextern PROFILE_BINDING *profile_binding_space();
- Xextern PROFILE_VALUE *profile_value_space();
- X
- Xstatic PROFILE_BINDING *get_binding();
- Xstatic PROFILE_BINDING *get_bindings();
- Xstatic PROFILE_MARKER *get_marker();
- Xstatic PROFILE_MARKER *get_markers();
- Xstatic PROFILE_VALUE *get_value();
- Xstatic PROFILE_VALUE *get_values();
- Xstatic char parse_character();
- Xstatic PROFILE_VALUE *parse_value();
- X
- XPROFILE_STANZA *profile_read_stanza (f)
- XFILE *f;
- X{
- X PROFILE_STANZA *stanza;
- X
- X stanza = profile_stanza_space();
- X if (stanza == NULL)
- X return(NULL);
- X stanza->marker = get_markers(f);
- X if (get_open_bindings(f))
- X stanza->binding = get_bindings(f);
- X else {
- X profile_free_stanza(stanza);
- X return(NULL);
- X }
- X if (get_close_bindings(f))
- X return(stanza);
- X else {
- X profile_free_stanza(stanza);
- X return(NULL);
- X }
- X}
- X
- X/* Returns the list of markers at the head of a stanza. */
- Xstatic PROFILE_MARKER *get_markers (f)
- XFILE *f;
- X{
- X PROFILE_MARKER *head, *tail, *m;
- X
- X head = tail = NULL;
- X while (m = get_marker(f))
- X if (tail) {
- X tail->next = m;
- X m->previous = tail;
- X tail = m;
- X } else
- X head = tail = m;
- X return(head);
- X}
- X
- X/* Returns the next marker from the head of the stanza. */
- Xstatic PROFILE_MARKER *get_marker (f)
- XFILE *f;
- X{
- X int n;
- X PROFILE_MARKER *m;
- X char scratch[PROFILE_MAX_TEXT+1];
- X
- X for (;;)
- X if (n = get_name_text(f, scratch)) {
- X if ((m = profile_marker_space(n)) == NULL)
- X return(NULL);
- X strcpy(m->text, scratch);
- X return(m);
- X } else if (get_end_of_line(f))
- X continue;
- X else
- X return(NULL);
- X}
- X
- X/* Returns the list of bindings in the body of the stanza. */
- Xstatic PROFILE_BINDING *get_bindings (f)
- XFILE *f;
- X{
- X PROFILE_BINDING *head, *tail, *b;
- X
- X head = tail = NULL;
- X while (b = get_binding(f))
- X if (tail) {
- X tail->next = b;
- X b->previous = tail;
- X tail = b;
- X } else
- X head = tail = b;
- X return(head);
- X}
- X
- X/* Returns the next binding in the body of the stanza. */
- Xstatic PROFILE_BINDING *get_binding (f)
- XFILE *f;
- X{
- X int n;
- X PROFILE_BINDING *b;
- X char scratch[PROFILE_MAX_TEXT+1];
- X
- X for (;;)
- X if (n = get_name_text(f, scratch)) {
- X if ((b = profile_binding_space(n)) == NULL)
- X return(NULL);
- X strcpy(b->name, scratch);
- X break;
- X } else if (get_end_of_line(f))
- X continue;
- X else
- X return(NULL);
- X b->value = get_values(f);
- X return(b);
- X}
- X
- X/* Returns the list of values following the name of the binding. */
- Xstatic PROFILE_VALUE *get_values (f)
- XFILE *f;
- X{
- X PROFILE_VALUE *head, *tail, *v;
- X
- X head = tail = NULL;
- X while (v = get_value(f))
- X if (tail) {
- X tail->next = v;
- X v->previous = tail;
- X tail = v;
- X } else
- X head = tail = v;
- X return(head);
- X}
- X
- X/* Returns the next value in the binding. */
- Xstatic PROFILE_VALUE *get_value (f)
- XFILE *f;
- X{
- X char text[PROFILE_MAX_TEXT+1];
- X int n;
- X
- X for (;;)
- X if (n = get_value_text(f, text))
- X return(parse_value(text, n));
- X else if (get_end_of_line(f))
- X return(NULL);
- X else
- X return(NULL);
- X}
- X
- X/*
- X * Reads the text of the next value (if any) in the binding. Returns
- X * the length of the literal text in characters.
- X */
- Xstatic int get_value_text (f, text)
- XFILE *f;
- Xchar *text;
- X{
- X register int c;
- X char *s = text;
- X
- X while ((c = getc(f)) != EOF)
- X switch (c) {
- X case '\b': case '\f':
- X case '\r': case '\t': case ' ':
- X /* white space terminates any text gathered so far */
- X if (s > text) {
- X *s = '\0';
- X return(s - text);
- X }
- X continue;
- X
- X case '\n':
- X /* newline terminates a binding */
- X ungetc(c, f);
- X *s = '\0';
- X return(s - text);
- X
- X case '#':
- X /* gobble up the comment */
- X while ((c = getc(f)) != EOF && c != '\n')
- X continue;
- X if (c == '\n')
- X ungetc(c, f);
- X *s = '\0';
- X return(s - text);
- X
- X case '{': case '}':
- X ungetc(c, f);
- X *s = '\0';
- X return(s - text);
- X
- X case '"': /* string quotes */
- X ungetc(c, f);
- X if (s > text) {
- X *s = '\0';
- X return(s - text);
- X } else
- X return(get_string(f, s));
- X
- X case '\'': /* character quotes */
- X ungetc(c, f);
- X if (s > text) {
- X *s = '\0';
- X return(s - text);
- X } else
- X return(get_character(f, s));
- X
- X case '\\': /* newline escape */
- X c = getc(f);
- X if (c == '\n') {
- X if (s > text) {
- X *s = '\0';
- X return(s - text);
- X }
- X continue; /* just like a blank */
- X }
- X ungetc(c, f);
- X if (s < &text[PROFILE_MAX_TEXT])
- X *s++ = '\\';
- X continue;
- X
- X default:
- X if (s < &text[PROFILE_MAX_TEXT])
- X *s++ = c;
- X continue;
- X }
- X *s = '\0';
- X return(s - text);
- X}
- X
- X/* Digests the raw value text returning a new value structure. */
- Xstatic PROFILE_VALUE *parse_value (s, length)
- Xchar *s; /* literal text */
- Xint length; /* in characters */
- X{
- X PROFILE_VALUE *v;
- X
- X if (is_integer(s)) {
- X if ((v = profile_value_space(0)) == NULL)
- X return(NULL);
- X v->class = PROFILE_INTEGER;
- X sscanf(s, "%D", &v->value.i);
- X } else if (is_octal(s)) {
- X if ((v = profile_value_space(0)) == NULL)
- X return(NULL);
- X v->class = PROFILE_OCTAL;
- X /* skip the `0o' prefix */
- X sscanf(s+2, "%O", &v->value.i);
- X } else if (is_hex(s)) {
- X if ((v = profile_value_space(0)) == NULL)
- X return(NULL);
- X v->class = PROFILE_HEX;
- X /* skip the `0x' prefix */
- X sscanf(s+2, "%X", &v->value.i);
- X } else if (is_string(s)) {
- X /* be careful when dealing with the empty string "" */
- X if ((v = profile_value_space(length > 2 ? length - 2 : 1)) == NULL)
- X return(NULL);
- X v->class = PROFILE_STRING;
- X /* erase the terminating double quote */
- X s[length - 1] = '\0';
- X /* skip past the initial quote */
- X parse_string(s + 1, v->value.s);
- X } else if (is_character(s)) {
- X if ((v = profile_value_space(0)) == NULL)
- X return(NULL);
- X v->class = PROFILE_CHARACTER;
- X /* erase the end single quote */
- X s[length - 1] = '\0';
- X v->value.c = parse_character(s + 1);
- X } else if (is_float(s)) {
- X if ((v = profile_value_space(0)) == NULL)
- X return(NULL);
- X v->class = PROFILE_FLOAT;
- X sscanf(s, "%E", &v->value.f);
- X } else {
- X if ((v = profile_value_space(length)) == NULL)
- X return(NULL);
- X v->class = PROFILE_OTHER;
- X strcpy(v->value.s, s);
- X }
- X return(v);
- X}
- X
- X/* Converts a string literal to the internal representation. */
- Xstatic parse_string (source, result)
- Xchar *source;
- Xchar *result;
- X{
- X for (; *source; source++)
- X if (*source == '\\')
- X switch (*++source) {
- X case 'b': /* backspace */
- X *result++ = '\b';
- X continue;
- X case 'f': /* formfeed */
- X *result++ = '\f';
- X continue;
- X case 'n': /* newline */
- X *result++ = '\n';
- X continue;
- X case 'r': /* carriage return */
- X *result++ = '\r';
- X continue;
- X case 't': /* horizontal tab */
- X *result++ = '\t';
- X continue;
- X case '\'': /* single quote */
- X *result++ = '\'';
- X continue;
- X case '"': /* double quote */
- X *result++ = '"';
- X continue;
- X case '\\': /* backslash */
- X *result++ = '\\';
- X continue;
- X case '^': /* caret */
- X *result++ = '^';
- X continue;
- X case '0': case '1': /* octal constant */
- X case '2': case '3':
- X case '4': case '5':
- X case '6': case '7':
- X source += parse_octal(source, result) - 1;
- X result++;
- X continue;
- X default:
- X *result++ = *source; /* ignore backslash */
- X }
- X else if (*source == '^') { /* control escape */
- X char c = *++source;
- X *result++ = ('@' <= c && c <= '_') ? c - '@' :
- X (c == '?') ? '\177' : c;
- X continue;
- X } else
- X *result++ = *source;
- X *result = '\0';
- X}
- X
- X/* Converts a character literal to the internal representation. */
- Xstatic char parse_character (source)
- Xchar *source;
- X{
- X char c;
- X
- X if (*source == '\\')
- X switch (*++source) {
- X case 'b': /* backspace */
- X return('\b');
- X case 'f': /* formfeed */
- X return('\f');
- X case 'n': /* newline */
- X return('\n');
- X case 'r': /* carriage return */
- X return('\r');
- X case 't': /* horizontal tab */
- X return('\t');
- X case '\'': /* single quote */
- X return('\'');
- X case '\\': /* backslash */
- X return('\\');
- X case '^':
- X return('^');
- X case '0': case '1': /* octal constant */
- X case '2': case '3':
- X case '4': case '5':
- X case '6': case '7':
- X parse_octal(source, &c);
- X return(c);
- X default:
- X return(*source); /* ignore backslash */
- X }
- X else if (*source == '^') { /* control escape */
- X c = *++source;
- X return(('@' <= c && c <= '_') ? c - '@' : (c == '?') ? '\177' : c);
- X } else
- X return(*source);
- X}
- X
- X/* Converts an octal escape `\ddd' to its byte representation. */
- Xstatic int parse_octal (source, result)
- Xchar *source;
- Xchar *result;
- X{
- X int count;
- X char byte = '\0';
- X char digit;
- X
- X for (count = 1; count <= 3; count++) {
- X digit = *source++;
- X if ('0' <= digit && digit <= '7')
- X byte = (byte * 8) + (digit - '0');
- X else
- X break;
- X }
- X *result = byte;
- X return(count);
- X}
- X
- X/*
- X * Reads the literal text for markers and binding names. Returns the
- X * length in characters of the literal text.
- X */
- Xstatic int get_name_text (f, text)
- XFILE *f;
- Xchar *text;
- X{
- X register int c;
- X char *s = text;
- X
- X while ((c = getc(f)) != EOF)
- X switch (c) {
- X case '\b': case '\f':
- X case '\r': case '\t': case ' ':
- X /* white space terminates text gathered so far */
- X if (s > text) {
- X *s = '\0';
- X return(s - text);
- X }
- X continue;
- X
- X case '\n':
- X ungetc(c, f);
- X *s = '\0';
- X return(s - text);
- X
- X case '#':
- X /* gobble up the comment */
- X while ((c = getc(f)) != EOF && c != '\n')
- X continue;
- X if (c == '\n')
- X ungetc(c, f);
- X *s = '\0';
- X return(s - text);
- X
- X case '{': case '}':
- X ungetc(c, f);
- X *s = '\0';
- X return(s - text);
- X
- X case '[':
- X /* sets may contain embedded white space */
- X if (s + 1 < &text[PROFILE_MAX_TEXT]) {
- X *s++ = '[';
- X if ((c = getc(f)) != EOF)
- X *s++ = c;
- X }
- X while ((c = getc(f)) != EOF) {
- X if (s < &text[PROFILE_MAX_TEXT])
- X *s++ = c;
- X if (c == ']')
- X break;
- X }
- X continue;
- X
- X case '\\':
- X c = getc(f);
- X if (c == '\n') {
- X if (s > text) {
- X *s = '\0';
- X return(s - text);
- X }
- X continue; /* just like a blank */
- X }
- X ungetc(c, f);
- X if (s < &text[PROFILE_MAX_TEXT])
- X *s++ = '\\';
- X continue;
- X
- X default:
- X if (s < &text[PROFILE_MAX_TEXT])
- X *s++ = c;
- X continue;
- X }
- X *s = '\0';
- X return(s - text);
- X}
- X
- X/* Returns non-zero on end of line and zero otherwise. */
- Xstatic int get_end_of_line (f)
- XFILE *f;
- X{
- X int c;
- X
- X if ((c = getc(f)) == '\n')
- X return(1);
- X ungetc(c, f);
- X return(0);
- X}
- X
- X/* Returns non-zero on seeing `{' and zero otherwise. */
- Xstatic int get_open_bindings (f)
- XFILE *f;
- X{
- X int c;
- X
- X if ((c = getc(f)) == '{')
- X return(1);
- X ungetc(c, f);
- X return(0);
- X}
- X
- X/* Returns non-zero on seeing `}' and zero otherwise. */
- Xstatic int get_close_bindings (f)
- XFILE *f;
- X{
- X int c;
- X
- X if ((c = getc(f)) == '}')
- X return(1);
- X ungetc(c, f);
- X return(0);
- X}
- X
- X/* Reads a string literal returning the length of the literal text in characters */
- Xstatic int get_string (f, text)
- XFILE *f;
- Xchar *text;
- X{
- X register int c;
- X char *s = text;
- X
- X /* the first double quote is guaranteed */
- X *s++ = getc(f);
- X while ((c = getc(f)) != EOF)
- X switch (c) {
- X case '\\':
- X if (s < &text[PROFILE_MAX_TEXT])
- X *s++ = c;
- X c = getc(f);
- X if (c == EOF)
- X return(s - text);
- X else if (c == '\n') {
- X ungetc(c, f);
- X return(s - text);
- X } else if (s < &text[PROFILE_MAX_TEXT])
- X *s++ = c;
- X continue;
- X
- X case '"':
- X if (s < &text[PROFILE_MAX_TEXT])
- X *s++ = c;
- X *s = '\0';
- X return(s - text);
- X
- X case '\n':
- X ungetc(c, f);
- X *s = '\0';
- X return(s - text);
- X
- X default:
- X if (s < &text[PROFILE_MAX_TEXT])
- X *s++ = c;
- X continue;
- X }
- X *s = '\0';
- X return(s - text);
- X}
- X
- X/* Reads a character literal returning the length of the literal text in characters. */
- Xstatic int get_character (f, text)
- XFILE *f;
- Xchar *text;
- X{
- X register int c;
- X char *s = text;
- X
- X /* the first single quote is guaranteed */
- X *s++ = getc(f);
- X while ((c = getc(f)) != EOF)
- X switch (c) {
- X case '\\':
- X if (s < &text[PROFILE_MAX_TEXT])
- X *s++ = c;
- X c = getc(f);
- X if (c == EOF)
- X return(s - text);
- X else if (c == '\n') {
- X ungetc(c, f);
- X return(s - text);
- X } else if (s < &text[PROFILE_MAX_TEXT])
- X *s++ = c;
- X continue;
- X case '\'':
- X if (s < &text[PROFILE_MAX_TEXT])
- X *s++ = c;
- X *s = '\0';
- X return(s - text);
- X case '\n':
- X ungetc(c, f);
- X *s = '\0';
- X return(s - text);
- X default:
- X if (s < &text[PROFILE_MAX_TEXT])
- X *s++ = c;
- X continue;
- X }
- X *s = '\0';
- X return(s - text);
- X}
- X
- X/* all regular expressions below are in lex notation */
- X
- X/* returns non-zero iff -?[0-9]+ matches */
- Xstatic int is_integer (s)
- Xchar *s;
- X{
- X char *x;
- X
- X /* -? */
- X if (*s == '-')
- X s++;
- X /* [0-9]+ */
- X for (x = s; isdigit(*s); s++)
- X continue;
- X return(s > x && !*s);
- X}
- X
- X/* returns non-zero iff 0[oO][0-7]+ matches */
- Xstatic int is_octal (s)
- Xchar *s;
- X{
- X char *x;
- X
- X /* 0 */
- X if (*s == '0')
- X s++;
- X else
- X return(0);
- X /* [oO] */
- X if (*s == 'o' || *s == 'O')
- X s++;
- X else
- X return(0);
- X /* [0-7]+ */
- X for (x = s; isoctal(*s); s++)
- X continue;
- X return(s > x && !*s);
- X}
- X
- X/* returns non-zero iff 0[xX][0-9a-fA-F]+ matches */
- Xstatic int is_hex (s)
- Xchar *s;
- X{
- X char *x;
- X
- X /* 0 */
- X if (*s == '0')
- X s++;
- X else
- X return(0);
- X /* [xX] */
- X if (*s == 'x' || *s == 'X')
- X s++;
- X else
- X return(0);
- X /* [0-9a-fA-F]+ */
- X for (x = s; ishex(*s); s++)
- X continue;
- X return(s > x && !*s);
- X}
- X
- X/* returns non-zero iff [eE][-+]?[0-9]+ matches */
- Xstatic int is_exponent (s)
- Xchar *s;
- X{
- X char *x;
- X
- X /* [eE] */
- X if (*s == 'e' || *s == 'E')
- X s++;
- X else
- X return(0);
- X /* [-+]? */
- X if (*s == '-' || *s == '+')
- X s++;
- X /* [0-9]+ */
- X for (x = s; isdigit(*s); s++)
- X continue;
- X return(s > x && !*s);
- X}
- X
- Xstatic int is_float (s)
- Xchar *s;
- X{
- X return(is_integer_part_float(s) ||
- X is_fractional_part_float(s) ||
- X is_power_float(s));
- X}
- X
- X/* returns non-zero iff -?[0-9]+"."[0-9]*({exponent})? matches */
- Xstatic int is_integer_part_float (s)
- Xchar *s;
- X{
- X char *x;
- X
- X /* -? */
- X if (*s == '-')
- X s++;
- X /* [0-9]+"." */
- X for (x = s; isdigit(*s); s++)
- X continue;
- X if (x == s || *s != '.')
- X return(0);
- X /* [0-9]* */
- X for (s++; isdigit(*s); s++)
- X continue;
- X /* ({exponent})? */
- X return(*s ? is_exponent(s) : 1);
- X}
- X
- X/* returns non-zero iff -?"."[0-9]+({exponent})? matches */
- Xstatic int is_fractional_part_float (s)
- Xchar *s;
- X{
- X char *x;
- X
- X /* -? */
- X if (*s == '-')
- X s++;
- X /* "." */
- X if (*s == '.')
- X s++;
- X else
- X return(0);
- X /* [0-9]+({exponent})? */
- X for (x = s; isdigit(*s); s++)
- X continue;
- X return(s > x ? !*s || is_exponent(s) : 0);
- X}
- X
- X/* returns non-zero iff -?[0-9]+{exponent} matches */
- Xstatic int is_power_float (s)
- Xchar *s;
- X{
- X char *x;
- X
- X /* -? */
- X if (*s == '-')
- X s++;
- X /* [0-9]+{exponent} */
- X for (x = s; isdigit(*s); s++)
- X continue;
- X return(s > x ? is_exponent(s) : 0);
- X}
- X
- X/* returns non-zero iff '[^^\]' | '\^.' | '\\\\' | '\\'' | '\[0-7]{1-3}' matches */
- Xstatic int is_character (s)
- Xchar *s;
- X{
- X char *x;
- X
- X if (isprime(*s))
- X s++;
- X else
- X return(0);
- X if (isbackslash(*s)) {
- X s++;
- X if ((isbackslash(s[0]) || isprime(s[0]) || !isdigit(s[0])) &&
- X isprime(s[1]) && !s[2])
- X return(1);
- X for (x = s; isoctal(*s); s++)
- X continue;
- X return(x < s && s < (x+4) && isprime(s[0]) && !s[1]);
- X } else if (iscaret(*s))
- X s++;
- X return(isprint(s[0]) && isprime(s[1]) && !s[2]);
- X}
- X
- X/* returns non-zero iff s is a string constant */
- Xstatic int is_string (s)
- Xchar *s;
- X{
- X char *x;
- X
- X if (*s != '"')
- X return(0);
- X for (s++; *s; s++) {
- X if (*s == '"')
- X return(!*++s); /* quote must be followed by null */
- X if (isbackslash(*s) || iscaret(*s)) {
- X if (*++s)
- X continue; /* legal escape */
- X return(0); /* null follows \ or ^ */
- X }
- X }
- X return(0);
- X}
- X
- X/*
- X * read an entire profile, making a bidirectional
- X * circularly linked list
- X * returns pointer to the first stanza or NULL on error
- X */
- XPROFILE_STANZA *profile_read_profile(f)
- XFILE *f;
- X{
- X PROFILE_STANZA *head = NULL;
- X PROFILE_STANZA *tail = NULL;
- X PROFILE_STANZA *x = NULL;
- X
- X while ((x = profile_read_stanza(f)) != NULL) {
- X if (head == NULL)
- X head = tail = x;
- X else {
- X tail->next = x;
- X x->previous = tail;
- X tail = x;
- X }
- X }
- X if (head != NULL) {
- X tail->next = head;
- X head->previous = tail;
- X }
- X return(head);
- X}
- !FaR!OuT!
- if [ ! -d libprofile ]
- then
- mkdir libprofile
- echo mkdir libprofile
- fi
- echo x - libprofile/space.c
- sed -e 's/^X//' > libprofile/space.c << '!FaR!OuT!'
- Xstatic char *trwsccs = "@(#)space.c 1.1 (TRW) 1/14/86";
- X#include "profile.h"
- X
- Xextern char *calloc();
- X
- XPROFILE_STANZA *profile_stanza_space ()
- X{
- X return((PROFILE_STANZA *)calloc(1, sizeof(PROFILE_STANZA)));
- X}
- X
- XPROFILE_MARKER *profile_marker_space (n)
- Xint n;
- X{
- X char *space;
- X PROFILE_MARKER *m = (PROFILE_MARKER *)0;
- X
- X if (space = calloc(1, sizeof(PROFILE_MARKER) + n + 1)) {
- X m = (PROFILE_MARKER *)space;
- X m->text = space + sizeof(PROFILE_MARKER);
- X }
- X return(m);
- X}
- X
- XPROFILE_BINDING *profile_binding_space (n)
- Xint n; /* length of binding name in characters */
- X{
- X char *space;
- X PROFILE_BINDING *b = (PROFILE_BINDING *)0;
- X
- X if (space = calloc(1, sizeof(PROFILE_BINDING) + n + 1)) {
- X b = (PROFILE_BINDING *)space;
- X b->name = space + sizeof(PROFILE_BINDING);
- X }
- X return(b);
- X}
- X
- XPROFILE_VALUE *profile_value_space (n)
- Xint n;
- X{
- X char *space;
- X PROFILE_VALUE *v = (PROFILE_VALUE *)0;
- X
- X if (n > 0) {
- X if (space = calloc(1, sizeof(PROFILE_VALUE) + n + 1)) {
- X v = (PROFILE_VALUE *)space;
- X v->value.s = space + sizeof(PROFILE_VALUE);
- X }
- X } else
- X v = (PROFILE_VALUE *)calloc(1, sizeof(PROFILE_VALUE));
- X return(v);
- X}
- !FaR!OuT!
- if [ ! -d libprofile ]
- then
- mkdir libprofile
- echo mkdir libprofile
- fi
- echo x - libprofile/write.c
- sed -e 's/^X//' > libprofile/write.c << '!FaR!OuT!'
- Xstatic char *trwsccs = "@(#)write.c 1.1 (TRW) 1/14/86";
- X#include <stdio.h>
- X#include <ctype.h>
- X#include "profile.h"
- X
- Xprofile_write_stanza (f, s)
- XFILE *f;
- XPROFILE_STANZA *s;
- X{
- X write_markers(f, s->marker);
- X fprintf(f, "{\n");
- X write_bindings(f, s->binding);
- X fprintf(f, "}\n");
- X}
- X
- Xstatic write_markers (f, m)
- XFILE *f;
- XPROFILE_MARKER *m;
- X{
- X for (; m; m = m->next)
- X fprintf(f, "%s\n", m->text);
- X}
- X
- Xstatic write_bindings (f, b)
- XFILE *f;
- XPROFILE_BINDING *b;
- X{
- X while (b) {
- X fprintf(f, "\t%s", b->name);
- X write_values(f, b->value);
- X fputc('\n', f);
- X b = b->next;
- X }
- X}
- X
- Xstatic write_values (f, v)
- XFILE *f;
- XPROFILE_VALUE *v;
- X{
- X char scratch[PROFILE_MAX_TEXT+1];
- X
- X for (; v; v = v->next)
- X switch (v->class) {
- X case PROFILE_INTEGER:
- X fprintf(f, " %D", v->value.i);
- X continue;
- X case PROFILE_FLOAT:
- X fprintf(f, " %G", v->value.f);
- X continue;
- X case PROFILE_STRING:
- X unparse_string(v->value.s, scratch);
- X fprintf(f, " \"%s\"", scratch);
- X continue;
- X case PROFILE_CHARACTER:
- X unparse_character(v->value.c, scratch);
- X fprintf(f, " '%s'", scratch);
- X continue;
- X case PROFILE_OCTAL:
- X fprintf(f, " 0o%O", v->value.i);
- X continue;
- X case PROFILE_HEX:
- X fprintf(f, " 0x%X", v->value.i);
- X continue;
- X case PROFILE_OTHER:
- X fprintf(f, " %s", v->value.s);
- X continue;
- X }
- X}
- X
- Xstatic int unparse_string (from, to)
- Xchar *from;
- Xchar *to;
- X{
- X char *x = to;
- X
- X for (; *from; from++)
- X switch (*from) {
- X case '\b': /* backspace */
- X *x++ = '\\';
- X *x++ = 'b';
- X continue;
- X case '\f': /* formfeed */
- X *x++ = '\\';
- X *x++ = 'f';
- X continue;
- X case '\n': /* newline */
- X *x++ = '\\';
- X *x++ = 'n';
- X continue;
- X case '\r':
- X *x++ = '\\';
- X *x++ = 'r';
- X continue;
- X case '\t': /* horizontal tab */
- X *x++ = '\\';
- X *x++ = 't';
- X continue;
- X case '\\': /* backslash */
- X *x++ = '\\';
- X *x++ = '\\';
- X continue;
- X case '"': /* double quote */
- X *x++ = '\\';
- X *x++ = '"';
- X continue;
- X case '^':
- X *x++ = '\\';
- X *x++ = '^';
- X continue;
- X default:
- X if (isascii(*from))
- X if (iscntrl(*from)) {
- X sprintf(x, "^%c", *from == '\177' ? '?' : *from + '@');
- X x += 2;
- X } else
- X *x++ = *from;
- X else {
- X sprintf(x, "\\%03o", *from);
- X x += 4;
- X }
- X continue;
- X }
- X *x = '\0';
- X return(x - to);
- X}
- X
- Xstatic int unparse_character (from, to)
- Xchar from;
- Xchar *to;
- X{
- X char *x = to;
- X
- X switch (from) {
- X case '\b': /* backspace */
- X *x++ = '\\';
- X *x++ = 'b';
- X break;
- X case '\f': /* formfeed */
- X *x++ = '\\';
- X *x++ = 'f';
- X break;
- X case '\n': /* newline */
- X *x++ = '\\';
- X *x++ = 'n';
- X break;
- X case '\r':
- X *x++ = '\\';
- X *x++ = 'r';
- X break;
- X case '\t': /* horizontal tab */
- X *x++ = '\\';
- X *x++ = 't';
- X break;
- X case '\\': /* backslash */
- X *x++ = '\\';
- X *x++ = '\\';
- X break;
- X case '\'': /* single quote */
- X *x++ = '\\';
- X *x++ = '\'';
- X break;
- X case '^':
- X *x++ = '\\';
- X *x++ = '^';
- X break;
- X default:
- X if (isascii(from))
- X if (iscntrl(from)) {
- X sprintf(x, "^%c", from == '\177' ? '?' : from + '@');
- X x += 2;
- X } else
- X *x++ = from;
- X else {
- X sprintf(x, "\\%03o", from);
- X x += 4;
- X }
- X break;
- X }
- X *x = '\0';
- X return(x - to);
- X}
- X
- X/*
- X * write out a linked list of stanzas
- X */
- Xprofile_write_profile(f, s)
- XFILE *f;
- XPROFILE_STANZA *s;
- X{
- X PROFILE_STANZA *x;
- X
- X for (x = s; x != NULL; x = x->next) {
- X profile_write_stanza(f, x);
- X if (x->next == s)
- X break;
- X }
- X}
- !FaR!OuT!
- if [ ! -d libtrw ]
- then
- mkdir libtrw
- echo mkdir libtrw
- fi
- echo x - libtrw/Makefile
- sed -e 's/^X//' > libtrw/Makefile << '!FaR!OuT!'
- X# @(#)Makefile 1.1 (TRW) 1/14/86
- XCFLAGS= -O
- XDEST= /usr/local/lib
- XINCLUDE=/usr/include/local
- X
- X.c.o:
- X ${CC} ${CFLAGS} -c $*.c
- X -ld -x -r $*.o
- X mv a.out $*.o
- X
- Xall: libtrw.a
- X
- Xlibtrw.a: shift.o getopt.o getunent.o
- X ar cr libtrw.a shift.o getopt.o getunent.o
- X ranlib libtrw.a
- X
- Xclean:
- X rm -f *.o
- X
- Xinstall: all
- X mv libtrw.a $(DEST)
- X ranlib $(DEST)/libtrw.a
- X cp universe.h $(INCLUDE)
- !FaR!OuT!
- if [ ! -d libtrw ]
- then
- mkdir libtrw
- echo mkdir libtrw
- fi
- echo x - libtrw/getopt.3
- sed -e 's/^X//' > libtrw/getopt.3 << '!FaR!OuT!'
- X.\" @(#)getopt.3 1.1 (TRW) 2/27/84
- X.TH GETOPT 3C
- X.SH NAME
- Xgetopt \- get option letter from argument vector
- X.SH SYNOPSIS
- X.B int getopt (argc, argv, optstring)
- X.br
- X.B int argc;
- X.br
- X.B char \(**\(**argv;
- X.br
- X.B char \(**optstring;
- X.PP
- X.B extern char \(**optarg;
- X.br
- X.B extern int optind;
- X.PP
- Xcc ... -ltrw
- X.SH DESCRIPTION
- X.I Getopt\^
- Xreturns the next option letter in
- X.I argv\^
- Xthat matches
- Xa letter in
- X.IR optstring .
- X.I Optstring\^
- Xis a string of recognized option letters;
- Xif a letter is followed by a colon, the option
- Xis expected to have an argument that may or
- Xmay not be separated from it by white space.
- X.I Optarg\^
- Xis set to point to the start of the option argument
- Xon return from
- X.IR getopt .
- X.PP
- X.I Getopt\^
- Xplaces in
- X.I optind\^
- Xthe
- X.I argv\^
- Xindex of the next argument to be processed.
- XBecause
- X.I optind\^
- Xis external, it is normally initialized to zero
- Xautomatically before the first call to
- X.IR getopt .
- X.PP
- XWhen all options have been processed
- X(i.e., up to the first non-option argument),
- X.I getopt\^
- Xreturns
- X.SM
- X.BR EOF .
- XThe special option
- X.B \-\-
- Xmay be used to delimit the end of the options;
- X.SM
- X.B EOF
- Xwill be returned, and
- X.B \-\-
- Xwill be skipped.
- X.SH DIAGNOSTICS
- X.I Getopt\^
- Xprints an error message on
- X.I stderr\^
- Xand returns a
- Xquestion mark
- X.RB ( ? )
- Xwhen it encounters an option letter not included in
- X.IR optstring .
- X.SH WARNING
- XThe above routine uses \fB<stdio.h>\fP, which causes
- Xit to increase the size of programs,
- Xnot otherwise using standard I/O, more
- Xthan might be expected.
- X.SH EXAMPLE
- XThe following code fragment shows how one might process the arguments
- Xfor a command that can take the mutually exclusive options
- X.B a
- Xand
- X.BR b ,
- Xand the options
- X.B f
- Xand
- X.BR o ,
- Xboth of which require arguments:
- X.PP
- X.RS
- X.nf
- X.ss 18
- Xmain (argc, argv)
- Xint argc;
- Xchar \(**\(**argv;
- X{
- X int c;
- X extern int optind;
- X extern char \(**optarg;
- X \&\f3.\fP
- X \&\f3.\fP
- X \&\f3.\fP
- X while ((c = getopt (argc, argv, "abf:o:")) != \s-1EOF\s+1)
- X switch (c) {
- X case \(fma\(fm:
- X if (bflg)
- X errflg++;
- X else
- X aflg++;
- X break;
- X case \(fmb\(fm:
- X if (aflg)
- X errflg++;
- X else
- X bproc( );
- X break;
- X case \(fmf\(fm:
- X ifile = optarg;
- X break;
- X case \(fmo\(fm:
- X ofile = optarg;
- X bufsiza = 512;
- X break;
- X case \(fm?\(fm:
- X errflg++;
- X }
- X if (errflg) {
- X fprintf (stderr, "usage: . . . ");
- X exit (2);
- X }
- X for ( ; optind < argc; optind++) {
- X if (access (argv[optind], 4)) {
- X \&\f3.\fP
- X \&\f3.\fP
- X \&\f3.\fP
- X}
- X.ss 12
- X.fi
- X.RE
- X.\" @(#)getopt.3c 5.2 of 5/18/82
- !FaR!OuT!
- if [ ! -d libtrw ]
- then
- mkdir libtrw
- echo mkdir libtrw
- fi
- echo x - libtrw/getopt.c
- sed -e 's/^X//' > libtrw/getopt.c << '!FaR!OuT!'
- Xstatic char *trwsccs = "@(#)getopt.c 1.1 (TRW) 1/14/86";
- X/* This is the System V getopt(3), modified to use index(3) instead
- X * of strchr(3).
- X */
- X
- X/* @(#)getopt.c 1.2 */
- X/* 3.0 SID # 1.2 */
- X/*LINTLIBRARY*/
- X#include <stdio.h>
- X#define ERR(s, c) if(opterr){\
- X (void) fputs(argv[0], stderr);\
- X (void) fputs(s, stderr);\
- X (void) fputc(c, stderr);\
- X (void) fputc('\n', stderr);}
- X
- Xextern int strcmp();
- Xextern char *index();
- X
- Xint opterr = 1;
- Xint optind = 1;
- Xint optopt;
- Xchar *optarg;
- X
- Xint
- Xgetopt(argc, argv, opts)
- Xint argc;
- Xchar **argv, *opts;
- X{
- X static int sp = 1;
- X register int c;
- X register char *cp;
- X
- X if(sp == 1)
- X if(optind >= argc ||
- X argv[optind][0] != '-' || argv[optind][1] == '\0')
- X return(EOF);
- X else if(strcmp(argv[optind], "--") == NULL) {
- X optind++;
- X return(EOF);
- X }
- X optopt = c = argv[optind][sp];
- X if(c == ':' || (cp=index(opts, c)) == NULL) {
- X ERR(": illegal option -- ", c);
- X if(argv[optind][++sp] == '\0') {
- X optind++;
- X sp = 1;
- X }
- X return('?');
- X }
- X if(*++cp == ':') {
- X if(argv[optind][sp+1] != '\0')
- X optarg = &argv[optind++][sp+1];
- X else if(++optind >= argc) {
- X ERR(": option requires an argument -- ", c);
- X sp = 1;
- X return('?');
- X } else
- X optarg = argv[optind++];
- X sp = 1;
- X } else {
- X if(argv[optind][++sp] == '\0') {
- X sp = 1;
- X optind++;
- X }
- X optarg = NULL;
- X }
- X return(c);
- X}
- !FaR!OuT!
- if [ ! -d libtrw ]
- then
- mkdir libtrw
- echo mkdir libtrw
- fi
- echo x - libtrw/getunent.3
- sed -e 's/^X//' > libtrw/getunent.3 << '!FaR!OuT!'
- X.TH GETUNENT 3-ucb
- X.SH NAME
- Xgetunent, getunnam, setunent, endunent \- get universe file entry
- X.SH ORIGIN
- X4.2BSD
- X.SH SYNOPSIS
- X.nf
- X.B #include <local/universe.h>
- X.PP
- X.B struct universe *getunent()
- X.PP
- X.B struct universe *getunnam(name)
- X.B char *name;
- X.PP
- X.B int setunent()
- X.PP
- X.B int endunent()
- X.PP
- Xcc ... -ltrw
- X.fi
- X.SH DESCRIPTION
- X.I Getunent
- Xand
- X.I getunnam
- Xeach return a pointer to an object with the
- Xfollowing structure,
- Xcontaining the broken-out
- Xfields of a line in the universe file.
- X.RS
- X.PP
- X.nf
- X.so /usr/include/local/universe.h
- X.ft R
- X.ad
- X.fi
- X.RE
- X.PP
- X.I Getunent
- Xreads the next
- Xline (opening the file if necessary);
- X.I setunent
- Xrewinds the file;
- X.I endunent
- Xcloses it.
- X.PP
- X.I Getunnam
- Xsearches from the beginning until a matching
- X.I name
- Xis found
- X(or until EOF is encountered).
- X.SH FILES
- X/etc/u_universe
- X.SH AUTHOR
- XScott Simpson, TRW
- X.SH "SEE ALSO"
- Xu_universe(5)
- X.SH DIAGNOSTICS
- XNull pointer
- X(0) returned on EOF or error.
- X.SH BUGS
- XAll information
- Xis contained in a static area,
- Xso it must be copied if it is
- Xto be saved.
- !FaR!OuT!
- if [ ! -d libtrw ]
- then
- mkdir libtrw
- echo mkdir libtrw
- fi
- echo x - libtrw/getunent.c
- sed -e 's/^X//' > libtrw/getunent.c << '!FaR!OuT!'
- X/* Scott Simpson, TRW */
- X#include <stdio.h>
- X#include <local/universe.h>
- X
- Xstatic char UNIVERSE[] = "/etc/u_universe";
- Xstatic char EMPTY[] = "";
- Xstatic FILE *uf = NULL;
- Xstatic char line[BUFSIZ+1];
- Xstatic char name[80];
- Xstatic char univ[80];
- Xstatic struct universe universe;
- X
- Xsetunent()
- X{
- X if( uf == NULL )
- X uf = fopen(UNIVERSE, "r" );
- X else
- X rewind( uf );
- X}
- X
- Xendunent()
- X{
- X if( uf != NULL ){
- X fclose( uf );
- X uf = NULL;
- X }
- X}
- X
- Xstruct universe *
- Xgetunent()
- X{
- X register char *p;
- X if (uf == NULL) {
- X if( (uf = fopen( UNIVERSE, "r" )) == NULL )
- X return(0);
- X }
- X while (1) {
- X p = fgets(line, BUFSIZ, uf);
- X if (p==NULL)
- X return(0);
- X if (line[strlen(line)-1]=='\n')line[strlen(line)-1]='\0';
- X if (strlen(line) == 0 || line[0] == '#' || line[0] == ':')
- X continue;
- X if (sscanf(line, "%[^:]:%s", name, univ) != 2) {
- X return(0);
- X} else {
- X universe.un_name = &name[0];
- X universe.un_universe = &univ[0];
- X break;
- X }
- X }
- X return(&universe);
- X}
- X
- Xgetunnam(name)
- Xchar *name;
- X{
- X register struct universe *u;
- X
- X setunent();
- X while ( (u = getunent()) && strcmp(name,u->un_name) );
- X endpwent();
- X return(u);
- X}
- !FaR!OuT!
- if [ ! -d libtrw ]
- then
- mkdir libtrw
- echo mkdir libtrw
- fi
- echo x - libtrw/shift.3
- sed -e 's/^X//' > libtrw/shift.3 << '!FaR!OuT!'
- X.\" @(#)shift.3 1.1 (TRW) 11/15/83
- X.TH SHIFT 3 TRW
- X.UC
- X.SH NAME
- Xstring_downshift, string_upshift \- shift case of strings
- X.SH SYNOPSIS
- X.nf
- X.B char *string_downshift(s)
- X.B char *s;
- X
- X.B char *string_upshift(s)
- X.B char *s;
- X
- X.B cc ... -ltrw
- X.fi
- X.SH DESCRIPTION
- X.I String_downshift
- Xshifts
- X.I s
- Xin place to lowercase.
- X.I String_upshift
- Xshifts
- X.I s
- Xin place to uppercase.
- XBoth routines return
- X.I s.
- X.SH AUTHOR
- XMichael Gorlick, TRW
- X.SH SEE ALSO
- Xctype(3), string(3)
- !FaR!OuT!
- if [ ! -d libtrw ]
- then
- mkdir libtrw
- echo mkdir libtrw
- fi
- echo x - libtrw/shift.c
- sed -e 's/^X//' > libtrw/shift.c << '!FaR!OuT!'
- Xstatic char *trwsccs = "@(#)shift.c 1.1 (TRW) 1/14/86";
- X#include <ctype.h>
- X
- X/*
- X * Downshifts a string in place.
- X */
- Xchar *string_downshift(s)
- Xchar *s;
- X{
- X
- X register char *x = s;
- X for (; *x; x++)
- X if (isupper(*x))
- X *x = tolower(*x);
- X return(s);
- X}
- X
- X/*
- X * Upshifts a string in place.
- X */
- Xchar *string_upshift(s)
- Xchar *s;
- X{
- X
- X register char *x = s;
- X for (; *x; x++)
- X if (islower(*x))
- X *x = toupper(*x);
- X return(s);
- X}
- !FaR!OuT!
- if [ ! -d libtrw ]
- then
- mkdir libtrw
- echo mkdir libtrw
- fi
- echo x - libtrw/universe.h
- sed -e 's/^X//' > libtrw/universe.h << '!FaR!OuT!'
- Xstruct universe { /* see getunent(3) */
- X char *un_name;
- X char *un_universe;
- X};
- X
- Xstruct universe *getunent(), *getunnam();
- !FaR!OuT!
- exit
- --
- Scott Simpson
- TRW Electronics and Defense Sector
- ...{decvax,ihnp4,ucbvax}!trwrb!simpson
-
-
-