diff --git a/README.md b/README.md index 8a1b5f8f..5c6ff172 100644 --- a/README.md +++ b/README.md @@ -4763,7 +4763,8 @@ in markdown: --tabs[=NUM] Set the tab size to NUM to expand tabs for option -k. The value - of NUM may be 1, 2, 4, or 8. The default tab size is 8. + of NUM may be 1 (no expansion), 2, 4, or 8. The default size is + 8. --tag[=TAG[,END]] Disables colors to mark up matches with TAG. END marks the end of @@ -5458,7 +5459,7 @@ in markdown: - ugrep 7.0.2 October 27, 2024 UGREP(1) + ugrep 7.0.3 November 10, 2024 UGREP(1) 🔝 [Back to table of contents](#toc) diff --git a/bin/win32/ug.exe b/bin/win32/ug.exe index f243e83c..46f61d62 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 1a24117c..6b190286 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 f243e83c..46f61d62 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 c05a0fdb..595e2e7c 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 aa0b711e..a1181da5 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 c05a0fdb..595e2e7c 100755 Binary files a/bin/win64/ugrep.exe and b/bin/win64/ugrep.exe differ diff --git a/configure b/configure index b0be4514..e6489c2d 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.0.2. +# Generated by GNU Autoconf 2.72 for ugrep 7.0.3. # # Report bugs to . # @@ -606,8 +606,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='ugrep' PACKAGE_TARNAME='ugrep' -PACKAGE_VERSION='7.0.2' -PACKAGE_STRING='ugrep 7.0.2' +PACKAGE_VERSION='7.0.3' +PACKAGE_STRING='ugrep 7.0.3' 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.0.2 to adapt to many kinds of systems. +'configure' configures ugrep 7.0.3 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.0.2:";; + short | recursive ) echo "Configuration of ugrep 7.0.3:";; 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.0.2 +ugrep configure 7.0.3 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.0.2, which was +It was created by ugrep $as_me 7.0.3, 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.0.2' + VERSION='7.0.3' 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.0.2, which was +This file was extended by ugrep $as_me 7.0.3, 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.0.2 +ugrep config.status 7.0.3 configured by $0, generated by GNU Autoconf 2.72, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 31f190c9..419477ac 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT([ugrep],[7.0.2],[https://github.com/Genivia/ugrep/issues],[ugrep],[https://ugrep.com]) +AC_INIT([ugrep],[7.0.3],[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/matcher_avx512bw.cpp b/lib/matcher_avx512bw.cpp index 37fcd6af..bb27af11 100644 --- a/lib/matcher_avx512bw.cpp +++ b/lib/matcher_avx512bw.cpp @@ -77,13 +77,11 @@ void Matcher::simd_init_advance_avx512bw() } else if (pat_->bmd_ == 0) { -#if defined(WITH_STRING_PM) if (pat_->min_ >= 4) adv_ = &Matcher::simd_advance_string_pmh_avx512bw; else if (pat_->min_ > 0) adv_ = &Matcher::simd_advance_string_pma_avx512bw; else -#endif adv_ = &Matcher::simd_advance_string_avx512bw; } } @@ -271,8 +269,6 @@ bool Matcher::simd_advance_string_avx512bw(size_t loc) return advance_string(loc); } -#if defined(WITH_STRING_PM) - /// Implements AVX512BW string search scheme based on http://0x80.pl/articles/simd-friendly-karp-rabin.html bool Matcher::simd_advance_string_pma_avx512bw(size_t loc) { @@ -367,8 +363,6 @@ bool Matcher::simd_advance_string_pmh_avx512bw(size_t loc) return advance_string_pmh(loc); } -#endif // WITH_STRING_PM - #else // appease ranlib "has no symbols" diff --git a/man/ug.1 b/man/ug.1 index b14b9f5a..5eeb4705 100644 --- a/man/ug.1 +++ b/man/ug.1 @@ -1,4 +1,4 @@ -.TH UGREP "1" "October 27, 2024" "ugrep 7.0.2" "User Commands" +.TH UGREP "1" "November 10, 2024" "ugrep 7.0.3" "User Commands" .SH NAME \fBugrep\fR, \fBug\fR -- file pattern searcher .SH SYNOPSIS @@ -817,7 +817,7 @@ repeated. The possible file types can be (\fB\-t\fRlist displays a list): .TP \fB\-\-tabs\fR[=\fINUM\fR] Set the tab size to NUM to expand tabs for option \fB\-k\fR. The value of -NUM may be 1, 2, 4, or 8. The default tab size is 8. +NUM may be 1 (no expansion), 2, 4, or 8. The default size is 8. .TP \fB\-\-tag\fR[=\fITAG\fR[,\fIEND\fR]] Disables colors to mark up matches with TAG. END marks the end of diff --git a/man/ugrep-indexer.1 b/man/ugrep-indexer.1 index 339bddad..692a0eb2 100644 --- a/man/ugrep-indexer.1 +++ b/man/ugrep-indexer.1 @@ -1,4 +1,4 @@ -.TH UGREP-INDEXER "1" "October 27, 2024" "ugrep-indexer 7.0.2" "User Commands" +.TH UGREP-INDEXER "1" "November 10, 2024" "ugrep-indexer 7.0.3" "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 b14b9f5a..5eeb4705 100644 --- a/man/ugrep.1 +++ b/man/ugrep.1 @@ -1,4 +1,4 @@ -.TH UGREP "1" "October 27, 2024" "ugrep 7.0.2" "User Commands" +.TH UGREP "1" "November 10, 2024" "ugrep 7.0.3" "User Commands" .SH NAME \fBugrep\fR, \fBug\fR -- file pattern searcher .SH SYNOPSIS @@ -817,7 +817,7 @@ repeated. The possible file types can be (\fB\-t\fRlist displays a list): .TP \fB\-\-tabs\fR[=\fINUM\fR] Set the tab size to NUM to expand tabs for option \fB\-k\fR. The value of -NUM may be 1, 2, 4, or 8. The default tab size is 8. +NUM may be 1 (no expansion), 2, 4, or 8. The default size is 8. .TP \fB\-\-tag\fR[=\fITAG\fR[,\fIEND\fR]] Disables colors to mark up matches with TAG. END marks the end of diff --git a/src/query.cpp b/src/query.cpp index 8fb59214..77f36956 100644 --- a/src/query.cpp +++ b/src/query.cpp @@ -2429,6 +2429,10 @@ void Query::view() FILE *pager = NULL; +#ifdef OS_WIN + std::wstring wcommand; +#endif + if (flag_stdin && filename == flag_label) { // standard input is viewed via a pipe to the pager @@ -2463,12 +2467,35 @@ void Query::view() } else { - // view file in the pager + // view file in the pager using system() call command.append(" \"").append(filename).append("\""); + +#ifdef OS_WIN + // Windows system() does not support non-ASCII, instead we use a wide string with _wsystem() + wcommand = utf8_decode(command); + + // flush before calling _wsystem(), according to the Window's system API documentation + _flushall(); +#endif + } + + // pipe to pager was OK or executing the command is OK + bool ok; + + if ((flag_stdin && filename == flag_label) || !partname.empty()) + { + ok = (pager != NULL); + } + else + { +#ifdef OS_WIN + ok = (_wsystem(wcommand.c_str()) == 0); +#else + ok = (system(command.c_str()) == 0); +#endif } - // pipe to pager was OK or execute the command - if ((flag_stdin && filename == flag_label) || !partname.empty() ? pager != NULL : system(command.c_str()) == 0) + if (ok) { #ifdef OS_WIN if (strcmp(flag_view, "more") == 0) diff --git a/src/ugrep-indexer.cpp b/src/ugrep-indexer.cpp index 8dd7caf0..0c44c9b4 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.0.2" +#define UGREP_VERSION "7.0.3" // use a task-parallel thread to decompress the stream into a pipe to search, also handles nested archives #define WITH_DECOMPRESSION_THREAD diff --git a/src/ugrep.cpp b/src/ugrep.cpp index 5578dd7e..945852b2 100644 --- a/src/ugrep.cpp +++ b/src/ugrep.cpp @@ -7264,6 +7264,9 @@ void init(int argc, const char **argv) // --filter: Cygwin forked process may hang when searching with multiple threads, force one worker thread if (!flag_filter.empty()) flag_jobs = 1; +#elif defined(OS_WIN) + if (!flag_filter.empty()) + abort("--filter: not supported for ", PLATFORM); #endif } @@ -14389,7 +14392,7 @@ void help(std::ostream& out) out << ".\n\ --tabs[=NUM]\n\ Set the tab size to NUM to expand tabs for option -k. The value of\n\ - NUM may be 1, 2, 4, or 8. The default tab size is 8.\n\ + NUM may be 1 (no expansion), 2, 4, or 8. The default size is 8.\n\ --tag[=TAG[,END]]\n\ Disables colors to mark up matches with TAG. END marks the end of\n\ a match if specified, otherwise TAG. The default is `___'.\n\ diff --git a/src/ugrep.hpp b/src/ugrep.hpp index 9a9ae97e..bb8b7e8c 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.0.2" +#define UGREP_VERSION "7.0.3" // 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/vkey.cpp b/src/vkey.cpp index 93ef6180..85db575f 100644 --- a/src/vkey.cpp +++ b/src/vkey.cpp @@ -138,21 +138,23 @@ int VKey::raw_in(int timeout) if (keybuf[0]) return rot_keybuf(); - switch (WaitForSingleObject(hConIn, timeout)) + while (true) { - case WAIT_OBJECT_0: - if (!_kbhit()) - { + switch (WaitForSingleObject(hConIn, timeout)) + { + case WAIT_OBJECT_0: + if (_kbhit()) + return raw_get(); + // discard non-key-press event FlushConsoleInputBuffer(hConIn); - return 0; - } - return raw_get(); + break; - case WAIT_TIMEOUT: - return 0; + case WAIT_TIMEOUT: + return 0; - default: - return EOF; + default: + return EOF; + } } } @@ -265,25 +267,27 @@ int VKey::raw_in(int timeout) DWORD nread = 0; INPUT_RECORD rec; - switch (WaitForSingleObject(hConIn, timeout)) + while (true) { - case WAIT_OBJECT_0: - if (PeekConsoleInputW(hConIn, &rec, 1, &nread) != 0 && - nread == 1 && - rec.EventType == KEY_EVENT && - rec.Event.KeyEvent.bKeyDown) - return raw_get(); - - // discard event - if (nread == 1) - ReadConsoleInputW(hConIn, &rec, 1, &nread); - return 0; + switch (WaitForSingleObject(hConIn, timeout)) + { + case WAIT_OBJECT_0: + if (PeekConsoleInputW(hConIn, &rec, 1, &nread) != 0 && + nread == 1 && + rec.EventType == KEY_EVENT && + rec.Event.KeyEvent.bKeyDown) + return raw_get(); + // discard non-key-press event + if (nread == 1) + ReadConsoleInputW(hConIn, &rec, 1, &nread); + break; - case WAIT_TIMEOUT: - return 0; + case WAIT_TIMEOUT: + return 0; - default: - return EOF; + default: + return EOF; + } } } @@ -293,25 +297,27 @@ bool VKey::poll(int timeout) DWORD nread = 0; INPUT_RECORD rec; - switch (WaitForSingleObject(hConIn, timeout)) + while (true) { - case WAIT_OBJECT_0: - if (PeekConsoleInputW(hConIn, &rec, 1, &nread) != 0 && - nread == 1 && - rec.EventType == KEY_EVENT && - rec.Event.KeyEvent.bKeyDown) - return true; - - // discard event - if (nread == 1) - ReadConsoleInputW(hConIn, &rec, 1, &nread); - return 0; + switch (WaitForSingleObject(hConIn, timeout)) + { + case WAIT_OBJECT_0: + if (PeekConsoleInputW(hConIn, &rec, 1, &nread) != 0 && + nread == 1 && + rec.EventType == KEY_EVENT && + rec.Event.KeyEvent.bKeyDown) + return true; + // discard non-key-press event + if (nread == 1) + ReadConsoleInputW(hConIn, &rec, 1, &nread); + break; - case WAIT_TIMEOUT: - return false; + case WAIT_TIMEOUT: + return false; - default: - return true; + default: + return true; + } } }