コード例 #1
0
ファイル: env.cpp プロジェクト: ixjlyons/fish-shell
void env_init(const struct config_paths_t *paths /* or NULL */)
{
    /*
      env_read_only variables can not be altered directly by the user
    */

    const wchar_t * const ro_keys[] =
    {
        L"status",
        L"history",
        L"version",
        L"_",
        L"LINES",
        L"COLUMNS",
        L"PWD",
        //L"SHLVL", // will be inserted a bit lower down
        L"FISH_VERSION",
    };
    for (size_t i=0; i < sizeof ro_keys / sizeof *ro_keys; i++)
    {
        env_read_only.insert(ro_keys[i]);
    }

    /*
       Names of all dynamically calculated variables
       */
    env_electric.insert(L"history");
    env_electric.insert(L"status");
    env_electric.insert(L"umask");
    env_electric.insert(L"COLUMNS");
    env_electric.insert(L"LINES");

    top = new env_node_t;
    global_env = top;
    global = &top->env;

    /*
      Now the environemnt variable handling is set up, the next step
      is to insert valid data
    */

    /*
      Import environment variables
    */
    for (char **p = (environ ? environ : __environ); p && *p; p++)
    {
        const wcstring key_and_val = str2wcstring(*p); //like foo=bar
        size_t eql = key_and_val.find(L'=');
        if (eql == wcstring::npos)
        {
            // no equals found
            if (is_read_only(key_and_val) || is_electric(key_and_val)) continue;
            env_set(key_and_val, L"", ENV_EXPORT | ENV_GLOBAL);
        }
        else
        {
            wcstring key = key_and_val.substr(0, eql);
            if (is_read_only(key) || is_electric(key)) continue;
            wcstring val = key_and_val.substr(eql + 1);
            if (variable_is_colon_delimited_array(key))
            {
                std::replace(val.begin(), val.end(), L':', ARRAY_SEP);
            }

            env_set(key, val.c_str(), ENV_EXPORT | ENV_GLOBAL);
        }
    }

    /* Set the given paths in the environment, if we have any */
    if (paths != NULL)
    {
        env_set(FISH_DATADIR_VAR, paths->data.c_str(), ENV_GLOBAL);
        env_set(FISH_SYSCONFDIR_VAR, paths->sysconf.c_str(), ENV_GLOBAL);
        env_set(FISH_HELPDIR_VAR, paths->doc.c_str(), ENV_GLOBAL);
        env_set(FISH_BIN_DIR, paths->bin.c_str(), ENV_GLOBAL);
    }

    /*
      Set up the PATH variable
    */
    setup_path();

    /*
      Set up the USER variable
    */
    if (env_get_string(L"USER").missing_or_empty())
    {
        const struct passwd *pw = getpwuid(getuid());
        if (pw && pw->pw_name)
        {
            const wcstring uname = str2wcstring(pw->pw_name);
            env_set(L"USER", uname.c_str(), ENV_GLOBAL | ENV_EXPORT);
        }
    }

    /*
      Set up the version variables
    */
    wcstring version = str2wcstring(get_fish_version());
    env_set(L"version", version.c_str(), ENV_GLOBAL);
    env_set(L"FISH_VERSION", version.c_str(), ENV_GLOBAL);

    /*
      Set up SHLVL variable
    */
    const env_var_t shlvl_str = env_get_string(L"SHLVL");
    wcstring nshlvl_str = L"1";
    if (! shlvl_str.missing())
    {
        wchar_t *end;
        long shlvl_i = wcstol(shlvl_str.c_str(), &end, 10);
        while (iswspace(*end)) ++end; /* skip trailing whitespace */
        if (shlvl_i >= 0 && *end == '\0')
        {
            nshlvl_str = to_string<long>(shlvl_i + 1);
        }
    }
    env_set(L"SHLVL", nshlvl_str.c_str(), ENV_GLOBAL | ENV_EXPORT);
    env_read_only.insert(L"SHLVL");

    /* Set up the HOME variable */
    if (env_get_string(L"HOME").missing_or_empty())
    {
        const env_var_t unam = env_get_string(L"USER");
        char *unam_narrow = wcs2str(unam.c_str());
        struct passwd *pw = getpwnam(unam_narrow);
        if (pw->pw_dir != NULL)
        {
            const wcstring dir = str2wcstring(pw->pw_dir);
            env_set(L"HOME", dir.c_str(), ENV_GLOBAL | ENV_EXPORT);
        }
        free(unam_narrow);
    }

    /* Set PWD */
    env_set_pwd();

    /* Set up universal variables. The empty string means to use the deafult path. */
    assert(s_universal_variables == NULL);
    s_universal_variables = new env_universal_t(L"");
    s_universal_variables->load();

    /* Set g_log_forks */
    env_var_t log_forks = env_get_string(L"fish_log_forks");
    g_log_forks = ! log_forks.missing_or_empty() && from_string<bool>(log_forks);

    /* Set g_use_posix_spawn. Default to true. */
    env_var_t use_posix_spawn = env_get_string(L"fish_use_posix_spawn");
    g_use_posix_spawn = (use_posix_spawn.missing_or_empty() ? true : from_string<bool>(use_posix_spawn));

    /* Set fish_bind_mode to "default" */
    env_set(FISH_BIND_MODE_VAR, DEFAULT_BIND_MODE, ENV_GLOBAL);

    /*
      Now that the global scope is fully initialized, add a toplevel local
      scope. This same local scope will persist throughout the lifetime of the
      fish process, and it will ensure that `set -l` commands run at the
      command-line don't affect the global scope.
    */
    env_push(false);
}
コード例 #2
0
ファイル: fish_indent.cpp プロジェクト: Sam0523/fish-shell
int main(int argc, char *argv[]) {
    program_name = L"fish_indent";
    set_main_thread();
    setup_fork_guards();
    // Using the user's default locale could be a problem if it doesn't use UTF-8 encoding. That's
    // because the fish project assumes Unicode UTF-8 encoding in all of its scripts.
    //
    // TODO: Auto-detect the encoding of the script. We should look for a vim style comment
    // (e.g., "# vim: set fileencoding=<encoding-name>:") or an emacs style comment
    // (e.g., "# -*- coding: <encoding-name> -*-").
    setlocale(LC_ALL, "");
    env_init();

    // Types of output we support.
    enum {
        output_type_plain_text,
        output_type_file,
        output_type_ansi,
        output_type_html
    } output_type = output_type_plain_text;
    const char *output_location = "";
    bool do_indent = true;

    const char *short_opts = "+d:hvwiD:";
    const struct option long_opts[] = {{"debug-level", required_argument, NULL, 'd'},
                                       {"debug-stack-frames", required_argument, NULL, 'D'},
                                       {"dump-parse-tree", no_argument, NULL, 'P'},
                                       {"no-indent", no_argument, NULL, 'i'},
                                       {"help", no_argument, NULL, 'h'},
                                       {"version", no_argument, NULL, 'v'},
                                       {"write", no_argument, NULL, 'w'},
                                       {"html", no_argument, NULL, 1},
                                       {"ansi", no_argument, NULL, 2},
                                       {NULL, 0, NULL, 0}};

    int opt;
    while ((opt = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) {
        switch (opt) {
            case 'P': {
                dump_parse_tree = true;
                break;
            }
            case 'h': {
                print_help("fish_indent", 1);
                exit(0);
                break;
            }
            case 'v': {
                fwprintf(stderr, _(L"%ls, version %s\n"), program_name, get_fish_version());
                exit(0);
                break;
            }
            case 'w': {
                output_type = output_type_file;
                break;
            }
            case 'i': {
                do_indent = false;
                break;
            }
            case 1: {
                output_type = output_type_html;
                break;
            }
            case 2: {
                output_type = output_type_ansi;
                break;
            }
            case 'd': {
                char *end;
                long tmp;

                errno = 0;
                tmp = strtol(optarg, &end, 10);

                if (tmp >= 0 && tmp <= 10 && !*end && !errno) {
                    debug_level = (int)tmp;
                } else {
                    fwprintf(stderr, _(L"Invalid value '%s' for debug-level flag"), optarg);
                    exit(1);
                }
                break;
            }
            case 'D': {
                char *end;
                long tmp;

                errno = 0;
                tmp = strtol(optarg, &end, 10);

                if (tmp > 0 && tmp <= 128 && !*end && !errno) {
                    debug_stack_frames = (int)tmp;
                } else {
                    fwprintf(stderr, _(L"Invalid value '%s' for debug-stack-frames flag"), optarg);
                    exit(1);
                }
                break;
            }
            default: {
                // We assume getopt_long() has already emitted a diagnostic msg.
                exit(1);
                break;
            }
        }
    }

    argc -= optind;
    argv += optind;

    wcstring src;
    if (argc == 0) {
        if (output_type == output_type_file) {
            fwprintf(stderr, _(L"Expected file path to read/write for -w:\n\n $ %ls -w foo.fish\n"),
                     program_name);
            exit(1);
        }
        src = read_file(stdin);
    } else if (argc == 1) {
        FILE *fh = fopen(*argv, "r");
        if (fh) {
            src = read_file(fh);
            fclose(fh);
            output_location = *argv;
        } else {
            fwprintf(stderr, _(L"Opening \"%s\" failed: %s\n"), *argv, strerror(errno));
            exit(1);
        }
    } else {
        fwprintf(stderr, _(L"Too many arguments\n"));
        exit(1);
    }

    const wcstring output_wtext = prettify(src, do_indent);

    // Maybe colorize.
    std::vector<highlight_spec_t> colors;
    if (output_type != output_type_plain_text) {
        highlight_shell_no_io(output_wtext, colors, output_wtext.size(), NULL,
                              env_vars_snapshot_t::current());
    }

    std::string colored_output;
    switch (output_type) {
        case output_type_plain_text: {
            colored_output = no_colorize(output_wtext);
            break;
        }
        case output_type_file: {
            FILE *fh = fopen(output_location, "w");
            if (fh) {
                fputws(output_wtext.c_str(), fh);
                fclose(fh);
                exit(0);
            } else {
                fwprintf(stderr, _(L"Opening \"%s\" failed: %s\n"), output_location,
                         strerror(errno));
                exit(1);
            }
            break;
        }
        case output_type_ansi: {
            colored_output = ansi_colorize(output_wtext, colors);
            break;
        }
        case output_type_html: {
            colored_output = html_colorize(output_wtext, colors);
            break;
        }
    }

    fputws(str2wcstring(colored_output).c_str(), stdout);
    return 0;
}
コード例 #3
0
ファイル: fish.cpp プロジェクト: haarts/fish-shell
/// Parse the argument list, return the index of the first non-flag arguments.
static int fish_parse_opt(int argc, char **argv, std::vector<std::string> *cmds) {
    const char *short_opts = "+hilnvc:p:d:D:";
    const struct option long_opts[] = {{"command", required_argument, NULL, 'c'},
                                       {"debug-level", required_argument, NULL, 'd'},
                                       {"debug-stack-frames", required_argument, NULL, 'D'},
                                       {"interactive", no_argument, NULL, 'i'},
                                       {"login", no_argument, NULL, 'l'},
                                       {"no-execute", no_argument, NULL, 'n'},
                                       {"profile", required_argument, NULL, 'p'},
                                       {"help", no_argument, NULL, 'h'},
                                       {"version", no_argument, NULL, 'v'},
                                       {NULL, 0, NULL, 0}};

    int opt;
    while ((opt = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) {
        switch (opt) {
            case 0: {
                fwprintf(stderr, _(L"getopt_long() unexpectedly returned zero\n"));
                exit(127);
                break;
            }
            case 'c': {
                cmds->push_back(optarg);
                break;
            }
            case 'd': {
                char *end;
                long tmp;

                errno = 0;
                tmp = strtol(optarg, &end, 10);

                if (tmp >= 0 && tmp <= 10 && !*end && !errno) {
                    debug_level = (int)tmp;
                } else {
                    fwprintf(stderr, _(L"Invalid value '%s' for debug-level flag"), optarg);
                    exit(1);
                }
                break;
            }
            case 'h': {
                cmds->push_back("__fish_print_help fish");
                break;
            }
            case 'i': {
                is_interactive_session = 1;
                break;
            }
            case 'l': {
                is_login = 1;
                break;
            }
            case 'n': {
                no_exec = 1;
                break;
            }
            case 'p': {
                s_profiling_output_filename = optarg;
                g_profiling_active = true;
                break;
            }
            case 'v': {
                fwprintf(stdout, _(L"%s, version %s\n"), PACKAGE_NAME, get_fish_version());
                exit(0);
                break;
            }
            case 'D': {
                char *end;
                long tmp;

                errno = 0;
                tmp = strtol(optarg, &end, 10);

                if (tmp > 0 && tmp <= 128 && !*end && !errno) {
                    debug_stack_frames = (int)tmp;
                } else {
                    fwprintf(stderr, _(L"Invalid value '%s' for debug-stack-frames flag"), optarg);
                    exit(1);
                }
                break;
            }
            default: {
                // We assume getopt_long() has already emitted a diagnostic msg.
                exit(1);
                break;
            }
        }
    }

    // If our command name begins with a dash that implies we're a login shell.
    is_login |= argv[0][0] == '-';

    // We are an interactive session if we have not been given an explicit
    // command or file to execute and stdin is a tty. Note that the -i or
    // --interactive options also force interactive mode.
    if (cmds->size() == 0 && optind == argc && isatty(STDIN_FILENO)) {
        is_interactive_session = 1;
    }

    return optind;
}
コード例 #4
0
ファイル: env.cpp プロジェクト: Aulos/fish-shell
void env_init(const struct config_paths_t *paths /* or NULL */)
{
    /*
      env_read_only variables can not be altered directly by the user
    */

    const wchar_t * const ro_keys[] =
    {
        L"status",
        L"history",
        L"version",
        L"_",
        L"LINES",
        L"COLUMNS",
        L"PWD",
        L"SHLVL",
        L"FISH_VERSION",
    };
    for (size_t i=0; i < sizeof ro_keys / sizeof *ro_keys; i++)
    {
        env_read_only.insert(ro_keys[i]);
    }

    /*
      HOME and USER should be writeable by root, since this can be a
      convenient way to install software.
    */
    if (getuid() != 0)
    {
        env_read_only.insert(L"HOME");
        env_read_only.insert(L"USER");
    }

    /*
       Names of all dynamically calculated variables
       */
    env_electric.insert(L"history");
    env_electric.insert(L"status");
    env_electric.insert(L"umask");

    top = new env_node_t;
    global_env = top;
    global = &top->env;

    /*
      Now the environemnt variable handling is set up, the next step
      is to insert valid data
    */

    /*
      Import environment variables
    */
    for (char **p = (environ ? environ : __environ); p && *p; p++)
    {
        const wcstring key_and_val = str2wcstring(*p); //like foo=bar
        size_t eql = key_and_val.find(L'=');
        if (eql == wcstring::npos)
        {
            // no equals found
            env_set(key_and_val, L"", ENV_EXPORT);
        }
        else
        {
            wcstring key = key_and_val.substr(0, eql);
            wcstring val = key_and_val.substr(eql + 1);
            if (variable_can_be_array(val))
            {
                std::replace(val.begin(), val.end(), L':', ARRAY_SEP);
            }

            env_set(key, val.c_str(), ENV_EXPORT | ENV_GLOBAL);
        }
    }

    /* Set the given paths in the environment, if we have any */
    if (paths != NULL)
    {
        env_set(FISH_DATADIR_VAR, paths->data.c_str(), ENV_GLOBAL | ENV_EXPORT);
        env_set(FISH_SYSCONFDIR_VAR, paths->sysconf.c_str(), ENV_GLOBAL | ENV_EXPORT);
        env_set(FISH_HELPDIR_VAR, paths->doc.c_str(), ENV_GLOBAL | ENV_EXPORT);
        env_set(FISH_BIN_DIR, paths->bin.c_str(), ENV_GLOBAL | ENV_EXPORT);
    }

    /*
      Set up the PATH variable
    */
    setup_path();

    /*
      Set up the USER variable
    */
    const struct passwd *pw = getpwuid(getuid());
    if (pw && pw->pw_name)
    {
        const wcstring uname = str2wcstring(pw->pw_name);
        env_set(L"USER", uname.c_str(), ENV_GLOBAL | ENV_EXPORT);
    }

    /*
      Set up the version variables
    */
    wcstring version = str2wcstring(get_fish_version());
    env_set(L"version", version.c_str(), ENV_GLOBAL);
    env_set(L"FISH_VERSION", version.c_str(), ENV_GLOBAL);

    /* Set up universal variables. The empty string means to use the deafult path. */
    assert(s_universal_variables == NULL);
    s_universal_variables = new env_universal_t(L"");

    /*
      Set up SHLVL variable
    */
    const env_var_t shlvl_str = env_get_string(L"SHLVL");
    wcstring nshlvl_str = L"1";
    if (! shlvl_str.missing())
    {
        long shlvl_i = wcstol(shlvl_str.c_str(), NULL, 10);
        if (shlvl_i >= 0)
        {
            nshlvl_str = to_string<long>(shlvl_i + 1);
        }
    }
    env_set(L"SHLVL", nshlvl_str.c_str(), ENV_GLOBAL | ENV_EXPORT);

    /* Set correct defaults for e.g. USER and HOME variables */
    env_set_defaults();

    /* Set g_log_forks */
    env_var_t log_forks = env_get_string(L"fish_log_forks");
    g_log_forks = ! log_forks.missing_or_empty() && from_string<bool>(log_forks);

    /* Set g_use_posix_spawn. Default to true. */
    env_var_t use_posix_spawn = env_get_string(L"fish_use_posix_spawn");
    g_use_posix_spawn = (use_posix_spawn.missing_or_empty() ? true : from_string<bool>(use_posix_spawn));

    /* Set fish_bind_mode to "default" */
    env_set(FISH_BIND_MODE_VAR, DEFAULT_BIND_MODE, ENV_GLOBAL);
}
コード例 #5
0
ファイル: fish.cpp プロジェクト: Ju2ender/fish-shell
/**
  Parse the argument list, return the index of the first non-switch
  arguments.
 */
static int fish_parse_opt(int argc, char **argv, std::vector<std::string> *out_cmds)
{
    int my_optind;
    int force_interactive=0;
    bool has_cmd = false;

    while (1)
    {
        static struct option
                long_options[] =
        {
            { "command", required_argument, 0, 'c' },
            { "debug-level", required_argument, 0, 'd' },
            { "interactive", no_argument, 0, 'i' } ,
            { "login", no_argument, 0, 'l' },
            { "no-execute", no_argument, 0, 'n' },
            { "profile", required_argument, 0, 'p' },
            { "help", no_argument, 0, 'h' },
            { "version", no_argument, 0, 'v' },
            { 0, 0, 0, 0 }
        }
        ;

        int opt_index = 0;

        int opt = getopt_long(argc,
                              argv,
                              GETOPT_STRING,
                              long_options,
                              &opt_index);

        if (opt == -1)
            break;

        switch (opt)
        {
            case 0:
            {
                break;
            }

            case 'c':
            {
                out_cmds->push_back(optarg ? optarg : "");
                has_cmd = true;
                is_interactive_session = 0;
                break;
            }

            case 'd':
            {
                char *end;
                long tmp;

                errno = 0;
                tmp = strtol(optarg, &end, 10);

                if (tmp >= 0 && tmp <=10 && !*end && !errno)
                {
                    debug_level = (int)tmp;
                }
                else
                {
                    debug(0, _(L"Invalid value '%s' for debug level switch"), optarg);
                    exit_without_destructors(1);
                }
                break;
            }

            case 'h':
            {
                out_cmds->push_back("__fish_print_help fish");
                has_cmd = true;
                break;
            }

            case 'i':
            {
                force_interactive = 1;
                break;
            }

            case 'l':
            {
                is_login=1;
                break;
            }

            case 'n':
            {
                no_exec=1;
                break;
            }

            case 'p':
            {
                s_profiling_output_filename = optarg;
                g_profiling_active = true;
                break;
            }

            case 'v':
            {
                fwprintf(stderr,
                         _(L"%s, version %s\n"),
                         PACKAGE_NAME,
                         get_fish_version());
                exit_without_destructors(0);
            }

            case '?':
            {
                exit_without_destructors(1);
            }

        }
    }

    my_optind = optind;

    is_login |= (strcmp(argv[0], "-fish") == 0);

    /* We are an interactive session if we are either forced, or have not been given an explicit command to execute and stdin is a tty. */
    if (force_interactive)
    {
        is_interactive_session = true;
    }
    else if (is_interactive_session)
    {
        is_interactive_session = ! has_cmd && (my_optind == argc) && isatty(STDIN_FILENO);
    }

    return my_optind;
}
コード例 #6
0
ファイル: fish_indent.cpp プロジェクト: actionless/fish-shell
int main(int argc, char *argv[])
{
    set_main_thread();
    setup_fork_guards();

    wsetlocale(LC_ALL, L"");
    program_name=L"fish_indent";

    env_init();
    input_init();

    /* Types of output we support */
    enum
    {
        output_type_plain_text,
        output_type_ansi,
        output_type_html
    } output_type = output_type_plain_text;
    bool do_indent = true;

    const char *short_opts = "+dhvi";
    const struct option long_opts[] =
    {
        { "dump", no_argument, NULL, 'd' },
        { "no-indent", no_argument, NULL, 'i' },
        { "help", no_argument, NULL, 'h' },
        { "version", no_argument, NULL, 'v' },
        { "html", no_argument, NULL, 1 },
        { "ansi", no_argument, NULL, 2 },
        { NULL, 0, NULL, 0 }
    };

    int opt;
    while ((opt = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1)
    {
        switch (opt)
        {
            case 0:
            {
                fwprintf(stderr, _(L"getopt_long() unexpectedly returned zero\n"));
                exit_without_destructors(127);
            }

            case 'd':
            {
                dump_parse_tree = true;
                break;
            }

            case 'h':
            {
                print_help("fish_indent", 1);
                exit_without_destructors(0);
            }

            case 'v':
            {
                fwprintf(stderr, _(L"%ls, version %s\n"), program_name, get_fish_version());
                exit(0);
                assert(0 && "Unreachable code reached");
                break;
            }

            case 'i':
            {
                do_indent = false;
                break;
            }

            case 1:
            {
                output_type = output_type_html;
                break;
            }

            case 2:
            {
                output_type = output_type_ansi;
                break;
            }

            default:
            {
                // We assume getopt_long() has already emitted a diagnostic msg.
                exit_without_destructors(1);
            }
        }
    }

    const wcstring src = read_file(stdin);
    const wcstring output_wtext = prettify(src, do_indent);

    /* Maybe colorize */
    std::vector<highlight_spec_t> colors;
    if (output_type != output_type_plain_text)
    {
        highlight_shell_no_io(output_wtext, colors, output_wtext.size(), NULL, env_vars_snapshot_t::current());
    }

    std::string colored_output;
    switch (output_type)
    {
        case output_type_plain_text:
            colored_output = no_colorize(output_wtext);
            break;

        case output_type_ansi:
            colored_output = ansi_colorize(output_wtext, colors);
            break;

        case output_type_html:
            colored_output = html_colorize(output_wtext, colors);
            break;
    }

    fputs(colored_output.c_str(), stdout);
    return 0;
}
コード例 #7
0
ファイル: fish.cpp プロジェクト: ixjlyons/fish-shell
/**
  Parse the argument list, return the index of the first non-switch
  arguments.
 */
static int fish_parse_opt(int argc, char **argv, std::vector<std::string> *cmds)
{
    const struct option long_options[] =
    {
        { "command", required_argument, NULL, 'c' },
        { "debug-level", required_argument, NULL, 'd' },
        { "interactive", no_argument, NULL, 'i' } ,
        { "login", no_argument, NULL, 'l' },
        { "no-execute", no_argument, NULL, 'n' },
        { "profile", required_argument, NULL, 'p' },
        { "help", no_argument, NULL, 'h' },
        { "version", no_argument, NULL, 'v' },
        { NULL, 0, NULL, 0 }
    };

    while (1)
    {
        int opt = getopt_long(argc, argv, GETOPT_STRING, long_options, NULL);
        if (opt == -1)
            break;

        switch (opt)
        {
            case 0:
            {
                break;
            }

            case 'c':
            {
                cmds->push_back(optarg);
                break;
            }

            case 'd':
            {
                char *end;
                long tmp;

                errno = 0;
                tmp = strtol(optarg, &end, 10);

                if (tmp >= 0 && tmp <=10 && !*end && !errno)
                {
                    debug_level = (int)tmp;
                }
                else
                {
                    debug(0, _(L"Invalid value '%s' for debug level switch"), optarg);
                    exit_without_destructors(1);
                }
                break;
            }

            case 'h':
            {
                cmds->push_back("__fish_print_help fish");
                break;
            }

            case 'i':
            {
                is_interactive_session = 1;
                break;
            }

            case 'l':
            {
                is_login = 1;
                break;
            }

            case 'n':
            {
                no_exec = 1;
                break;
            }

            case 'p':
            {
                s_profiling_output_filename = optarg;
                g_profiling_active = true;
                break;
            }

            case 'v':
            {
                fwprintf(stderr, _(L"%s, version %s\n"), PACKAGE_NAME,
                         get_fish_version());
                exit_without_destructors(0);
            }

            default:
            {
                exit_without_destructors(1);
            }

        }
    }

    // If our command name begins with a dash that implies we're a login shell.
    is_login |= argv[0][0] == '-';

    // We are an interactive session if we have not been given an explicit
    // command or file to execute and stdin is a tty. Note that the -i or
    // --interactive options also force interactive mode.
    if (cmds->size() == 0 && optind == argc && isatty(STDIN_FILENO))
    {
        is_interactive_session = 1;
    }

    return optind;
}