#include #include "defs.h" #include "types.h" #include "exports.h" #include "file.h" /* Check with .pro file (definition of DefPatt) before increasing MAXLAYERS. */ /* current implementation of cif2ps.pro prevents making MAXLAYERS > 36. */ #define MAXLAYERS 30 /* A ridiculously large number of layers */ typedef enum { EOFILE, SPACE, NEWLN, ALPHA, DIGIT, QUOTE, HEXDIGIT } lexTypes; private Layer layerTable[ MAXLAYERS ]; public int nLayer; public Layer layer[ MAXLAYERS ]; public int totRects[ MAXLAYERS ]; public SpecialLayers specialLayers = { TRUE, TRUE, TRUE, TRUE }; /* * Return a pointer to layer 'name'. If not found and 'add' is TRUE then * a new record is initialized and added to the list (hash-table), otherwise * a NULL is returned upon failure. */ public Layer GetLayer( name, add ) char *name; int add; { Layer lay; int i, t; char *sp; sp = name; for( t = *sp++, i = 1; *sp != '\0'; sp++, i++ ) t += *sp * i; t = t % MAXLAYERS; lay = layerTable[ t ]; while( lay != NULL ) { if( !strcmp( lay->name, name ) ) return( lay ); lay = lay->next; } if( add ) { if( (lay = (Layer) Malloc( sizeof( LayerRec ) )) == NULL ) Crash( "Out of memory for stipple-patterns", 2 ); strcpy( lay->name, name ); lay->skip = FALSE; lay->next = layerTable[ t ]; layerTable[ t ] = lay; } return( lay ); } /* * Return TRUE if the stipple-patern for layer in question is * visible (any of its bits are on). */ public int IsVisible( layNum ) int layNum; { register unsigned int *patp, *patend; patp = layer[ layNum ]->pat; for( patend = &(patp[7]); patp <= patend; patp++ ) { if( *patp != 0 ) return( TRUE ); } return( FALSE ); } private lexTypes *lexChars; private File fin; private char nameBuff[ 5 ]; private unsigned lexNum; private int nLine; /* * Parse the stipple-pattern file and initialize the layer data-structure. */ public void ReadPatterns( fname, usrLayers ) char *fname; char *usrLayers; { lexTypes lex, GetToken(); lexTypes cBuff[ 256 ]; char fileBuff[ BUFSIZ ]; int n; Layer lay; if( OpenFile( fname, fileBuff, &fin ) < 0 ) Crash( "can not open pattern file '%s'\n", 1, fname ); InitLexer( cBuff ); nLayer = 0; while( (lex = GetToken()) != EOFILE ) { if( nLayer >= MAXLAYERS ) Crash( "More than %d layers in %s\n", MAXLAYERS, 1, fname ); if( lex != ALPHA ) LexError( "Expected quoted layer name" ); if( !strcmp( nameBuff, "COLOR" )) { color = TRUE; continue; } if( strlen( nameBuff ) > 4 ) LexError( "Layer names should be at most 4 characters" ); lay = GetLayer( nameBuff, TRUE ); if( strcmp( nameBuff, lay->name ) ) fprintf( stderr, "warning:\"%s\" repeated in '%s'\n", nameBuff, fname ); lay->num = nLayer++; for( n = 0; n < 8; n++ ) { if( (lex = GetToken()) != DIGIT ) LexError( "Expected pattern number" ); lay->pat[ n ] = lexNum; } layer[ lay->num ] = lay; if( color == TRUE ) for( n = 0; n < 4; n++ ) { if( (lex = GetToken()) != DIGIT ) LexError( "Expected color component" ); lay->color[ n ] = (float)lexNum / 256; } } CloseFile( fin ); if( usrLayers ) SetOptions( usrLayers ); } /* * Parse and set the layers as requested by command-line argument '-l'. */ private SetOptions( usrLayers ) char *usrLayers; { register char *p; register Layer lay; int n; p = usrLayers; while( *usrLayers != '\0' ) { while( *p != ',' and *p != '\0' ) p++; if( *p ) *p++ = '\0'; if( !strcmp( usrLayers, "-" ) ) { for( n = 0; n < MAXLAYERS; n++ ) { lay = layerTable[ n ]; while( lay ) { lay->skip ^= 1; lay = lay->next; } } specialLayers.pointName ^= 1; specialLayers.symbolName ^= 1; specialLayers.bbox ^= 1; specialLayers.outline ^= 1; } else if( !strcmp( usrLayers, "allText" ) ) { specialLayers.pointName ^= 1; specialLayers.symbolName ^= 1; } else if( !strcmp( usrLayers, "bbox" ) ) specialLayers.bbox ^= 1; else if( !strcmp( usrLayers, "outline" ) ) specialLayers.outline ^= 1; else if( !strcmp( usrLayers, "pointName" ) ) specialLayers.pointName ^= 1; else if( !strcmp( usrLayers, "symbolName" ) ) specialLayers.symbolName ^= 1; else if( !strcmp( usrLayers, "text" ) ) ; else { lay = GetLayer( usrLayers, FALSE ); if( lay == NULL ) { fprintf( stderr, "warning:%s is not a pattern\n", usrLayers ); fprintf( stderr, " Acceptable global layers are:\n"); fprintf( stderr, "\t allText\n\t bbox\n\t outline \ \n\t pointName\n\t symbolName\n\t text\n"); } else lay->skip ^= 1; } usrLayers = p; } } private lexTypes GetToken() { char c, c1, *buffp; unsigned n; int base; for(;;) { GetChar( c, fin ); switch( lexChars[ c ] ) { case EOFILE : return( EOFILE ); break; case NEWLN : nLine++; case SPACE : break; case QUOTE : buffp = nameBuff; GetChar( c, fin ); while( lexChars[ c ] == ALPHA or lexChars[ c ] == DIGIT ) { *buffp++ = c; GetChar( c, fin ); } *buffp = '\0'; if( c != '"' ) LexError( "Unmatched '\"'" ); return( ALPHA ); break; case ALPHA : case HEXDIGIT : LexError( "Unquoted Layer Name" ); break; case DIGIT : if( c == '0' ) { GetChar( c, fin ); if( c == 'x' ) { GetChar( c, fin ); c = c | 0x20; base = 16; } else base = 8; } else base = 10; n = 0; while( lexChars[ c ] == DIGIT or lexChars[ c ] == HEXDIGIT ) { if( base == 16 and lexChars[ c ] == HEXDIGIT ) n = n * 16 + c - 'a' + 0xa; else if( c - '0' < base ) n = n * base + c - '0'; else LexError( "Improper number" ); GetChar( c1, fin ); c = c1 | 0x20; } lexNum = n; if( lexChars[ c1 ] == NEWLN ) nLine++; return( DIGIT ); break; } } } private LexError( msg ) char *msg; { int n; char buff[ 512 ]; long a1, a2; fprintf( stderr, "Error in pattern file: line # %d: %s:\n", nLine, msg ); n = PrintErrLine( &fin ); while( --n > 0 ) fputc( '-', stderr ); Crash( "^\n", 1 ); } private InitLexer( buff ) lexTypes *buff; { register c; lexChars = buff; for( c = 0; c < 256; c++ ) lexChars[ c ] = SPACE; for( c = 'A'; c <= 'Z'; c++ ) lexChars[ c ] = ALPHA; for( c = '0'; c <= '9'; c++ ) lexChars[ c ] = DIGIT; for( c = 'a'; c <= 'f'; c++ ) lexChars[ c ] = HEXDIGIT; lexChars[ '"' ] = QUOTE; lexChars[ '\n' ] = NEWLN; lexChars[ ENDOFFILE ] = EOFILE; nLine = 1; }