#include #include "defs.h" #include "types.h" #include "exports.h" #include "file.h" #include "ciflex.h" #include "transforms.h" #define LAYER_COMM() \ { \ GetLayerName( layerName ); \ i = strlen( layerName ); \ if( i == 0 ) \ LexError( "Missing Layer Name", RECOVER ); \ else \ SetLayer( layerName ); \ } \ #define BOX_COMM() \ { \ a0 = GetNumber(0); \ if (a0 < 0) { \ LexError( "Negative length for box", RECOVER ); \ a0 = -a0; \ } \ a1 = GetNumber(0); \ if (a1 < 0) { \ LexError( "Negative width for box", RECOVER ); \ a1 = -a1; \ } \ a2 = GetNumber(0); \ a3 = GetNumber(0); \ token = GetToken(); \ if( token != ';') \ { \ a4 = GetNumber(token); \ a5 = GetNumber(0); \ token = GetToken(); \ } \ else \ { \ a4 = 1; \ a5 = 0; \ } \ AddBox( a0, a1, a2, a3, a4, a5 ); \ } \ #define WIRE_COMM() \ { \ a0 = GetNumber(0); \ if (a0 < 0) { \ LexError( "Negative width for wire", RECOVER ); \ a0 = -a0; \ } \ b1 = GetNumber(0); \ b2 = GetNumber(0); \ while (token != ';') { \ token = GetToken(); \ if (token != ';') { \ b3 = GetNumber(token); \ b4 = GetNumber(0); \ } \ else { \ b3 = b1; \ b4 = b2; \ } \ a1 = max(abs(b3 - b1), abs(b4 - b2)) + a0; \ a2 = (b3 + b1) / 2; \ a3 = (b2 + b4) / 2; \ if (a1 == a0) { \ a4 = 1; \ a5 = 0; \ } \ else { \ a4 = abs(b4 - b2); \ a5 = abs(b3 - b1); \ } \ AddBox(a0, a1, a2, a3, a4, a5); \ b1 = b3; \ b2 = b4; \ } \ } \ #define DS_COMM() \ { \ cellNum = GetNumber(0); \ if( cellNum < 0 ) { \ LexError( \ "Negative cell number made positive", \ RECOVER ); \ cellNum = -cellNum; \ } \ token = GetToken(); \ if( token != ';') \ { \ a0 = GetNumber(token); \ a1 = GetNumber(0); \ if(( a0 == 0 ) || ( a1 == 0 )) { \ LexError( "Illegal scale--set to 1", RECOVER ); \ a0 = 1; \ a1 = 1; \ } \ token = GetToken(); \ } \ else \ { \ a0 = a1 = 1; \ } \ DefineCell( cellNum, a0, a1 ); \ } \ #define MIRROR_COMM() \ { \ token = GetToken(); \ if( token == 'X' ) \ { \ ctm[ 0 ] = -ctm[ 0 ]; \ ctm[ 2 ] = -ctm[ 2 ]; \ ctm[ 4 ] = -ctm[ 4 ]; \ } \ else if( token == 'Y' ) \ { \ ctm[ 1 ] = -ctm[ 1 ]; \ ctm[ 3 ] = -ctm[ 3 ]; \ ctm[ 5 ] = -ctm[ 5 ]; \ } \ else \ LexError( "Expected X or Y", RECOVER ); \ } \ #define TRANSLATE_COMM() \ { \ a0 = GetNumber(0); \ a1 = GetNumber(0); \ ctm[ 4 ] += (Real) a0; \ ctm[ 5 ] += (Real) a1; \ } \ #define ROTATE_COMM() \ { \ static Real a, b, tmp; \ \ a0 = GetNumber(0); \ a1 = GetNumber(0); \ if( a0 != 0 and a1 != 0 ) { \ LexError( "Only 90 degree rotations supported", RECOVER ); \ flag = TRUE; \ } \ else if( a0 + a1 == 0 ) { \ LexError( "Can't rotate by (0,0)", RECOVER ); \ flag = TRUE; \ } \ else \ { \ a = ( a0 == 0 ) ? 0.0 : (( a0 < 0 ) ? -1.0 : 1.0); \ b = ( a1 == 0 ) ? 0.0 : (( a1 < 0 ) ? -1.0 : 1.0); \ tmp = ctm[ 0 ] * a - ctm[ 1 ] * b; \ ctm[ 1 ] = ctm[ 0 ] * b + ctm[ 1 ] * a; \ ctm[ 0 ] = tmp; \ tmp = ctm[ 2 ] * a - ctm[ 3 ] * b; \ ctm[ 3 ] = ctm[ 2 ] * b + ctm[ 3 ] * a; \ ctm[ 2 ] = tmp; \ tmp = ctm[ 4 ] * a - ctm[ 5 ] * b; \ ctm[ 5 ] = ctm[ 4 ] * b + ctm[ 5 ] * a; \ ctm[ 4 ] = tmp; \ } \ } \ public void ParseCif( fname ) char *fname; { int fin, i, flag; char token, c; int cellNum, commLevel; Tmatrix ctm; int a0, a1, a2, a3, a4, a5; int b1, b2, b3, b4; char fileBuff[ BUFSIZ ]; int lexBuff[ 256 ]; char layerName[ 5 ]; if( (fin = InitLexer( fname, fileBuff, lexBuff )) < 0 ) Crash( "can not open cif file '%s'\n", 1, fname ); InitCells(); InitCtm( ctm ); for(;;) { token = GetToken(); switch( token ) { case EO_FILE : LexError( "Premature End of File", FATAL ); break; case '(' : PassComment(); token = GetToken(); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': LexError( "Unsupported user-extension", RECOVER ); i = ParseUserArgs(); token = *tokens[ i ]; break; case '9': i = ParseUserArgs(); UserExtension(token - '0', tokens, i ); token = *tokens[ i ]; break; case ';' : break; case 'R' : LexError( "RoundFlash not supported", RECOVER ); token = CifSkip(); break; case 'W' : WIRE_COMM(); break; case 'P' : LexError( "Polygon not supported", RECOVER ); token = CifSkip(); break; case 'L' : LAYER_COMM(); token = GetToken(); break; case 'B' : BOX_COMM(); break; case 'E' : close( fin ); if( cifErrs != 0 ) printf("(%d errors occurred: check CIF and PostScript)\n", cifErrs); return; case 'D' : token = GetToken(); switch( token ) { case 'F' : CloseCell(); token = GetToken(); break; case 'D' : cellNum = GetNumber(0); if( cellNum < 0 ) { LexError( "Negative cell number made positive", RECOVER ); cellNum = -cellNum; } UnDefCell( cellNum ); token = GetToken(); break; case 'S' : DS_COMM() break; default : LexError( "Unknown DEF command", RECOVER ); token = CifSkip(); } break; case 'C' : flag = FALSE; cellNum = GetNumber(0); if( cellNum < 0 ) { LexError( "Negative cell number made positive", RECOVER ); cellNum = -cellNum; } token = GetToken(); while( token != ';' and token != EO_FILE ) { switch( token ) { case 'M' : MIRROR_COMM(); break; case 'T' : TRANSLATE_COMM(); break; case 'R' : ROTATE_COMM(); break; default : LexError( "Unknown Transformation", RECOVER ); } token = GetToken(); } if (flag == FALSE) CallCell( cellNum, ctm ); InitCtm( ctm ); break; default : LexError( "Unknown Command", RECOVER ); token = CifSkip(); } if( token != ';' ) { LexError( "Missing Semicolon", RECOVER ); token = CifSkip(); } } } private UserExtension( ext, args, nargs ) int ext; char *args[]; int nargs; { if( strcmp(args[0],"4") == 0) { if( nargs < 4 or nargs > 5 ) LexError( "Wrong number of arguments", RECOVER ); else AddLabel( args[ 1 ], atoi( args[ 2 ] ), atoi( args[ 3 ] ) ); } else if( nargs != 1 ) LexError( "Wrong number of arguments", RECOVER ); else NameCell( args[ 0 ] ); }