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