plt - Software for 2D Plots 2.5
(4,758 bytes)
/* plt/optn3.c Paul Albrecht Sept 1987
Copyright (C) Paul Albrecht 1988. All rights reserved.
Last Update: May 21, 1989
EMACS_MODES: tabstop=4
*/
#include "plt.h"
#include "optn.h"
#include <ctype.h>
#define MAXOLEV 6
#define INFILE 01
#define STRING 02
static struct {
int type;
FILE *fp;
char *sp;
char *name;
short line;
Boolean lock;
} input[MAXOLEV], *in;
static short nilev = 0;
in_file( name, lock )
char *name;
Boolean lock;
{
if( nilev == MAXOLEV )
err( YES, "Too many nested input streams" );
in = &input[nilev];
in->fp = fopen( name, "r" );
if( in->fp == NULL )
err( YES, "Can't read file `%s'", name );
in->type = INFILE;
in->name = name;
in->line = 0;
in->lock = lock;
nilev++;
}
in_string( string, lock )
char *string;
Boolean lock;
{
if( nilev == MAXOLEV )
err( YES, "Too many nested input streams" );
in = &input[nilev];
in->type = STRING;
in->sp = string;
in->name = "format string";
in->line = 0;
in->lock = lock;
nilev++;
}
in_close( nlev )
short nlev;
{
if( nlev < -1 || nlev > nilev )
nlev = nilev;
while( nlev-- > 0 ) {
nilev--;
if( input[nilev].type == INFILE )
fclose( input[nilev].fp );
}
in = &input[nilev-1];
return( nilev );
}
/************************************************************************/
in_char()
{
short c;
if( nilev == 0 )
return( EOF );
switch( in->type ) {
case INFILE: c = getc( in->fp );
break;
case STRING: c = *in->sp;
if( c == 0 )
c = EOF;
else
in->sp++;
break;
}
if( c == EOF && !in->lock ) {
in_close( (short)1 );
return( in_char() );
}
else
return( c );
}
in_unchar( c )
short c;
{
if( c != EOF ) {
switch( in->type ) {
case INFILE: ungetc( c, in->fp );
break;
case STRING: in->sp--;
break;
}
}
}
/************************************************************************/
in_parse( s, maxflds, obj, maxchrs )
short maxflds, maxchrs;
char *s[], *obj;
{
short status, nflds, nchrs, n;
status = nflds = 0;
while( nflds < maxflds && !(status & END_LINE) ) {
status = in_obj( obj, maxchrs, IN_OBJ );
if( status & HAVE_OBJ ) {
if( nflds == maxflds )
err( YES, "Too many fields" );
s[nflds++] = StringSave( obj );
nchrs = strlen( obj );
obj += (nchrs + 1);
maxchrs -= (nchrs + 1);
}
}
if( optn ) {
eprintf( "PARSE:" );
for( n=0; n < nflds; n++ )
eprintf( " (%s)", s[n] );
eprintf( "\n" );
}
return( nflds );
}
/*********************************************************************/
in_obj( obj, maxchrs, mode )
char *obj;
short maxchrs;
Const mode;
{
register short nchrs, c;
short shield, quote, first, nbrack, status, more, outchar;
shield = NO;
more = first = YES;
status = nbrack = quote = nchrs = 0;
if( mode & DEL_SPACE ) {
do { c = in_char();
switch( c ) {
case '\t':
case ' ': break;
case '\n': if( !(mode & SKIP_CR) )
more = NO;
break;
default: more = NO;
break;
}
} while( more && c != EOF );
}
else
c = in_char();
do {
outchar = NO;
switch( (c!= EOF && shield) ? 0 : c ) {
case 0: if( quote != 0 ) {
if( quote == c ) {
shield = NO;
quote = 0;
}
else
outchar = YES;
}
else {
shield = NO;
outchar = YES;
}
break;
case '\\': if( !(mode & VERBATIM) )
shield = YES;
break;
case '"':
case '\'': if( !(mode & VERBATIM) && quote == 0 ) {
shield = YES;
quote = c;
}
break;
case '{': nbrack++;
break;
case '}': if( nbrack == 0 )
err( NO, "Stray '}' -- line %d of %s\n", in->line, in->name );
if( --nbrack == 0 )
status |= END_INPUT;
break;
case ';': if( mode & SEMI_TERM ) {
if( mode & SAVE_TERM )
in_unchar( c );
status |= END_LINE;
}
else
outchar = YES;
break;
case '\n': if( !(mode & SKIP_CR) ) {
if( mode & SAVE_TERM )
in_unchar( c );
status |= END_LINE;
}
break;
case '\t':
case ' ': if( mode & SPACE_DELIM )
status |= HAVE_OBJ;
else
outchar = YES;
break;
case EOF: status |= (END_LINE|END_INPUT);
break;
default: outchar = YES;
break;
}
if( outchar ) {
if( maxchrs > 1 ) {
obj[nchrs++] = c;
maxchrs--;
}
else {
if( first ) {
err( NO, "Line `%.25s...' too long", obj );
first = NO;
}
}
}
if( status == 0)
c = in_char();
} while( status == 0 );
if( nbrack > 0 )
err( NO, "Missing '}' for `%.10s...'\n", obj );
if( nchrs > 0 )
status |= HAVE_OBJ;
obj[nchrs] = 0;
if( optn )
eprintf( "OBJECT: (%s)\n", obj );
if( quote )
err( NO, "Unmatched quote in format specification" );
return( status );
}