Commit e0a1cc68 authored by dickelbeck's avatar dickelbeck
Browse files

more specctra dsn work

parent ba3b2934
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -280,7 +280,7 @@ const static KEYWORD tokens[] = {
    TOKDEF(place_rule),
    TOKDEF(plan),
    TOKDEF(plane),
    TOKDEF(PN),
    TOKDEF(pn),
    TOKDEF(point),
    TOKDEF(polygon),
    TOKDEF(position),
+1 −1
Original line number Diff line number Diff line
@@ -280,7 +280,7 @@ enum DSN_T {
    T_place_rule,
    T_plan,
    T_plane,
    T_PN,
    T_pn,
    T_point,
    T_polygon,
    T_position,
+221 −57
Original line number Diff line number Diff line
@@ -604,10 +604,15 @@ public:
};


/**
 * Class KEEPOUT
 * is used for <keepout_descriptor> and <plane_descriptor>.
 */
class KEEPOUT : public ELEM
{
    friend class SPECCTRA_DB;

protected:    
    std::string     name;
    int             sequence_number;
    RULES*          rules;
@@ -942,6 +947,132 @@ public:
};


class PLANE : public KEEPOUT
{
    friend class SPECCTRA_DB;

public:    
    PLANE( ELEM* aParent ) :
        KEEPOUT( aParent, T_plane )
   {}
};


/**
 * Class TOKPROP
 * is a container for a single property whose value is another DSN_T token.
 * The name of the property is obtained from the DSN_T Type().
 */
class TOKPROP : public ELEM
{
    friend class SPECCTRA_DB;

    DSN_T       value;

public:

    TOKPROP( ELEM* aParent, DSN_T aType ) :
        ELEM( aType, aParent )
    {
    }
    
    void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
    {
        out->Print( nestLevel, "(%s %s)\n", LEXER::GetTokenText( Type() ),
                   LEXER::GetTokenText( value ) );
    }
};


/**
 * Class STRINGPROP
 * is a container for a single property whose value is a string.
 * The name of the property is obtained from the DSN_T.
 */
class STRINGPROP : public ELEM
{
    friend class SPECCTRA_DB;

    std::string     value;

public:

    STRINGPROP( ELEM* aParent, DSN_T aType ) :
        ELEM( aType, aParent )
    {
    }
    
    void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
    {
        const char* quote_char = out->GetQuoteChar( value.c_str() );
        
        out->Print( nestLevel, "(%s %s%s%s)\n", LEXER::GetTokenText( Type() ),
                                quote_char, value.c_str(), quote_char );
    }
};


class REGION : public ELEM
{
    friend class SPECCTRA_DB;

    std::string     region_id;

    //-----<mutually exclusive>--------------------------------------
    RECTANGLE*      rectangle;
    PATH*           polygon;
    //-----</mutually exclusive>-------------------------------------

    STRINGPROP*     region_data;  ///< region_net | region_class | region_class_class
    RULES*          rules;    

public:
    REGION( ELEM* aParent ) :
        ELEM( T_region, aParent )
    {
        rectangle = 0;
        polygon = 0;
        region_data = 0;
        rules = 0;
    }

    ~REGION()
    {
        delete rectangle;
        delete polygon;
        delete region_data;
        delete rules;
    }
    
    void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
    {
        out->Print( nestLevel, "(%s", LEXER::GetTokenText( Type() ) );
        
        if( region_id.size() )
        {
            const char* quote = out->GetQuoteChar( region_id.c_str() );
            out->Print( 0, " %s%s%s", quote, region_id.c_str(), quote );
        }
        
        out->Print( 0, "\n" );
        
        if( rectangle )
            rectangle->Format( out, nestLevel+1 );
        
        if( polygon )
            polygon->Format( out, nestLevel+1 );
        
        if( region_data )
            region_data->Format( out, nestLevel+1 );
        
        if( rules )
            rules->Format( out, nestLevel+1 );
        
        out->Print( nestLevel, ")\n" );
    }
};


class STRUCTURE : public ELEM
{
    friend class SPECCTRA_DB;
@@ -963,6 +1094,11 @@ class STRUCTURE : public ELEM
    typedef boost::ptr_vector<KEEPOUT>  KEEPOUTS;
    KEEPOUTS    keepouts;

    typedef boost::ptr_vector<PLANE>    PLANES;
    PLANES      planes;

    typedef boost::ptr_vector<REGION>   REGIONS;
    REGIONS     regions;
    
public:

@@ -1013,6 +1149,12 @@ public:
        if( place_boundary )
            place_boundary->Format( out, nestLevel+1 );

        for( unsigned i=0;  i<planes.size();  ++i )
            planes[i].Format( out, nestLevel+1 );

        for( unsigned i=0;  i<regions.size();  ++i )
            regions[i].Format( out, nestLevel+1 );
        
        for( unsigned i=0;  i<keepouts.size();  ++i )
            keepouts[i].Format( out, nestLevel+1 );
        
@@ -1043,60 +1185,6 @@ public:
};


/**
 * Class TOKPROP
 * is a container for a single property whose value is another DSN_T token.
 * The name of the property is obtained from the DSN_T Type().
 */
class TOKPROP : public ELEM
{
    friend class SPECCTRA_DB;

    DSN_T       value;

public:

    TOKPROP( ELEM* aParent, DSN_T aType ) :
        ELEM( aType, aParent )
    {
    }
    
    void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
    {
        out->Print( nestLevel, "(%s %s)\n", LEXER::GetTokenText( Type() ),
                   LEXER::GetTokenText( value ) );
    }
};


/**
 * Class STRINGPROP
 * is a container for a single property whose value is a string.
 * The name of the property is obtained from the DSN_T.
 */
class STRINGPROP : public ELEM
{
    friend class SPECCTRA_DB;

    std::string     value;

public:

    STRINGPROP( ELEM* aParent, DSN_T aType ) :
        ELEM( aType, aParent )
    {
    }
    
    void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
    {
        const char* quote_char = out->GetQuoteChar( value.c_str() );
        
        out->Print( nestLevel, "(%s %s%s%s)\n", LEXER::GetTokenText( Type() ),
                                quote_char, value.c_str(), quote_char );
    }
};


class PCB : public ELEM
{
    friend class SPECCTRA_DB;
@@ -1161,6 +1249,7 @@ public:
};



/**
 * Class SPECCTRA_DB
 * holds a DSN data tree, usually coming from a DSN file.
@@ -1223,6 +1312,8 @@ class SPECCTRA_DB : public OUTPUTFORMATTER
    void doCIRCLE( CIRCLE* growth ) throw( IOError );
    void doQARC( QARC* growth ) throw( IOError );
    void doWINDOW( WINDOW* growth ) throw( IOError );
    void doREGION( REGION* region ) throw( IOError );
    
    
public:

@@ -1686,6 +1777,20 @@ L_place:
            doBOUNDARY( growth->boundary );
            break;

        case T_plane:
            PLANE* plane;
            plane = new PLANE( growth );
            growth->planes.push_back( plane );
            doKEEPOUT( plane );
            break;

        case T_region:
            REGION* region;
            region = new REGION( growth );
            growth->regions.push_back( region );
            doREGION( region );
            break;
            
        case T_snap_angle:
            STRINGPROP* stringprop;
            stringprop = new STRINGPROP( growth, T_snap_angle ); 
@@ -2324,6 +2429,59 @@ void SPECCTRA_DB::doRULES( RULES* growth ) throw( IOError )
        unexpected( T_EOF );
}


void SPECCTRA_DB::doREGION( REGION* growth ) throw( IOError )
{
    DSN_T tok = nextTok();
    
    if( isSymbol(tok) )
    {
        growth->region_id = lexer->CurText();
        tok = nextTok();
    }

    do
    {
        if( tok != T_LEFT )
            expecting( T_LEFT );

        tok = nextTok();
        switch( tok )
        {
        case T_rect:
            growth->rectangle = new RECTANGLE( growth );
            doRECTANGLE( growth->rectangle );
            break;
            
        case T_polygon:
            growth->polygon = new PATH( growth, T_polygon );
            doPATH( growth->polygon );
            break;
            
        case T_region_net:
        case T_region_class:
            growth->region_data = new STRINGPROP( growth, tok );
            doSTRINGPROP( growth->region_data );
            break;            

/* @todo            
        case T_class_class:
            break;
*/            
            
        case T_rule:
            growth->rules = new RULES( growth, T_rule );
            doRULES( growth->rules );
            break;
            
        default:
            unexpected( lexer->CurText() );
        }
        
    } while( (tok = nextTok()) != T_RIGHT );
}


void SPECCTRA_DB::Print( int nestLevel, const char* fmt, ... ) throw( IOError )
{
    va_list     args;
@@ -2348,12 +2506,18 @@ void SPECCTRA_DB::Print( int nestLevel, const char* fmt, ... ) throw( IOError )

const char* SPECCTRA_DB::GetQuoteChar( const char* wrapee ) 
{
    // I include '#' so a symbol is not confused with a comment.  We intend
    // to wrap any symbol starting with a '#'.
    // Our LEXER class handles comments, and comments appear to be an extension
    // to the SPECCTRA DSN specification. 
    if( *wrapee == '#' )
        return quote_char.c_str();
    
    while( *wrapee )
    {
        // if the string to be wrapped (wrapee) has a delimiter in it, 
        // return the quote_char so caller wraps the wrapee.
        // I include '#' so a symbol is not confused with a comment. 
        if( strchr( "#\t ()", *wrapee++ ) )
        if( strchr( "\t ()", *wrapee++ ) )
            return quote_char.c_str();
    }
    return "";      // can use an unwrapped string.