|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T x
Length: 6648 (0x19f8)
Types: TextFile
Names: »xalparse.c«
└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit
└─⟦aa80fdcbc⟧ »EurOpenD3/mail/ida.5.61.tar.Z«
└─⟦4314099ac⟧
└─⟦this⟧ »aux/xalparse.c«
/*
** XALPARSE -- Xaliases file parser.
** Copyright (c) 1987 Lennart Lovstrand
** CIS Dept, Univ of Linkoping, Sweden
**
** Use it, abuse it, but don't sell it.
*/
#include "useful.h"
#include <stdio.h>
#include <ctype.h>
#ifndef lint
static char SccsId[] = "@(#)xalparse.c 1.1 (lel@ida.liu.se) 4/12/87";
#endif !lint
struct alias {
bool a_in, a_out;
char *a_name;
};
#define ANULL (struct alias *) NULL
/*
** XPARSE -- Parse an xaliases file, producing aliases + generics files.
**
** This program parses a file in ``xaliases'' format, producing
** a standard aliases file + a generics file. The xaliases input
** file has entry of the following format:
** generic_list: mbox_list
** where elements in both lists are separated by commas. In
** addition, each element in the mbox_list may be prefixed with
** either or both of the ``redirection characters,'' "<" and ">".
** In its simplest form, the generic_list has just one member and
** the mbox_list uses no redirection characters. This
** corresponds exactly to the standard aliases format and
** function.
** The first extention is made by allowing more than one entry on
** the left hand side, thus making "a, b: c" as shorthand for the
** two entries "a: c" and "b: c".
** The second extension is made by adding the previously
** mentioned redirection characters to the addresses on the right
** hand side. These control in what direction the aliases should
** be used.
**
** etc.
*/
int iflag = FALSE, Iflag = FALSE, Oflag = FALSE;
main(argc, argv)
int argc;
char **argv;
{
extern int optind;
extern char *optarg;
char c;
FILE *xaliases, *aliases, *generics;
if (argc != 4) {
fprintf(stderr, "usage: %s xaliases aliases generics\n", argv[0]);
exit(1);
}
if (strcmp(argv[1], "-") == 0)
xaliases = stdin;
else {
xaliases = fopen(argv[1], "r");
if (xaliases == NULL)
perror(argv[1]), exit(2);
}
aliases = fopen(argv[2], "w");
if (aliases == NULL)
perror(argv[2]), exit(2);
generics = fopen(argv[3], "w");
if (generics == NULL)
perror(argv[3]), exit(2);
parsefile(xaliases, aliases, generics);
exit(0);
}
parsefile(xaliases, aliases, generics)
FILE *xaliases, *aliases, *generics;
{
extern char *index();
char line[BUFSIZ];
struct alias *rhs[BUFSIZ], *lhs[BUFSIZ];
struct alias **a, **r, **first;
while (readline(line, sizeof(line), xaliases) >= 0) {
parseline(line, lhs, rhs);
for (first = rhs; *first != ANULL; first++)
if ((*first)->a_in)
break;
if (*first != ANULL)
for (a = lhs; *a != ANULL; a++) {
fprintf(aliases, "%s:%s", (*a)->a_name, (*first)->a_name);
for (r = first+1; *r != ANULL; r++)
if ((*r)->a_in)
fprintf(aliases, ",%s", (*r)->a_name);
fprintf(aliases, "\n");
}
for (first = rhs; *first != ANULL; first++)
if ((*first)->a_out)
break;
if (*first != ANULL) {
fprintf(generics, "%s\t%s", lhs[0]->a_name, (*first)->a_name);
for (r = first+1; *r != ANULL; r++)
if ((*r)->a_out)
fprintf(generics, " %s", (*r)->a_name);
fprintf(generics, "\n");
}
freebufs(lhs, rhs);
}
}
/**
** PEEKC -- Return the next char to be read.
**/
peekc(stream)
FILE *stream;
{
int c;
c = getc(stream);
if (c != EOF)
ungetc(c, stream);
return c;
}
/**
** READLINE -- Read a (logical) line and return the # of chars read
**/
readline(buf, bufsiz, stream)
char *buf;
int bufsiz;
FILE *stream;
{
int len;
char *sharp;
if (fgets(buf, bufsiz, stream) == NULL)
return -1;
buf[strlen(buf)-1] = '\0';
/*
if ((sharp = index(buf, '#')) != NULL)
*sharp = '\0';
*/
if (buf[0] == '#')
buf[0] = '\0';
len = strlen(buf);
if (isspace(peekc(stream)))
return len + readline(&buf[len], bufsiz-len, stream);
else
return len;
}
/**
** PARSETHING
**/
#define LHS 1
#define RHS 2
char *
parsething(line, thing, side)
char *line;
struct alias **thing;
int side;
{
register char *s, *d;
register bool
insideroute = FALSE,
insidestring = FALSE,
quotedchar = FALSE;
bool i_mark, o_mark;
char buf[BUFSIZ];
extern char *malloc();
s = line;
d = buf;
while (*s != '\0' && isspace(*s)) s++;
if (side == RHS) {
if (o_mark = (*s == '<')) s++;
if (i_mark = (*s == '>')) s++;
i_mark = i_mark || !o_mark; /* default to '>' */
while (*s != '\0' && isspace(*s)) s++;
}
for (;*s != '\0'; s++) {
/* exit if non-quoted comma (or colon & LHS) */
if (!insidestring && !quotedchar && !insideroute &&
*s == ',' || ((side == LHS) && *s == ':'))
break;
/* copy if not unquoted whitespace */
if (insidestring || quotedchar || !isspace(*s))
*d++ = *s;
/* special quote character handling */
if (quotedchar)
quotedchar = FALSE;
else {
quotedchar = (*s == '\\');
if (!insidestring)
if (*s == '<')
insideroute = TRUE;
else if (*s == '>')
insideroute = FALSE;
if (*s == '"')
insidestring = !insidestring;
}
}
while (d > buf && isspace(d[-1])) d--;
*d = '\0';
if (d == buf && *s == '\0') {
*thing = ANULL;
return NULL;
} else {
*thing = (struct alias *) malloc(sizeof(struct alias));
(*thing)->a_in = i_mark;
(*thing)->a_out = o_mark;
(*thing)->a_name = malloc(strlen(buf) + 1);
strcpy((*thing)->a_name, buf);
return s;
}
}
/**
** PARSELINE
**/
parseline(line, lhs, rhs)
char *line;
struct alias **lhs, **rhs;
{
line--;
while ((line = parsething(line+1, lhs++, LHS)) != NULL)
if (*line == ':')
break;
*lhs = NULL;
if (line != NULL)
while ((line = parsething(line+1, rhs++, RHS)) != NULL);
*rhs = ANULL;
}
/**
** FREEBUFS
**/
freebufs(lhs, rhs)
struct alias **lhs, **rhs;
{
while (*lhs != ANULL) {
free((*lhs)->a_name);
free(*lhs);
lhs++;
}
while (*rhs != ANULL) {
free((*rhs)->a_name);
free(*rhs);
rhs++;
}
}
/**
** COMPRESSLINE -- Remove all heading & trailing whitespace around items.
**/
compressline(line)
char *line;
{
register char *d, *s, *b, *e;
for (d = s = line; *s != '\0'; s++) {
/* eat initial whitespace */
while (*s != '\0' && isspace(*s)) s++;
if (*s == '\0')
break;
/* remember beginning of "word" and find end */
b = s;
while (*s != '\0' && *s != ',' && *s != ':') s++;
e = s - 1;
/* backspace end thru whitespace */
while (e >= b && isspace(*e)) e--;
/* copy "word" w/o whitespace */
while (b <= e) *d++ = *b++;
/* copy separator */
*d++ = *s;
if (*s == '\0')
return;
}
*d = '\0';
}