|
|
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 i
Length: 3842 (0xf02)
Types: TextFile
Names: »io.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
└─⟦this⟧ »EUUGD11/euug-87hel/sec1/news/misc/undig/io.c«
#include "undig.h"
FILE *infp= NULL; /* Input file pointer. */
/* Memory allocation. */
char *
getmem(n)
int n;
{
char *p= malloc(n);
if (p == NULL)
fatal("out of memory");
return p;
}
/* Create a new line object. */
struct line *
grabline(indent, text)
int indent;
char *text;
{
struct line *p= (struct line *) getmem(sizeof(struct line));
p->indent= indent;
p->text= text;
p->next= NULL;
return p;
}
/* Free the memory held by a line object and its followers. */
freeline(p)
struct line *p;
{
struct line *q;
while (p != NULL) {
q= p->next;
if (p->text != NULL)
free(p->text);
free((char *)p);
p= q;
}
}
/* Input a text line, return a new struct line object. */
struct line *
getline()
{
struct line *p;
char buf[BUFSIZ];
char *cp, *cq;
int i, len;
if (fgets(buf, sizeof buf, infp) == NULL)
return NULL;
i= 0;
for (cp= buf; *cp == ' ' || *cp == '\t'; ++cp) {
if (*cp == '\t')
i= (i/TABSTOP + 1) * TABSTOP;
else /* *cp == ' ' */
++i;
}
cq= index(cp, '\n');
if (cq != NULL) {
while (cq > cp && isspace(cq[-1]))
--cq;
len= cq-cp;
}
else {
int c;
len= strlen(cp);
while ((c= getc(infp)) != '\n' && c != EOF)
;
}
if (len > 0) {
cp[len]= EOS;
cq= getmem(len+1);
strcpy(cq, cp);
}
else {
i= 0;
cq= NULL;
}
return grabline(i, cq);
}
/* Read the next text block. */
getblock(bp)
struct block *bp;
{
struct line *p;
struct line **pp;
bp->top= NULL;
bp->lead= 0;
pp= &bp->top;
bp->class= EOF; /* Default */
for (;;) {
bp->seekaddr= ftell(infp);
p= getline();
if (p == NULL)
return;
if (p->text != 0)
break;
freeline(p);
++bp->lead;
}
for (;;) {
*pp= p;
pp= &p->next;
p= getline();
if (p == NULL)
break;
if (p->text == NULL) {
freeline(p);
ungetc('\n', infp);
break;
}
}
bp->class= classify(bp->top);
}
/* Classify a text block. */
int
classify(p)
struct line *p;
{
bool subject= NO;
bool from= NO;
if (p == NULL)
return EOF;
do {
if (!isheader(p))
return TEXT;
if (strncmp("Subject:", p->text, 8) == 0)
subject= YES;
else if (strncmp("From:", p->text, 5) == 0)
from= YES;
do {
p= p->next;
if (p == NULL)
break;
} while (iscont(p));
} while (p != NULL);
if (from || subject)
return HEADER;
else
return TEXT; /* Garbage conforming to header syntax. */
}
bool
isheader(p)
struct line *p;
{
char *cp;
if (p == NULL || p->indent != 0 || p->text == NULL)
return NO;
cp= p->text;
while (isalnum(*cp) || *cp == '-' || *cp == '.')
++cp;
return *cp == ':' && isspace(cp[1]);
}
bool
iscont(p)
struct line *p;
{
return p != NULL && p->indent > 0;
}
/* Output routine. (Should skip uninteresting headers.) */
bool nospace= NO;
/* Output a text block. */
bool
putblock(bp)
struct block *bp;
{
int i;
struct line *p;
if (!nospace) {
p= grabline(0, (char *) NULL);
for (i= bp->lead; --i >= 0;) {
if (!pageline(p))
return NO;
}
freeline(p);
}
if (bp->class == HEADER) {
for (p= bp->top; p != NULL; ) {
bool ok= interesting(p);
for (;;) {
if (ok && !pageline(p))
return NO;
p= p->next;
if (p == NULL || !iscont(p))
break;
}
}
}
else {
for (p= bp->top; p != NULL; p= p->next) {
if (!pageline(p))
return NO;
}
}
return YES;
}
/* Table giving headers that we want to skip. */
char *uninteresting[]= {
"Approved:",
"Article-I.D.:",
"Date-Received:",
"Distribution:",
"Lines:",
"Message-ID:",
"Newsgroups:",
"Organization:",
"Path:",
"Posted:",
"References:",
"Relay-Version:",
"Sender:",
NULL
};
/* Interesting headers are those not in the above list. */
bool
interesting(p)
struct line *p;
{
int i;
for (i= 0; uninteresting[i] != NULL; ++i) {
if (strncmp(uninteresting[i], p->text,
strlen(uninteresting[i])) == 0)
return NO;
}
return YES;
}