diff --git a/qa/drc_proto/drc_proto.cpp b/qa/drc_proto/drc_proto.cpp new file mode 100644 index 0000000000..603034f23d --- /dev/null +++ b/qa/drc_proto/drc_proto.cpp @@ -0,0 +1,137 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2019-2020 KiCad Developers, see AUTHORS.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 + */ + +#include + +#include +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include "drc_proto.h" + +PROJECT_CONTEXT loadKicadProject( wxString filename, OPT rulesFilePath ) +{ + PROJECT_CONTEXT rv; + + auto &manager = Pgm().GetSettingsManager(); + + wxFileName pro( filename ); + wxFileName brdName ( filename ); + wxFileName schName ( filename ); + wxFileName ruleFileName ( filename ); + + pro.SetExt( ProjectFileExtension ); + brdName.SetExt( KiCadPcbFileExtension ); + schName.SetExt( KiCadSchematicFileExtension ); + ruleFileName.SetExt( DesignRulesFileExtension ); + + + + brdName.MakeAbsolute(); + schName.MakeAbsolute(); + ruleFileName.MakeAbsolute(); + pro.MakeAbsolute(); + + manager.LoadProject( pro.GetFullPath() ); + + rv.project = &manager.Prj(); + rv.board.reset( KI_TEST::ReadBoardFromFileOrStream( (const char *) brdName.GetFullPath() ).release() ); + rv.board->SetProject( rv.project ); + + if( rulesFilePath ) + rv.rulesFilePath = *rulesFilePath; + else + rv.rulesFilePath = ruleFileName.GetFullPath(); + + + if( wxFileExists( schName.GetFullPath() ) ) + { + //printf("Generating SCH netlist for '%s'\n", (const char*) schName.GetFullPath() ); + //rv.netlist.reset( new NETLIST ); + //generateSchematicNetlist( schName.GetFullPath(), *rv.netlist.get() ); + } + + return rv; +} + + +int runDRCProto( PROJECT_CONTEXT project, std::shared_ptr aDebugOverlay ) +{ + std::shared_ptr drcEngine( new DRC_ENGINE ); + + CONSOLE_LOG consoleLog; + + project.board->GetDesignSettings().m_DRCEngine = drcEngine; + + drcEngine->SetBoard( project.board.get() ); + drcEngine->SetDesignSettings( &project.board->GetDesignSettings() ); + drcEngine->SetLogReporter( new CONSOLE_MSG_REPORTER ( &consoleLog ) ); + drcEngine->SetProgressReporter( new CONSOLE_PROGRESS_REPORTER ( &consoleLog ) ); + + drcEngine->SetViolationHandler( + [&]( const std::shared_ptr& aItem, wxPoint aPos ) + { + // fixme + } ); + + + drcEngine->InitEngine( project.rulesFilePath ); + drcEngine->SetDebugOverlay( aDebugOverlay ); + + for( auto provider : drcEngine->GetTestProviders() ) + { + //if( provider->GetName() == "diff_pair_coupling" ) + // provider->Enable(true); + //else + // provider->Enable(false); + } + + drcEngine->RunTests(); + return 0; +} diff --git a/qa/drc_proto/drc_proto.h b/qa/drc_proto/drc_proto.h new file mode 100644 index 0000000000..5a22232c6c --- /dev/null +++ b/qa/drc_proto/drc_proto.h @@ -0,0 +1,173 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2019-2020 KiCad Developers, see AUTHORS.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 + */ + +#ifndef __DRC_PROTO_H +#define __DRC_PROTO_H + +#include + +#include +#include +#include +#include +#include +#include + +class BOARD; + +class CONSOLE_LOG +{ +public: + enum COLOR { + RED = 0, + GREEN, + DEFAULT + }; + + CONSOLE_LOG() {}; + + void PrintProgress( const wxString& aMessage ) + { + if( m_lastLineIsProgressBar ) + eraseLastLine(); + + printf("%s", (const char *) aMessage.c_str() ); + fflush(stdout); + + m_lastLineIsProgressBar = true; + } + + + void Print( const wxString& aMessage ) + { + if( m_lastLineIsProgressBar ) + eraseLastLine(); + + printf("%s", (const char *) aMessage.c_str() ); + fflush(stdout); + + m_lastLineIsProgressBar = false; + } + + + void SetColor( COLOR color ) + { + std::map colorMap = + { + { RED, "\033[0;31m" }, + { GREEN, "\033[0;32m" }, + { DEFAULT, "\033[0;37m" } + }; + + printf( "%s", (const char*) colorMap[ color ].c_str() ); + fflush(stdout); + } + + +private: + void eraseLastLine() + { + printf("\r\033[K"); + fflush(stdout); + } + + bool m_lastLineIsProgressBar = false; + std::mutex m_lock; +}; + +class CONSOLE_PROGRESS_REPORTER : public PROGRESS_REPORTER +{ +public: + CONSOLE_PROGRESS_REPORTER( CONSOLE_LOG* log ) : + PROGRESS_REPORTER( 0 ), + m_log( log ) {}; + ~CONSOLE_PROGRESS_REPORTER() {}; + + virtual void SetCurrentProgress( double aProgress ) override + { + PROGRESS_REPORTER::SetCurrentProgress( aProgress ); + updateUI(); + } + +private: + virtual bool updateUI() override + { + m_log->SetColor( CONSOLE_LOG::GREEN ); + m_log->PrintProgress( wxString::Format( " | %s : %.02f%%", m_rptMessage, (double) m_progress / (double) m_maxProgress * 100.0 ) ); + return true; + } + + CONSOLE_LOG* m_log; +}; + +class CONSOLE_MSG_REPORTER : public REPORTER +{ +public: + CONSOLE_MSG_REPORTER( CONSOLE_LOG *log ) : + m_log(log) + {}; + ~CONSOLE_MSG_REPORTER() {}; + + + virtual REPORTER& Report( const wxString& aText, SEVERITY aSeverity = RPT_SEVERITY_UNDEFINED ) override + { + switch( aSeverity ) + { + case RPT_SEVERITY_ERROR: + m_log->SetColor( CONSOLE_LOG::RED ); + m_log->Print("ERROR | "); + break; + + default: + m_log->SetColor( CONSOLE_LOG::DEFAULT ); + m_log->Print(" | "); + } + + m_log->SetColor( CONSOLE_LOG::DEFAULT ); + m_log->Print( aText + "\n" ); + return *this; + } + + virtual bool HasMessage() const override + { + return true; + } + +private: + CONSOLE_LOG* m_log; +}; + + +struct PROJECT_CONTEXT { + PROJECT* project; + wxString rulesFilePath; + std::shared_ptr board; + std::shared_ptr netlist; +}; + +PROJECT_CONTEXT loadKicadProject( wxString filename, OPT rulesFilePath ); +int runDRCProto( PROJECT_CONTEXT project, std::shared_ptr aDebugOverlay = nullptr); + +#endif + + diff --git a/qa/drc_proto/test_cases/basic_clearance/board.kicad_dru b/qa/drc_proto/test_cases/basic_clearance/board.kicad_dru new file mode 100644 index 0000000000..bbacaab192 --- /dev/null +++ b/qa/drc_proto/test_cases/basic_clearance/board.kicad_dru @@ -0,0 +1,11 @@ +(version 20200610) + + +(rule "pad2pad_clearance_back" + (condition "A.type == 'Pad' && B.type == 'Pad' && (A.onlayer('B.Cu'))" ) + (constraint clearance (min "1mm") ) +) + +(rule "default" + (constraint clearance (min "0.2mm") ) +) diff --git a/qa/drc_proto/test_cases/basic_clearance/board.kicad_prl b/qa/drc_proto/test_cases/basic_clearance/board.kicad_prl new file mode 100644 index 0000000000..3e87e2ba2a --- /dev/null +++ b/qa/drc_proto/test_cases/basic_clearance/board.kicad_prl @@ -0,0 +1,59 @@ +{ + "board": { + "active_layer": 0, + "active_layer_preset": "", + "hidden_nets": [], + "high_contrast_mode": 0, + "selection_filter": { + "dimensions": true, + "footprints": true, + "graphics": true, + "keepouts": true, + "lockedItems": true, + "otherItems": true, + "pads": true, + "text": true, + "tracks": true, + "vias": true, + "zones": true + }, + "visible_items": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30 + ], + "visible_layers": "0ffff_80000007" + }, + "meta": { + "filename": "board.kicad_prl", + "version": 1 + } +} diff --git a/qa/drc_proto/test_cases/basic_clearance/board.kicad_pro b/qa/drc_proto/test_cases/basic_clearance/board.kicad_pro new file mode 100644 index 0000000000..51574a8181 --- /dev/null +++ b/qa/drc_proto/test_cases/basic_clearance/board.kicad_pro @@ -0,0 +1,179 @@ +{ + "board": { + "design_settings": { + "defaults": { + "board_outline_line_width": 0.2032, + "copper_line_width": 0.30479999999999996, + "copper_text_italic": false, + "copper_text_size_h": 1.524, + "copper_text_size_v": 1.524, + "copper_text_thickness": 0.2032, + "copper_text_upright": false, + "courtyard_line_width": 0.049999999999999996, + "dimension_precision": 1, + "dimension_units": 0, + "fab_line_width": 0.09999999999999999, + "fab_text_italic": false, + "fab_text_size_h": 1.0, + "fab_text_size_v": 1.0, + "fab_text_thickness": 0.15, + "fab_text_upright": false, + "other_line_width": 0.09999999999999999, + "other_text_italic": false, + "other_text_size_h": 1.0, + "other_text_size_v": 1.0, + "other_text_thickness": 0.15, + "other_text_upright": false, + "pads": { + "drill": 3.2, + "height": 7.0, + "width": 7.0 + }, + "silk_line_width": 0.30479999999999996, + "silk_text_italic": false, + "silk_text_size_h": 1.27, + "silk_text_size_v": 1.27, + "silk_text_thickness": 0.2032, + "silk_text_upright": false, + "zones": { + "45_degree_only": false, + "min_clearance": 0.39999999999999997 + } + }, + "diff_pair_dimensions": [ + { + "gap": 0.25, + "via_gap": 0.25, + "width": 0.2 + } + ], + "drc_exclusions": [], + "meta": { + "version": 0 + }, + "rule_severities": { + "clearance": "error", + "copper_edge_clearance": "error", + "courtyards_overlap": "error", + "drill_too_small": "error", + "duplicate_footprints": "warning", + "extra_footprint": "warning", + "hole_near_hole": "error", + "invalid_outline": "error", + "item_on_disabled_layer": "error", + "items_not_allowed": "error", + "keepout": "error", + "malformed_courtyard": "error", + "microvia_drill_too_small": "error", + "microvia_too_small": "error", + "missing_courtyard": "ignore", + "missing_footprint": "warning", + "npth_inside_courtyard": "ignore", + "padstack": "error", + "pth_inside_courtyard": "ignore", + "track_dangling": "warning", + "track_width": "error", + "tracks_crossing": "error", + "unconnected_items": "error", + "unresolved_variable": "error", + "via_annulus": "error", + "via_dangling": "warning", + "via_hole_larger_than_pad": "error", + "via_too_small": "error", + "zone_has_empty_net": "error", + "zones_intersect": "error" + }, + "rules": { + "allow_blind_buried_vias": false, + "allow_microvias": false, + "max_error": 0.005, + "min_clearance": 0.0, + "min_copper_edge_clearance": 0.01, + "min_hole_to_hole": 0.25, + "min_microvia_diameter": 0.508, + "min_microvia_drill": 0.127, + "min_through_hole_diameter": 0.508, + "min_track_width": 0.2032, + "min_via_annulus": 0.049999999999999996, + "min_via_diameter": 0.889, + "solder_mask_clearance": 0.254, + "solder_mask_min_width": 0.0, + "solder_paste_clearance": 0.0, + "solder_paste_margin_ratio": 0.0 + }, + "track_widths": [ + 0.2032 + ], + "via_dimensions": [ + { + "diameter": 0.889, + "drill": 0.635 + } + ], + "zones_use_no_outline": false + }, + "layer_presets": [] + }, + "boards": [], + "cvpcb": { + "equivalence_files": [] + }, + "libraries": { + "pinned_footprint_libs": [], + "pinned_symbol_libs": [] + }, + "meta": { + "filename": "board.kicad_pro", + "version": 1 + }, + "net_settings": { + "classes": [ + { + "clearance": 0.2032, + "diff_pair_gap": 0.25, + "diff_pair_via_gap": 0.25, + "diff_pair_width": 0.2, + "microvia_diameter": 0.508, + "microvia_drill": 0.127, + "name": "Default", + "track_width": 0.2032, + "via_diameter": 0.889, + "via_drill": 0.635 + }, + { + "clearance": 0.2286, + "diff_pair_gap": 0.25, + "diff_pair_via_gap": 0.25, + "diff_pair_width": 0.2, + "microvia_diameter": 0.508, + "microvia_drill": 0.127, + "name": "pwr", + "nets": [], + "track_width": 0.2286, + "via_diameter": 0.889, + "via_drill": 0.635 + } + ], + "meta": { + "version": 0 + }, + "net_colors": null + }, + "pcbnew": { + "last_paths": { + "gencad": "", + "idf": "", + "netlist": "", + "specctra_dsn": "", + "step": "", + "vmrl": "" + }, + "page_layout_descr_file": "" + }, + "schematic": { + "legacy_lib_dir": "", + "legacy_lib_list": [] + }, + "sheets": [], + "text_variables": {} +} diff --git a/qa/drc_proto/test_cases/basic_edge_clearance/board.kicad_dru b/qa/drc_proto/test_cases/basic_edge_clearance/board.kicad_dru new file mode 100644 index 0000000000..d965b75286 --- /dev/null +++ b/qa/drc_proto/test_cases/basic_edge_clearance/board.kicad_dru @@ -0,0 +1,20 @@ +(version 20200610) + +(rule "default" + +( constraint edge_clearance (min "0.5mm") ) + +( constraint silk_pad_clearance (min "0.5mm") ) +( constraint silk_silk_clearance (min "0.5mm") ) + +( constraint diff_pair_width ) +( constraint diff_pair_gap ) +( constraint diff_pair_via_gap ) + +( constraint diff_pair_matched_length ) + +( constraint max_skew ) + +) + + diff --git a/qa/drc_proto/test_cases/basic_edge_clearance/board.kicad_pcb b/qa/drc_proto/test_cases/basic_edge_clearance/board.kicad_pcb new file mode 100644 index 0000000000..83d8a2cbb5 --- /dev/null +++ b/qa/drc_proto/test_cases/basic_edge_clearance/board.kicad_pcb @@ -0,0 +1,310 @@ +(kicad_pcb (version 20200724) (host pcbnew "(5.99.0-2470-gb06c158764-dirty)") + + (general + (thickness 1.6002) + (drawings 7) + (tracks 28) + (modules 6) + (nets 5) + ) + + (paper "A3") + (title_block + (title "KiCad demo") + (date "2015-10-14") + (rev "1.A") + ) + + (layers + (0 "Composant" signal) + (1 "GND_layer" signal) + (2 "VCC_layer" signal) + (31 "Cuivre" signal) + (32 "B.Adhes" user) + (33 "F.Adhes" user) + (34 "B.Paste" user) + (35 "F.Paste" user) + (36 "B.SilkS" user) + (37 "F.SilkS" user) + (38 "B.Mask" user) + (39 "F.Mask" user) + (40 "Dwgs.User" user) + (41 "Cmts.User" user) + (42 "Eco1.User" user) + (43 "Eco2.User" user) + (44 "Edge.Cuts" user) + (45 "Margin" user) + (46 "B.CrtYd" user) + (47 "F.CrtYd" user) + ) + + (setup + (aux_axis_origin 40.9 173.1) + (pcbplotparams + (layerselection 0x010fc_80000007) + (usegerberextensions false) + (usegerberattributes true) + (usegerberadvancedattributes true) + (creategerberjobfile true) + (svguseinch false) + (svgprecision 6) + (excludeedgelayer false) + (linewidth 0.100000) + (plotframeref false) + (viasonmask false) + (mode 1) + (useauxorigin true) + (hpglpennumber 1) + (hpglpenspeed 20) + (hpglpendiameter 15.000000) + (psnegative false) + (psa4output false) + (plotreference true) + (plotvalue true) + (plotinvisibletext false) + (sketchpadsonfab false) + (subtractmaskfromsilk false) + (outputformat 1) + (mirror false) + (drillshape 0) + (scaleselection 1) + (outputdirectory "plots") + ) + ) + + (net 0 "") + (net 1 "Net1") + (net 2 "Net2") + (net 3 "Net3") + (net 4 "Net4") + + (module "lib_smd:SM1206" (layer "Composant") (tedit 5F1AFF3A) (tstamp 00000000-0000-0000-0000-00005402cf81) + (at 60.66 26.51 90) + (path "/00000000-0000-0000-0000-00004bf0367f/00000000-0000-0000-0000-000022760f80") + (attr smd) + (fp_text reference "R10" (at 0 0 270) (layer "F.SilkS") + (effects (font (size 0.762 0.762) (thickness 0.127))) + (tstamp da150652-2846-4482-abb7-c0153df1f1a8) + ) + (fp_text value "1K" (at 0 0 270) (layer "F.SilkS") hide + (effects (font (size 0.762 0.762) (thickness 0.127))) + (tstamp 26e96a7d-01f3-41ea-bd97-088bbd1adcfe) + ) + (fp_line (start -2.54 1.143) (end -0.889 1.143) (layer "F.SilkS") (width 0.127) (tstamp 0a6ed827-a1ce-421c-ad38-d3ad8173b150)) + (fp_line (start 2.54 -1.143) (end 2.54 1.143) (layer "F.SilkS") (width 0.127) (tstamp 2c5feb20-7cc1-4bde-a850-7bb547935d76)) + (fp_line (start -2.54 -1.143) (end -2.54 1.143) (layer "F.SilkS") (width 0.127) (tstamp 2d82e9f5-8a6a-4092-a430-eba549476e82)) + (fp_line (start 0.889 -1.143) (end 2.54 -1.143) (layer "F.SilkS") (width 0.127) (tstamp 2fb22259-68fc-4e9c-9acd-32e139163ab4)) + (fp_line (start 2.54 1.143) (end 0.889 1.143) (layer "F.SilkS") (width 0.127) (tstamp adcd8f67-5bbf-4fc5-b2cb-d0930aba6332)) + (fp_line (start -0.889 -1.143) (end -2.54 -1.143) (layer "F.SilkS") (width 0.127) (tstamp ec40258a-ce28-4182-a8a4-90e0beaa79f4)) + (pad "1" thru_hole rect (at -1.651 0 90) (size 1.524 2.032) (drill 1) (layers *.Cu *.Mask) + (net 2 "Net2") (tstamp d85d64ec-0c45-4808-b66c-a6e95250cd7d)) + (pad "2" smd rect (at 1.651 0 90) (size 1.524 2.032) (layers "Composant" "F.Paste" "F.Mask") + (net 4 "Net4") (tstamp b1cfb053-add6-4c39-a602-ee8cec92ed6d)) + (model "SMD_Packages.3dshapes/SMD-1206.wrl" + (at (xyz 0 0 0)) + (scale (xyz 0.17 0.16 0.16)) + (rotate (xyz 0 0 0)) + ) + ) + + (module "lib_smd:SM1206" (layer "Composant") (tedit 54019107) (tstamp 00000000-0000-0000-0000-00005402cf8c) + (at 57.26 50.29 -90) + (path "/00000000-0000-0000-0000-00004bf0367f/00000000-0000-0000-0000-000022760fbc") + (attr smd) + (fp_text reference "R11" (at 0 0 90) (layer "F.SilkS") + (effects (font (size 0.762 0.762) (thickness 0.127))) + (tstamp 32be642b-937a-4421-8813-4374c03e1d6b) + ) + (fp_text value "1K" (at 0 0 90) (layer "F.SilkS") hide + (effects (font (size 0.762 0.762) (thickness 0.127))) + (tstamp 1816928c-17d7-48ce-bee8-1741317d10ac) + ) + (fp_line (start 0.889 -1.143) (end 2.54 -1.143) (layer "F.SilkS") (width 0.127) (tstamp 2b9557e5-e0b3-423c-86ee-54738cae7bd2)) + (fp_line (start 2.54 -1.143) (end 2.54 1.143) (layer "F.SilkS") (width 0.127) (tstamp 31d6a4c9-c879-4883-9ae6-151f2ee7b0f1)) + (fp_line (start -2.54 1.143) (end -0.889 1.143) (layer "F.SilkS") (width 0.127) (tstamp 64afb3d7-59d9-480f-8afe-2fad3014a2c2)) + (fp_line (start -0.889 -1.143) (end -2.54 -1.143) (layer "F.SilkS") (width 0.127) (tstamp 8efd779d-1807-4503-80d0-0ebe2419b838)) + (fp_line (start -2.54 -1.143) (end -2.54 1.143) (layer "F.SilkS") (width 0.127) (tstamp a15f31b1-286c-4230-833f-ecb13c2a63b7)) + (fp_line (start 2.54 1.143) (end 0.889 1.143) (layer "F.SilkS") (width 0.127) (tstamp c4588b05-d768-4848-92eb-0ce90965459b)) + (pad "1" smd rect (at -1.651 0 270) (size 1.524 2.032) (layers "Composant" "F.Paste" "F.Mask") + (net 3 "Net3") (tstamp aa67310d-5884-4d05-8dcf-bf41060498ff)) + (pad "2" smd rect (at 1.651 0 270) (size 1.524 2.032) (layers "Composant" "F.Paste" "F.Mask") + (net 1 "Net1") (tstamp 11cb9d3f-10e3-41e4-b53f-517fc40917f8)) + (model "SMD_Packages.3dshapes/SMD-1206.wrl" + (at (xyz 0 0 0)) + (scale (xyz 0.17 0.16 0.16)) + (rotate (xyz 0 0 0)) + ) + ) + + (module "lib_smd:SM1206" (layer "Composant") (tedit 5F1AFF3A) (tstamp 62f63c2d-5de7-4136-94e8-8bc3f03545b5) + (at 53.56 43.68 90) + (path "/00000000-0000-0000-0000-00004bf0367f/00000000-0000-0000-0000-000022760f80") + (attr smd) + (fp_text reference "R10" (at 0 0 270) (layer "F.SilkS") + (effects (font (size 0.762 0.762) (thickness 0.127))) + (tstamp c97d29fa-3f85-4a3a-95c1-1cbc45fb9e1e) + ) + (fp_text value "1K" (at 0 0 270) (layer "F.SilkS") hide + (effects (font (size 0.762 0.762) (thickness 0.127))) + (tstamp 50091b90-a4f6-4cfc-b220-05ab2fec5964) + ) + (fp_line (start 0.889 -1.143) (end 2.54 -1.143) (layer "F.SilkS") (width 0.127) (tstamp 4d5698b8-7842-481b-a7bd-33b032fd3a13)) + (fp_line (start -2.54 1.143) (end -0.889 1.143) (layer "F.SilkS") (width 0.127) (tstamp 6003f482-46ce-4725-9a26-272441c23cbb)) + (fp_line (start 2.54 -1.143) (end 2.54 1.143) (layer "F.SilkS") (width 0.127) (tstamp 63a8aa6b-e16e-41fa-838b-ee00c835b4eb)) + (fp_line (start -0.889 -1.143) (end -2.54 -1.143) (layer "F.SilkS") (width 0.127) (tstamp 72181855-ec9b-4540-b21a-8ae1df278ae4)) + (fp_line (start -2.54 -1.143) (end -2.54 1.143) (layer "F.SilkS") (width 0.127) (tstamp a8fdd33d-4066-49a5-ad54-1c695bc743c0)) + (fp_line (start 2.54 1.143) (end 0.889 1.143) (layer "F.SilkS") (width 0.127) (tstamp eaf060d2-a6fa-45b6-a910-72c92e1bd176)) + (pad "1" thru_hole rect (at -1.651 0 90) (size 1.524 2.032) (drill 1) (layers *.Cu *.Mask) + (net 2 "Net2") (tstamp d85d64ec-0c45-4808-b66c-a6e95250cd7d)) + (pad "2" smd rect (at 1.651 0 90) (size 1.524 2.032) (layers "Composant" "F.Paste" "F.Mask") + (net 4 "Net4") (tstamp b1cfb053-add6-4c39-a602-ee8cec92ed6d)) + (model "SMD_Packages.3dshapes/SMD-1206.wrl" + (at (xyz 0 0 0)) + (scale (xyz 0.17 0.16 0.16)) + (rotate (xyz 0 0 0)) + ) + ) + + (module "lib_smd:SM1206" (layer "Cuivre") (tedit 5F1AFEB3) (tstamp 6839e320-e6b8-495a-b2b3-9c17db9c24c2) + (at 77.29 47.42 -90) + (path "/00000000-0000-0000-0000-00004bf0367f/00000000-0000-0000-0000-000022760fbc") + (attr smd) + (fp_text reference "R11" (at 0 0 -90) (layer "B.SilkS") + (effects (font (size 0.762 0.762) (thickness 0.127)) (justify mirror)) + (tstamp 6c9d5d75-5381-4e16-be31-56c62e953955) + ) + (fp_text value "1K" (at 0 0 -90) (layer "B.SilkS") hide + (effects (font (size 0.762 0.762) (thickness 0.127)) (justify mirror)) + (tstamp cfc24072-932d-476a-8799-bc855bcd6f94) + ) + (fp_text user "${REFERENCE}" (at 0 0 -90) (layer "B.SilkS") + (effects (font (size 0.762 0.762) (thickness 0.127)) (justify mirror)) + (tstamp 98aaf6f4-aeff-490d-b426-ed3ea79e409e) + ) + (fp_text user "${VALUE}" (at 0 0 -90) (layer "B.SilkS") hide + (effects (font (size 0.762 0.762) (thickness 0.127)) (justify mirror)) + (tstamp a7ff2e67-23da-4026-aa9c-8fbbcd438cd7) + ) + (fp_line (start 2.54 1.143) (end 2.54 -1.143) (layer "B.SilkS") (width 0.127) (tstamp 243c1190-748e-40da-b135-52c103061a9a)) + (fp_line (start -2.54 -1.143) (end -0.889 -1.143) (layer "B.SilkS") (width 0.127) (tstamp 5ad8dcc3-639a-4ff4-b812-cadfbd3c45eb)) + (fp_line (start 0.889 1.143) (end 2.54 1.143) (layer "B.SilkS") (width 0.127) (tstamp 966d9104-e5b2-4af0-8380-c0cc1b472081)) + (fp_line (start 2.54 -1.143) (end 0.889 -1.143) (layer "B.SilkS") (width 0.127) (tstamp 9fe32d4e-cd36-4621-86dc-04b40ea28488)) + (fp_line (start -0.889 1.143) (end -2.54 1.143) (layer "B.SilkS") (width 0.127) (tstamp bbef550f-3d7b-40c5-a369-a92fdb131d09)) + (fp_line (start -2.54 1.143) (end -2.54 -1.143) (layer "B.SilkS") (width 0.127) (tstamp c4f75699-5c60-43be-9273-447f7e937019)) + (pad "1" thru_hole rect (at -1.651 0 270) (size 1.524 2.032) (drill 1) (layers *.Cu *.Mask) + (net 3 "Net3") (tstamp aa67310d-5884-4d05-8dcf-bf41060498ff)) + (pad "2" smd rect (at 1.651 0 270) (size 1.524 2.032) (layers "Cuivre" "B.Paste" "B.Mask") + (net 1 "Net1") (tstamp 11cb9d3f-10e3-41e4-b53f-517fc40917f8)) + (model "SMD_Packages.3dshapes/SMD-1206.wrl" + (at (xyz 0 0 0)) + (scale (xyz 0.17 0.16 0.16)) + (rotate (xyz 0 0 0)) + ) + ) + + (module "lib_smd:SM1206" (layer "Cuivre") (tedit 54019107) (tstamp 7878478d-dbff-4e07-9acb-bbb7715fff75) + (at 74.75 42.046 -90) + (path "/00000000-0000-0000-0000-00004bf0367f/00000000-0000-0000-0000-000022760f80") + (attr smd) + (fp_text reference "R10" (at 0 0 -270) (layer "B.SilkS") + (effects (font (size 0.762 0.762) (thickness 0.127)) (justify mirror)) + (tstamp d9a9766d-8462-45d0-84af-44eb0b8b676f) + ) + (fp_text value "1K" (at 0 0 -270) (layer "B.SilkS") hide + (effects (font (size 0.762 0.762) (thickness 0.127)) (justify mirror)) + (tstamp 9379d568-7c3d-4b0f-af91-d304a27665b2) + ) + (fp_line (start 2.54 1.143) (end 2.54 -1.143) (layer "B.SilkS") (width 0.127) (tstamp 01d8d962-fa7d-487b-a13f-d91a1785d8fe)) + (fp_line (start 0.889 1.143) (end 2.54 1.143) (layer "B.SilkS") (width 0.127) (tstamp 47f13511-dbc0-4eaf-958d-38f9d6411b11)) + (fp_line (start -0.889 1.143) (end -2.54 1.143) (layer "B.SilkS") (width 0.127) (tstamp 9c5ebfe9-a9a1-4c67-af77-8473bbc20a8b)) + (fp_line (start 2.54 -1.143) (end 0.889 -1.143) (layer "B.SilkS") (width 0.127) (tstamp a0decc16-4599-4964-b22c-a8a9d1c62b3e)) + (fp_line (start -2.54 1.143) (end -2.54 -1.143) (layer "B.SilkS") (width 0.127) (tstamp c2160f97-eccd-4065-9e35-a39ec0935a8c)) + (fp_line (start -2.54 -1.143) (end -0.889 -1.143) (layer "B.SilkS") (width 0.127) (tstamp d98fa1cd-3e0c-4d59-96a9-182045b4db05)) + (pad "1" smd rect (at -1.651 0 270) (size 1.524 2.032) (layers "Cuivre" "B.Paste" "B.Mask") + (net 2 "Net2") (tstamp d85d64ec-0c45-4808-b66c-a6e95250cd7d)) + (pad "2" smd rect (at 1.651 0 270) (size 1.524 2.032) (layers "Cuivre" "B.Paste" "B.Mask") + (net 4 "Net4") (tstamp b1cfb053-add6-4c39-a602-ee8cec92ed6d)) + (model "SMD_Packages.3dshapes/SMD-1206.wrl" + (at (xyz 0 0 0)) + (scale (xyz 0.17 0.16 0.16)) + (rotate (xyz 0 0 0)) + ) + ) + + (module "lib_smd:SM1206" (layer "Cuivre") (tedit 5F1AFEB3) (tstamp cf6d41b6-be24-4142-a50b-7bf0419214d3) + (at 77.31 42.02 90) + (path "/00000000-0000-0000-0000-00004bf0367f/00000000-0000-0000-0000-000022760fbc") + (attr smd) + (fp_text reference "R11" (at 0 0 -90) (layer "B.SilkS") + (effects (font (size 0.762 0.762) (thickness 0.127)) (justify mirror)) + (tstamp bd7c394f-e3f3-4c3b-9fc1-b2dbd95bcba2) + ) + (fp_text value "1K" (at 0 0 -90) (layer "B.SilkS") hide + (effects (font (size 0.762 0.762) (thickness 0.127)) (justify mirror)) + (tstamp 5db512ad-3a40-4e1b-95c7-676959a6f69e) + ) + (fp_text user "${REFERENCE}" (at -0.08 3.02 -90) (layer "B.SilkS") + (effects (font (size 0.762 0.762) (thickness 0.127)) (justify mirror)) + (tstamp a4c51c66-f116-4f86-8760-bf1bfbdfca4e) + ) + (fp_text user "${VALUE}" (at -0.08 3.02 -90) (layer "B.SilkS") hide + (effects (font (size 0.762 0.762) (thickness 0.127)) (justify mirror)) + (tstamp ee9d8cf5-f63a-45f5-aeeb-574c34bd7676) + ) + (fp_line (start 2.54 1.143) (end 2.54 -1.143) (layer "B.SilkS") (width 0.127) (tstamp 1c3b4780-a468-4611-98e3-08b03761e1a9)) + (fp_line (start -2.54 -1.143) (end -0.889 -1.143) (layer "B.SilkS") (width 0.127) (tstamp 2f28c98b-3003-41fb-bf3c-c8060c15ddb3)) + (fp_line (start -0.889 1.143) (end -2.54 1.143) (layer "B.SilkS") (width 0.127) (tstamp 39d92047-85c9-48de-8284-5b1ca983b249)) + (fp_line (start -2.54 1.143) (end -2.54 -1.143) (layer "B.SilkS") (width 0.127) (tstamp 59330c43-31b9-48e2-89d7-5502209ecf10)) + (fp_line (start 2.54 -1.143) (end 0.889 -1.143) (layer "B.SilkS") (width 0.127) (tstamp 65a55daf-02a0-4605-9ca9-60f0378ab577)) + (fp_line (start 0.889 1.143) (end 2.54 1.143) (layer "B.SilkS") (width 0.127) (tstamp c996da25-315b-4992-9a2d-fb11e18eefb1)) + (pad "1" thru_hole rect (at -1.651 0 90) (size 1.524 2.032) (drill 1) (layers *.Cu *.Mask) + (net 3 "Net3") (tstamp aa67310d-5884-4d05-8dcf-bf41060498ff)) + (pad "2" smd rect (at 1.651 0 90) (size 1.524 2.032) (layers "Cuivre" "B.Paste" "B.Mask") + (net 1 "Net1") (tstamp 11cb9d3f-10e3-41e4-b53f-517fc40917f8)) + (model "SMD_Packages.3dshapes/SMD-1206.wrl" + (at (xyz 0 0 0)) + (scale (xyz 0.17 0.16 0.16)) + (rotate (xyz 0 0 0)) + ) + ) + + (gr_line (start 56.68 23.92) (end 78.67 29.48) (layer "Edge.Cuts") (width 0.2032) (tstamp 474b8fab-d96d-474a-8c61-c7e2227329f8)) + (gr_line (start 78.59 29.47) (end 86.44 39.17) (layer "Edge.Cuts") (width 0.2032) (tstamp 5840e644-6b66-44f1-845b-59fe9e9bb901)) + (gr_line (start 75.97 61.76) (end 47.64 56.73) (layer "Edge.Cuts") (width 0.2032) (tstamp 676cd0a0-0234-4236-888b-4a7984fb9c70)) + (gr_line (start 47.64 56.73) (end 45.28 39.94) (layer "Edge.Cuts") (width 0.2032) (tstamp 67c6ebce-4603-490b-a1e3-1a9ac74324f1)) + (gr_line (start 86.44 39.17) (end 75.97 61.76) (layer "Edge.Cuts") (width 0.2032) (tstamp d2f503b1-ed74-4d31-a991-bd9656ff581e)) + (gr_line (start 45.28 39.94) (end 56.68 23.92) (layer "Edge.Cuts") (width 0.2032) (tstamp f8679be3-5fc7-4d34-9446-82eee2eee5bf)) + (gr_text "Dupa" (at 69.51 27.22) (layer "F.SilkS") (tstamp 1c39f03d-97a7-46d9-9bed-38e617c3b619) + (effects (font (size 1.524 1.524) (thickness 0.2032)) (justify mirror)) + ) + + (segment (start 61.7 47.13) (end 61.7 46.24) (width 0.2032) (layer "Composant") (net 1) (tstamp 2911a49d-d9ac-4dad-8965-d7abcbd48932)) + (segment (start 62.67077 45.26923) (end 65.01834 45.26923) (width 0.2032) (layer "Composant") (net 1) (tstamp 5223ac82-4207-4e56-8f80-fc8163229ff2)) + (segment (start 61.7 46.24) (end 62.67077 45.26923) (width 0.2032) (layer "Composant") (net 1) (tstamp 78574693-36f7-41c3-8372-1beb483f4919)) + (segment (start 57.26 51.941) (end 57.26 51.57) (width 0.2032) (layer "Composant") (net 1) (tstamp 8a8d348d-69c0-4919-a6e5-75f8709b0d4b)) + (segment (start 65.01834 45.26923) (end 64.87 45.26923) (width 0.2032) (layer "Composant") (net 1) (tstamp f3f895af-921c-4405-9d2c-a994ff46a36e)) + (segment (start 57.26 51.57) (end 61.7 47.13) (width 0.2032) (layer "Composant") (net 1) (tstamp f694334e-a9e7-4d5c-a90b-b15a26d06084)) + (segment (start 77.31 39.77) (end 84.88 32.2) (width 0.2032) (layer "Cuivre") (net 1) (tstamp 054c3a3d-6273-48aa-b503-07ff4f30ed20)) + (segment (start 77.31 40.369) (end 77.31 40.03) (width 0.2032) (layer "Cuivre") (net 1) (tstamp 44d2121f-742d-41b0-b6c7-957e6c8e6fa4)) + (segment (start 84.88 32.2) (end 84.88 32.19) (width 0.2032) (layer "Cuivre") (net 1) (tstamp 6693b7e0-4787-4a5c-bdfa-1148a6c61bcd)) + (segment (start 77.31 40.369) (end 77.31 39.77) (width 0.2032) (layer "Cuivre") (net 1) (tstamp a4ee6832-cebc-44f0-9404-95c1a8125935)) + (segment (start 65.95641 44.45641) (end 66.48 44.98) (width 0.2032) (layer "Composant") (net 2) (tstamp 14bb23f7-15be-43d6-82ba-05802d6e870c)) + (segment (start 74.11 44.98) (end 74.75 44.34) (width 0.2032) (layer "Composant") (net 2) (tstamp 33b71764-2dee-43d4-862d-4ce8ab506b73)) + (segment (start 74.75 44.34) (end 74.75 40.395) (width 0.2032) (layer "Composant") (net 2) (tstamp 34677ff2-0a86-43cc-8da2-df756ebaf399)) + (segment (start 66.48 44.98) (end 74.11 44.98) (width 0.2032) (layer "Composant") (net 2) (tstamp 58870eeb-1ee8-4365-81f6-644d10260a70)) + (segment (start 60.40359 44.45641) (end 60.89166 44.45641) (width 0.2032) (layer "Composant") (net 2) (tstamp 8e2d1065-302e-482f-81b6-3d31d0643e24)) + (segment (start 59.523 45.337) (end 60.40359 44.45641) (width 0.2032) (layer "Composant") (net 2) (tstamp c954b2e0-51d2-4950-8f2a-7143adff5865)) + (segment (start 57.26 45.337) (end 59.523 45.337) (width 0.2032) (layer "Composant") (net 2) (tstamp ef9660dc-199b-4386-8c7f-92cec3d85773)) + (segment (start 60.89166 44.45641) (end 65.95641 44.45641) (width 0.2032) (layer "Composant") (net 2) (tstamp efec1be9-cdeb-40da-a27f-a503d55d30a2)) + (via (at 74.75 40.395) (size 0.889) (drill 0.635) (layers "Composant" "Cuivre") (net 2) (tstamp 2ee707fc-c4c2-436b-9f8a-082000400e64)) + (segment (start 57.26 48.639) (end 61.03618 44.86282) (width 0.2032) (layer "Composant") (net 3) (tstamp 18e8fb07-1048-4440-81bf-85c3063dee17)) + (segment (start 61.03618 44.86282) (end 64.85 44.86282) (width 0.2032) (layer "Composant") (net 3) (tstamp eac47d05-6561-4d3b-88a5-073ca5967b09)) + (segment (start 67.26 44.05) (end 67.56 43.75) (width 0.2032) (layer "Composant") (net 4) (tstamp 3b16deb7-8d8e-44b8-b5c1-b34386add5b7)) + (segment (start 65.86 44.05) (end 67.26 44.05) (width 0.2032) (layer "Composant") (net 4) (tstamp 4f87807d-8760-44de-8181-8c3a080a5a75)) + (segment (start 59.045 42.035) (end 61.06 44.05) (width 0.2032) (layer "Composant") (net 4) (tstamp 6d7d1289-6535-423f-a199-f228105c6d91)) + (segment (start 57.26 42.035) (end 59.045 42.035) (width 0.2032) (layer "Composant") (net 4) (tstamp 75276ab2-082f-49bf-89bf-cb2785abb992)) + (segment (start 61.06 44.05) (end 65.86 44.05) (width 0.2032) (layer "Composant") (net 4) (tstamp 84f97f24-934c-4869-a0a5-9b902def1b2b)) + (segment (start 67.56 43.75) (end 72.99 43.75) (width 0.2032) (layer "Composant") (net 4) (tstamp ae29a614-f3a7-4e3a-8466-54ac0eb68621)) + (via (at 72.99 43.75) (size 0.889) (drill 0.635) (layers "Composant" "Cuivre") (net 4) (tstamp 3a8e56c3-5066-45b4-9519-5a33d6834af0)) + +) diff --git a/qa/drc_proto/test_cases/basic_edge_clearance/board.kicad_prl b/qa/drc_proto/test_cases/basic_edge_clearance/board.kicad_prl new file mode 100644 index 0000000000..e4d189676e --- /dev/null +++ b/qa/drc_proto/test_cases/basic_edge_clearance/board.kicad_prl @@ -0,0 +1,66 @@ +{ + "board": { + "active_layer": 31, + "active_layer_preset": "", + "hidden_nets": [], + "high_contrast_mode": 0, + "net_color_mode": 1, + "opacity": { + "pads": 1.0, + "tracks": 1.0, + "vias": 1.0, + "zones": 1.0 + }, + "selection_filter": { + "dimensions": true, + "footprints": true, + "graphics": true, + "keepouts": true, + "lockedItems": true, + "otherItems": true, + "pads": true, + "text": true, + "tracks": true, + "vias": true, + "zones": true + }, + "visible_items": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30 + ], + "visible_layers": "0ffff_80000007" + }, + "meta": { + "filename": "board.kicad_prl", + "version": 2 + } +} diff --git a/qa/drc_proto/test_cases/basic_edge_clearance/board.kicad_pro b/qa/drc_proto/test_cases/basic_edge_clearance/board.kicad_pro new file mode 100644 index 0000000000..b9dd1a9682 --- /dev/null +++ b/qa/drc_proto/test_cases/basic_edge_clearance/board.kicad_pro @@ -0,0 +1,186 @@ +{ + "board": { + "design_settings": { + "defaults": { + "board_outline_line_width": 0.2032, + "copper_line_width": 0.30479999999999996, + "copper_text_italic": false, + "copper_text_size_h": 1.524, + "copper_text_size_v": 1.524, + "copper_text_thickness": 0.2032, + "copper_text_upright": false, + "courtyard_line_width": 0.049999999999999996, + "dimension_precision": 1, + "dimension_units": 0, + "fab_line_width": 0.09999999999999999, + "fab_text_italic": false, + "fab_text_size_h": 1.0, + "fab_text_size_v": 1.0, + "fab_text_thickness": 0.15, + "fab_text_upright": false, + "other_line_width": 0.09999999999999999, + "other_text_italic": false, + "other_text_size_h": 1.0, + "other_text_size_v": 1.0, + "other_text_thickness": 0.15, + "other_text_upright": false, + "pads": { + "drill": 1.0, + "height": 2.032, + "width": 1.524 + }, + "silk_line_width": 0.30479999999999996, + "silk_text_italic": false, + "silk_text_size_h": 1.27, + "silk_text_size_v": 1.27, + "silk_text_thickness": 0.2032, + "silk_text_upright": false, + "zones": { + "45_degree_only": false, + "min_clearance": 0.39999999999999997 + } + }, + "diff_pair_dimensions": [ + { + "gap": 0.25, + "via_gap": 0.25, + "width": 0.2 + } + ], + "drc_exclusions": [], + "meta": { + "version": 0 + }, + "rule_severities": { + "clearance": "error", + "copper_edge_clearance": "error", + "courtyards_overlap": "error", + "drill_too_small": "error", + "duplicate_footprints": "warning", + "extra_footprint": "warning", + "hole_near_hole": "error", + "invalid_outline": "error", + "item_on_disabled_layer": "error", + "items_not_allowed": "error", + "keepout": "error", + "malformed_courtyard": "error", + "microvia_drill_too_small": "error", + "microvia_too_small": "error", + "missing_courtyard": "ignore", + "missing_footprint": "warning", + "npth_inside_courtyard": "ignore", + "padstack": "error", + "pth_inside_courtyard": "ignore", + "shorting_items": "error", + "track_dangling": "warning", + "track_width": "error", + "tracks_crossing": "error", + "unconnected_items": "error", + "unresolved_variable": "error", + "via_annulus": "error", + "via_dangling": "warning", + "via_hole_larger_than_pad": "error", + "via_too_small": "error", + "zone_has_empty_net": "error", + "zones_intersect": "error" + }, + "rules": { + "allow_blind_buried_vias": false, + "allow_microvias": false, + "max_error": 0.005, + "min_clearance": 0.0, + "min_copper_edge_clearance": 0.01, + "min_hole_to_hole": 0.25, + "min_microvia_diameter": 0.508, + "min_microvia_drill": 0.127, + "min_through_hole_diameter": 0.508, + "min_track_width": 0.2032, + "min_via_annulus": 0.049999999999999996, + "min_via_diameter": 0.889, + "solder_mask_clearance": 0.254, + "solder_mask_min_width": 0.0, + "solder_paste_clearance": 0.0, + "solder_paste_margin_ratio": 0.0 + }, + "track_widths": [ + 0.2032 + ], + "via_dimensions": [ + { + "diameter": 0.889, + "drill": 0.635 + } + ], + "zones_use_no_outline": false + }, + "layer_presets": [] + }, + "boards": [], + "cvpcb": { + "equivalence_files": [] + }, + "libraries": { + "pinned_footprint_libs": [], + "pinned_symbol_libs": [] + }, + "meta": { + "filename": "board.kicad_pro", + "version": 1 + }, + "net_settings": { + "classes": [ + { + "bus_width": 6.0, + "clearance": 0.2032, + "diff_pair_gap": 0.25, + "diff_pair_via_gap": 0.25, + "diff_pair_width": 0.2, + "line_style": 0, + "microvia_diameter": 0.508, + "microvia_drill": 0.127, + "name": "Default", + "track_width": 0.2032, + "via_diameter": 0.889, + "via_drill": 0.635, + "wire_width": 6.0 + }, + { + "bus_width": 6.0, + "clearance": 0.2286, + "diff_pair_gap": 0.25, + "diff_pair_via_gap": 0.25, + "diff_pair_width": 0.2, + "line_style": 0, + "microvia_diameter": 0.508, + "microvia_drill": 0.127, + "name": "pwr", + "nets": [], + "track_width": 0.2286, + "via_diameter": 0.889, + "via_drill": 0.635, + "wire_width": 6.0 + } + ], + "meta": { + "version": 0 + }, + "net_colors": null + }, + "pcbnew": { + "last_paths": { + "gencad": "", + "idf": "", + "netlist": "./", + "specctra_dsn": "", + "step": "", + "vmrl": "" + }, + "page_layout_descr_file": "" + }, + "schematic": { + "legacy_lib_dir": "", + "legacy_lib_list": [] + }, + "sheets": [], + "text_variables": {} +} diff --git a/qa/qa_utils/test_app_main.cpp b/qa/qa_utils/test_app_main.cpp new file mode 100644 index 0000000000..0b2b185b35 --- /dev/null +++ b/qa/qa_utils/test_app_main.cpp @@ -0,0 +1,272 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2014 SoftPLC Corporation, Dick Hollenbeck + * Copyright (C) 2014 KiCad Developers, see CHANGELOG.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 + */ + + +/* + + This is a program launcher for a single KIFACE DSO. It only mimics a KIWAY, + not actually implements one, since only a single DSO is supported by it. + + It is compiled multiple times, once for each standalone program and as such + gets different compiler command line supplied #defines from CMake. + +*/ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + + +static struct IFACE : public KIFACE_I +{ + // Of course all are overloads, implementations of the KIFACE. + + IFACE( const char* aName, KIWAY::FACE_T aType ) : + KIFACE_I( aName, aType ) + {} + + bool OnKifaceStart( PGM_BASE* aProgram, int aCtlBits ) override + { + return true; + } + + void OnKifaceEnd() override {} + + wxWindow* CreateWindow( wxWindow* aParent, int aClassId, KIWAY* aKiway, int aCtlBits = 0 ) override + { + assert( false ); + return nullptr; + } + + /** + * Function IfaceOrAddress + * return a pointer to the requested object. The safest way to use this + * is to retrieve a pointer to a static instance of an interface, similar to + * how the KIFACE interface is exported. But if you know what you are doing + * use it to retrieve anything you want. + * + * @param aDataId identifies which object you want the address of. + * + * @return void* - and must be cast into the know type. + */ + void* IfaceOrAddress( int aDataId ) override + { + return NULL; + } +} +kiface( "pcb_test_frame", KIWAY::FACE_PCB ); + +KIWAY Kiway( &Pgm(), KFCTL_STANDALONE ); + +static struct PGM_TEST_FRAME : public PGM_BASE +{ + bool OnPgmInit(); + + void OnPgmExit() + { + printf("Destroy\n"); + Kiway.OnKiwayEnd(); + + // Destroy everything in PGM_BASE, especially wxSingleInstanceCheckerImpl + // earlier than wxApp and earlier than static destruction would. + PGM_BASE::Destroy(); + } + + + void MacOpenFile( const wxString& aFileName ) override + { + wxFileName filename( aFileName ); + + if( filename.FileExists() ) + { + #if 0 + // this pulls in EDA_DRAW_FRAME type info, which we don't want in + // the single_top link image. + KIWAY_PLAYER* frame = dynamic_cast( App().GetTopWindow() ); + #else + KIWAY_PLAYER* frame = (KIWAY_PLAYER*) App().GetTopWindow(); + #endif + + if( frame ) + frame->OpenProjectFiles( std::vector( 1, aFileName ) ); + } + } +} +program; + +PGM_BASE& Pgm() +{ + return program; +} + + +// Similar to PGM_BASE& Pgm(), but return nullptr when a *.ki_face +// is run from a python script, mot from a Kicad application +PGM_BASE* PgmOrNull() +{ + return &program; +} + + +KIFACE_I& Kiface() +{ + return kiface; +} + +/** + * Struct APP_SINGLE_TOP + * implements a bare naked wxApp (so that we don't become dependent on + * functionality in a wxApp derivative that we cannot deliver under wxPython). + */ +struct APP_TEST : public wxApp +{ + APP_TEST() + {} + + bool OnInit() override + { + + try + { + if( !program.OnPgmInit() ) + { + program.OnPgmExit(); + return false; + } + + + KI_TEST::COMBINED_UTILITY c_util; + auto app = wxApp::GetInstance(); + auto ret = c_util.HandleCommandLine( app->argc, app->argv ); + + if( ret != KI_TEST::RET_CODES::OK) + return false; + + return true; + } + catch( const std::exception& e ) + { + wxLogError( wxT( "Unhandled exception class: %s what: %s" ), + GetChars( FROM_UTF8( typeid(e).name() )), + GetChars( FROM_UTF8( e.what() ) ) ); + } + catch( const IO_ERROR& ioe ) + { + wxLogError( GetChars( ioe.What() ) ); + } + catch(...) + { + wxLogError( wxT( "Unhandled exception of unknown type" ) ); + } + + program.OnPgmExit(); + + + + return false; + } + + int OnExit() override + { + program.OnPgmExit(); + return wxApp::OnExit(); + } + + int OnRun() override + { + int ret = -1; + + try + { + ret = wxApp::OnRun(); + } + catch( const std::exception& e ) + { + wxLogError( wxT( "Unhandled exception class: %s what: %s" ), + GetChars( FROM_UTF8( typeid(e).name() )), + GetChars( FROM_UTF8( e.what() ) ) ); + } + catch( const IO_ERROR& ioe ) + { + wxLogError( GetChars( ioe.What() ) ); + } + catch(...) + { + wxLogError( wxT( "Unhandled exception of unknown type" ) ); + } + + program.OnPgmExit(); + return ret; + } +}; + + +bool PGM_TEST_FRAME::OnPgmInit() +{ + if( !InitPgm() ) + return false; + + return true; +} + +void SetTopFrame ( wxFrame* aFrame ) +{ + Pgm().App().SetTopWindow( aFrame ); // wxApp gets a face. + aFrame->Show(); +} + +IMPLEMENT_APP_NO_MAIN(APP_TEST); + +#ifndef TEST_APP_NO_MAIN + +int main( int argc, char** argv ) +{ + wxInitialize( argc, argv ); + + Pgm().InitPgm(); + + auto ret = wxEntry( argc, argv ); + + // This causes some glib warnings on GTK3 (http://trac.wxwidgets.org/ticket/18274) + // but without it, Valgrind notices a lot of leaks from WX + wxUninitialize(); + + return ret; +} + +#endif \ No newline at end of file