++common:

* macros.h now has TO_UTF8() and FROM_UTF8() which are working converters
    to and from UTF-8 encoding for any wxWidgets build mode.  We can switch to
    them at any time.  I am using them now for specctra conversions and
    elsewhere where I wanted gauranteed UTF8 encoding.
  * added OUTPUTFORMATTER::Quoted( const wxString& ) to simplify converting
    to UTF8 encoded s-expression atoms.  The recommended technique is now simply:
        out->Quoted( wxString ).c_str()
This commit is contained in:
Dick Hollenbeck 2011-02-02 09:31:48 -06:00
parent 740c03e717
commit 0093f4f612
10 changed files with 70 additions and 1021 deletions

View File

@ -4,6 +4,17 @@ KiCad ChangeLog 2010
Please add newer entries at the top, list the date and your name with Please add newer entries at the top, list the date and your name with
email address. email address.
2011-Feb-2 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================
++common:
* macros.h now has TO_UTF8() and FROM_UTF8() which are working converters
to and from UTF-8 encoding for any wxWidgets build mode. We can switch to
them at any time. I am using them now for specctra conversions and
elsewhere where I wanted gauranteed UTF8 encoding.
* added OUTPUTFORMATTER::Quoted( const wxString& ) to simplify converting
to UTF8 encoded s-expression atoms. The recommended technique is now simply:
out->Quoted( wxString ).c_str()
2011-Jan-30 UPDATE Dick Hollenbeck <dick@softplc.com> 2011-Jan-30 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================ ================================================================================
++all: ++all:

View File

@ -642,979 +642,3 @@ exit: // single point of exit, no returns elsewhere please.
return curTok; return curTok;
} }
// stand alone testing
#if defined(STANDALONE)
#include <wx/dataobj.h>
#include <wx/clipbrd.h>
enum TEST_T {
// these first few are negative special ones for syntax, and are
// inherited from DSNLEXER.
T_NONE = DSN_NONE,
T_STRING_QUOTE = DSN_STRING_QUOTE,
T_QUOTE_DEF = DSN_QUOTE_DEF,
T_DASH = DSN_DASH,
T_SYMBOL = DSN_SYMBOL,
T_NUMBER = DSN_NUMBER,
T_RIGHT = DSN_RIGHT, // right bracket, ')'
T_LEFT = DSN_LEFT, // left bracket, '('
T_STRING = DSN_STRING, // a quoted string, stripped of the quotes
T_EOF = DSN_EOF, // special case for end of file
// This should be coordinated with the
// const static KEYWORD tokens[] array, and both must be sorted
// identically and alphabetically. Remember that '_' is less than any
// alpha character according to ASCII.
T_absolute = 0, // 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_back,
T_base_design,
T_bbv_ctr2ctr,
T_bend_keepout,
T_bond,
T_both,
T_bottom,
T_bottom_layer_sel,
T_boundary,
T_brickpat,
T_bundle,
T_bus,
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_comp_order,
T_component,
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_delete_pins,
T_deleted,
T_deleted_keepout,
T_delta,
T_diagonal,
T_direction,
T_directory,
T_discrete,
T_effective_via_length,
T_elongate_keepout,
T_exclude,
T_expose,
T_extra_image_directory,
T_family,
T_family_family,
T_family_family_spacing,
T_fanout,
T_farad,
T_file,
T_fit,
T_fix,
T_flip_style,
T_floor_plan,
T_footprint,
T_forbidden,
T_force_to_terminal_point,
T_free,
T_forgotten,
T_fromto,
T_front,
T_front_only,
T_gap,
T_gate,
T_gates,
T_generated_by_freeroute,
T_global,
T_grid,
T_group,
T_group_set,
T_guide,
T_hard,
T_height,
T_high,
T_history,
T_horizontal,
T_host_cad,
T_host_version,
T_image,
T_image_conductor,
T_image_image,
T_image_image_spacing,
T_image_outline_clearance,
T_image_set,
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_low,
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_medium,
T_mhenry,
T_mho,
T_microvia,
T_mid_driven,
T_mil,
T_min_gap,
T_mirror,
T_mirror_first,
T_mixed,
T_mm,
T_negative_diagonal,
T_net,
T_net_number,
T_net_out,
T_net_pin_changes,
T_nets,
T_network,
T_network_out,
T_no,
T_noexpose,
T_noise_accumulation,
T_noise_calculation,
T_normal,
T_object_type,
T_off,
T_off_grid,
T_offset,
T_on,
T_open,
T_opposite_side,
T_order,
T_orthogonal,
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_pin_via_cap,
T_pin_width_taper,
T_pins,
T_pintype,
T_place,
T_place_boundary,
T_place_control,
T_place_keepout,
T_place_rule,
T_placement,
T_plan,
T_plane,
T_pn,
T_point,
T_polyline_path,
T_polygon,
T_position,
T_positive_diagonal,
T_power,
T_power_dissipation,
T_power_fanout,
T_prefix,
T_primary,
T_priority,
T_property,
T_protect,
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_resistor,
T_resolution,
T_restricted_layer_length_factor,
T_room,
T_rotate,
T_rotate_first,
T_round,
T_roundoff_rotation,
T_route,
T_route_to_fanout_only,
T_routes,
T_routes_include,
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_small,
T_smd,
T_snap,
T_snap_angle,
T_soft,
T_source,
T_space_in_quoted_tokens,
T_spacing,
T_spare,
T_spiral_via,
T_square,
T_stack_via,
T_stack_via_depth,
T_standard,
T_starburst,
T_status,
T_structure,
T_structure_out,
T_subgate,
T_subgates,
T_substituted,
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_test_points,
T_testpoint,
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_vertical,
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_wire_keepout,
T_wires,
T_wires_include,
T_wiring,
T_write_resolution,
T_x,
T_xy,
T_y,
};
#define TOKDEF(x) { #x, T_##x }
// This MUST be sorted alphabetically, and the order of enum DSN_T {} be
// identially alphabetized. These MUST all be lower case because of the
// conversion to lowercase in findToken().
static const KEYWORD keywords[] = {
// Note that TOKDEF(string_quote) has been moved to the
// DSNLEXER, and DSN_SYNTAX_T enum, and the string for it is "string_quote".
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),
TOKDEF(back),
TOKDEF(base_design),
TOKDEF(bbv_ctr2ctr),
TOKDEF(bend_keepout),
TOKDEF(bond),
TOKDEF(both),
TOKDEF(bottom),
TOKDEF(bottom_layer_sel),
TOKDEF(boundary),
TOKDEF(brickpat),
TOKDEF(bundle),
TOKDEF(bus),
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),
TOKDEF(component),
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),
TOKDEF(deleted),
TOKDEF(deleted_keepout),
TOKDEF(delta),
TOKDEF(diagonal),
TOKDEF(direction),
TOKDEF(directory),
TOKDEF(discrete),
TOKDEF(effective_via_length),
TOKDEF(elongate_keepout),
TOKDEF(exclude),
TOKDEF(expose),
TOKDEF(extra_image_directory),
TOKDEF(family),
TOKDEF(family_family),
TOKDEF(family_family_spacing),
TOKDEF(fanout),
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),
TOKDEF(free),
TOKDEF(fromto),
TOKDEF(front),
TOKDEF(front_only),
TOKDEF(gap),
TOKDEF(gate),
TOKDEF(gates),
TOKDEF(generated_by_freeroute),
TOKDEF(global),
TOKDEF(grid),
TOKDEF(group),
TOKDEF(group_set),
TOKDEF(guide),
TOKDEF(hard),
TOKDEF(height),
TOKDEF(high),
TOKDEF(history),
TOKDEF(horizontal),
TOKDEF(host_cad),
TOKDEF(host_version),
TOKDEF(image),
TOKDEF(image_conductor),
TOKDEF(image_image),
TOKDEF(image_image_spacing),
TOKDEF(image_outline_clearance),
TOKDEF(image_set),
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),
TOKDEF(low),
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),
TOKDEF(medium),
TOKDEF(mhenry),
TOKDEF(mho),
TOKDEF(microvia),
TOKDEF(mid_driven),
TOKDEF(mil),
TOKDEF(min_gap),
TOKDEF(mirror),
TOKDEF(mirror_first),
TOKDEF(mixed),
TOKDEF(mm),
TOKDEF(negative_diagonal),
TOKDEF(net),
TOKDEF(net_number),
TOKDEF(net_out),
TOKDEF(net_pin_changes),
TOKDEF(nets),
TOKDEF(network),
TOKDEF(network_out),
TOKDEF(no),
TOKDEF(noexpose),
TOKDEF(noise_accumulation),
TOKDEF(noise_calculation),
TOKDEF(normal),
TOKDEF(object_type),
TOKDEF(off),
TOKDEF(off_grid),
TOKDEF(offset),
TOKDEF(on),
TOKDEF(open),
TOKDEF(opposite_side),
TOKDEF(order),
TOKDEF(orthogonal),
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),
TOKDEF(pins),
TOKDEF(pintype),
TOKDEF(place),
TOKDEF(place_boundary),
TOKDEF(place_control),
TOKDEF(place_keepout),
TOKDEF(place_rule),
TOKDEF(placement),
TOKDEF(plan),
TOKDEF(plane),
TOKDEF(pn),
TOKDEF(point),
TOKDEF(polyline_path), // used by freerouting.com
TOKDEF(polygon),
TOKDEF(position),
TOKDEF(positive_diagonal),
TOKDEF(power),
TOKDEF(power_dissipation),
TOKDEF(power_fanout),
TOKDEF(prefix),
TOKDEF(primary),
TOKDEF(priority),
TOKDEF(property),
TOKDEF(protect),
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),
TOKDEF(resistor),
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),
TOKDEF(routes),
TOKDEF(routes_include),
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),
TOKDEF(small),
TOKDEF(smd),
TOKDEF(snap),
TOKDEF(snap_angle),
TOKDEF(soft),
TOKDEF(source),
TOKDEF(space_in_quoted_tokens),
TOKDEF(spacing),
TOKDEF(spare),
TOKDEF(spiral_via),
TOKDEF(square),
TOKDEF(stack_via),
TOKDEF(stack_via_depth),
TOKDEF(standard),
TOKDEF(starburst),
TOKDEF(status),
TOKDEF(structure),
TOKDEF(structure_out),
TOKDEF(subgate),
TOKDEF(subgates),
TOKDEF(substituted),
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),
TOKDEF(testpoint),
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),
TOKDEF(vertical),
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),
TOKDEF(wire_keepout),
TOKDEF(wires),
TOKDEF(wires_include),
TOKDEF(wiring),
TOKDEF(write_resolution),
TOKDEF(x),
TOKDEF(xy),
TOKDEF(y),
};
/* To run this test code, simply copy some DSN text to the clipboard, then run
the program from the command line and it will beautify the input from the
clipboard to stdout. stderr gets errors, if any.
The wxApp is involved because the clipboard is not available to a raw
int main() type program on all platforms.
*/
class DSNTEST : public wxApp
{
DSNLEXER* lexer;
int nestLevel;
void recursion() throw( IO_ERROR );
void indent()
{
const int NESTWIDTH = 2;
printf("\n");
for( int i=0; i<nestLevel; ++i )
printf( "%*c", NESTWIDTH, ' ' );
}
public:
DSNTEST() :
lexer(0),
nestLevel(0)
{}
~DSNTEST()
{
delete lexer;
}
virtual bool OnInit();
};
IMPLEMENT_APP( DSNTEST )
bool DSNTEST::OnInit()
{
#if 0 // file based LINE_READER.
wxFFile file;
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);
}
file.Attach( fp ); // "exception safe" way to close the file.
// this won't compile without a token table.
DSNLEXER lexer( fp, filename, keywords, DIM(keywords) );
#else // clipboard based line reader
if( !wxTheClipboard->Open() )
{
fprintf( stderr, "unable to open clipboard\n" );
exit( 1 );
}
wxTextDataObject dataObj;
if( !wxTheClipboard->GetData( dataObj ) )
{
fprintf( stderr, "nothing of interest on clipboard\n" );
exit( 2 );
}
int formatCount = dataObj.GetFormatCount();
fprintf( stderr, "formatCount:%d\n", formatCount );
wxDataFormat* formats = new wxDataFormat[formatCount];
dataObj.GetAllFormats( formats );
for( int fmt=0; fmt<formatCount; ++fmt )
{
fprintf( stderr, "format:%d\n", formats[fmt].GetType() );
// @todo: what are these formats in terms of enum strings, and how
// do they vary across platforms. I am seeing
// on linux: 2 formats, 13 and 1
}
lexer = new DSNLEXER( std::string( CONV_TO_UTF8( dataObj.GetText() ) ),
keywords, DIM(keywords) );
#endif
// read the stream via the lexer, and use recursion to establish a nesting
// level and some output.
try
{
int tok;
while( (tok = lexer->NextTok()) != DSN_EOF )
{
if( tok == DSN_LEFT )
{
recursion();
}
else
printf( " %s", lexer->CurText() );
}
printf("\n");
}
catch( IO_ERROR ioe )
{
fprintf( stderr, "%s\n", CONV_TO_UTF8( ioe.errorText ) );
}
return 0;
}
void DSNTEST::recursion() throw( IO_ERROR )
{
int tok;
const char* space = "";
indent();
printf("(");
while( (tok = lexer->NextTok()) != DSN_EOF && tok != DSN_RIGHT )
{
if( tok == DSN_LEFT )
{
++nestLevel;
recursion();
--nestLevel;
}
else
printf( "%s%s", space, lexer->CurText() );
space = " "; // only the first tok gets no leading space.
}
printf(")");
}
#endif

View File

@ -2,7 +2,7 @@
/* /*
* This program source code file is part of KICAD, a free EDA CAD application. * This program source code file is part of KICAD, a free EDA CAD application.
* *
* Copyright (C) 2007-2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com> * Copyright (C) 2007-2011 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2007 Kicad Developers, see change_log.txt for contributors. * Copyright (C) 2007 Kicad Developers, see change_log.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or

View File

@ -34,7 +34,7 @@ void XNODE::Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
switch( GetType() ) switch( GetType() )
{ {
case wxXML_ELEMENT_NODE: case wxXML_ELEMENT_NODE:
out->Print( nestLevel, "(%s", CONV_TO_UTF8( GetName() ) ); out->Print( nestLevel, "(%s", out->Quoted( GetName() ).c_str() );
FormatContents( out, nestLevel ); FormatContents( out, nestLevel );
if( GetNext() ) if( GetNext() )
out->Print( 0, ")\n" ); out->Print( 0, ")\n" );
@ -55,8 +55,8 @@ void XNODE::FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERRO
{ {
out->Print( 0, " (%s %s)", out->Print( 0, " (%s %s)",
// attr names should never need quoting, no spaces, we designed the file. // attr names should never need quoting, no spaces, we designed the file.
CONV_TO_UTF8( attr->GetName() ), out->Quoted( attr->GetName() ).c_str(),
out->Quoted( CONV_TO_UTF8( attr->GetValue() ) ).c_str() out->Quoted( attr->GetValue() ).c_str()
); );
} }
@ -82,9 +82,7 @@ void XNODE::FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERRO
break; break;
case wxXML_TEXT_NODE: case wxXML_TEXT_NODE:
out->Print( 0, " %s", out->Print( 0, " %s", out->Quoted( GetContent() ).c_str() );
out->Quoted( CONV_TO_UTF8( GetContent() ) ).c_str()
);
break; break;
default: default:

View File

@ -32,12 +32,10 @@ wxString TEMPLATE_FIELDNAME::GetDefaultFieldName( int aFieldNdx )
void TEMPLATE_FIELDNAME::Format( OUTPUTFORMATTER* out, int nestLevel ) const throw( IO_ERROR ) void TEMPLATE_FIELDNAME::Format( OUTPUTFORMATTER* out, int nestLevel ) const throw( IO_ERROR )
{ {
out->Print( nestLevel, "(field (name %s)", out->Print( nestLevel, "(field (name %s)", out->Quoted( m_Name ).c_str() );
out->Quoted( CONV_TO_UTF8(m_Name) ).c_str() );
if( !m_Value.IsEmpty() ) if( !m_Value.IsEmpty() )
out->Print( 0, "(value %s)", out->Print( 0, "(value %s)", out->Quoted( m_Value ).c_str() );
out->Quoted( CONV_TO_UTF8(m_Value) ).c_str() );
if( m_Visible ) if( m_Visible )
out->Print( 0, " visible" ); out->Print( 0, " visible" );
@ -57,7 +55,7 @@ void TEMPLATE_FIELDNAME::Parse( TEMPLATE_FIELDNAMES_LEXER* in ) throw( IO_ERROR
in->NeedSYMBOLorNUMBER(); in->NeedSYMBOLorNUMBER();
m_Name = CONV_FROM_UTF8( in->CurText() ); m_Name = FROM_UTF8( in->CurText() );
in->NeedRIGHT(); // end (name ...) in->NeedRIGHT(); // end (name ...)
@ -71,7 +69,7 @@ void TEMPLATE_FIELDNAME::Parse( TEMPLATE_FIELDNAMES_LEXER* in ) throw( IO_ERROR
{ {
case T_value: case T_value:
in->NeedSYMBOLorNUMBER(); in->NeedSYMBOLorNUMBER();
m_Value = CONV_FROM_UTF8( in->CurText() ); m_Value = FROM_UTF8( in->CurText() );
in->NeedRIGHT(); in->NeedRIGHT();
break; break;
@ -156,14 +154,14 @@ int TEMPLATES::AddTemplateFieldName( const TEMPLATE_FIELDNAME& aFieldName )
if( m_Fields[i].m_Name == aFieldName.m_Name ) if( m_Fields[i].m_Name == aFieldName.m_Name )
{ {
D(printf("inserting template fieldname:'%s' at %d\n", D(printf("inserting template fieldname:'%s' at %d\n",
CONV_TO_UTF8(aFieldName.m_Name), i );) aFieldName.m_Name.utf8_str(), i );)
m_Fields[i] = aFieldName; m_Fields[i] = aFieldName;
return i; // return the container index return i; // return the container index
} }
} }
// D(printf("appending template fieldname:'%s'\n", CONV_TO_UTF8(aFieldName.m_Name) );) // D(printf("appending template fieldname:'%s'\n", aFieldName.m_Name.utf8_str() );)
// the name is legal and not previously added to the config container, append // the name is legal and not previously added to the config container, append
// it and return its index within the container. // it and return its index within the container.

View File

@ -11,7 +11,7 @@
// in order to use UTF8 in Kicad files. // in order to use UTF8 in Kicad files.
// But this change break compatibility with older files under Windows, // But this change break compatibility with older files under Windows,
// if some non ASCII characters are found in strings. // if some non ASCII characters are found in strings.
// So this is a TODO change. // So this is a TODO change. Simply switch to TO_UTF8() and FROM_UTF() then.
#if wxUSE_UNICODE #if wxUSE_UNICODE
#define CONV_TO_UTF8( wxstring ) ( (const char*) wxConvCurrent->cWX2MB( wxstring ) ) #define CONV_TO_UTF8( wxstring ) ( (const char*) wxConvCurrent->cWX2MB( wxstring ) )
#define CONV_FROM_UTF8( utf8string ) ( wxConvCurrent->cMB2WC( utf8string ) ) #define CONV_FROM_UTF8( utf8string ) ( wxConvCurrent->cMB2WC( utf8string ) )
@ -21,6 +21,19 @@
#define CONV_FROM_UTF8( utf8string ) (utf8string) #define CONV_FROM_UTF8( utf8string ) (utf8string)
#endif #endif
/**
* Macro TO_UTF8
* converts a wxString to a UTF8 encoded C string for all wxWidgets build modes.
* wxstring is a wxString, not a wxT() or _(). The scope of the return value
* is very limited and volatile, but can be used with printf() style functions well.
*/
#define TO_UTF8( wxstring ) ( (const char*) (wxstring).utf8_str() )
/**
* Macro FROM_UTF8
* converts a UTF8 encoded C string to a wxString for all wxWidgets build modes.
*/
#define FROM_UTF8( cstring ) wxString::FromUTF8( cstring )
/** /**
* Function GetChars * Function GetChars

View File

@ -489,20 +489,25 @@ public:
* Function Quoted * Function Quoted
* checks \a aWrapee input string for a need to be quoted * checks \a aWrapee input string for a need to be quoted
* (e.g. contains a ')' character or a space), and for \" double quotes * (e.g. contains a ')' character or a space), and for \" double quotes
* within the string that need to be doubled up such that the DSNLEXER * within the string that need to be escaped such that the DSNLEXER
* will correctly parse the string from a file later. * will correctly parse the string from a file later.
* *
* @param aWrapee is a string that might need wraping in double quotes, * @param aWrapee is a string that might need wraping in double quotes,
* and it might need to have its internal quotes doubled up, or not. * and it might need to have its internal content escaped, or not.
* *
* @return std::string - whose c_str() function can be called for passing * @return std::string - whose c_str() function can be called for passing
* to printf() style functions that must output utf8 encoded s-expression streams. * to printf() style functions that output UTF8 encoded s-expression streams.
* @throw IO_ERROR, if aWrapee has any \r or \n bytes in it which is *
* illegal according to the DSNLEXER who does not ever want them * @throw IO_ERROR, if there is any kind of problem with the input string.
* within a string.
*/ */
virtual std::string Quoted( const std::string& aWrapee ) throw( IO_ERROR ); virtual std::string Quoted( const std::string& aWrapee ) throw( IO_ERROR );
std::string Quoted( const wxString& aWrapee ) throw( IO_ERROR )
{
// s-expressions atoms are always encoded as UTF-8
return Quoted( (const char*) aWrapee.utf8_str() );
}
//-----</interface functions>----------------------------------------- //-----</interface functions>-----------------------------------------
}; };

View File

@ -88,7 +88,7 @@ void SPECCTRA_DB::buildLayerMaps( BOARD* aBoard )
kicadLayer2pcb[kilayer] = pcbNdx; kicadLayer2pcb[kilayer] = pcbNdx;
// save the specctra layer name in SPECCTRA_DB::layerIds for later. // save the specctra layer name in SPECCTRA_DB::layerIds for later.
layerIds.push_back( CONV_TO_UTF8( aBoard->GetLayerName( kilayer ) ) ); layerIds.push_back( TO_UTF8( aBoard->GetLayerName( kilayer ) ) );
} }
} }
@ -3404,7 +3404,7 @@ void SPECCTRA_DB::ExportPCB( wxString filename, bool aNameChange ) throw( IO_ERR
STREAM_OUTPUTFORMATTER outputFormatter( os, quote_char[0] ); STREAM_OUTPUTFORMATTER outputFormatter( os, quote_char[0] );
if( aNameChange ) if( aNameChange )
pcb->pcbname = CONV_TO_UTF8(filename); pcb->pcbname = TO_UTF8(filename);
pcb->Format( &outputFormatter, 0 ); pcb->Format( &outputFormatter, 0 );
} }
@ -3600,7 +3600,7 @@ PARSER::PARSER( ELEM* aParent ) :
host_cad = "Kicad's PCBNEW"; host_cad = "Kicad's PCBNEW";
wxString msg = GetBuildVersion(); wxString msg = GetBuildVersion();
host_version = CONV_TO_UTF8(msg); host_version = TO_UTF8(msg);
} }

View File

@ -221,7 +221,7 @@ static DRAWSEGMENT* findPoint( const wxPoint& aPoint, TYPE_COLLECTOR* items )
DRAWSEGMENT* graphic = (DRAWSEGMENT*) (*items)[i]; DRAWSEGMENT* graphic = (DRAWSEGMENT*) (*items)[i];
printf( "type=%s, GetStart()=%d,%d GetEnd()=%d,%d\n", printf( "type=%s, GetStart()=%d,%d GetEnd()=%d,%d\n",
CONV_TO_UTF8( BOARD_ITEM::ShowShape( (Track_Shapes)graphic->m_Shape ) ), TO_UTF8( BOARD_ITEM::ShowShape( (Track_Shapes)graphic->m_Shape ) ),
graphic->GetStart().x, graphic->GetStart().x,
graphic->GetStart().y, graphic->GetStart().y,
graphic->GetEnd().x, graphic->GetEnd().x,
@ -509,7 +509,7 @@ IMAGE* SPECCTRA_DB::makeIMAGE( BOARD* aBoard, MODULE* aModule )
IMAGE* image = new IMAGE(0); IMAGE* image = new IMAGE(0);
image->image_id = CONV_TO_UTF8( aModule->m_LibRef ); image->image_id = TO_UTF8( aModule->m_LibRef );
// from the pads, and make an IMAGE using collated padstacks. // from the pads, and make an IMAGE using collated padstacks.
for( int p=0; p<moduleItems.GetCount(); ++p ) for( int p=0; p<moduleItems.GetCount(); ++p )
@ -558,7 +558,7 @@ IMAGE* SPECCTRA_DB::makeIMAGE( BOARD* aBoard, MODULE* aModule )
PIN* pin = new PIN(image); PIN* pin = new PIN(image);
padName = pad->ReturnStringPadName(); padName = pad->ReturnStringPadName();
pin->pin_id = CONV_TO_UTF8( padName ); pin->pin_id = TO_UTF8( padName );
if( padName!=wxEmptyString && pinmap.find( padName )==pinmap.end() ) if( padName!=wxEmptyString && pinmap.find( padName )==pinmap.end() )
{ {
@ -659,7 +659,7 @@ IMAGE* SPECCTRA_DB::makeIMAGE( BOARD* aBoard, MODULE* aModule )
case S_ARC: case S_ARC:
default: default:
D( printf("makeIMAGE(): unsupported shape %s\n", D( printf("makeIMAGE(): unsupported shape %s\n",
CONV_TO_UTF8( BOARD_ITEM::ShowShape( (Track_Shapes)graphic->m_Shape)) );) TO_UTF8( BOARD_ITEM::ShowShape( (Track_Shapes)graphic->m_Shape)) );)
continue; continue;
} }
} }
@ -932,7 +932,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR )
} }
// if we cannot insert OK, that means the reference has been seen before. // if we cannot insert OK, that means the reference has been seen before.
STRINGSET_PAIR refpair = refs.insert( CONV_TO_UTF8( module->GetReference() ) ); STRINGSET_PAIR refpair = refs.insert( TO_UTF8( module->GetReference() ) );
if( !refpair.second ) // insert failed if( !refpair.second ) // insert failed
{ {
ThrowIOError( _("Multiple components have identical reference IDs of \"%s\"."), ThrowIOError( _("Multiple components have identical reference IDs of \"%s\"."),
@ -1096,7 +1096,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR )
PATH* mainPolygon = new PATH( plane, T_polygon ); PATH* mainPolygon = new PATH( plane, T_polygon );
plane->SetShape( mainPolygon ); plane->SetShape( mainPolygon );
plane->name = CONV_TO_UTF8( item->m_Netname ); plane->name = TO_UTF8( item->m_Netname );
if( plane->name.size() == 0 ) if( plane->name.size() == 0 )
{ {
@ -1181,7 +1181,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR )
NETINFO_ITEM* net = aBoard->m_NetInfo->GetNetItem(ii); NETINFO_ITEM* net = aBoard->m_NetInfo->GetNetItem(ii);
int netcode = net->GetNet(); int netcode = net->GetNet();
if( netcode > 0 ) if( netcode > 0 )
nets[ netcode ]->net_id = CONV_TO_UTF8( net->GetNetname() ); nets[ netcode ]->net_id = TO_UTF8( net->GetNetname() );
} }
items.Collect( aBoard, scanMODULEs ); items.Collect( aBoard, scanMODULEs );
@ -1194,7 +1194,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR )
IMAGE* image = makeIMAGE( aBoard, module ); IMAGE* image = makeIMAGE( aBoard, module );
componentId = CONV_TO_UTF8( module->GetReference() ); componentId = TO_UTF8( module->GetReference() );
// create a net list entry for all the actual pins in the image // create a net list entry for all the actual pins in the image
// for the current module. location of this code is critical // for the current module. location of this code is critical
@ -1241,7 +1241,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR )
place->SetRotation( module->m_Orient/10.0 ); place->SetRotation( module->m_Orient/10.0 );
place->SetVertex( mapPt( module->m_Pos ) ); place->SetVertex( mapPt( module->m_Pos ) );
place->component_id = componentId; place->component_id = componentId;
place->part_number = CONV_TO_UTF8( module->GetValue() ); place->part_number = TO_UTF8( module->GetValue() );
// module is flipped from bottom side, set side to T_back // module is flipped from bottom side, set side to T_back
if( module->flag ) if( module->flag )
@ -1373,7 +1373,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR )
old_netcode = netcode; old_netcode = netcode;
NETINFO_ITEM* net = aBoard->FindNet( netcode ); NETINFO_ITEM* net = aBoard->FindNet( netcode );
wxASSERT( net ); wxASSERT( net );
netname = CONV_TO_UTF8( net->GetNetname() ); netname = TO_UTF8( net->GetNetname() );
} }
WIRE* wire = new WIRE( wiring ); WIRE* wire = new WIRE( wiring );
@ -1435,7 +1435,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR )
NETINFO_ITEM* net = aBoard->FindNet( netcode ); NETINFO_ITEM* net = aBoard->FindNet( netcode );
wxASSERT( net ); wxASSERT( net );
dsnVia->net_id = CONV_TO_UTF8( net->GetNetname() ); dsnVia->net_id = TO_UTF8( net->GetNetname() );
dsnVia->via_type = T_protect; // @todo, this should be configurable dsnVia->via_type = T_protect; // @todo, this should be configurable
} }
@ -1512,10 +1512,10 @@ void SPECCTRA_DB::exportNETCLASS( NETCLASS* aNetClass, BOARD* aBoard )
// freerouter creates a class named 'default' anyway, and if we // freerouter creates a class named 'default' anyway, and if we
// try and use that, we end up with two 'default' via rules so use // try and use that, we end up with two 'default' via rules so use
// something else as the name of our default class. // something else as the name of our default class.
clazz->class_id = CONV_TO_UTF8( aNetClass->GetName() ); clazz->class_id = TO_UTF8( aNetClass->GetName() );
for( NETCLASS::iterator net = aNetClass->begin(); net != aNetClass->end(); ++net ) for( NETCLASS::iterator net = aNetClass->begin(); net != aNetClass->end(); ++net )
clazz->net_ids.push_back( CONV_TO_UTF8( *net ) ); clazz->net_ids.push_back( TO_UTF8( *net ) );
clazz->rules = new RULE( clazz, T_rule ); clazz->rules = new RULE( clazz, T_rule );

View File

@ -200,7 +200,7 @@ TRACK* SPECCTRA_DB::makeTRACK( PATH* aPath, int aPointIndex, int aNetcode ) thro
if( layerNdx == -1 ) if( layerNdx == -1 )
{ {
wxString layerName = CONV_FROM_UTF8( aPath->layer_id.c_str() ); wxString layerName = FROM_UTF8( aPath->layer_id.c_str() );
ThrowIOError( _("Session file uses invalid layer id \"%s\""), ThrowIOError( _("Session file uses invalid layer id \"%s\""),
GetChars(layerName) ); GetChars(layerName) );
} }
@ -308,7 +308,7 @@ SEGVIA* SPECCTRA_DB::makeVIA( PADSTACK* aPadstack, const POINT& aPoint, int aNet
int layerNdx = findLayerName( circle->layer_id ); int layerNdx = findLayerName( circle->layer_id );
if( layerNdx == -1 ) if( layerNdx == -1 )
{ {
wxString layerName = CONV_FROM_UTF8( circle->layer_id.c_str() ); wxString layerName = FROM_UTF8( circle->layer_id.c_str() );
ThrowIOError( _("Session file uses invalid layer id \"%s\""), ThrowIOError( _("Session file uses invalid layer id \"%s\""),
GetChars( layerName ) ); GetChars( layerName ) );
} }
@ -387,7 +387,7 @@ void SPECCTRA_DB::FromSESSION( BOARD* aBoard ) throw( IO_ERROR )
{ {
PLACE* place = &places[i]; // '&' even though places[] holds a pointer! PLACE* place = &places[i]; // '&' even though places[] holds a pointer!
wxString reference = CONV_FROM_UTF8( place->component_id.c_str() ); wxString reference = FROM_UTF8( place->component_id.c_str() );
MODULE* module = aBoard->FindModuleByReference( reference ); MODULE* module = aBoard->FindModuleByReference( reference );
if( !module ) if( !module )
{ {
@ -446,7 +446,7 @@ void SPECCTRA_DB::FromSESSION( BOARD* aBoard ) throw( IO_ERROR )
// page 143 of spec says wire's net_id is optional // page 143 of spec says wire's net_id is optional
if( net->net_id.size() ) if( net->net_id.size() )
{ {
wxString netName = CONV_FROM_UTF8( net->net_id.c_str() ); wxString netName = FROM_UTF8( net->net_id.c_str() );
NETINFO_ITEM* net = aBoard->FindNet( netName ); NETINFO_ITEM* net = aBoard->FindNet( netName );
if( net ) if( net )
@ -471,7 +471,7 @@ void SPECCTRA_DB::FromSESSION( BOARD* aBoard ) throw( IO_ERROR )
We kept our own zones in the BOARD, so ignore this so called We kept our own zones in the BOARD, so ignore this so called
'wire'. 'wire'.
wxString netId = CONV_FROM_UTF8( wire->net_id.c_str() ); wxString netId = FROM_UTF8( wire->net_id.c_str() );
ThrowIOError( ThrowIOError(
_("Unsupported wire shape: \"%s\" for net: \"%s\""), _("Unsupported wire shape: \"%s\" for net: \"%s\""),
DLEX::GetTokenString(shape).GetData(), DLEX::GetTokenString(shape).GetData(),
@ -507,7 +507,7 @@ void SPECCTRA_DB::FromSESSION( BOARD* aBoard ) throw( IO_ERROR )
// page 144 of spec says wire_via's net_id is optional // page 144 of spec says wire_via's net_id is optional
if( net->net_id.size() ) if( net->net_id.size() )
{ {
wxString netName = CONV_FROM_UTF8( net->net_id.c_str() ); wxString netName = FROM_UTF8( net->net_id.c_str() );
NETINFO_ITEM* net = aBoard->FindNet( netName ); NETINFO_ITEM* net = aBoard->FindNet( netName );
if( net ) if( net )
@ -534,7 +534,7 @@ void SPECCTRA_DB::FromSESSION( BOARD* aBoard ) throw( IO_ERROR )
// Could use a STRING_FORMATTER here and convert the entire // Could use a STRING_FORMATTER here and convert the entire
// wire_via to text and put that text into the exception. // wire_via to text and put that text into the exception.
wxString psid( CONV_FROM_UTF8( wire_via->GetPadstackId().c_str() ) ); wxString psid( FROM_UTF8( wire_via->GetPadstackId().c_str() ) );
ThrowIOError( _("A wire_via references a missing padstack \"%s\""), ThrowIOError( _("A wire_via references a missing padstack \"%s\""),
GetChars( psid ) ); GetChars( psid ) );