void uParserCustom::_customParserValidateFields(const std::vector<std::string>& fieldsNames) const { /**< Must have at least 2 fields */ if (fieldsNames.size() < 3) { customParser_missing_mandatory_values e; e << string_error("Custom file fields description is too short, must have at least 3 values: CHR and START_POS and a way to infer END_POS.\n"); throw e; } /**< Check if mandatory fields are present */ if (!_paramExists("CHR", fieldsNames)) { customParser_missing_mandatory_values e; e << string_error("Mandatory field is missing: CHR\n"); throw e; } if (!_paramExists("START_POS", fieldsNames)) { customParser_missing_mandatory_values e; e << string_error("Mandatory field is missing: START_POS\n"); throw e; } /**< We need to be able to infer END_POS either directly or indirectly (with a sequence or cigar score) */ if (!_paramExists("END_POS", fieldsNames) && !_paramExists("SEQUENCE", fieldsNames) && !_paramExists("CIGAR", fieldsNames)) { customParser_missing_mandatory_values e; e << string_error("We must be able to infer END_POS directly or indirectly (with SEQUENCE or CIGAR)\n"); throw e; } }
compiled_regex_t(const wchar_t *argv0, const wchar_t *pattern, bool ignore_case, io_streams_t &streams) : code(0), match(0) { // Disable some sequences that can lead to security problems. uint32_t options = PCRE2_NEVER_UTF; #if PCRE2_CODE_UNIT_WIDTH < 32 options |= PCRE2_NEVER_BACKSLASH_C; #endif int err_code = 0; PCRE2_SIZE err_offset = 0; code = pcre2_compile(PCRE2_SPTR(pattern), PCRE2_ZERO_TERMINATED, options | (ignore_case ? PCRE2_CASELESS : 0), &err_code, &err_offset, 0); if (code == 0) { string_error(streams, _(L"%ls: Regular expression compile error: %ls\n"), argv0, pcre2_strerror(err_code).c_str()); string_error(streams, L"%ls: %ls\n", argv0, pattern); string_error(streams, L"%ls: %*ls\n", argv0, err_offset, L"^"); return; } match = pcre2_match_data_create_from_pattern(code, 0); if (match == 0) { DIE_MEM(); } }
int report_match(const wchar_t *arg, int pcre2_rc) { // Return values: -1 = error, 0 = no match, 1 = match. if (pcre2_rc == PCRE2_ERROR_NOMATCH) { if (opts.invert_match && !opts.quiet) { if (opts.index) { streams.out.append_format(L"1 %lu\n", wcslen(arg)); } else { streams.out.append(arg); streams.out.push_back(L'\n'); } } return opts.invert_match ? 1 : 0; } else if (pcre2_rc < 0) { string_error(streams, _(L"%ls: Regular expression match error: %ls\n"), argv0, pcre2_strerror(pcre2_rc).c_str()); return -1; } else if (pcre2_rc == 0) { // The output vector wasn't big enough. Should not happen. string_error(streams, _(L"%ls: Regular expression internal error\n"), argv0); return -1; } else if (opts.invert_match) { return 0; } if (opts.entire) { streams.out.append(arg); streams.out.push_back(L'\n'); } PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(regex.match); for (int j = (opts.entire ? 1 : 0); j < pcre2_rc; j++) { PCRE2_SIZE begin = ovector[2 * j]; PCRE2_SIZE end = ovector[2 * j + 1]; if (begin != PCRE2_UNSET && end != PCRE2_UNSET && !opts.quiet) { if (opts.index) { streams.out.append_format(L"%lu %lu", (unsigned long)(begin + 1), (unsigned long)(end - begin)); } else if (end > begin) { // May have end < begin if \K is used. streams.out.append(wcstring(&arg[begin], end - begin)); } streams.out.push_back(L'\n'); } } return opts.invert_match ? 0 : 1; }
/// Parse the arguments for flags recognized by a specific string subcommand. static int parse_opts(options_t *opts, int *optind, int n_req_args, int argc, wchar_t **argv, parser_t &parser, io_streams_t &streams) { const wchar_t *cmd = argv[0]; wcstring short_opts = construct_short_opts(opts); const wchar_t *short_options = short_opts.c_str(); int opt; wgetopter_t w; while ((opt = w.wgetopt_long(argc, argv, short_options, long_options, NULL)) != -1) { auto fn = flag_to_function.find(opt); if (fn != flag_to_function.end()) { int retval = fn->second(argv, parser, streams, w, opts); if (retval != STATUS_CMD_OK) return retval; } else if (opt == ':') { string_error(streams, STRING_ERR_MISSING, cmd); return STATUS_INVALID_ARGS; } else if (opt == '?') { string_unknown_option(parser, streams, cmd, argv[w.woptind - 1]); return STATUS_INVALID_ARGS; } else { DIE("unexpected retval from wgetopt_long"); } } *optind = w.woptind; // If the caller requires one or two mandatory args deal with that here. if (n_req_args) { opts->arg1 = string_get_arg_argv(optind, argv); if (!opts->arg1) { string_error(streams, STRING_ERR_MISSING, cmd); return STATUS_INVALID_ARGS; } } if (n_req_args > 1) { opts->arg2 = string_get_arg_argv(optind, argv); if (!opts->arg2) { string_error(streams, STRING_ERR_MISSING, cmd); return STATUS_INVALID_ARGS; } } // At this point we should not have optional args and be reading args from stdin. if (string_args_from_stdin(streams) && argc > *optind) { string_error(streams, BUILTIN_ERR_TOO_MANY_ARGUMENTS, cmd); return STATUS_INVALID_ARGS; } return STATUS_CMD_OK; }
static int string_length(parser_t &parser, io_streams_t &streams, int argc, wchar_t **argv) { const wchar_t *short_options = L"q"; const struct woption long_options[] = { { L"quiet", no_argument, 0, 'q'}, { 0, 0, 0, 0 } }; bool quiet = 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 'q': quiet = true; break; case '?': string_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]); return BUILTIN_STRING_ERROR; } } int i = w.woptind; if (string_args_from_stdin(streams) && argc > i) { string_error(streams, BUILTIN_ERR_TOO_MANY_ARGUMENTS, argv[0]); return BUILTIN_STRING_ERROR; } const wchar_t *arg; int nnonempty = 0; wcstring storage; while ((arg = string_get_arg(&i, argv, &storage, streams)) != 0) { size_t n = wcslen(arg); if (n > 0) { nnonempty++; } if (!quiet) { streams.out.append(to_string(n)); streams.out.append(L'\n'); } } return (nnonempty > 0) ? BUILTIN_STRING_OK : BUILTIN_STRING_NONE; }
static int handle_flag_s(wchar_t **argv, parser_t &parser, io_streams_t &streams, wgetopter_t &w, options_t *opts) { if (opts->start_valid) { opts->start = fish_wcstol(w.woptarg); if (opts->start == 0 || opts->start == LONG_MIN || errno == ERANGE) { string_error(streams, _(L"%ls: Invalid start value '%ls'\n"), argv[0], w.woptarg); return STATUS_INVALID_ARGS; } else if (errno) { string_error(streams, BUILTIN_ERR_NOT_NUMBER, argv[0], w.woptarg); return STATUS_INVALID_ARGS; } return STATUS_CMD_OK; } string_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]); return STATUS_INVALID_ARGS; }
void CALLBACK RemoveDeviceW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int nCmdShow) { try { WCHAR *s, *vol, *dev; uint64_t devid; win_handle h, token; TOKEN_PRIVILEGES tp; LUID luid; NTSTATUS Status; IO_STATUS_BLOCK iosb; set_dpi_aware(); if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token)) throw last_error(GetLastError()); if (!LookupPrivilegeValueW(nullptr, L"SeManageVolumePrivilege", &luid)) throw last_error(GetLastError()); tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if (!AdjustTokenPrivileges(token, false, &tp, sizeof(TOKEN_PRIVILEGES), nullptr, nullptr)) throw last_error(GetLastError()); s = wcsstr(lpszCmdLine, L"|"); if (!s) return; s[0] = 0; vol = lpszCmdLine; dev = &s[1]; devid = _wtoi(dev); if (devid == 0) return; h = CreateFileW(vol, FILE_TRAVERSE | FILE_READ_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, nullptr); if (h == INVALID_HANDLE_VALUE) throw last_error(GetLastError()); Status = NtFsControlFile(h, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_REMOVE_DEVICE, &devid, sizeof(uint64_t), nullptr, 0); if (!NT_SUCCESS(Status)) { if (Status == STATUS_CANNOT_DELETE) throw string_error(IDS_CANNOT_REMOVE_RAID); else throw ntstatus_error(Status); return; } BtrfsBalance bb(vol, true); bb.ShowBalance(hwnd); } catch (const exception& e) { error_message(hwnd, e.what()); } }
/** \brief Set the fields name (only used for the Custom file) */ void uWriterBase::setFieldsNames(const std::vector<std::string>& fieldsNames) { if (fieldsNames.size() == 0) { throw no_fields_names() << string_error("fieldsNames vector is empty"); } m_fieldsNames = fieldsNames; }
void uParserBed::_validateColumnNumber(int numberOfColumn) const { if (numberOfColumn < 3 || numberOfColumn > 6) { uParserBed_invalid_number_of_columns e; e << string_error("uParserBed: Invalid number of columns."); throw e; } }
static int string_escape(parser_t &parser, io_streams_t &streams, int argc, wchar_t **argv) { const wchar_t *short_options = L"n"; const struct woption long_options[] = { { L"no-quoted", no_argument, 0, 'n' }, { 0, 0, 0, 0 } }; escape_flags_t flags = ESCAPE_ALL; 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 'n': flags |= ESCAPE_NO_QUOTED; break; case '?': string_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]); return BUILTIN_STRING_ERROR; } } int i = w.woptind; if (string_args_from_stdin(streams) && argc > i) { string_error(streams, BUILTIN_ERR_TOO_MANY_ARGUMENTS, argv[0]); return BUILTIN_STRING_ERROR; } int nesc = 0; wcstring storage; const wchar_t *arg; while ((arg = string_get_arg(&i, argv, &storage, streams)) != 0) { streams.out.append(escape(arg, flags)); streams.out.append(L'\n'); nesc++; } return (nesc > 0) ? BUILTIN_STRING_OK : BUILTIN_STRING_NONE; }
/// A return value of true means all is well (even if no replacements were performed), false /// indicates an unrecoverable error. bool regex_replacer_t::replace_matches(const wchar_t *arg) { if (regex.code == 0) { // pcre2_compile() failed return false; } uint32_t options = PCRE2_SUBSTITUTE_OVERFLOW_LENGTH | PCRE2_SUBSTITUTE_EXTENDED | (opts.all ? PCRE2_SUBSTITUTE_GLOBAL : 0); size_t arglen = wcslen(arg); PCRE2_SIZE bufsize = (arglen == 0) ? 16 : 2 * arglen; wchar_t *output = (wchar_t *)malloc(sizeof(wchar_t) * bufsize); int pcre2_rc; bool done = false; while (!done) { if (output == NULL) { DIE_MEM(); } PCRE2_SIZE outlen = bufsize; pcre2_rc = pcre2_substitute(regex.code, PCRE2_SPTR(arg), arglen, 0, // start offset options, regex.match, 0, // match context PCRE2_SPTR(replacement.c_str()), PCRE2_ZERO_TERMINATED, (PCRE2_UCHAR *)output, &outlen); if (pcre2_rc != PCRE2_ERROR_NOMEMORY || bufsize >= outlen) { done = true; } else { bufsize = outlen; // cppcheck-suppress memleakOnRealloc output = (wchar_t *)realloc(output, sizeof(wchar_t) * bufsize); } } bool rc = true; if (pcre2_rc < 0) { string_error(streams, _(L"%ls: Regular expression substitute error: %ls\n"), argv0, pcre2_strerror(pcre2_rc).c_str()); rc = false; } else { if (!opts.quiet) { streams.out.append(output); streams.out.append(L'\n'); } total_replaced += pcre2_rc; } free(output); return rc; }
void uParserBed::_parseHeader() { std::string unformatedHeader; /**< We parse a line at a time until we get a valid token, then we return the token back in the stream */ do { char line[4096]; if (m_pIostream->getline(line, 4096)) { std::stringstream token_infos; _convertLineToTokenInfosBed(line, token_infos); try { uToken token(token_infos); /**< When we have a valid token, we consider that all the header have beed fetched */ /**< We put token back into stream, and exit function */ _pushBackLine(line); m_headerParsed = true; } /**< If there is a throw, we are not at the first valid token line, so we add line to header object */ catch(invalid_uToken_throw& e) { } catch(invalid_value_throw& e) { } if (m_headerParsed == false) { std::string s(line); unformatedHeader += s; unformatedHeader += '\n'; } } else { std::cout << "Reached end of file" << std::endl; #ifdef DEBUG std::cerr << "Reached end of file." << std::endl; #endif end_of_file_throw e; e << string_error("Reached end of file."); throw e; } } while(m_headerParsed == false); m_headerData.setUnformatedHeader(unformatedHeader); }
/** \brief Produce a token with next entry in the file/stream. * \return uToken containing the infos of the next entry. */ uToken uParserCustom::getNextEntry() { char line[4096]; if (m_pIostream->getline(line, 4096)) { /**< We start by fetching the infos from the line */ m_rawString=line; std::stringstream token_infos; _convertLineToTokenInfosCustom(line, token_infos); /**< We try to create a token with the infos that were fetched from the line */ /**< If it doesn't work andit's the first token, we don't throw an error. Instead, we try again with another line */ try { uToken token(token_infos, true); return token; } catch(invalid_uToken_throw& e) { throw e; } catch(invalid_value_throw& e) { throw e; } } else { #ifdef DEBUG std::cerr << "Reached end of file." << std::endl; #endif end_of_file_throw e; e << string_error("Reached end of file."); throw e; } std::cerr <<"Fatal error in getNextEntry() from Custom parser, should not reach here." <<std::endl; abort(); }
bool replace_matches(const wchar_t *arg) { // A return value of true means all is well (even if no replacements // were performed), false indicates an unrecoverable error. if (regex.code == 0) { // pcre2_compile() failed return false; } uint32_t options = opts.all ? PCRE2_SUBSTITUTE_GLOBAL : 0; size_t arglen = wcslen(arg); PCRE2_SIZE bufsize = (arglen == 0) ? 16 : 2 * arglen; wchar_t *output = (wchar_t *)malloc(sizeof(wchar_t) * bufsize); if (output == 0) { DIE_MEM(); } int pcre2_rc = 0; for (;;) { PCRE2_SIZE outlen = bufsize; pcre2_rc = pcre2_substitute( regex.code, PCRE2_SPTR(arg), arglen, 0, // start offset options, regex.match, 0, // match context PCRE2_SPTR(replacement.c_str()), PCRE2_ZERO_TERMINATED, (PCRE2_UCHAR *)output, &outlen); if (pcre2_rc == PCRE2_ERROR_NOMEMORY) { if (bufsize < MAX_REPLACE_SIZE) { bufsize = std::min(2 * bufsize, MAX_REPLACE_SIZE); output = (wchar_t *)realloc(output, sizeof(wchar_t) * bufsize); if (output == 0) { DIE_MEM(); } continue; } string_error(streams, _(L"%ls: Replacement string too large\n"), argv0); free(output); return false; } break; } bool rc = true; if (pcre2_rc < 0) { string_error(streams, _(L"%ls: Regular expression substitute error: %ls\n"), argv0, pcre2_strerror(pcre2_rc).c_str()); rc = false; } else { if (!opts.quiet) { streams.out.append(output); streams.out.append(L'\n'); } total_replaced += pcre2_rc; } free(output); return rc; }
void BtrfsDeviceAdd::AddDevice(HWND hwndDlg) { wstring mess, title; NTSTATUS Status; UNICODE_STRING vn; OBJECT_ATTRIBUTES attr; IO_STATUS_BLOCK iosb; if (!sel) { EndDialog(hwndDlg, 0); return; } if (sel->fstype != L"") { wstring s; if (!load_string(module, IDS_ADD_DEVICE_CONFIRMATION_FS, s)) throw last_error(GetLastError()); wstring_sprintf(mess, s, sel->fstype.c_str()); } else { if (!load_string(module, IDS_ADD_DEVICE_CONFIRMATION, mess)) throw last_error(GetLastError()); } if (!load_string(module, IDS_CONFIRMATION_TITLE, title)) throw last_error(GetLastError()); if (MessageBoxW(hwndDlg, mess.c_str(), title.c_str(), MB_YESNO) != IDYES) return; win_handle h = CreateFileW(cmdline, FILE_TRAVERSE | FILE_READ_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, nullptr); if (h == INVALID_HANDLE_VALUE) throw last_error(GetLastError()); { nt_handle h2; vn.Length = vn.MaximumLength = (uint16_t)(sel->pnp_name.length() * sizeof(WCHAR)); vn.Buffer = (WCHAR*)sel->pnp_name.c_str(); InitializeObjectAttributes(&attr, &vn, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, nullptr, nullptr); Status = NtOpenFile(&h2, FILE_GENERIC_READ | FILE_GENERIC_WRITE, &attr, &iosb, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_ALERT); if (!NT_SUCCESS(Status)) throw ntstatus_error(Status); if (!sel->is_disk) { Status = NtFsControlFile(h2, nullptr, nullptr, nullptr, &iosb, FSCTL_LOCK_VOLUME, nullptr, 0, nullptr, 0); if (!NT_SUCCESS(Status)) throw string_error(IDS_LOCK_FAILED, Status); } Status = NtFsControlFile(h, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_ADD_DEVICE, &h2, sizeof(HANDLE), nullptr, 0); if (!NT_SUCCESS(Status)) throw ntstatus_error(Status); if (!sel->is_disk) { Status = NtFsControlFile(h2, nullptr, nullptr, nullptr, &iosb, FSCTL_DISMOUNT_VOLUME, nullptr, 0, nullptr, 0); if (!NT_SUCCESS(Status)) throw ntstatus_error(Status); Status = NtFsControlFile(h2, nullptr, nullptr, nullptr, &iosb, FSCTL_UNLOCK_VOLUME, nullptr, 0, nullptr, 0); if (!NT_SUCCESS(Status)) throw ntstatus_error(Status); } } EndDialog(hwndDlg, 0); }
void BtrfsDeviceAdd::populate_device_tree(HWND tree) { HWND hwnd = GetParent(tree); unsigned int i; ULONG last_disk_num = 0xffffffff; HTREEITEM diskitem; NTSTATUS Status; OBJECT_ATTRIBUTES attr; UNICODE_STRING us; IO_STATUS_BLOCK iosb; btrfs_filesystem* bfs = nullptr; static WCHAR btrfs[] = L"\\Btrfs"; device_list.clear(); { nt_handle mountmgr; RtlInitUnicodeString(&us, MOUNTMGR_DEVICE_NAME); InitializeObjectAttributes(&attr, &us, 0, nullptr, nullptr); Status = NtOpenFile(&mountmgr, FILE_GENERIC_READ | FILE_GENERIC_WRITE, &attr, &iosb, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_ALERT); if (!NT_SUCCESS(Status)) throw string_error(IDS_CANT_OPEN_MOUNTMGR); { nt_handle btrfsh; us.Length = us.MaximumLength = (uint16_t)(wcslen(btrfs) * sizeof(WCHAR)); us.Buffer = btrfs; InitializeObjectAttributes(&attr, &us, 0, nullptr, nullptr); Status = NtOpenFile(&btrfsh, SYNCHRONIZE | FILE_READ_ATTRIBUTES, &attr, &iosb, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SYNCHRONOUS_IO_ALERT); if (NT_SUCCESS(Status)) { ULONG bfssize = 0; do { bfssize += 1024; if (bfs) free(bfs); bfs = (btrfs_filesystem*)malloc(bfssize); Status = NtDeviceIoControlFile(btrfsh, nullptr, nullptr, nullptr, &iosb, IOCTL_BTRFS_QUERY_FILESYSTEMS, nullptr, 0, bfs, bfssize); if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW) { free(bfs); bfs = nullptr; break; } } while (Status == STATUS_BUFFER_OVERFLOW); if (bfs && bfs->num_devices == 0) { // no mounted filesystems found free(bfs); bfs = nullptr; } } } find_devices(hwnd, &GUID_DEVINTERFACE_DISK, mountmgr, device_list); find_devices(hwnd, &GUID_DEVINTERFACE_VOLUME, mountmgr, device_list); find_devices(hwnd, &GUID_DEVINTERFACE_HIDDEN_VOLUME, mountmgr, device_list); } sort(device_list.begin(), device_list.end(), sort_devices); for (i = 0; i < device_list.size(); i++) { if (!device_list[i].ignore) { TVINSERTSTRUCTW tis; HTREEITEM item; wstring name, size; if (device_list[i].disk_num != 0xffffffff && device_list[i].disk_num == last_disk_num) tis.hParent = diskitem; else tis.hParent = TVI_ROOT; tis.hInsertAfter = TVI_LAST; tis.itemex.mask = TVIF_TEXT | TVIF_STATE | TVIF_PARAM; tis.itemex.state = TVIS_EXPANDED; tis.itemex.stateMask = TVIS_EXPANDED; if (device_list[i].disk_num != 0xffffffff) { wstring t; if (!load_string(module, device_list[i].part_num != 0 ? IDS_PARTITION : IDS_DISK_NUM, t)) throw last_error(GetLastError()); wstring_sprintf(name, t, device_list[i].part_num != 0 ? device_list[i].part_num : device_list[i].disk_num); } else name = device_list[i].pnp_name; // match child Btrfs devices to their parent if (bfs && device_list[i].drive == L"" && device_list[i].fstype == L"Btrfs") { btrfs_filesystem* bfs2 = bfs; while (true) { if (RtlCompareMemory(&bfs2->uuid, &device_list[i].fs_uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) { ULONG j, k; btrfs_filesystem_device* dev; for (j = 0; j < bfs2->num_devices; j++) { if (j == 0) dev = &bfs2->device; else dev = (btrfs_filesystem_device*)((uint8_t*)dev + offsetof(btrfs_filesystem_device, name[0]) + dev->name_length); if (RtlCompareMemory(&device_list[i].dev_uuid, &device_list[i].dev_uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) { for (k = 0; k < device_list.size(); k++) { if (k != i && device_list[k].fstype == L"Btrfs" && device_list[k].drive != L"" && RtlCompareMemory(&device_list[k].fs_uuid, &device_list[i].fs_uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) { device_list[i].drive = device_list[k].drive; break; } } device_list[i].multi_device = bfs2->num_devices > 1; break; } } break; } if (bfs2->next_entry != 0) bfs2 = (btrfs_filesystem*)((uint8_t*)bfs2 + bfs2->next_entry); else break; } } name += L" ("; if (device_list[i].friendly_name != L"") { name += device_list[i].friendly_name; name += L", "; } if (device_list[i].drive != L"") { name += device_list[i].drive; name += L", "; } if (device_list[i].fstype != L"") { name += device_list[i].fstype; name += L", "; } format_size(device_list[i].size, size, false); name += size; name += L")"; tis.itemex.pszText = (WCHAR*)name.c_str(); tis.itemex.cchTextMax = name.length(); tis.itemex.lParam = (LPARAM)&device_list[i]; item = (HTREEITEM)SendMessageW(tree, TVM_INSERTITEMW, 0, (LPARAM)&tis); if (!item) throw string_error(IDS_TVM_INSERTITEM_FAILED); if (device_list[i].part_num == 0) { diskitem = item; last_disk_num = device_list[i].disk_num; } } } }
static int string_sub(parser_t &parser, io_streams_t &streams, int argc, wchar_t **argv) { const wchar_t *short_options = L":l:qs:"; const struct woption long_options[] = {{L"length", required_argument, 0, 'l'}, {L"quiet", no_argument, 0, 'q'}, {L"start", required_argument, 0, 's'}, {0, 0, 0, 0}}; long start = 0; long length = -1; bool quiet = false; wgetopter_t w; wchar_t *endptr = NULL; for (;;) { int c = w.wgetopt_long(argc, argv, short_options, long_options, 0); if (c == -1) { break; } switch (c) { case 0: { break; } case 'l': { errno = 0; length = wcstol(w.woptarg, &endptr, 10); if (*endptr != L'\0' || (errno != 0 && errno != ERANGE)) { string_error(streams, BUILTIN_ERR_NOT_NUMBER, argv[0], w.woptarg); return BUILTIN_STRING_ERROR; } if (length < 0 || errno == ERANGE) { string_error(streams, _(L"%ls: Invalid length value '%ls'\n"), argv[0], w.woptarg); return BUILTIN_STRING_ERROR; } break; } case 'q': { quiet = true; break; } case 's': { errno = 0; start = wcstol(w.woptarg, &endptr, 10); if (*endptr != L'\0' || (errno != 0 && errno != ERANGE)) { string_error(streams, BUILTIN_ERR_NOT_NUMBER, argv[0], w.woptarg); return BUILTIN_STRING_ERROR; } if (start == 0 || start == LONG_MIN || errno == ERANGE) { string_error(streams, _(L"%ls: Invalid start value '%ls'\n"), argv[0], w.woptarg); return BUILTIN_STRING_ERROR; } 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; if (string_args_from_stdin(streams) && argc > i) { string_error(streams, BUILTIN_ERR_TOO_MANY_ARGUMENTS, argv[0]); return BUILTIN_STRING_ERROR; } int nsub = 0; const wchar_t *arg; wcstring storage; while ((arg = string_get_arg(&i, argv, &storage, streams)) != NULL) { typedef wcstring::size_type size_type; size_type pos = 0; size_type count = wcstring::npos; wcstring s(arg); if (start > 0) { pos = static_cast<size_type>(start - 1); } else if (start < 0) { assert(start != LONG_MIN); // checked above size_type n = static_cast<size_type>(-start); pos = n > s.length() ? 0 : s.length() - n; } if (pos > s.length()) { pos = s.length(); } if (length >= 0) { count = static_cast<size_type>(length); } // Note that std::string permits count to extend past end of string. if (!quiet) { streams.out.append(s.substr(pos, count)); streams.out.append(L'\n'); } nsub++; } return nsub > 0 ? BUILTIN_STRING_OK : BUILTIN_STRING_NONE; }
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; }
static int string_replace(parser_t &parser, io_streams_t &streams, int argc, wchar_t **argv) { const wchar_t *short_options = L"aiqr"; const struct woption long_options[] = {{L"all", no_argument, 0, 'a'}, {L"ignore-case", no_argument, 0, 'i'}, {L"quiet", no_argument, 0, 'q'}, {L"regex", no_argument, 0, 'r'}, {0, 0, 0, 0}}; replace_options_t opts; bool regex = false; wgetopter_t w; for (;;) { int opt = w.wgetopt_long(argc, argv, short_options, long_options, 0); if (opt == -1) { break; } switch (opt) { case 0: { break; } case 'a': { opts.all = true; break; } case 'i': { opts.ignore_case = true; break; } case 'q': { opts.quiet = true; break; } case 'r': { regex = true; break; } 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 *pattern, *replacement; if ((pattern = string_get_arg_argv(&i, argv)) == 0) { string_error(streams, STRING_ERR_MISSING, argv[0]); return BUILTIN_STRING_ERROR; } if ((replacement = string_get_arg_argv(&i, argv)) == 0) { string_error(streams, STRING_ERR_MISSING, argv[0]); return BUILTIN_STRING_ERROR; } if (string_args_from_stdin(streams) && argc > i) { string_error(streams, BUILTIN_ERR_TOO_MANY_ARGUMENTS, argv[0]); return BUILTIN_STRING_ERROR; } string_replacer_t *replacer; if (regex) { replacer = new regex_replacer_t(argv[0], pattern, replacement, opts, streams); } else { replacer = new literal_replacer_t(argv[0], pattern, replacement, opts, streams); } const wchar_t *arg; wcstring storage; while ((arg = string_get_arg(&i, argv, &storage, streams)) != 0) { if (!replacer->replace_matches(arg)) { delete replacer; return BUILTIN_STRING_ERROR; } } int rc = replacer->replace_count() > 0 ? BUILTIN_STRING_OK : BUILTIN_STRING_NONE; delete replacer; return rc; }
static void string_unknown_option(parser_t &parser, io_streams_t &streams, const wchar_t *subcmd, const wchar_t *opt) { string_error(streams, BUILTIN_ERR_UNKNOWN, subcmd, opt); builtin_print_help(parser, streams, L"string", streams.err); }
/** \brief Initialize the uParserCustom object (default initialization of uParserCustom is not valid). */ void uParserCustom::init(const std::string& filename, bool header) { throw uParser_exception_base()<<string_error("Invalid constructor call for Custom Format"); }
static int string_join(parser_t &parser, io_streams_t &streams, int argc, wchar_t **argv) { const wchar_t *short_options = L"q"; const struct woption long_options[] = {{L"quiet", no_argument, 0, 'q'}, {0, 0, 0, 0}}; bool quiet = false; wgetopter_t w; for (;;) { int opt = w.wgetopt_long(argc, argv, short_options, long_options, 0); if (opt == -1) { break; } switch (opt) { case 0: { break; } case 'q': { quiet = true; break; } 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)) == 0) { string_error(streams, STRING_ERR_MISSING, argv[0]); return BUILTIN_STRING_ERROR; } if (string_args_from_stdin(streams) && argc > i) { string_error(streams, BUILTIN_ERR_TOO_MANY_ARGUMENTS, argv[0]); return BUILTIN_STRING_ERROR; } int nargs = 0; const wchar_t *arg; wcstring storage; while ((arg = string_get_arg(&i, argv, &storage, streams)) != 0) { if (!quiet) { if (nargs > 0) { streams.out.append(sep); } streams.out.append(arg); } nargs++; } if (nargs > 0 && !quiet) { streams.out.push_back(L'\n'); } return nargs > 1 ? BUILTIN_STRING_OK : BUILTIN_STRING_NONE; }
static int string_trim(parser_t &parser, io_streams_t &streams, int argc, wchar_t **argv) { const wchar_t *short_options = L":c:lqr"; const struct woption long_options[] = {{L"chars", required_argument, 0, 'c'}, {L"left", no_argument, 0, 'l'}, {L"quiet", no_argument, 0, 'q'}, {L"right", no_argument, 0, 'r'}, {0, 0, 0, 0}}; bool do_left = 0, do_right = 0; bool quiet = false; wcstring chars_to_trim = L" \f\n\r\t"; 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 'c': { chars_to_trim = w.woptarg; break; } case 'l': { do_left = true; break; } case 'q': { quiet = true; break; } case 'r': { do_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; if (string_args_from_stdin(streams) && argc > i) { string_error(streams, BUILTIN_ERR_TOO_MANY_ARGUMENTS, argv[0]); return BUILTIN_STRING_ERROR; } // If neither left or right is specified, we do both. if (!do_left && !do_right) { do_left = true; do_right = true; } const wchar_t *arg; size_t ntrim = 0; wcstring argstr; wcstring storage; while ((arg = string_get_arg(&i, argv, &storage, streams)) != 0) { argstr = arg; // Begin and end are respectively the first character to keep on the left, and first // character to trim on the right. The length is thus end - start. size_t begin = 0, end = argstr.size(); if (do_right) { size_t last_to_keep = argstr.find_last_not_of(chars_to_trim); end = (last_to_keep == wcstring::npos) ? 0 : last_to_keep + 1; } if (do_left) { size_t first_to_keep = argstr.find_first_not_of(chars_to_trim); begin = (first_to_keep == wcstring::npos ? end : first_to_keep); } assert(begin <= end && end <= argstr.size()); ntrim += argstr.size() - (end - begin); if (!quiet) { streams.out.append(wcstring(argstr, begin, end - begin)); streams.out.append(L'\n'); } } return ntrim > 0 ? BUILTIN_STRING_OK : BUILTIN_STRING_NONE; }
static int string_match(parser_t &parser, io_streams_t &streams, int argc, wchar_t **argv) { const wchar_t *short_options = L"ainvqr"; const struct woption long_options[] = {{L"all", no_argument, 0, 'a'}, {L"ignore-case", no_argument, 0, 'i'}, {L"index", no_argument, 0, 'n'}, {L"invert", no_argument, 0, 'v'}, {L"quiet", no_argument, 0, 'q'}, {L"regex", no_argument, 0, 'r'}, {0, 0, 0, 0}}; match_options_t opts; bool regex = false; wgetopter_t w; for (;;) { int opt = w.wgetopt_long(argc, argv, short_options, long_options, 0); if (opt == -1) { break; } switch (opt) { case 0: { break; } case 'a': { opts.all = true; break; } case 'i': { opts.ignore_case = true; break; } case 'n': { opts.index = true; break; } case 'v': { opts.invert_match = true; break; } case 'q': { opts.quiet = true; break; } case 'r': { regex = true; break; } 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 *pattern; if ((pattern = string_get_arg_argv(&i, argv)) == 0) { string_error(streams, STRING_ERR_MISSING, argv[0]); return BUILTIN_STRING_ERROR; } if (string_args_from_stdin(streams) && argc > i) { string_error(streams, BUILTIN_ERR_TOO_MANY_ARGUMENTS, argv[0]); return BUILTIN_STRING_ERROR; } std::unique_ptr<string_matcher_t> matcher; if (regex) { matcher = make_unique<pcre2_matcher_t>(argv[0], pattern, opts, streams); } else { matcher = make_unique<wildcard_matcher_t>(argv[0], pattern, opts, streams); } const wchar_t *arg; wcstring storage; while ((arg = string_get_arg(&i, argv, &storage, streams)) != 0) { if (!matcher->report_matches(arg)) { return BUILTIN_STRING_ERROR; } } int rc = matcher->match_count() > 0 ? BUILTIN_STRING_OK : BUILTIN_STRING_NONE; return rc; }
/** \brief Initialize the uParserCustom object (default initialization of uParserCustom is not valid). */ void uParserCustom::init(std::istream* stream, bool header) { throw uParser_exception_base()<<string_error("Invalid constructor call for Custom Format"); }