DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download
Index: ┃ T i

⟦700da1188⟧ TextFile

    Length: 3842 (0xf02)
    Types: TextFile
    Names: »io.c«

Derivation

└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
    └─ ⟦this⟧ »EUUGD11/euug-87hel/sec1/news/misc/undig/io.c« 

TextFile

#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;
}