+
+static void handle_action(ReplayAction* action)
+{
+ XBT_DEBUG("%s replays a %s action", action->at(0).c_str(), action->at(1).c_str());
+ char** c_action = new char*[action->size() + 1];
+ action_fun function = action_funs.at(action->at(1));
+ int i = 0;
+ for (auto arg : *action) {
+ c_action[i] = xbt_strdup(arg.c_str());
+ i++;
+ }
+ c_action[i] = nullptr;
+ try {
+ function(c_action);
+ } catch (xbt_ex& e) {
+ for (unsigned int j = 0; j < action->size(); j++)
+ xbt_free(c_action[j]);
+ delete[] c_action;
+ action->clear();
+ xbt_die("Replay error:\n %s", e.what());
+ }
+ for (unsigned int j = 0; j < action->size(); j++)
+ xbt_free(c_action[j]);
+ delete[] c_action;
+}
+
+/**
+ * \ingroup XBT_replay
+ * \brief function used internally to actually run the replay
+
+ * \param argc argc .
+ * \param argv argv
+ */
+int replay_runner(int argc, char* argv[])
+{
+ if (simgrid::xbt::action_fs) { // A unique trace file
+ while (true) {
+ simgrid::xbt::ReplayAction* evt = simgrid::xbt::get_action(argv[0]);
+ if (evt == nullptr)
+ break;
+ simgrid::xbt::handle_action(evt);
+ delete evt;
+ }
+ } else { // Should have got my trace file in argument
+ simgrid::xbt::ReplayAction* evt = new simgrid::xbt::ReplayAction();
+ xbt_assert(argc >= 2, "No '%s' agent function provided, no simulation-wide trace file provided, "
+ "and no process-wide trace file provided in deployment file. Aborting.",
+ argv[0]);
+ simgrid::xbt::ReplayReader* reader = new simgrid::xbt::ReplayReader(argv[1]);
+ while (reader->get(evt)) {
+ if (evt->at(0).compare(argv[0]) == 0) {
+ simgrid::xbt::handle_action(evt);
+ } else {
+ XBT_WARN("%s:%d: Ignore trace element not for me", reader->filename_, reader->linenum);
+ }
+ evt->clear();
+ }
+ delete evt;
+ delete reader;
+ }
+ return 0;
+}
+}
+}
+
+/**
+ * \ingroup XBT_replay
+ * \brief Registers a function to handle a kind of action
+ *
+ * Registers a function to handle a kind of action
+ * This table is then used by \ref xbt_replay_action_runner
+ *
+ * The argument of the function is the line describing the action, fields separated by spaces.
+ *
+ * \param action_name the reference name of the action.
+ * \param function prototype given by the type: void...(const char** action)
+ */
+void xbt_replay_action_register(const char* action_name, action_fun function)
+{
+ if (!is_replay_active) // If the user registers a function before the start
+ simgrid::xbt::replay_init();
+ simgrid::xbt::action_funs.insert({std::string(action_name), function});
+}