diff options
author | ridiculousfish <corydoras@ridiculousfish.com> | 2014-08-21 21:36:39 -0700 |
---|---|---|
committer | ridiculousfish <corydoras@ridiculousfish.com> | 2014-08-21 21:36:39 -0700 |
commit | 033373f078db74b26dc458252734099482dc8a1a (patch) | |
tree | e0bce4834f17059cc83942eb4e3b0c036e6c2855 /builtin.cpp | |
parent | d63db59adeb84251c3ab5fe1b13981e44571bf31 (diff) | |
parent | 16e50c258a5d5cecc76e1f2dc29a62be88a1ac2f (diff) |
Merge branch 'make_type_better' of github.com:kballard/fish-shell into kballard-make_type_better
Diffstat (limited to 'builtin.cpp')
-rw-r--r-- | builtin.cpp | 164 |
1 files changed, 154 insertions, 10 deletions
diff --git a/builtin.cpp b/builtin.cpp index 0213f5cb..efe28f90 100644 --- a/builtin.cpp +++ b/builtin.cpp @@ -1054,6 +1054,87 @@ static int builtin_emit(parser_t &parser, wchar_t **argv) /** + Implementation of the builtin 'command'. Actual command running is handled by + the parser, this just processes the flags. +*/ +static int builtin_command(parser_t &parser, wchar_t **argv) +{ + int argc=builtin_count_args(argv); + int print_path=0; + + woptind=0; + + static const struct woption + long_options[] = + { + { L"search", no_argument, 0, 's' }, + { L"help", no_argument, 0, 'h' }, + { 0, 0, 0, 0 } + }; + + while (1) + { + int opt_index = 0; + + int opt = wgetopt_long(argc, + argv, + L"svh", + long_options, + &opt_index); + if (opt == -1) + break; + + switch (opt) + { + case 0: + if (long_options[opt_index].flag != 0) + break; + append_format(stderr_buffer, + BUILTIN_ERR_UNKNOWN, + argv[0], + long_options[opt_index].name); + builtin_print_help(parser, argv[0], stderr_buffer); + return STATUS_BUILTIN_ERROR; + + case 'h': + builtin_print_help(parser, argv[0], stdout_buffer); + return STATUS_BUILTIN_OK; + + case 's': + case 'v': + print_path=1; + break; + + case '?': + builtin_unknown_option(parser, argv[0], argv[woptind-1]); + return STATUS_BUILTIN_ERROR; + + } + + } + + if (!print_path) + { + builtin_print_help(parser, argv[0], stdout_buffer); + return STATUS_BUILTIN_ERROR; + } + + int found=0; + + for (int idx = woptind; argv[idx]; ++idx) + { + const wchar_t *command_name = argv[idx]; + wcstring path; + if (path_get_path(command_name, &path)) + { + append_format(stdout_buffer, L"%ls\n", path.c_str()); + ++found; + } + } + return found ? STATUS_BUILTIN_OK : STATUS_BUILTIN_ERROR; +} + +/** A generic bultin that only supports showing a help message. This is only a placeholder that prints the help message. Useful for commands that live in the parser. @@ -2233,6 +2314,7 @@ static int builtin_read(parser_t &parser, wchar_t **argv) int exit_res=STATUS_BUILTIN_OK; const wchar_t *mode_name = READ_MODE_NAME; int shell = 0; + int array = 0; woptind=0; @@ -2278,6 +2360,10 @@ static int builtin_read(parser_t &parser, wchar_t **argv) } , { + L"array", no_argument, 0, 'a' + } + , + { L"help", no_argument, 0, 'h' } , @@ -2291,7 +2377,7 @@ static int builtin_read(parser_t &parser, wchar_t **argv) int opt = wgetopt_long(argc, argv, - L"xglUup:c:hm:s", + L"xglUup:c:hm:sa", long_options, &opt_index); if (opt == -1) @@ -2346,6 +2432,10 @@ static int builtin_read(parser_t &parser, wchar_t **argv) shell = 1; break; + case 'a': + array = 1; + break; + case 'h': builtin_print_help(parser, argv[0], stdout_buffer); return STATUS_BUILTIN_OK; @@ -2378,6 +2468,14 @@ static int builtin_read(parser_t &parser, wchar_t **argv) return STATUS_BUILTIN_ERROR; } + if (array && woptind+1 != argc) + { + append_format(stderr_buffer, _(L"%ls: --array option requires a single variable name.\n"), argv[0]); + builtin_print_help(parser, argv[0], stderr_buffer); + + return STATUS_BUILTIN_ERROR; + } + /* Verify all variable names */ @@ -2512,18 +2610,64 @@ static int builtin_read(parser_t &parser, wchar_t **argv) wchar_t *state; env_var_t ifs = env_get_string(L"IFS"); - if (ifs.missing()) - ifs = L""; - nxt = wcstok(buff, (i<argc-1)?ifs.c_str():L"", &state); + if (ifs.missing_or_empty()) + { + /* Every character is a separate token */ + size_t bufflen = wcslen(buff); + if (array) + { + if (bufflen > 0) + { + wcstring chars(bufflen+(bufflen-1), ARRAY_SEP); + for (size_t j=0; j<bufflen; ++j) + { + chars[j*2] = buff[j]; + } + env_set(argv[i], chars.c_str(), place); + } + else + { + env_set(argv[i], NULL, place); + } + } + else + { + size_t j = 0; + for (; i+1 < argc; ++i) + { + env_set(argv[i], j < bufflen ? (wchar_t[2]){buff[j], 0} : L"", place); + if (j < bufflen) ++j; + } + if (i < argc) env_set(argv[i], &buff[j], place); + } + } + else if (array) + { + wcstring tokens; + tokens.reserve(wcslen(buff)); + bool empty = true; - while (i<argc) + for (nxt = wcstok(buff, ifs.c_str(), &state); nxt != 0; nxt = wcstok(0, ifs.c_str(), &state)) + { + if (! tokens.empty()) tokens.push_back(ARRAY_SEP); + tokens.append(nxt); + empty = false; + } + env_set(argv[i], empty ? NULL : tokens.c_str(), place); + } + else { - env_set(argv[i], nxt != 0 ? nxt: L"", place); + nxt = wcstok(buff, (i<argc-1)?ifs.c_str():L"", &state); + + while (i<argc) + { + env_set(argv[i], nxt != 0 ? nxt: L"", place); - i++; - if (nxt != 0) - nxt = wcstok(0, (i<argc-1)?ifs.c_str():L"", &state); + i++; + if (nxt != 0) + nxt = wcstok(0, (i<argc-1)?ifs.c_str():L"", &state); + } } } @@ -3726,7 +3870,7 @@ static const builtin_data_t builtin_datas[]= { L"builtin", &builtin_builtin, N_(L"Run a builtin command instead of a function") }, { L"case", &builtin_generic, N_(L"Conditionally execute a block of commands") }, { L"cd", &builtin_cd, N_(L"Change working directory") }, - { L"command", &builtin_generic, N_(L"Run a program instead of a function or builtin") }, + { L"command", &builtin_command, N_(L"Run a program instead of a function or builtin") }, { L"commandline", &builtin_commandline, N_(L"Set or get the commandline") }, { L"complete", &builtin_complete, N_(L"Edit command specific completions") }, { L"contains", &builtin_contains, N_(L"Search for a specified string in a list") }, |