This is mifread.c in view mode; [Download] [Up]
/* mifread.c
* cm, 17 Dec 90
*
* HISTORY
* 28 May 92, neek: Added support for include swapping the current
* IOstream w/ a temporary one, for @include functionality.
*
*
* read/parse FrameMaker files
* external entry points:
* mif_open(): open the file to filter, validate file type.
* mif_gets(): returns the next line (Null replaces newline) from file.
* mif_getc(): returns the next byte from file.
* mif_ungetc(): place previously read char back on input stream.
* mif_close(): close specified file.
* mif_lineno(): returns value of the current line number in input stream.
*/
/*
* Copyright (c) 1991 Carnegie Mellon University
* All Rights Reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie Mellon
* the rights to redistribute these changes.
*/
#include <stdio.h>
#include <errno.h>
#include <sys/file.h>
#include <mif.h>
#define BLKSIZE (1024*4)
#define MAX_TMP_STREAMS 12
typedef struct
{
char rbuf[BLKSIZE]; /* read buffer */
char fname[256]; /* file name */
char *rp; /* current point in read buffer */
char *erp; /* current end of read buffer */
int rfd; /* read file descriptor */
int lineno; /* current line no. of file */
char eof; /* true if end of stream hit */
} IOstream;
static IOstream streams[4]; /* mif, bib, ref, tmp files */
static IOstream streamstack[MAX_TMP_STREAMS];
int stacktop;
/* open input file for processing (.mif file )
* return 1 on success, 0 on failure.
*/
mif_open( type, fname )
register char *fname;
{
register IOstream *sp;
sp = &streams[type];
if( (sp->rfd = open( fname, O_RDONLY)) < 0 )
{
err( WARN, "Can't open <%s>, errno=%d\n",
fname, errno );
return(0);
}
sp->lineno = 1;
sp->eof = 0;
strcpy( sp->fname, fname );
return(1);
}
/* close the current .mif input file
*/
mif_close(type)
{
IOstream *sp;
sp = &streams[type];
close(sp->rfd);
}
/* push the current IOstream onto a stack */
mif_push_readcontext(type)
{
if( stacktop == MAX_TMP_STREAMS )
return(0);
copy_streams(&streamstack[stacktop], &streams[type]);
stacktop++;
return(1);
}
/* pop the next IOstream from the stack */
mif_pop_readcontext(type)
{
if( stacktop == 0 )
return(0);
stacktop--;
copy_streams(&streams[type], &streamstack[stacktop]);
return(1);
}
static
copy_streams( dp, sp )
register IOstream *dp; /* destination */
register IOstream *sp; /* source */
{
bcopy( sp->rbuf, dp->rbuf, BLKSIZE );
strcpy( dp->fname, sp->fname );
dp->rp = sp->rp;
dp->erp = sp->erp;
dp->rfd = sp->rfd;
dp->lineno = sp->lineno;
dp->eof = sp->eof;
}
/* read next line from mif file buffer.
* if necessary, read from file. Return pointer to
* next line, or NULL if at end of file.
*/
char *
mif_gets(type, dest)
register char *dest;
{
char *retp;
int n;
register IOstream *sp;
sp = &streams[type];
if( sp->eof ) return( (char *)0);
if( sp->rp >= sp->erp )
{
n=mif_readbuf(sp);
if( n == 0 ) /* eof */
{
sp->eof = 1;
return( (char *) 0 );
}
}
retp = sp->rp;
sp->rp += strlen( sp->rp ) + 1;
sp->lineno++;
strcpy( dest, retp );
return( retp );
}
/* pass pointer to the next char in input stream.
* read in another buffer if necessary.
* return NULL if at end of file.
*/
char *
mif_getc(type)
{
char *retp;
int n;
register IOstream *sp;
sp = &streams[type];
if( sp->eof ) return( (char *)0);
if( sp->rp >= sp->erp )
{
n=mif_readbuf(sp);
if( n == 0 ) /* eof */
{
sp->eof = 1;
return( (char *) 0 );
}
}
retp = sp->rp;
if( *retp == 0 )
sp->lineno++;
sp->rp++;
return( retp );
}
/* decrement input stream pointer */
mif_ungetc(type)
{
register IOstream *sp;
sp = &streams[type];
sp->rp--;
if( *(sp->rp) == 0 )
sp->lineno--;
}
/* read into read buffer at specified location, as much as
* will fill the input buffer. Assure we've ended on an
* even newline, to ease the parsing. Replace all newlines
* w/ 0.
*/
static int
mif_readbuf(sp)
register IOstream *sp;
{
register dec;
register char *cp;
int n;
if((n=read( sp->rfd, sp->rbuf, BLKSIZE )) < 0 )
err( FATAL, "Fatal read on .mif file, errno=%d\n",
errno );
/* bailout if eof */
if( n == 0 )
return( 0 );
sp->rp = sp->rbuf;
sp->erp = sp->rp+n;
/* assure read ends on even newline
*/
for( cp = sp->erp-1; (cp>sp->rbuf) && (*cp != '\n'); cp-- )
; if ( dec = cp - sp->erp + 1 ) { sp->erp += dec;
if( lseek( sp->rfd, dec, L_INCR ) < 0 )
err( FATAL, "lseek failed on mif file, errno=%d\n",
errno );
}
/* change newlines to nulls for easy string retrieval
*/
for(cp=sp->rbuf; cp<sp->erp; cp++)
if( *cp == '\n' )
*cp=0;
return(sp->erp - sp->rbuf);
}
mif_lineno(type)
{
register IOstream *sp;
sp = &streams[type];
return( sp->lineno );
}
char *
mif_filename(type)
{
register IOstream *sp;
sp = &streams[type];
return( sp->fname );
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.