+ * user categories support
+ */
+static void recursiveNewVariableType(const std::string& new_typename, const std::string& color,
+ simgrid::instr::Type* root)
+{
+ if (root->get_name() == "HOST" || root->get_name() == "VM")
+ root->by_name_or_create(std::string("p") + new_typename, color);
+
+ if (root->get_name() == "LINK")
+ root->by_name_or_create(std::string("b") + new_typename, color);
+
+ for (auto const& [_, child] : root->get_children()) {
+ recursiveNewVariableType(new_typename, color, child.get());
+ }
+}
+
+void instr_new_variable_type(const std::string& new_typename, const std::string& color)
+{
+ recursiveNewVariableType(new_typename, color, simgrid::instr::Container::get_root()->get_type());
+}
+
+static void recursiveNewUserVariableType(const std::string& parent_type, const std::string& new_typename,
+ const std::string& color, simgrid::instr::Type* root)
+{
+ if (root->get_name() == parent_type) {
+ root->by_name_or_create(new_typename, color);
+ }
+ for (auto const& [_, child] : root->get_children())
+ recursiveNewUserVariableType(parent_type, new_typename, color, child.get());
+}
+
+void instr_new_user_variable_type(const std::string& parent_type, const std::string& new_typename,
+ const std::string& color)
+{
+ recursiveNewUserVariableType(parent_type, new_typename, color, simgrid::instr::Container::get_root()->get_type());
+}
+
+static void recursiveNewUserStateType(const std::string& parent_type, const std::string& new_typename,
+ simgrid::instr::Type* root)
+{
+ if (root->get_name() == parent_type)
+ root->by_name_or_create<simgrid::instr::StateType>(new_typename);
+
+ for (auto const& [_, child] : root->get_children())
+ recursiveNewUserStateType(parent_type, new_typename, child.get());
+}
+
+void instr_new_user_state_type(const std::string& parent_type, const std::string& new_typename)
+{
+ recursiveNewUserStateType(parent_type, new_typename, simgrid::instr::Container::get_root()->get_type());
+}
+
+static void recursiveNewValueForUserStateType(const std::string& type_name, const char* val, const std::string& color,
+ simgrid::instr::Type* root)
+{
+ if (root->get_name() == type_name)
+ static_cast<simgrid::instr::StateType*>(root)->add_entity_value(val, color);
+
+ for (auto const& [_, child] : root->get_children())
+ recursiveNewValueForUserStateType(type_name, val, color, child.get());
+}
+
+void instr_new_value_for_user_state_type(const std::string& type_name, const char* value, const std::string& color)
+{
+ recursiveNewValueForUserStateType(type_name, value, color, simgrid::instr::Container::get_root()->get_type());
+}
+
+namespace simgrid {
+namespace instr {
+
+/** @brief Creates a file with the topology of the platform file used for the simulator.
+ *
+ * The graph topology will have the following properties: all hosts, links and routers of the platform file are mapped
+ * to graph nodes; routes are mapped to edges. The platform's zones are not represented in the output.