kicad/pcbnew/dsn.cpp

844 lines
20 KiB
C++
Raw Normal View History

2007-12-22 07:18:20 +00:00
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
2008-01-02 18:18:37 +00:00
* Copyright (C) 2007-2008 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
2007-12-22 07:18:20 +00:00
* Copyright (C) 2007 Kicad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
2007-12-23 05:43:30 +00:00
#include <cstdarg>
#include <cstdio>
#include <cstdlib> // bsearch()
2007-12-22 07:18:20 +00:00
#include <cctype>
2007-12-23 05:43:30 +00:00
#include "dsn.h"
2007-12-22 07:18:20 +00:00
2007-12-23 05:43:30 +00:00
#include "fctsys.h"
#include "pcbnew.h"
2007-12-22 07:18:20 +00:00
2008-01-22 20:48:02 +00:00
/**
* Class LEXER
* implements a lexical analyzer for the SPECCTRA DSN file format. It
* reads lexical tokens from the current LINE_READER through the NextTok()
* function. The NextTok() function returns one of the DSN_T values.
*/
2007-12-23 05:43:30 +00:00
namespace DSN {
2007-12-22 07:18:20 +00:00
/**
* Struct KEYWORD
* holds a string and a DSN_T
*/
struct KEYWORD
{
const char* name;
2008-01-14 22:50:08 +00:00
// int token;
2007-12-22 07:18:20 +00:00
};
2008-01-14 22:50:08 +00:00
//#define TOKDEF(x) { #x, T_##x }
#define TOKDEF(x) { #x }
2007-12-22 07:18:20 +00:00
// This MUST be sorted alphabetically, and also so MUST enum DSN_T {} be alphabetized.
2007-12-22 15:07:42 +00:00
// These MUST all be lower case because of the conversion to lowercase in findToken().
2007-12-22 07:18:20 +00:00
const static KEYWORD tokens[] = {
2007-12-22 15:07:42 +00:00
TOKDEF(absolute),
TOKDEF(added),
TOKDEF(add_group),
TOKDEF(add_pins),
TOKDEF(allow_antenna),
TOKDEF(allow_redundant_wiring),
TOKDEF(amp),
TOKDEF(ancestor),
TOKDEF(antipad),
TOKDEF(aperture_type),
TOKDEF(array),
TOKDEF(attach),
TOKDEF(attr),
TOKDEF(average_pair_length),
2008-01-15 23:12:38 +00:00
TOKDEF(back),
2007-12-22 15:07:42 +00:00
TOKDEF(base_design),
TOKDEF(bbv_ctr2ctr),
2008-01-23 22:37:03 +00:00
TOKDEF(bend_keepout),
2007-12-22 15:07:42 +00:00
TOKDEF(bond),
2008-01-16 23:08:22 +00:00
TOKDEF(both),
2007-12-22 15:07:42 +00:00
TOKDEF(bottom),
TOKDEF(bottom_layer_sel),
TOKDEF(boundary),
TOKDEF(brickpat),
TOKDEF(bundle),
2008-01-18 22:41:16 +00:00
TOKDEF(bus),
2007-12-22 15:07:42 +00:00
TOKDEF(bypass),
TOKDEF(capacitance_resolution),
TOKDEF(capacitor),
TOKDEF(case_sensitive),
TOKDEF(cct1),
TOKDEF(cct1a),
TOKDEF(center_center),
TOKDEF(checking_trim_by_pin),
TOKDEF(circ),
TOKDEF(circle),
TOKDEF(circuit),
TOKDEF(class),
TOKDEF(class_class),
TOKDEF(classes),
TOKDEF(clear),
TOKDEF(clearance),
TOKDEF(cluster),
TOKDEF(cm),
TOKDEF(color),
TOKDEF(colors),
TOKDEF(comment),
TOKDEF(comp),
TOKDEF(comp_edge_center),
TOKDEF(comp_order),
2008-01-15 23:12:38 +00:00
TOKDEF(component),
2007-12-22 15:07:42 +00:00
TOKDEF(composite),
TOKDEF(conductance_resolution),
TOKDEF(conductor),
TOKDEF(conflict),
TOKDEF(connect),
TOKDEF(constant),
TOKDEF(contact),
TOKDEF(control),
TOKDEF(corner),
TOKDEF(corners),
TOKDEF(cost),
TOKDEF(created_time),
TOKDEF(cross),
TOKDEF(crosstalk_model),
TOKDEF(current_resolution),
TOKDEF(delete_pins),
2008-01-15 23:12:38 +00:00
TOKDEF(deleted),
TOKDEF(deleted_keepout),
2007-12-22 15:07:42 +00:00
TOKDEF(delta),
2008-01-03 22:24:17 +00:00
TOKDEF(diagonal),
2007-12-22 15:07:42 +00:00
TOKDEF(direction),
TOKDEF(directory),
2008-01-14 22:50:08 +00:00
TOKDEF(discrete),
2007-12-22 15:07:42 +00:00
TOKDEF(effective_via_length),
2008-01-23 22:37:03 +00:00
TOKDEF(elongate_keepout),
2007-12-22 15:07:42 +00:00
TOKDEF(exclude),
TOKDEF(expose),
TOKDEF(extra_image_directory),
TOKDEF(family),
TOKDEF(family_family),
TOKDEF(family_family_spacing),
2008-01-18 22:41:16 +00:00
TOKDEF(fanout),
2007-12-22 15:07:42 +00:00
TOKDEF(farad),
TOKDEF(file),
TOKDEF(fit),
TOKDEF(fix),
TOKDEF(flip_style),
TOKDEF(floor_plan),
TOKDEF(footprint),
TOKDEF(forbidden),
TOKDEF(force_to_terminal_point),
TOKDEF(forgotten),
2008-01-03 22:24:17 +00:00
TOKDEF(free),
2007-12-22 15:07:42 +00:00
TOKDEF(fromto),
TOKDEF(front),
TOKDEF(front_only),
TOKDEF(gap),
2008-01-15 23:12:38 +00:00
TOKDEF(gate),
2007-12-22 15:07:42 +00:00
TOKDEF(gates),
2008-01-20 12:58:55 +00:00
TOKDEF(generated_by_freeroute),
2007-12-22 15:07:42 +00:00
TOKDEF(global),
TOKDEF(grid),
TOKDEF(group),
TOKDEF(group_set),
TOKDEF(guide),
TOKDEF(hard),
TOKDEF(height),
2008-01-03 22:24:17 +00:00
TOKDEF(high),
2007-12-22 15:07:42 +00:00
TOKDEF(history),
TOKDEF(horizontal),
TOKDEF(host_cad),
TOKDEF(host_version),
TOKDEF(image),
2008-01-01 08:45:47 +00:00
TOKDEF(image_conductor),
2007-12-22 15:07:42 +00:00
TOKDEF(image_image),
TOKDEF(image_image_spacing),
TOKDEF(image_outline_clearance),
2008-01-14 22:50:08 +00:00
TOKDEF(image_set),
2007-12-22 15:07:42 +00:00
TOKDEF(image_type),
TOKDEF(inch),
TOKDEF(include),
TOKDEF(include_pins_in_crosstalk),
TOKDEF(inductance_resolution),
TOKDEF(insert),
TOKDEF(instcnfg),
TOKDEF(inter_layer_clearance),
TOKDEF(jumper),
TOKDEF(junction_type),
TOKDEF(keepout),
TOKDEF(kg),
TOKDEF(kohm),
TOKDEF(large),
TOKDEF(large_large),
TOKDEF(layer),
TOKDEF(layer_depth),
TOKDEF(layer_noise_weight),
TOKDEF(layer_pair),
TOKDEF(layer_rule),
TOKDEF(length),
TOKDEF(length_amplitude),
TOKDEF(length_factor),
TOKDEF(length_gap),
TOKDEF(library),
TOKDEF(library_out),
TOKDEF(limit),
TOKDEF(limit_bends),
TOKDEF(limit_crossing),
TOKDEF(limit_vias),
TOKDEF(limit_way),
TOKDEF(linear),
TOKDEF(linear_interpolation),
TOKDEF(load),
TOKDEF(lock_type),
TOKDEF(logical_part),
TOKDEF(logical_part_mapping),
2008-01-03 22:24:17 +00:00
TOKDEF(low),
2007-12-22 15:07:42 +00:00
TOKDEF(match_fromto_delay),
TOKDEF(match_fromto_length),
TOKDEF(match_group_delay),
TOKDEF(match_group_length),
TOKDEF(match_net_delay),
TOKDEF(match_net_length),
TOKDEF(max_delay),
TOKDEF(max_len),
TOKDEF(max_length),
TOKDEF(max_noise),
TOKDEF(max_restricted_layer_length),
TOKDEF(max_stagger),
TOKDEF(max_stub),
TOKDEF(max_total_delay),
TOKDEF(max_total_length),
TOKDEF(max_total_vias),
2008-01-03 22:24:17 +00:00
TOKDEF(medium),
2007-12-22 15:07:42 +00:00
TOKDEF(mhenry),
TOKDEF(mho),
TOKDEF(microvia),
TOKDEF(mid_driven),
TOKDEF(mil),
TOKDEF(min_gap),
TOKDEF(mirror),
TOKDEF(mirror_first),
2008-01-03 22:24:17 +00:00
TOKDEF(mixed),
2007-12-22 15:07:42 +00:00
TOKDEF(mm),
2008-01-03 22:24:17 +00:00
TOKDEF(negative_diagonal),
2007-12-22 15:07:42 +00:00
TOKDEF(net),
TOKDEF(net_number),
2008-01-21 20:55:04 +00:00
TOKDEF(net_out),
2007-12-22 15:07:42 +00:00
TOKDEF(net_pin_changes),
TOKDEF(nets),
TOKDEF(network),
TOKDEF(network_out),
TOKDEF(no),
TOKDEF(noexpose),
TOKDEF(noise_accumulation),
TOKDEF(noise_calculation),
2008-01-16 23:08:22 +00:00
TOKDEF(normal),
2007-12-22 15:07:42 +00:00
TOKDEF(object_type),
TOKDEF(off),
TOKDEF(off_grid),
TOKDEF(offset),
TOKDEF(on),
TOKDEF(open),
TOKDEF(opposite_side),
TOKDEF(order),
2008-01-03 22:24:17 +00:00
TOKDEF(orthogonal),
2007-12-22 15:07:42 +00:00
TOKDEF(outline),
TOKDEF(overlap),
TOKDEF(pad),
TOKDEF(pad_pad),
TOKDEF(padstack),
TOKDEF(pair),
TOKDEF(parallel),
TOKDEF(parallel_noise),
TOKDEF(parallel_segment),
TOKDEF(parser),
TOKDEF(part_library),
TOKDEF(path),
TOKDEF(pcb),
TOKDEF(permit_orient),
TOKDEF(permit_side),
TOKDEF(physical),
TOKDEF(physical_part_mapping),
TOKDEF(piggyback),
TOKDEF(pin),
TOKDEF(pin_allow),
TOKDEF(pin_cap_via),
TOKDEF(pin_via_cap),
TOKDEF(pin_width_taper),
2008-01-20 12:58:55 +00:00
TOKDEF(pins),
TOKDEF(pintype),
2007-12-22 15:07:42 +00:00
TOKDEF(place),
TOKDEF(place_boundary),
TOKDEF(place_control),
2008-01-23 22:37:03 +00:00
TOKDEF(place_keepout),
2007-12-22 15:07:42 +00:00
TOKDEF(place_rule),
2008-01-11 20:25:52 +00:00
TOKDEF(placement),
2007-12-22 15:07:42 +00:00
TOKDEF(plan),
TOKDEF(plane),
2008-01-07 07:43:23 +00:00
TOKDEF(pn),
2007-12-22 15:07:42 +00:00
TOKDEF(point),
TOKDEF(polygon),
TOKDEF(position),
2008-01-03 22:24:17 +00:00
TOKDEF(positive_diagonal),
2007-12-22 15:07:42 +00:00
TOKDEF(power),
TOKDEF(power_dissipation),
TOKDEF(power_fanout),
TOKDEF(prefix),
TOKDEF(primary),
TOKDEF(priority),
TOKDEF(property),
2008-01-18 22:41:16 +00:00
TOKDEF(protect),
2007-12-22 15:07:42 +00:00
TOKDEF(qarc),
TOKDEF(quarter),
TOKDEF(radius),
TOKDEF(ratio),
TOKDEF(ratio_tolerance),
TOKDEF(rect),
TOKDEF(reduced),
TOKDEF(region),
TOKDEF(region_class),
TOKDEF(region_class_class),
TOKDEF(region_net),
TOKDEF(relative_delay),
TOKDEF(relative_group_delay),
TOKDEF(relative_group_length),
TOKDEF(relative_length),
TOKDEF(reorder),
TOKDEF(reroute_order_viols),
TOKDEF(resistance_resolution),
2008-01-14 22:50:08 +00:00
TOKDEF(resistor),
2007-12-22 15:07:42 +00:00
TOKDEF(resolution),
TOKDEF(restricted_layer_length_factor),
TOKDEF(room),
TOKDEF(rotate),
TOKDEF(rotate_first),
TOKDEF(round),
TOKDEF(roundoff_rotation),
TOKDEF(route),
TOKDEF(route_to_fanout_only),
2008-01-20 12:58:55 +00:00
TOKDEF(routes),
2008-01-16 23:08:22 +00:00
TOKDEF(routes_include),
2007-12-22 15:07:42 +00:00
TOKDEF(rule),
TOKDEF(same_net_checking),
TOKDEF(sample_window),
TOKDEF(saturation_length),
TOKDEF(sec),
TOKDEF(secondary),
TOKDEF(self),
TOKDEF(sequence_number),
TOKDEF(session),
TOKDEF(set_color),
TOKDEF(set_pattern),
TOKDEF(shape),
TOKDEF(shield),
TOKDEF(shield_gap),
TOKDEF(shield_loop),
TOKDEF(shield_tie_down_interval),
TOKDEF(shield_width),
TOKDEF(side),
TOKDEF(signal),
TOKDEF(site),
2008-01-14 22:50:08 +00:00
TOKDEF(small),
2007-12-22 15:07:42 +00:00
TOKDEF(smd),
2008-01-11 20:25:52 +00:00
TOKDEF(snap),
2007-12-22 15:07:42 +00:00
TOKDEF(snap_angle),
2008-01-18 22:41:16 +00:00
TOKDEF(soft),
2007-12-22 15:07:42 +00:00
TOKDEF(source),
TOKDEF(space_in_quoted_tokens),
TOKDEF(spacing),
TOKDEF(spare),
TOKDEF(spiral_via),
2008-01-03 06:33:28 +00:00
TOKDEF(square),
2007-12-22 15:07:42 +00:00
TOKDEF(stack_via),
TOKDEF(stack_via_depth),
TOKDEF(standard),
TOKDEF(starburst),
TOKDEF(status),
TOKDEF(string_quote),
TOKDEF(structure),
TOKDEF(structure_out),
2008-01-15 23:12:38 +00:00
TOKDEF(subgate),
2007-12-22 15:07:42 +00:00
TOKDEF(subgates),
2008-01-15 23:12:38 +00:00
TOKDEF(substituted),
2007-12-22 15:07:42 +00:00
TOKDEF(such),
TOKDEF(suffix),
TOKDEF(super_placement),
TOKDEF(supply),
TOKDEF(supply_pin),
TOKDEF(swapping),
TOKDEF(switch_window),
TOKDEF(system),
TOKDEF(tandem_noise),
TOKDEF(tandem_segment),
TOKDEF(tandem_shield_overhang),
TOKDEF(terminal),
TOKDEF(terminator),
TOKDEF(term_only),
TOKDEF(test),
TOKDEF(test_points),
2008-01-16 23:08:22 +00:00
TOKDEF(testpoint),
2007-12-22 15:07:42 +00:00
TOKDEF(threshold),
TOKDEF(time_length_factor),
TOKDEF(time_resolution),
TOKDEF(tjunction),
TOKDEF(tolerance),
TOKDEF(top),
TOKDEF(topology),
TOKDEF(total),
TOKDEF(track_id),
TOKDEF(turret),
TOKDEF(type),
TOKDEF(um),
TOKDEF(unassigned),
TOKDEF(unconnects),
TOKDEF(unit),
TOKDEF(up),
TOKDEF(use_array),
TOKDEF(use_layer),
TOKDEF(use_net),
TOKDEF(use_via),
TOKDEF(value),
2008-01-03 22:24:17 +00:00
TOKDEF(vertical),
2007-12-22 15:07:42 +00:00
TOKDEF(via),
TOKDEF(via_array_template),
TOKDEF(via_at_smd),
TOKDEF(via_keepout),
TOKDEF(via_number),
TOKDEF(via_rotate_first),
TOKDEF(via_site),
TOKDEF(via_size),
TOKDEF(virtual_pin),
TOKDEF(volt),
TOKDEF(voltage_resolution),
TOKDEF(was_is),
TOKDEF(way),
TOKDEF(weight),
TOKDEF(width),
TOKDEF(window),
TOKDEF(wire),
2008-01-23 22:37:03 +00:00
TOKDEF(wire_keepout),
2007-12-22 15:07:42 +00:00
TOKDEF(wires),
TOKDEF(wires_include),
TOKDEF(wiring),
TOKDEF(write_resolution),
TOKDEF(x),
2008-01-14 22:50:08 +00:00
TOKDEF(xy),
2008-01-11 20:25:52 +00:00
TOKDEF(y),
2007-12-22 07:18:20 +00:00
};
2007-12-22 15:07:42 +00:00
2007-12-22 07:18:20 +00:00
static int compare( const void* a1, const void* a2 )
{
const KEYWORD* k1 = (const KEYWORD*) a1;
const KEYWORD* k2 = (const KEYWORD*) a2;
int ret = strcmp( k1->name, k2->name );
return ret;
}
2007-12-23 05:43:30 +00:00
//-----<LINE_READER>------------------------------------------------------
2007-12-22 07:18:20 +00:00
LINE_READER::LINE_READER( FILE* aFile, unsigned aMaxLineLength )
{
fp = aFile;
lineNum = 0;
maxLineLength = aMaxLineLength;
// the real capacity is 10 bytes larger than requested.
capacity = aMaxLineLength + 10;
line = new char[capacity];
line[0] = '\0';
length = 0;
}
int LINE_READER::ReadLine() throw (IOError)
{
2007-12-22 15:07:42 +00:00
const char* p = fgets( line, capacity, fp );
2007-12-22 07:18:20 +00:00
if( !p )
{
2007-12-22 15:07:42 +00:00
line[0] = 0;
length = 0;
2007-12-22 07:18:20 +00:00
}
else
{
2007-12-22 15:07:42 +00:00
length = strlen( line );
2007-12-22 07:18:20 +00:00
if( length > maxLineLength )
throw IOError( _("Line length exceeded") );
++lineNum;
}
return length;
}
2007-12-23 05:43:30 +00:00
//-----<LEXER>-------------------------------------------------------------
2007-12-22 07:18:20 +00:00
2008-01-01 08:45:47 +00:00
LEXER::LEXER( FILE* aFile, const wxString& aFilename ) :
reader( aFile, 4096 )
{
curTok = T_END;
stringDelimiter = '"';
filename = aFilename;
2008-01-20 00:34:21 +00:00
space_in_quoted_tokens = true;
2008-01-01 08:45:47 +00:00
// "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;
next = start;
}
2007-12-23 05:43:30 +00:00
int LEXER::findToken( const std::string& tok )
{
// convert to lower case once, this should be faster than using strcasecmp()
// for each test in compare().
lowercase.clear();
2007-12-22 07:18:20 +00:00
2007-12-23 05:43:30 +00:00
for( std::string::const_iterator iter = tok.begin(); iter!=tok.end(); ++iter )
lowercase += (char) tolower( *iter );
2007-12-22 07:18:20 +00:00
2007-12-23 05:43:30 +00:00
KEYWORD search;
search.name = lowercase.c_str();
2007-12-22 07:18:20 +00:00
2007-12-23 05:43:30 +00:00
const KEYWORD* findings = (const KEYWORD*) bsearch( &search,
tokens, sizeof(tokens)/sizeof(tokens[0]),
sizeof(KEYWORD), compare );
if( findings )
2008-01-14 22:50:08 +00:00
// return findings->token;
return findings - tokens;
2007-12-23 05:43:30 +00:00
else
return -1;
}
2007-12-22 07:18:20 +00:00
2008-01-01 08:45:47 +00:00
2008-01-02 18:18:37 +00:00
const char* LEXER::GetTokenText( DSN_T aTok )
2008-01-01 08:45:47 +00:00
{
2008-01-02 18:18:37 +00:00
const char* ret;
2008-01-01 08:45:47 +00:00
if( aTok < 0 )
{
switch( aTok )
{
2008-01-15 23:12:38 +00:00
case T_NONE:
ret = "NONE";
break;
2008-01-01 08:45:47 +00:00
case T_QUOTE_DEF:
2008-01-15 23:12:38 +00:00
ret = "quoted text delimiter";
2008-01-01 08:45:47 +00:00
break;
case T_DASH:
2008-01-15 23:12:38 +00:00
ret = "-";
2008-01-01 08:45:47 +00:00
break;
case T_SYMBOL:
2008-01-15 23:12:38 +00:00
ret = "symbol";
2008-01-01 08:45:47 +00:00
break;
case T_NUMBER:
2008-01-15 23:12:38 +00:00
ret = "number";
2008-01-01 08:45:47 +00:00
break;
case T_RIGHT:
2008-01-15 23:12:38 +00:00
ret = ")";
2008-01-01 08:45:47 +00:00
break;
case T_LEFT:
2008-01-15 23:12:38 +00:00
ret = "(";
2008-01-01 08:45:47 +00:00
break;
case T_STRING:
2008-01-15 23:12:38 +00:00
ret = "quoted string";
2008-01-01 08:45:47 +00:00
break;
case T_EOF:
2008-01-15 23:12:38 +00:00
ret = "end of file";
2008-01-01 08:45:47 +00:00
break;
default:
2008-01-02 18:18:37 +00:00
ret = "???";
2008-01-01 08:45:47 +00:00
}
}
else
{
2008-01-02 18:18:37 +00:00
ret = tokens[aTok].name;
2008-01-01 08:45:47 +00:00
}
return ret;
}
2008-01-02 18:18:37 +00:00
wxString LEXER::GetTokenString( DSN_T aTok )
{
2008-01-03 06:33:28 +00:00
wxString ret;
ret << wxT("'") << CONV_FROM_UTF8( GetTokenText(aTok) ) << wxT("'");
2008-01-02 18:18:37 +00:00
return ret;
}
2008-01-01 08:45:47 +00:00
void LEXER::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 );
}
2007-12-22 07:18:20 +00:00
2007-12-22 15:07:42 +00:00
DSN_T LEXER::NextTok() throw (IOError)
2007-12-22 07:18:20 +00:00
{
2008-01-01 08:45:47 +00:00
char* cur = next;
char* head = cur;
2007-12-23 05:43:30 +00:00
2008-01-04 08:28:16 +00:00
prevTok = curTok;
2007-12-22 07:18:20 +00:00
if( curTok != T_EOF )
{
if( cur >= limit )
{
L_read:
int len = readLine();
if( len == 0 )
{
curTok = T_EOF;
goto exit;
}
2007-12-23 05:43:30 +00:00
2008-01-06 00:45:49 +00:00
cur = start;
// skip leading whitespace
while( cur<limit && isspace(*cur) )
++cur;
// if the first non-blank character is #, this line is a comment.
if( cur<limit && *cur=='#' )
goto L_read;
}
else
{
// skip leading whitespace
while( cur<limit && isspace(*cur) )
++cur;
2007-12-22 07:18:20 +00:00
}
if( cur >= limit )
goto L_read;
2007-12-23 05:43:30 +00:00
// switching the string_quote character
2008-01-04 08:28:16 +00:00
if( prevTok == T_string_quote )
2007-12-22 07:18:20 +00:00
{
2008-01-01 08:45:47 +00:00
static const wxString errtxt( _("String delimiter must be a single character of ', \", or $"));
char cc = *cur;
switch( cc )
{
case '\'':
case '$':
case '"':
break;
default:
ThrowIOError( errtxt, CurOffset() );
}
2007-12-23 05:43:30 +00:00
curText.clear();
2008-01-01 08:45:47 +00:00
curText += cc;
2007-12-23 05:43:30 +00:00
head = cur+1;
2007-12-22 15:18:03 +00:00
2007-12-23 05:43:30 +00:00
if( head<limit && *head!=')' && *head!='(' && !isspace(*head) )
{
2008-01-01 08:45:47 +00:00
ThrowIOError( errtxt, CurOffset() );
2007-12-22 07:18:20 +00:00
}
2007-12-23 05:43:30 +00:00
curTok = T_QUOTE_DEF;
2008-01-21 20:55:04 +00:00
goto exit;
2007-12-23 05:43:30 +00:00
}
2008-01-21 20:55:04 +00:00
if( *cur == '(' )
2007-12-23 05:43:30 +00:00
{
curText.clear();
curText += *cur;
2007-12-22 07:18:20 +00:00
2007-12-23 05:43:30 +00:00
curTok = T_LEFT;
head = cur+1;
2008-01-21 20:55:04 +00:00
goto exit;
2007-12-23 05:43:30 +00:00
}
2007-12-22 07:18:20 +00:00
2008-01-21 20:55:04 +00:00
if( *cur == ')' )
2007-12-23 05:43:30 +00:00
{
curText.clear();
curText += *cur;
curTok = T_RIGHT;
head = cur+1;
2008-01-21 20:55:04 +00:00
goto exit;
2007-12-23 05:43:30 +00:00
}
2008-01-18 22:41:16 +00:00
/* get the dash out of a <pin_reference> which is embedded for example
like: U2-14 or "U2"-"14"
This is detectable by a non-space immediately preceeding the dash.
*/
2008-01-21 20:55:04 +00:00
if( *cur == '-' && cur>start && !isspace( cur[-1] ) )
2008-01-18 22:41:16 +00:00
{
head = cur+1;
curText.clear();
curText += '-';
curTok = T_DASH;
2008-01-21 20:55:04 +00:00
goto exit;
2008-01-18 22:41:16 +00:00
}
// handle T_NUMBER
2008-01-21 20:55:04 +00:00
if( strchr( "+-.0123456789", *cur ) )
2007-12-23 05:43:30 +00:00
{
2008-01-18 22:41:16 +00:00
head = cur+1;
while( head<limit && strchr( ".0123456789", *head ) )
++head;
2007-12-23 05:43:30 +00:00
2008-01-21 20:55:04 +00:00
if( (head<limit && isspace(*head)) || *head==')' || *head=='(' || head==limit )
{
curText.clear();
curText.append( cur, head );
curTok = T_NUMBER;
goto exit;
}
// else it was something like +5V, reset head back
2007-12-23 05:43:30 +00:00
}
// a quoted string
2008-01-21 20:55:04 +00:00
if( *cur == stringDelimiter )
2007-12-23 05:43:30 +00:00
{
2008-01-01 08:45:47 +00:00
++cur; // skip over the leading delimiter: ",', or $
2007-12-22 07:18:20 +00:00
2007-12-23 05:43:30 +00:00
head = cur;
2008-01-01 08:45:47 +00:00
while( head<limit && !isStringTerminator( *head ) )
2007-12-23 05:43:30 +00:00
++head;
if( head >= limit )
2007-12-22 07:18:20 +00:00
{
2007-12-23 05:43:30 +00:00
wxString errtxt(_("Un-terminated delimited string") );
2008-01-01 08:45:47 +00:00
ThrowIOError( errtxt, CurOffset() );
2007-12-22 07:18:20 +00:00
}
2007-12-23 05:43:30 +00:00
curText.clear();
curText.append( cur, head );
++head; // skip over the trailing delimiter
2008-01-21 20:55:04 +00:00
curTok = T_STRING;
goto exit;
2007-12-23 05:43:30 +00:00
}
// a token we hope to find in the tokens[] array. If not, then
// call it a T_SYMBOL.
{
head = cur+1;
while( head<limit && !isspace( *head ) && *head!=')' && *head!='(' )
++head;
curText.clear();
curText.append( cur, head );
int found = findToken( curText );
if( found != -1 )
curTok = (DSN_T) found;
2008-01-21 20:55:04 +00:00
else // unrecogized token, call it a symbol
curTok = T_SYMBOL;
2007-12-22 07:18:20 +00:00
}
}
2008-01-01 08:45:47 +00:00
exit: // single point of exit
2007-12-23 05:43:30 +00:00
2008-01-01 08:45:47 +00:00
curOffset = cur - start;
2007-12-23 05:43:30 +00:00
next = head;
2008-01-21 20:55:04 +00:00
// printf("tok:\"%s\"\n", curText.c_str() );
2007-12-23 05:43:30 +00:00
2007-12-22 07:18:20 +00:00
return curTok;
}
} // namespace DSN
2008-01-01 08:45:47 +00:00
#if 0 && defined(STANDALONE)
2007-12-22 07:18:20 +00:00
// stand alone testing
int main( int argc, char** argv )
{
// wxString filename( wxT("/tmp/fpcroute/Sample_1sided/demo_1sided.dsn") );
wxString filename( wxT("/tmp/testdesigns/test.dsn") );
FILE* fp = wxFopen( filename, wxT("r") );
if( !fp )
{
fprintf( stderr, "unable to open file \"%s\"\n",
(const char*) filename.mb_str() );
exit(1);
}
DSN::LEXER lexer( fp, filename );
try
{
int tok;
while( (tok = lexer.NextTok()) != DSN::T_EOF )
{
printf( "%-3d %s\n", tok, lexer.CurText() );
}
}
catch( DSN::IOError ioe )
{
printf( "%s\n", (const char*) ioe.errorText.mb_str() );
}
fclose( fp );
return 0;
}
#endif