384 lines
13 KiB
Java
384 lines
13 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.
|
|
*
|
|
* Rule.java
|
|
*
|
|
* Created on 1. Juni 2004, 09:27
|
|
*/
|
|
|
|
package designformats.specctra;
|
|
|
|
import java.util.Collection;
|
|
import java.util.LinkedList;
|
|
|
|
|
|
/**
|
|
* Class for reading and writing rule scopes from dsn-files.
|
|
*
|
|
* @author Alfons Wirtz
|
|
*/
|
|
public abstract class Rule
|
|
{
|
|
/**
|
|
* Returns a collection of objects of class Rule.
|
|
*/
|
|
public static Collection<Rule> read_scope( Scanner p_scanner)
|
|
{
|
|
Collection<Rule> result = new LinkedList<Rule>();
|
|
Object next_token = null;
|
|
for (;;)
|
|
{
|
|
Object prev_token = next_token;
|
|
try
|
|
{
|
|
next_token = p_scanner.next_token();
|
|
}
|
|
catch (java.io.IOException e)
|
|
{
|
|
System.out.println("Rule.read_scope: IO error scanning file");
|
|
System.out.println(e);
|
|
return null;
|
|
}
|
|
if (next_token == null)
|
|
{
|
|
System.out.println("Rule.read_scope: unexpected end of file");
|
|
return null;
|
|
}
|
|
if (next_token == Keyword.CLOSED_BRACKET)
|
|
{
|
|
// end of scope
|
|
break;
|
|
}
|
|
if (prev_token == Keyword.OPEN_BRACKET)
|
|
{
|
|
Rule curr_rule = null;
|
|
if (next_token == Keyword.WIDTH)
|
|
{
|
|
curr_rule = read_width_rule(p_scanner);
|
|
}
|
|
else if (next_token == Keyword.CLEARANCE)
|
|
{
|
|
curr_rule = read_clearance_rule(p_scanner);
|
|
}
|
|
else
|
|
{
|
|
ScopeKeyword.skip_scope(p_scanner);
|
|
}
|
|
if (curr_rule != null)
|
|
{
|
|
result.add(curr_rule);
|
|
}
|
|
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Reads a LayerRule from dsn-file.
|
|
*/
|
|
public static LayerRule read_layer_rule_scope( Scanner p_scanner)
|
|
{
|
|
try
|
|
{
|
|
Collection<String> layer_names = new LinkedList<String>();
|
|
Collection<Rule> rule_list = new LinkedList<Rule>();
|
|
for (;;)
|
|
{
|
|
p_scanner.yybegin(SpecctraFileScanner.LAYER_NAME);
|
|
Object next_token = p_scanner.next_token();
|
|
if (next_token == Keyword.OPEN_BRACKET)
|
|
{
|
|
break;
|
|
}
|
|
if (!(next_token instanceof String))
|
|
{
|
|
|
|
System.out.println("Rule.read_layer_rule_scope: string expected");
|
|
return null;
|
|
}
|
|
layer_names.add((String) next_token);
|
|
}
|
|
for (;;)
|
|
{
|
|
Object next_token = p_scanner.next_token();
|
|
if (next_token == Keyword.CLOSED_BRACKET)
|
|
{
|
|
break;
|
|
}
|
|
if (next_token != Keyword.RULE)
|
|
{
|
|
|
|
System.out.println("Rule.read_layer_rule_scope: rule expected");
|
|
return null;
|
|
}
|
|
rule_list.addAll(read_scope(p_scanner));
|
|
}
|
|
return new LayerRule(layer_names, rule_list);
|
|
}
|
|
catch (java.io.IOException e)
|
|
{
|
|
System.out.println("Rule.read_layer_rule_scope: IO error scanning file");
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public static WidthRule read_width_rule(Scanner p_scanner)
|
|
{
|
|
try
|
|
{
|
|
double value;
|
|
Object next_token = p_scanner.next_token();
|
|
if (next_token instanceof Double)
|
|
{
|
|
value = ((Double) next_token).doubleValue();
|
|
}
|
|
else if (next_token instanceof Integer)
|
|
{
|
|
value = ((Integer) next_token).intValue();
|
|
}
|
|
else
|
|
{
|
|
System.out.println("Rule.read_width_rule: number expected");
|
|
return null;
|
|
}
|
|
next_token = p_scanner.next_token();
|
|
if (next_token != Keyword.CLOSED_BRACKET)
|
|
{
|
|
System.out.println("Rule.read_width_rule: closing bracket expected");
|
|
return null;
|
|
}
|
|
return new WidthRule(value);
|
|
}
|
|
catch (java.io.IOException e)
|
|
{
|
|
System.out.println("Rule.read_width_rule: IO error scanning file");
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public static void write_scope(rules.NetClass p_net_class, WriteScopeParameter p_par) throws java.io.IOException
|
|
{
|
|
p_par.file.start_scope();
|
|
p_par.file.write("rule");
|
|
|
|
// write the trace width
|
|
int default_trace_half_width = p_net_class.get_trace_half_width(0);
|
|
double trace_width = 2 * p_par.coordinate_transform.board_to_dsn(default_trace_half_width);
|
|
p_par.file.new_line();
|
|
p_par.file.write("(width ");
|
|
p_par.file.write((new Double(trace_width)).toString());
|
|
p_par.file.write(")");
|
|
p_par.file.end_scope();
|
|
for (int i = 1; i < p_par.board.layer_structure.arr.length; ++i)
|
|
{
|
|
if (p_net_class.get_trace_half_width(i) != default_trace_half_width)
|
|
{
|
|
write_layer_rule(p_net_class, i, p_par);
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void write_layer_rule(rules.NetClass p_net_class, int p_layer_no, WriteScopeParameter p_par) throws java.io.IOException
|
|
{
|
|
p_par.file.start_scope();
|
|
p_par.file.write("layer_rule ");
|
|
|
|
board.Layer curr_board_layer = p_par.board.layer_structure.arr[p_layer_no];
|
|
|
|
p_par.file.write(curr_board_layer.name);
|
|
p_par.file.start_scope();
|
|
p_par.file.write("rule ");
|
|
|
|
int curr_trace_half_width = p_net_class.get_trace_half_width(p_layer_no);
|
|
|
|
// write the trace width
|
|
double trace_width = 2 * p_par.coordinate_transform.board_to_dsn(curr_trace_half_width);
|
|
p_par.file.new_line();
|
|
p_par.file.write("(width ");
|
|
p_par.file.write((new Double(trace_width)).toString());
|
|
p_par.file.write(") ");
|
|
p_par.file.end_scope();
|
|
p_par.file.end_scope();
|
|
}
|
|
|
|
/**
|
|
* Writes the default rule as a scope to an output dsn-file.
|
|
*/
|
|
public static void write_default_rule(WriteScopeParameter p_par, int p_layer) throws java.io.IOException
|
|
{
|
|
p_par.file.start_scope();
|
|
p_par.file.write("rule");
|
|
// write the trace width
|
|
double trace_width = 2 * p_par.coordinate_transform.board_to_dsn(p_par.board.rules.get_default_net_class().get_trace_half_width(0));
|
|
p_par.file.new_line();
|
|
p_par.file.write("(width ");
|
|
p_par.file.write((new Double(trace_width)).toString());
|
|
p_par.file.write(")");
|
|
// write the default clearance rule
|
|
int default_cl_no = rules.BoardRules.default_clearance_class();
|
|
int default_board_clearance = p_par.board.rules.clearance_matrix.value(default_cl_no, default_cl_no, p_layer);
|
|
double default_clearance = p_par.coordinate_transform.board_to_dsn(default_board_clearance);
|
|
p_par.file.new_line();
|
|
p_par.file.write("(clear ");
|
|
p_par.file.write((new Double(default_clearance)).toString());
|
|
p_par.file.write(")");
|
|
// write the Smd_to_turn_gap
|
|
Double smd_to_turn_dist = p_par.coordinate_transform.board_to_dsn(p_par.board.rules.get_pin_edge_to_turn_dist());
|
|
p_par.file.new_line();
|
|
p_par.file.write("(clear ");
|
|
p_par.file.write(smd_to_turn_dist.toString());
|
|
p_par.file.write(" (type smd_to_turn_gap))");
|
|
int cl_count = p_par.board.rules.clearance_matrix.get_class_count();
|
|
for (int i = 1; i <= cl_count; ++i)
|
|
{
|
|
write_clearance_rules(p_par, p_layer, i, cl_count, default_board_clearance);
|
|
}
|
|
p_par.file.end_scope();
|
|
}
|
|
|
|
/**
|
|
* Write the clearance rules, which are different from the default clearance.
|
|
*/
|
|
private static void write_clearance_rules(WriteScopeParameter p_par,
|
|
int p_layer, int p_cl_class, int p_max_cl_class, int p_default_clearance) throws java.io.IOException
|
|
{
|
|
rules.ClearanceMatrix cl_matrix = p_par.board.rules.clearance_matrix;
|
|
for (int i = p_cl_class; i < p_max_cl_class; ++i)
|
|
{
|
|
int curr_board_clearance = cl_matrix.value(p_cl_class, i, p_layer);
|
|
if (curr_board_clearance == p_default_clearance)
|
|
{
|
|
continue;
|
|
}
|
|
double curr_clearance = p_par.coordinate_transform.board_to_dsn(curr_board_clearance);
|
|
p_par.file.new_line();
|
|
p_par.file.write("(clear ");
|
|
p_par.file.write((new Double(curr_clearance)).toString());
|
|
p_par.file.write(" (type ");
|
|
p_par.identifier_type.write(cl_matrix.get_name(p_cl_class), p_par.file);
|
|
p_par.file.write("_");
|
|
p_par.identifier_type.write(cl_matrix.get_name(i), p_par.file);
|
|
p_par.file.write("))");
|
|
}
|
|
}
|
|
|
|
public static ClearanceRule read_clearance_rule(Scanner p_scanner)
|
|
{
|
|
try
|
|
{
|
|
double value;
|
|
Object next_token = p_scanner.next_token();
|
|
if (next_token instanceof Double)
|
|
{
|
|
value = ((Double) next_token).doubleValue();
|
|
}
|
|
else if (next_token instanceof Integer)
|
|
{
|
|
value = ((Integer) next_token).intValue();
|
|
}
|
|
else
|
|
{
|
|
System.out.println("Rule.read_clearance_rule: number expected");
|
|
return null;
|
|
}
|
|
Collection<String> class_pairs = new LinkedList<String> ();
|
|
next_token = p_scanner.next_token();
|
|
if (next_token != Keyword.CLOSED_BRACKET)
|
|
{
|
|
if (next_token != Keyword.OPEN_BRACKET)
|
|
{
|
|
System.out.println("Rule.read_clearance_rule: ( expected");
|
|
return null;
|
|
}
|
|
next_token = p_scanner.next_token();
|
|
if (next_token != Keyword.TYPE)
|
|
{
|
|
System.out.println("Rule.read_clearance_rule: type expected");
|
|
return null;
|
|
}
|
|
for (;;)
|
|
{
|
|
p_scanner.yybegin(SpecctraFileScanner.IGNORE_QUOTE);
|
|
next_token = p_scanner.next_token();
|
|
if (next_token == Keyword.CLOSED_BRACKET)
|
|
{
|
|
break;
|
|
}
|
|
if (!(next_token instanceof String))
|
|
{
|
|
System.out.println("Rule.read_clearance_rule: string expected");
|
|
return null;
|
|
}
|
|
class_pairs.add((String)next_token);
|
|
}
|
|
next_token = p_scanner.next_token();
|
|
if (next_token != Keyword.CLOSED_BRACKET)
|
|
{
|
|
System.out.println("Rule.read_clearance_rule: closing bracket expected");
|
|
return null;
|
|
}
|
|
}
|
|
return new ClearanceRule(value, class_pairs);
|
|
}
|
|
catch (java.io.IOException e)
|
|
{
|
|
System.out.println("Rule.read_clearance_rule: IO error scanning file");
|
|
return null;
|
|
}
|
|
|
|
}
|
|
|
|
static public void write_item_clearance_class( String p_name, datastructures.IndentFileWriter p_file,
|
|
datastructures.IdentifierType p_identifier_type) throws java.io.IOException
|
|
{
|
|
p_file.new_line();
|
|
p_file.write("(clearance_class ");
|
|
p_identifier_type.write(p_name, p_file);
|
|
p_file.write(")");
|
|
}
|
|
|
|
public static class WidthRule extends Rule
|
|
{
|
|
public WidthRule(double p_value)
|
|
{
|
|
value = p_value;
|
|
}
|
|
final double value;
|
|
}
|
|
|
|
public static class ClearanceRule extends Rule
|
|
{
|
|
public ClearanceRule(double p_value, Collection<String> p_class_pairs)
|
|
{
|
|
value = p_value;
|
|
clearance_class_pairs = p_class_pairs;
|
|
}
|
|
final double value;
|
|
final Collection<String> clearance_class_pairs;
|
|
}
|
|
|
|
public static class LayerRule
|
|
{
|
|
LayerRule(Collection<String> p_layer_names, Collection<Rule> p_rules)
|
|
{
|
|
layer_names = p_layer_names;
|
|
rules = p_rules;
|
|
}
|
|
final Collection<String> layer_names;
|
|
final Collection<Rule> rules;
|
|
}
|
|
}
|