static int string_split(parser_t &parser, io_streams_t &streams, int argc, wchar_t **argv) { options_t opts; opts.quiet_valid = true; opts.right_valid = true; opts.max_valid = true; opts.max = LONG_MAX; int optind; int retval = parse_opts(&opts, &optind, 1, argc, argv, parser, streams); if (retval != STATUS_CMD_OK) return retval; const wchar_t *sep = opts.arg1; const wchar_t *sep_end = sep + wcslen(sep); wcstring_list_t splits; size_t arg_count = 0; wcstring storage; const wchar_t *arg; while ((arg = string_get_arg(&optind, argv, &storage, streams)) != 0) { const wchar_t *arg_end = arg + wcslen(arg); if (opts.right) { typedef std::reverse_iterator<const wchar_t *> reverser; split_about(reverser(arg_end), reverser(arg), reverser(sep_end), reverser(sep), &splits, opts.max); } else { split_about(arg, arg_end, sep, sep_end, &splits, opts.max); } arg_count++; } // If we are from the right, split_about gave us reversed strings, in reversed order! if (opts.right) { for (size_t j = 0; j < splits.size(); j++) { std::reverse(splits[j].begin(), splits[j].end()); } std::reverse(splits.begin(), splits.end()); } if (!opts.quiet) { for (wcstring_list_t::const_iterator si = splits.begin(); si != splits.end(); ++si) { streams.out.append(*si); streams.out.append(L'\n'); } } // We split something if we have more split values than args. return splits.size() > arg_count ? STATUS_CMD_OK : STATUS_CMD_ERROR; }
static int string_split(parser_t &parser, io_streams_t &streams, int argc, wchar_t **argv) { const wchar_t *short_options = L":m:qr"; const struct woption long_options[] = {{L"max", required_argument, 0, 'm'}, {L"quiet", no_argument, 0, 'q'}, {L"right", no_argument, 0, 'r'}, {0, 0, 0, 0}}; long max = LONG_MAX; bool quiet = false; bool right = false; wgetopter_t w; for (;;) { int c = w.wgetopt_long(argc, argv, short_options, long_options, 0); if (c == -1) { break; } switch (c) { case 0: { break; } case 'm': { errno = 0; wchar_t *endptr = 0; max = wcstol(w.woptarg, &endptr, 10); if (*endptr != L'\0' || errno != 0) { string_error(streams, BUILTIN_ERR_NOT_NUMBER, argv[0], w.woptarg); return BUILTIN_STRING_ERROR; } break; } case 'q': { quiet = true; break; } case 'r': { right = true; break; } case ':': { string_error(streams, STRING_ERR_MISSING, argv[0]); return BUILTIN_STRING_ERROR; } case '?': { string_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]); return BUILTIN_STRING_ERROR; } default: { DIE("unexpected opt"); break; } } } int i = w.woptind; const wchar_t *sep; if ((sep = string_get_arg_argv(&i, argv)) == NULL) { string_error(streams, STRING_ERR_MISSING, argv[0]); return BUILTIN_STRING_ERROR; } const wchar_t *sep_end = sep + wcslen(sep); if (string_args_from_stdin(streams) && argc > i) { string_error(streams, BUILTIN_ERR_TOO_MANY_ARGUMENTS, argv[0]); return BUILTIN_STRING_ERROR; } wcstring_list_t splits; size_t arg_count = 0; wcstring storage; const wchar_t *arg; while ((arg = string_get_arg(&i, argv, &storage, streams)) != 0) { const wchar_t *arg_end = arg + wcslen(arg); if (right) { typedef std::reverse_iterator<const wchar_t *> reverser; split_about(reverser(arg_end), reverser(arg), reverser(sep_end), reverser(sep), &splits, max); } else { split_about(arg, arg_end, sep, sep_end, &splits, max); } arg_count++; } // If we are from the right, split_about gave us reversed strings, in reversed order! if (right) { for (size_t j = 0; j < splits.size(); j++) { std::reverse(splits[j].begin(), splits[j].end()); } std::reverse(splits.begin(), splits.end()); } if (!quiet) { for (wcstring_list_t::const_iterator si = splits.begin(); si != splits.end(); ++si) { streams.out.append(*si); streams.out.append(L'\n'); } } // We split something if we have more split values than args. return splits.size() > arg_count ? BUILTIN_STRING_OK : BUILTIN_STRING_NONE; }