diff --git a/README.md b/README.md index f90875f2..a99b2a0f 100644 --- a/README.md +++ b/README.md @@ -5459,7 +5459,7 @@ in markdown: - ugrep 7.1.0 November 19, 2024 UGREP(1) + ugrep 7.1.1 November 29, 2024 UGREP(1) 🔝 [Back to table of contents](#toc) diff --git a/bin/win32/ug.exe b/bin/win32/ug.exe index 1ca1af8c..d0565550 100755 Binary files a/bin/win32/ug.exe and b/bin/win32/ug.exe differ diff --git a/bin/win32/ugrep-indexer.exe b/bin/win32/ugrep-indexer.exe index 98879179..4faeecac 100755 Binary files a/bin/win32/ugrep-indexer.exe and b/bin/win32/ugrep-indexer.exe differ diff --git a/bin/win32/ugrep.exe b/bin/win32/ugrep.exe index 1ca1af8c..d0565550 100755 Binary files a/bin/win32/ugrep.exe and b/bin/win32/ugrep.exe differ diff --git a/bin/win64/ug.exe b/bin/win64/ug.exe index 36f8942a..fb2c5a0f 100755 Binary files a/bin/win64/ug.exe and b/bin/win64/ug.exe differ diff --git a/bin/win64/ugrep-indexer.exe b/bin/win64/ugrep-indexer.exe index 6457bb00..6190c621 100755 Binary files a/bin/win64/ugrep-indexer.exe and b/bin/win64/ugrep-indexer.exe differ diff --git a/bin/win64/ugrep.exe b/bin/win64/ugrep.exe index 36f8942a..fb2c5a0f 100755 Binary files a/bin/win64/ugrep.exe and b/bin/win64/ugrep.exe differ diff --git a/configure b/configure index 1e574943..56653bf1 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.72 for ugrep 7.1.0. +# Generated by GNU Autoconf 2.72 for ugrep 7.1.1. # # Report bugs to . # @@ -606,8 +606,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='ugrep' PACKAGE_TARNAME='ugrep' -PACKAGE_VERSION='7.1.0' -PACKAGE_STRING='ugrep 7.1.0' +PACKAGE_VERSION='7.1.1' +PACKAGE_STRING='ugrep 7.1.1' PACKAGE_BUGREPORT='https://github.com/Genivia/ugrep/issues' PACKAGE_URL='https://ugrep.com' @@ -1382,7 +1382,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -'configure' configures ugrep 7.1.0 to adapt to many kinds of systems. +'configure' configures ugrep 7.1.1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1453,7 +1453,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of ugrep 7.1.0:";; + short | recursive ) echo "Configuration of ugrep 7.1.1:";; esac cat <<\_ACEOF @@ -1630,7 +1630,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -ugrep configure 7.1.0 +ugrep configure 7.1.1 generated by GNU Autoconf 2.72 Copyright (C) 2023 Free Software Foundation, Inc. @@ -2184,7 +2184,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by ugrep $as_me 7.1.0, which was +It was created by ugrep $as_me 7.1.1, which was generated by GNU Autoconf 2.72. Invocation command line was $ $0$ac_configure_args_raw @@ -3694,7 +3694,7 @@ fi # Define the identity of the package. PACKAGE='ugrep' - VERSION='7.1.0' + VERSION='7.1.1' printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h @@ -11790,7 +11790,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by ugrep $as_me 7.1.0, which was +This file was extended by ugrep $as_me 7.1.1, which was generated by GNU Autoconf 2.72. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -11863,7 +11863,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -ugrep config.status 7.1.0 +ugrep config.status 7.1.1 configured by $0, generated by GNU Autoconf 2.72, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 43c37d20..72b48b04 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT([ugrep],[7.1.0],[https://github.com/Genivia/ugrep/issues],[ugrep],[https://ugrep.com]) +AC_INIT([ugrep],[7.1.1],[https://github.com/Genivia/ugrep/issues],[ugrep],[https://ugrep.com]) AM_INIT_AUTOMAKE([foreign subdir-objects dist-xz no-dist-gzip]) AC_CONFIG_HEADERS([config.h]) AC_COPYRIGHT([Copyright (C) 2019-2024 Robert van Engelen, Genivia Inc.]) diff --git a/lib/convert.cpp b/lib/convert.cpp index 37f2988b..6abea45b 100644 --- a/lib/convert.cpp +++ b/lib/convert.cpp @@ -120,7 +120,7 @@ static std::string unicode_class(const char *s, int esc, convert_flag_type flags { if (wc[0] > 0xDFFF) { - // exclude U+D800 to U+DFFF + // exclude surrogates U+D800 to U+DFFF regex.assign(utf8(0x00, 0xD7FF, esc, par, !(flags & convert_flag::permissive))).push_back('|'); if (wc[0] > 0xE000) regex.append(utf8(0xE000, wc[0] - 1, esc, par, !(flags & convert_flag::permissive))).push_back('|'); @@ -136,7 +136,7 @@ static std::string unicode_class(const char *s, int esc, convert_flag_type flags { if (last <= 0xD800 && wc[0] > 0xDFFF) { - // exclude U+D800 to U+DFFF + // exclude surrogates U+D800 to U+DFFF if (last < 0xD800) regex.append(utf8(last, 0xD7FF, esc, par, !(flags & convert_flag::permissive))).push_back('|'); if (wc[0] > 0xE000) @@ -152,7 +152,7 @@ static std::string unicode_class(const char *s, int esc, convert_flag_type flags { if (last <= 0xD800) { - // exclude U+D800 to U+DFFF + // exclude surrogates U+D800 to U+DFFF if (last < 0xD800) regex.append(utf8(last, 0xD7FF, esc, par, !(flags & convert_flag::permissive))).push_back('|'); regex.append(utf8(0xE000, 0x10FFFF, esc, par, !(flags & convert_flag::permissive))).push_back('|'); @@ -402,7 +402,7 @@ static std::string convert_ranges(const char *pattern, size_t pos, ORanges& { if (ranges.find('\n') != ranges.end()) nl = true; - if (is_modified(mod, 'i')) + if (is_modified(mod, 'i') || (is_modified(mod, 'a') && is_modified(mod, 'u') && ranges.hi() > 0x7F)) convert_anycase_ranges(ranges); if (is_modified(mod, 'u') && ranges.hi() > 0x7F) return convert_unicode_ranges(ranges, flags, signature, par); @@ -551,7 +551,7 @@ static void insert_escape_class(const char *pattern, size_t pos, convert_flag_ty wc = Posix::range(name); if (wc == NULL) throw regex_error(regex_error::invalid_class, pattern, pos); - if (std::islower(static_cast(c))) + if (c >= 'a' && c <= 'z') { if (wc[0] <= '\n' && wc[1] >= '\n' && (flags & convert_flag::notnewline)) { @@ -573,7 +573,7 @@ static void insert_escape_class(const char *pattern, size_t pos, convert_flag_ty { if (last <= 0xD800 && wc[0] > 0xDFFF) { - // exclude U+D800 to U+DFFF + // exclude surrogates U+D800 to U+DFFF if (last < 0xD800) ranges.insert(last, 0xD7FF); if (wc[0] > 0xE000) @@ -590,7 +590,7 @@ static void insert_escape_class(const char *pattern, size_t pos, convert_flag_ty { if (last <= 0xD800) { - // exclude U+D800 to U+DFFF + // exclude surrogates U+D800 to U+DFFF if (last < 0xD800) ranges.insert(last, 0xD7FF); ranges.insert(0xE000, 0x10FFFF); @@ -697,7 +697,7 @@ static int insert_escape(const char *pattern, size_t len, size_t& pos, convert_f { if (last <= 0xD800 && wc[0] > 0xDFFF) { - // exclude U+D800 to U+DFFF + // exclude surrogates U+D800 to U+DFFF if (last < 0xD800) ranges.insert(last, 0xD7FF); if (wc[0] > 0xE000) @@ -714,7 +714,7 @@ static int insert_escape(const char *pattern, size_t len, size_t& pos, convert_f { if (last <= 0xD800) { - // exclude U+D800 to U+DFFF + // exclude surrogates U+D800 to U+DFFF if (last < 0xD800) ranges.insert(last, 0xD7FF); ranges.insert(0xE000, 0x10FFFF); @@ -871,6 +871,9 @@ static void subtract_list(const char *pattern, size_t len, size_t& pos, convert_ { ++pos; insert_list(pattern, len, pos, flags, mod, subtract, macros); + // always convert case-insensitive Unicode negated character classes (modifier 'a') + if (is_modified(mod, 'a')) + convert_anycase_ranges(subtract); ranges -= subtract; } else if (pattern[pos] == '{' && macros != NULL) @@ -881,6 +884,9 @@ static void subtract_list(const char *pattern, size_t len, size_t& pos, convert_ throw regex_error(regex_error::invalid_class_range, pattern, pos); size_t subpos = 1; insert_list(list.c_str(), list.size(), subpos, flags, mod, subtract, macros); + // always convert case-insensitive Unicode negated character classes (modifier 'a') + if (is_modified(mod, 'a')) + convert_anycase_ranges(subtract); ranges -= subtract; if (subpos + 1 < list.size()) throw regex_error(regex_error::invalid_class_range, pattern, pos); @@ -919,7 +925,8 @@ static void extend_list(const char *pattern, size_t len, size_t& pos, convert_fl static void negate_list(convert_flag_type flags, const std::map& mod, ORanges& ranges) { - if (is_modified(mod, 'i')) + // always convert case-insensitive Unicode negated character classes (modifier 'a') + if (is_modified(mod, 'a')) convert_anycase_ranges(ranges); if (is_modified(mod, 'u')) { @@ -959,6 +966,8 @@ static void insert_list(const char *pattern, size_t len, size_t& pos, convert_fl c = insert_escape(pattern, len, pos, flags, mod, ranges); if (range) { + if (pc >= 'a' && pc <= 'z' && is_modified(mod, 'a')) + pc = lowercase(pc); if (c == -1 || pc > c) throw regex_error(regex_error::invalid_class_range, pattern, pos); ranges.insert(pc, c); @@ -1042,6 +1051,8 @@ static void insert_list(const char *pattern, size_t len, size_t& pos, convert_fl } if (range) { + if (pc >= 'a' && pc <= 'z' && is_modified(mod, 'a')) + pc = uppercase(pc); if (c == -1 || pc > c) throw regex_error(regex_error::invalid_class_range, pattern, pos); ranges.insert(pc, c); @@ -1098,7 +1109,7 @@ static void convert_escape_char(const char *pattern, size_t len, size_t& loc, si else if (std::strchr(regex_meta, c) == NULL) { char buf[3] = { '^', static_cast(lowercase(c)), '\0' }; - bool invert = std::isupper(static_cast(c)) != 0; + bool invert = (c >= 'A' && c <= 'Z'); if (c == 'n' || (invert && strchr("DHLUWX", c) != NULL)) nl = true; const char *name = buf + !invert; @@ -1512,6 +1523,8 @@ std::string convert(const char *pattern, const char *signature, convert_flag_typ { if (supports_modifier(signature, pattern[k])) { + if (pattern[k] == 'i') + mod[lev].push_back('a'); // convert case-insensitive Unicode negated character classes mods.push_back(pattern[k]); } else if (pattern[k] == 'm') @@ -1526,11 +1539,19 @@ std::string convert(const char *pattern, const char *signature, convert_flag_typ else { if (supports_modifier(signature, pattern[k])) + { + if (pattern[k] == 'i') + mod[lev].push_back('A'); unmods.push_back(pattern[k]); + } else if (pattern[k] == 'm') + { throw regex_error(regex_error::invalid_modifier, pattern, pos); + } else + { disable_modifier(pattern[k], pattern, k, mod, lev); + } } ++k; } @@ -1724,16 +1745,28 @@ std::string convert(const char *pattern, const char *signature, convert_flag_typ else if (!invert) { if (supports_modifier(signature, pattern[k])) + { + if (pattern[k] == 'i') + mod[lev].push_back('a'); // convert case-insensitive Unicode negated character classes mods.push_back(pattern[k]); + } else + { enable_modifier(pattern[k], pattern, k, mod, lev); + } } else { if (supports_modifier(signature, pattern[k])) + { + if (pattern[k] == 'i') + mod[lev].push_back('A'); unmods.push_back(pattern[k]); + } else + { disable_modifier(pattern[k], pattern, k, mod, lev); + } } ++k; } @@ -2017,7 +2050,6 @@ std::string convert(const char *pattern, const char *signature, convert_flag_typ ++pos; loc = pos; const std::string& subregex = expand(macros, pattern, len, pos); - int c; if ((flags & convert_flag::lex) && pos + 5 < len && pattern[pos + 1] == '{' && ((c = pattern[pos + 2]) == '+' || c == '|' || c == '&' || c == '-') && pattern[pos + 3] == '}') { size_t subpos = 0; diff --git a/lib/matcher.cpp b/lib/matcher.cpp index efccefc8..fe544bab 100644 --- a/lib/matcher.cpp +++ b/lib/matcher.cpp @@ -3451,7 +3451,7 @@ bool Matcher::advance_string_bm(size_t loc) } else { - size_t k = bms[static_cast(*q)]; + k = bms[static_cast(*q)]; if (p + k > t + bmd) s += k - (t - p); else @@ -3510,7 +3510,7 @@ bool Matcher::advance_string_bm_pma(size_t loc) } else { - size_t k = bms[static_cast(*q)]; + k = bms[static_cast(*q)]; if (p + k > t + bmd) s += k - (t - p); else @@ -3570,7 +3570,7 @@ bool Matcher::advance_string_bm_pmh(size_t loc) } else { - size_t k = bms[static_cast(*q)]; + k = bms[static_cast(*q)]; if (p + k > t + bmd) s += k - (t - p); else diff --git a/lib/pattern.cpp b/lib/pattern.cpp index 4f5ae3d8..d6ca96aa 100644 --- a/lib/pattern.cpp +++ b/lib/pattern.cpp @@ -795,9 +795,9 @@ void Pattern::parse( bol_ = false; bool quote = false; #ifdef WITH_TREE_DFA - DFA::State *t = tfa_.start(); + DFA::State *r = tfa_.start(); #else - Tree::Node *t = tfa_.root(); + Tree::Node *r = tfa_.root(); #endif while (loc < end) { @@ -830,14 +830,14 @@ void Pattern::parse( c = lowercase(c); } #ifdef WITH_TREE_DFA - DFA::State::Edges::iterator i = t->edges.find(c); - if (i == t->edges.end()) + DFA::State::Edges::iterator i = r->edges.find(c); + if (i == r->edges.end()) { if (last_state == NULL) - last_state = t; // t points to the tree DFA start state + last_state = r; // r points to the tree DFA root (start state) DFA::State *target_state = last_state = last_state->next = tfa_.state(); - t->edges[c] = DFA::State::Edge(c, target_state); - t = target_state; + r->edges[c] = DFA::State::Edge(c, target_state); + r = target_state; ++eno_; ++vno_; if (vno_ > DFA::MAX_STATES) @@ -845,14 +845,14 @@ void Pattern::parse( } else { - t = i->second.second; + r = i->second.second; } #else - t = tfa_.edge(t, c); + r = tfa_.edge(r, c); #endif } - if (t->accept == 0) - t->accept = choice; + if (r->accept == 0) + r->accept = choice; #ifdef WITH_TREE_DFA acc_.resize(choice, false); acc_[choice - 1] = true; @@ -1165,12 +1165,12 @@ void Pattern::parse3( } else if (c == '{') // {n,m} repeat min n times to max m { - size_t k = 0; + size_t d = 0; for (Location i = 0; i < 7 && std::isdigit(c = at(++loc)); ++i) - k = 10 * k + (c - '0'); - if (k > Position::MAXITER) + d = 10 * d + (c - '0'); + if (d > Position::MAXITER) error(regex_error::exceeds_limits, loc); - Iter n = static_cast(k); + Iter n = static_cast(d); Iter m = n; bool unlimited = false; if (at(loc) == ',') @@ -2378,9 +2378,9 @@ void Pattern::compile_transition( error(regex_error::exceeds_limits, loc); state->heads.insert(l); } - Lookahead k = n; + Lookahead l = n; n += static_cast(i->second.size()); - if (n < k) + if (n < l) error(regex_error::exceeds_limits, loc); } } @@ -2402,9 +2402,9 @@ void Pattern::compile_transition( error(regex_error::exceeds_limits, loc); state->tails.insert(l); } - Lookahead k = n; + Lookahead l = n; n += static_cast(i->second.size()); - if (n < k) + if (n < l) error(regex_error::exceeds_limits, loc); } } @@ -2656,19 +2656,29 @@ void Pattern::compile_list(Location loc, Chars& chars, const Mods modifiers) con { if (!is_meta(lo)) { - if (lo <= c) - chars.add(lo, c); - else - error(regex_error::invalid_class_range, loc); if (is_modified(ModConst::i, modifiers, loc)) { - for (Char a = lo; a <= c; ++a) - { - if (a >= 'A' && a <= 'Z') - chars.add(lowercase(a)); - else if (a >= 'a' && a <= 'z') - chars.add(uppercase(a)); - } + Char a = lo; + Char b = c; + if (a >= 'a' && a <= 'z' && b <= 'z') + a = uppercase(a); + if (b >= 'a' && b <= 'z' && a <= uppercase(b)) + b = uppercase(b); + if (a > b) + error(regex_error::invalid_class_range, loc); + chars.add(a, b); + a = std::max(lo, 'A'); + b = std::min(c, 'Z'); + if (a <= b) + chars.add(lowercase(a), lowercase(b)); + a = std::max(lo, 'a'); + b = std::min(c, 'z'); + if (a <= b) + chars.add(uppercase(a), uppercase(b)); + } + else + { + chars.add(lo, c); } c = META_EOL; } @@ -3049,9 +3059,9 @@ void Pattern::encode_dfa(DFA::State *start) void Pattern::gencode_dfa(const DFA::State *start) const { #ifndef WITH_NO_CODEGEN - for (std::vector::const_iterator i = opt_.f.begin(); i != opt_.f.end(); ++i) + for (std::vector::const_iterator it = opt_.f.begin(); it != opt_.f.end(); ++it) { - const std::string& filename = *i; + const std::string& filename = *it; size_t len = filename.length(); if ((len > 2 && filename.compare(len - 2, 2, ".h" ) == 0) || (len > 3 && filename.compare(len - 3, 3, ".hh" ) == 0) @@ -3521,9 +3531,9 @@ void Pattern::gencode_dfa_closure(FILE *file, const DFA::State *state, int nest, void Pattern::graph_dfa(const DFA::State *start) const { #ifndef WITH_NO_CODEGEN - for (std::vector::const_iterator i = opt_.f.begin(); i != opt_.f.end(); ++i) + for (std::vector::const_iterator it = opt_.f.begin(); it != opt_.f.end(); ++it) { - const std::string& filename = *i; + const std::string& filename = *it; size_t len = filename.length(); if ((len > 3 && filename.compare(len - 3, 3, ".gv") == 0) || (len > 4 && filename.compare(len - 4, 4, ".dot") == 0)) @@ -3694,9 +3704,9 @@ void Pattern::export_code() const #ifndef WITH_NO_CODEGEN if (nop_ == 0) return; - for (std::vector::const_iterator i = opt_.f.begin(); i != opt_.f.end(); ++i) + for (std::vector::const_iterator it = opt_.f.begin(); it != opt_.f.end(); ++it) { - const std::string& filename = *i; + const std::string& filename = *it; size_t len = filename.length(); if ((len > 2 && filename.compare(len - 2, 2, ".h" ) == 0) || (len > 3 && filename.compare(len - 3, 3, ".hh" ) == 0) @@ -4586,7 +4596,7 @@ void Pattern::gen_match_hfa(DFA::State *start) { HFA::HashRanges& set_ranges = hfa_.hashes[level][next->first->index]; HFA::HashRanges& get_ranges = next->second; - for (size_t offset = std::max(HFA::MAX_CHAIN - 1, level) + 1 - HFA::MAX_CHAIN; offset <= level; ++offset) + for (size_t offset = std::max(HFA::MAX_CHAIN - 1, level) + 1 - HFA::MAX_CHAIN; offset <= level; ++offset) set_ranges[offset].swap(get_ranges[offset]); } } @@ -4635,7 +4645,7 @@ bool Pattern::gen_match_hfa_transitions(size_t level, size_t& max_level, DFA::St Char lo = edge.lo(); Char hi = edge.hi(); DBGLOG("%zu HFA %p: %u..%u -> %p", level, state, lo, hi, next_state); - for (size_t offset = std::max(HFA::MAX_CHAIN - 1, level) + 1 - HFA::MAX_CHAIN; offset < level; ++offset) + for (size_t offset = std::max(HFA::MAX_CHAIN - 1, level) + 1 - HFA::MAX_CHAIN; offset < level; ++offset) { DBGLOGN(" offset%3zu", offset); HFA::HashRange& next_hashes = hashes[next_state][offset]; diff --git a/lzma/C/README.txt b/lzma/C/README.txt index 9c772dd0..ac1a93f6 100644 --- a/lzma/C/README.txt +++ b/lzma/C/README.txt @@ -6,28 +6,29 @@ LZMA SDK is placed in the public domain. LZMA SDK by Igor Pavlov. -Updated to apply YOKOTA Hiroshi's patches: +Updated 23.01 to apply YOKOTA Hiroshi's patches: https://salsa.debian.org/debian/7zip/-/blob/master/debian/patches/0002-Disable-hardware-acceleration-support-on-armel.patch?ref_type=heads -Included in this directory is a new C API to simplify decompression: +Included in this directory is a new C API written for ugrep to simplify +decompression: -- viizip.h declarations, see below (hides implementation details) -- viizip.c implementation +- viizip.h API declarations, see below (hides implementation details) +- viizip.c API implementation - libviiz.a static library compiled from source -The 7zip decompressor state with hidden members: -struct viizip +The 7zip decompressor API state with hidden members: + struct viizip To create a new 7zip decompressor for the given 7zip file: -struct viizip *viinew(FILE *file) + struct viizip *viinew(FILE *file) To free viizip decompressor state: -void viifree(struct viizip *viizip) + void viifree(struct viizip *viizip) To get archive part pathname and info, start decompressing: -int viiget(struct viizip *viizip, char *name, size_t max, time_t *mtime, uint64_t *usize) + int viiget(struct viizip *viizip, char *name, size_t max, time_t *mtime, uint64_t *usize) To decompress up to len bytes into buf[], return number of bytes decompressed: -ssize_t viidec(struct viizip *viizip, unsigned char *buf, size_t len) + ssize_t viidec(struct viizip *viizip, unsigned char *buf, size_t len) The viizip files are part of the ugrep project licensed BSD-3. diff --git a/man/ug.1 b/man/ug.1 index 8f9feea7..a2d8b552 100644 --- a/man/ug.1 +++ b/man/ug.1 @@ -1,4 +1,4 @@ -.TH UGREP "1" "November 19, 2024" "ugrep 7.1.0" "User Commands" +.TH UGREP "1" "November 29, 2024" "ugrep 7.1.1" "User Commands" .SH NAME \fBugrep\fR, \fBug\fR -- file pattern searcher .SH SYNOPSIS diff --git a/man/ugrep-indexer.1 b/man/ugrep-indexer.1 index 8d380340..8554fdb8 100644 --- a/man/ugrep-indexer.1 +++ b/man/ugrep-indexer.1 @@ -1,4 +1,4 @@ -.TH UGREP-INDEXER "1" "November 19, 2024" "ugrep-indexer 7.1.0" "User Commands" +.TH UGREP-INDEXER "1" "November 29, 2024" "ugrep-indexer 7.1.1" "User Commands" .SH NAME \fBugrep-indexer\fR -- file indexer to accelerate recursive searching .SH SYNOPSIS diff --git a/man/ugrep.1 b/man/ugrep.1 index 8f9feea7..a2d8b552 100644 --- a/man/ugrep.1 +++ b/man/ugrep.1 @@ -1,4 +1,4 @@ -.TH UGREP "1" "November 19, 2024" "ugrep 7.1.0" "User Commands" +.TH UGREP "1" "November 29, 2024" "ugrep 7.1.1" "User Commands" .SH NAME \fBugrep\fR, \fBug\fR -- file pattern searcher .SH SYNOPSIS diff --git a/src/query.cpp b/src/query.cpp index c239d55e..7ee408e3 100644 --- a/src/query.cpp +++ b/src/query.cpp @@ -1342,15 +1342,15 @@ void Query::query_ui() case VKey::FN(4): if (mark_.row >= 0) { - int row; - if (mark_.restore(line_, col_, row, flags_)) + int old_row; + if (mark_.restore(old_row)) { globbing_ = false; set_prompt(); len_ = line_len(); search(); } - jump(row); + jump(old_row); } else { @@ -1398,8 +1398,15 @@ void Query::query_ui() case VKey::CTRL_X: // CTRL-X or F3: set bookmark and save state case VKey::FN(3): - mark_.save(line_, col_, (select_ >= 0 ? select_ : row_), flags_); - status(true); + if (select_ == -1) + { + mark_.save(); + status(true); + } + else + { + Screen::alert(); + } break; case VKey::CTRL_Y: // CTRL-Y or F2: view (or edit) file @@ -2809,7 +2816,7 @@ void Query::select() files_.swap(Static::arg_files); history_.emplace(); - history_.top().save(line_, col_, row_, flags_, mark_); + history_.top().save(); if (flag_directories_action != Action::RECURSE) { @@ -2967,8 +2974,8 @@ void Query::deselect() if (!history_.empty()) { - int row; - history_.top().restore(line_, col_, row, flags_, mark_); + int old_row; + history_.top().restore(old_row); history_.pop(); if (history_.empty()) files_.swap(Static::arg_files); @@ -2976,7 +2983,7 @@ void Query::deselect() set_prompt(); len_ = line_len(); search(); - jump(row); + jump(old_row); } else { @@ -3048,15 +3055,15 @@ void Query::unselect() { while (history_.size() > 1) history_.pop(); - int row; - history_.top().restore(line_, col_, row, flags_, mark_); + int old_row; + history_.top().restore(old_row); history_.pop(); files_.swap(Static::arg_files); globbing_ = false; set_prompt(); len_ = line_len(); search(); - jump(row); + jump(old_row); } else { diff --git a/src/query.hpp b/src/query.hpp index a25a4a4f..94d83a2f 100644 --- a/src/query.hpp +++ b/src/query.hpp @@ -105,7 +105,7 @@ class Query { return row != -1; } - void save(const Line& line_, int col_, int row_, const Flags flags_[]) + void save() { memcpy(line, line_, sizeof(Line)); col = col_; @@ -115,9 +115,9 @@ class Query { set.push_back(flags_[i].flag); } - bool restore(Line& line_, int& col_, int& row_, Flags flags_[]) + bool restore(int& old_row) { - row_ = 0; + old_row = 0; if (row < 0) return false; @@ -126,7 +126,7 @@ class Query { memcpy(line_, line, sizeof(Line)); col_ = col; - row_ = row; + old_row = row; for (int i = 0; flags_[i].text != NULL; ++i) { if (flags_[i].flag != set[i]) @@ -149,15 +149,15 @@ class Query { // history to restore pattern, bookmark and option upon SHIFT-TAB struct History : public State { - void save(const Line& line_, int col_, int row_, const Flags flags_[], const State& mark_) + void save() { - State::save(line_, col_, row_, flags_); + State::save(); mark = mark_; } - void restore(Line& line_, int& col_, int& row_, Flags flags_[], State& mark_) + void restore(int& old_row) { - State::restore(line_, col_, row_, flags_); + State::restore(old_row); mark_ = mark; } diff --git a/src/ugrep-indexer.cpp b/src/ugrep-indexer.cpp index fce71db5..94b940ff 100644 --- a/src/ugrep-indexer.cpp +++ b/src/ugrep-indexer.cpp @@ -35,7 +35,7 @@ */ // DO NOT ALTER THIS LINE: updated by makemake.sh and we need it physically here for MSVC++ build from source -#define UGREP_VERSION "7.1.0" +#define UGREP_VERSION "7.1.1" // use a task-parallel thread to decompress the stream into a pipe to search, also handles nested archives #define WITH_DECOMPRESSION_THREAD @@ -277,7 +277,7 @@ static const char ugrep_index_file_magic[5] = "UG#\x03"; static const char ugrep_indexer_config_filename[] = ".ugrep-indexer"; // command-line optional PATH argument -const char *arg_pathname = NULL; +const char *arg_path = NULL; // command-line options int flag_accuracy = 4; // -0 ... -9 (--accuracy) default is -4 @@ -1434,7 +1434,7 @@ void deleter(const char *pathname) } // recursively index files -void indexer(const char *pathname) +void indexer(const char *path) { if (!flag_no_messages && !flag_check && !flag_quiet) { @@ -1473,11 +1473,11 @@ void indexer(const char *pathname) float sum_noise = 0; uint8_t hashes[65536]; - // pathname to the directory tree to index or . - if (pathname == NULL) + // argument path to the directory tree to index or . + if (path == NULL) dir_entries.emplace(); else - dir_entries.emplace(pathname); + dir_entries.emplace(path); // recurse subdirectories while (!dir_entries.empty()) @@ -1947,13 +1947,13 @@ void options(int argc, const char **argv) } } } - else if (arg_pathname == NULL) + else if (arg_path == NULL) { - arg_pathname = arg; + arg_path = arg; } else { - usage("argument PATH already specified as ", arg_pathname); + usage("argument PATH already specified as ", arg_path); } } @@ -2060,9 +2060,9 @@ int main(int argc, const char **argv) options(argc, argv); if (flag_delete) - deleter(arg_pathname); + deleter(arg_path); else - indexer(arg_pathname); + indexer(arg_path); return EXIT_SUCCESS; } diff --git a/src/ugrep.hpp b/src/ugrep.hpp index 053792e5..05ae2f51 100644 --- a/src/ugrep.hpp +++ b/src/ugrep.hpp @@ -38,7 +38,7 @@ #define UGREP_HPP // DO NOT ALTER THIS LINE: updated by makemake.sh and we need it physically here for MSVC++ build from source -#define UGREP_VERSION "7.1.0" +#define UGREP_VERSION "7.1.1" // disable mmap because mmap is almost always slower than the file reading speed improvements since 3.0.0 #define WITH_NO_MMAP diff --git a/src/zstream.hpp b/src/zstream.hpp index 81242888..76b2173b 100644 --- a/src/zstream.hpp +++ b/src/zstream.hpp @@ -146,15 +146,15 @@ class zstreambuf : public std::streambuf { viifree(viizip); } - // next 7zip file to decompress and get its info, return 0 if OK, if none return 1 or -1 on error - int get(std::string& name, time_t& mtime, uint64_t& usize) + // next 7zip file to decompress and get its ZipInfo, return 0 if OK, if none return 1 or -1 on error + int get(ZipInfo& zipinfo) { char buf[PATH_MAX]; - int res = viiget(viizip, buf, PATH_MAX, &mtime, &usize); + int res = viiget(viizip, buf, PATH_MAX, &zipinfo.mtime, &zipinfo.usize); if (res) return res; - name.assign(buf); + zipinfo.name.assign(buf); return 0; } @@ -260,7 +260,7 @@ class zstreambuf : public std::streambuf { if (!znew_) return true; - int res = sz_strm_->get(name, mtime, usize); + int res = sz_strm_->get(*this); if (res < 0) { cannot_decompress(pathname_, "corrupt 7zip archive"); diff --git a/src/zthread.hpp b/src/zthread.hpp index 3d16d8ec..588b50bf 100644 --- a/src/zthread.hpp +++ b/src/zthread.hpp @@ -233,10 +233,12 @@ struct Zthread { pipe_fd[0] = -1; // if extracting and the decompression filter thread is not yet waiting, then wait until decompression thread closed its end of the pipe - std::unique_lock lock(pipe_mutex); - if (!is_waiting) - pipe_close.wait(lock); - lock.unlock(); + { + std::unique_lock lock(pipe_mutex); + if (!is_waiting) + pipe_close.wait(lock); + lock.unlock(); + } // partnameref is not assigned yet, used only when this decompression thread is chained is_assigned = false;