diff --git a/eeschema/sch_pin.cpp b/eeschema/sch_pin.cpp index 6fa987a590..ff34fa1661 100644 --- a/eeschema/sch_pin.cpp +++ b/eeschema/sch_pin.cpp @@ -308,25 +308,15 @@ void SCH_PIN::SetType( ELECTRICAL_PINTYPE aType ) wxString SCH_PIN::GetCanonicalElectricalTypeName() const { - if( m_type != ELECTRICAL_PINTYPE::PT_INHERIT ) - return ::GetCanonicalElectricalTypeName( m_type ); - - if( !m_libPin ) - return ::GetCanonicalElectricalTypeName( ELECTRICAL_PINTYPE::PT_UNSPECIFIED ); - - return m_libPin->GetCanonicalElectricalTypeName(); + // Use GetType() which correctly handles alternates + return ::GetCanonicalElectricalTypeName( GetType() ); } wxString SCH_PIN::GetElectricalTypeName() const { - if( m_type != ELECTRICAL_PINTYPE::PT_INHERIT ) - return ElectricalPinTypeGetText( m_type ); - - if( !m_libPin ) - return ElectricalPinTypeGetText( ELECTRICAL_PINTYPE::PT_UNSPECIFIED ); - - return m_libPin->GetElectricalTypeName(); + // Use GetType() which correctly handles alternates + return ElectricalPinTypeGetText( GetType() ); } @@ -1186,7 +1176,7 @@ void SCH_PIN::PlotPinType( PLOTTER *aPlotter, const VECTOR2I &aPosition, y1 + ( MapY1 + MapX1 ) * deco_size ) ); } - if( m_type == ELECTRICAL_PINTYPE::PT_NC ) // Draw a N.C. symbol + if( GetType() == ELECTRICAL_PINTYPE::PT_NC ) // Draw a N.C. symbol { const int deco_size = TARGET_PIN_RADIUS; const int ex1 = aPosition.x; diff --git a/qa/data/eeschema/issue22286/bugtest.kicad_pro b/qa/data/eeschema/issue22286/bugtest.kicad_pro new file mode 100644 index 0000000000..1aea9f022e --- /dev/null +++ b/qa/data/eeschema/issue22286/bugtest.kicad_pro @@ -0,0 +1,660 @@ +{ + "board": { + "3dviewports": [], + "design_settings": { + "defaults": { + "apply_defaults_to_fp_barcodes": false, + "apply_defaults_to_fp_dimensions": false, + "apply_defaults_to_fp_fields": false, + "apply_defaults_to_fp_shapes": false, + "apply_defaults_to_fp_text": false, + "board_outline_line_width": 0.05, + "copper_line_width": 0.2, + "copper_text_italic": false, + "copper_text_size_h": 1.5, + "copper_text_size_v": 1.5, + "copper_text_thickness": 0.3, + "copper_text_upright": false, + "courtyard_line_width": 0.05, + "dimension_precision": 4, + "dimension_units": 3, + "dimensions": { + "arrow_length": 1270000, + "extension_offset": 500000, + "keep_text_aligned": true, + "suppress_zeroes": true, + "text_position": 0, + "units_format": 0 + }, + "fab_line_width": 0.1, + "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.1, + "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": 0.8, + "height": 1.27, + "width": 2.54 + }, + "silk_line_width": 0.1, + "silk_text_italic": false, + "silk_text_size_h": 1.0, + "silk_text_size_v": 1.0, + "silk_text_thickness": 0.1, + "silk_text_upright": false, + "zones": { + "min_clearance": 0.5 + } + }, + "diff_pair_dimensions": [], + "drc_exclusions": [], + "meta": { + "version": 2 + }, + "rule_severities": { + "annular_width": "error", + "clearance": "error", + "connection_width": "warning", + "copper_edge_clearance": "error", + "copper_sliver": "warning", + "courtyards_overlap": "error", + "creepage": "error", + "diff_pair_gap_out_of_range": "error", + "diff_pair_uncoupled_length_too_long": "error", + "drill_out_of_range": "error", + "duplicate_footprints": "warning", + "extra_footprint": "warning", + "footprint": "error", + "footprint_filters_mismatch": "ignore", + "footprint_symbol_field_mismatch": "warning", + "footprint_symbol_mismatch": "warning", + "footprint_type_mismatch": "ignore", + "hole_clearance": "error", + "hole_to_hole": "warning", + "holes_co_located": "warning", + "invalid_outline": "error", + "isolated_copper": "warning", + "item_on_disabled_layer": "error", + "items_not_allowed": "error", + "length_out_of_range": "error", + "lib_footprint_issues": "warning", + "lib_footprint_mismatch": "warning", + "malformed_courtyard": "error", + "microvia_drill_out_of_range": "error", + "mirrored_text_on_front_layer": "warning", + "missing_courtyard": "ignore", + "missing_footprint": "warning", + "missing_tuning_profile": "warning", + "net_conflict": "warning", + "nonmirrored_text_on_back_layer": "warning", + "npth_inside_courtyard": "ignore", + "padstack": "warning", + "pth_inside_courtyard": "ignore", + "shorting_items": "error", + "silk_edge_clearance": "warning", + "silk_over_copper": "warning", + "silk_overlap": "warning", + "skew_out_of_range": "error", + "solder_mask_bridge": "error", + "starved_thermal": "error", + "text_height": "warning", + "text_on_edge_cuts": "error", + "text_thickness": "warning", + "through_hole_pad_without_hole": "error", + "too_many_vias": "error", + "track_angle": "error", + "track_dangling": "warning", + "track_on_post_machined_layer": "error", + "track_segment_length": "error", + "track_width": "error", + "tracks_crossing": "error", + "tuning_profile_track_geometries": "ignore", + "unconnected_items": "error", + "unresolved_variable": "error", + "via_dangling": "warning", + "zones_intersect": "error" + }, + "rules": { + "max_error": 0.005, + "min_clearance": 0.0, + "min_connection": 0.0, + "min_copper_edge_clearance": 0.5, + "min_groove_width": 0.0, + "min_hole_clearance": 0.25, + "min_hole_to_hole": 0.25, + "min_microvia_diameter": 0.2, + "min_microvia_drill": 0.1, + "min_resolved_spokes": 2, + "min_silk_clearance": 0.0, + "min_text_height": 0.8, + "min_text_thickness": 0.08, + "min_through_hole_diameter": 0.3, + "min_track_width": 0.0, + "min_via_annular_width": 0.1, + "min_via_diameter": 0.5, + "solder_mask_to_copper_clearance": 0.0, + "use_height_for_length_calcs": true + }, + "teardrop_options": [ + { + "td_onpthpad": true, + "td_onroundshapesonly": false, + "td_onsmdpad": true, + "td_ontrackend": false, + "td_onvia": true + } + ], + "teardrop_parameters": [ + { + "td_allow_use_two_tracks": true, + "td_curve_segcount": 0, + "td_height_ratio": 1.0, + "td_length_ratio": 0.5, + "td_maxheight": 2.0, + "td_maxlen": 1.0, + "td_on_pad_in_zone": false, + "td_target_name": "td_round_shape", + "td_width_to_size_filter_ratio": 0.9 + }, + { + "td_allow_use_two_tracks": true, + "td_curve_segcount": 0, + "td_height_ratio": 1.0, + "td_length_ratio": 0.5, + "td_maxheight": 2.0, + "td_maxlen": 1.0, + "td_on_pad_in_zone": false, + "td_target_name": "td_rect_shape", + "td_width_to_size_filter_ratio": 0.9 + }, + { + "td_allow_use_two_tracks": true, + "td_curve_segcount": 0, + "td_height_ratio": 1.0, + "td_length_ratio": 0.5, + "td_maxheight": 2.0, + "td_maxlen": 1.0, + "td_on_pad_in_zone": false, + "td_target_name": "td_track_end", + "td_width_to_size_filter_ratio": 0.9 + } + ], + "track_widths": [], + "tuning_pattern_settings": { + "diff_pair_defaults": { + "corner_radius_percentage": 80, + "corner_style": 1, + "max_amplitude": 1.0, + "min_amplitude": 0.2, + "single_sided": false, + "spacing": 1.0 + }, + "diff_pair_skew_defaults": { + "corner_radius_percentage": 80, + "corner_style": 1, + "max_amplitude": 1.0, + "min_amplitude": 0.2, + "single_sided": false, + "spacing": 0.6 + }, + "single_track_defaults": { + "corner_radius_percentage": 80, + "corner_style": 1, + "max_amplitude": 1.0, + "min_amplitude": 0.2, + "single_sided": false, + "spacing": 0.6 + } + }, + "via_dimensions": [], + "zones_allow_external_fillets": false + }, + "ipc2581": { + "dist": "", + "distpn": "", + "internal_id": "", + "mfg": "", + "mpn": "" + }, + "layer_pairs": [], + "layer_presets": [], + "viewports": [] + }, + "boards": [], + "component_class_settings": { + "assignments": [], + "meta": { + "version": 0 + }, + "sheet_component_classes": { + "enabled": false + } + }, + "cvpcb": { + "equivalence_files": [] + }, + "erc": { + "erc_exclusions": [], + "meta": { + "version": 0 + }, + "pin_map": [ + [ + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 2 + ], + [ + 0, + 2, + 0, + 1, + 0, + 0, + 1, + 0, + 2, + 2, + 2, + 2 + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 2 + ], + [ + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 2, + 1, + 1, + 2 + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 2 + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2 + ], + [ + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 2 + ], + [ + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 2 + ], + [ + 0, + 2, + 1, + 2, + 0, + 0, + 1, + 0, + 2, + 2, + 2, + 2 + ], + [ + 0, + 2, + 0, + 1, + 0, + 0, + 1, + 0, + 2, + 0, + 0, + 2 + ], + [ + 0, + 2, + 1, + 1, + 0, + 0, + 1, + 0, + 2, + 0, + 0, + 2 + ], + [ + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2 + ] + ], + "rule_severities": { + "bus_definition_conflict": "error", + "bus_entry_needed": "error", + "bus_to_bus_conflict": "error", + "bus_to_net_conflict": "error", + "different_unit_footprint": "error", + "different_unit_net": "error", + "duplicate_reference": "error", + "duplicate_sheet_names": "error", + "endpoint_off_grid": "warning", + "extra_units": "error", + "footprint_filter": "ignore", + "footprint_link_issues": "warning", + "four_way_junction": "ignore", + "global_label_dangling": "warning", + "ground_pin_not_ground": "warning", + "hier_label_mismatch": "error", + "isolated_pin_label": "warning", + "label_dangling": "error", + "label_multiple_wires": "warning", + "lib_symbol_issues": "warning", + "lib_symbol_mismatch": "warning", + "missing_bidi_pin": "warning", + "missing_input_pin": "warning", + "missing_power_pin": "error", + "missing_unit": "warning", + "multiple_net_names": "warning", + "net_not_bus_member": "warning", + "no_connect_connected": "warning", + "no_connect_dangling": "warning", + "pin_not_connected": "error", + "pin_not_driven": "error", + "pin_to_pin": "warning", + "power_pin_not_driven": "error", + "same_local_global_label": "warning", + "similar_label_and_power": "warning", + "similar_labels": "warning", + "similar_power": "warning", + "simulation_model_issue": "ignore", + "single_global_label": "ignore", + "stacked_pin_name": "warning", + "unannotated": "error", + "unconnected_wire_endpoint": "warning", + "undefined_netclass": "error", + "unit_value_mismatch": "error", + "unresolved_variable": "error", + "wire_dangling": "error" + } + }, + "libraries": { + "pinned_footprint_libs": [], + "pinned_symbol_libs": [] + }, + "meta": { + "filename": "bugtest.kicad_pro", + "version": 3 + }, + "net_settings": { + "classes": [ + { + "bus_width": 12, + "clearance": 0.2, + "diff_pair_gap": 0.25, + "diff_pair_via_gap": 0.25, + "diff_pair_width": 0.2, + "line_style": 0, + "microvia_diameter": 0.3, + "microvia_drill": 0.1, + "name": "Default", + "pcb_color": "rgba(0, 0, 0, 0.000)", + "priority": 2147483647, + "schematic_color": "rgba(0, 0, 0, 0.000)", + "track_width": 0.2, + "tuning_profile": "", + "via_diameter": 0.6, + "via_drill": 0.3, + "wire_width": 6 + } + ], + "meta": { + "version": 5 + }, + "net_colors": null, + "netclass_assignments": null, + "netclass_patterns": [] + }, + "pcbnew": { + "last_paths": { + "gencad": "", + "idf": "", + "netlist": "", + "plot": "", + "pos_files": "", + "specctra_dsn": "", + "step": "", + "svg": "", + "vrml": "" + }, + "page_layout_descr_file": "" + }, + "schematic": { + "annotate_start_num": 0, + "annotation": { + "method": 0, + "sort_order": 0 + }, + "bom_export_filename": "${PROJECTNAME}.csv", + "bom_fmt_presets": [], + "bom_fmt_settings": { + "field_delimiter": ",", + "keep_line_breaks": false, + "keep_tabs": false, + "name": "CSV", + "ref_delimiter": ",", + "ref_range_delimiter": "", + "string_delimiter": "\"" + }, + "bom_presets": [], + "bom_settings": { + "exclude_dnp": false, + "fields_ordered": [ + { + "group_by": false, + "label": "Reference", + "name": "Reference", + "show": true + }, + { + "group_by": false, + "label": "Qty", + "name": "${QUANTITY}", + "show": true + }, + { + "group_by": true, + "label": "Value", + "name": "Value", + "show": true + }, + { + "group_by": true, + "label": "DNP", + "name": "${DNP}", + "show": true + }, + { + "group_by": true, + "label": "Exclude from BOM", + "name": "${EXCLUDE_FROM_BOM}", + "show": true + }, + { + "group_by": true, + "label": "Exclude from Board", + "name": "${EXCLUDE_FROM_BOARD}", + "show": true + }, + { + "group_by": true, + "label": "Footprint", + "name": "Footprint", + "show": true + }, + { + "group_by": false, + "label": "Datasheet", + "name": "Datasheet", + "show": true + } + ], + "filter_string": "", + "group_symbols": true, + "include_excluded_from_bom": true, + "name": "Default Editing", + "sort_asc": true, + "sort_field": "Reference" + }, + "bus_aliases": {}, + "connection_grid_size": 50.0, + "drawing": { + "dashed_lines_dash_length_ratio": 12.0, + "dashed_lines_gap_length_ratio": 3.0, + "default_line_thickness": 6.0, + "default_text_size": 50.0, + "field_names": [], + "hop_over_size_choice": 0, + "intersheets_ref_own_page": false, + "intersheets_ref_prefix": "", + "intersheets_ref_short": false, + "intersheets_ref_show": false, + "intersheets_ref_suffix": "", + "junction_size_choice": 3, + "label_size_ratio": 0.25, + "operating_point_overlay_i_precision": 3, + "operating_point_overlay_i_range": "~A", + "operating_point_overlay_v_precision": 3, + "operating_point_overlay_v_range": "~V", + "overbar_offset_ratio": 1.23, + "pin_symbol_size": 0.0, + "text_offset_ratio": 0.08 + }, + "legacy_lib_dir": "", + "legacy_lib_list": [], + "meta": { + "version": 1 + }, + "net_format_name": "", + "page_layout_descr_file": "", + "plot_directory": "", + "reuse_designators": true, + "space_save_all_events": true, + "spice_current_sheet_as_root": false, + "spice_external_command": "spice \"%I\"", + "spice_model_current_sheet_as_root": true, + "spice_save_all_currents": false, + "spice_save_all_dissipations": false, + "spice_save_all_voltages": false, + "subpart_first_id": 65, + "subpart_id_separator": 0, + "top_level_sheets": [ + { + "filename": "bugtest.kicad_sch", + "name": "bugtest", + "uuid": "084ee3b1-71f6-47a6-9dc8-ecb4f5c55a9a" + } + ], + "used_designators": "", + "variants": [] + }, + "sheets": [ + [ + "084ee3b1-71f6-47a6-9dc8-ecb4f5c55a9a", + "bugtest" + ] + ], + "text_variables": {}, + "tuning_profiles": { + "meta": { + "version": 0 + }, + "tuning_profiles_impedance_geometric": [] + } +} diff --git a/qa/data/eeschema/issue22286/bugtest.kicad_sch b/qa/data/eeschema/issue22286/bugtest.kicad_sch new file mode 100644 index 0000000000..1585292788 --- /dev/null +++ b/qa/data/eeschema/issue22286/bugtest.kicad_sch @@ -0,0 +1,1396 @@ +(kicad_sch + (version 20250114) + (generator "eeschema") + (generator_version "9.0") + (uuid "084ee3b1-71f6-47a6-9dc8-ecb4f5c55a9a") + (paper "A4") + (lib_symbols + (symbol "Device:R" + (pin_numbers + (hide yes) + ) + (pin_names + (offset 0) + ) + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (property "Reference" "R" + (at 2.032 0 90) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Value" "R" + (at 0 0 90) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Footprint" "" + (at -1.778 0 90) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Datasheet" "" + (at 0 0 0) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Description" "Resistor" + (at 0 0 0) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "ki_keywords" "R res resistor" + (at 0 0 0) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "ki_fp_filters" "R_*" + (at 0 0 0) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (symbol "R_0_1" + (rectangle + (start -1.016 -2.54) + (end 1.016 2.54) + (stroke + (width 0.254) + (type default) + ) + (fill + (type none) + ) + ) + ) + (symbol "R_1_1" + (pin passive line + (at 0 3.81 270) + (length 1.27) + (name "" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "1" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin passive line + (at 0 -3.81 90) + (length 1.27) + (name "" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "2" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + ) + ) + (symbol "custom:MOLEX_PICOBLADE_8PHOR" + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (property "Reference" "J1" + (at 6.35 0.0001 0) + (effects + (font + (size 1.27 1.0795) + ) + (justify left) + ) + ) + (property "Value" "MOLEX" + (at 6.35 -2.5399 0) + (effects + (font + (size 1.27 1.0795) + ) + (justify left) + ) + ) + (property "Footprint" "" + (at 0 0 0) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Datasheet" "" + (at 0 0 0) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Description" "1.25mm (.049\") Pitch PicoBlade Header, SMT, Vertical, Lead-free, 8 Circuits" + (at 0 0 0) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "LOCATION" "Front" + (at 0 0 0) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "FUNCTION" "Panel" + (at 0 0 0) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (symbol "MOLEX_PICOBLADE_8PHOR_1_0" + (polyline + (pts + (xy -2.54 12.7) (xy 5.08 12.7) + ) + (stroke + (width 0.254) + (type solid) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy -2.54 -15.24) (xy -2.54 12.7) + ) + (stroke + (width 0.254) + (type solid) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 5.08 12.7) (xy 5.08 -15.24) + ) + (stroke + (width 0.254) + (type solid) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 5.08 -15.24) (xy -2.54 -15.24) + ) + (stroke + (width 0.254) + (type solid) + ) + (fill + (type none) + ) + ) + (text "${LOCATION}" + (at 2.286 -2.54 900) + (effects + (font + (size 1.27 1.0795) + ) + (justify bottom) + ) + ) + (text "${FUNCTION}" + (at 3.81 -2.54 900) + (effects + (font + (size 1.27 1.0795) + ) + (justify bottom) + ) + ) + (pin no_connect line + (at -5.08 7.62 0) + (length 2.54) + (name "1" + (effects + (font + (size 0 0) + ) + ) + ) + (number "1" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (alternate "1.bidir" bidirectional line) + (alternate "1.free" free line) + (alternate "1.in" input line) + (alternate "1.oc" open_collector line) + (alternate "1.oe" open_emitter line) + (alternate "1.out" output line) + (alternate "1.pas" passive line) + (alternate "1.pow" power_in line) + (alternate "1.sup" power_out line) + (alternate "1.tristate" tri_state line) + (alternate "1.unspec" unspecified line) + ) + (pin no_connect line + (at -5.08 5.08 0) + (length 2.54) + (name "2" + (effects + (font + (size 0 0) + ) + ) + ) + (number "2" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (alternate "2.bidir" bidirectional line) + (alternate "2.free" free line) + (alternate "2.in" input line) + (alternate "2.oc" open_collector line) + (alternate "2.oe" open_emitter line) + (alternate "2.out" output line) + (alternate "2.pas" passive line) + (alternate "2.pow" power_in line) + (alternate "2.sup" power_out line) + (alternate "2.tristate" tri_state line) + (alternate "2.unspec" unspecified line) + ) + (pin no_connect line + (at -5.08 2.54 0) + (length 2.54) + (name "3" + (effects + (font + (size 0 0) + ) + ) + ) + (number "3" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (alternate "3.bidir" bidirectional line) + (alternate "3.free" free line) + (alternate "3.in" input line) + (alternate "3.oc" open_collector line) + (alternate "3.oe" open_emitter line) + (alternate "3.out" output line) + (alternate "3.pas" passive line) + (alternate "3.pow" power_in line) + (alternate "3.sup" power_out line) + (alternate "3.tristate" tri_state line) + (alternate "3.unspec" unspecified line) + ) + (pin no_connect line + (at -5.08 0 0) + (length 2.54) + (name "4" + (effects + (font + (size 0 0) + ) + ) + ) + (number "4" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (alternate "4.bidir" bidirectional line) + (alternate "4.free" free line) + (alternate "4.in" input line) + (alternate "4.oc" open_collector line) + (alternate "4.oe" open_emitter line) + (alternate "4.out" output line) + (alternate "4.pas" passive line) + (alternate "4.pow" power_in line) + (alternate "4.sup" power_out line) + (alternate "4.tristate" tri_state line) + (alternate "4.unspec" unspecified line) + ) + (pin no_connect line + (at -5.08 -2.54 0) + (length 2.54) + (name "5" + (effects + (font + (size 0 0) + ) + ) + ) + (number "5" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (alternate "5.bidir" bidirectional line) + (alternate "5.free" free line) + (alternate "5.in" input line) + (alternate "5.oc" open_collector line) + (alternate "5.oe" open_emitter line) + (alternate "5.out" output line) + (alternate "5.pas" passive line) + (alternate "5.pow" power_in line) + (alternate "5.sup" power_out line) + (alternate "5.tristate" tri_state line) + (alternate "5.unspec" unspecified line) + ) + (pin no_connect line + (at -5.08 -5.08 0) + (length 2.54) + (name "6" + (effects + (font + (size 0 0) + ) + ) + ) + (number "6" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (alternate "6.bidir" bidirectional line) + (alternate "6.free" free line) + (alternate "6.in" input line) + (alternate "6.oc" open_collector line) + (alternate "6.oe" open_emitter line) + (alternate "6.out" output line) + (alternate "6.pas" passive line) + (alternate "6.pow" power_in line) + (alternate "6.sup" power_out line) + (alternate "6.tristate" tri_state line) + (alternate "6.unspec" unspecified line) + ) + (pin no_connect line + (at -5.08 -7.62 0) + (length 2.54) + (name "7" + (effects + (font + (size 0 0) + ) + ) + ) + (number "7" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (alternate "7.bidir" bidirectional line) + (alternate "7.free" free line) + (alternate "7.in" input line) + (alternate "7.oc" open_collector line) + (alternate "7.oe" open_emitter line) + (alternate "7.out" output line) + (alternate "7.pas" passive line) + (alternate "7.pow" power_in line) + (alternate "7.sup" power_out line) + (alternate "7.tristate" tri_state line) + (alternate "7.unspec" unspecified line) + ) + (pin no_connect line + (at -5.08 -10.16 0) + (length 2.54) + (name "8" + (effects + (font + (size 0 0) + ) + ) + ) + (number "8" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (alternate "8.bidir" bidirectional line) + (alternate "8.free" free line) + (alternate "8.in" input line) + (alternate "8.oc" open_collector line) + (alternate "8.oe" open_emitter line) + (alternate "8.out" output line) + (alternate "8.pas" passive line) + (alternate "8.pow" power_in line) + (alternate "8.sup" power_out line) + (alternate "8.tristate" tri_state line) + (alternate "8.unspec" unspecified line) + ) + (pin passive line + (at -5.08 -15.24 0) + (length 2.54) + (name "G" + (effects + (font + (size 0 0) + ) + ) + ) + (number "G" + (effects + (font + (size 0 0) + ) + ) + ) + ) + ) + ) + (symbol "power:+5V" + (power) + (pin_numbers + (hide yes) + ) + (pin_names + (offset 0) + (hide yes) + ) + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (property "Reference" "#PWR" + (at 0 -3.81 0) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Value" "+5V" + (at 0 3.556 0) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Footprint" "" + (at 0 0 0) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Datasheet" "" + (at 0 0 0) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Description" "Power symbol creates a global label with name \"+5V\"" + (at 0 0 0) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "ki_keywords" "global power" + (at 0 0 0) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (symbol "+5V_0_1" + (polyline + (pts + (xy -0.762 1.27) (xy 0 2.54) + ) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 0 2.54) (xy 0.762 1.27) + ) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 0 0) (xy 0 2.54) + ) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + ) + (symbol "+5V_1_1" + (pin power_in line + (at 0 0 90) + (length 0) + (name "" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "1" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + ) + ) + (symbol "power:Earth" + (power) + (pin_numbers + (hide yes) + ) + (pin_names + (offset 0) + (hide yes) + ) + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (property "Reference" "#PWR" + (at 0 -6.35 0) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Value" "Earth" + (at 0 -3.81 0) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Footprint" "" + (at 0 0 0) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Datasheet" "" + (at 0 0 0) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Description" "Power symbol creates a global label with name \"Earth\"" + (at 0 0 0) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "ki_keywords" "global ground gnd" + (at 0 0 0) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (symbol "Earth_0_1" + (polyline + (pts + (xy -0.635 -1.905) (xy 0.635 -1.905) + ) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy -0.127 -2.54) (xy 0.127 -2.54) + ) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 0 -1.27) (xy 0 0) + ) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 1.27 -1.27) (xy -1.27 -1.27) + ) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + ) + (symbol "Earth_1_1" + (pin power_in line + (at 0 0 270) + (length 0) + (name "" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "1" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + ) + ) + (symbol "power:GND" + (power) + (pin_numbers + (hide yes) + ) + (pin_names + (offset 0) + (hide yes) + ) + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (property "Reference" "#PWR" + (at 0 -6.35 0) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Value" "GND" + (at 0 -3.81 0) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Footprint" "" + (at 0 0 0) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Datasheet" "" + (at 0 0 0) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Description" "Power symbol creates a global label with name \"GND\" , ground" + (at 0 0 0) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "ki_keywords" "global power" + (at 0 0 0) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (symbol "GND_0_1" + (polyline + (pts + (xy 0 0) (xy 0 -1.27) (xy 1.27 -1.27) (xy 0 -2.54) (xy -1.27 -1.27) (xy 0 -1.27) + ) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + ) + (symbol "GND_1_1" + (pin power_in line + (at 0 0 270) + (length 0) + (name "" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "1" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + ) + ) + ) + (junction + (at 85.09 93.98) + (diameter 0) + (color 0 0 0 0) + (uuid "31c76005-9544-4f38-b6a0-6ae83f0386bc") + ) + (wire + (pts + (xy 85.09 76.2) (xy 85.09 93.98) + ) + (stroke + (width 0) + (type default) + ) + (uuid "03283a21-37a8-4be3-a83b-05022aecb5ce") + ) + (wire + (pts + (xy 88.9 78.74) (xy 92.71 78.74) + ) + (stroke + (width 0) + (type default) + ) + (uuid "175d51ad-1833-4225-8e47-d86877adcffa") + ) + (wire + (pts + (xy 85.09 93.98) (xy 85.09 102.87) + ) + (stroke + (width 0) + (type default) + ) + (uuid "31547fd0-1020-4539-bb10-3fdbad1f2045") + ) + (wire + (pts + (xy 88.9 72.39) (xy 88.9 78.74) + ) + (stroke + (width 0) + (type default) + ) + (uuid "7fcdb06a-24bf-4b00-a801-33307b5957b3") + ) + (wire + (pts + (xy 92.71 93.98) (xy 85.09 93.98) + ) + (stroke + (width 0) + (type default) + ) + (uuid "8117aae9-8613-4995-8829-436336821ab6") + ) + (wire + (pts + (xy 92.71 76.2) (xy 85.09 76.2) + ) + (stroke + (width 0) + (type default) + ) + (uuid "8f47b358-6a7c-4822-b751-1549790e4ce4") + ) + (wire + (pts + (xy 72.39 91.44) (xy 92.71 91.44) + ) + (stroke + (width 0) + (type default) + ) + (uuid "afe3cf3c-a797-441c-8494-05d4ce3c6509") + ) + (wire + (pts + (xy 72.39 90.17) (xy 72.39 91.44) + ) + (stroke + (width 0) + (type default) + ) + (uuid "b26b8eae-7d3b-4f8c-86c3-96417a6466bc") + ) + (wire + (pts + (xy 92.71 99.06) (xy 90.17 99.06) + ) + (stroke + (width 0) + (type default) + ) + (uuid "ba724338-c17a-4314-ad2b-8b4499d06987") + ) + (wire + (pts + (xy 72.39 81.28) (xy 72.39 82.55) + ) + (stroke + (width 0) + (type default) + ) + (uuid "c2d498b9-c1cc-4f65-b5a7-cccfd272ffab") + ) + (wire + (pts + (xy 90.17 99.06) (xy 90.17 102.87) + ) + (stroke + (width 0) + (type default) + ) + (uuid "ccdc2def-304b-42b4-b59e-790f21b9ed12") + ) + (wire + (pts + (xy 92.71 81.28) (xy 72.39 81.28) + ) + (stroke + (width 0) + (type default) + ) + (uuid "ddb9afac-d203-4a7b-9f85-a85897811d66") + ) + (symbol + (lib_id "power:GND") + (at 85.09 102.87 0) + (unit 1) + (convert 1) + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (dnp no) + (fields_autoplaced yes) + (uuid "00b0a16a-5d95-4758-8d6d-dfedfbbd5679") + (property "Reference" "#PWR01" + (at 85.09 109.22 0) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Value" "GND" + (at 85.09 107.95 0) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Footprint" "" + (at 85.09 102.87 0) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Datasheet" "" + (at 85.09 102.87 0) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Description" "Power symbol creates a global label with name \"GND\" , ground" + (at 85.09 102.87 0) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (pin "1" + (uuid "5fe867c6-abbc-4d3f-b562-c0bf449681bc") + ) + (instances + (project "" + (path "/084ee3b1-71f6-47a6-9dc8-ecb4f5c55a9a" + (reference "#PWR01") + (unit 1) + ) + ) + ) + ) + (symbol + (lib_id "power:+5V") + (at 88.9 72.39 0) + (unit 1) + (convert 1) + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (dnp no) + (fields_autoplaced yes) + (uuid "0bf7304d-cddc-482e-be1d-230ed543df30") + (property "Reference" "#PWR03" + (at 88.9 76.2 0) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Value" "+5V" + (at 88.9 67.31 0) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Footprint" "" + (at 88.9 72.39 0) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Datasheet" "" + (at 88.9 72.39 0) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Description" "Power symbol creates a global label with name \"+5V\"" + (at 88.9 72.39 0) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (pin "1" + (uuid "ba45b7ae-2fdb-449b-8344-5edd3e2bced0") + ) + (instances + (project "" + (path "/084ee3b1-71f6-47a6-9dc8-ecb4f5c55a9a" + (reference "#PWR03") + (unit 1) + ) + ) + ) + ) + (symbol + (lib_id "custom:MOLEX_PICOBLADE_8PHOR") + (at 97.79 83.82 0) + (unit 1) + (convert 1) + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (dnp no) + (fields_autoplaced yes) + (uuid "3ab50da0-dc9b-4c7e-9b38-423adaa36f32") + (property "Reference" "J1" + (at 104.14 83.8199 0) + (effects + (font + (size 1.27 1.0795) + ) + (justify left) + ) + ) + (property "Value" "MOLEX" + (at 104.14 86.3599 0) + (effects + (font + (size 1.27 1.0795) + ) + (justify left) + ) + ) + (property "Footprint" "custom:MOLEX_533980871" + (at 97.79 83.82 0) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Datasheet" "" + (at 97.79 83.82 0) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Description" "1.25mm (.049\") Pitch PicoBlade Header, SMT, Vertical, Lead-free, 8 Circuits" + (at 97.79 83.82 0) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "FUNCTION" "Function" + (at 97.79 83.82 0) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "LOCATION" "Location" + (at 97.79 83.82 0) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (pin "3" + (uuid "8d40c13b-ca88-4bea-96f9-9162687d1a15") + (alternate "3.out") + ) + (pin "2" + (uuid "ecc7a8a0-6780-432c-be66-419246b0cc68") + (alternate "2.pow") + ) + (pin "1" + (uuid "da3d86a0-e961-4510-b252-496e6ec73525") + (alternate "1.pow") + ) + (pin "G" + (uuid "e0b67bf0-f49c-4092-baf0-8b2431d66cd0") + ) + (pin "8" + (uuid "a5dfe102-d9b3-4c36-ab6e-74e1e94947ad") + (alternate "8.pow") + ) + (pin "4" + (uuid "9524aeac-9d98-4ef0-9c75-c2b946b99539") + ) + (pin "5" + (uuid "8d3cd619-2054-49c2-bab2-c20f69cf2427") + ) + (pin "6" + (uuid "54318b82-91fa-4026-bd2e-ae3523629182") + ) + (pin "7" + (uuid "4e298e64-7335-4754-9a87-df8ee799761d") + (alternate "7.in") + ) + (instances + (project "" + (path "/084ee3b1-71f6-47a6-9dc8-ecb4f5c55a9a" + (reference "J1") + (unit 1) + ) + ) + ) + ) + (symbol + (lib_id "Device:R") + (at 72.39 86.36 0) + (unit 1) + (convert 1) + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (dnp no) + (fields_autoplaced yes) + (uuid "998e570a-b1c1-4603-9941-689066dfd496") + (property "Reference" "R1" + (at 74.93 85.0899 0) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Value" "R" + (at 74.93 87.6299 0) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Footprint" "Resistor_SMD:R_0402_1005Metric" + (at 70.612 86.36 90) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Datasheet" "" + (at 72.39 86.36 0) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Description" "Resistor" + (at 72.39 86.36 0) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (pin "1" + (uuid "efa88045-795d-4f40-b266-58ab929be9ee") + ) + (pin "2" + (uuid "4b35d9de-f91b-436e-b21a-5b9cdd9edbc7") + ) + (instances + (project "" + (path "/084ee3b1-71f6-47a6-9dc8-ecb4f5c55a9a" + (reference "R1") + (unit 1) + ) + ) + ) + ) + (symbol + (lib_id "power:Earth") + (at 90.17 102.87 0) + (unit 1) + (convert 1) + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (dnp no) + (fields_autoplaced yes) + (uuid "a2fc4745-c6e3-4833-81c9-b14aed29a6ab") + (property "Reference" "#PWR02" + (at 90.17 109.22 0) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Value" "Earth" + (at 90.17 107.95 0) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Footprint" "" + (at 90.17 102.87 0) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Datasheet" "" + (at 90.17 102.87 0) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Description" "Power symbol creates a global label with name \"Earth\"" + (at 90.17 102.87 0) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (pin "1" + (uuid "c47987e9-c88b-43cd-810a-8b260893e2fa") + ) + (instances + (project "" + (path "/084ee3b1-71f6-47a6-9dc8-ecb4f5c55a9a" + (reference "#PWR02") + (unit 1) + ) + ) + ) + ) + (sheet_instances + (path "/" + (page "1") + ) + ) +) diff --git a/qa/data/eeschema/issue22286/bugtest.kicad_sym b/qa/data/eeschema/issue22286/bugtest.kicad_sym new file mode 100644 index 0000000000..3a4c9bc67b --- /dev/null +++ b/qa/data/eeschema/issue22286/bugtest.kicad_sym @@ -0,0 +1,392 @@ +(kicad_symbol_lib + (version 20241209) + (generator "kicad_symbol_editor") + (generator_version "9.0") + (symbol "MOLEX_PICOBLADE_8PHOR" + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (property "Reference" "J1" + (at 6.35 0.0001 0) + (effects + (font + (size 1.27 1.0795) + ) + (justify left) + ) + ) + (property "Value" "MOLEX" + (at 6.35 -2.5399 0) + (effects + (font + (size 1.27 1.0795) + ) + (justify left) + ) + ) + (property "Footprint" "" + (at 0 0 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Datasheet" "" + (at 0 0 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Description" "1.25mm (.049\") Pitch PicoBlade Header, SMT, Vertical, Lead-free, 8 Circuits" + (at 0 0 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "LOCATION" "Front" + (at 0 0 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "FUNCTION" "Panel" + (at 0 0 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (symbol "MOLEX_PICOBLADE_8PHOR_1_0" + (polyline + (pts + (xy -2.54 12.7) (xy 5.08 12.7) + ) + (stroke + (width 0.254) + (type solid) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy -2.54 -15.24) (xy -2.54 12.7) + ) + (stroke + (width 0.254) + (type solid) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 5.08 12.7) (xy 5.08 -15.24) + ) + (stroke + (width 0.254) + (type solid) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 5.08 -15.24) (xy -2.54 -15.24) + ) + (stroke + (width 0.254) + (type solid) + ) + (fill + (type none) + ) + ) + (text "${LOCATION}" + (at 2.286 -2.54 900) + (effects + (font + (size 1.27 1.0795) + ) + (justify bottom) + ) + ) + (text "${FUNCTION}" + (at 3.81 -2.54 900) + (effects + (font + (size 1.27 1.0795) + ) + (justify bottom) + ) + ) + (pin no_connect line + (at -5.08 7.62 0) + (length 2.54) + (name "1" + (effects + (font + (size 0 0) + ) + ) + ) + (number "1" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (alternate "1.bidir" bidirectional line) + (alternate "1.free" free line) + (alternate "1.in" input line) + (alternate "1.oc" open_collector line) + (alternate "1.oe" open_emitter line) + (alternate "1.out" output line) + (alternate "1.pas" passive line) + (alternate "1.pow" power_in line) + (alternate "1.sup" power_out line) + (alternate "1.tristate" tri_state line) + (alternate "1.unspec" unspecified line) + ) + (pin no_connect line + (at -5.08 5.08 0) + (length 2.54) + (name "2" + (effects + (font + (size 0 0) + ) + ) + ) + (number "2" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (alternate "2.bidir" bidirectional line) + (alternate "2.free" free line) + (alternate "2.in" input line) + (alternate "2.oc" open_collector line) + (alternate "2.oe" open_emitter line) + (alternate "2.out" output line) + (alternate "2.pas" passive line) + (alternate "2.pow" power_in line) + (alternate "2.sup" power_out line) + (alternate "2.tristate" tri_state line) + (alternate "2.unspec" unspecified line) + ) + (pin no_connect line + (at -5.08 2.54 0) + (length 2.54) + (name "3" + (effects + (font + (size 0 0) + ) + ) + ) + (number "3" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (alternate "3.bidir" bidirectional line) + (alternate "3.free" free line) + (alternate "3.in" input line) + (alternate "3.oc" open_collector line) + (alternate "3.oe" open_emitter line) + (alternate "3.out" output line) + (alternate "3.pas" passive line) + (alternate "3.pow" power_in line) + (alternate "3.sup" power_out line) + (alternate "3.tristate" tri_state line) + (alternate "3.unspec" unspecified line) + ) + (pin no_connect line + (at -5.08 0 0) + (length 2.54) + (name "4" + (effects + (font + (size 0 0) + ) + ) + ) + (number "4" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (alternate "4.bidir" bidirectional line) + (alternate "4.free" free line) + (alternate "4.in" input line) + (alternate "4.oc" open_collector line) + (alternate "4.oe" open_emitter line) + (alternate "4.out" output line) + (alternate "4.pas" passive line) + (alternate "4.pow" power_in line) + (alternate "4.sup" power_out line) + (alternate "4.tristate" tri_state line) + (alternate "4.unspec" unspecified line) + ) + (pin no_connect line + (at -5.08 -2.54 0) + (length 2.54) + (name "5" + (effects + (font + (size 0 0) + ) + ) + ) + (number "5" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (alternate "5.bidir" bidirectional line) + (alternate "5.free" free line) + (alternate "5.in" input line) + (alternate "5.oc" open_collector line) + (alternate "5.oe" open_emitter line) + (alternate "5.out" output line) + (alternate "5.pas" passive line) + (alternate "5.pow" power_in line) + (alternate "5.sup" power_out line) + (alternate "5.tristate" tri_state line) + (alternate "5.unspec" unspecified line) + ) + (pin no_connect line + (at -5.08 -5.08 0) + (length 2.54) + (name "6" + (effects + (font + (size 0 0) + ) + ) + ) + (number "6" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (alternate "6.bidir" bidirectional line) + (alternate "6.free" free line) + (alternate "6.in" input line) + (alternate "6.oc" open_collector line) + (alternate "6.oe" open_emitter line) + (alternate "6.out" output line) + (alternate "6.pas" passive line) + (alternate "6.pow" power_in line) + (alternate "6.sup" power_out line) + (alternate "6.tristate" tri_state line) + (alternate "6.unspec" unspecified line) + ) + (pin no_connect line + (at -5.08 -7.62 0) + (length 2.54) + (name "7" + (effects + (font + (size 0 0) + ) + ) + ) + (number "7" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (alternate "7.bidir" bidirectional line) + (alternate "7.free" free line) + (alternate "7.in" input line) + (alternate "7.oc" open_collector line) + (alternate "7.oe" open_emitter line) + (alternate "7.out" output line) + (alternate "7.pas" passive line) + (alternate "7.pow" power_in line) + (alternate "7.sup" power_out line) + (alternate "7.tristate" tri_state line) + (alternate "7.unspec" unspecified line) + ) + (pin no_connect line + (at -5.08 -10.16 0) + (length 2.54) + (name "8" + (effects + (font + (size 0 0) + ) + ) + ) + (number "8" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (alternate "8.bidir" bidirectional line) + (alternate "8.free" free line) + (alternate "8.in" input line) + (alternate "8.oc" open_collector line) + (alternate "8.oe" open_emitter line) + (alternate "8.out" output line) + (alternate "8.pas" passive line) + (alternate "8.pow" power_in line) + (alternate "8.sup" power_out line) + (alternate "8.tristate" tri_state line) + (alternate "8.unspec" unspecified line) + ) + (pin passive line + (at -5.08 -15.24 0) + (length 2.54) + (name "G" + (effects + (font + (size 0 0) + ) + ) + ) + (number "G" + (effects + (font + (size 0 0) + ) + ) + ) + ) + ) + (embedded_fonts no) + ) +) diff --git a/qa/tests/eeschema/CMakeLists.txt b/qa/tests/eeschema/CMakeLists.txt index 029fcc8216..dafc28dfe9 100644 --- a/qa/tests/eeschema/CMakeLists.txt +++ b/qa/tests/eeschema/CMakeLists.txt @@ -68,6 +68,7 @@ set( QA_EESCHEMA_SRCS test_issue18119_bus_hierarchy.cpp test_issue18299_bus_member_rename.cpp test_issue20173_paste_subsheet.cpp + test_issue22286_pin_alternate.cpp test_issue16915_bus_netclass.cpp test_nc_pin_connectivity.cpp test_crossing_label.cpp diff --git a/qa/tests/eeschema/test_issue22286_pin_alternate.cpp b/qa/tests/eeschema/test_issue22286_pin_alternate.cpp new file mode 100644 index 0000000000..c309dedae7 --- /dev/null +++ b/qa/tests/eeschema/test_issue22286_pin_alternate.cpp @@ -0,0 +1,197 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright The 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 + */ + +/** + * @file + * Test for issue #22286 - Pin alternate type not being applied after schematic load. + * + * When a pin has an alternate function selected (like "8.pow" with type power_in), + * the pin TYPE should switch from the default (no_connect) to the alternate's type. + * This test verifies the fix by loading the actual reproduction schematic. + */ + +#include +#include "eeschema_test_utils.h" + +#include +#include +#include +#include +#include + + +class TEST_ISSUE22286_FIXTURE : public KI_TEST::SCHEMATIC_TEST_FIXTURE +{ +protected: + wxFileName GetSchematicPath( const wxString& aBaseName ) override + { + wxFileName fn( aBaseName ); + return fn; + } + +public: + SCH_SYMBOL* FindSymbolByRef( const wxString& aRef ) + { + if( !m_schematic ) + return nullptr; + + SCH_SCREEN* screen = m_schematic->RootScreen(); + + if( !screen ) + return nullptr; + + for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) ) + { + SCH_SYMBOL* symbol = static_cast( item ); + + if( symbol && symbol->GetRef( &m_schematic->Hierarchy()[0], false ) == aRef ) + return symbol; + } + + return nullptr; + } + + SCH_PIN* FindPinByNumber( SCH_SYMBOL* aSymbol, const wxString& aNumber ) + { + if( !aSymbol ) + return nullptr; + + for( SCH_PIN* pin : aSymbol->GetPins( &m_schematic->Hierarchy()[0] ) ) + { + if( pin->GetNumber() == aNumber ) + return pin; + } + + return nullptr; + } +}; + + +BOOST_FIXTURE_TEST_SUITE( Issue22286, TEST_ISSUE22286_FIXTURE ) + + +/** + * Test that pin alternates are correctly applied after loading a schematic from disk. + * + * This test loads the actual reproduction schematic for issue #22286 and verifies that: + * 1. Pin 8 on symbol J1 has the alternate "8.pow" set + * 2. Pin 8's GetType() returns PT_POWER_IN (not PT_NC) + * 3. The library pin has the alternates map populated + */ +BOOST_AUTO_TEST_CASE( PinAlternateTypeAfterSchematicLoad ) +{ + wxFileName fn; + fn.SetPath( KI_TEST::GetEeschemaTestDataDir() ); + fn.AppendDir( wxS( "issue22286" ) ); + fn.SetName( wxS( "bugtest" ) ); + fn.SetExt( FILEEXT::KiCadSchematicFileExtension ); + + LoadSchematic( fn.GetFullPath() ); + + // Find symbol J1 (the MOLEX connector) + SCH_SYMBOL* j1 = FindSymbolByRef( wxS( "J1" ) ); + BOOST_REQUIRE_MESSAGE( j1 != nullptr, "Symbol J1 not found in schematic" ); + + // Find pin 8 + SCH_PIN* pin8 = FindPinByNumber( j1, wxS( "8" ) ); + BOOST_REQUIRE_MESSAGE( pin8 != nullptr, "Pin 8 not found on symbol J1" ); + + // Check that the alternate is set + BOOST_CHECK_MESSAGE( pin8->GetAlt() == wxS( "8.pow" ), + "Pin 8 should have alternate '8.pow' set, but has '" + + pin8->GetAlt() + "'" ); + + // Check that m_libPin is set + BOOST_CHECK_MESSAGE( pin8->GetLibPin() != nullptr, + "Pin 8 should have m_libPin set after schematic load" ); + + if( pin8->GetLibPin() ) + { + // Check that the library pin has alternates + const auto& alternates = pin8->GetLibPin()->GetAlternates(); + BOOST_CHECK_MESSAGE( !alternates.empty(), + "Library pin should have alternates populated" ); + BOOST_CHECK_MESSAGE( alternates.count( wxS( "8.pow" ) ) > 0, + "Library pin should have '8.pow' in alternates map" ); + + // Check the alternate's type in the library pin + if( alternates.count( wxS( "8.pow" ) ) > 0 ) + { + const SCH_PIN::ALT& alt = alternates.at( wxS( "8.pow" ) ); + BOOST_CHECK_MESSAGE( alt.m_Type == ELECTRICAL_PINTYPE::PT_POWER_IN, + "Library pin alternate '8.pow' should have type PT_POWER_IN" ); + } + } + + // The critical test: GetType() should return the alternate's type, not the default + ELECTRICAL_PINTYPE pinType = pin8->GetType(); + BOOST_CHECK_MESSAGE( pinType == ELECTRICAL_PINTYPE::PT_POWER_IN, + "Pin 8 GetType() should return PT_POWER_IN (7) for alternate '8.pow', " + "but returned " + std::to_string( static_cast( pinType ) ) + + " (" + ElectricalPinTypeGetText( pinType ) + ")" ); + + // Verify the shown name is the alternate name + BOOST_CHECK_MESSAGE( pin8->GetShownName() == wxS( "8.pow" ), + "Pin 8 GetShownName() should return '8.pow', but returned '" + + pin8->GetShownName() + "'" ); +} + + +/** + * Verify the connection graph does NOT treat the pin as no-connect. + * + * When pin 8 has type PT_POWER_IN (from alternate), it should NOT be marked + * as a no-connect in the connection graph. It will still get a "Net-(...)" name + * because it's on a regular connector (not a power symbol), but importantly it + * should NOT be prefixed with "unconnected-". + */ +BOOST_AUTO_TEST_CASE( ConnectionGraphHandlesPinAlternateType ) +{ + wxFileName fn; + fn.SetPath( KI_TEST::GetEeschemaTestDataDir() ); + fn.AppendDir( wxS( "issue22286" ) ); + fn.SetName( wxS( "bugtest" ) ); + fn.SetExt( FILEEXT::KiCadSchematicFileExtension ); + + LoadSchematic( fn.GetFullPath() ); + + SCH_SYMBOL* j1 = FindSymbolByRef( wxS( "J1" ) ); + BOOST_REQUIRE( j1 != nullptr ); + + SCH_PIN* pin8 = FindPinByNumber( j1, wxS( "8" ) ); + BOOST_REQUIRE( pin8 != nullptr ); + + // Get the net name for pin 8 + SCH_SHEET_PATH path = m_schematic->Hierarchy()[0]; + wxString netName = pin8->GetDefaultNetName( path ); + + // With the fix, pin 8 should NOT get an "unconnected-(...)" name because + // it's a power pin (PT_POWER_IN), not a no-connect pin (PT_NC). + // It will still get a "Net-(...)" name because it's on a regular connector. + BOOST_CHECK_MESSAGE( !netName.StartsWith( wxS( "unconnected-(" ) ), + "Pin 8 (power_in) should not get an 'unconnected-(...)' name. " + "Got: '" + netName + "'" ); +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/qa/tests/eeschema/test_sch_pin.cpp b/qa/tests/eeschema/test_sch_pin.cpp index a04d4ae2b3..f9bd18f231 100644 --- a/qa/tests/eeschema/test_sch_pin.cpp +++ b/qa/tests/eeschema/test_sch_pin.cpp @@ -214,6 +214,334 @@ BOOST_AUTO_TEST_CASE( AlternatePinRenameUpdates ) } +/** + * Test for issue #22286 - GetType() should return the alternate's type when alternate is selected + */ +BOOST_AUTO_TEST_CASE( AlternatePinTypeReturnsCorrectType ) +{ + // Set the library pin's default type to no_connect + m_lib_pin->SetType( ELECTRICAL_PINTYPE::PT_NC ); + + // Add an alternate with a different type (power_in) + SCH_PIN::ALT powerAlt; + powerAlt.m_Name = wxS( "8.pow" ); + powerAlt.m_Shape = GRAPHIC_PINSHAPE::LINE; + powerAlt.m_Type = ELECTRICAL_PINTYPE::PT_POWER_IN; + m_lib_pin->GetAlternates()[ wxS( "8.pow" ) ] = powerAlt; + + // Flatten and update the symbol to get a fresh schematic pin + m_parent_symbol->SetLibSymbol( m_parent_part->Flatten().release() ); + m_sch_pin = m_parent_symbol->GetPins()[0]; + + // Before selecting alternate, type should be the default (NC) + BOOST_CHECK( m_sch_pin->GetType() == ELECTRICAL_PINTYPE::PT_NC ); + + // Select the alternate + m_sch_pin->SetAlt( wxS( "8.pow" ) ); + + // After selecting alternate, type should be the alternate's type (POWER_IN) + BOOST_CHECK_EQUAL( m_sch_pin->GetAlt(), "8.pow" ); + BOOST_CHECK( m_sch_pin->GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN ); + + // Also verify shape changed + BOOST_CHECK( m_sch_pin->GetShape() == GRAPHIC_PINSHAPE::LINE ); +} + + +/** + * Test for issue #22286 - simulate schematic loading scenario + * When a schematic is loaded, the pin's alternate is set BEFORE SetLibSymbol is called. + * The alternate must persist through UpdatePins(). + */ +BOOST_AUTO_TEST_CASE( AlternatePinTypePersistsThroughSymbolUpdate ) +{ + // Set the library pin's default type to no_connect + m_lib_pin->SetType( ELECTRICAL_PINTYPE::PT_NC ); + + // Add an alternate with a different type (power_in) + SCH_PIN::ALT powerAlt; + powerAlt.m_Name = wxS( "8.pow" ); + powerAlt.m_Shape = GRAPHIC_PINSHAPE::LINE; + powerAlt.m_Type = ELECTRICAL_PINTYPE::PT_POWER_IN; + m_lib_pin->GetAlternates()[ wxS( "8.pow" ) ] = powerAlt; + + // First flatten to set up the symbol + m_parent_symbol->SetLibSymbol( m_parent_part->Flatten().release() ); + m_sch_pin = m_parent_symbol->GetPins()[0]; + + // Set the alternate on the schematic pin (like the parser would) + m_sch_pin->SetAlt( wxS( "8.pow" ) ); + BOOST_CHECK_EQUAL( m_sch_pin->GetAlt(), "8.pow" ); + BOOST_CHECK( m_sch_pin->GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN ); + + // Now simulate what happens when the library symbol is re-resolved + // This is similar to what happens after loading a schematic from file + m_parent_symbol->SetLibSymbol( m_parent_part->Flatten().release() ); + m_sch_pin = m_parent_symbol->GetPins()[0]; + + // After the symbol update, the alternate should still be set + BOOST_CHECK_EQUAL( m_sch_pin->GetAlt(), "8.pow" ); + + // And GetType() should return the alternate's type + BOOST_CHECK( m_sch_pin->GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN ); +} + + +/** + * Test for issue #22286 - simulate parser-created pins with alternates + * The parser creates pins with m_alt set but m_libPin=nullptr. + * Verify that after UpdatePins() the alternate type is correctly returned. + */ +BOOST_AUTO_TEST_CASE( ParserCreatedPinWithAlternate ) +{ + // Create a library symbol with a pin that has alternates + LIB_SYMBOL* libSymbol = new LIB_SYMBOL( "test_symbol", nullptr ); + + SCH_PIN* libPin = new SCH_PIN( libSymbol ); + libPin->SetNumber( "8" ); + libPin->SetName( "PIN8" ); + libPin->SetType( ELECTRICAL_PINTYPE::PT_NC ); // Default type is NC + libPin->SetPosition( VECTOR2I( 0, 0 ) ); + + // Add an alternate with power_in type + SCH_PIN::ALT powerAlt; + powerAlt.m_Name = wxS( "8.pow" ); + powerAlt.m_Shape = GRAPHIC_PINSHAPE::LINE; + powerAlt.m_Type = ELECTRICAL_PINTYPE::PT_POWER_IN; + libPin->GetAlternates()[ wxS( "8.pow" ) ] = powerAlt; + + libSymbol->AddDrawItem( libPin ); + + // Create a schematic symbol + SCH_SHEET_PATH path; + SCH_SYMBOL* symbol = new SCH_SYMBOL( *libSymbol, libSymbol->GetLibId(), &path, 0, 0, + VECTOR2I( 0, 0 ) ); + symbol->SetRef( &path, "J1" ); + + // Simulate what the parser does: create a raw pin with alternate set + // This bypasses SetAlt() validation by using the constructor directly + symbol->GetRawPins().clear(); // Remove auto-created pins + symbol->GetRawPins().emplace_back( + std::make_unique( symbol, wxS( "8" ), wxS( "8.pow" ), KIID() ) ); + + SCH_PIN* parserPin = symbol->GetRawPins()[0].get(); + + // At this point, m_alt is set but m_libPin is nullptr + BOOST_CHECK_EQUAL( parserPin->GetAlt(), "8.pow" ); + BOOST_CHECK( parserPin->GetLibPin() == nullptr ); + + // GetType() should return PT_UNSPECIFIED when m_libPin is null + BOOST_CHECK( parserPin->GetType() == ELECTRICAL_PINTYPE::PT_UNSPECIFIED ); + + // Now simulate SetLibSymbol() which calls UpdatePins() + symbol->SetLibSymbol( libSymbol->Flatten().release() ); + + // Verify the flattened library symbol has pins with alternates + BOOST_CHECK( symbol->GetLibSymbolRef() != nullptr ); + std::vector libPins = symbol->GetLibSymbolRef()->GetPins(); + BOOST_CHECK_EQUAL( libPins.size(), 1 ); + + if( !libPins.empty() ) + { + SCH_PIN* flattenedLibPin = libPins[0]; + BOOST_CHECK( !flattenedLibPin->GetAlternates().empty() ); + BOOST_CHECK( flattenedLibPin->GetAlternates().count( wxS( "8.pow" ) ) > 0 ); + } + + // Get the pin after the update + SCH_PIN* updatedPin = symbol->GetPins( &path )[0]; + + // The alternate should still be set + BOOST_CHECK_EQUAL( updatedPin->GetAlt(), "8.pow" ); + + // m_libPin should now be set + BOOST_CHECK( updatedPin->GetLibPin() != nullptr ); + + // GetType() should return the alternate's type (PT_POWER_IN) + BOOST_CHECK( updatedPin->GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN ); + + delete symbol; + delete libSymbol; +} + + +/** + * Test for issue #22286 - detailed trace of SetLibSymbol flow + * Verifies that library pin alternates are preserved through the copy + * and that SetAlt succeeds in UpdatePins(). + */ +BOOST_AUTO_TEST_CASE( LibraryPinAlternatesPreservedThroughCopy ) +{ + // Create original library symbol with pin that has alternates + LIB_SYMBOL* origLibSymbol = new LIB_SYMBOL( "test_symbol", nullptr ); + + SCH_PIN* origLibPin = new SCH_PIN( origLibSymbol ); + origLibPin->SetNumber( "8" ); + origLibPin->SetName( "8" ); // Default name matches number + origLibPin->SetType( ELECTRICAL_PINTYPE::PT_NC ); // Default type is NC + origLibPin->SetPosition( VECTOR2I( 0, 0 ) ); + + // Add alternate with power_in type + SCH_PIN::ALT powerAlt; + powerAlt.m_Name = wxS( "8.pow" ); + powerAlt.m_Shape = GRAPHIC_PINSHAPE::LINE; + powerAlt.m_Type = ELECTRICAL_PINTYPE::PT_POWER_IN; + origLibPin->GetAlternates()[ wxS( "8.pow" ) ] = powerAlt; + + origLibSymbol->AddDrawItem( origLibPin ); + + // Verify original has alternates + BOOST_CHECK( !origLibPin->GetAlternates().empty() ); + BOOST_CHECK( origLibPin->GetAlternates().count( wxS( "8.pow" ) ) > 0 ); + + // Simulate what happens during loading: + // 1. Library symbol is stored in m_libSymbols (just keep the original) + // 2. Create a COPY of the library symbol (like UpdateLocalLibSymbolLinks does) + LIB_SYMBOL* copiedLibSymbol = new LIB_SYMBOL( *origLibSymbol ); + + // Verify the copied library symbol has pins with alternates + std::vector copiedLibPins = copiedLibSymbol->GetPins(); + BOOST_CHECK_EQUAL( copiedLibPins.size(), 1 ); + + if( !copiedLibPins.empty() ) + { + SCH_PIN* copiedLibPin = copiedLibPins[0]; + + // This is the critical check - does the copied lib pin have alternates? + BOOST_CHECK_MESSAGE( !copiedLibPin->GetAlternates().empty(), + "Copied library pin should have alternates" ); + BOOST_CHECK_MESSAGE( copiedLibPin->GetAlternates().count( wxS( "8.pow" ) ) > 0, + "Copied library pin should have '8.pow' alternate" ); + + // Check if the alternate has the correct type + if( copiedLibPin->GetAlternates().count( wxS( "8.pow" ) ) > 0 ) + { + BOOST_CHECK( copiedLibPin->GetAlternates().at( wxS( "8.pow" ) ).m_Type + == ELECTRICAL_PINTYPE::PT_POWER_IN ); + } + } + + // Now create a schematic symbol with parser-created raw pins + SCH_SHEET_PATH path; + SCH_SYMBOL* symbol = new SCH_SYMBOL( *origLibSymbol, origLibSymbol->GetLibId(), &path, 0, 0, + VECTOR2I( 0, 0 ) ); + symbol->SetRef( &path, "J1" ); + + // Clear auto-created pins and add parser-style raw pin + symbol->GetRawPins().clear(); + symbol->GetRawPins().emplace_back( + std::make_unique( symbol, wxS( "8" ), wxS( "8.pow" ), KIID() ) ); + + // Verify raw pin state before SetLibSymbol + SCH_PIN* rawPin = symbol->GetRawPins()[0].get(); + BOOST_CHECK_EQUAL( rawPin->GetAlt(), "8.pow" ); + BOOST_CHECK( rawPin->GetLibPin() == nullptr ); + + // Call SetLibSymbol with the COPIED library symbol (like UpdateLocalLibSymbolLinks does) + symbol->SetLibSymbol( copiedLibSymbol ); // Takes ownership + + // Get the pin after UpdatePins() was called + std::vector schPins = symbol->GetPins( &path ); + BOOST_CHECK_EQUAL( schPins.size(), 1 ); + + if( !schPins.empty() ) + { + SCH_PIN* schPin = schPins[0]; + + // Check that m_libPin is set + BOOST_CHECK_MESSAGE( schPin->GetLibPin() != nullptr, + "Schematic pin should have m_libPin set after UpdatePins" ); + + // Check that the alternate is still set + BOOST_CHECK_MESSAGE( schPin->GetAlt() == "8.pow", + "Alternate should be preserved as '8.pow'" ); + + // Check that GetType() returns the alternate's type + BOOST_CHECK_MESSAGE( schPin->GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN, + "GetType() should return alternate's type (PT_POWER_IN)" ); + + // Additional diagnostic: check the library pin's alternates + if( schPin->GetLibPin() ) + { + BOOST_CHECK_MESSAGE( !schPin->GetLibPin()->GetAlternates().empty(), + "Library pin pointed to by schematic pin should have alternates" ); + BOOST_CHECK_MESSAGE( schPin->GetLibPin()->GetAlternates().count( wxS( "8.pow" ) ) > 0, + "Library pin should have '8.pow' in its alternates map" ); + } + } + + delete symbol; + delete origLibSymbol; +} + + +/** + * Test for issue #22286 - verify behavior when GetType() is called before + * m_libPin is set. This simulates what happens if GetType() is called + * during loading before UpdateLocalLibSymbolLinks() runs. + */ +BOOST_AUTO_TEST_CASE( GetTypeBeforeLibPinSet ) +{ + // Create a schematic symbol with parser-created raw pin + SCH_SHEET_PATH path; + LIB_SYMBOL* libSymbol = new LIB_SYMBOL( "test_symbol", nullptr ); + + SCH_PIN* libPin = new SCH_PIN( libSymbol ); + libPin->SetNumber( "8" ); + libPin->SetName( "8" ); + libPin->SetType( ELECTRICAL_PINTYPE::PT_NC ); + libPin->SetPosition( VECTOR2I( 0, 0 ) ); + + SCH_PIN::ALT powerAlt; + powerAlt.m_Name = wxS( "8.pow" ); + powerAlt.m_Shape = GRAPHIC_PINSHAPE::LINE; + powerAlt.m_Type = ELECTRICAL_PINTYPE::PT_POWER_IN; + libPin->GetAlternates()[ wxS( "8.pow" ) ] = powerAlt; + libSymbol->AddDrawItem( libPin ); + + // Create symbol using default constructor (like parser does) + SCH_SYMBOL* symbol = new SCH_SYMBOL(); + symbol->SetLibId( libSymbol->GetLibId() ); + + // Add parser-style raw pin with alternate set but no m_libPin + symbol->GetRawPins().emplace_back( + std::make_unique( symbol, wxS( "8" ), wxS( "8.pow" ), KIID() ) ); + + SCH_PIN* rawPin = symbol->GetRawPins()[0].get(); + + // At this point: m_alt is set, m_libPin is nullptr, m_type is PT_INHERIT + BOOST_CHECK_EQUAL( rawPin->GetAlt(), "8.pow" ); + BOOST_CHECK( rawPin->GetLibPin() == nullptr ); + + // GetType() with m_alt set but m_libPin=nullptr should return PT_UNSPECIFIED + // per the code in GetType() + BOOST_CHECK_MESSAGE( rawPin->GetType() == ELECTRICAL_PINTYPE::PT_UNSPECIFIED, + "GetType() with m_alt set but m_libPin=nullptr should return PT_UNSPECIFIED" ); + + // GetShownName() should still return the alternate name + BOOST_CHECK_EQUAL( rawPin->GetShownName(), "8.pow" ); + + // Now set the library symbol which triggers UpdatePins() + symbol->SetLibSymbol( new LIB_SYMBOL( *libSymbol ) ); + + // After UpdatePins(), pin should have correct type + std::vector schPins = symbol->GetPins( &path ); + BOOST_CHECK_EQUAL( schPins.size(), 1 ); + + if( !schPins.empty() ) + { + SCH_PIN* schPin = schPins[0]; + BOOST_CHECK_EQUAL( schPin->GetAlt(), "8.pow" ); + BOOST_CHECK( schPin->GetLibPin() != nullptr ); + BOOST_CHECK_MESSAGE( schPin->GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN, + "After SetLibSymbol, GetType() should return PT_POWER_IN" ); + } + + delete symbol; + delete libSymbol; +} + + /** * Test for issue #22566 - changing to a symbol with fewer pins should not crash */