freerouting/src/main/java/eu/mihosoft/freerouting/designformats/specctra/RulesFile.java

322 lines
12 KiB
Java

/*
* Copyright (C) 2014 Alfons Wirtz
* website www.freerouting.net
*
* 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 3 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 at <http://www.gnu.org/licenses/>
* for more details.
*
* RulesFile.java
*
* Created on 18. Juli 2005, 07:07
*
*/
package designformats.specctra;
import datastructures.IndentFileWriter;
import board.BasicBoard;
/**
* File for saving the board rules, so that they can be restored after the Board
* is creates anew from the host system.
*
* @author Alfons Wirtz
*/
public class RulesFile
{
public static void write(interactive.BoardHandling p_board_handling, java.io.OutputStream p_output_stream, String p_design_name)
{
IndentFileWriter output_file = new IndentFileWriter(p_output_stream);
BasicBoard routing_board = p_board_handling.get_routing_board();
WriteScopeParameter write_scope_parameter =
new WriteScopeParameter(routing_board, p_board_handling.settings.autoroute_settings,
output_file, routing_board.communication.specctra_parser_info.string_quote,
routing_board.communication.coordinate_transform, false);
try
{
write_rules(write_scope_parameter, p_design_name);
}
catch (java.io.IOException e)
{
System.out.println("unable to write rules to file");
}
try
{
output_file.close();
}
catch (java.io.IOException e)
{
System.out.println("unable to close rules file");
}
}
public static boolean read(java.io.InputStream p_input_stream, String p_design_name,
interactive.BoardHandling p_board_handling)
{
BasicBoard routing_board = p_board_handling.get_routing_board();
Scanner scanner = new SpecctraFileScanner(p_input_stream);
try
{
Object curr_token = scanner.next_token();
if (curr_token != Keyword.OPEN_BRACKET)
{
System.out.println("RulesFile.read: open bracket expected");
return false;
}
curr_token = scanner.next_token();
if (curr_token != Keyword.RULES)
{
System.out.println("RulesFile.read: keyword rules expected");
return false;
}
curr_token = scanner.next_token();
if (curr_token != Keyword.PCB_SCOPE)
{
System.out.println("RulesFile.read: keyword pcb expected");
return false;
}
scanner.yybegin(SpecctraFileScanner.NAME);
curr_token = scanner.next_token();
if (!(curr_token instanceof String) || !((String) curr_token).equals(p_design_name))
{
System.out.println("RulesFile.read: design_name not matching");
return false;
}
}
catch (java.io.IOException e)
{
System.out.println("RulesFile.read: IO error scanning file");
return false;
}
LayerStructure layer_structure = new LayerStructure(routing_board.layer_structure);
CoordinateTransform coordinate_transform = routing_board.communication.coordinate_transform;
Object next_token = null;
for (;;)
{
Object prev_token = next_token;
try
{
next_token = scanner.next_token();
}
catch (java.io.IOException e)
{
System.out.println("RulesFile.read: IO error scanning file");
return false;
}
if (next_token == null)
{
System.out.println("Structure.read_scope: unexpected end of file");
return false;
}
if (next_token == Keyword.CLOSED_BRACKET)
{
// end of scope
break;
}
boolean read_ok = true;
if (prev_token == Keyword.OPEN_BRACKET)
{
if (next_token == Keyword.RULE)
{
add_rules(Rule.read_scope(scanner), routing_board, null);
}
else if (next_token == Keyword.LAYER)
{
add_layer_rules(scanner, routing_board);
}
else if (next_token == Keyword.PADSTACK)
{
Library.read_padstack_scope(scanner, layer_structure, coordinate_transform, routing_board.library.padstacks);
}
else if (next_token == Keyword.VIA)
{
read_via_info(scanner, routing_board);
}
else if (next_token == Keyword.VIA_RULE)
{
read_via_rule(scanner, routing_board);
}
else if (next_token == Keyword.CLASS)
{
read_net_class(scanner, layer_structure, routing_board);
}
else if (next_token == Keyword.SNAP_ANGLE)
{
board.AngleRestriction snap_angle = Structure.read_snap_angle(scanner);
if (snap_angle != null)
{
routing_board.rules.set_trace_angle_restriction(snap_angle);
}
}
else if (next_token == Keyword.AUTOROUTE_SETTINGS)
{
interactive.AutorouteSettings autoroute_settings
= AutorouteSettings.read_scope(scanner, layer_structure);
if (autoroute_settings != null)
{
p_board_handling.settings.autoroute_settings = autoroute_settings;
}
}
else
{
ScopeKeyword.skip_scope(scanner);
}
}
if (!read_ok)
{
return false;
}
}
return true;
}
private static void write_rules( WriteScopeParameter p_par, String p_design_name) throws java.io.IOException
{
p_par.file.start_scope();
p_par.file.write("rules PCB ");
p_par.file.write(p_design_name);
Structure.write_snap_angle(p_par.file, p_par.board.rules.get_trace_angle_restriction());
AutorouteSettings.write_scope(p_par.file, p_par.autoroute_settings,
p_par.board.layer_structure, p_par.identifier_type);
// write the default rule using 0 as default layer.
Rule.write_default_rule(p_par, 0);
// write the via padstacks
for (int i = 1; i <= p_par.board.library.padstacks.count(); ++i)
{
library.Padstack curr_padstack = p_par.board.library.padstacks.get(i);
if (p_par.board.library.get_via_padstack(curr_padstack.name )!= null)
{
Library.write_padstack_scope(p_par, curr_padstack);
}
}
Network.write_via_infos(p_par.board.rules, p_par.file, p_par.identifier_type);
Network.write_via_rules(p_par.board.rules, p_par.file, p_par.identifier_type);
Network.write_net_classes(p_par);
p_par.file.end_scope();
}
private static void add_rules(java.util.Collection<Rule> p_rules, BasicBoard p_board, String p_layer_name)
{
int layer_no = -1;
if (p_layer_name != null)
{
layer_no = p_board.layer_structure.get_no(p_layer_name);
if (layer_no < 0)
{
System.out.println("RulesFile.add_rules: layer not found");
}
}
CoordinateTransform coordinate_transform = p_board.communication.coordinate_transform;
String string_quote = p_board.communication.specctra_parser_info.string_quote;
for (Rule curr_rule : p_rules)
{
if (curr_rule instanceof Rule.WidthRule)
{
double wire_width = ((Rule.WidthRule)curr_rule).value;
int trace_halfwidth = (int) Math.round(coordinate_transform.dsn_to_board(wire_width) / 2);
if (layer_no < 0)
{
p_board.rules.set_default_trace_half_widths(trace_halfwidth);
}
else
{
p_board.rules.set_default_trace_half_width(layer_no, trace_halfwidth);
}
}
else if (curr_rule instanceof Rule.ClearanceRule)
{
Structure.set_clearance_rule(( Rule.ClearanceRule)curr_rule, layer_no, coordinate_transform, p_board.rules, string_quote);
}
}
}
private static boolean add_layer_rules(Scanner p_scanner, BasicBoard p_board)
{
try
{
Object next_token = p_scanner.next_token();
if (!(next_token instanceof String))
{
System.out.println("RulesFile.add_layer_rules: String expected");
return false;
}
String layer_string = (String) next_token;
next_token = p_scanner.next_token();
while (next_token != Keyword.CLOSED_BRACKET)
{
if (next_token != Keyword.OPEN_BRACKET)
{
System.out.println("RulesFile.add_layer_rules: ( expected");
return false;
}
next_token = p_scanner.next_token();
if (next_token == Keyword.RULE)
{
java.util.Collection<Rule> curr_rules = Rule.read_scope(p_scanner);
add_rules(curr_rules, p_board, layer_string);
}
else
{
ScopeKeyword.skip_scope(p_scanner);
}
next_token = p_scanner.next_token();
}
return true;
}
catch (java.io.IOException e)
{
System.out.println("RulesFile.add_layer_rules: IO error scanning file");
return false;
}
}
private static boolean read_via_info(Scanner p_scanner, BasicBoard p_board)
{
rules.ViaInfo curr_via_info = Network.read_via_info(p_scanner, p_board);
if (curr_via_info == null)
{
return false;
}
rules.ViaInfo existing_via = p_board.rules.via_infos.get(curr_via_info.get_name());
if (existing_via != null)
{
// replace existing via info
p_board.rules.via_infos.remove(existing_via);
}
p_board.rules.via_infos.add(curr_via_info);
return true;
}
private static boolean read_via_rule(Scanner p_scanner, BasicBoard p_board)
{
java.util.Collection<String> via_rule = Network.read_via_rule(p_scanner, p_board);
if (via_rule == null)
{
return false;
}
Network.add_via_rule(via_rule, p_board);
return true;
}
private static boolean read_net_class(Scanner p_scanner, LayerStructure p_layer_structure, BasicBoard p_board)
{
NetClass curr_class = NetClass.read_scope(p_scanner);
if (curr_class == null)
{
return false;
}
Network.insert_net_class(curr_class, p_layer_structure, p_board, p_board.communication.coordinate_transform, false);
return true;
}
}