Introspection: Refactor the way selection is extracted

Signed-off-by: Tomasz Michalak <tmichalak@antmicro.com>
diff --git a/design_introspection-plugin/get_cells.cc b/design_introspection-plugin/get_cells.cc
index 6c4f0c9..3cdc0b4 100644
--- a/design_introspection-plugin/get_cells.cc
+++ b/design_introspection-plugin/get_cells.cc
@@ -6,21 +6,24 @@
 
 std::string GetCells::SelectionType() { return "c"; }
 
-void GetCells::ExtractSelection(Tcl_Obj* tcl_list, RTLIL::Module* module,
-                                const CommandArgs& args) {
-    for (auto cell : module->selected_cells()) {
-	if (args.filters.size() > 0) {
-	    Filter filter = args.filters.at(0);
-	    std::string attr_value = cell->get_string_attribute(
-	        RTLIL::IdString(RTLIL::escape_id(filter.first)));
-	    if (attr_value.compare(filter.second)) {
-		continue;
+GetCells::SelectionObjects GetCells::ExtractSelection(RTLIL::Design* design, const CommandArgs& args) {
+    SelectionObjects selected_objects;
+    for (auto module : design->selected_modules()) {
+	for (auto cell : module->selected_cells()) {
+	    if (args.filters.size() > 0) {
+		Filter filter = args.filters.at(0);
+		std::string attr_value = cell->get_string_attribute(
+		    RTLIL::IdString(RTLIL::escape_id(filter.first)));
+		if (attr_value.compare(filter.second)) {
+		    continue;
+		}
 	    }
+	    std::string object_name(RTLIL::unescape_id(cell->name));
+	    if (!args.is_quiet) {
+		log("%s ", object_name.c_str());
+	    }
+	    selected_objects.push_back(object_name);
 	}
-	if (!args.is_quiet) {
-	    log("%s ", id2cstr(cell->name));
-	}
-	Tcl_Obj* value_obj = Tcl_NewStringObj(id2cstr(cell->name), -1);
-	Tcl_ListObjAppendElement(yosys_get_tcl_interp(), tcl_list, value_obj);
     }
+    return selected_objects;
 }
diff --git a/design_introspection-plugin/get_cells.h b/design_introspection-plugin/get_cells.h
index 48f6b30..3412a72 100644
--- a/design_introspection-plugin/get_cells.h
+++ b/design_introspection-plugin/get_cells.h
@@ -10,7 +10,7 @@
 
     std::string TypeName() override;
     std::string SelectionType() override;
-    void ExtractSelection(Tcl_Obj* tcl_list, RTLIL::Module* module,
+    SelectionObjects ExtractSelection(RTLIL::Design* design,
                           const CommandArgs& args) override;
 };
 
diff --git a/design_introspection-plugin/get_cmd.cc b/design_introspection-plugin/get_cmd.cc
index 74f8989..470788e 100644
--- a/design_introspection-plugin/get_cmd.cc
+++ b/design_introspection-plugin/get_cmd.cc
@@ -34,28 +34,33 @@
     std::vector<std::string> selection_args;
     // Add name of top module to selection string
     std::transform(args.selection_objects.begin(), args.selection_objects.end(),
-                   std::back_inserter(selection_args), [&](const std::string& obj) {
-	               return RTLIL::unescape_id(design->top_module()->name) + "/" +
-	                      SelectionType() + ":" + obj;
+                   std::back_inserter(selection_args),
+                   [&](const std::string& obj) {
+	               return RTLIL::unescape_id(design->top_module()->name) +
+	                      "/" + SelectionType() + ":" + obj;
                    });
     extra_args(selection_args, 0, design);
     if (design->selected_modules().empty()) {
 	if (!args.is_quiet) {
-	    log_warning("Specified %s not found in design\n", TypeName().c_str());
+	    log_warning("Specified %s not found in design\n",
+	                TypeName().c_str());
 	}
     }
 }
 
-void GetCmd::PackSelectionToTcl(RTLIL::Design* design, const CommandArgs& args) {
-    // Pack the selected nets into Tcl List
-    Tcl_Obj* tcl_list = Tcl_NewListObj(0, NULL);
-    for (auto module : design->selected_modules()) {
-	ExtractSelection(tcl_list, module, args);
+void GetCmd::PackToTcl(const SelectionObjects& objects) {
+    Tcl_Obj* tcl_result;
+    if (objects.size() == 1) {
+	tcl_result = Tcl_NewStringObj(objects.at(0).c_str(), -1);
+    } else {
+	tcl_result = Tcl_NewListObj(0, NULL);
+	for (const auto& object : objects) {
+	    Tcl_Obj* value_obj = Tcl_NewStringObj(object.c_str(), -1);
+	    Tcl_ListObjAppendElement(yosys_get_tcl_interp(), tcl_result,
+	                             value_obj);
+	}
     }
-    if (!args.is_quiet) {
-	log("\n");
-    }
-    Tcl_SetObjResult(yosys_get_tcl_interp(), tcl_list);
+    Tcl_SetObjResult(yosys_get_tcl_interp(), tcl_result);
 }
 
 GetCmd::CommandArgs GetCmd::ParseCommand(const std::vector<std::string>& args) {
@@ -98,7 +103,7 @@
 		                  args[argidx].c_str());
 		}
 		parsed_args.filters.emplace_back(filter.substr(0, separator),
-		                     filter.substr(separator + 2));
+		                                 filter.substr(separator + 2));
 	    }
 	    if (parsed_args.filters.size() > 1) {
 		log_warning(
@@ -115,7 +120,8 @@
 
 	break;
     }
-    std::copy(args.begin() + argidx, args.end(), std::back_inserter(parsed_args.selection_objects));
+    std::copy(args.begin() + argidx, args.end(),
+              std::back_inserter(parsed_args.selection_objects));
     return parsed_args;
 }
 
@@ -126,5 +132,5 @@
 
     CommandArgs parsed_args(ParseCommand(args));
     ExecuteSelection(design, parsed_args);
-    PackSelectionToTcl(design, parsed_args);
+    PackToTcl(ExtractSelection(design, parsed_args));
 }
diff --git a/design_introspection-plugin/get_cmd.h b/design_introspection-plugin/get_cmd.h
index 5eb295b..d3d524b 100644
--- a/design_introspection-plugin/get_cmd.h
+++ b/design_introspection-plugin/get_cmd.h
@@ -22,13 +22,15 @@
     void execute(std::vector<std::string> args, RTLIL::Design* design) override;
 
    protected:
+    CommandArgs ParseCommand(const std::vector<std::string>& args);
+    void PackToTcl(const SelectionObjects& objects);
+
+   private:
     virtual std::string TypeName() = 0;
     virtual std::string SelectionType() = 0;
-    CommandArgs ParseCommand(const std::vector<std::string>& args);
-    virtual void ExtractSelection(Tcl_Obj*, RTLIL::Module*, const CommandArgs& args) {}
+    virtual SelectionObjects ExtractSelection(RTLIL::Design* design, const CommandArgs& args) = 0;
     virtual void ExecuteSelection(RTLIL::Design* design,
                                   const CommandArgs& args);
-    virtual void PackSelectionToTcl(RTLIL::Design* design, const CommandArgs& args);
 };
 
 #endif  // GET_CMD_H_
diff --git a/design_introspection-plugin/get_nets.cc b/design_introspection-plugin/get_nets.cc
index 75adf91..504bb87 100644
--- a/design_introspection-plugin/get_nets.cc
+++ b/design_introspection-plugin/get_nets.cc
@@ -6,21 +6,25 @@
 
 std::string GetNets::SelectionType() { return "w"; }
 
-void GetNets::ExtractSelection(Tcl_Obj* tcl_list, RTLIL::Module* module,
-                               const CommandArgs& args) {
-    for (auto wire : module->selected_wires()) {
-	if (args.filters.size() > 0) {
-	    Filter filter = args.filters.at(0);
-	    std::string attr_value = wire->get_string_attribute(
-	        RTLIL::IdString(RTLIL::escape_id(filter.first)));
-	    if (attr_value.compare(filter.second)) {
-		continue;
+GetNets::SelectionObjects GetNets::ExtractSelection(RTLIL::Design* design,
+                                                    const CommandArgs& args) {
+    SelectionObjects selected_objects;
+    for (auto module : design->selected_modules()) {
+	for (auto wire : module->selected_wires()) {
+	    if (args.filters.size() > 0) {
+		Filter filter = args.filters.at(0);
+		std::string attr_value = wire->get_string_attribute(
+		    RTLIL::IdString(RTLIL::escape_id(filter.first)));
+		if (attr_value.compare(filter.second)) {
+		    continue;
+		}
 	    }
+	    std::string object_name(RTLIL::unescape_id(wire->name));
+	    if (!args.is_quiet) {
+		log("%s ", object_name.c_str());
+	    }
+	    selected_objects.push_back(object_name);
 	}
-	if (!args.is_quiet) {
-	    log("%s ", id2cstr(wire->name));
-	}
-	Tcl_Obj* value_obj = Tcl_NewStringObj(id2cstr(wire->name), -1);
-	Tcl_ListObjAppendElement(yosys_get_tcl_interp(), tcl_list, value_obj);
     }
+    return selected_objects;
 }
diff --git a/design_introspection-plugin/get_nets.h b/design_introspection-plugin/get_nets.h
index bd0f453..ab738a1 100644
--- a/design_introspection-plugin/get_nets.h
+++ b/design_introspection-plugin/get_nets.h
@@ -10,8 +10,8 @@
 
     std::string TypeName() override;
     std::string SelectionType() override;
-    void ExtractSelection(Tcl_Obj* tcl_list, RTLIL::Module* module,
-                          const CommandArgs& args) override;
+    SelectionObjects ExtractSelection(RTLIL::Design* design,
+                                      const CommandArgs& args) override;
 };
 
 #endif  // GET_NETS_H_
diff --git a/design_introspection-plugin/get_pins.cc b/design_introspection-plugin/get_pins.cc
index ef6e887..f57662d 100644
--- a/design_introspection-plugin/get_pins.cc
+++ b/design_introspection-plugin/get_pins.cc
@@ -28,6 +28,10 @@
     Tcl_SetObjResult(yosys_get_tcl_interp(), tcl_list);
 }
 
+GetPins::SelectionObjects GetPins::ExtractSelection(RTLIL::Design* design, const CommandArgs& args) {
+    return SelectionObjects();
+}
+
 void GetPins::ExtractSingleSelection(Tcl_Obj* tcl_list, RTLIL::Design* design,
                                      const std::string& port_name,
                                      const CommandArgs& args) {
diff --git a/design_introspection-plugin/get_pins.h b/design_introspection-plugin/get_pins.h
index 0a7e90e..ab5bf75 100644
--- a/design_introspection-plugin/get_pins.h
+++ b/design_introspection-plugin/get_pins.h
@@ -8,11 +8,12 @@
 struct GetPins : public GetCmd {
     GetPins() : GetCmd("get_pins", "Print matching pins") {}
 
+   private:
     std::string TypeName() override;
     std::string SelectionType() override;
     void execute(std::vector<std::string> args, RTLIL::Design* design) override;
-
-   private:
+    SelectionObjects ExtractSelection(RTLIL::Design* design,
+                                      const CommandArgs& args) override;
     void ExtractSingleSelection(Tcl_Obj* tcl_list, RTLIL::Design* design,
                                 const std::string& port_name,
                                 const CommandArgs& args);
diff --git a/design_introspection-plugin/get_ports.cc b/design_introspection-plugin/get_ports.cc
index 0476ef1..8c60712 100644
--- a/design_introspection-plugin/get_ports.cc
+++ b/design_introspection-plugin/get_ports.cc
@@ -6,6 +6,10 @@
 
 std::string GetPorts::SelectionType() { return "x"; }
 
+GetPorts::SelectionObjects GetPorts::ExtractSelection(RTLIL::Design* design, const CommandArgs& args) {
+    return SelectionObjects();
+}
+
 void GetPorts::execute(std::vector<std::string> args, RTLIL::Design* design) {
     if (args.size() < 2) {
 	log_cmd_error("No port specified.\n");
diff --git a/design_introspection-plugin/get_ports.h b/design_introspection-plugin/get_ports.h
index a06bc53..7a66d6d 100644
--- a/design_introspection-plugin/get_ports.h
+++ b/design_introspection-plugin/get_ports.h
@@ -8,9 +8,12 @@
 struct GetPorts : public GetCmd {
     GetPorts() : GetCmd("get_ports", "Print matching ports") {}
 
+   private:
     std::string TypeName() override;
     std::string SelectionType() override;
     void execute(std::vector<std::string> args, RTLIL::Design* design) override;
+    SelectionObjects ExtractSelection(RTLIL::Design* design,
+                                      const CommandArgs& args) override;
 };
 
 #endif  // GET_PORTS_H_