@ 260915.5

250301.1 · 89b979c56b9da56e91db560a650fad378abf4a51

make option -i Unicode case-insensitive

fix #467

reading declarations

bin/win32/ug.exe

Binary file changed

bin/win32/ugrep-indexer.exe

Binary file changed

bin/win32/ugrep.exe

Binary file changed

bin/win64/ug.exe

Binary file changed

bin/win64/ugrep-indexer.exe

Binary file changed

bin/win64/ugrep.exe

Binary file changed

completions/bash/ug

@@ -281,7 +281,7 @@ cat <<'END' --include-fs=MOUNTS Only file systems specified by MOUNTS are included in recursive searches. --index Perform fast index-based recursive search. -J NUM, --jobs=NUM Specifies the number of threads spawned to search files.--j, --smart-case Perform case insensitive matching, unless a pattern is specified with a literal upper case ASCII letter.+-j, --smart-case Perform case insensitive matching, unless a pattern is specified with a literal upper case letter. --json Output file matches in JSON. -K [MIN,][MAX], --range=[MIN,][MAX], --min-line=MIN, --max-line=MAX Start searching at line MIN, stop at line MAX when specified. -k, --column-number The column number of a pattern match is displayed in front of the respective matched line, starting at column 1.

completions/fish/ug+.fish

@@ -59,7 +59,7 @@ complete -c ug+ -l include-from -d 'Read the globs from FILE and search only fil complete -c ug+ -l include-fs -d 'Only file systems specified by MOUNTS are included in recursive searches' complete -c ug+ -l index -d 'Perform fast index-based recursive search' complete -c ug+ -s J -r -l jobs -d 'Specifies the number of threads spawned to search files'-complete -c ug+ -s j -l smart-case -d 'Perform case insensitive matching, unless a pattern is specified with a literal upper case ASCII letter'+complete -c ug+ -s j -l smart-case -d 'Perform case insensitive matching, unless a pattern is specified with a literal upper case letter' complete -c ug+ -l json -d 'Output file matches in JSON' complete -c ug+ -s K -r -l range -l min-line -l max-line -d 'Start searching at line MIN, stop at line MAX when specified' complete -c ug+ -s k -l column-number -d 'The column number of a pattern match is displayed in front of the respective matched line, starting at column 1'

completions/fish/ug.fish

@@ -59,7 +59,7 @@ complete -c ug -l include-from -d 'Read the globs from FILE and search only file complete -c ug -l include-fs -d 'Only file systems specified by MOUNTS are included in recursive searches' complete -c ug -l index -d 'Perform fast index-based recursive search' complete -c ug -s J -r -l jobs -d 'Specifies the number of threads spawned to search files'-complete -c ug -s j -l smart-case -d 'Perform case insensitive matching, unless a pattern is specified with a literal upper case ASCII letter'+complete -c ug -s j -l smart-case -d 'Perform case insensitive matching, unless a pattern is specified with a literal upper case letter' complete -c ug -l json -d 'Output file matches in JSON' complete -c ug -s K -r -l range -l min-line -l max-line -d 'Start searching at line MIN, stop at line MAX when specified' complete -c ug -s k -l column-number -d 'The column number of a pattern match is displayed in front of the respective matched line, starting at column 1'

completions/fish/ugrep+.fish

@@ -59,7 +59,7 @@ complete -c ugrep+ -l include-from -d 'Read the globs from FILE and search only complete -c ugrep+ -l include-fs -d 'Only file systems specified by MOUNTS are included in recursive searches' complete -c ugrep+ -l index -d 'Perform fast index-based recursive search' complete -c ugrep+ -s J -r -l jobs -d 'Specifies the number of threads spawned to search files'-complete -c ugrep+ -s j -l smart-case -d 'Perform case insensitive matching, unless a pattern is specified with a literal upper case ASCII letter'+complete -c ugrep+ -s j -l smart-case -d 'Perform case insensitive matching, unless a pattern is specified with a literal upper case letter' complete -c ugrep+ -l json -d 'Output file matches in JSON' complete -c ugrep+ -s K -r -l range -l min-line -l max-line -d 'Start searching at line MIN, stop at line MAX when specified' complete -c ugrep+ -s k -l column-number -d 'The column number of a pattern match is displayed in front of the respective matched line, starting at column 1'

completions/fish/ugrep.fish

@@ -59,7 +59,7 @@ complete -c ugrep -l include-from -d 'Read the globs from FILE and search only f complete -c ugrep -l include-fs -d 'Only file systems specified by MOUNTS are included in recursive searches' complete -c ugrep -l index -d 'Perform fast index-based recursive search' complete -c ugrep -s J -r -l jobs -d 'Specifies the number of threads spawned to search files'-complete -c ugrep -s j -l smart-case -d 'Perform case insensitive matching, unless a pattern is specified with a literal upper case ASCII letter'+complete -c ugrep -s j -l smart-case -d 'Perform case insensitive matching, unless a pattern is specified with a literal upper case letter' complete -c ugrep -l json -d 'Output file matches in JSON' complete -c ugrep -s K -r -l range -l min-line -l max-line -d 'Start searching at line MIN, stop at line MAX when specified' complete -c ugrep -s k -l column-number -d 'The column number of a pattern match is displayed in front of the respective matched line, starting at column 1'

completions/zsh/_ug

@@ -66,7 +66,7 @@ $matchers{-G,--basic-regexp}'[Interpret patterns as basic regular expressions (B '(1)*'--include-fs=-'[Only file systems specified by MOUNTS are included in recursive searches]' --index'[Perform fast index-based recursive search]' {-J,--jobs=-}'[Specifies the number of threads spawned to search files]:NUM:( )'-{-j,--smart-case}'[Perform case insensitive matching, unless a pattern is specified with a literal upper case ASCII letter]'+{-j,--smart-case}'[Perform case insensitive matching, unless a pattern is specified with a literal upper case letter]' --json'[Output file matches in JSON]' {-K,--range=-,--min-line=-,--max-line=-}'[Start searching at line MIN, stop at line MAX when specified]:MIN,MAX:( )' {-k,--column-number}'[The column number of a pattern match is displayed in front of the respective matched line, starting at column 1]'

completions/zsh/_ug+

@@ -66,7 +66,7 @@ $matchers{-G,--basic-regexp}'[Interpret patterns as basic regular expressions (B '(1)*'--include-fs=-'[Only file systems specified by MOUNTS are included in recursive searches]' --index'[Perform fast index-based recursive search]' {-J,--jobs=-}'[Specifies the number of threads spawned to search files]:NUM:( )'-{-j,--smart-case}'[Perform case insensitive matching, unless a pattern is specified with a literal upper case ASCII letter]'+{-j,--smart-case}'[Perform case insensitive matching, unless a pattern is specified with a literal upper case letter]' --json'[Output file matches in JSON]' {-K,--range=-,--min-line=-,--max-line=-}'[Start searching at line MIN, stop at line MAX when specified]:MIN,MAX:( )' {-k,--column-number}'[The column number of a pattern match is displayed in front of the respective matched line, starting at column 1]'

completions/zsh/_ugrep

@@ -66,7 +66,7 @@ $matchers{-G,--basic-regexp}'[Interpret patterns as basic regular expressions (B '(1)*'--include-fs=-'[Only file systems specified by MOUNTS are included in recursive searches]' --index'[Perform fast index-based recursive search]' {-J,--jobs=-}'[Specifies the number of threads spawned to search files]:NUM:( )'-{-j,--smart-case}'[Perform case insensitive matching, unless a pattern is specified with a literal upper case ASCII letter]'+{-j,--smart-case}'[Perform case insensitive matching, unless a pattern is specified with a literal upper case letter]' --json'[Output file matches in JSON]' {-K,--range=-,--min-line=-,--max-line=-}'[Start searching at line MIN, stop at line MAX when specified]:MIN,MAX:( )' {-k,--column-number}'[The column number of a pattern match is displayed in front of the respective matched line, starting at column 1]'

completions/zsh/_ugrep+

@@ -66,7 +66,7 @@ $matchers{-G,--basic-regexp}'[Interpret patterns as basic regular expressions (B '(1)*'--include-fs=-'[Only file systems specified by MOUNTS are included in recursive searches]' --index'[Perform fast index-based recursive search]' {-J,--jobs=-}'[Specifies the number of threads spawned to search files]:NUM:( )'-{-j,--smart-case}'[Perform case insensitive matching, unless a pattern is specified with a literal upper case ASCII letter]'+{-j,--smart-case}'[Perform case insensitive matching, unless a pattern is specified with a literal upper case letter]' --json'[Output file matches in JSON]' {-K,--range=-,--min-line=-,--max-line=-}'[Start searching at line MIN, stop at line MAX when specified]:MIN,MAX:( )' {-k,--column-number}'[The column number of a pattern match is displayed in front of the respective matched line, starting at column 1]'

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.2.2.+# Generated by GNU Autoconf 2.72 for ugrep 7.3.0. # # Report bugs to <https://github.com/Genivia/ugrep/issues>. #@@ -12,7 +12,7 @@ # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. #-# Copyright (C) 2019-2024 Robert van Engelen, Genivia Inc.+# Copyright (C) 2019-2025 Robert van Engelen, Genivia Inc. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ##@@ -606,8 +606,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='ugrep' PACKAGE_TARNAME='ugrep'-PACKAGE_VERSION='7.2.2'-PACKAGE_STRING='ugrep 7.2.2'+PACKAGE_VERSION='7.3.0'+PACKAGE_STRING='ugrep 7.3.0' 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.2.2 to adapt to many kinds of systems.+'configure' configures ugrep 7.3.0 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.2.2:";;+     short | recursive ) echo "Configuration of ugrep 7.3.0:";;    esac   cat <<\_ACEOF @@ -1630,14 +1630,14 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then   cat <<\_ACEOF-ugrep configure 7.2.2+ugrep configure 7.3.0 generated by GNU Autoconf 2.72  Copyright (C) 2023 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. -Copyright (C) 2019-2024 Robert van Engelen, Genivia Inc.+Copyright (C) 2019-2025 Robert van Engelen, Genivia Inc. _ACEOF   exit fi@@ -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.2.2, which was+It was created by ugrep $as_me 7.3.0, 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.2.2'+ VERSION='7.3.0'   printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h@@ -3804,8 +3804,8 @@ ac_config_headers="$ac_config_headers config.h"   # if CXXFLAGS is undefined, set it to our preferred default flags-: ${CXXFLAGS="-Wall -Wextra -Wunused -O2"}-: ${CFLAGS="-Wall -Wextra -Wunused -O2"}+: ${CXXFLAGS="-Wall -Wextra -Wunused -O2 -fvisibility=hidden"}+: ${CFLAGS="-Wall -Wextra -Wunused -O2 -fvisibility=hidden"}  ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS'@@ -11808,7 +11808,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.2.2, which was+This file was extended by ugrep $as_me 7.3.0, which was generated by GNU Autoconf 2.72.  Invocation command line was    CONFIG_FILES    = $CONFIG_FILES@@ -11881,7 +11881,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.2.2+ugrep config.status 7.3.0 configured by $0, generated by GNU Autoconf 2.72,   with options \\"\$ac_cs_config\\" 

configure.ac

@@ -1,13 +1,13 @@-AC_INIT([ugrep],[7.2.2],[https://github.com/Genivia/ugrep/issues],[ugrep],[https://ugrep.com])+AC_INIT([ugrep],[7.3.0],[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.])+AC_COPYRIGHT([Copyright (C) 2019-2025 Robert van Engelen, Genivia Inc.])  AC_CONFIG_MACRO_DIR([m4])  # if CXXFLAGS is undefined, set it to our preferred default flags-: ${CXXFLAGS="-Wall -Wextra -Wunused -O2"}-: ${CFLAGS="-Wall -Wextra -Wunused -O2"}+: ${CXXFLAGS="-Wall -Wextra -Wunused -O2 -fvisibility=hidden"}+: ${CFLAGS="-Wall -Wextra -Wunused -O2 -fvisibility=hidden"}  AC_LANG([C++]) AX_CXX_COMPILE_STDCXX([11],[ext],[mandatory])

include/reflex/convert.h

@@ -30,7 +30,7 @@ @file      convert.h @brief     RE/flex regex converter @author    Robert van Engelen - engelen@genivia.com-@copyright (c) 2016-2020, Robert van Engelen, Genivia Inc. All rights reserved.+@copyright (c) 2016-2025, Robert van Engelen, Genivia Inc. All rights reserved. @copyright (c) BSD-3 License - see LICENSE.txt */ @@ -69,7 +69,7 @@ namespace convert_flag {   const convert_flag_type dotall     = 0x0080; ///< convert `.` (dot) to match all, same as `(?s)`   const convert_flag_type freespace  = 0x0100; ///< convert regex by removing spacing, same as `(?x)`   const convert_flag_type notnewline = 0x0200; ///< inverted character classes and \s do not match newline `\n`-  const convert_flag_type permissive = 0x0400; ///< convert Unicode to compact UTF-8 patterns, permits some invalid UTF-8 sequences+  const convert_flag_type permissive = 0x0400; ///< convert Unicode to more compact UTF-8 patterns, permits some invalid UTF-8 sequences   const convert_flag_type closing    = 0x8000; ///< permit matching ) literally when it has no opening ( } 

include/reflex/pattern.h

@@ -30,7 +30,7 @@ @file      pattern.h @brief     RE/flex regular expression pattern compiler @author    Robert van Engelen - engelen@genivia.com-@copyright (c) 2016-2020, Robert van Engelen, Genivia Inc. All rights reserved.+@copyright (c) 2016-2025, Robert van Engelen, Genivia Inc. All rights reserved. @copyright (c) BSD-3 License - see LICENSE.txt */ @@ -536,10 +536,10 @@ class Pattern {   typedef std::map<Position,Positions> Follow;   typedef std::pair<Chars,Positions>   Move;   typedef std::list<Move>              Moves;-  inline static void pos_insert(Positions& s1, const Positions& s2) { s1.insert(s1.end(), s2.begin(), s2.end()); }-  inline static void pos_add(Positions& s, const Position& e) { s.insert(s.end(), e); }-  inline static void lazy_insert(Lazypos& s1, const Lazypos& s2) { s1.insert(s1.end(), s2.begin(), s2.end()); }-  inline static void lazy_add(Lazypos& s, const Lazy i, Location p) { s.insert(s.end(), Position(p).lazy(i)); }+  static inline void pos_insert(Positions& s1, const Positions& s2) { s1.insert(s1.end(), s2.begin(), s2.end()); }+  static inline void pos_add(Positions& s, const Position& e) { s.insert(s.end(), e); }+  static inline void lazy_insert(Lazypos& s1, const Lazypos& s2) { s1.insert(s1.end(), s2.begin(), s2.end()); }+  static inline void lazy_add(Lazypos& s, const Lazy i, Location p) { s.insert(s.end(), Position(p).lazy(i)); } #ifndef WITH_TREE_DFA   /// Tree DFA constructed from string patterns.   struct Tree {

include/reflex/posix.h

@@ -44,6 +44,7 @@ namespace reflex {  namespace Posix { +/// Tables of character ranges [lo,hi] for each character class class Tables {  public:   struct lt {@@ -54,6 +55,7 @@ class Tables {   Range range; }; +/// Return table entry pointer to [lo,hi] range of characters for the given POSIX class name, or return NULL const int * range(const char *);  } // namespace Posix

include/reflex/unicode.h

@@ -30,7 +30,7 @@ @file      unicode.h @brief     Get Unicode character class ranges and UTF-8 regex translations @author    Robert van Engelen - engelen@genivia.com-@copyright (c) 2016-2020, Robert van Engelen, Genivia Inc. All rights reserved.+@copyright (c) 2016-2025, Robert van Engelen, Genivia Inc. All rights reserved. @copyright (c) BSD-3 License - see LICENSE.txt */ @@ -48,6 +48,8 @@ class Tables : public Posix::Tables {   Tables();   typedef std::map<int,const int*> Compose;   Compose compose;+  static int toupper(int c);+  static int tolower(int c);  private:   void block_scripts();   void language_scripts();@@ -55,9 +57,17 @@ class Tables : public Posix::Tables {   void composer(); }; +/// Return table entry pointer to [lo,hi] range of characters for the given Unicode class name, or return NULL const int * range(const char *);++/// Normalize Unicode by composition of prev and next characters into one, or return -1 int compose(int, int); +/// Unicode translations between lower case and upper case letters+int toupper(int c);+int tolower(int c);+int invcase(int c);+ } // namespace Unicode  } // namespace reflex

lib/Makefile.am

@@ -42,6 +42,7 @@ libreflex_a_SOURCES = \ 	block_scripts.cpp \ 	language_scripts.cpp \ 	letter_scripts.cpp \+	letter_case.cpp \ 	composer.cpp  # separately compile matcher_avx2.cpp and matcher_avx512bw with AVX2 optimizations enabled

lib/Makefile.in

@@ -128,6 +128,7 @@ am_libreflex_a_OBJECTS = libreflex_a-convert.$(OBJEXT) \ 	libreflex_a-block_scripts.$(OBJEXT) \ 	libreflex_a-language_scripts.$(OBJEXT) \ 	libreflex_a-letter_scripts.$(OBJEXT) \+	libreflex_a-letter_case.$(OBJEXT) \ 	libreflex_a-composer.$(OBJEXT) libreflex_a_OBJECTS = $(am_libreflex_a_OBJECTS) AM_V_P = $(am__v_P_@AM_V@)@@ -152,6 +153,7 @@ am__depfiles_remade = ./$(DEPDIR)/libreflex_a-block_scripts.Po \ 	./$(DEPDIR)/libreflex_a-error.Po \ 	./$(DEPDIR)/libreflex_a-input.Po \ 	./$(DEPDIR)/libreflex_a-language_scripts.Po \+	./$(DEPDIR)/libreflex_a-letter_case.Po \ 	./$(DEPDIR)/libreflex_a-letter_scripts.Po \ 	./$(DEPDIR)/libreflex_a-matcher.Po \ 	./$(DEPDIR)/libreflex_a-matcher_avx2.Po \@@ -392,6 +394,7 @@ libreflex_a_SOURCES = \ 	block_scripts.cpp \ 	language_scripts.cpp \ 	letter_scripts.cpp \+	letter_case.cpp \ 	composer.cpp  all: all-am@@ -449,6 +452,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libreflex_a-error.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libreflex_a-input.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libreflex_a-language_scripts.Po@am__quote@ # am--include-marker+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libreflex_a-letter_case.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libreflex_a-letter_scripts.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libreflex_a-matcher.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libreflex_a-matcher_avx2.Po@am__quote@ # am--include-marker@@ -721,6 +725,20 @@ libreflex_a-letter_scripts.obj: letter_scripts.cpp @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libreflex_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libreflex_a-letter_scripts.obj `if test -f 'letter_scripts.cpp'; then $(CYGPATH_W) 'letter_scripts.cpp'; else $(CYGPATH_W) '$(srcdir)/letter_scripts.cpp'; fi` +libreflex_a-letter_case.o: letter_case.cpp+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libreflex_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libreflex_a-letter_case.o -MD -MP -MF $(DEPDIR)/libreflex_a-letter_case.Tpo -c -o libreflex_a-letter_case.o `test -f 'letter_case.cpp' || echo '$(srcdir)/'`letter_case.cpp+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libreflex_a-letter_case.Tpo $(DEPDIR)/libreflex_a-letter_case.Po+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='letter_case.cpp' object='libreflex_a-letter_case.o' libtool=no @AMDEPBACKSLASH@+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libreflex_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libreflex_a-letter_case.o `test -f 'letter_case.cpp' || echo '$(srcdir)/'`letter_case.cpp++libreflex_a-letter_case.obj: letter_case.cpp+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libreflex_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libreflex_a-letter_case.obj -MD -MP -MF $(DEPDIR)/libreflex_a-letter_case.Tpo -c -o libreflex_a-letter_case.obj `if test -f 'letter_case.cpp'; then $(CYGPATH_W) 'letter_case.cpp'; else $(CYGPATH_W) '$(srcdir)/letter_case.cpp'; fi`+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libreflex_a-letter_case.Tpo $(DEPDIR)/libreflex_a-letter_case.Po+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='letter_case.cpp' object='libreflex_a-letter_case.obj' libtool=no @AMDEPBACKSLASH@+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libreflex_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libreflex_a-letter_case.obj `if test -f 'letter_case.cpp'; then $(CYGPATH_W) 'letter_case.cpp'; else $(CYGPATH_W) '$(srcdir)/letter_case.cpp'; fi`+ libreflex_a-composer.o: composer.cpp @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libreflex_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libreflex_a-composer.o -MD -MP -MF $(DEPDIR)/libreflex_a-composer.Tpo -c -o libreflex_a-composer.o `test -f 'composer.cpp' || echo '$(srcdir)/'`composer.cpp @am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libreflex_a-composer.Tpo $(DEPDIR)/libreflex_a-composer.Po@@ -865,6 +883,7 @@ distclean: distclean-am 	-rm -f ./$(DEPDIR)/libreflex_a-error.Po 	-rm -f ./$(DEPDIR)/libreflex_a-input.Po 	-rm -f ./$(DEPDIR)/libreflex_a-language_scripts.Po+	-rm -f ./$(DEPDIR)/libreflex_a-letter_case.Po 	-rm -f ./$(DEPDIR)/libreflex_a-letter_scripts.Po 	-rm -f ./$(DEPDIR)/libreflex_a-matcher.Po 	-rm -f ./$(DEPDIR)/libreflex_a-matcher_avx2.Po@@ -928,6 +947,7 @@ maintainer-clean: maintainer-clean-am 	-rm -f ./$(DEPDIR)/libreflex_a-error.Po 	-rm -f ./$(DEPDIR)/libreflex_a-input.Po 	-rm -f ./$(DEPDIR)/libreflex_a-language_scripts.Po+	-rm -f ./$(DEPDIR)/libreflex_a-letter_case.Po 	-rm -f ./$(DEPDIR)/libreflex_a-letter_scripts.Po 	-rm -f ./$(DEPDIR)/libreflex_a-matcher.Po 	-rm -f ./$(DEPDIR)/libreflex_a-matcher_avx2.Po

lib/convert.cpp

@@ -30,7 +30,7 @@ @file      convert.cpp @brief     RE/flex regex converter @author    Robert van Engelen - engelen@genivia.com-@copyright (c) 2016-2020, Robert van Engelen, Genivia Inc. All rights reserved.+@copyright (c) 2016-2025, Robert van Engelen, Genivia Inc. All rights reserved. @copyright (c) BSD-3 License - see LICENSE.txt */ @@ -72,12 +72,12 @@ static const char regex_abtnvfr[] = "abtnvfr"; //                                                                            // //////////////////////////////////////////////////////////////////////////////// -inline int lowercase(int c)+static inline int lowercase(int c) {   return static_cast<unsigned char>(c | 0x20); } -inline int uppercase(int c)+static inline int uppercase(int c) {   return static_cast<unsigned char>(c & ~0x20); }@@ -190,21 +190,21 @@ static std::string unicode_class(const char *s, int esc, convert_flag_type flags //                                                                            // //////////////////////////////////////////////////////////////////////////////// -inline void enable_modifier(int c, const char *pattern, size_t pos, std::map<size_t,std::string>& mod, size_t lev)+static inline void enable_modifier(int c, const char *pattern, size_t pos, std::map<size_t,std::string>& mod, size_t lev) {   if (c != 'i' && c != 'm' && c != 's' && c != 'u' && c != 'x')     throw regex_error(regex_error::invalid_modifier, pattern, pos);   mod[lev].push_back(c); } -inline void disable_modifier(int c, const char *pattern, size_t pos, std::map<size_t,std::string>& mod, size_t lev)+static inline void disable_modifier(int c, const char *pattern, size_t pos, std::map<size_t,std::string>& mod, size_t lev) {   if (c != 'i' && c != 'm' && c != 's' && c != 'u' && c != 'x')     throw regex_error(regex_error::invalid_modifier, pattern, pos);   mod[lev].push_back(uppercase(c)); } -inline bool is_modified(const std::map<size_t,std::string>& mod, int c)+static inline bool is_modified(const std::map<size_t,std::string>& mod, int c) {   for (std::map<size_t,std::string>::const_reverse_iterator i = mod.rbegin(); i != mod.rend(); ++i)   {@@ -219,7 +219,7 @@ inline bool is_modified(const std::map<size_t,std::string>& mod, int c)   return false; } -inline int hex_or_octal_escape(const char *signature)+static inline int hex_or_octal_escape(const char *signature) {   if (supports_escape(signature, 'x'))     return 'x';@@ -390,12 +390,11 @@ static std::string convert_posix_ranges(const ORanges<int>& ranges, const char *  static void convert_anycase_ranges(ORanges<int>& ranges) {-  ORanges<int> letters;-  letters.insert('A', 'Z');-  letters.insert('a', 'z');-  letters &= ranges;-  for (ORanges<int>::const_iterator i = letters.begin(); i != letters.end(); ++i)-    ranges.insert(i->first ^ 0x20, (i->second - 1) ^ 0x20);+  ORanges<int> anyranges(ranges);+  for (ORanges<int>::const_iterator i = ranges.begin(); i != ranges.end(); ++i)+    for (int wc = i->first; wc < i->second; ++wc)+      anyranges.insert(Unicode::invcase(wc));+  ranges.swap(anyranges); }  static std::string convert_ranges(const char *pattern, size_t pos, ORanges<int>& ranges, const std::map<size_t,std::string>& mod, convert_flag_type flags, const char *signature, const char *par, bool& nl)@@ -508,7 +507,7 @@ static void expand_list(const char *pattern, size_t len, size_t& loc, size_t& po       c = utf8(s, &s);       while (true)       {-        // try combining one or more Unicode combining characters, if any+        // normalize by combining two or more Unicode combining characters, if any are composable         pos = s - pattern;         if (pos >= len || (*s & 0xC0) != 0xC0)           break;@@ -634,6 +633,7 @@ static int insert_escape(const char *pattern, size_t len, size_t& pos, convert_f       ranges.insert(0, 9);       ranges.insert(11, 0xFF);     }+    return -1;   }   else if (c >= '0' && c <= '7')   {@@ -872,7 +872,7 @@ 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'))+    if (is_modified(mod, 'a') || is_modified(mod, 'i'))       convert_anycase_ranges(subtract);     ranges -= subtract;   }@@ -885,7 +885,7 @@ static void subtract_list(const char *pattern, size_t len, size_t& pos, convert_     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'))+    if (is_modified(mod, 'a') || is_modified(mod, 'i'))       convert_anycase_ranges(subtract);     ranges -= subtract;     if (subpos + 1 < list.size())@@ -926,7 +926,7 @@ 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<size_t,std::string>& mod, ORanges<int>& ranges) {   // always convert case-insensitive Unicode negated character classes (modifier 'a')-  if (is_modified(mod, 'a'))+  if (is_modified(mod, 'a') || is_modified(mod, 'i'))     convert_anycase_ranges(ranges);   if (is_modified(mod, 'u'))   {@@ -966,8 +966,6 @@ 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);@@ -1037,7 +1035,7 @@ static void insert_list(const char *pattern, size_t len, size_t& pos, convert_fl         c = utf8(s, &s);         while (true)         {-          // try combining one or more Unicode combining characters, if any+          // normalize by combining two or more Unicode combining characters, if any are composable           pos = s - pattern;           if (pos >= len || (*s & 0xC0) != 0xC0)             break;@@ -1051,8 +1049,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 (pc >= 'a' && pc <= 'z' && c >= 'A' && c <= 'Z' && is_modified(mod, 'a'))+          c = lowercase(c);         if (c == -1 || pc > c)           throw regex_error(regex_error::invalid_class_range, pattern, pos);         ranges.insert(pc, c);@@ -1131,77 +1129,69 @@ static void convert_escape_char(const char *pattern, size_t len, size_t& loc, si     }     else if (!supports_escape(signature, c))     {+      regex.append(&pattern[loc], pos - loc - 1);       if (c == 'A')       {         if (!supports_escape(signature, '`'))           throw regex_error(regex_error::invalid_anchor, pattern, pos);         // translate \A to \`-        regex.append(&pattern[loc], pos - loc - 1).append("\\`");-        loc = pos + 1;+        regex.append("\\`");       }       else if (c == 'z')       {         if (!supports_escape(signature, '\''))           throw regex_error(regex_error::invalid_anchor, pattern, pos);         // translate \z to \'-        regex.append(&pattern[loc], pos - loc - 1).append("\\'");-        loc = pos + 1;+        regex.append("\\'");       }       else if (c == 'Z')       {         if (!supports_escape(signature, 'z') || !supports_modifier(signature, '='))           throw regex_error(regex_error::invalid_anchor, pattern, pos);         // translate \Z to (?=(\r?\n)?\z)-        regex.append(&pattern[loc], pos - loc - 1).append("(?=(\\r?\\n)?\\z)");-        loc = pos + 1;+        regex.append("(?=(\\r?\\n)?\\z)");       }       else if (c == 'b')       {         if (!supports_escape(signature, 'y'))           throw regex_error(regex_error::invalid_anchor, pattern, pos);         // translate \b to \y-        regex.append(&pattern[loc], pos - loc - 1).append("\\y");-        loc = pos + 1;+        regex.append("\\y");       }       else if (c == 'y')       {         if (!supports_escape(signature, 'b'))           throw regex_error(regex_error::invalid_anchor, pattern, pos);         // translate \y to \b-        regex.append(&pattern[loc], pos - loc - 1).append("\\b");-        loc = pos + 1;+        regex.append("\\b");       }       else if (c == 'B')       {         if (!supports_escape(signature, 'Y'))           throw regex_error(regex_error::invalid_anchor, pattern, pos);         // translate \B to \Y-        regex.append(&pattern[loc], pos - loc - 1).append("\\y");-        loc = pos + 1;+        regex.append("\\y");       }       else if (c == 'Y')       {         if (!supports_escape(signature, 'B'))           throw regex_error(regex_error::invalid_anchor, pattern, pos);         // translate \Y to \B-        regex.append(&pattern[loc], pos - loc - 1).append("\\b");-        loc = pos + 1;+        regex.append("\\b");       }       else if (c == '<')       {         if (!supports_escape(signature, 'b') || !supports_escape(signature, 'w') || !supports_modifier(signature, '='))           throw regex_error(regex_error::invalid_anchor, pattern, pos);         // translate \< to \b(?=\w)-        regex.append(&pattern[loc], pos - loc - 1).append("\\b(?=\\w)");-        loc = pos + 1;+        regex.append("\\b(?=\\w)");       }       else if (c == '>')       {         if (!supports_escape(signature, 'b') || !supports_escape(signature, 'w') || !supports_modifier(signature, '<'))           throw regex_error(regex_error::invalid_anchor, pattern, pos);         // translate \> to \b(?<=\w)-        regex.append(&pattern[loc], pos - loc - 1).append("\\b(?<=\\w)");-        loc = pos + 1;+        regex.append("\\b(?<=\\w)");       }       else       {@@ -1211,9 +1201,9 @@ static void convert_escape_char(const char *pattern, size_t len, size_t& loc, si         if (s == NULL)           throw regex_error(regex_error::invalid_escape, pattern, pos);         int wc = static_cast<int>(s - regex_abtnvfr + '\a');-        regex.append(&pattern[loc], pos - loc - 1).append(latin1(wc, wc, esc));-        loc = pos + 1;+        regex.append(latin1(wc, wc, esc));       }+      loc = pos + 1;     }     else if ((c == 'g' || c == 'k') && pos + 2 < len && pattern[pos + 1] == '{')     {@@ -1301,22 +1291,12 @@ static void convert_escape(const char *pattern, size_t len, size_t& loc, size_t&       throw regex_error(regex_error::invalid_escape, pattern, pos);     if (wc == '\n')       nl = true;-    if (std::isalpha(static_cast<unsigned char>(wc)) && is_modified(mod, 'i'))-    {-      // anycase: translate A to [Aa]-      regex.append(&pattern[loc], pos - loc - 1).push_back('[');-      regex.push_back(wc);-      regex.push_back(wc ^ 0x20);-      regex.push_back(']');-    }+    regex.append(&pattern[loc], pos - loc - 1);+    int esc = hex_or_octal_escape(signature);+    if (is_modified(mod, 'u'))+      regex.append(utf8(wc, wc, esc, par));     else-    {-      int esc = hex_or_octal_escape(signature);-      if (is_modified(mod, 'u'))-        regex.append(&pattern[loc], pos - loc - 1).append(utf8(wc, wc, esc, par));-      else-        regex.append(&pattern[loc], pos - loc - 1).append(latin1(wc, wc, esc));-    }+      regex.append(latin1(wc, wc, esc));     pos = k - 1;     loc = pos + 1;   }@@ -1339,40 +1319,30 @@ static void convert_escape(const char *pattern, size_t len, size_t& loc, size_t&           throw regex_error(regex_error::invalid_escape, pattern, k - 2);         wc = 0x010000 - 0xDC00 + ((wc - 0xD800) << 10) + c2;       }+      regex.append(&pattern[loc], pos - loc - 1);       if (supports_escape(signature, 'p'))       {         // translate \u{X}, \uXXXX (convert_flag::u4) and \x{X} to \xXX and \x{X}         char buf[16];-        regex.append(&pattern[loc], pos - loc - 1).append(hex_escape(buf, wc));+        regex.append(hex_escape(buf, wc));       }       else       {         if (wc <= 0xFF)         {           // translate \u{X}, \u00XX (convert_flag::u4) and \x{X} to \xXX-          if (std::isalpha(static_cast<unsigned char>(wc)) && is_modified(mod, 'i'))-          {-            // anycase: translate A to [Aa]-            regex.append(&pattern[loc], pos - loc - 1).push_back('[');-            regex.push_back(wc);-            regex.push_back(wc ^ 0x20);-            regex.push_back(']');-          }+          int esc = hex_or_octal_escape(signature);+          if (is_modified(mod, 'u'))+            regex.append(utf8(wc, wc, esc, par));           else-          {-            int esc = hex_or_octal_escape(signature);-            if (is_modified(mod, 'u'))-              regex.append(&pattern[loc], pos - loc - 1).append(utf8(wc, wc, esc, par));-            else-              regex.append(&pattern[loc], pos - loc - 1).append(latin1(wc, wc, esc));-          }+            regex.append(latin1(wc, wc, esc));         }         else if (is_modified(mod, 'u'))         {           // translate \u{X}, \uXXXX, \uDXXX\uDYYY, and \x{X} to UTF-8 pattern           char buf[8];           buf[utf8(wc, buf)] = '\0';-          regex.append(&pattern[loc], pos - loc - 1).append(par).append(buf).push_back(')');+          regex.append(par).append(buf).push_back(')');         }         else         {@@ -1447,23 +1417,23 @@ static void convert_escape(const char *pattern, size_t len, size_t& loc, size_t&   else if (c == 's' && (flags & convert_flag::notnewline))   {     // \s is the same as \p{Space} without newline \n+    regex.append(&pattern[loc], pos - loc - 1);     if (is_modified(mod, 'u'))     {       if (supports_escape(signature, 'p'))       {-        regex.append(&pattern[loc], pos - loc - 1).append("[\\t\\x0b-\\r\\x85\\p{Z}]");+        regex.append("[\\t\\x0b-\\r\\x85\\p{Z}]");       }       else       {         ORanges<int> ranges;         insert_escape_class(pattern, pos, flags, mod, ranges);-        regex.append(&pattern[loc], pos - loc - 1);         regex.append(convert_ranges(pattern, pos, ranges, mod, flags, signature, par, nl));       }     }     else     {-      regex.append(&pattern[loc], pos - loc - 1).append("[\\h\\x0b-\\r\\x85\\xa0]");+      regex.append("[\\h\\x0b-\\r\\x85\\xa0]");     }     loc = pos + 1;   }@@ -2158,20 +2128,21 @@ std::string convert(const char *pattern, const char *signature, convert_flag_typ           else if (!supports_escape(signature, 'p'))           {             // \p is not supported: this indicates that . is matches as non-Unicode but we want to match Unicode+            regex.append(&pattern[loc], pos - loc);             if ((flags & convert_flag::lex))             {               // lex . matches any byte (including invalid UTF-8) and any Unicode character e.g. in a catch-all-else rule               if (supports_modifier(signature, 's') || supports_escape(signature, '.'))-                regex.append(&pattern[loc], pos - loc).append(par).append(".[\\x80-\\xbf]*)");+                regex.append(par).append(".[\\x80-\\xbf]*)");               else-                regex.append(&pattern[loc], pos - loc).append(par).append("[^\\n][\\x80-\\xbf]*)");+                regex.append(par).append("[^\\n][\\x80-\\xbf]*)");             }             else             {               if (is_modified(mod, 's'))-                regex.append(&pattern[loc], pos - loc).append(par).append("[^\\x80-\\xbf][\\x80-\\xbf]*)");+                regex.append(par).append("[^\\x80-\\xbf][\\x80-\\xbf]*)");               else-                regex.append(&pattern[loc], pos - loc).append(par).append("[^\\n\\x80-\\xbf][\\x80-\\xbf]*)");+                regex.append(par).append("[^\\n\\x80-\\xbf][\\x80-\\xbf]*)");             }             loc = pos + 1;           }@@ -2245,7 +2216,7 @@ std::string convert(const char *pattern, const char *signature, convert_flag_typ         {           if (is_modified(mod, 'i'))           {-            // anycase: translate A to [Aa]+            // anycase: translate ASCII A to [Aa]             regex.append(&pattern[loc], pos - loc).push_back('[');             regex.push_back(c);             regex.push_back(c ^ 0x20);@@ -2263,7 +2234,7 @@ std::string convert(const char *pattern, const char *signature, convert_flag_typ           c = utf8(s, &s);           while (true)           {-            // try combining one or more Unicode combining characters, if any+            // normalize by combining two or more Unicode combining characters, if any are composable             pos = s - pattern;             if (pos >= len || (*s & 0xC0) != 0xC0)               break;@@ -2275,22 +2246,43 @@ std::string convert(const char *pattern, const char *signature, convert_flag_typ           }           char buf[8];           size_t size = utf8(c, buf);-          if (pos < len &&-              !supports_escape(signature, 'p') &&-              (pattern[pos] == '*' ||-               ((flags & convert_flag::basic) && pos + 1 < len ?-                (pattern[pos] == '\\' && (pattern[pos + 1] == '?' || pattern[pos + 1] == '+' || pattern[pos + 1] == '{')) :-                (pattern[pos] == '?' || pattern[pos] == '+' || pattern[pos] == '{'))))+          if (is_modified(mod, 'a'))           {-            // group normalized Unicode character as UTF-8-            regex.append(par).append(buf, size).push_back(')');-            loc = pos--;+            int a = Unicode::invcase(c);+            if (a != c)+            {+              // save normalized Unicode letter and its alternative lower/upper case as UTF-8+              regex.append(par).append(buf, size).push_back('|');+              size = utf8(a, buf);+              regex.append(buf, size).push_back(')');+              loc = pos--;+            }+            else+            {+              // save normalized Unicode character as UTF-8+              regex.append(buf, size);+              loc = pos--;+            }           }-          else if (pos > loc)+          else           {-            // save normalized Unicode character as UTF-8-            regex.append(buf, size);-            loc = pos--;+            if (pos < len &&+                !supports_escape(signature, 'p') &&+                (pattern[pos] == '*' ||+                 ((flags & convert_flag::basic) && pos + 1 < len ?+                  (pattern[pos] == '\\' && (pattern[pos + 1] == '?' || pattern[pos + 1] == '+' || pattern[pos + 1] == '{')) :+                  (pattern[pos] == '?' || pattern[pos] == '+' || pattern[pos] == '{'))))+            {+              // group normalized Unicode character as UTF-8+              regex.append(par).append(buf, size).push_back(')');+              loc = pos--;+            }+            else if (pos > loc)+            {+              // save normalized Unicode character as UTF-8+              regex.append(buf, size);+              loc = pos--;+            }           }         }         anc = false;

lib/letter_case.cpp

new file mode 100644@@ -0,0 +1,3322 @@+// Converted from http://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt by letter_case.l+#include <reflex/unicode.h>+#include <cstdlib>++static int cmpint2(const void *p, const void *q)+{+  int a = *static_cast<const int*>(p);+  int b = *static_cast<const int*>(q);+  return a < b ? -1 : a > b ? 1 : 0;+}++int reflex::Unicode::Tables::tolower(int c)+{+  static const int ul[] = {+    65, 97,+    66, 98,+    67, 99,+    68, 100,+    69, 101,+    70, 102,+    71, 103,+    72, 104,+    73, 105,+    74, 106,+    75, 107,+    76, 108,+    77, 109,+    78, 110,+    79, 111,+    80, 112,+    81, 113,+    82, 114,+    83, 115,+    84, 116,+    85, 117,+    86, 118,+    87, 119,+    88, 120,+    89, 121,+    90, 122,+    192, 224,+    193, 225,+    194, 226,+    195, 227,+    196, 228,+    197, 229,+    198, 230,+    199, 231,+    200, 232,+    201, 233,+    202, 234,+    203, 235,+    204, 236,+    205, 237,+    206, 238,+    207, 239,+    208, 240,+    209, 241,+    210, 242,+    211, 243,+    212, 244,+    213, 245,+    214, 246,+    216, 248,+    217, 249,+    218, 250,+    219, 251,+    220, 252,+    221, 253,+    222, 254,+    256, 257,+    258, 259,+    260, 261,+    262, 263,+    264, 265,+    266, 267,+    268, 269,+    270, 271,+    272, 273,+    274, 275,+    276, 277,+    278, 279,+    280, 281,+    282, 283,+    284, 285,+    286, 287,+    288, 289,+    290, 291,+    292, 293,+    294, 295,+    296, 297,+    298, 299,+    300, 301,+    302, 303,+    306, 307,+    308, 309,+    310, 311,+    313, 314,+    315, 316,+    317, 318,+    319, 320,+    321, 322,+    323, 324,+    325, 326,+    327, 328,+    330, 331,+    332, 333,+    334, 335,+    336, 337,+    338, 339,+    340, 341,+    342, 343,+    344, 345,+    346, 347,+    348, 349,+    350, 351,+    352, 353,+    354, 355,+    356, 357,+    358, 359,+    360, 361,+    362, 363,+    364, 365,+    366, 367,+    368, 369,+    370, 371,+    372, 373,+    374, 375,+    376, 255,+    377, 378,+    379, 380,+    381, 382,+    385, 595,+    386, 387,+    388, 389,+    390, 596,+    391, 392,+    394, 599,+    395, 396,+    398, 600,+    399, 601,+    400, 603,+    401, 402,+    403, 608,+    404, 611,+    406, 617,+    407, 616,+    408, 409,+    412, 623,+    413, 626,+    416, 417,+    418, 419,+    420, 421,+    423, 424,+    425, 643,+    428, 429,+    430, 648,+    431, 432,+    433, 650,+    434, 651,+    435, 436,+    437, 438,+    439, 658,+    440, 441,+    444, 445,+    452, 454,+    455, 457,+    458, 460,+    461, 462,+    463, 464,+    465, 466,+    467, 468,+    469, 470,+    471, 472,+    473, 474,+    475, 476,+    478, 479,+    480, 481,+    482, 483,+    484, 485,+    486, 487,+    488, 489,+    490, 491,+    492, 493,+    494, 495,+    497, 499,+    500, 501,+    504, 505,+    506, 507,+    508, 509,+    510, 511,+    512, 513,+    514, 515,+    516, 517,+    518, 519,+    520, 521,+    522, 523,+    524, 525,+    526, 527,+    528, 529,+    530, 531,+    532, 533,+    534, 535,+    536, 537,+    538, 539,+    540, 541,+    542, 543,+    544, 414,+    546, 547,+    548, 549,+    550, 551,+    552, 553,+    554, 555,+    556, 557,+    558, 559,+    560, 561,+    562, 563,+    570, 11365,+    571, 572,+    573, 410,+    574, 11366,+    577, 578,+    579, 384,+    580, 649,+    581, 652,+    582, 583,+    584, 585,+    588, 589,+    590, 591,+    880, 881,+    882, 883,+    886, 887,+    902, 940,+    904, 941,+    905, 942,+    906, 943,+    908, 972,+    910, 973,+    911, 974,+    913, 945,+    914, 946,+    915, 947,+    916, 948,+    917, 949,+    918, 950,+    919, 951,+    920, 952,+    921, 953,+    922, 954,+    923, 955,+    924, 956,+    925, 957,+    926, 958,+    927, 959,+    928, 960,+    929, 961,+    931, 963,+    932, 964,+    933, 965,+    934, 966,+    935, 967,+    936, 968,+    937, 969,+    938, 970,+    939, 971,+    994, 995,+    996, 997,+    998, 999,+    1000, 1001,+    1002, 1003,+    1004, 1005,+    1006, 1007,+    1015, 1016,+    1018, 1019,+    1021, 891,+    1022, 892,+    1023, 893,+    1024, 1104,+    1025, 1105,+    1026, 1106,+    1027, 1107,+    1028, 1108,+    1029, 1109,+    1030, 1110,+    1031, 1111,+    1032, 1112,+    1033, 1113,+    1034, 1114,+    1035, 1115,+    1036, 1116,+    1037, 1117,+    1038, 1118,+    1039, 1119,+    1040, 1072,+    1041, 1073,+    1042, 1074,+    1043, 1075,+    1044, 1076,+    1045, 1077,+    1046, 1078,+    1047, 1079,+    1048, 1080,+    1049, 1081,+    1050, 1082,+    1051, 1083,+    1052, 1084,+    1053, 1085,+    1054, 1086,+    1055, 1087,+    1056, 1088,+    1057, 1089,+    1058, 1090,+    1059, 1091,+    1060, 1092,+    1061, 1093,+    1062, 1094,+    1063, 1095,+    1064, 1096,+    1065, 1097,+    1066, 1098,+    1067, 1099,+    1068, 1100,+    1069, 1101,+    1070, 1102,+    1071, 1103,+    1120, 1121,+    1122, 1123,+    1124, 1125,+    1126, 1127,+    1128, 1129,+    1130, 1131,+    1132, 1133,+    1134, 1135,+    1136, 1137,+    1138, 1139,+    1140, 1141,+    1142, 1143,+    1144, 1145,+    1146, 1147,+    1148, 1149,+    1150, 1151,+    1152, 1153,+    1162, 1163,+    1164, 1165,+    1166, 1167,+    1168, 1169,+    1170, 1171,+    1172, 1173,+    1174, 1175,+    1176, 1177,+    1178, 1179,+    1180, 1181,+    1182, 1183,+    1184, 1185,+    1186, 1187,+    1188, 1189,+    1190, 1191,+    1192, 1193,+    1194, 1195,+    1196, 1197,+    1198, 1199,+    1200, 1201,+    1202, 1203,+    1204, 1205,+    1206, 1207,+    1208, 1209,+    1210, 1211,+    1212, 1213,+    1214, 1215,+    1217, 1218,+    1219, 1220,+    1221, 1222,+    1223, 1224,+    1225, 1226,+    1227, 1228,+    1229, 1230,+    1232, 1233,+    1234, 1235,+    1236, 1237,+    1238, 1239,+    1240, 1241,+    1242, 1243,+    1244, 1245,+    1246, 1247,+    1248, 1249,+    1250, 1251,+    1252, 1253,+    1254, 1255,+    1256, 1257,+    1258, 1259,+    1260, 1261,+    1262, 1263,+    1264, 1265,+    1266, 1267,+    1268, 1269,+    1270, 1271,+    1272, 1273,+    1274, 1275,+    1276, 1277,+    1278, 1279,+    1280, 1281,+    1282, 1283,+    1284, 1285,+    1286, 1287,+    1288, 1289,+    1290, 1291,+    1292, 1293,+    1294, 1295,+    1296, 1297,+    1298, 1299,+    1300, 1301,+    1302, 1303,+    1304, 1305,+    1306, 1307,+    1308, 1309,+    1310, 1311,+    1312, 1313,+    1314, 1315,+    1316, 1317,+    1318, 1319,+    1320, 1321,+    1322, 1323,+    1324, 1325,+    1326, 1327,+    1329, 1377,+    1330, 1378,+    1331, 1379,+    1332, 1380,+    1333, 1381,+    1334, 1382,+    1335, 1383,+    1336, 1384,+    1337, 1385,+    1338, 1386,+    1339, 1387,+    1340, 1388,+    1341, 1389,+    1342, 1390,+    1343, 1391,+    1344, 1392,+    1345, 1393,+    1346, 1394,+    1347, 1395,+    1348, 1396,+    1349, 1397,+    1350, 1398,+    1351, 1399,+    1352, 1400,+    1353, 1401,+    1354, 1402,+    1355, 1403,+    1356, 1404,+    1357, 1405,+    1358, 1406,+    1359, 1407,+    1360, 1408,+    1361, 1409,+    1362, 1410,+    1363, 1411,+    1364, 1412,+    1365, 1413,+    1366, 1414,+    4256, 11520,+    4257, 11521,+    4258, 11522,+    4259, 11523,+    4260, 11524,+    4261, 11525,+    4262, 11526,+    4263, 11527,+    4264, 11528,+    4265, 11529,+    4266, 11530,+    4267, 11531,+    4268, 11532,+    4269, 11533,+    4270, 11534,+    4271, 11535,+    4272, 11536,+    4273, 11537,+    4274, 11538,+    4275, 11539,+    4276, 11540,+    4277, 11541,+    4278, 11542,+    4279, 11543,+    4280, 11544,+    4281, 11545,+    4282, 11546,+    4283, 11547,+    4284, 11548,+    4285, 11549,+    4286, 11550,+    4287, 11551,+    4288, 11552,+    4289, 11553,+    4290, 11554,+    4291, 11555,+    4292, 11556,+    4293, 11557,+    4295, 11559,+    4301, 11565,+    7680, 7681,+    7682, 7683,+    7684, 7685,+    7686, 7687,+    7688, 7689,+    7690, 7691,+    7692, 7693,+    7694, 7695,+    7696, 7697,+    7698, 7699,+    7700, 7701,+    7702, 7703,+    7704, 7705,+    7706, 7707,+    7708, 7709,+    7710, 7711,+    7712, 7713,+    7714, 7715,+    7716, 7717,+    7718, 7719,+    7720, 7721,+    7722, 7723,+    7724, 7725,+    7726, 7727,+    7728, 7729,+    7730, 7731,+    7732, 7733,+    7734, 7735,+    7736, 7737,+    7738, 7739,+    7740, 7741,+    7742, 7743,+    7744, 7745,+    7746, 7747,+    7748, 7749,+    7750, 7751,+    7752, 7753,+    7754, 7755,+    7756, 7757,+    7758, 7759,+    7760, 7761,+    7762, 7763,+    7764, 7765,+    7766, 7767,+    7768, 7769,+    7770, 7771,+    7772, 7773,+    7774, 7775,+    7776, 7777,+    7778, 7779,+    7780, 7781,+    7782, 7783,+    7784, 7785,+    7786, 7787,+    7788, 7789,+    7790, 7791,+    7792, 7793,+    7794, 7795,+    7796, 7797,+    7798, 7799,+    7800, 7801,+    7802, 7803,+    7804, 7805,+    7806, 7807,+    7808, 7809,+    7810, 7811,+    7812, 7813,+    7814, 7815,+    7816, 7817,+    7818, 7819,+    7820, 7821,+    7822, 7823,+    7824, 7825,+    7826, 7827,+    7828, 7829,+    7838, 223,+    7840, 7841,+    7842, 7843,+    7844, 7845,+    7846, 7847,+    7848, 7849,+    7850, 7851,+    7852, 7853,+    7854, 7855,+    7856, 7857,+    7858, 7859,+    7860, 7861,+    7862, 7863,+    7864, 7865,+    7866, 7867,+    7868, 7869,+    7870, 7871,+    7872, 7873,+    7874, 7875,+    7876, 7877,+    7878, 7879,+    7880, 7881,+    7882, 7883,+    7884, 7885,+    7886, 7887,+    7888, 7889,+    7890, 7891,+    7892, 7893,+    7894, 7895,+    7896, 7897,+    7898, 7899,+    7900, 7901,+    7902, 7903,+    7904, 7905,+    7906, 7907,+    7908, 7909,+    7910, 7911,+    7912, 7913,+    7914, 7915,+    7916, 7917,+    7918, 7919,+    7920, 7921,+    7922, 7923,+    7924, 7925,+    7926, 7927,+    7928, 7929,+    7930, 7931,+    7932, 7933,+    7934, 7935,+    7944, 7936,+    7945, 7937,+    7946, 7938,+    7947, 7939,+    7948, 7940,+    7949, 7941,+    7950, 7942,+    7951, 7943,+    7960, 7952,+    7961, 7953,+    7962, 7954,+    7963, 7955,+    7964, 7956,+    7965, 7957,+    7976, 7968,+    7977, 7969,+    7978, 7970,+    7979, 7971,+    7980, 7972,+    7981, 7973,+    7982, 7974,+    7983, 7975,+    7992, 7984,+    7993, 7985,+    7994, 7986,+    7995, 7987,+    7996, 7988,+    7997, 7989,+    7998, 7990,+    7999, 7991,+    8008, 8000,+    8009, 8001,+    8010, 8002,+    8011, 8003,+    8012, 8004,+    8013, 8005,+    8025, 8017,+    8027, 8019,+    8029, 8021,+    8031, 8023,+    8040, 8032,+    8041, 8033,+    8042, 8034,+    8043, 8035,+    8044, 8036,+    8045, 8037,+    8046, 8038,+    8047, 8039,+    8120, 8112,+    8121, 8113,+    8122, 8048,+    8123, 8049,+    8136, 8050,+    8137, 8051,+    8138, 8052,+    8139, 8053,+    8152, 8144,+    8153, 8145,+    8154, 8054,+    8155, 8055,+    8168, 8160,+    8169, 8161,+    8170, 8058,+    8171, 8059,+    8172, 8165,+    8184, 8056,+    8185, 8057,+    8186, 8060,+    8187, 8061,+    8466, 8467,+    8496, 8495,+    8498, 8526,+    8510, 8509,+    8511, 8508,+    8517, 8518,+    11264, 11312,+    11265, 11313,+    11266, 11314,+    11267, 11315,+    11268, 11316,+    11269, 11317,+    11270, 11318,+    11271, 11319,+    11272, 11320,+    11273, 11321,+    11274, 11322,+    11275, 11323,+    11276, 11324,+    11277, 11325,+    11278, 11326,+    11279, 11327,+    11280, 11328,+    11281, 11329,+    11282, 11330,+    11283, 11331,+    11284, 11332,+    11285, 11333,+    11286, 11334,+    11287, 11335,+    11288, 11336,+    11289, 11337,+    11290, 11338,+    11291, 11339,+    11292, 11340,+    11293, 11341,+    11294, 11342,+    11295, 11343,+    11296, 11344,+    11297, 11345,+    11298, 11346,+    11299, 11347,+    11300, 11348,+    11301, 11349,+    11302, 11350,+    11303, 11351,+    11304, 11352,+    11305, 11353,+    11306, 11354,+    11307, 11355,+    11308, 11356,+    11309, 11357,+    11310, 11358,+    11311, 11359,+    11360, 11361,+    11362, 619,+    11363, 7549,+    11364, 637,+    11367, 11368,+    11369, 11370,+    11371, 11372,+    11373, 593,+    11374, 625,+    11375, 592,+    11376, 594,+    11378, 11379,+    11381, 11382,+    11390, 575,+    11391, 576,+    11392, 11393,+    11394, 11395,+    11396, 11397,+    11398, 11399,+    11400, 11401,+    11402, 11403,+    11404, 11405,+    11406, 11407,+    11408, 11409,+    11410, 11411,+    11412, 11413,+    11414, 11415,+    11416, 11417,+    11418, 11419,+    11420, 11421,+    11422, 11423,+    11424, 11425,+    11426, 11427,+    11428, 11429,+    11430, 11431,+    11432, 11433,+    11434, 11435,+    11436, 11437,+    11438, 11439,+    11440, 11441,+    11442, 11443,+    11444, 11445,+    11446, 11447,+    11448, 11449,+    11450, 11451,+    11452, 11453,+    11454, 11455,+    11456, 11457,+    11458, 11459,+    11460, 11461,+    11462, 11463,+    11464, 11465,+    11466, 11467,+    11468, 11469,+    11470, 11471,+    11472, 11473,+    11474, 11475,+    11476, 11477,+    11478, 11479,+    11480, 11481,+    11482, 11483,+    11484, 11485,+    11486, 11487,+    11488, 11489,+    11490, 11491,+    11499, 11500,+    11501, 11502,+    11506, 11507,+    42560, 42561,+    42562, 42563,+    42564, 42565,+    42566, 42567,+    42568, 42569,+    42570, 42571,+    42572, 42573,+    42574, 42575,+    42576, 42577,+    42578, 42579,+    42580, 42581,+    42582, 42583,+    42584, 42585,+    42586, 42587,+    42588, 42589,+    42590, 42591,+    42592, 42593,+    42594, 42595,+    42596, 42597,+    42598, 42599,+    42600, 42601,+    42602, 42603,+    42604, 42605,+    42624, 42625,+    42626, 42627,+    42628, 42629,+    42630, 42631,+    42632, 42633,+    42634, 42635,+    42636, 42637,+    42638, 42639,+    42640, 42641,+    42642, 42643,+    42644, 42645,+    42646, 42647,+    42648, 42649,+    42650, 42651,+    42786, 42787,+    42788, 42789,+    42790, 42791,+    42792, 42793,+    42794, 42795,+    42796, 42797,+    42798, 42799,+    42802, 42803,+    42804, 42805,+    42806, 42807,+    42808, 42809,+    42810, 42811,+    42812, 42813,+    42814, 42815,+    42816, 42817,+    42818, 42819,+    42820, 42821,+    42822, 42823,+    42824, 42825,+    42826, 42827,+    42828, 42829,+    42830, 42831,+    42832, 42833,+    42834, 42835,+    42836, 42837,+    42838, 42839,+    42840, 42841,+    42842, 42843,+    42844, 42845,+    42846, 42847,+    42848, 42849,+    42850, 42851,+    42852, 42853,+    42854, 42855,+    42856, 42857,+    42858, 42859,+    42860, 42861,+    42862, 42863,+    42873, 42874,+    42875, 42876,+    42877, 7545,+    42878, 42879,+    42880, 42881,+    42882, 42883,+    42884, 42885,+    42886, 42887,+    42891, 42892,+    42893, 613,+    42896, 42897,+    42898, 42899,+    42902, 42903,+    42904, 42905,+    42906, 42907,+    42908, 42909,+    42910, 42911,+    42912, 42913,+    42914, 42915,+    42916, 42917,+    42918, 42919,+    42920, 42921,+    42922, 614,+    42923, 604,+    42924, 609,+    42925, 620,+    42928, 670,+    42929, 647,+    42930, 669,+    42931, 43859,+    42932, 42933,+    42934, 42935,+    42936, 42937,+    42938, 42939,+    42940, 42941,+    42942, 42943,+    42944, 42945,+    42946, 42947,+    42948, 42900,+    42949, 642,+    42950, 7566,+    42951, 42952,+    42953, 42954,+    42960, 42961,+    42966, 42967,+    42968, 42969,+    42997, 42998,+    65313, 65345,+    65314, 65346,+    65315, 65347,+    65316, 65348,+    65317, 65349,+    65318, 65350,+    65319, 65351,+    65320, 65352,+    65321, 65353,+    65322, 65354,+    65323, 65355,+    65324, 65356,+    65325, 65357,+    65326, 65358,+    65327, 65359,+    65328, 65360,+    65329, 65361,+    65330, 65362,+    65331, 65363,+    65332, 65364,+    65333, 65365,+    65334, 65366,+    65335, 65367,+    65336, 65368,+    65337, 65369,+    65338, 65370,+    66560, 66600,+    66561, 66601,+    66562, 66602,+    66563, 66603,+    66564, 66604,+    66565, 66605,+    66566, 66606,+    66567, 66607,+    66568, 66608,+    66569, 66609,+    66570, 66610,+    66571, 66611,+    66572, 66612,+    66573, 66613,+    66574, 66614,+    66575, 66615,+    66576, 66616,+    66577, 66617,+    66578, 66618,+    66579, 66619,+    66580, 66620,+    66581, 66621,+    66582, 66622,+    66583, 66623,+    66584, 66624,+    66585, 66625,+    66586, 66626,+    66587, 66627,+    66588, 66628,+    66589, 66629,+    66590, 66630,+    66591, 66631,+    66592, 66632,+    66593, 66633,+    66594, 66634,+    66595, 66635,+    66596, 66636,+    66597, 66637,+    66598, 66638,+    66599, 66639,+    66736, 66776,+    66737, 66777,+    66738, 66778,+    66739, 66779,+    66740, 66780,+    66741, 66781,+    66742, 66782,+    66743, 66783,+    66744, 66784,+    66745, 66785,+    66746, 66786,+    66747, 66787,+    66748, 66788,+    66749, 66789,+    66750, 66790,+    66751, 66791,+    66752, 66792,+    66753, 66793,+    66754, 66794,+    66755, 66795,+    66756, 66796,+    66757, 66797,+    66758, 66798,+    66759, 66799,+    66760, 66800,+    66761, 66801,+    66762, 66802,+    66763, 66803,+    66764, 66804,+    66765, 66805,+    66766, 66806,+    66767, 66807,+    66768, 66808,+    66769, 66809,+    66770, 66810,+    66771, 66811,+    66928, 66967,+    66929, 66968,+    66930, 66969,+    66931, 66970,+    66932, 66971,+    66933, 66972,+    66934, 66973,+    66935, 66974,+    66936, 66975,+    66937, 66976,+    66938, 66977,+    66940, 66979,+    66941, 66980,+    66942, 66981,+    66943, 66982,+    66944, 66983,+    66945, 66984,+    66946, 66985,+    66947, 66986,+    66948, 66987,+    66949, 66988,+    66950, 66989,+    66951, 66990,+    66952, 66991,+    66953, 66992,+    66954, 66993,+    66956, 66995,+    66957, 66996,+    66958, 66997,+    66959, 66998,+    66960, 66999,+    66961, 67000,+    66962, 67001,+    66964, 67003,+    66965, 67004,+    68736, 68800,+    68737, 68801,+    68738, 68802,+    68739, 68803,+    68740, 68804,+    68741, 68805,+    68742, 68806,+    68743, 68807,+    68744, 68808,+    68745, 68809,+    68746, 68810,+    68747, 68811,+    68748, 68812,+    68749, 68813,+    68750, 68814,+    68751, 68815,+    68752, 68816,+    68753, 68817,+    68754, 68818,+    68755, 68819,+    68756, 68820,+    68757, 68821,+    68758, 68822,+    68759, 68823,+    68760, 68824,+    68761, 68825,+    68762, 68826,+    68763, 68827,+    68764, 68828,+    68765, 68829,+    68766, 68830,+    68767, 68831,+    68768, 68832,+    68769, 68833,+    68770, 68834,+    68771, 68835,+    68772, 68836,+    68773, 68837,+    68774, 68838,+    68775, 68839,+    68776, 68840,+    68777, 68841,+    68778, 68842,+    68779, 68843,+    68780, 68844,+    68781, 68845,+    68782, 68846,+    68783, 68847,+    68784, 68848,+    68785, 68849,+    68786, 68850,+    71840, 71872,+    71841, 71873,+    71842, 71874,+    71843, 71875,+    71844, 71876,+    71845, 71877,+    71846, 71878,+    71847, 71879,+    71848, 71880,+    71849, 71881,+    71850, 71882,+    71851, 71883,+    71852, 71884,+    71853, 71885,+    71854, 71886,+    71855, 71887,+    71856, 71888,+    71857, 71889,+    71858, 71890,+    71859, 71891,+    71860, 71892,+    71861, 71893,+    71862, 71894,+    71863, 71895,+    71864, 71896,+    71865, 71897,+    71866, 71898,+    71867, 71899,+    71868, 71900,+    71869, 71901,+    71870, 71902,+    71871, 71903,+    93760, 93792,+    93761, 93793,+    93762, 93794,+    93763, 93795,+    93764, 93796,+    93765, 93797,+    93766, 93798,+    93767, 93799,+    93768, 93800,+    93769, 93801,+    93770, 93802,+    93771, 93803,+    93772, 93804,+    93773, 93805,+    93774, 93806,+    93775, 93807,+    93776, 93808,+    93777, 93809,+    93778, 93810,+    93779, 93811,+    93780, 93812,+    93781, 93813,+    93782, 93814,+    93783, 93815,+    93784, 93816,+    93785, 93817,+    93786, 93818,+    93787, 93819,+    93788, 93820,+    93789, 93821,+    93790, 93822,+    93791, 93823,+    119808, 119834,+    119809, 119835,+    119810, 119836,+    119811, 119837,+    119812, 119838,+    119813, 119839,+    119814, 119840,+    119815, 119841,+    119816, 119842,+    119817, 119843,+    119818, 119844,+    119819, 119845,+    119820, 119846,+    119821, 119847,+    119822, 119848,+    119823, 119849,+    119824, 119850,+    119825, 119851,+    119826, 119852,+    119827, 119853,+    119828, 119854,+    119829, 119855,+    119830, 119856,+    119831, 119857,+    119832, 119858,+    119833, 119859,+    119860, 119886,+    119861, 119887,+    119862, 119888,+    119863, 119889,+    119864, 119890,+    119865, 119891,+    119866, 119892,+    119868, 119894,+    119869, 119895,+    119870, 119896,+    119871, 119897,+    119872, 119898,+    119873, 119899,+    119874, 119900,+    119875, 119901,+    119876, 119902,+    119877, 119903,+    119878, 119904,+    119879, 119905,+    119880, 119906,+    119881, 119907,+    119882, 119908,+    119883, 119909,+    119884, 119910,+    119885, 119911,+    119912, 119938,+    119913, 119939,+    119914, 119940,+    119915, 119941,+    119916, 119942,+    119917, 119943,+    119918, 119944,+    119919, 119945,+    119920, 119946,+    119921, 119947,+    119922, 119948,+    119923, 119949,+    119924, 119950,+    119925, 119951,+    119926, 119952,+    119927, 119953,+    119928, 119954,+    119929, 119955,+    119930, 119956,+    119931, 119957,+    119932, 119958,+    119933, 119959,+    119934, 119960,+    119935, 119961,+    119936, 119962,+    119937, 119963,+    119964, 119990,+    119966, 119992,+    119967, 119993,+    119973, 119999,+    119974, 120000,+    119977, 120003,+    119979, 120005,+    119980, 120006,+    119982, 120008,+    119983, 120009,+    119984, 120010,+    119985, 120011,+    119986, 120012,+    119987, 120013,+    119988, 120014,+    119989, 120015,+    120016, 120042,+    120017, 120043,+    120018, 120044,+    120019, 120045,+    120020, 120046,+    120021, 120047,+    120022, 120048,+    120023, 120049,+    120024, 120050,+    120025, 120051,+    120026, 120052,+    120027, 120053,+    120028, 120054,+    120029, 120055,+    120030, 120056,+    120031, 120057,+    120032, 120058,+    120033, 120059,+    120034, 120060,+    120035, 120061,+    120036, 120062,+    120037, 120063,+    120038, 120064,+    120039, 120065,+    120040, 120066,+    120041, 120067,+    120068, 120094,+    120069, 120095,+    120071, 120097,+    120072, 120098,+    120073, 120099,+    120074, 120100,+    120077, 120103,+    120078, 120104,+    120079, 120105,+    120080, 120106,+    120081, 120107,+    120082, 120108,+    120083, 120109,+    120084, 120110,+    120086, 120112,+    120087, 120113,+    120088, 120114,+    120089, 120115,+    120090, 120116,+    120091, 120117,+    120092, 120118,+    120120, 120146,+    120121, 120147,+    120123, 120149,+    120124, 120150,+    120125, 120151,+    120126, 120152,+    120128, 120154,+    120129, 120155,+    120130, 120156,+    120131, 120157,+    120132, 120158,+    120134, 120160,+    120138, 120164,+    120139, 120165,+    120140, 120166,+    120141, 120167,+    120142, 120168,+    120143, 120169,+    120144, 120170,+    120172, 120198,+    120173, 120199,+    120174, 120200,+    120175, 120201,+    120176, 120202,+    120177, 120203,+    120178, 120204,+    120179, 120205,+    120180, 120206,+    120181, 120207,+    120182, 120208,+    120183, 120209,+    120184, 120210,+    120185, 120211,+    120186, 120212,+    120187, 120213,+    120188, 120214,+    120189, 120215,+    120190, 120216,+    120191, 120217,+    120192, 120218,+    120193, 120219,+    120194, 120220,+    120195, 120221,+    120196, 120222,+    120197, 120223,+    120224, 120250,+    120225, 120251,+    120226, 120252,+    120227, 120253,+    120228, 120254,+    120229, 120255,+    120230, 120256,+    120231, 120257,+    120232, 120258,+    120233, 120259,+    120234, 120260,+    120235, 120261,+    120236, 120262,+    120237, 120263,+    120238, 120264,+    120239, 120265,+    120240, 120266,+    120241, 120267,+    120242, 120268,+    120243, 120269,+    120244, 120270,+    120245, 120271,+    120246, 120272,+    120247, 120273,+    120248, 120274,+    120249, 120275,+    120276, 120302,+    120277, 120303,+    120278, 120304,+    120279, 120305,+    120280, 120306,+    120281, 120307,+    120282, 120308,+    120283, 120309,+    120284, 120310,+    120285, 120311,+    120286, 120312,+    120287, 120313,+    120288, 120314,+    120289, 120315,+    120290, 120316,+    120291, 120317,+    120292, 120318,+    120293, 120319,+    120294, 120320,+    120295, 120321,+    120296, 120322,+    120297, 120323,+    120298, 120324,+    120299, 120325,+    120300, 120326,+    120301, 120327,+    120328, 120354,+    120329, 120355,+    120330, 120356,+    120331, 120357,+    120332, 120358,+    120333, 120359,+    120334, 120360,+    120335, 120361,+    120336, 120362,+    120337, 120363,+    120338, 120364,+    120339, 120365,+    120340, 120366,+    120341, 120367,+    120342, 120368,+    120343, 120369,+    120344, 120370,+    120345, 120371,+    120346, 120372,+    120347, 120373,+    120348, 120374,+    120349, 120375,+    120350, 120376,+    120351, 120377,+    120352, 120378,+    120353, 120379,+    120380, 120406,+    120381, 120407,+    120382, 120408,+    120383, 120409,+    120384, 120410,+    120385, 120411,+    120386, 120412,+    120387, 120413,+    120388, 120414,+    120389, 120415,+    120390, 120416,+    120391, 120417,+    120392, 120418,+    120393, 120419,+    120394, 120420,+    120395, 120421,+    120396, 120422,+    120397, 120423,+    120398, 120424,+    120399, 120425,+    120400, 120426,+    120401, 120427,+    120402, 120428,+    120403, 120429,+    120404, 120430,+    120405, 120431,+    120432, 120458,+    120433, 120459,+    120434, 120460,+    120435, 120461,+    120436, 120462,+    120437, 120463,+    120438, 120464,+    120439, 120465,+    120440, 120466,+    120441, 120467,+    120442, 120468,+    120443, 120469,+    120444, 120470,+    120445, 120471,+    120446, 120472,+    120447, 120473,+    120448, 120474,+    120449, 120475,+    120450, 120476,+    120451, 120477,+    120452, 120478,+    120453, 120479,+    120454, 120480,+    120455, 120481,+    120456, 120482,+    120457, 120483,+    120488, 120514,+    120489, 120515,+    120490, 120516,+    120491, 120517,+    120492, 120518,+    120493, 120519,+    120494, 120520,+    120495, 120521,+    120496, 120522,+    120497, 120523,+    120498, 120524,+    120499, 120525,+    120500, 120526,+    120501, 120527,+    120502, 120528,+    120503, 120529,+    120504, 120530,+    120506, 120532,+    120507, 120533,+    120508, 120534,+    120509, 120535,+    120510, 120536,+    120511, 120537,+    120512, 120538,+    120546, 120572,+    120547, 120573,+    120548, 120574,+    120549, 120575,+    120550, 120576,+    120551, 120577,+    120552, 120578,+    120553, 120579,+    120554, 120580,+    120555, 120581,+    120556, 120582,+    120557, 120583,+    120558, 120584,+    120559, 120585,+    120560, 120586,+    120561, 120587,+    120562, 120588,+    120564, 120590,+    120565, 120591,+    120566, 120592,+    120567, 120593,+    120568, 120594,+    120569, 120595,+    120570, 120596,+    120604, 120630,+    120605, 120631,+    120606, 120632,+    120607, 120633,+    120608, 120634,+    120609, 120635,+    120610, 120636,+    120611, 120637,+    120612, 120638,+    120613, 120639,+    120614, 120640,+    120615, 120641,+    120616, 120642,+    120617, 120643,+    120618, 120644,+    120619, 120645,+    120620, 120646,+    120622, 120648,+    120623, 120649,+    120624, 120650,+    120625, 120651,+    120626, 120652,+    120627, 120653,+    120628, 120654,+    120662, 120688,+    120663, 120689,+    120664, 120690,+    120665, 120691,+    120666, 120692,+    120667, 120693,+    120668, 120694,+    120669, 120695,+    120670, 120696,+    120671, 120697,+    120672, 120698,+    120673, 120699,+    120674, 120700,+    120675, 120701,+    120676, 120702,+    120677, 120703,+    120678, 120704,+    120680, 120706,+    120681, 120707,+    120682, 120708,+    120683, 120709,+    120684, 120710,+    120685, 120711,+    120686, 120712,+    120720, 120746,+    120721, 120747,+    120722, 120748,+    120723, 120749,+    120724, 120750,+    120725, 120751,+    120726, 120752,+    120727, 120753,+    120728, 120754,+    120729, 120755,+    120730, 120756,+    120731, 120757,+    120732, 120758,+    120733, 120759,+    120734, 120760,+    120735, 120761,+    120736, 120762,+    120738, 120764,+    120739, 120765,+    120740, 120766,+    120741, 120767,+    120742, 120768,+    120743, 120769,+    120744, 120770,+    120778, 120779,+    125184, 125218,+    125185, 125219,+    125186, 125220,+    125187, 125221,+    125188, 125222,+    125189, 125223,+    125190, 125224,+    125191, 125225,+    125192, 125226,+    125193, 125227,+    125194, 125228,+    125195, 125229,+    125196, 125230,+    125197, 125231,+    125198, 125232,+    125199, 125233,+    125200, 125234,+    125201, 125235,+    125202, 125236,+    125203, 125237,+    125204, 125238,+    125205, 125239,+    125206, 125240,+    125207, 125241,+    125208, 125242,+    125209, 125243,+    125210, 125244,+    125211, 125245,+    125212, 125246,+    125213, 125247,+    125214, 125248,+    125215, 125249,+    125216, 125250,+    125217, 125251,+  };+  const int key[2] = { c, 0 };+  const int *val = static_cast<const int*>(std::bsearch(key, ul, 1647, sizeof(key), &cmpint2));+  return val != NULL ? val[1] : c;+}++int reflex::Unicode::Tables::toupper(int c)+{+  static const int lu[] = {+    97, 65,+    98, 66,+    99, 67,+    100, 68,+    101, 69,+    102, 70,+    103, 71,+    104, 72,+    105, 73,+    106, 74,+    107, 75,+    108, 76,+    109, 77,+    110, 78,+    111, 79,+    112, 80,+    113, 81,+    114, 82,+    115, 83,+    116, 84,+    117, 85,+    118, 86,+    119, 87,+    120, 88,+    121, 89,+    122, 90,+    223, 7838,+    224, 192,+    225, 193,+    226, 194,+    227, 195,+    228, 196,+    229, 197,+    230, 198,+    231, 199,+    232, 200,+    233, 201,+    234, 202,+    235, 203,+    236, 204,+    237, 205,+    238, 206,+    239, 207,+    240, 208,+    241, 209,+    242, 210,+    243, 211,+    244, 212,+    245, 213,+    246, 214,+    248, 216,+    249, 217,+    250, 218,+    251, 219,+    252, 220,+    253, 221,+    254, 222,+    255, 376,+    257, 256,+    259, 258,+    261, 260,+    263, 262,+    265, 264,+    267, 266,+    269, 268,+    271, 270,+    273, 272,+    275, 274,+    277, 276,+    279, 278,+    281, 280,+    283, 282,+    285, 284,+    287, 286,+    289, 288,+    291, 290,+    293, 292,+    295, 294,+    297, 296,+    299, 298,+    301, 300,+    303, 302,+    307, 306,+    309, 308,+    311, 310,+    314, 313,+    316, 315,+    318, 317,+    320, 319,+    322, 321,+    324, 323,+    326, 325,+    328, 327,+    331, 330,+    333, 332,+    335, 334,+    337, 336,+    339, 338,+    341, 340,+    343, 342,+    345, 344,+    347, 346,+    349, 348,+    351, 350,+    353, 352,+    355, 354,+    357, 356,+    359, 358,+    361, 360,+    363, 362,+    365, 364,+    367, 366,+    369, 368,+    371, 370,+    373, 372,+    375, 374,+    378, 377,+    380, 379,+    382, 381,+    384, 579,+    387, 386,+    389, 388,+    392, 391,+    396, 395,+    402, 401,+    409, 408,+    410, 573,+    414, 544,+    417, 416,+    419, 418,+    421, 420,+    424, 423,+    429, 428,+    432, 431,+    436, 435,+    438, 437,+    441, 440,+    445, 444,+    454, 452,+    457, 455,+    460, 458,+    462, 461,+    464, 463,+    466, 465,+    468, 467,+    470, 469,+    472, 471,+    474, 473,+    476, 475,+    479, 478,+    481, 480,+    483, 482,+    485, 484,+    487, 486,+    489, 488,+    491, 490,+    493, 492,+    495, 494,+    499, 497,+    501, 500,+    505, 504,+    507, 506,+    509, 508,+    511, 510,+    513, 512,+    515, 514,+    517, 516,+    519, 518,+    521, 520,+    523, 522,+    525, 524,+    527, 526,+    529, 528,+    531, 530,+    533, 532,+    535, 534,+    537, 536,+    539, 538,+    541, 540,+    543, 542,+    547, 546,+    549, 548,+    551, 550,+    553, 552,+    555, 554,+    557, 556,+    559, 558,+    561, 560,+    563, 562,+    572, 571,+    575, 11390,+    576, 11391,+    578, 577,+    583, 582,+    585, 584,+    589, 588,+    591, 590,+    592, 11375,+    593, 11373,+    594, 11376,+    595, 385,+    596, 390,+    599, 394,+    600, 398,+    601, 399,+    603, 400,+    604, 42923,+    608, 403,+    609, 42924,+    611, 404,+    613, 42893,+    614, 42922,+    616, 407,+    617, 406,+    619, 11362,+    620, 42925,+    623, 412,+    625, 11374,+    626, 413,+    637, 11364,+    642, 42949,+    643, 425,+    647, 42929,+    648, 430,+    649, 580,+    650, 433,+    651, 434,+    652, 581,+    658, 439,+    669, 42930,+    670, 42928,+    881, 880,+    883, 882,+    887, 886,+    891, 1021,+    892, 1022,+    893, 1023,+    940, 902,+    941, 904,+    942, 905,+    943, 906,+    945, 913,+    946, 914,+    947, 915,+    948, 916,+    949, 917,+    950, 918,+    951, 919,+    952, 920,+    953, 921,+    954, 922,+    955, 923,+    956, 924,+    957, 925,+    958, 926,+    959, 927,+    960, 928,+    961, 929,+    963, 931,+    964, 932,+    965, 933,+    966, 934,+    967, 935,+    968, 936,+    969, 937,+    970, 938,+    971, 939,+    972, 908,+    973, 910,+    974, 911,+    995, 994,+    997, 996,+    999, 998,+    1001, 1000,+    1003, 1002,+    1005, 1004,+    1007, 1006,+    1016, 1015,+    1019, 1018,+    1072, 1040,+    1073, 1041,+    1074, 1042,+    1075, 1043,+    1076, 1044,+    1077, 1045,+    1078, 1046,+    1079, 1047,+    1080, 1048,+    1081, 1049,+    1082, 1050,+    1083, 1051,+    1084, 1052,+    1085, 1053,+    1086, 1054,+    1087, 1055,+    1088, 1056,+    1089, 1057,+    1090, 1058,+    1091, 1059,+    1092, 1060,+    1093, 1061,+    1094, 1062,+    1095, 1063,+    1096, 1064,+    1097, 1065,+    1098, 1066,+    1099, 1067,+    1100, 1068,+    1101, 1069,+    1102, 1070,+    1103, 1071,+    1104, 1024,+    1105, 1025,+    1106, 1026,+    1107, 1027,+    1108, 1028,+    1109, 1029,+    1110, 1030,+    1111, 1031,+    1112, 1032,+    1113, 1033,+    1114, 1034,+    1115, 1035,+    1116, 1036,+    1117, 1037,+    1118, 1038,+    1119, 1039,+    1121, 1120,+    1123, 1122,+    1125, 1124,+    1127, 1126,+    1129, 1128,+    1131, 1130,+    1133, 1132,+    1135, 1134,+    1137, 1136,+    1139, 1138,+    1141, 1140,+    1143, 1142,+    1145, 1144,+    1147, 1146,+    1149, 1148,+    1151, 1150,+    1153, 1152,+    1163, 1162,+    1165, 1164,+    1167, 1166,+    1169, 1168,+    1171, 1170,+    1173, 1172,+    1175, 1174,+    1177, 1176,+    1179, 1178,+    1181, 1180,+    1183, 1182,+    1185, 1184,+    1187, 1186,+    1189, 1188,+    1191, 1190,+    1193, 1192,+    1195, 1194,+    1197, 1196,+    1199, 1198,+    1201, 1200,+    1203, 1202,+    1205, 1204,+    1207, 1206,+    1209, 1208,+    1211, 1210,+    1213, 1212,+    1215, 1214,+    1218, 1217,+    1220, 1219,+    1222, 1221,+    1224, 1223,+    1226, 1225,+    1228, 1227,+    1230, 1229,+    1233, 1232,+    1235, 1234,+    1237, 1236,+    1239, 1238,+    1241, 1240,+    1243, 1242,+    1245, 1244,+    1247, 1246,+    1249, 1248,+    1251, 1250,+    1253, 1252,+    1255, 1254,+    1257, 1256,+    1259, 1258,+    1261, 1260,+    1263, 1262,+    1265, 1264,+    1267, 1266,+    1269, 1268,+    1271, 1270,+    1273, 1272,+    1275, 1274,+    1277, 1276,+    1279, 1278,+    1281, 1280,+    1283, 1282,+    1285, 1284,+    1287, 1286,+    1289, 1288,+    1291, 1290,+    1293, 1292,+    1295, 1294,+    1297, 1296,+    1299, 1298,+    1301, 1300,+    1303, 1302,+    1305, 1304,+    1307, 1306,+    1309, 1308,+    1311, 1310,+    1313, 1312,+    1315, 1314,+    1317, 1316,+    1319, 1318,+    1321, 1320,+    1323, 1322,+    1325, 1324,+    1327, 1326,+    1377, 1329,+    1378, 1330,+    1379, 1331,+    1380, 1332,+    1381, 1333,+    1382, 1334,+    1383, 1335,+    1384, 1336,+    1385, 1337,+    1386, 1338,+    1387, 1339,+    1388, 1340,+    1389, 1341,+    1390, 1342,+    1391, 1343,+    1392, 1344,+    1393, 1345,+    1394, 1346,+    1395, 1347,+    1396, 1348,+    1397, 1349,+    1398, 1350,+    1399, 1351,+    1400, 1352,+    1401, 1353,+    1402, 1354,+    1403, 1355,+    1404, 1356,+    1405, 1357,+    1406, 1358,+    1407, 1359,+    1408, 1360,+    1409, 1361,+    1410, 1362,+    1411, 1363,+    1412, 1364,+    1413, 1365,+    1414, 1366,+    7545, 42877,+    7549, 11363,+    7566, 42950,+    7681, 7680,+    7683, 7682,+    7685, 7684,+    7687, 7686,+    7689, 7688,+    7691, 7690,+    7693, 7692,+    7695, 7694,+    7697, 7696,+    7699, 7698,+    7701, 7700,+    7703, 7702,+    7705, 7704,+    7707, 7706,+    7709, 7708,+    7711, 7710,+    7713, 7712,+    7715, 7714,+    7717, 7716,+    7719, 7718,+    7721, 7720,+    7723, 7722,+    7725, 7724,+    7727, 7726,+    7729, 7728,+    7731, 7730,+    7733, 7732,+    7735, 7734,+    7737, 7736,+    7739, 7738,+    7741, 7740,+    7743, 7742,+    7745, 7744,+    7747, 7746,+    7749, 7748,+    7751, 7750,+    7753, 7752,+    7755, 7754,+    7757, 7756,+    7759, 7758,+    7761, 7760,+    7763, 7762,+    7765, 7764,+    7767, 7766,+    7769, 7768,+    7771, 7770,+    7773, 7772,+    7775, 7774,+    7777, 7776,+    7779, 7778,+    7781, 7780,+    7783, 7782,+    7785, 7784,+    7787, 7786,+    7789, 7788,+    7791, 7790,+    7793, 7792,+    7795, 7794,+    7797, 7796,+    7799, 7798,+    7801, 7800,+    7803, 7802,+    7805, 7804,+    7807, 7806,+    7809, 7808,+    7811, 7810,+    7813, 7812,+    7815, 7814,+    7817, 7816,+    7819, 7818,+    7821, 7820,+    7823, 7822,+    7825, 7824,+    7827, 7826,+    7829, 7828,+    7841, 7840,+    7843, 7842,+    7845, 7844,+    7847, 7846,+    7849, 7848,+    7851, 7850,+    7853, 7852,+    7855, 7854,+    7857, 7856,+    7859, 7858,+    7861, 7860,+    7863, 7862,+    7865, 7864,+    7867, 7866,+    7869, 7868,+    7871, 7870,+    7873, 7872,+    7875, 7874,+    7877, 7876,+    7879, 7878,+    7881, 7880,+    7883, 7882,+    7885, 7884,+    7887, 7886,+    7889, 7888,+    7891, 7890,+    7893, 7892,+    7895, 7894,+    7897, 7896,+    7899, 7898,+    7901, 7900,+    7903, 7902,+    7905, 7904,+    7907, 7906,+    7909, 7908,+    7911, 7910,+    7913, 7912,+    7915, 7914,+    7917, 7916,+    7919, 7918,+    7921, 7920,+    7923, 7922,+    7925, 7924,+    7927, 7926,+    7929, 7928,+    7931, 7930,+    7933, 7932,+    7935, 7934,+    7936, 7944,+    7937, 7945,+    7938, 7946,+    7939, 7947,+    7940, 7948,+    7941, 7949,+    7942, 7950,+    7943, 7951,+    7952, 7960,+    7953, 7961,+    7954, 7962,+    7955, 7963,+    7956, 7964,+    7957, 7965,+    7968, 7976,+    7969, 7977,+    7970, 7978,+    7971, 7979,+    7972, 7980,+    7973, 7981,+    7974, 7982,+    7975, 7983,+    7984, 7992,+    7985, 7993,+    7986, 7994,+    7987, 7995,+    7988, 7996,+    7989, 7997,+    7990, 7998,+    7991, 7999,+    8000, 8008,+    8001, 8009,+    8002, 8010,+    8003, 8011,+    8004, 8012,+    8005, 8013,+    8017, 8025,+    8019, 8027,+    8021, 8029,+    8023, 8031,+    8032, 8040,+    8033, 8041,+    8034, 8042,+    8035, 8043,+    8036, 8044,+    8037, 8045,+    8038, 8046,+    8039, 8047,+    8048, 8122,+    8049, 8123,+    8050, 8136,+    8051, 8137,+    8052, 8138,+    8053, 8139,+    8054, 8154,+    8055, 8155,+    8056, 8184,+    8057, 8185,+    8058, 8170,+    8059, 8171,+    8060, 8186,+    8061, 8187,+    8112, 8120,+    8113, 8121,+    8144, 8152,+    8145, 8153,+    8160, 8168,+    8161, 8169,+    8165, 8172,+    8467, 8466,+    8495, 8496,+    8508, 8511,+    8509, 8510,+    8518, 8517,+    8526, 8498,+    11312, 11264,+    11313, 11265,+    11314, 11266,+    11315, 11267,+    11316, 11268,+    11317, 11269,+    11318, 11270,+    11319, 11271,+    11320, 11272,+    11321, 11273,+    11322, 11274,+    11323, 11275,+    11324, 11276,+    11325, 11277,+    11326, 11278,+    11327, 11279,+    11328, 11280,+    11329, 11281,+    11330, 11282,+    11331, 11283,+    11332, 11284,+    11333, 11285,+    11334, 11286,+    11335, 11287,+    11336, 11288,+    11337, 11289,+    11338, 11290,+    11339, 11291,+    11340, 11292,+    11341, 11293,+    11342, 11294,+    11343, 11295,+    11344, 11296,+    11345, 11297,+    11346, 11298,+    11347, 11299,+    11348, 11300,+    11349, 11301,+    11350, 11302,+    11351, 11303,+    11352, 11304,+    11353, 11305,+    11354, 11306,+    11355, 11307,+    11356, 11308,+    11357, 11309,+    11358, 11310,+    11359, 11311,+    11361, 11360,+    11365, 570,+    11366, 574,+    11368, 11367,+    11370, 11369,+    11372, 11371,+    11379, 11378,+    11382, 11381,+    11393, 11392,+    11395, 11394,+    11397, 11396,+    11399, 11398,+    11401, 11400,+    11403, 11402,+    11405, 11404,+    11407, 11406,+    11409, 11408,+    11411, 11410,+    11413, 11412,+    11415, 11414,+    11417, 11416,+    11419, 11418,+    11421, 11420,+    11423, 11422,+    11425, 11424,+    11427, 11426,+    11429, 11428,+    11431, 11430,+    11433, 11432,+    11435, 11434,+    11437, 11436,+    11439, 11438,+    11441, 11440,+    11443, 11442,+    11445, 11444,+    11447, 11446,+    11449, 11448,+    11451, 11450,+    11453, 11452,+    11455, 11454,+    11457, 11456,+    11459, 11458,+    11461, 11460,+    11463, 11462,+    11465, 11464,+    11467, 11466,+    11469, 11468,+    11471, 11470,+    11473, 11472,+    11475, 11474,+    11477, 11476,+    11479, 11478,+    11481, 11480,+    11483, 11482,+    11485, 11484,+    11487, 11486,+    11489, 11488,+    11491, 11490,+    11500, 11499,+    11502, 11501,+    11507, 11506,+    11520, 4256,+    11521, 4257,+    11522, 4258,+    11523, 4259,+    11524, 4260,+    11525, 4261,+    11526, 4262,+    11527, 4263,+    11528, 4264,+    11529, 4265,+    11530, 4266,+    11531, 4267,+    11532, 4268,+    11533, 4269,+    11534, 4270,+    11535, 4271,+    11536, 4272,+    11537, 4273,+    11538, 4274,+    11539, 4275,+    11540, 4276,+    11541, 4277,+    11542, 4278,+    11543, 4279,+    11544, 4280,+    11545, 4281,+    11546, 4282,+    11547, 4283,+    11548, 4284,+    11549, 4285,+    11550, 4286,+    11551, 4287,+    11552, 4288,+    11553, 4289,+    11554, 4290,+    11555, 4291,+    11556, 4292,+    11557, 4293,+    11559, 4295,+    11565, 4301,+    42561, 42560,+    42563, 42562,+    42565, 42564,+    42567, 42566,+    42569, 42568,+    42571, 42570,+    42573, 42572,+    42575, 42574,+    42577, 42576,+    42579, 42578,+    42581, 42580,+    42583, 42582,+    42585, 42584,+    42587, 42586,+    42589, 42588,+    42591, 42590,+    42593, 42592,+    42595, 42594,+    42597, 42596,+    42599, 42598,+    42601, 42600,+    42603, 42602,+    42605, 42604,+    42625, 42624,+    42627, 42626,+    42629, 42628,+    42631, 42630,+    42633, 42632,+    42635, 42634,+    42637, 42636,+    42639, 42638,+    42641, 42640,+    42643, 42642,+    42645, 42644,+    42647, 42646,+    42649, 42648,+    42651, 42650,+    42787, 42786,+    42789, 42788,+    42791, 42790,+    42793, 42792,+    42795, 42794,+    42797, 42796,+    42799, 42798,+    42803, 42802,+    42805, 42804,+    42807, 42806,+    42809, 42808,+    42811, 42810,+    42813, 42812,+    42815, 42814,+    42817, 42816,+    42819, 42818,+    42821, 42820,+    42823, 42822,+    42825, 42824,+    42827, 42826,+    42829, 42828,+    42831, 42830,+    42833, 42832,+    42835, 42834,+    42837, 42836,+    42839, 42838,+    42841, 42840,+    42843, 42842,+    42845, 42844,+    42847, 42846,+    42849, 42848,+    42851, 42850,+    42853, 42852,+    42855, 42854,+    42857, 42856,+    42859, 42858,+    42861, 42860,+    42863, 42862,+    42874, 42873,+    42876, 42875,+    42879, 42878,+    42881, 42880,+    42883, 42882,+    42885, 42884,+    42887, 42886,+    42892, 42891,+    42897, 42896,+    42899, 42898,+    42900, 42948,+    42903, 42902,+    42905, 42904,+    42907, 42906,+    42909, 42908,+    42911, 42910,+    42913, 42912,+    42915, 42914,+    42917, 42916,+    42919, 42918,+    42921, 42920,+    42933, 42932,+    42935, 42934,+    42937, 42936,+    42939, 42938,+    42941, 42940,+    42943, 42942,+    42945, 42944,+    42947, 42946,+    42952, 42951,+    42954, 42953,+    42961, 42960,+    42967, 42966,+    42969, 42968,+    42998, 42997,+    43859, 42931,+    65345, 65313,+    65346, 65314,+    65347, 65315,+    65348, 65316,+    65349, 65317,+    65350, 65318,+    65351, 65319,+    65352, 65320,+    65353, 65321,+    65354, 65322,+    65355, 65323,+    65356, 65324,+    65357, 65325,+    65358, 65326,+    65359, 65327,+    65360, 65328,+    65361, 65329,+    65362, 65330,+    65363, 65331,+    65364, 65332,+    65365, 65333,+    65366, 65334,+    65367, 65335,+    65368, 65336,+    65369, 65337,+    65370, 65338,+    66600, 66560,+    66601, 66561,+    66602, 66562,+    66603, 66563,+    66604, 66564,+    66605, 66565,+    66606, 66566,+    66607, 66567,+    66608, 66568,+    66609, 66569,+    66610, 66570,+    66611, 66571,+    66612, 66572,+    66613, 66573,+    66614, 66574,+    66615, 66575,+    66616, 66576,+    66617, 66577,+    66618, 66578,+    66619, 66579,+    66620, 66580,+    66621, 66581,+    66622, 66582,+    66623, 66583,+    66624, 66584,+    66625, 66585,+    66626, 66586,+    66627, 66587,+    66628, 66588,+    66629, 66589,+    66630, 66590,+    66631, 66591,+    66632, 66592,+    66633, 66593,+    66634, 66594,+    66635, 66595,+    66636, 66596,+    66637, 66597,+    66638, 66598,+    66639, 66599,+    66776, 66736,+    66777, 66737,+    66778, 66738,+    66779, 66739,+    66780, 66740,+    66781, 66741,+    66782, 66742,+    66783, 66743,+    66784, 66744,+    66785, 66745,+    66786, 66746,+    66787, 66747,+    66788, 66748,+    66789, 66749,+    66790, 66750,+    66791, 66751,+    66792, 66752,+    66793, 66753,+    66794, 66754,+    66795, 66755,+    66796, 66756,+    66797, 66757,+    66798, 66758,+    66799, 66759,+    66800, 66760,+    66801, 66761,+    66802, 66762,+    66803, 66763,+    66804, 66764,+    66805, 66765,+    66806, 66766,+    66807, 66767,+    66808, 66768,+    66809, 66769,+    66810, 66770,+    66811, 66771,+    66967, 66928,+    66968, 66929,+    66969, 66930,+    66970, 66931,+    66971, 66932,+    66972, 66933,+    66973, 66934,+    66974, 66935,+    66975, 66936,+    66976, 66937,+    66977, 66938,+    66979, 66940,+    66980, 66941,+    66981, 66942,+    66982, 66943,+    66983, 66944,+    66984, 66945,+    66985, 66946,+    66986, 66947,+    66987, 66948,+    66988, 66949,+    66989, 66950,+    66990, 66951,+    66991, 66952,+    66992, 66953,+    66993, 66954,+    66995, 66956,+    66996, 66957,+    66997, 66958,+    66998, 66959,+    66999, 66960,+    67000, 66961,+    67001, 66962,+    67003, 66964,+    67004, 66965,+    68800, 68736,+    68801, 68737,+    68802, 68738,+    68803, 68739,+    68804, 68740,+    68805, 68741,+    68806, 68742,+    68807, 68743,+    68808, 68744,+    68809, 68745,+    68810, 68746,+    68811, 68747,+    68812, 68748,+    68813, 68749,+    68814, 68750,+    68815, 68751,+    68816, 68752,+    68817, 68753,+    68818, 68754,+    68819, 68755,+    68820, 68756,+    68821, 68757,+    68822, 68758,+    68823, 68759,+    68824, 68760,+    68825, 68761,+    68826, 68762,+    68827, 68763,+    68828, 68764,+    68829, 68765,+    68830, 68766,+    68831, 68767,+    68832, 68768,+    68833, 68769,+    68834, 68770,+    68835, 68771,+    68836, 68772,+    68837, 68773,+    68838, 68774,+    68839, 68775,+    68840, 68776,+    68841, 68777,+    68842, 68778,+    68843, 68779,+    68844, 68780,+    68845, 68781,+    68846, 68782,+    68847, 68783,+    68848, 68784,+    68849, 68785,+    68850, 68786,+    71872, 71840,+    71873, 71841,+    71874, 71842,+    71875, 71843,+    71876, 71844,+    71877, 71845,+    71878, 71846,+    71879, 71847,+    71880, 71848,+    71881, 71849,+    71882, 71850,+    71883, 71851,+    71884, 71852,+    71885, 71853,+    71886, 71854,+    71887, 71855,+    71888, 71856,+    71889, 71857,+    71890, 71858,+    71891, 71859,+    71892, 71860,+    71893, 71861,+    71894, 71862,+    71895, 71863,+    71896, 71864,+    71897, 71865,+    71898, 71866,+    71899, 71867,+    71900, 71868,+    71901, 71869,+    71902, 71870,+    71903, 71871,+    93792, 93760,+    93793, 93761,+    93794, 93762,+    93795, 93763,+    93796, 93764,+    93797, 93765,+    93798, 93766,+    93799, 93767,+    93800, 93768,+    93801, 93769,+    93802, 93770,+    93803, 93771,+    93804, 93772,+    93805, 93773,+    93806, 93774,+    93807, 93775,+    93808, 93776,+    93809, 93777,+    93810, 93778,+    93811, 93779,+    93812, 93780,+    93813, 93781,+    93814, 93782,+    93815, 93783,+    93816, 93784,+    93817, 93785,+    93818, 93786,+    93819, 93787,+    93820, 93788,+    93821, 93789,+    93822, 93790,+    93823, 93791,+    119834, 119808,+    119835, 119809,+    119836, 119810,+    119837, 119811,+    119838, 119812,+    119839, 119813,+    119840, 119814,+    119841, 119815,+    119842, 119816,+    119843, 119817,+    119844, 119818,+    119845, 119819,+    119846, 119820,+    119847, 119821,+    119848, 119822,+    119849, 119823,+    119850, 119824,+    119851, 119825,+    119852, 119826,+    119853, 119827,+    119854, 119828,+    119855, 119829,+    119856, 119830,+    119857, 119831,+    119858, 119832,+    119859, 119833,+    119886, 119860,+    119887, 119861,+    119888, 119862,+    119889, 119863,+    119890, 119864,+    119891, 119865,+    119892, 119866,+    119894, 119868,+    119895, 119869,+    119896, 119870,+    119897, 119871,+    119898, 119872,+    119899, 119873,+    119900, 119874,+    119901, 119875,+    119902, 119876,+    119903, 119877,+    119904, 119878,+    119905, 119879,+    119906, 119880,+    119907, 119881,+    119908, 119882,+    119909, 119883,+    119910, 119884,+    119911, 119885,+    119938, 119912,+    119939, 119913,+    119940, 119914,+    119941, 119915,+    119942, 119916,+    119943, 119917,+    119944, 119918,+    119945, 119919,+    119946, 119920,+    119947, 119921,+    119948, 119922,+    119949, 119923,+    119950, 119924,+    119951, 119925,+    119952, 119926,+    119953, 119927,+    119954, 119928,+    119955, 119929,+    119956, 119930,+    119957, 119931,+    119958, 119932,+    119959, 119933,+    119960, 119934,+    119961, 119935,+    119962, 119936,+    119963, 119937,+    119990, 119964,+    119992, 119966,+    119993, 119967,+    119999, 119973,+    120000, 119974,+    120003, 119977,+    120005, 119979,+    120006, 119980,+    120008, 119982,+    120009, 119983,+    120010, 119984,+    120011, 119985,+    120012, 119986,+    120013, 119987,+    120014, 119988,+    120015, 119989,+    120042, 120016,+    120043, 120017,+    120044, 120018,+    120045, 120019,+    120046, 120020,+    120047, 120021,+    120048, 120022,+    120049, 120023,+    120050, 120024,+    120051, 120025,+    120052, 120026,+    120053, 120027,+    120054, 120028,+    120055, 120029,+    120056, 120030,+    120057, 120031,+    120058, 120032,+    120059, 120033,+    120060, 120034,+    120061, 120035,+    120062, 120036,+    120063, 120037,+    120064, 120038,+    120065, 120039,+    120066, 120040,+    120067, 120041,+    120094, 120068,+    120095, 120069,+    120097, 120071,+    120098, 120072,+    120099, 120073,+    120100, 120074,+    120103, 120077,+    120104, 120078,+    120105, 120079,+    120106, 120080,+    120107, 120081,+    120108, 120082,+    120109, 120083,+    120110, 120084,+    120112, 120086,+    120113, 120087,+    120114, 120088,+    120115, 120089,+    120116, 120090,+    120117, 120091,+    120118, 120092,+    120146, 120120,+    120147, 120121,+    120149, 120123,+    120150, 120124,+    120151, 120125,+    120152, 120126,+    120154, 120128,+    120155, 120129,+    120156, 120130,+    120157, 120131,+    120158, 120132,+    120160, 120134,+    120164, 120138,+    120165, 120139,+    120166, 120140,+    120167, 120141,+    120168, 120142,+    120169, 120143,+    120170, 120144,+    120198, 120172,+    120199, 120173,+    120200, 120174,+    120201, 120175,+    120202, 120176,+    120203, 120177,+    120204, 120178,+    120205, 120179,+    120206, 120180,+    120207, 120181,+    120208, 120182,+    120209, 120183,+    120210, 120184,+    120211, 120185,+    120212, 120186,+    120213, 120187,+    120214, 120188,+    120215, 120189,+    120216, 120190,+    120217, 120191,+    120218, 120192,+    120219, 120193,+    120220, 120194,+    120221, 120195,+    120222, 120196,+    120223, 120197,+    120250, 120224,+    120251, 120225,+    120252, 120226,+    120253, 120227,+    120254, 120228,+    120255, 120229,+    120256, 120230,+    120257, 120231,+    120258, 120232,+    120259, 120233,+    120260, 120234,+    120261, 120235,+    120262, 120236,+    120263, 120237,+    120264, 120238,+    120265, 120239,+    120266, 120240,+    120267, 120241,+    120268, 120242,+    120269, 120243,+    120270, 120244,+    120271, 120245,+    120272, 120246,+    120273, 120247,+    120274, 120248,+    120275, 120249,+    120302, 120276,+    120303, 120277,+    120304, 120278,+    120305, 120279,+    120306, 120280,+    120307, 120281,+    120308, 120282,+    120309, 120283,+    120310, 120284,+    120311, 120285,+    120312, 120286,+    120313, 120287,+    120314, 120288,+    120315, 120289,+    120316, 120290,+    120317, 120291,+    120318, 120292,+    120319, 120293,+    120320, 120294,+    120321, 120295,+    120322, 120296,+    120323, 120297,+    120324, 120298,+    120325, 120299,+    120326, 120300,+    120327, 120301,+    120354, 120328,+    120355, 120329,+    120356, 120330,+    120357, 120331,+    120358, 120332,+    120359, 120333,+    120360, 120334,+    120361, 120335,+    120362, 120336,+    120363, 120337,+    120364, 120338,+    120365, 120339,+    120366, 120340,+    120367, 120341,+    120368, 120342,+    120369, 120343,+    120370, 120344,+    120371, 120345,+    120372, 120346,+    120373, 120347,+    120374, 120348,+    120375, 120349,+    120376, 120350,+    120377, 120351,+    120378, 120352,+    120379, 120353,+    120406, 120380,+    120407, 120381,+    120408, 120382,+    120409, 120383,+    120410, 120384,+    120411, 120385,+    120412, 120386,+    120413, 120387,+    120414, 120388,+    120415, 120389,+    120416, 120390,+    120417, 120391,+    120418, 120392,+    120419, 120393,+    120420, 120394,+    120421, 120395,+    120422, 120396,+    120423, 120397,+    120424, 120398,+    120425, 120399,+    120426, 120400,+    120427, 120401,+    120428, 120402,+    120429, 120403,+    120430, 120404,+    120431, 120405,+    120458, 120432,+    120459, 120433,+    120460, 120434,+    120461, 120435,+    120462, 120436,+    120463, 120437,+    120464, 120438,+    120465, 120439,+    120466, 120440,+    120467, 120441,+    120468, 120442,+    120469, 120443,+    120470, 120444,+    120471, 120445,+    120472, 120446,+    120473, 120447,+    120474, 120448,+    120475, 120449,+    120476, 120450,+    120477, 120451,+    120478, 120452,+    120479, 120453,+    120480, 120454,+    120481, 120455,+    120482, 120456,+    120483, 120457,+    120514, 120488,+    120515, 120489,+    120516, 120490,+    120517, 120491,+    120518, 120492,+    120519, 120493,+    120520, 120494,+    120521, 120495,+    120522, 120496,+    120523, 120497,+    120524, 120498,+    120525, 120499,+    120526, 120500,+    120527, 120501,+    120528, 120502,+    120529, 120503,+    120530, 120504,+    120532, 120506,+    120533, 120507,+    120534, 120508,+    120535, 120509,+    120536, 120510,+    120537, 120511,+    120538, 120512,+    120572, 120546,+    120573, 120547,+    120574, 120548,+    120575, 120549,+    120576, 120550,+    120577, 120551,+    120578, 120552,+    120579, 120553,+    120580, 120554,+    120581, 120555,+    120582, 120556,+    120583, 120557,+    120584, 120558,+    120585, 120559,+    120586, 120560,+    120587, 120561,+    120588, 120562,+    120590, 120564,+    120591, 120565,+    120592, 120566,+    120593, 120567,+    120594, 120568,+    120595, 120569,+    120596, 120570,+    120630, 120604,+    120631, 120605,+    120632, 120606,+    120633, 120607,+    120634, 120608,+    120635, 120609,+    120636, 120610,+    120637, 120611,+    120638, 120612,+    120639, 120613,+    120640, 120614,+    120641, 120615,+    120642, 120616,+    120643, 120617,+    120644, 120618,+    120645, 120619,+    120646, 120620,+    120648, 120622,+    120649, 120623,+    120650, 120624,+    120651, 120625,+    120652, 120626,+    120653, 120627,+    120654, 120628,+    120688, 120662,+    120689, 120663,+    120690, 120664,+    120691, 120665,+    120692, 120666,+    120693, 120667,+    120694, 120668,+    120695, 120669,+    120696, 120670,+    120697, 120671,+    120698, 120672,+    120699, 120673,+    120700, 120674,+    120701, 120675,+    120702, 120676,+    120703, 120677,+    120704, 120678,+    120706, 120680,+    120707, 120681,+    120708, 120682,+    120709, 120683,+    120710, 120684,+    120711, 120685,+    120712, 120686,+    120746, 120720,+    120747, 120721,+    120748, 120722,+    120749, 120723,+    120750, 120724,+    120751, 120725,+    120752, 120726,+    120753, 120727,+    120754, 120728,+    120755, 120729,+    120756, 120730,+    120757, 120731,+    120758, 120732,+    120759, 120733,+    120760, 120734,+    120761, 120735,+    120762, 120736,+    120764, 120738,+    120765, 120739,+    120766, 120740,+    120767, 120741,+    120768, 120742,+    120769, 120743,+    120770, 120744,+    120779, 120778,+    125218, 125184,+    125219, 125185,+    125220, 125186,+    125221, 125187,+    125222, 125188,+    125223, 125189,+    125224, 125190,+    125225, 125191,+    125226, 125192,+    125227, 125193,+    125228, 125194,+    125229, 125195,+    125230, 125196,+    125231, 125197,+    125232, 125198,+    125233, 125199,+    125234, 125200,+    125235, 125201,+    125236, 125202,+    125237, 125203,+    125238, 125204,+    125239, 125205,+    125240, 125206,+    125241, 125207,+    125242, 125208,+    125243, 125209,+    125244, 125210,+    125245, 125211,+    125246, 125212,+    125247, 125213,+    125248, 125214,+    125249, 125215,+    125250, 125216,+    125251, 125217,+  };+  const int key[2] = { c, 0 };+  const int *val = static_cast<const int*>(std::bsearch(key, lu, 1647, sizeof(key), &cmpint2));+  return val != NULL ? val[1] : c;+}

lib/pattern.cpp

@@ -2667,12 +2667,10 @@ void Pattern::compile_list(Location loc, Chars& chars, const Mods modifiers) con         {           if (is_modified(ModConst::i, modifiers, loc))           {+            if (lo >= 'a' && lo <= 'z' && c >= 'A' && c <= 'Z')+              c = lowercase(c);             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);

lib/unicode.cpp

@@ -30,7 +30,7 @@ @file      unicode.cpp @brief     Get Unicode character class ranges and UTF-8 regex translations @author    Robert van Engelen - engelen@genivia.com-@copyright (c) 2016-2020, Robert van Engelen, Genivia Inc. All rights reserved.+@copyright (c) 2016-2025, Robert van Engelen, Genivia Inc. All rights reserved. @copyright (c) BSD-3 License - see LICENSE.txt */ @@ -116,6 +116,24 @@ int compose(int prev, int next)   return -1; } +int toupper(int c)+{+  return Tables::toupper(c);+}++int tolower(int c)+{+  return Tables::tolower(c);+}++int invcase(int c)+{+  int a = toupper(c);+  if (a == c)+    a = tolower(c);+  return a;+}+ } // namespace Unicode  } // namespace reflex

man/ug.1

@@ -1,4 +1,4 @@-.TH UGREP "1" "February 03, 2025" "ugrep 7.2.2" "User Commands"+.TH UGREP "1" "March 01, 2025" "ugrep 7.3.0" "User Commands" .SH NAME \fBugrep\fR, \fBug\fR -- file pattern searcher .SH SYNOPSIS@@ -492,8 +492,7 @@ Ignore matches in binary files.  This option is equivalent to the .TP \fB\-i\fR, \fB\-\-ignore\-case\fR Perform case insensitive matching.  By default, ugrep is case-sensitive.  By default, this option applies to ASCII letters only.-Use options \fB\-P\fR and \fB\-i\fR for Unicode case insensitive matching.+sensitive. .TP \fB\-\-ignore\-files\fR[=\fIFILE\fR] Ignore files and directories matching the globs in each FILE that@@ -560,7 +559,7 @@ file systems, or any file system that is slow to search.  Note that the start\-up time to search may be increased when complex search patterns are specified that contain large Unicode character classes combined with `*' or `+' repeats, which should be avoided.  Option-\fB\-U\fR (\fB\-\-ascii\fR) improves performance.  Option \fB\-\-stats\fR displays an+\fB\-U\fR or \fB\-\-ascii\fR improves performance.  Option \fB\-\-stats\fR displays an index search report. .TP \fB\-J\fR \fINUM\fR, \fB\-\-jobs\fR=\fINUM\fR@@ -571,7 +570,7 @@ same order as specified. .TP \fB\-j\fR, \fB\-\-smart\-case\fR Perform case insensitive matching, unless a pattern is specified-with a literal upper case ASCII letter.+with a literal upper case letter. .TP \fB\-\-json\fR Output file matches in JSON.  When \fB\-H\fR, \fB\-n\fR, \fB\-k\fR, or \fB\-b\fR is specified,@@ -934,9 +933,11 @@ and compressed archives (e.g. .zip, .7z, .taz, .tgz, .tpz, .tbz, pathnames of files in archives are output in braces.  When used with option \fB\-\-zmax\fR=\fINUM\fR, searches the contents of compressed files and archives stored within archives up to NUM levels.  When \fB\-g\fR, \fB\-O\fR,-\fB\-M\fR, or \fB\-t\fR is specified, searches files stored in archives whose-filenames match globs, match filename extensions, match file-signature magic bytes, or match file types, respectively.+\fB\-M\fR, or \fB\-t\fR is specified, searches archives for files that match the+specified globs, file extensions, file signature magic bytes, or+file types, respectively; a side\-effect of these options is that+the compressed files and archives searched are only those with+filename extensions that match known compression and archive types. Supported compression formats: gzip (.gz), compress (.Z), zip, 7z, bzip2 (requires suffix .bz, .bz2, .bzip2, .tbz, .tbz2, .tb2, .tz2), lzma and xz (requires suffix .lzma, .tlz, .xz, .txz),

man/ugrep-indexer.1

@@ -1,4 +1,4 @@-.TH UGREP-INDEXER "1" "February 03, 2025" "ugrep-indexer 7.2.2" "User Commands"+.TH UGREP-INDEXER "1" "March 01, 2025" "ugrep-indexer 7.3.0" "User Commands" .SH NAME \fBugrep-indexer\fR -- file indexer to accelerate recursive searching .SH SYNOPSIS

man/ugrep.1

@@ -1,4 +1,4 @@-.TH UGREP "1" "February 03, 2025" "ugrep 7.2.2" "User Commands"+.TH UGREP "1" "March 01, 2025" "ugrep 7.3.0" "User Commands" .SH NAME \fBugrep\fR, \fBug\fR -- file pattern searcher .SH SYNOPSIS@@ -492,8 +492,7 @@ Ignore matches in binary files.  This option is equivalent to the .TP \fB\-i\fR, \fB\-\-ignore\-case\fR Perform case insensitive matching.  By default, ugrep is case-sensitive.  By default, this option applies to ASCII letters only.-Use options \fB\-P\fR and \fB\-i\fR for Unicode case insensitive matching.+sensitive. .TP \fB\-\-ignore\-files\fR[=\fIFILE\fR] Ignore files and directories matching the globs in each FILE that@@ -560,7 +559,7 @@ file systems, or any file system that is slow to search.  Note that the start\-up time to search may be increased when complex search patterns are specified that contain large Unicode character classes combined with `*' or `+' repeats, which should be avoided.  Option-\fB\-U\fR (\fB\-\-ascii\fR) improves performance.  Option \fB\-\-stats\fR displays an+\fB\-U\fR or \fB\-\-ascii\fR improves performance.  Option \fB\-\-stats\fR displays an index search report. .TP \fB\-J\fR \fINUM\fR, \fB\-\-jobs\fR=\fINUM\fR@@ -571,7 +570,7 @@ same order as specified. .TP \fB\-j\fR, \fB\-\-smart\-case\fR Perform case insensitive matching, unless a pattern is specified-with a literal upper case ASCII letter.+with a literal upper case letter. .TP \fB\-\-json\fR Output file matches in JSON.  When \fB\-H\fR, \fB\-n\fR, \fB\-k\fR, or \fB\-b\fR is specified,@@ -934,9 +933,11 @@ and compressed archives (e.g. .zip, .7z, .taz, .tgz, .tpz, .tbz, pathnames of files in archives are output in braces.  When used with option \fB\-\-zmax\fR=\fINUM\fR, searches the contents of compressed files and archives stored within archives up to NUM levels.  When \fB\-g\fR, \fB\-O\fR,-\fB\-M\fR, or \fB\-t\fR is specified, searches files stored in archives whose-filenames match globs, match filename extensions, match file-signature magic bytes, or match file types, respectively.+\fB\-M\fR, or \fB\-t\fR is specified, searches archives for files that match the+specified globs, file extensions, file signature magic bytes, or+file types, respectively; a side\-effect of these options is that+the compressed files and archives searched are only those with+filename extensions that match known compression and archive types. Supported compression formats: gzip (.gz), compress (.Z), zip, 7z, bzip2 (requires suffix .bz, .bz2, .bzip2, .tbz, .tbz2, .tb2, .tz2), lzma and xz (requires suffix .lzma, .tlz, .xz, .txz),

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.2.2"+#define UGREP_VERSION "7.3.0"  // use a task-parallel thread to decompress the stream into a pipe to search, also handles nested archives #define WITH_DECOMPRESSION_THREAD

src/ugrep.cpp

@@ -83,6 +83,7 @@ After this, you may want to test ugrep and install it (optional): #include <reflex/matcher.h> #include <reflex/linematcher.h> #include <reflex/fuzzymatcher.h>+#include <reflex/unicode.h> #include <iomanip> #include <cctype> #include <limits>@@ -6600,7 +6601,7 @@ void init(int argc, const char **argv)       exit(EXIT_ERROR);     } -    // scan the encoding_table[] for a matching encoding, case insensitive ASCII+    // scan the encoding_table[] for a matching encoding, case insensitive     for (i = 0; encoding_table[i].format != NULL; ++i)     {       for (j = 0; flag_encoding[j] != '\0' && encoding_table[i].format[j] != '\0'; ++j)@@ -8356,26 +8357,31 @@ void ugrep()   if (flag_ignore_case)     flag_smart_case = false; -  // -j: smart case insensitive search if regex does not contain an upper case letter+  // -j: smart case insensitive search if regex does not contain a Unicode upper case letter   if (flag_smart_case)   {     flag_ignore_case = true; -    for (size_t i = 0; i < regex.size(); ++i)+    for (const char *s = regex.c_str(); *s != '\0'; ++s)     {-      if (regex[i] == '\\')+      if (*s == '\\')       {-        ++i;+        ++s;       }-      else if (regex[i] == '{')+      else if (*s == '{')       {-        while (++i < regex.size() && regex[i] != '}')+        while (*++s != '\0' && *s != '}')           continue;       }-      else if (isupper(static_cast<unsigned char>(regex[i])))+      else       {-        flag_ignore_case = false;-        break;+        int c = reflex::utf8(s, &s);+        if (reflex::Unicode::tolower(c) != c)+        {+          flag_ignore_case = false;+          break;+        }+        --s;       }     }   }@@ -8506,7 +8512,7 @@ void ugrep()   // set reflex::Pattern options to enable multiline mode   std::string pattern_options("(?m"); -  // -i: case insensitive reflex::Pattern option, applies to ASCII only+  // -i: case insensitive reflex::Pattern option   if (flag_ignore_case)     pattern_options.push_back('i'); @@ -8773,7 +8779,7 @@ void ugrep()      if (flag_fuzzy > 0)     {-      // -U: disable fuzzy Unicode matching, ASCII/binary only with -Z MAX edit distance+      // -U or --binary: disable fuzzy Unicode matching, ASCII/binary matching with -Z MAX edit distance       uint16_t max = static_cast<uint16_t>(flag_fuzzy) | (flag_binary ? reflex::FuzzyMatcher::BIN : 0);       Static::matcher = std::unique_ptr<reflex::AbstractMatcher>(new reflex::FuzzyMatcher(Static::reflex_pattern, max, reflex::Input(), matcher_options.c_str())); @@ -14269,8 +14275,7 @@ void help(std::ostream& out)             --binary-files=without-match option.\n\     -i, --ignore-case\n\             Perform case insensitive matching.  By default, ugrep is case\n\-            sensitive.  By default, this option applies to ASCII letters only.\n\-            Use options -P and -i for Unicode case insensitive matching.\n\+            sensitive.\n\     --ignore-files[=FILE]\n\             Ignore files and directories matching the globs in each FILE that\n\             is encountered in recursive searches.  The default FILE is\n\@@ -14335,7 +14340,7 @@ void help(std::ostream& out)             the start-up time to search may be increased when complex search\n\             patterns are specified that contain large Unicode character classes\n\             combined with `*' or `+' repeats, which should be avoided.  Option\n\-            -U (--ascii) improves performance.  Option --stats displays an\n\+            -U or --ascii improves performance.  Option --stats displays an\n\             index search report.\n\     -J NUM, --jobs=NUM\n\             Specifies the number of threads spawned to search files.  By\n\@@ -14344,7 +14349,7 @@ void help(std::ostream& out)             same order as specified.\n\     -j, --smart-case\n\             Perform case insensitive matching, unless a pattern is specified\n\-            with a literal upper case ASCII letter.\n\+            with a literal upper case letter.\n\     --json\n\             Output file matches in JSON.  When -H, -n, -k, or -b is specified,\n\             additional values are output.  See also options --format and -u.\n\@@ -14654,9 +14659,11 @@ void help(std::ostream& out)             pathnames of files in archives are output in braces.  When used\n\             with option --zmax=NUM, searches the contents of compressed files\n\             and archives stored within archives up to NUM levels.  When -g, -O,\n\-            -M, or -t is specified, searches files stored in archives whose\n\-            filenames match globs, match filename extensions, match file\n\-            signature magic bytes, or match file types, respectively.\n"+            -M, or -t is specified, searches archives for files that match the\n\+            specified globs, file extensions, file signature magic bytes, or\n\+            file types, respectively; a side-effect of these options is that\n\+            the compressed files and archives searched are only those with\n\+            filename extensions that match known compression and archive types.\n" #ifndef HAVE_LIBZ             "\             This option is not available in this build configuration of ugrep.\n"@@ -15062,7 +15069,7 @@ example, specify -g \"*foo.*\" or -g\"*foo.*\" or \"-g*foo.*\".\n\ No whitespace may be given between -Z and its argument.\n\ \n\ Insertions, deletions and/or substitutions are applied to Unicode characters,\n\-except when option -U is specified for binary/ASCII pattern search.\n\+except when option -U is specified for ASCII/binary pattern search.\n\ \n\ The 'best' prefix outputs the best matching lines with the lowest cost (minimal\n\ edit distance) per file.  For example, if a file has an exact match anywhere,\n\

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.2.2"+#define UGREP_VERSION "7.3.0"  // disable mmap because mmap is almost always slower than the file reading speed improvements since 3.0.0 #define WITH_NO_MMAP