Commit c5e58154 authored by dickelbeck's avatar dickelbeck
Browse files

more dsn work

parent 751e2f5c
Loading
Loading
Loading
Loading
+125 −696
Original line number Diff line number Diff line
@@ -24,394 +24,19 @@
 */

 
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>         // bsearch()
#include <cstdarg>
#include <cstdio>
#include <cstdlib>         // bsearch()
#include <cctype>


#include "dsn.h"

#include "fctsys.h"
#include "pcbnew.h"
//#include "common.h"

namespace DSN {

    
/**
 * Enum DSN_T
 * lists all the DSN lexer's tokens that are supported in lexing.  It is up
 * to the parser if it wants also to support them.
 */ 
enum DSN_T {
    
    // the first few are special (the uppercase ones)
    T_QUOTE_DEF = -9,
    T_DASH = -8,
    T_SYMBOL = -7,
    T_NUMBER = -6,
    T_NONE = -5,            // not a token
    T_RIGHT = -4,           // right bracket, ')'
    T_LEFT = -3,            // left bracket, '('
    T_STRING = -2,          // a quoted string, stripped of the quotes
    T_EOF = -1,             // special case for end of file

    // from here down, this list segment should be coordinated with the
    // const static KEYWORD tokens[] array below, and must be sorted
    // alphabetically.

    T_absolute,             // this one should be == zero
    T_added,
    T_add_group,
    T_add_pins,
    T_allow_antenna,
    T_allow_redundant_wiring,
    T_amp,
    T_ancestor,
    T_antipad,
    T_aperture_type,
    T_array,
    T_attach,
    T_attr,
    T_average_pair_length,
    T_base_design,
    T_bbv_ctr2ctr,
    T_bond,
    T_bottom,
    T_bottom_layer_sel,
    T_boundary,
    T_brickpat,
    T_bundle,
    T_bypass,
    T_capacitance_resolution,
    T_capacitor,
    T_case_sensitive,
    T_cct1,
    T_cct1a,
    T_center_center,
    T_checking_trim_by_pin,
    T_circ,
    T_circle,
    T_circuit,
    T_class,
    T_class_class,
    T_classes,
    T_clear,
    T_clearance,
    T_cluster,
    T_cm,
    T_color,
    T_colors,
    T_comment,
    T_comp,
    T_comp_edge_center,
    T_component,
    T_comp_order,
    T_composite,
    T_conductance_resolution,
    T_conductor,
    T_conflict,
    T_connect,
    T_constant,
    T_contact,
    T_control,
    T_corner,
    T_corners,
    T_cost,
    T_created_time,
    T_cross,
    T_crosstalk_model,
    T_current_resolution,
    T_deleted_keepout,
    T_delete_pins,
    T_delta,
    T_direction,
    T_directory,
    T_effective_via_length,
    T_exclude,
    T_expose,
    T_extra_image_directory,
    T_family,
    T_family_family,
    T_family_family_spacing,
    T_farad,
    T_file,
    T_fit,
    T_fix,
    T_flip_style,
    T_floor_plan,
    T_footprint,
    T_forbidden,
    T_force_to_terminal_point,
    T_forgotten,
    T_fromto,
    T_front,
    T_front_only,
    T_gap,
    T_gates,
    T_global,
    T_grid,
    T_group,
    T_group_set,
    T_guide,
    T_hard,
    T_height,
    T_history,
    T_horizontal,
    T_host_cad,
    T_host_version,
    T_image,
    T_image_image,
    T_image_image_spacing,
    T_image_outline_clearance,
    T_image_type,
    T_inch,
    T_include,
    T_include_pins_in_crosstalk,
    T_inductance_resolution,
    T_insert,
    T_instcnfg,
    T_inter_layer_clearance,
    T_jumper,
    T_junction_type,
    T_keepout,
    T_kg,
    T_kohm,
    T_large,
    T_large_large,
    T_layer,
    T_layer_depth,
    T_layer_noise_weight,
    T_layer_pair,
    T_layer_rule,
    T_length,
    T_length_amplitude,
    T_length_factor,
    T_length_gap,
    T_library,
    T_library_out,
    T_limit,
    T_limit_bends,
    T_limit_crossing,
    T_limit_vias,
    T_limit_way,
    T_linear,
    T_linear_interpolation,
    T_load,
    T_lock_type,
    T_logical_part,
    T_logical_part_mapping,
    T_match_fromto_delay,
    T_match_fromto_length,
    T_match_group_delay,
    T_match_group_length,
    T_match_net_delay,
    T_match_net_length,
    T_max_delay,
    T_max_len,
    T_max_length,
    T_max_noise,
    T_max_restricted_layer_length,
    T_max_stagger,
    T_max_stub,
    T_max_total_delay,
    T_max_total_length,
    T_max_total_vias,
    T_mhenry,
    T_mho,
    T_microvia,
    T_mid_driven,
    T_mil,
    T_min_gap,
    T_mirror,
    T_mirror_first,
    T_mm,
    T_net,
    T_net_number,
    T_net_pin_changes,
    T_nets,
    T_network,
    T_network_out,
    T_no,
    T_noexpose,
    T_noise_accumulation,
    T_noise_calculation,
    T_object_type,
    T_off,
    T_off_grid,
    T_offset,
    T_on,
    T_open,
    T_opposite_side,
    T_order,
    T_outline,
    T_overlap,
    T_pad,
    T_pad_pad,
    T_padstack,
    T_pair,
    T_parallel,
    T_parallel_noise,
    T_parallel_segment,
    T_parser,
    T_part_library,
    T_path,
    T_pcb,
    T_permit_orient,
    T_permit_side,
    T_physical,
    T_physical_part_mapping,
    T_piggyback,
    T_pin,
    T_pin_allow,
    T_pin_cap_via,
    T_pins,
    T_pintype,
    T_pin_via_cap,
    T_pin_width_taper,
    T_place,
    T_place_boundary,
    T_place_control,
    T_placement,
    T_place_rule,
    T_plan,
    T_plane,
    T_PN,
    T_point,
    T_polygon,
    T_position,
    T_power,
    T_power_dissipation,
    T_power_fanout,
    T_prefix,
    T_primary,
    T_priority,
    T_property,
    T_qarc,
    T_quarter,
    T_radius,
    T_ratio,
    T_ratio_tolerance,
    T_rect,
    T_reduced,
    T_region,
    T_region_class,
    T_region_class_class,
    T_region_net,
    T_relative_delay,
    T_relative_group_delay,
    T_relative_group_length,
    T_relative_length,
    T_reorder,
    T_reroute_order_viols,
    T_resistance_resolution,
    T_resolution,
    T_restricted_layer_length_factor,
    T_room,
    T_rotate,
    T_rotate_first,
    T_round,
    T_roundoff_rotation,
    T_route,
    T_routes,
    T_routes_include,
    T_route_to_fanout_only,
    T_rule,
    T_same_net_checking,
    T_sample_window,
    T_saturation_length,
    T_sec,
    T_secondary,
    T_self,
    T_sequence_number,
    T_session,
    T_set_color,
    T_set_pattern,
    T_shape,
    T_shield,
    T_shield_gap,
    T_shield_loop,
    T_shield_tie_down_interval,
    T_shield_width,
    T_side,
    T_signal,
    T_site,
    T_smd,
    T_snap_angle,
    T_source,
    T_space_in_quoted_tokens,
    T_spacing,
    T_spare,
    T_spiral_via,
    T_stack_via,
    T_stack_via_depth,
    T_standard,
    T_starburst,
    T_status,
    T_string_quote,
    T_structure,
    T_structure_out,
    T_subgates,
    T_such,
    T_suffix,
    T_super_placement,
    T_supply,
    T_supply_pin,
    T_swapping,
    T_switch_window,
    T_system,
    T_tandem_noise,
    T_tandem_segment,
    T_tandem_shield_overhang,
    T_terminal,
    T_terminator,
    T_term_only,
    T_test,
    T_testpoint,
    T_test_points,
    T_threshold,
    T_time_length_factor,
    T_time_resolution,
    T_tjunction,
    T_tolerance,
    T_top,
    T_topology,
    T_total,
    T_track_id,
    T_turret,
    T_type,
    T_um,
    T_unassigned,
    T_unconnects,
    T_unit,
    T_up,
    T_use_array,
    T_use_layer,
    T_use_net,
    T_use_via,
    T_value,
    T_via,
    T_via_array_template,
    T_via_at_smd,
    T_via_keepout,
    T_via_number,
    T_via_rotate_first,
    T_via_site,
    T_via_size,
    T_virtual_pin,
    T_volt,
    T_voltage_resolution,
    T_was_is,
    T_way,
    T_weight,
    T_width,
    T_window,
    T_wire,
    T_wires,
    T_wires_include,
    T_wiring,
    T_write_resolution,
    T_x,
    T_END       // just a sentinel, not a token
};
namespace DSN {


/**
@@ -795,88 +420,7 @@ static int compare( const void* a1, const void* a2 )
}


struct IOError
{
    wxString    errorText;
    
    IOError( const wxChar* aMsg ) :
        errorText( aMsg )
    {
    }
    
    IOError( const wxString& aMsg ) :
        errorText( aMsg )
    {
    }
};


/**
 * Class LINE_READER
 * reads single lines of text into its buffer and increments a line number counter.
 * It throws an exception if a line is too long.
 */
class LINE_READER
{
protected:
    
    FILE*               fp;
    int                 lineNum;
    unsigned            maxLineLength;
    unsigned            length;
    char*               line;
    unsigned            capacity;
    
public:
    
    /**
     * Constructor LINE_READER
     * takes an open FILE and the size of the desired line buffer.
     * @param aFile An open file in "ascii" mode, not binary mode.
     * @param aMaxLineLength The number of bytes to use in the line buffer.
     */
    LINE_READER( FILE* aFile,  unsigned aMaxLineLength );
    
    ~LINE_READER()
    {
        delete[] line;
    }

    /*    
    int  CharAt( int aNdx )
    {
        if( (unsigned) aNdx < capacity )
            return (char) (unsigned char) line[aNdx];
        return -1;
    }
    */

    /**
     * Function ReadLine
     * reads a line of text into the buffer and increments the line number 
     * counter.  If the line is larger than the buffer size, then an exception
     * is thrown.
     * @return int - The number of bytes read, 0 at end of file.
     * @throw IOError only when a line is too long. 
     */
    int ReadLine() throw (IOError);

    operator char* ()
    {
        return line;
    }
    
    int LineNumber()
    {
        return lineNum;
    }
    
    unsigned Length()
    {
        return length; 
    }
};

//-----<LINE_READER>------------------------------------------------------

LINE_READER::LINE_READER( FILE* aFile,  unsigned aMaxLineLength )
{
@@ -917,50 +461,10 @@ int LINE_READER::ReadLine() throw (IOError)
}


/**
 * Class LEXER
 * reads lexical tokens from the current LINE_READER through the NextTok()
 * function.  The NextTok() function returns one of the DSN_T values.
 */
class LEXER
{
    char*               head;

    char*               cur;    
    char*               start;
    char*               limit;
    
    LINE_READER         reader;
    int                 stringDelimiter;
    wxString            filename;
    int                 lastTok;        ///< curTok from previous NextTok() call.
    
    DSN_T               curTok;         ///< the current token obtained on last NextTok()
    std::string         curText;        ///< the text of the current token
    std::string         lowercase;      ///< a scratch buf holding token in lowercase

    
    int readLine() throw (IOError)
    {
        int len = reader.ReadLine();

        cur   = start;
        limit = start + len;
//-----<LEXER>-------------------------------------------------------------

        return len;
    }


    /**
     * Function findToken
     * takes a string and looks up the string in the list of expected
     * tokens.
     *
     * @param tok A string holding the token text to lookup, in an 
     *   unpredictable case: uppercase or lowercase
     * @return int - DSN_T or -1 if argument string is not a recognized token.
    */ 
    int findToken( const std::string& tok )
int LEXER::findToken( const std::string& tok )
{
    // convert to lower case once, this should be faster than using strcasecmp()
    // for each test in compare().
@@ -982,90 +486,14 @@ class LEXER
}

    
public:
    LEXER( FILE* aFile, const wxString& aFilename ) :
        reader( aFile, 4096 )
    {
        curTok = T_NONE;
        stringDelimiter = '"';
        filename = aFilename;
        
        // "start" should never change until we change the reader.  The DSN
        // format spec supports an include file mechanism but we can add that later
        // using a std::stack to hold a stack of LINE_READERs to track nesting.
        start = (char*) reader;     
        
        limit = start;
        cur   = start;
        head  = start;
    }

    /**
     * Function SetStringDelimiter
     * changes the string delimiter from the default " to some other character
     * and returns the old value.
     * @param aStringDelimiter The character in lowest 8 bits.
     * @return int - The old delimiter in the lowest 8 bits.
     */
    int SetStringDelimiter( int aStringDelimiter )
    {
        int old = stringDelimiter;
        stringDelimiter = aStringDelimiter;
        return old;
    }
    
    /**
     * Function NextTok
     * returns the next token found in the input file or T_EOF when reaching
     * the end of file.
     * @return DSN_T - the type of token found next.
     * @throw IOError - only if the LINE_READER throws it.
     */
    DSN_T NextTok() throw (IOError);
    
    
    /**
     * Function ThrowIOError
     * encapsulates the formatting of an error message which contains the exact
     * location within the input file of a lexical error.
     */
    void ThrowIOError( wxString aText, int charOffset ) throw (IOError)
    {
        aText << wxT(" ") << _("in file") << wxT(" \"") << filename 
              << wxT("\" ") << _("on line") << wxT(" ") << reader.LineNumber()
              << wxT(" ") << _("at offset") << wxT(" ") << charOffset;
              
        throw IOError( aText );
    }
    
    
    /**
     * Function CurText
     * returns a pointer to the current token's text.
     */
    const char* CurText()
    {
        return curText.c_str();
    }

    
    /**
     * Function CurTok
     * returns whatever NextTok() returned the last time it was called.
     */
    DSN_T CurTok()
    {
        return curTok;
    }
    
};


DSN_T LEXER::NextTok() throw (IOError)
{
    char*   head;
    char*   cur;

    lastTok = curTok;
    
    cur = head;
    cur = next;
    
    if( curTok != T_EOF )
    {
@@ -1078,6 +506,8 @@ L_read:
                curTok = T_EOF;
                goto exit;
            }
            
            cur = next;
        }
        
        // skip leading whitespace
@@ -1087,8 +517,6 @@ L_read:
        if( cur >= limit )
            goto L_read;
        
        else
        {
        // switching the string_quote character
        if( lastTok == T_string_quote )
        {
@@ -1106,30 +534,6 @@ L_read:
            curTok = T_QUOTE_DEF;
        }
        
            // a quoted string
            else if( *cur == stringDelimiter )
            {
                ++cur;  // skip over the leading "

                head = cur;
            
                while( head<limit && *head!=stringDelimiter )
                    ++head;
                
                if( head >= limit )
                {
                    wxString errtxt(_("Un-terminated delimited string") );
                    ThrowIOError( errtxt, cur-start+1 );
                }
                
                curText.clear();
                curText.append( cur, head );
                
                ++head;     // skip over the trailing delimiter
                
                curTok  = T_STRING;                    
            }
        
        else if( *cur == '(' )
        {
            curText.clear();
@@ -1171,6 +575,30 @@ L_read:
            }
        }
        
        // a quoted string
        else if( *cur == stringDelimiter )
        {
            ++cur;  // skip over the leading "

            head = cur;
        
            while( head<limit && *head!=stringDelimiter )
                ++head;
            
            if( head >= limit )
            {
                wxString errtxt(_("Un-terminated delimited string") );
                ThrowIOError( errtxt, cur-start+1 );
            }
            
            curText.clear();
            curText.append( cur, head );
            
            ++head;     // skip over the trailing delimiter
            
            curTok  = T_STRING;                    
        }
    
        // a token we hope to find in the tokens[] array.  If not, then
        // call it a T_SYMBOL.
        else
@@ -1199,14 +627,15 @@ L_read:
            }
        }
    }
    }
    
exit:        
exit:       // single point of exit
    
    next = head;
    
    return curTok;
}



}   // namespace DSN