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.