/* * Interface to unix's read function. Provide for buffered input files. */ #include "defs.h" public #include public #include public #define ENDOFFILE 0 /* return value for GetChar on end-of-file */ public typedef struct /* open file information */ { int fd; /* file descriptor */ int nChars; /* characters left in buffer */ char *buffp; /* pointer to next char. in buffer */ char *buff; /* begining address of the buffer */ } File; /* * Open a file for reading, return the file descriptor as obtained from open. */ public int OpenFile( fname, buff, file ) char *fname; char *buff; File *file; { file->fd = open( fname, O_RDONLY, 0 ); file->buff = buff; file->buffp = buff; file->nChars = 0; return( file->fd ); } /* * A lot of data gets read during CIF parsing: inline this procedure */ public #define GetChar( c, f ) \ { \ if( --(f).nChars >= 0 ) \ c = *(f).buffp++; \ else \ { \ (f).nChars = read( (f).fd, (f).buff, BUFSIZ ); \ if( (f).nChars > 0 ) \ { \ (f).buffp = (f).buff; \ (f).nChars--; \ c = *(f).buffp++; \ } \ else \ c = ENDOFFILE; \ } \ } \ public #define UngetChar( f ) (f).buffp--; (f).nChars++ public #define CloseFile( f ) close( (f).fd ) /* * Move back in the file to find the begining of the current line. Display * the line in question and a pointer to the current position within the line * Then restore the file buffer to its initial state. */ public int PrintErrLine( f ) File *f; { char *cp, c; int col, nc; long fpos, savePos; char *buff; File f1; savePos = fpos = BUFSIZ * ((lseek( f->fd, 0, L_INCR ) - 1) / BUFSIZ); cp = f->buffp; nc = f->nChars; buff = f->buff; if( *cp == '\n' ) { cp--; nc++; } for( col = 0; *cp != '\n' and cp > buff; cp--, col++, nc++ ); while( *cp != '\n' and fpos >= BUFSIZ ) { fpos -= BUFSIZ; (void) lseek( f->fd, fpos, L_SET ); (void) read( f->fd, buff, BUFSIZ ); col++; for( cp = buff+BUFSIZ-1; cp > buff and *cp != '\n'; cp--, col++ ); nc = buff + BUFSIZ - cp; } if( *cp == '\n' ) { cp++; col--; nc--; } f1.fd = f->fd; f1.buff = f->buff; f1.nChars = nc; f1.buffp = cp; do { GetChar( c, f1 ); fputc( c, stderr ); } while( c != '\n' and c != ENDOFFILE ); if( c != '\n' ) fputc( '\n', stderr ); /* put it back the way you found it */ (void) lseek( f->fd, savePos, L_SET ); (void) read( f->fd, buff, BUFSIZ ); return( col ); }