<commit_before>#include "assert.hh"
#include "buffer.hh"
#include "buffer_manager.hh"
#include "buffer_utils.hh"
#include "client_manager.hh"
#include "command_manager.hh"
#include "commands.hh"
#include "context.hh"
#include "debug.hh"
#include "event_manager.hh"
#include "face_registry.hh"
#include "file.hh"
#include "highlighters.hh"
#include "hook_manager.hh"
#include "keymap_manager.hh"
#include "ncurses.hh"
#include "option_manager.hh"
#include "parameters_parser.hh"
#include "register_manager.hh"
#include "remote.hh"
#include "shell_manager.hh"
#include "string.hh"
#include "window.hh"

#if defined(__APPLE__)
#include <mach-o/dyld.h>
#endif

#include <unordered_map>
#include <locale>
#include <signal.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

using namespace Kakoune;

void run_unit_tests();

String runtime_directory()
{
    char buffer[2048];
#if defined(__linux__) || defined(__CYGWIN__)
    ssize_t res = readlink("/proc/self/exe", buffer, 2048);
    kak_assert(res != -1);
    buffer[res] = '\0';
#elif defined(__APPLE__)
    uint32_t bufsize = 2048;
    _NSGetExecutablePath(buffer, &bufsize);
    char* canonical_path = realpath(buffer, nullptr);
    strncpy(buffer, canonical_path, 2048);
    free(canonical_path);
#else
# error "finding executable path is not implemented on this platform"
#endif
    char* ptr = strrchr(buffer, '/');
    if (not ptr)
        throw runtime_error("unable to determine runtime directory");
    return String(buffer, ptr) + "/../share/kak";
}

void register_env_vars()
{
    static const struct {
        const char* name;
        String (*func)(StringView, const Context&);
    } env_vars[] = { {
            "bufname",
            [](StringView name, const Context& context)
            { return context.buffer().display_name(); }
        }, {
            "buffile",
            [](StringView name, const Context& context) -> String
            { return context.buffer().name(); }
        }, {
            "timestamp",
            [](StringView name, const Context& context)
            { return to_string(context.buffer().timestamp()); }
        }, {
            "selection",
            [](StringView name, const Context& context)
            { const Selection& sel = context.selections().main();
              return content(context.buffer(), sel); }
        }, {
            "selections",
            [](StringView name, const Context& context)
            { auto sels = context.selections_content();
              String res;
              for (size_t i = 0; i < sels.size(); ++i)
              {
                  res += escape(sels[i], ':', '\\');
                  if (i != sels.size() - 1)
                      res += ':';
              }
              return res; }
        }, {
            "runtime",
            [](StringView name, const Context& context)
            { return runtime_directory(); }
        }, {
            "opt_.+",
            [](StringView name, const Context& context)
            { return context.options()[name.substr(4_byte)].get_as_string(); }
        }, {
            "reg_.+",
            [](StringView name, const Context& context) -> String
            { return context.main_sel_register_value(name.substr(4_byte)); }
        }, {
            "client_env_.+",
            [](StringView name, const Context& context) -> String
            { return context.client().get_env_var(name.substr(11_byte)); }
        }, {
            "session",
            [](StringView name, const Context& context) -> String
            { return Server::instance().session(); }
        }, {
            "client",
            [](StringView name, const Context& context) -> String
            { return context.name(); }
        }, {
            "cursor_line",
            [](StringView name, const Context& context)
            { return to_string(context.selections().main().cursor().line + 1); }
        }, {
            "cursor_column",
            [](StringView name, const Context& context)
            { return to_string(context.selections().main().cursor().column + 1); }
        }, {
            "cursor_char_column",
            [](StringView name, const Context& context)
            { auto coord = context.selections().main().cursor();
              return to_string(context.buffer()[coord.line].char_count_to(coord.column) + 1); }
        }, {
            "selection_desc",
            [](StringView name, const Context& context)
            { auto& sel = context.selections().main();
                auto beg = sel.min();
                return to_string(beg.line + 1) + '.' + to_string(beg.column + 1) + '+' +
                       to_string((int)context.buffer().distance(beg, sel.max())+1); }
        }, {
            "selections_desc",
            [](StringView name, const Context& context)
            {
                String res;
                for (auto& sel : context.selections())
                {
                    auto beg = sel.min();
                    if (not res.empty())
                        res += ':';
                    res += to_string(beg.line + 1) + '.' + to_string(beg.column + 1) + '+' +
                           to_string((int)context.buffer().distance(beg, sel.max())+1);
                }
                return res;
            }
        }, {
            "window_width",
            [](StringView name, const Context& context)
            { return to_string(context.window().dimensions().column); }
        }, {
            "window_height",
            [](StringView name, const Context& context)
            { return to_string(context.window().dimensions().line); }
    } };

    ShellManager& shell_manager = ShellManager::instance();
    for (auto& env_var : env_vars)
        shell_manager.register_env_var(env_var.name, env_var.func);
}

void register_registers()
{
    using StringList = std::vector<String>;
    static const struct {
        char name;
        StringList (*func)(const Context&);
    } dyn_regs[] = {
        { '%', [](const Context& context) { return StringList{{context.buffer().display_name()}}; } },
        { '.', [](const Context& context) { return context.selections_content(); } },
        { '#', [](const Context& context) {
            StringList res;
            for (size_t i = 1; i < context.selections().size()+1; ++i)
                res.push_back(to_string((int)i));
            return res;
        } }
    };

    RegisterManager& register_manager = RegisterManager::instance();
    for (auto& dyn_reg : dyn_regs)
        register_manager.register_dynamic_register(dyn_reg.name, dyn_reg.func);

    for (size_t i = 0; i < 10; ++i)
    {
        register_manager.register_dynamic_register('0'+i,
            [i](const Context& context) {
                std::vector<String> result;
                for (auto& sel : context.selections())
                    result.emplace_back(i < sel.captures().size() ? sel.captures()[i] : "");
                return result;
            });
    }
}

void create_local_client(const String& init_command)
{
    class LocalNCursesUI : public NCursesUI
    {
        ~LocalNCursesUI()
        {
            if (not ClientManager::instance().empty() and fork())
            {
                this->NCursesUI::~NCursesUI();
                puts("detached from terminal\n");
                exit(0);
            }
        }
    };

    if (not isatty(1))
        throw runtime_error("stdout is not a tty");

    if (not isatty(0))
    {
        // move stdin to another fd, and restore tty as stdin
        int fd = dup(0);
        int tty = open("/dev/tty", O_RDONLY);
        dup2(tty, 0);
        close(tty);
        create_fifo_buffer("*stdin*", fd);
    }

    UserInterface* ui = new LocalNCursesUI{};
    static Client* client = ClientManager::instance().create_client(
        std::unique_ptr<UserInterface>{ui}, get_env_vars(), init_command);
    signal(SIGHUP, [](int) {
        if (client)
            ClientManager::instance().remove_client(*client);
        client = nullptr;
    });
}

void signal_handler(int signal)
{
    NCursesUI::abort();
    const char* text = nullptr;
    switch (signal)
    {
        case SIGSEGV: text = "SIGSEGV"; break;
        case SIGFPE:  text = "SIGFPE";  break;
        case SIGQUIT: text = "SIGQUIT"; break;
        case SIGTERM: text = "SIGTERM"; break;
    }
    on_assert_failed(text);
    if (Server::has_instance())
        Server::instance().close_session();
    abort();
}

int run_client(const String& session, const String& init_command)
{
    try
    {
        EventManager event_manager;
        auto client = connect_to(session,
                                 std::unique_ptr<UserInterface>{new NCursesUI{}},
                                 get_env_vars(),
                                 init_command);
        while (true)
            event_manager.handle_next_events();
    }
    catch (peer_disconnected&)
    {
        fputs("disconnected from server\n", stderr);
        return -1;
    }
    catch (connection_failed& e)
    {
        fputs(e.what(), stderr);
        return -1;
    }
    return 0;
}

int kakoune(const ParametersParser& parser)
{
    if (parser.has_option("p"))
    {
        for (auto opt : { "c", "n", "s", "d", "e" })
        {
            if (parser.has_option(opt))
            {
                fprintf(stderr, "error: -%s makes not sense with -p\n", opt);
                return -1;
            }
        }
        char buf[512];
        String command;
        while (ssize_t count = read(0, buf, 512))
        {
            if (count < 0)
            {
                fprintf(stderr, "error while reading stdin\n");
                return -1;
            }
            command += String{buf, buf + count};
        }
        try
        {
            send_command(parser.option_value("p"), command);
        }
        catch (connection_failed& e)
        {
            fputs(e.what(), stderr);
            return -1;
        }
        return 0;
    }

    String init_command;
    if (parser.has_option("e"))
        init_command = parser.option_value("e");

    if (parser.has_option("c"))
    {
        for (auto opt : { "n", "s", "d" })
        {
            if (parser.has_option(opt))
            {
                fprintf(stderr, "error: -%s makes not sense with -c\n", opt);
                return -1;
            }
        }
        return run_client(parser.option_value("c"), init_command);
    }

    const bool daemon = parser.has_option("d");
    static bool terminate = false;
    if (daemon)
    {
        if (not parser.has_option("s"))
        {
            fputs("-d needs a session name to be specified with -s\n", stderr);
            return -1;
        }
        if (pid_t child = fork())
        {
            printf("Kakoune forked to background, for session '%s'\n"
                   "send SIGTERM to process %d for closing the session\n",
                   parser.option_value("s").c_str(), child);
            exit(0);
        }
        signal(SIGTERM, [](int) { terminate = true; });
    }

    EventManager        event_manager;
    GlobalOptions       global_options;
    GlobalHooks         global_hooks;
    GlobalKeymaps       global_keymaps;
    ShellManager        shell_manager;
    CommandManager      command_manager;
    BufferManager       buffer_manager;
    RegisterManager     register_manager;
    HighlighterRegistry highlighter_registry;
    DefinedHighlighters defined_highlighters;
    FaceRegistry        face_registry;
    ClientManager       client_manager;

    run_unit_tests();

    register_env_vars();
    register_registers();
    register_commands();
    register_highlighters();

    write_debug("*** This is the debug buffer, where debug info will be written ***");
    write_debug("pid: " + to_string(getpid()));

    Server server(parser.has_option("s") ? parser.option_value("s") : to_string(getpid()));
    write_debug("session: " + server.session());

    if (not parser.has_option("n")) try
    {
        Context initialisation_context;
        command_manager.execute("source " + runtime_directory() + "/kakrc",
                                initialisation_context);
    }
    catch (Kakoune::runtime_error& error)
    {
        write_debug("error while parsing kakrc:\n    "_str + error.what());
    }
    catch (Kakoune::client_removed&)
    {
        write_debug("error while parsing kakrc: asked to quit");
    }

    {
        Context empty_context;
        global_hooks.run_hook("KakBegin", "", empty_context);
    }

    if (parser.positional_count() != 0) try
    {
        // create buffers in reverse order so that the first given buffer
        // is the most recently created one.
        for (int i = parser.positional_count() - 1; i >= 0; --i)
        {
            const String& file = parser[i];
            if (not create_buffer_from_file(file))
                new Buffer(file, Buffer::Flags::New | Buffer::Flags::File);
        }
    }
    catch (Kakoune::runtime_error& error)
    {
         write_debug("error while opening command line files: "_str + error.what());
    }
    else
        new Buffer("*scratch*", Buffer::Flags::None);

    if (not daemon)
        create_local_client(init_command);

    while (not terminate and (not client_manager.empty() or daemon))
    {
        event_manager.handle_next_events();
        client_manager.clear_mode_trashes();
        buffer_manager.clear_buffer_trash();
        client_manager.redraw_clients();
    }

    {
        Context empty_context;
        global_hooks.run_hook("KakEnd", "", empty_context);
    }
    return 0;
}

int main(int argc, char* argv[])
{
    setlocale(LC_ALL, "");

    signal(SIGSEGV, signal_handler);
    signal(SIGFPE,  signal_handler);
    signal(SIGQUIT, signal_handler);
    signal(SIGTERM, signal_handler);

    std::vector<String> params;
    for (size_t i = 1; i < argc; ++i)
        params.push_back(argv[i]);

    const ParameterDesc param_desc{
        SwitchMap{ { "c", { true, "connect to given session" } },
                   { "e", { true, "execute argument on initialisation" } },
                   { "n", { false, "do not source kakrc files on startup" } },
                   { "s", { true, "set session name" } },
                   { "d", { false, "run as a headless session (requires -s)" } },
                   { "p", { true, "just send stdin as commands to the given session" } } }
    };
    try
    {
        kakoune(ParametersParser(params, param_desc));
    }
    catch (Kakoune::parameter_error& error)
    {
        printf("Error: %s\n"
               "Valid switches:\n"
               "%s",
               error.what(), generate_switches_doc(param_desc.switches).c_str());
       return -1;
    }
    catch (Kakoune::exception& error)
    {
        on_assert_failed(("uncaught exception:\n"_str + error.what()).c_str());
        return -1;
    }
    catch (std::exception& error)
    {
        on_assert_failed(("uncaught exception:\n"_str + error.what()).c_str());
        return -1;
    }
    catch (...)
    {
        on_assert_failed("uncaught exception");
        return -1;
    }
    return 0;
}
<commit_msg>Refactor main loops, use separate functions for each running mode<commit_after>#include "assert.hh"
#include "buffer.hh"
#include "buffer_manager.hh"
#include "buffer_utils.hh"
#include "client_manager.hh"
#include "command_manager.hh"
#include "commands.hh"
#include "context.hh"
#include "debug.hh"
#include "event_manager.hh"
#include "face_registry.hh"
#include "file.hh"
#include "highlighters.hh"
#include "hook_manager.hh"
#include "keymap_manager.hh"
#include "ncurses.hh"
#include "option_manager.hh"
#include "parameters_parser.hh"
#include "register_manager.hh"
#include "remote.hh"
#include "shell_manager.hh"
#include "string.hh"
#include "window.hh"

#if defined(__APPLE__)
#include <mach-o/dyld.h>
#endif

#include <unordered_map>
#include <locale>
#include <signal.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

using namespace Kakoune;

void run_unit_tests();

String runtime_directory()
{
    char buffer[2048];
#if defined(__linux__) || defined(__CYGWIN__)
    ssize_t res = readlink("/proc/self/exe", buffer, 2048);
    kak_assert(res != -1);
    buffer[res] = '\0';
#elif defined(__APPLE__)
    uint32_t bufsize = 2048;
    _NSGetExecutablePath(buffer, &bufsize);
    char* canonical_path = realpath(buffer, nullptr);
    strncpy(buffer, canonical_path, 2048);
    free(canonical_path);
#else
# error "finding executable path is not implemented on this platform"
#endif
    char* ptr = strrchr(buffer, '/');
    if (not ptr)
        throw runtime_error("unable to determine runtime directory");
    return String(buffer, ptr) + "/../share/kak";
}

void register_env_vars()
{
    static const struct {
        const char* name;
        String (*func)(StringView, const Context&);
    } env_vars[] = { {
            "bufname",
            [](StringView name, const Context& context)
            { return context.buffer().display_name(); }
        }, {
            "buffile",
            [](StringView name, const Context& context) -> String
            { return context.buffer().name(); }
        }, {
            "timestamp",
            [](StringView name, const Context& context)
            { return to_string(context.buffer().timestamp()); }
        }, {
            "selection",
            [](StringView name, const Context& context)
            { const Selection& sel = context.selections().main();
              return content(context.buffer(), sel); }
        }, {
            "selections",
            [](StringView name, const Context& context)
            { auto sels = context.selections_content();
              String res;
              for (size_t i = 0; i < sels.size(); ++i)
              {
                  res += escape(sels[i], ':', '\\');
                  if (i != sels.size() - 1)
                      res += ':';
              }
              return res; }
        }, {
            "runtime",
            [](StringView name, const Context& context)
            { return runtime_directory(); }
        }, {
            "opt_.+",
            [](StringView name, const Context& context)
            { return context.options()[name.substr(4_byte)].get_as_string(); }
        }, {
            "reg_.+",
            [](StringView name, const Context& context) -> String
            { return context.main_sel_register_value(name.substr(4_byte)); }
        }, {
            "client_env_.+",
            [](StringView name, const Context& context) -> String
            { return context.client().get_env_var(name.substr(11_byte)); }
        }, {
            "session",
            [](StringView name, const Context& context) -> String
            { return Server::instance().session(); }
        }, {
            "client",
            [](StringView name, const Context& context) -> String
            { return context.name(); }
        }, {
            "cursor_line",
            [](StringView name, const Context& context)
            { return to_string(context.selections().main().cursor().line + 1); }
        }, {
            "cursor_column",
            [](StringView name, const Context& context)
            { return to_string(context.selections().main().cursor().column + 1); }
        }, {
            "cursor_char_column",
            [](StringView name, const Context& context)
            { auto coord = context.selections().main().cursor();
              return to_string(context.buffer()[coord.line].char_count_to(coord.column) + 1); }
        }, {
            "selection_desc",
            [](StringView name, const Context& context)
            { auto& sel = context.selections().main();
                auto beg = sel.min();
                return to_string(beg.line + 1) + '.' + to_string(beg.column + 1) + '+' +
                       to_string((int)context.buffer().distance(beg, sel.max())+1); }
        }, {
            "selections_desc",
            [](StringView name, const Context& context)
            {
                String res;
                for (auto& sel : context.selections())
                {
                    auto beg = sel.min();
                    if (not res.empty())
                        res += ':';
                    res += to_string(beg.line + 1) + '.' + to_string(beg.column + 1) + '+' +
                           to_string((int)context.buffer().distance(beg, sel.max())+1);
                }
                return res;
            }
        }, {
            "window_width",
            [](StringView name, const Context& context)
            { return to_string(context.window().dimensions().column); }
        }, {
            "window_height",
            [](StringView name, const Context& context)
            { return to_string(context.window().dimensions().line); }
    } };

    ShellManager& shell_manager = ShellManager::instance();
    for (auto& env_var : env_vars)
        shell_manager.register_env_var(env_var.name, env_var.func);
}

void register_registers()
{
    using StringList = std::vector<String>;
    static const struct {
        char name;
        StringList (*func)(const Context&);
    } dyn_regs[] = {
        { '%', [](const Context& context) { return StringList{{context.buffer().display_name()}}; } },
        { '.', [](const Context& context) { return context.selections_content(); } },
        { '#', [](const Context& context) {
            StringList res;
            for (size_t i = 1; i < context.selections().size()+1; ++i)
                res.push_back(to_string((int)i));
            return res;
        } }
    };

    RegisterManager& register_manager = RegisterManager::instance();
    for (auto& dyn_reg : dyn_regs)
        register_manager.register_dynamic_register(dyn_reg.name, dyn_reg.func);

    for (size_t i = 0; i < 10; ++i)
    {
        register_manager.register_dynamic_register('0'+i,
            [i](const Context& context) {
                std::vector<String> result;
                for (auto& sel : context.selections())
                    result.emplace_back(i < sel.captures().size() ? sel.captures()[i] : "");
                return result;
            });
    }
}

void create_local_client(const String& init_command)
{
    class LocalNCursesUI : public NCursesUI
    {
        ~LocalNCursesUI()
        {
            if (not ClientManager::instance().empty() and fork())
            {
                this->NCursesUI::~NCursesUI();
                puts("detached from terminal\n");
                exit(0);
            }
        }
    };

    if (not isatty(1))
        throw runtime_error("stdout is not a tty");

    if (not isatty(0))
    {
        // move stdin to another fd, and restore tty as stdin
        int fd = dup(0);
        int tty = open("/dev/tty", O_RDONLY);
        dup2(tty, 0);
        close(tty);
        create_fifo_buffer("*stdin*", fd);
    }

    UserInterface* ui = new LocalNCursesUI{};
    static Client* client = ClientManager::instance().create_client(
        std::unique_ptr<UserInterface>{ui}, get_env_vars(), init_command);
    signal(SIGHUP, [](int) {
        if (client)
            ClientManager::instance().remove_client(*client);
        client = nullptr;
    });
}

void signal_handler(int signal)
{
    NCursesUI::abort();
    const char* text = nullptr;
    switch (signal)
    {
        case SIGSEGV: text = "SIGSEGV"; break;
        case SIGFPE:  text = "SIGFPE";  break;
        case SIGQUIT: text = "SIGQUIT"; break;
        case SIGTERM: text = "SIGTERM"; break;
    }
    on_assert_failed(text);
    if (Server::has_instance())
        Server::instance().close_session();
    abort();
}

int run_client(StringView session, StringView init_command)
{
    try
    {
        EventManager event_manager;
        auto client = connect_to(session,
                                 std::unique_ptr<UserInterface>{new NCursesUI{}},
                                 get_env_vars(),
                                 init_command);
        while (true)
            event_manager.handle_next_events();
    }
    catch (peer_disconnected&)
    {
        fputs("disconnected from server\n", stderr);
        return -1;
    }
    catch (connection_failed& e)
    {
        fputs(e.what(), stderr);
        return -1;
    }
    return 0;
}

int run_server(StringView session, StringView init_command,
               bool ignore_kakrc, bool daemon, memoryview<StringView> files)
{
    static bool terminate = false;
    if (daemon)
    {
        if (session.empty())
        {
            fputs("-d needs a session name to be specified with -s\n", stderr);
            return -1;
        }
        if (pid_t child = fork())
        {
            printf("Kakoune forked to background, for session '%s'\n"
                   "send SIGTERM to process %d for closing the session\n",
                   (const char*)session.zstr(), child);
            exit(0);
        }
        signal(SIGTERM, [](int) { terminate = true; });
    }

    EventManager        event_manager;
    GlobalOptions       global_options;
    GlobalHooks         global_hooks;
    GlobalKeymaps       global_keymaps;
    ShellManager        shell_manager;
    CommandManager      command_manager;
    BufferManager       buffer_manager;
    RegisterManager     register_manager;
    HighlighterRegistry highlighter_registry;
    DefinedHighlighters defined_highlighters;
    FaceRegistry        face_registry;
    ClientManager       client_manager;

    run_unit_tests();

    register_env_vars();
    register_registers();
    register_commands();
    register_highlighters();

    write_debug("*** This is the debug buffer, where debug info will be written ***");
    write_debug("pid: " + to_string(getpid()));

    Server server(session.empty() ? to_string(getpid()) : String{session});
    write_debug("session: " + server.session());

    if (not ignore_kakrc) try
    {
        Context initialisation_context;
        command_manager.execute("source " + runtime_directory() + "/kakrc",
                                initialisation_context);
    }
    catch (Kakoune::runtime_error& error)
    {
        write_debug("error while parsing kakrc:\n    "_str + error.what());
    }
    catch (Kakoune::client_removed&)
    {
        write_debug("error while parsing kakrc: asked to quit");
    }

    {
        Context empty_context;
        global_hooks.run_hook("KakBegin", "", empty_context);
    }

    if (not files.empty()) try
    {
        // create buffers in reverse order so that the first given buffer
        // is the most recently created one.
        for (auto& file : reversed(files))
        {
            if (not create_buffer_from_file(file))
                new Buffer(file, Buffer::Flags::New | Buffer::Flags::File);
        }
    }
    catch (Kakoune::runtime_error& error)
    {
         write_debug("error while opening command line files: "_str + error.what());
    }
    else
        new Buffer("*scratch*", Buffer::Flags::None);

    if (not daemon)
        create_local_client(init_command);

    while (not terminate and (not client_manager.empty() or daemon))
    {
        event_manager.handle_next_events();
        client_manager.clear_mode_trashes();
        buffer_manager.clear_buffer_trash();
        client_manager.redraw_clients();
    }

    {
        Context empty_context;
        global_hooks.run_hook("KakEnd", "", empty_context);
    }

    return 0;
}

int run_pipe(StringView session)
{
    char buf[512];
    String command;
    while (ssize_t count = read(0, buf, 512))
    {
        if (count < 0)
        {
            fprintf(stderr, "error while reading stdin\n");
            return -1;
        }
        command += String{buf, buf + count};
    }
    try
    {
        send_command(session, command);
    }
    catch (connection_failed& e)
    {
        fputs(e.what(), stderr);
        return -1;
    }
    return 0;
}

int kakoune(const ParametersParser& parser)
{
    if (parser.has_option("p"))
    {
        for (auto opt : { "c", "n", "s", "d", "e" })
        {
            if (parser.has_option(opt))
            {
                fprintf(stderr, "error: -%s makes not sense with -p\n", opt);
                return -1;
            }
        }
        return run_pipe(parser.option_value("p"));
    }

    String init_command;
    if (parser.has_option("e"))
        init_command = parser.option_value("e");

    if (parser.has_option("c"))
    {
        for (auto opt : { "n", "s", "d" })
        {
            if (parser.has_option(opt))
            {
                fprintf(stderr, "error: -%s makes not sense with -c\n", opt);
                return -1;
            }
        }
        return run_client(parser.option_value("c"), init_command);
    }
    else
    {
        std::vector<StringView> files;
        for (size_t i = 0; i < parser.positional_count(); ++i)
            files.emplace_back(parser[i]);
        StringView session;
        if (parser.has_option("s"))
            session = parser.option_value("s");

        return run_server(session, init_command,
                          parser.has_option("d"),
                          parser.has_option("n"),
                          files);
    }
}

int main(int argc, char* argv[])
{
    setlocale(LC_ALL, "");

    signal(SIGSEGV, signal_handler);
    signal(SIGFPE,  signal_handler);
    signal(SIGQUIT, signal_handler);
    signal(SIGTERM, signal_handler);

    std::vector<String> params;
    for (size_t i = 1; i < argc; ++i)
        params.push_back(argv[i]);

    const ParameterDesc param_desc{
        SwitchMap{ { "c", { true, "connect to given session" } },
                   { "e", { true, "execute argument on initialisation" } },
                   { "n", { false, "do not source kakrc files on startup" } },
                   { "s", { true, "set session name" } },
                   { "d", { false, "run as a headless session (requires -s)" } },
                   { "p", { true, "just send stdin as commands to the given session" } } }
    };
    try
    {
        kakoune(ParametersParser(params, param_desc));
    }
    catch (Kakoune::parameter_error& error)
    {
        printf("Error: %s\n"
               "Valid switches:\n"
               "%s",
               error.what(), generate_switches_doc(param_desc.switches).c_str());
       return -1;
    }
    catch (Kakoune::exception& error)
    {
        on_assert_failed(("uncaught exception:\n"_str + error.what()).c_str());
        return -1;
    }
    catch (std::exception& error)
    {
        on_assert_failed(("uncaught exception:\n"_str + error.what()).c_str());
        return -1;
    }
    catch (...)
    {
        on_assert_failed("uncaught exception");
        return -1;
    }
    return 0;
}
<|endoftext|>


<commit_before>/**
 * \file   main.cc
 * \Author Andrea Barberio <insomniac@slackware.it>
 * \date   October 2015
 * \brief  entry point for dublin-traceroute
 *
 * This file contains the main routine for calling the standalone dublin-traceroute
 * executable.
 */

#include <iostream>
#include <fstream>

#include <dublintraceroute/dublin_traceroute.h>

// TODO argument parsing

#define TARGET		"8.8.8.8"
#define PATHS		10

void
usage(const char *name) {
	std::cout << "Usage: " << name << " target" << std::endl
		<< std::endl
		<< "See documentation at https://dublin-traceroute.net" << std::endl
		<< "Please report bugs at https://github.com/insomniacslk/dublin-traceroute" << std::endl;
	exit(EXIT_SUCCESS);
}

int
main(int argc, char **argv) {
	if (argc != 2)
		usage(argv[0]);

	const std::string target = std::string(argv[1]);
	std::cout << "Starting dublin-traceroute" << std::endl;

	DublinTraceroute Dublin(
			target,
			12345,
			(1<<15) + 666,  // traceroute's port
			PATHS
	);
	std::cout
		<< "Traceroute from 0.0.0.0:" << Dublin.srcport()
		<< " to " << Dublin.dst()
		<< ":" << Dublin.dstport() << "~" << (Dublin.dstport() + PATHS - 1)
		<< std::endl;

	std::shared_ptr<TracerouteResults> results;
	try {
		results = std::make_shared<TracerouteResults>(Dublin.traceroute());
	} catch (DublinTracerouteException &e) {
		std::cout << "Failed: " << e.what() << std::endl;
		exit(EXIT_FAILURE);
	} catch (std::runtime_error &e) {
		std::cout << "Failed: " << e.what() << std::endl;
		exit(EXIT_FAILURE);
	}

	results->show();

	// Save as JSON
	std::ofstream jsonfile;
	jsonfile.open("trace.json");
	jsonfile << results->to_json();
	jsonfile.close();
	std::cout << "Saved JSON file to trace.json ." << std::endl;

	std::cout << "You can convert it to DOT by running python -m dublintraceroute --plot trace.json" << std::endl;

	exit(EXIT_SUCCESS);
}

<commit_msg>Updated main to reflect the latest python module usage<commit_after>/**
 * \file   main.cc
 * \Author Andrea Barberio <insomniac@slackware.it>
 * \date   October 2015
 * \brief  entry point for dublin-traceroute
 *
 * This file contains the main routine for calling the standalone dublin-traceroute
 * executable.
 */

#include <iostream>
#include <fstream>

#include <dublintraceroute/dublin_traceroute.h>

// TODO argument parsing

#define TARGET		"8.8.8.8"
#define PATHS		10

void
usage(const char *name) {
	std::cout << "Usage: " << name << " target" << std::endl
		<< std::endl
		<< "See documentation at https://dublin-traceroute.net" << std::endl
		<< "Please report bugs at https://github.com/insomniacslk/dublin-traceroute" << std::endl;
	exit(EXIT_SUCCESS);
}

int
main(int argc, char **argv) {
	if (argc != 2)
		usage(argv[0]);

	const std::string target = std::string(argv[1]);
	std::cout << "Starting dublin-traceroute" << std::endl;

	DublinTraceroute Dublin(
			target,
			12345,
			(1<<15) + 666,  // traceroute's port
			PATHS
	);
	std::cout
		<< "Traceroute from 0.0.0.0:" << Dublin.srcport()
		<< " to " << Dublin.dst()
		<< ":" << Dublin.dstport() << "~" << (Dublin.dstport() + PATHS - 1)
		<< std::endl;

	std::shared_ptr<TracerouteResults> results;
	try {
		results = std::make_shared<TracerouteResults>(Dublin.traceroute());
	} catch (DublinTracerouteException &e) {
		std::cout << "Failed: " << e.what() << std::endl;
		exit(EXIT_FAILURE);
	} catch (std::runtime_error &e) {
		std::cout << "Failed: " << e.what() << std::endl;
		exit(EXIT_FAILURE);
	}

	results->show();

	// Save as JSON
	std::ofstream jsonfile;
	jsonfile.open("trace.json");
	jsonfile << results->to_json();
	jsonfile.close();
	std::cout << "Saved JSON file to trace.json ." << std::endl;

	std::cout << "You can convert it to DOT by running python -m dublintraceroute plot trace.json" << std::endl;

	exit(EXIT_SUCCESS);
}

<|endoftext|>


<commit_before>#include <debugger/breakpoint.h>
#include <debugger/evaluate.h>
#include <debugger/impl.h>
#include <debugger/lua.h>
#include <regex>

namespace vscode
{
	std::string lua_tostr(lua_State* L, int idx);

	static bool evaluate_isok(lua_State* L, lua::Debug *ar, const std::string& script)
	{
		int nresult = 0;
		if (!evaluate(L, ar, ("return " + script).c_str(), nresult))
		{
			lua_pop(L, 1);
			return false;
		}
		if (nresult > 0 && lua_type(L, -nresult) == LUA_TBOOLEAN && lua_toboolean(L, -nresult))
		{
			lua_pop(L, nresult);
			return true;
		}
		lua_pop(L, nresult);
		return false;
	}

	static std::string evaluate_getstr(lua_State* L, lua::Debug *ar, const std::string& script)
	{
		int nresult = 0;
		if (!evaluate(L, ar, ("return tostring(" + script + ")").c_str(), nresult))
		{
			lua_pop(L, 1);
			return "";
		}
		if (nresult <= 0)
		{
			return "";
		}
		std::string res = lua_tostr(L, -nresult);
		lua_pop(L, nresult);
		return res;
	}

	static std::string evaluate_log(lua_State* L, lua::Debug *ar, const std::string& log)
	{
		try {
			std::string res;
			std::regex re(R"(\{[^\}]*\})");
			std::smatch m;
			auto it = log.begin();
			for (; std::regex_search(it, log.end(), m, re); it = m[0].second) {
				res += std::string(it, m[0].first);
				res += evaluate_getstr(L, ar, std::string(m[0].first + 1, m[0].second - 1));
			}
			res += std::string(it, log.end());
			return res;
		}
		catch (std::exception& e) {
			return e.what();
		}
	}

	bp_breakpoint::bp_breakpoint(size_t id, rapidjson::Value const& info)
		: id(id)
		, line(0)
		, verified(false)
		, cond()
		, hitcond()
		, log()
		, hit(0)
	{
		line = info["line"].GetUint();
		update(info);
	}

	void bp_breakpoint::update(rapidjson::Value const& info)
	{
		if (info.HasMember("condition")) {
			cond = info["condition"].Get<std::string>();
		}
		else {
			cond.clear();
		}
		if (info.HasMember("hitCondition")) {
			hitcond = info["hitCondition"].Get<std::string>();
		}
		else {
			hitcond.clear();
		}
		if (info.HasMember("logMessage")) {
			log = info["logMessage"].Get<std::string>();
		}
		else {
			log.clear();
		}
	}

	bool bp_breakpoint::verify(bp_source& src, debugger_impl* dbg)
	{
		if (verified) return true;
		for (size_t i = line; i < src.defined.size(); ++i) {
			switch (src.defined[i]) {
			case eLine::unknown:
				return false;
			case eLine::defined:
				if (src.verified.find(i) != src.verified.end()) {
					return false;
				}
				verified = true;
				line = i;
				if (dbg) {
					dbg->event_breakpoint("changed", this);
				}
				return true;
			case eLine::undef:
				break;
			default:
				return false;
			}
		}
		return false;
	}

	void bp_breakpoint::output(wprotocol& res)
	{
		res("id").Uint64(id);
		res("verified").Bool(verified);
		res("line").Uint64(line);
		//if (cond.empty()) { res("condition").String(cond); }
		//if (hitcond.empty()) { res("hitCondition").String(hitcond); }
		//if (log.empty()) { res("logMessage").String(log); }
	}

	bool bp_breakpoint::run(debug& debug, debugger_impl& dbg)
	{
		if (debug.is_virtual()) {
			return true;
		}
		lua_State* L = debug.L();
		lua::Debug* ar = debug.value();
		if (!cond.empty() && !evaluate_isok(L, ar, cond)) {
			return false;
		}
		hit++;
		if (!hitcond.empty() && !evaluate_isok(L, ar, std::to_string(hit) + " " + hitcond)) {
			return false;
		}
		if (!log.empty()) {
			std::string res = evaluate_log(L, ar, log) + "\n";
			dbg.output("stdout", res.data(), res.size(), L, ar);
			return false;
		}
		return true;
	}

	bp_source::bp_source(debugger_impl& dbg_)
		: dbg(dbg_)
	{
	}

	bp_source::bp_source(bp_source&& s)
		: dbg(s.dbg)
		, defined(std::move(s.defined))
		, waitverfy(std::move(s.waitverfy))
		, verified(std::move(s.verified))
	{
	}

	bp_source::~bp_source()
	{
	}

	void bp_source::update(lua_State* L, lua::Debug* ar)
	{
		if (ar->what[0] == 'L') {
			while (defined.size() <= (size_t)ar->lastlinedefined) {
				defined.emplace_back(eLine::unknown);
			}
			for (int i = ar->linedefined; i <= ar->lastlinedefined; ++i) {
				if (defined[i] != eLine::defined) {
					defined[i] = eLine::unknown;
				}
			}
		}
		lua_pushnil(L);
		while (lua_next(L, -2)) {
			int line = (int)lua_tointeger(L, -2);
			lua_pop(L, 1);
			while (defined.size() <= (size_t)line) {
				defined.emplace_back(eLine::unknown);
			}
			defined[line] = eLine::defined;
		}

		for (size_t i = 0; i < waitverfy.size();) {
			bp_breakpoint& bp = waitverfy[i];
			if (bp.verify(*this, &dbg)) {
				std::swap(waitverfy[i], waitverfy.back());
				verified.insert(std::make_pair(waitverfy.back().line, waitverfy.back()));
				waitverfy.pop_back();
			}
			else {
				++i;
			}
		}
	}

	bp_breakpoint& bp_source::add(size_t line, rapidjson::Value const& bpinfo, size_t& next_id)
	{
		for (auto& bp : waitverfy) {
			if (bp.line == line) {
				bp.update(bpinfo);
				return bp;
			}
		}
		auto it = verified.find(line);
		if (it != verified.end()) {
			it->second.update(bpinfo);
			return it->second;
		}
		bp_breakpoint bp(next_id++, bpinfo);
		if (bp.verify(*this)) {
			return verified.insert(std::make_pair(bp.line, bp)).first->second;
		}
		waitverfy.emplace_back(std::move(bp));
		return waitverfy.back();
	}

	bp_breakpoint* bp_source::get(size_t line)
	{
		auto it = verified.find(line);
		if (it == verified.end()) {
			return 0;
		}
		return &it->second;
	}

	void bp_source::clear(rapidjson::Value const& args)
	{
		std::set<size_t> lines;
		for (auto& m : args["breakpoints"].GetArray()) {
			lines.insert(m["line"].GetUint());
		}

		for (size_t i = 0; i < waitverfy.size();) {
			bp_breakpoint& bp = waitverfy[i];
			if (lines.find(bp.line) == lines.end()) {
				std::swap(waitverfy[i], waitverfy.back());
				waitverfy.pop_back();
			}
			else {
				++i;
			}
		}
		for (auto it = verified.begin(); it != verified.end();) {
			bp_breakpoint& bp = it->second;
			if (lines.find(bp.line) == lines.end()) {
				it = verified.erase(it);
			}
			else {
				++it;
			}
		}
	}

	bool bp_source::has_breakpoint()
	{
		return !verified.empty();
	}

	breakpointMgr::breakpointMgr(debugger_impl& dbg)
		: dbg_(dbg)
		, files_()
		, next_id_(0)
	{ }

	void breakpointMgr::clear()
	{
		files_.clear();
		memorys_.clear();
        functions_.clear();
	}

	bool breakpointMgr::has(bp_source* src, size_t line, debug& debug) const
	{
		bp_breakpoint* bp = src->get(line);
		if (!bp) {
			return false;
		}
		return bp->run(debug, dbg_);
	}

	bp_source& breakpointMgr::get_source(source& source)
	{
		if (source.ref) {
			auto it = memorys_.find(source.ref);
			if (it != memorys_.end()) {
				return it->second;
			}
			return memorys_.insert(std::make_pair(source.ref, bp_source(dbg_))).first->second;
		}
		else {
			auto it = files_.find(source.path);
			if (it != files_.end()) {
				return it->second;
			}
			return files_.insert(std::make_pair(source.path, bp_source(dbg_))).first->second;
		}
	}

	bp_source* breakpointMgr::get_function(debug& debug)
	{
		if (debug.is_virtual()) {
			source* s = dbg_.openVSource();
			bp_source* func = &get_source(*s);
			return func;
		}
		lua_State* L = debug.L();
		lua::Debug* ar = debug.value();
		if (!lua_getinfo(L, "f", (lua_Debug*)ar)) {
			return nullptr;
		}
		intptr_t f = (intptr_t)lua_getprotohash(L, -1);
		lua_pop(L, 1);
		bp_source* func = nullptr;
		if (functions_.get(f, func)) {
			return func;
		}
		if (lua_getinfo(L, "SL", (lua_Debug*)ar)) {
			source* s = dbg_.createSource(ar);
			if (s && s->valid) {
				func = &get_source(*s);
				func->update(L, ar);
			}
		}
		lua_pop(L, 1);
		functions_.put(f, func);
		return func;
	}

	void breakpointMgr::set_breakpoint(source& s, rapidjson::Value const& args, wprotocol& res)
	{
		bp_source& src = get_source(s);
		src.clear(args);
		for (auto _ : res("breakpoints").Array())
		{
			for (auto& m : args["breakpoints"].GetArray())
			{
				unsigned int line = m["line"].GetUint();
				bp_breakpoint& bp = src.add(line, m, next_id_);
				for (auto _ : res.Object())
				{
					bp.output(res);
				}
			}
		}
	}
}
<commit_msg>logbp用console分类吧<commit_after>#include <debugger/breakpoint.h>
#include <debugger/evaluate.h>
#include <debugger/impl.h>
#include <debugger/lua.h>
#include <regex>

namespace vscode
{
	std::string lua_tostr(lua_State* L, int idx);

	static bool evaluate_isok(lua_State* L, lua::Debug *ar, const std::string& script)
	{
		int nresult = 0;
		if (!evaluate(L, ar, ("return " + script).c_str(), nresult))
		{
			lua_pop(L, 1);
			return false;
		}
		if (nresult > 0 && lua_type(L, -nresult) == LUA_TBOOLEAN && lua_toboolean(L, -nresult))
		{
			lua_pop(L, nresult);
			return true;
		}
		lua_pop(L, nresult);
		return false;
	}

	static std::string evaluate_getstr(lua_State* L, lua::Debug *ar, const std::string& script)
	{
		int nresult = 0;
		if (!evaluate(L, ar, ("return tostring(" + script + ")").c_str(), nresult))
		{
			lua_pop(L, 1);
			return "";
		}
		if (nresult <= 0)
		{
			return "";
		}
		std::string res = lua_tostr(L, -nresult);
		lua_pop(L, nresult);
		return res;
	}

	static std::string evaluate_log(lua_State* L, lua::Debug *ar, const std::string& log)
	{
		try {
			std::string res;
			std::regex re(R"(\{[^\}]*\})");
			std::smatch m;
			auto it = log.begin();
			for (; std::regex_search(it, log.end(), m, re); it = m[0].second) {
				res += std::string(it, m[0].first);
				res += evaluate_getstr(L, ar, std::string(m[0].first + 1, m[0].second - 1));
			}
			res += std::string(it, log.end());
			return res;
		}
		catch (std::exception& e) {
			return e.what();
		}
	}

	bp_breakpoint::bp_breakpoint(size_t id, rapidjson::Value const& info)
		: id(id)
		, line(0)
		, verified(false)
		, cond()
		, hitcond()
		, log()
		, hit(0)
	{
		line = info["line"].GetUint();
		update(info);
	}

	void bp_breakpoint::update(rapidjson::Value const& info)
	{
		if (info.HasMember("condition")) {
			cond = info["condition"].Get<std::string>();
		}
		else {
			cond.clear();
		}
		if (info.HasMember("hitCondition")) {
			hitcond = info["hitCondition"].Get<std::string>();
		}
		else {
			hitcond.clear();
		}
		if (info.HasMember("logMessage")) {
			log = info["logMessage"].Get<std::string>();
		}
		else {
			log.clear();
		}
	}

	bool bp_breakpoint::verify(bp_source& src, debugger_impl* dbg)
	{
		if (verified) return true;
		for (size_t i = line; i < src.defined.size(); ++i) {
			switch (src.defined[i]) {
			case eLine::unknown:
				return false;
			case eLine::defined:
				if (src.verified.find(i) != src.verified.end()) {
					return false;
				}
				verified = true;
				line = i;
				if (dbg) {
					dbg->event_breakpoint("changed", this);
				}
				return true;
			case eLine::undef:
				break;
			default:
				return false;
			}
		}
		return false;
	}

	void bp_breakpoint::output(wprotocol& res)
	{
		res("id").Uint64(id);
		res("verified").Bool(verified);
		res("line").Uint64(line);
		//if (cond.empty()) { res("condition").String(cond); }
		//if (hitcond.empty()) { res("hitCondition").String(hitcond); }
		//if (log.empty()) { res("logMessage").String(log); }
	}

	bool bp_breakpoint::run(debug& debug, debugger_impl& dbg)
	{
		if (debug.is_virtual()) {
			return true;
		}
		lua_State* L = debug.L();
		lua::Debug* ar = debug.value();
		if (!cond.empty() && !evaluate_isok(L, ar, cond)) {
			return false;
		}
		hit++;
		if (!hitcond.empty() && !evaluate_isok(L, ar, std::to_string(hit) + " " + hitcond)) {
			return false;
		}
		if (!log.empty()) {
			std::string res = evaluate_log(L, ar, log) + "\n";
			dbg.output("console", res.data(), res.size(), L, ar);
			return false;
		}
		return true;
	}

	bp_source::bp_source(debugger_impl& dbg_)
		: dbg(dbg_)
	{
	}

	bp_source::bp_source(bp_source&& s)
		: dbg(s.dbg)
		, defined(std::move(s.defined))
		, waitverfy(std::move(s.waitverfy))
		, verified(std::move(s.verified))
	{
	}

	bp_source::~bp_source()
	{
	}

	void bp_source::update(lua_State* L, lua::Debug* ar)
	{
		if (ar->what[0] == 'L') {
			while (defined.size() <= (size_t)ar->lastlinedefined) {
				defined.emplace_back(eLine::unknown);
			}
			for (int i = ar->linedefined; i <= ar->lastlinedefined; ++i) {
				if (defined[i] != eLine::defined) {
					defined[i] = eLine::unknown;
				}
			}
		}
		lua_pushnil(L);
		while (lua_next(L, -2)) {
			int line = (int)lua_tointeger(L, -2);
			lua_pop(L, 1);
			while (defined.size() <= (size_t)line) {
				defined.emplace_back(eLine::unknown);
			}
			defined[line] = eLine::defined;
		}

		for (size_t i = 0; i < waitverfy.size();) {
			bp_breakpoint& bp = waitverfy[i];
			if (bp.verify(*this, &dbg)) {
				std::swap(waitverfy[i], waitverfy.back());
				verified.insert(std::make_pair(waitverfy.back().line, waitverfy.back()));
				waitverfy.pop_back();
			}
			else {
				++i;
			}
		}
	}

	bp_breakpoint& bp_source::add(size_t line, rapidjson::Value const& bpinfo, size_t& next_id)
	{
		for (auto& bp : waitverfy) {
			if (bp.line == line) {
				bp.update(bpinfo);
				return bp;
			}
		}
		auto it = verified.find(line);
		if (it != verified.end()) {
			it->second.update(bpinfo);
			return it->second;
		}
		bp_breakpoint bp(next_id++, bpinfo);
		if (bp.verify(*this)) {
			return verified.insert(std::make_pair(bp.line, bp)).first->second;
		}
		waitverfy.emplace_back(std::move(bp));
		return waitverfy.back();
	}

	bp_breakpoint* bp_source::get(size_t line)
	{
		auto it = verified.find(line);
		if (it == verified.end()) {
			return 0;
		}
		return &it->second;
	}

	void bp_source::clear(rapidjson::Value const& args)
	{
		std::set<size_t> lines;
		for (auto& m : args["breakpoints"].GetArray()) {
			lines.insert(m["line"].GetUint());
		}

		for (size_t i = 0; i < waitverfy.size();) {
			bp_breakpoint& bp = waitverfy[i];
			if (lines.find(bp.line) == lines.end()) {
				std::swap(waitverfy[i], waitverfy.back());
				waitverfy.pop_back();
			}
			else {
				++i;
			}
		}
		for (auto it = verified.begin(); it != verified.end();) {
			bp_breakpoint& bp = it->second;
			if (lines.find(bp.line) == lines.end()) {
				it = verified.erase(it);
			}
			else {
				++it;
			}
		}
	}

	bool bp_source::has_breakpoint()
	{
		return !verified.empty();
	}

	breakpointMgr::breakpointMgr(debugger_impl& dbg)
		: dbg_(dbg)
		, files_()
		, next_id_(0)
	{ }

	void breakpointMgr::clear()
	{
		files_.clear();
		memorys_.clear();
        functions_.clear();
	}

	bool breakpointMgr::has(bp_source* src, size_t line, debug& debug) const
	{
		bp_breakpoint* bp = src->get(line);
		if (!bp) {
			return false;
		}
		return bp->run(debug, dbg_);
	}

	bp_source& breakpointMgr::get_source(source& source)
	{
		if (source.ref) {
			auto it = memorys_.find(source.ref);
			if (it != memorys_.end()) {
				return it->second;
			}
			return memorys_.insert(std::make_pair(source.ref, bp_source(dbg_))).first->second;
		}
		else {
			auto it = files_.find(source.path);
			if (it != files_.end()) {
				return it->second;
			}
			return files_.insert(std::make_pair(source.path, bp_source(dbg_))).first->second;
		}
	}

	bp_source* breakpointMgr::get_function(debug& debug)
	{
		if (debug.is_virtual()) {
			source* s = dbg_.openVSource();
			bp_source* func = &get_source(*s);
			return func;
		}
		lua_State* L = debug.L();
		lua::Debug* ar = debug.value();
		if (!lua_getinfo(L, "f", (lua_Debug*)ar)) {
			return nullptr;
		}
		intptr_t f = (intptr_t)lua_getprotohash(L, -1);
		lua_pop(L, 1);
		bp_source* func = nullptr;
		if (functions_.get(f, func)) {
			return func;
		}
		if (lua_getinfo(L, "SL", (lua_Debug*)ar)) {
			source* s = dbg_.createSource(ar);
			if (s && s->valid) {
				func = &get_source(*s);
				func->update(L, ar);
			}
		}
		lua_pop(L, 1);
		functions_.put(f, func);
		return func;
	}

	void breakpointMgr::set_breakpoint(source& s, rapidjson::Value const& args, wprotocol& res)
	{
		bp_source& src = get_source(s);
		src.clear(args);
		for (auto _ : res("breakpoints").Array())
		{
			for (auto& m : args["breakpoints"].GetArray())
			{
				unsigned int line = m["line"].GetUint();
				bp_breakpoint& bp = src.add(line, m, next_id_);
				for (auto _ : res.Object())
				{
					bp.output(res);
				}
			}
		}
	}
}
<|endoftext|>


<commit_before>/*
 * Copyright 2014 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "Resources.h"
#include "SkCommandLineFlags.h"
#include "SkFontConfigParser_android.h"
#include "Test.h"

DECLARE_bool(verboseFontMgr);

int CountFallbacks(SkTDArray<FontFamily*> fontFamilies) {
    int countOfFallbackFonts = 0;
    for (int i = 0; i < fontFamilies.count(); i++) {
        if (fontFamilies[i]->fIsFallbackFont) {
            countOfFallbackFonts++;
        }
    }
    return countOfFallbackFonts;
}

//https://tools.ietf.org/html/rfc5234#appendix-B.1
static bool isALPHA(int c) {
    return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z');
}

//https://tools.ietf.org/html/rfc5234#appendix-B.1
static bool isDIGIT(int c) {
    return ('0' <= c && c <= '9');
}

void ValidateLoadedFonts(SkTDArray<FontFamily*> fontFamilies, const char* firstExpectedFile,
                         skiatest::Reporter* reporter) {
    REPORTER_ASSERT(reporter, fontFamilies[0]->fNames.count() == 5);
    REPORTER_ASSERT(reporter, !strcmp(fontFamilies[0]->fNames[0].c_str(), "sans-serif"));
    REPORTER_ASSERT(reporter,
                    !strcmp(fontFamilies[0]->fFonts[0].fFileName.c_str(), firstExpectedFile));
    REPORTER_ASSERT(reporter, !fontFamilies[0]->fIsFallbackFont);

    // Check that the languages are all sane.
    for (int i = 0; i < fontFamilies.count(); ++i) {
        const SkString& lang = fontFamilies[i]->fLanguage.getTag();
        for (size_t j = 0; j < lang.size(); ++j) {
            int c = lang[j];
            REPORTER_ASSERT(reporter, isALPHA(c) || isDIGIT(c) || '-' == c);
        }
    }

    // All file names in the test configuration files start with a capital letter.
    // This is not a general requirement, but it is true of all the test configuration data.
    // Verifying ensures the filenames have been read sanely and have not been 'sliced'.
    for (int i = 0; i < fontFamilies.count(); ++i) {
        FontFamily& family = *fontFamilies[i];
        for (int j = 0; j < family.fFonts.count(); ++j) {
            FontFileInfo& file = family.fFonts[j];
            REPORTER_ASSERT(reporter, !file.fFileName.isEmpty() &&
                                      file.fFileName[0] >= 'A' &&
                                      file.fFileName[0] <= 'Z');
        }
    }
}

void DumpLoadedFonts(SkTDArray<FontFamily*> fontFamilies) {
    if (!FLAGS_verboseFontMgr) {
        return;
    }

    for (int i = 0; i < fontFamilies.count(); ++i) {
        SkDebugf("Family %d:\n", i);
        switch(fontFamilies[i]->fVariant) {
            case kElegant_FontVariant: SkDebugf("  elegant\n"); break;
            case kCompact_FontVariant: SkDebugf("  compact\n"); break;
            default: break;
        }
        SkDebugf("  basePath %s\n", fontFamilies[i]->fBasePath.c_str());
        if (!fontFamilies[i]->fLanguage.getTag().isEmpty()) {
            SkDebugf("  language %s\n", fontFamilies[i]->fLanguage.getTag().c_str());
        }
        for (int j = 0; j < fontFamilies[i]->fNames.count(); ++j) {
            SkDebugf("  name %s\n", fontFamilies[i]->fNames[j].c_str());
        }
        for (int j = 0; j < fontFamilies[i]->fFonts.count(); ++j) {
            const FontFileInfo& ffi = fontFamilies[i]->fFonts[j];
            SkDebugf("  file (%d) %s#%d\n", ffi.fWeight, ffi.fFileName.c_str(), ffi.fIndex);
        }
    }
    SkDebugf("\n\n");
}

DEF_TEST(FontConfigParserAndroid, reporter) {

    bool resourcesMissing = false;

    SkTDArray<FontFamily*> preV17FontFamilies;
    SkFontConfigParser::GetCustomFontFamilies(preV17FontFamilies,
        SkString("/custom/font/path/"),
        GetResourcePath("android_fonts/pre_v17/system_fonts.xml").c_str(),
        GetResourcePath("android_fonts/pre_v17/fallback_fonts.xml").c_str());

    if (preV17FontFamilies.count() > 0) {
        REPORTER_ASSERT(reporter, preV17FontFamilies.count() == 14);
        REPORTER_ASSERT(reporter, CountFallbacks(preV17FontFamilies) == 10);

        DumpLoadedFonts(preV17FontFamilies);
        ValidateLoadedFonts(preV17FontFamilies, "Roboto-Regular.ttf", reporter);
    } else {
        resourcesMissing = true;
    }

    SkTDArray<FontFamily*> v17FontFamilies;
    SkFontConfigParser::GetCustomFontFamilies(v17FontFamilies,
        SkString("/custom/font/path/"),
        GetResourcePath("android_fonts/v17/system_fonts.xml").c_str(),
        GetResourcePath("android_fonts/v17/fallback_fonts.xml").c_str(),
        GetResourcePath("android_fonts/v17").c_str());

    if (v17FontFamilies.count() > 0) {
        REPORTER_ASSERT(reporter, v17FontFamilies.count() == 56);
        REPORTER_ASSERT(reporter, CountFallbacks(v17FontFamilies) == 46);

        DumpLoadedFonts(v17FontFamilies);
        ValidateLoadedFonts(v17FontFamilies, "Roboto-Regular.ttf", reporter);
    } else {
        resourcesMissing = true;
    }

    SkTDArray<FontFamily*> v22FontFamilies;
    SkFontConfigParser::GetCustomFontFamilies(v22FontFamilies,
        SkString("/custom/font/path/"),
        GetResourcePath("android_fonts/v22/fonts.xml").c_str(),
        NULL);

    if (v22FontFamilies.count() > 0) {
        REPORTER_ASSERT(reporter, v22FontFamilies.count() == 53);
        REPORTER_ASSERT(reporter, CountFallbacks(v22FontFamilies) == 42);

        DumpLoadedFonts(v22FontFamilies);
        ValidateLoadedFonts(v22FontFamilies, "Roboto-Thin.ttf", reporter);
    } else {
        resourcesMissing = true;
    }

    if (resourcesMissing) {
        SkDebugf("---- Resource files missing for FontConfigParser test\n");
    }
}

<commit_msg>Labels when dumping fonts in Android parser test.<commit_after>/*
 * Copyright 2014 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "Resources.h"
#include "SkCommandLineFlags.h"
#include "SkFontConfigParser_android.h"
#include "Test.h"

DECLARE_bool(verboseFontMgr);

int CountFallbacks(SkTDArray<FontFamily*> fontFamilies) {
    int countOfFallbackFonts = 0;
    for (int i = 0; i < fontFamilies.count(); i++) {
        if (fontFamilies[i]->fIsFallbackFont) {
            countOfFallbackFonts++;
        }
    }
    return countOfFallbackFonts;
}

//https://tools.ietf.org/html/rfc5234#appendix-B.1
static bool isALPHA(int c) {
    return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z');
}

//https://tools.ietf.org/html/rfc5234#appendix-B.1
static bool isDIGIT(int c) {
    return ('0' <= c && c <= '9');
}

void ValidateLoadedFonts(SkTDArray<FontFamily*> fontFamilies, const char* firstExpectedFile,
                         skiatest::Reporter* reporter) {
    REPORTER_ASSERT(reporter, fontFamilies[0]->fNames.count() == 5);
    REPORTER_ASSERT(reporter, !strcmp(fontFamilies[0]->fNames[0].c_str(), "sans-serif"));
    REPORTER_ASSERT(reporter,
                    !strcmp(fontFamilies[0]->fFonts[0].fFileName.c_str(), firstExpectedFile));
    REPORTER_ASSERT(reporter, !fontFamilies[0]->fIsFallbackFont);

    // Check that the languages are all sane.
    for (int i = 0; i < fontFamilies.count(); ++i) {
        const SkString& lang = fontFamilies[i]->fLanguage.getTag();
        for (size_t j = 0; j < lang.size(); ++j) {
            int c = lang[j];
            REPORTER_ASSERT(reporter, isALPHA(c) || isDIGIT(c) || '-' == c);
        }
    }

    // All file names in the test configuration files start with a capital letter.
    // This is not a general requirement, but it is true of all the test configuration data.
    // Verifying ensures the filenames have been read sanely and have not been 'sliced'.
    for (int i = 0; i < fontFamilies.count(); ++i) {
        FontFamily& family = *fontFamilies[i];
        for (int j = 0; j < family.fFonts.count(); ++j) {
            FontFileInfo& file = family.fFonts[j];
            REPORTER_ASSERT(reporter, !file.fFileName.isEmpty() &&
                                      file.fFileName[0] >= 'A' &&
                                      file.fFileName[0] <= 'Z');
        }
    }
}

void DumpLoadedFonts(SkTDArray<FontFamily*> fontFamilies, const char* label) {
    if (!FLAGS_verboseFontMgr) {
        return;
    }

    SkDebugf("\n--- Dumping %s\n", label);
    for (int i = 0; i < fontFamilies.count(); ++i) {
        SkDebugf("Family %d:\n", i);
        switch(fontFamilies[i]->fVariant) {
            case kElegant_FontVariant: SkDebugf("  elegant\n"); break;
            case kCompact_FontVariant: SkDebugf("  compact\n"); break;
            default: break;
        }
        SkDebugf("  basePath %s\n", fontFamilies[i]->fBasePath.c_str());
        if (!fontFamilies[i]->fLanguage.getTag().isEmpty()) {
            SkDebugf("  language %s\n", fontFamilies[i]->fLanguage.getTag().c_str());
        }
        for (int j = 0; j < fontFamilies[i]->fNames.count(); ++j) {
            SkDebugf("  name %s\n", fontFamilies[i]->fNames[j].c_str());
        }
        for (int j = 0; j < fontFamilies[i]->fFonts.count(); ++j) {
            const FontFileInfo& ffi = fontFamilies[i]->fFonts[j];
            SkDebugf("  file (%d) %s#%d\n", ffi.fWeight, ffi.fFileName.c_str(), ffi.fIndex);
        }
    }
    SkDebugf("\n\n");
}

DEF_TEST(FontConfigParserAndroid, reporter) {

    bool resourcesMissing = false;

    SkTDArray<FontFamily*> preV17FontFamilies;
    SkFontConfigParser::GetCustomFontFamilies(preV17FontFamilies,
        SkString("/custom/font/path/"),
        GetResourcePath("android_fonts/pre_v17/system_fonts.xml").c_str(),
        GetResourcePath("android_fonts/pre_v17/fallback_fonts.xml").c_str());

    if (preV17FontFamilies.count() > 0) {
        REPORTER_ASSERT(reporter, preV17FontFamilies.count() == 14);
        REPORTER_ASSERT(reporter, CountFallbacks(preV17FontFamilies) == 10);

        DumpLoadedFonts(preV17FontFamilies, "pre version 17");
        ValidateLoadedFonts(preV17FontFamilies, "Roboto-Regular.ttf", reporter);
    } else {
        resourcesMissing = true;
    }

    SkTDArray<FontFamily*> v17FontFamilies;
    SkFontConfigParser::GetCustomFontFamilies(v17FontFamilies,
        SkString("/custom/font/path/"),
        GetResourcePath("android_fonts/v17/system_fonts.xml").c_str(),
        GetResourcePath("android_fonts/v17/fallback_fonts.xml").c_str(),
        GetResourcePath("android_fonts/v17").c_str());

    if (v17FontFamilies.count() > 0) {
        REPORTER_ASSERT(reporter, v17FontFamilies.count() == 56);
        REPORTER_ASSERT(reporter, CountFallbacks(v17FontFamilies) == 46);

        DumpLoadedFonts(v17FontFamilies, "version 17");
        ValidateLoadedFonts(v17FontFamilies, "Roboto-Regular.ttf", reporter);
    } else {
        resourcesMissing = true;
    }

    SkTDArray<FontFamily*> v22FontFamilies;
    SkFontConfigParser::GetCustomFontFamilies(v22FontFamilies,
        SkString("/custom/font/path/"),
        GetResourcePath("android_fonts/v22/fonts.xml").c_str(),
        NULL);

    if (v22FontFamilies.count() > 0) {
        REPORTER_ASSERT(reporter, v22FontFamilies.count() == 53);
        REPORTER_ASSERT(reporter, CountFallbacks(v22FontFamilies) == 42);

        DumpLoadedFonts(v22FontFamilies, "version 22");
        ValidateLoadedFonts(v22FontFamilies, "Roboto-Thin.ttf", reporter);
    } else {
        resourcesMissing = true;
    }

    if (resourcesMissing) {
        SkDebugf("---- Resource files missing for FontConfigParser test\n");
    }
}

<|endoftext|>


<commit_before>/*
 * Copyright 2016 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include <string>
#include <tuple>
#include <vector>
#include "Resources.h"
#include "SkCpu.h"
#include "SkImage.h"
#include "SkImage_Base.h"
#include "SkOpts.h"
#include "SkNx.h"
#include "Test.h"
#include "../include/core/SkImageInfo.h"

typedef void (*Blender)(uint32_t* dst, const uint32_t* const srcStart, int ndst, const int nsrc);

namespace sk_default {
extern void brute_force_srcover_srgb_srgb(
    uint32_t* dst, const uint32_t* const srcStart, int ndst, const int nsrc);
}

namespace sk_default {
extern void trivial_srcover_srgb_srgb(
    uint32_t* dst, const uint32_t* const srcStart, int ndst, const int nsrc);

extern void best_non_simd_srcover_srgb_srgb(
    uint32_t* dst, const uint32_t* const srcStart, int ndst, const int nsrc);

extern void srcover_srgb_srgb(
    uint32_t* dst, const uint32_t* const srcStart, int ndst, const int nsrc);
}

#if defined(SK_CPU_X86) && !defined(SK_BUILD_FOR_IOS)
namespace sk_sse41 {
extern void srcover_srgb_srgb(
    uint32_t* dst, const uint32_t* const srcStart, int ndst, const int nsrc);
}
#endif

static SkString missmatch_message(std::string resourceName, std::string name, int x, int y,
                                  uint32_t src, uint32_t good, uint32_t bad) {
    return SkStringPrintf(
        "%s - %s missmatch at %d, %d src: %08x good: %08x bad: %08x",
        resourceName.c_str(), name.c_str(), x, y, src, good, bad);
}

using Spec = std::tuple<Blender, std::string>;

static void test_blender(
    Spec spec,
    std::string resourceName,
    skiatest::Reporter* reporter)
{
    Blender blender;
    std::string name;
    std::tie(blender, name) = spec;

    std::string fileName = resourceName + ".png";
    sk_sp<SkImage> image = GetResourceAsImage(fileName.c_str());
    SkASSERT(image != nullptr);
    if (image == nullptr) {
        SkFAIL("image is NULL");
    }
    SkBitmap bm;
    if (!as_IB(image)->getROPixels(&bm)) {
        SkFAIL("Could not read resource");
    }

    SkPixmap pixmap;
    bm.peekPixels(&pixmap);
    SkASSERTF(pixmap.colorType() == kN32_SkColorType, "colorType: %d", pixmap.colorType());
    SkASSERT(pixmap.alphaType() != kUnpremul_SkAlphaType);
    const uint32_t* src = pixmap.addr32();
    const int width = pixmap.rowBytesAsPixels();
    SkASSERT(width > 0);
    SkASSERT(width < 4000);
    SkAutoTArray<uint32_t> correctDst(width);
    SkAutoTArray<uint32_t> testDst(width);

    for (int y = 0; y < pixmap.height(); y++) {
        memset(correctDst.get(), 0, width * sizeof(uint32_t));
        memset(testDst.get(), 0, width * sizeof(uint32_t));
        sk_default::brute_force_srcover_srgb_srgb(correctDst.get(), src, width, width);
        blender(testDst.get(), src, width, width);
        for (int x = 0; x < width; x++) {
            REPORTER_ASSERT_MESSAGE(
                reporter, correctDst[x] == testDst[x],
                missmatch_message(resourceName, name, x, y, src[x], correctDst[x], testDst[x]));
            if (correctDst[x] != testDst[x]) break;
        }
        src += width;
    }
}

DEF_TEST(SkBlend_optsCheck, reporter) {
    std::vector<Spec> specs = {
        Spec{sk_default::trivial_srcover_srgb_srgb,       "trivial"},
        Spec{sk_default::best_non_simd_srcover_srgb_srgb, "best_non_simd"},
        Spec{sk_default::srcover_srgb_srgb,               "default"},
    };
    #if defined(SK_CPU_X86) && !defined(SK_BUILD_FOR_IOS)
    if (SkCpu::Supports(SkCpu::SSE41)) {
        specs.push_back(Spec{sk_sse41::srcover_srgb_srgb, "sse41", });
    }
    #endif

    std::vector<std::string> testResources = {
        "yellow_rose", "baby_tux", "plane", "mandrill_512", "iconstrip"
    };

    for (auto& spec : specs) {
        for (auto& resourceName : testResources) {
            test_blender(spec, resourceName, reporter);
        }
    }
}

DEF_TEST(SkBlend_optsSqrtCheck, reporter) {
    for (int c = 0; c < 256; c++) {
        Sk4f i{(float)c};
        Sk4f ii = i * i;
        Sk4f s = ii.sqrt() + 0.5f;
        Sk4f sf = s.floor();
        REPORTER_ASSERT_MESSAGE(
            reporter, i[0] == sf[0], SkStringPrintf("i: %f, s: %f", i[0], sf[0]));
    }
}
<commit_msg>Make SkBlend_optsTests fail rather than crash when resources are missing<commit_after>/*
 * Copyright 2016 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include <string>
#include <tuple>
#include <vector>
#include "Resources.h"
#include "SkCpu.h"
#include "SkImage.h"
#include "SkImage_Base.h"
#include "SkOpts.h"
#include "SkNx.h"
#include "Test.h"
#include "../include/core/SkImageInfo.h"

typedef void (*Blender)(uint32_t* dst, const uint32_t* const srcStart, int ndst, const int nsrc);

namespace sk_default {
extern void brute_force_srcover_srgb_srgb(
    uint32_t* dst, const uint32_t* const srcStart, int ndst, const int nsrc);
}

namespace sk_default {
extern void trivial_srcover_srgb_srgb(
    uint32_t* dst, const uint32_t* const srcStart, int ndst, const int nsrc);

extern void best_non_simd_srcover_srgb_srgb(
    uint32_t* dst, const uint32_t* const srcStart, int ndst, const int nsrc);

extern void srcover_srgb_srgb(
    uint32_t* dst, const uint32_t* const srcStart, int ndst, const int nsrc);
}

#if defined(SK_CPU_X86) && !defined(SK_BUILD_FOR_IOS)
namespace sk_sse41 {
extern void srcover_srgb_srgb(
    uint32_t* dst, const uint32_t* const srcStart, int ndst, const int nsrc);
}
#endif

static SkString missmatch_message(std::string resourceName, std::string name, int x, int y,
                                  uint32_t src, uint32_t good, uint32_t bad) {
    return SkStringPrintf(
        "%s - %s missmatch at %d, %d src: %08x good: %08x bad: %08x",
        resourceName.c_str(), name.c_str(), x, y, src, good, bad);
}

using Spec = std::tuple<Blender, std::string>;

static void test_blender(
    Spec spec,
    std::string resourceName,
    skiatest::Reporter* reporter)
{
    Blender blender;
    std::string name;
    std::tie(blender, name) = spec;

    std::string fileName = resourceName + ".png";
    sk_sp<SkImage> image = GetResourceAsImage(fileName.c_str());
    if (image == nullptr) {
        ERRORF(reporter, "image is NULL");
        return;
    }
    SkBitmap bm;
    if (!as_IB(image)->getROPixels(&bm)) {
        ERRORF(reporter, "Could not read resource");
        return;
    }

    SkPixmap pixmap;
    bm.peekPixels(&pixmap);
    SkASSERTF(pixmap.colorType() == kN32_SkColorType, "colorType: %d", pixmap.colorType());
    SkASSERT(pixmap.alphaType() != kUnpremul_SkAlphaType);
    const uint32_t* src = pixmap.addr32();
    const int width = pixmap.rowBytesAsPixels();
    SkASSERT(width > 0);
    SkASSERT(width < 4000);
    SkAutoTArray<uint32_t> correctDst(width);
    SkAutoTArray<uint32_t> testDst(width);

    for (int y = 0; y < pixmap.height(); y++) {
        memset(correctDst.get(), 0, width * sizeof(uint32_t));
        memset(testDst.get(), 0, width * sizeof(uint32_t));
        sk_default::brute_force_srcover_srgb_srgb(correctDst.get(), src, width, width);
        blender(testDst.get(), src, width, width);
        for (int x = 0; x < width; x++) {
            REPORTER_ASSERT_MESSAGE(
                reporter, correctDst[x] == testDst[x],
                missmatch_message(resourceName, name, x, y, src[x], correctDst[x], testDst[x]));
            if (correctDst[x] != testDst[x]) break;
        }
        src += width;
    }
}

DEF_TEST(SkBlend_optsCheck, reporter) {
    std::vector<Spec> specs = {
        Spec{sk_default::trivial_srcover_srgb_srgb,       "trivial"},
        Spec{sk_default::best_non_simd_srcover_srgb_srgb, "best_non_simd"},
        Spec{sk_default::srcover_srgb_srgb,               "default"},
    };
    #if defined(SK_CPU_X86) && !defined(SK_BUILD_FOR_IOS)
    if (SkCpu::Supports(SkCpu::SSE41)) {
        specs.push_back(Spec{sk_sse41::srcover_srgb_srgb, "sse41", });
    }
    #endif

    std::vector<std::string> testResources = {
        "yellow_rose", "baby_tux", "plane", "mandrill_512", "iconstrip"
    };

    for (auto& spec : specs) {
        for (auto& resourceName : testResources) {
            test_blender(spec, resourceName, reporter);
        }
    }
}

DEF_TEST(SkBlend_optsSqrtCheck, reporter) {
    for (int c = 0; c < 256; c++) {
        Sk4f i{(float)c};
        Sk4f ii = i * i;
        Sk4f s = ii.sqrt() + 0.5f;
        Sk4f sf = s.floor();
        REPORTER_ASSERT_MESSAGE(
            reporter, i[0] == sf[0], SkStringPrintf("i: %f, s: %f", i[0], sf[0]));
    }
}
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/usr/hwpf/hwp/occ/occ_procedures/p8_pm_pba_firinit.C $     */
/*                                                                        */
/* IBM CONFIDENTIAL                                                       */
/*                                                                        */
/* COPYRIGHT International Business Machines Corp. 2013                   */
/*                                                                        */
/* p1                                                                     */
/*                                                                        */
/* Object Code Only (OCO) source materials                                */
/* Licensed Internal Code Source Materials                                */
/* IBM HostBoot Licensed Internal Code                                    */
/*                                                                        */
/* The source code for this program is not published or otherwise         */
/* divested of its trade secrets, irrespective of what has been           */
/* deposited with the U.S. Copyright Office.                              */
/*                                                                        */
/* Origin: 30                                                             */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
// $Id: p8_pm_pba_firinit.C,v 1.16 2013/08/26 12:44:34 stillgs Exp $
// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ipl/fapi/p8_pm_pba_firinit.C,v $
//------------------------------------------------------------------------------
// *! (C) Copyright International Business Machines Corp. 2011
// *! All Rights Reserved -- Property of IBM
// *! *** IBM Confidential ***
//------------------------------------------------------------------------------
// *! OWNER NAME: Pradeep CN         Email: pradeepcn@in.ibm.com
// *!
// *! General Description:
// *!
// *!   The purpose of this procedure is to ......
// *!
// *!   High-level procedure flow:
// *!     o Set the particluar bits of databuffers action0 , action 1 and mask for the correspoding actions via MACROS
// *!     o Write the action1 , actionn0 and mask registers of FIRs
// *!     o
// *!     o
// *!     o
// *!     o
// *!     o Check if all went well
// *!     o   If so celebrate
// *!     o   Else write logs, set bad return code
// *!
// *!
// *! Procedure Prereq:
// *!   o System clocks are running
// *!
//------------------------------------------------------------------------------

// ----------------------------------------------------------------------
// Includes
// ----------------------------------------------------------------------
#include <fapi.H>
#include "p8_scom_addresses.H"
#include "p8_pm_pba_firinit.H"

extern "C" {

using namespace fapi;

// ----------------------------------------------------------------------
// Constant definitions
// ----------------------------------------------------------------------

    // \todo move these to p8_scom_addresses after testing
  //   CONST_UINT64_T( PBA_FIR_ACTION1_0x02010847        , ULL(0x02010847)) ;
  //   CONST_UINT64_T( PBA_FIR_ACTION0_0x02010846        , ULL(0x02010846)) ;
   CONST_UINT64_T( PBA_FIR_MASK_WR_0x02010843        , ULL(0x02010843)) ;
   CONST_UINT64_T( PBA_FIR_MASK_WR_AND_0x02010844        , ULL(0x02010844)) ;
   CONST_UINT64_T( PBA_FIR_MASK_WR_OR_0x02010845        , ULL(0x02010845)) ;

// ----------------------------------------------------------------------
// Global variables
// ----------------------------------------------------------------------

fapi::ReturnCode
p8_pm_pba_firinit(const fapi::Target&  i_target , uint32_t mode )
{

//------------------------------------------------------------------------------
// Function prototypes
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// function: FAPI p8_pm_pba_firinit  HWP entry point
//           operates on chips passed in i_target argument to perform
//           desired settings of FIRS of PBA macro
// parameters: i_target        => chip target

// returns: FAPI_RC_SUCCESS if all specified operations complete successfully,
//          else return code for failing operation
//------------------------------------------------------------------------------

    fapi::ReturnCode    rc;
    ecmdDataBufferBase  fir(64);
    ecmdDataBufferBase  action_0(64);
    ecmdDataBufferBase  action_1(64);
    ecmdDataBufferBase  mask(64);
    uint32_t            e_rc = 0;

    FAPI_DBG("Executing p8_pm_pba_firinit  ....");
    do
    {
        if (mode == PM_RESET)
        {

            e_rc  = mask.flushTo0();
            e_rc |= mask.setBit(0, PBA_FIR_REGISTER_LENGTH);
            if (e_rc)
            {
                rc.setEcmdError(e_rc);
                break;
            }

            //--******************************************************************************
            //-- PBA_FIR_MASK (W0_OR_45) (WR_43) (WO_AND_44)
            //--******************************************************************************
            rc = fapiPutScom(i_target, PBA_FIR_MASK_WR_0x02010843, mask );
            if (rc)
            {
	            FAPI_ERR("fapiPutScom(PBA_FIR_MASK_WR_0x02010843) failed.");
                break;
            }
        }
        else
        {
            e_rc |= fir.flushTo0();
            e_rc |= action_0.flushTo0();
            e_rc |= action_1.flushTo0();
            e_rc |= mask.flushTo0()    ;
            if (e_rc)
            {
                rc.setEcmdError(e_rc);
                break;
            }

            SET_RECOV_ATTN  (PBAFIR_OCI_APAR_ERR      ) ; // 0   PBAFIR_OCI_APAR_ERR
            SET_RECOV_ATTN  (PBAFIR_PB_RDADRERR_FW    ) ; // 1   PBAFIR_PB_RDADRERR_FW
            SET_RECOV_ATTN  (PBAFIR_PB_RDDATATO_FW    ) ; // 2   PBAFIR_PB_RDDATATO_FW
            SET_RECOV_ATTN  (PBAFIR_PB_SUE_FW         ) ; // 3   PBAFIR_PB_SUE_FW
            SET_RECOV_ATTN  (PBAFIR_PB_UE_FW          ) ; // 4   PBAFIR_PB_UE_FW
            SET_RECOV_ATTN  (PBAFIR_PB_CE_FW          ) ; // 5   PBAFIR_PB_CE_FW
            SET_RECOV_ATTN  (PBAFIR_OCI_SLAVE_INIT    ) ; // 6   PBAFIR_OCI_SLAVE_INIT
            SET_RECOV_ATTN  (PBAFIR_OCI_WRPAR_ERR     ) ; // 7   PBAFIR_OCI_WRPAR_ERR
            SET_RECOV_ATTN  (PBAFIR_OCI_REREQTO       ) ; // 8   PBAFIR_OCI_REREQTO
            SET_RECOV_ATTN  (PBAFIR_PB_UNEXPCRESP     ) ; // 9   PBAFIR_PB_UNEXPCRESP
            SET_RECOV_ATTN  (PBAFIR_PB_UNEXPDATA      ) ; // 10  PBAFIR_PB_UNEXPDATA
            SET_RECOV_ATTN  (PBAFIR_PB_PARITY_ERR     ) ; // 11  PBAFIR_PB_PARITY_ERR
            SET_RECOV_ATTN  (PBAFIR_PB_WRADRERR_FW    ) ; // 12  PBAFIR_PB_WRADRERR_FW
            SET_RECOV_ATTN  (PBAFIR_PB_BADCRESP       ) ; // 13  PBAFIR_PB_BADCRESP
            SET_RECOV_ATTN  (PBAFIR_PB_ACKDEAD_FW_RD  ) ; // 14  PBAFIR_PB_ACKDEAD_FW_RD
            SET_RECOV_ATTN  (PBAFIR_PB_CRESPTO        ) ; // 15  PBAFIR_PB_CRESPTO
            SET_FIR_MASKED  (PBAFIR_BCUE_SETUP_ERR    ) ; // 16  PBAFIR_BCUE_SETUP_ERR
            SET_FIR_MASKED  (PBAFIR_BCUE_PB_ACK_DEAD  ) ; // 17  PBAFIR_BCUE_PB_ACK_DEAD
            SET_FIR_MASKED  (PBAFIR_BCUE_PB_ADRERR    ) ; // 18  PBAFIR_BCUE_PB_ADRERR
            SET_FIR_MASKED  (PBAFIR_BCUE_OCI_DATERR   ) ; // 19  PBAFIR_BCUE_OCI_DATERR
            SET_FIR_MASKED  (PBAFIR_BCDE_SETUP_ERR    ) ; // 20  PBAFIR_BCDE_SETUP_ERR
            SET_FIR_MASKED  (PBAFIR_BCDE_PB_ACK_DEAD  ) ; // 21  PBAFIR_BCDE_PB_ACK_DEAD
            SET_FIR_MASKED  (PBAFIR_BCDE_PB_ADRERR    ) ; // 22  PBAFIR_BCDE_PB_ADRERR
            SET_FIR_MASKED  (PBAFIR_BCDE_RDDATATO_ERR ) ; // 23  PBAFIR_BCDE_RDDATATO_ERR
            SET_FIR_MASKED  (PBAFIR_BCDE_SUE_ERR      ) ; // 24  PBAFIR_BCDE_SUE_ERR
            SET_FIR_MASKED  (PBAFIR_BCDE_UE_ERR       ) ; // 25  PBAFIR_BCDE_UE_ERR
            SET_FIR_MASKED  (PBAFIR_BCDE_CE           ) ; // 26  PBAFIR_BCDE_CE
            SET_FIR_MASKED  (PBAFIR_BCDE_OCI_DATERR   ) ; // 27  PBAFIR_BCDE_OCI_DATERR
            SET_RECOV_ATTN  (PBAFIR_INTERNAL_ERR      ) ; // 28  PBAFIR_INTERNAL_ERR
            SET_RECOV_ATTN  (PBAFIR_ILLEGAL_CACHE_OP  ) ; // 29  PBAFIR_ILLEGAL_CACHE_OP
            SET_RECOV_ATTN  (PBAFIR_OCI_BAD_REG_ADDR  ) ; // 30  PBAFIR_OCI_BAD_REG_ADDR
            SET_FIR_MASKED  (PBAFIR_AXPUSH_WRERR      ) ; // 31  PBAFIR_AXPUSH_WRERR
            SET_FIR_MASKED  (PBAFIR_AXRCV_DLO_ERR     ) ; // 32  PBAFIR_AXRCV_DLO_ERR
            SET_FIR_MASKED  (PBAFIR_AXRCV_DLO_TO      ) ; // 33  PBAFIR_AXRCV_DLO_TO
            SET_FIR_MASKED  (PBAFIR_AXRCV_RSVDATA_TO  ) ; // 34  PBAFIR_AXRCV_RSVDATA_TO
            SET_FIR_MASKED  (PBAFIR_AXFLOW_ERR        ) ; // 35  PBAFIR_AXFLOW_ERR
            SET_FIR_MASKED  (PBAFIR_AXSND_DHI_RTYTO   ) ; // 36  PBAFIR_AXSND_DHI_RTYTO
            SET_FIR_MASKED  (PBAFIR_AXSND_DLO_RTYTO   ) ; // 37  PBAFIR_AXSND_DLO_RTYTO
            SET_FIR_MASKED  (PBAFIR_AXSND_RSVTO       ) ; // 38  PBAFIR_AXSND_RSVTO
            SET_FIR_MASKED  (PBAFIR_AXSND_RSVERR      ) ; // 39  PBAFIR_AXSND_RSVERR
            SET_RECOV_ATTN  (PBAFIR_PB_ACKDEAD_FW_WR  ) ; // 40  PBAFIR_PB_ACKDEAD_FW_WR
            SET_FIR_MASKED  (PBAFIR_RESERVED_41       ) ; // 41  PBAFIR_RESERVED_41
            SET_FIR_MASKED  (PBAFIR_RESERVED_42       ) ; // 42  PBAFIR_RESERVED_42
            SET_FIR_MASKED  (PBAFIR_RESERVED_43       ) ; // 43  PBAFIR_RESERVED_43
            SET_RECOV_ATTN  (PBAFIR_FIR_PARITY_ERR2   ) ; // 44  PBAFIR_FIR_PARITY_ERR2
            SET_RECOV_ATTN  (PBAFIR_FIR_PARITY_ERR    ) ; // 45  PBAFIR_FIR_PARITY_ERR

            if (e_rc)
            {
                rc.setEcmdError(e_rc);
                break;
            }

            // ---------------
            // PBA_FIR - cleared
            // ---------------
            rc = fapiPutScom(i_target, PBA_FIR_0x02010840, fir);
            if (!rc.ok())
            {
                FAPI_ERR("fapiPutScom(PBA_FIR_0x02010840) failed.");
                 break;
            }

            FAPI_DBG(" action_0  => 0x%16llx ",  action_0.getDoubleWord(0));
            FAPI_DBG(" action_1  => 0x%16llx ",  action_1.getDoubleWord(0));
            FAPI_DBG(" mask      => 0x%16llx ",  mask.getDoubleWord(0));

            //#--******************************************************************************
            //#-- PBA_FIR_ACTION0
            //#--******************************************************************************

            rc = fapiPutScom(i_target, PBA_FIR_ACTION0_0x02010846, action_0 );
            if (rc)
            {
	            FAPI_ERR("fapiPutScom(PBA_FIR_ACTION0_0x02010846) failed.");
                break;
            }

            //#--******************************************************************************
            //#-- PBA_FIR_ACTION1
            //#--******************************************************************************

            rc = fapiPutScom(i_target, PBA_FIR_ACTION1_0x02010847, action_1 );
            if (rc)
            {
	            FAPI_ERR("fapiPutScom(PBA_FIR_ACTION1_0x02010847) failed.");
                break;
            }

            //--******************************************************************************
            //-- PBA_FIR_MASK (W0_OR_45) (WR_43) (WO_AND_44)
            //--******************************************************************************
            rc = fapiPutScom(i_target, PBA_FIR_MASK_WR_0x02010843, mask );
            if (rc)
            {
	            FAPI_ERR("fapiPutScom(PBA_FIR_MASK_WR_0x02010843) failed.");
                 break;
            }
        } // Mode
    } while(0);
    return rc;

} // Procedure

} //end extern C
<commit_msg>Procedure update - p8_pm_pba_firinit.C<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/usr/hwpf/hwp/occ/occ_procedures/p8_pm_pba_firinit.C $     */
/*                                                                        */
/* IBM CONFIDENTIAL                                                       */
/*                                                                        */
/* COPYRIGHT International Business Machines Corp. 2013,2014              */
/*                                                                        */
/* p1                                                                     */
/*                                                                        */
/* Object Code Only (OCO) source materials                                */
/* Licensed Internal Code Source Materials                                */
/* IBM HostBoot Licensed Internal Code                                    */
/*                                                                        */
/* The source code for this program is not published or otherwise         */
/* divested of its trade secrets, irrespective of what has been           */
/* deposited with the U.S. Copyright Office.                              */
/*                                                                        */
/* Origin: 30                                                             */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
// $Id: p8_pm_pba_firinit.C,v 1.17 2014/01/06 18:29:14 stillgs Exp $
// $Source: /archive/shadow/ekb/.cvsroot/eclipz/chips/p8/working/procedures/ipl/fapi/p8_pm_pba_firinit.C,v $
//------------------------------------------------------------------------------
// *! (C) Copyright International Business Machines Corp. 2011
// *! All Rights Reserved -- Property of IBM
// *! *** IBM Confidential ***
//------------------------------------------------------------------------------
// *! OWNER NAME: Pradeep CN         Email: pradeepcn@in.ibm.com
// *! OWNER NAME: Greg Still         Email: stillgs@us.ibm.com
/// \file p8_pm_pba_firinit.C
/// \brief Configure the PBA FIR
///
/// \verbatim
///
///   if RESET
///       masks all bits of the FIR k
///
///   else
///       using macros defined in p8_pm.H to establish the respective
///       mask/action bits in the relevant ecmdbuffer for one of the following
///       settings:
///           a) Masked
///           b) Recoverable Attention
///           c) Checkstop
///
///  Procedure Prereq:
///    o System clocks are running
///
/// \endverbatim
//------------------------------------------------------------------------------

// ----------------------------------------------------------------------
// Includes
// ----------------------------------------------------------------------
#include <fapi.H>
#include "p8_scom_addresses.H"
#include "p8_pm_pba_firinit.H"

extern "C" {

using namespace fapi;

// ----------------------------------------------------------------------
// Constant definitions
// ----------------------------------------------------------------------

// ----------------------------------------------------------------------
// Global variables
// ----------------------------------------------------------------------

fapi::ReturnCode
p8_pm_pba_firinit(const fapi::Target&  i_target , uint32_t mode )
{

//------------------------------------------------------------------------------
// Function prototypes
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// function: FAPI p8_pm_pba_firinit  HWP entry point
//           operates on chips passed in i_target argument to perform
//           desired settings of FIRS of PBA macro
// parameters: i_target        => chip target

// returns: FAPI_RC_SUCCESS if all specified operations complete successfully,
//          else return code for failing operation
//------------------------------------------------------------------------------

    fapi::ReturnCode    rc;
    ecmdDataBufferBase  fir(64);
    ecmdDataBufferBase  action_0(64);
    ecmdDataBufferBase  action_1(64);
    ecmdDataBufferBase  mask(64);
    uint32_t            e_rc = 0;

    FAPI_DBG("Executing p8_pm_pba_firinit  ....");
    do
    {
        if (mode == PM_RESET)
        {

            e_rc  = mask.flushTo0();
            e_rc |= mask.setBit(0, PBA_FIR_REGISTER_LENGTH);
            if (e_rc)
            {
                rc.setEcmdError(e_rc);
                break;
            }

            //--******************************************************************************
            //-- PBA_FIR_MASK (W0_OR_45) (WR_43) (WO_AND_44)
            //--******************************************************************************
            rc = fapiPutScom(i_target, PBA_FIR_MASK_0x02010843, mask );
            if (rc)
            {
                FAPI_ERR("fapiPutScom(PBA_FIR_MASK_0x02010843) failed.");
                break;
            }
        }
        else
        {
            e_rc |= fir.flushTo0();
            e_rc |= action_0.flushTo0();
            e_rc |= action_1.flushTo0();
            e_rc |= mask.flushTo0()    ;
            if (e_rc)
            {
                rc.setEcmdError(e_rc);
                break;
            }

            SET_RECOV_ATTN  (PBAFIR_OCI_APAR_ERR      ) ; // 0   PBAFIR_OCI_APAR_ERR
            SET_RECOV_ATTN  (PBAFIR_PB_RDADRERR_FW    ) ; // 1   PBAFIR_PB_RDADRERR_FW
            SET_RECOV_ATTN  (PBAFIR_PB_RDDATATO_FW    ) ; // 2   PBAFIR_PB_RDDATATO_FW
            SET_RECOV_ATTN  (PBAFIR_PB_SUE_FW         ) ; // 3   PBAFIR_PB_SUE_FW
            SET_RECOV_ATTN  (PBAFIR_PB_UE_FW          ) ; // 4   PBAFIR_PB_UE_FW
            SET_RECOV_ATTN  (PBAFIR_PB_CE_FW          ) ; // 5   PBAFIR_PB_CE_FW
            SET_RECOV_ATTN  (PBAFIR_OCI_SLAVE_INIT    ) ; // 6   PBAFIR_OCI_SLAVE_INIT
            SET_RECOV_ATTN  (PBAFIR_OCI_WRPAR_ERR     ) ; // 7   PBAFIR_OCI_WRPAR_ERR
            SET_RECOV_ATTN  (PBAFIR_OCI_REREQTO       ) ; // 8   PBAFIR_OCI_REREQTO
            SET_FIR_MASKED  (PBAFIR_PB_UNEXPCRESP     ) ; // 9   PBAFIR_PB_UNEXPCRESP
            SET_RECOV_ATTN  (PBAFIR_PB_UNEXPDATA      ) ; // 10  PBAFIR_PB_UNEXPDATA
            SET_RECOV_ATTN  (PBAFIR_PB_PARITY_ERR     ) ; // 11  PBAFIR_PB_PARITY_ERR
            SET_RECOV_ATTN  (PBAFIR_PB_WRADRERR_FW    ) ; // 12  PBAFIR_PB_WRADRERR_FW
            SET_RECOV_ATTN  (PBAFIR_PB_BADCRESP       ) ; // 13  PBAFIR_PB_BADCRESP
            SET_RECOV_ATTN  (PBAFIR_PB_ACKDEAD_FW_RD  ) ; // 14  PBAFIR_PB_ACKDEAD_FW_RD
            SET_RECOV_ATTN  (PBAFIR_PB_CRESPTO        ) ; // 15  PBAFIR_PB_CRESPTO
            SET_FIR_MASKED  (PBAFIR_BCUE_SETUP_ERR    ) ; // 16  PBAFIR_BCUE_SETUP_ERR
            SET_FIR_MASKED  (PBAFIR_BCUE_PB_ACK_DEAD  ) ; // 17  PBAFIR_BCUE_PB_ACK_DEAD
            SET_FIR_MASKED  (PBAFIR_BCUE_PB_ADRERR    ) ; // 18  PBAFIR_BCUE_PB_ADRERR
            SET_FIR_MASKED  (PBAFIR_BCUE_OCI_DATERR   ) ; // 19  PBAFIR_BCUE_OCI_DATERR
            SET_FIR_MASKED  (PBAFIR_BCDE_SETUP_ERR    ) ; // 20  PBAFIR_BCDE_SETUP_ERR
            SET_FIR_MASKED  (PBAFIR_BCDE_PB_ACK_DEAD  ) ; // 21  PBAFIR_BCDE_PB_ACK_DEAD
            SET_FIR_MASKED  (PBAFIR_BCDE_PB_ADRERR    ) ; // 22  PBAFIR_BCDE_PB_ADRERR
            SET_FIR_MASKED  (PBAFIR_BCDE_RDDATATO_ERR ) ; // 23  PBAFIR_BCDE_RDDATATO_ERR
            SET_FIR_MASKED  (PBAFIR_BCDE_SUE_ERR      ) ; // 24  PBAFIR_BCDE_SUE_ERR
            SET_FIR_MASKED  (PBAFIR_BCDE_UE_ERR       ) ; // 25  PBAFIR_BCDE_UE_ERR
            SET_FIR_MASKED  (PBAFIR_BCDE_CE           ) ; // 26  PBAFIR_BCDE_CE
            SET_FIR_MASKED  (PBAFIR_BCDE_OCI_DATERR   ) ; // 27  PBAFIR_BCDE_OCI_DATERR
            SET_RECOV_ATTN  (PBAFIR_INTERNAL_ERR      ) ; // 28  PBAFIR_INTERNAL_ERR
            SET_RECOV_ATTN  (PBAFIR_ILLEGAL_CACHE_OP  ) ; // 29  PBAFIR_ILLEGAL_CACHE_OP
            SET_RECOV_ATTN  (PBAFIR_OCI_BAD_REG_ADDR  ) ; // 30  PBAFIR_OCI_BAD_REG_ADDR
            SET_FIR_MASKED  (PBAFIR_AXPUSH_WRERR      ) ; // 31  PBAFIR_AXPUSH_WRERR
            SET_FIR_MASKED  (PBAFIR_AXRCV_DLO_ERR     ) ; // 32  PBAFIR_AXRCV_DLO_ERR
            SET_FIR_MASKED  (PBAFIR_AXRCV_DLO_TO      ) ; // 33  PBAFIR_AXRCV_DLO_TO
            SET_FIR_MASKED  (PBAFIR_AXRCV_RSVDATA_TO  ) ; // 34  PBAFIR_AXRCV_RSVDATA_TO
            SET_FIR_MASKED  (PBAFIR_AXFLOW_ERR        ) ; // 35  PBAFIR_AXFLOW_ERR
            SET_FIR_MASKED  (PBAFIR_AXSND_DHI_RTYTO   ) ; // 36  PBAFIR_AXSND_DHI_RTYTO
            SET_FIR_MASKED  (PBAFIR_AXSND_DLO_RTYTO   ) ; // 37  PBAFIR_AXSND_DLO_RTYTO
            SET_FIR_MASKED  (PBAFIR_AXSND_RSVTO       ) ; // 38  PBAFIR_AXSND_RSVTO
            SET_FIR_MASKED  (PBAFIR_AXSND_RSVERR      ) ; // 39  PBAFIR_AXSND_RSVERR
            SET_RECOV_ATTN  (PBAFIR_PB_ACKDEAD_FW_WR  ) ; // 40  PBAFIR_PB_ACKDEAD_FW_WR
            SET_FIR_MASKED  (PBAFIR_RESERVED_41       ) ; // 41  PBAFIR_RESERVED_41
            SET_FIR_MASKED  (PBAFIR_RESERVED_42       ) ; // 42  PBAFIR_RESERVED_42
            SET_FIR_MASKED  (PBAFIR_RESERVED_43       ) ; // 43  PBAFIR_RESERVED_43
            SET_RECOV_ATTN  (PBAFIR_FIR_PARITY_ERR2   ) ; // 44  PBAFIR_FIR_PARITY_ERR2
            SET_RECOV_ATTN  (PBAFIR_FIR_PARITY_ERR    ) ; // 45  PBAFIR_FIR_PARITY_ERR

            if (e_rc)
            {
                rc.setEcmdError(e_rc);
                break;
            }

            // ---------------
            // PBA_FIR - cleared
            // ---------------
            rc = fapiPutScom(i_target, PBA_FIR_0x02010840, fir);
            if (!rc.ok())
            {
                FAPI_ERR("fapiPutScom(PBA_FIR_0x02010840) failed.");
                 break;
            }

            FAPI_DBG(" action_0  => 0x%16llx ",  action_0.getDoubleWord(0));
            FAPI_DBG(" action_1  => 0x%16llx ",  action_1.getDoubleWord(0));
            FAPI_DBG(" mask      => 0x%16llx ",  mask.getDoubleWord(0));

            //#--******************************************************************************
            //#-- PBA_FIR_ACTION0
            //#--******************************************************************************

            rc = fapiPutScom(i_target, PBA_FIR_ACTION0_0x02010846, action_0 );
            if (rc)
            {
                FAPI_ERR("fapiPutScom(PBA_FIR_ACTION0_0x02010846) failed.");
                break;
            }

            //#--******************************************************************************
            //#-- PBA_FIR_ACTION1
            //#--******************************************************************************

            rc = fapiPutScom(i_target, PBA_FIR_ACTION1_0x02010847, action_1 );
            if (rc)
            {
                FAPI_ERR("fapiPutScom(PBA_FIR_ACTION1_0x02010847) failed.");
                break;
            }

            //--******************************************************************************
            //-- PBA_FIR_MASK (W0_OR_45) (WR_43) (WO_AND_44)
            //--******************************************************************************
            rc = fapiPutScom(i_target, PBA_FIR_MASK_0x02010843, mask );
            if (rc)
            {
                FAPI_ERR("fapiPutScom(PBA_FIR_MASK_0x02010843) failed.");
                 break;
            }
        } // Mode
    } while(0);
    return rc;

} // Procedure

} //end extern C<|endoftext|>