head 1.8; access; symbols; locks; strict; comment @ * @; 1.8 date 2026.10.14.22.25.13; author agc; state dead; branches; next 1.7; commitid EvQuBHLEvZ6nMuZG; 1.7 date 2025.07.23.01.14.07; author agc; state Exp; branches; next 1.6; commitid rSrs7KEnJrB89O3G; 1.6 date 2023.06.21.23.48.08; author agc; state Exp; branches; next 1.5; commitid Dr4GIJKe5KhuaStE; 1.5 date 2023.02.24.19.01.10; author agc; state Exp; branches; next 1.4; commitid XNCIUwEY3IazkOeE; 1.4 date 2021.12.04.03.40.29; author agc; state Exp; branches; next 1.3; commitid gs5QCYHUWnfYBhjD; 1.3 date 2021.12.04.01.54.51; author agc; state Exp; branches; next 1.2; commitid 0yjZXZ7z7xDY0hjD; 1.2 date 2021.10.05.01.23.39; author agc; state Exp; branches; next 1.1; commitid iWez0YTivClGMybD; 1.1 date 2017.08.16.23.38.13; author agc; state Exp; branches; next ; commitid QRh3ZHtCDsbQJu3A; desc @@ 1.8 log @Remove this old code, it's been superceded - see pkgsrc/devel/libagcre and pkgsrc/textproc/agcre @ text @/* * Copyright (c) 2013,2017,2020,2021,2022,2023,2025 Alistair Crooks. All Rights reserved. * Copyright (c) 2007-2009 Russ Cox, Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * Neither the name of Google, Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef AGCRE_VERSION #define AGCRE_VERSION 20250722 #include #ifdef USE_REGEX_INTERFACE #define REG_BASIC AGCRE_REG_BASIC #define REG_EXTENDED AGCRE_REG_EXTENDED #define REG_NOSPEC AGCRE_REG_NOSPEC #define REG_ICASE AGCRE_REG_ICASE #define REG_STARTEND AGCRE_REG_STARTEND #define REG_PEND AGCRE_REG_PEND #define REG_TRACE AGCRE_REG_TRACE #define REG_DUMP AGCRE_REG_DUMP #define REG_NOTBOL AGCRE_REG_NOTBOL #define REG_NOTEOL AGCRE_REG_NOTEOL #define REG_NEWLINE AGCRE_REG_NEWLINE #define REG_NOSUB AGCRE_REG_NOSUB #define REG_UTF16LE AGCRE_REG_UTF16LE #define REG_UTF16BE AGCRE_REG_UTF16BE #define REG_UTF32LE AGCRE_REG_UTF32LE #define REG_UTF32BE AGCRE_REG_UTF32BE #define REG_SUCCESS AGCRE_REG_SUCCESS #define REG_FAILURE AGCRE_REG_FAILURE #define REG_NOMATCH AGCRE_REG_FAILURE #define REG_MAGIC AGCRE_MAGIC2 #define REG_MAX_SUBEXPR AGCRE_MAX_SUBEXPR #define REG_MAX_EXPR_LENGTH AGCRE_MAX_EXPR_LENGTH #define REG_ANCHOR AGCRE_REG_ANCHOR #define REG_CTAGS AGCRE_REG_CTAGS #define regoff_t agcre_regoff_t #define regmatch_t agcre_regmatch_t #define regex_t agcre_regex_t #define regcomp agcre_regcomp #define regexec agcre_regexec #define regfree agcre_regfree #define regerror agcre_regerror #endif #define AGCRE_REG_BASIC 0x00000001 #define AGCRE_REG_EXTENDED 0x00000002 #define AGCRE_REG_NOSPEC 0x00000004 #define AGCRE_REG_ICASE 0x00000008 #define AGCRE_REG_STARTEND 0x00000010 #define AGCRE_REG_PEND 0x00000020 #define AGCRE_REG_TRACE 0x00000040 #define AGCRE_REG_DUMP 0x00000080 #define AGCRE_REG_NOTBOL 0x00000100 #define AGCRE_REG_NOTEOL 0x00000200 #define AGCRE_REG_NEWLINE 0x00000400 #define AGCRE_REG_NOSUB 0x00000800 #define AGCRE_REG_UTF16LE 0x00001000 #define AGCRE_REG_UTF16BE 0x00002000 #define AGCRE_REG_UTF32LE 0x00004000 #define AGCRE_REG_UTF32BE 0x00008000 #define AGCRE_REG_ANCHOR 0x00010000 #define AGCRE_REG_CTAGS 0x00020000 #define AGCRE_REG_SUCCESS 0 #define AGCRE_REG_FAILURE 1 #define AGCRE_MAGIC2 0x20230621 /* limits we impose on expressions */ #define AGCRE_MAX_SUBEXPR 100 #define AGCRE_MAX_EXPR_LENGTH 1024 #ifdef LIB_NAMESPACE #define AGCRE_CONCAT(x, y) x##y #define AGCRE_NAMESPACE(x, y) AGCRE_CONCAT(x, y) #define agcre_regex_t AGCRE_NAMESPACE(LIB_NAMESPACE, agcre_regex_t) #define agcre_regoff_t AGCRE_NAMESPACE(LIB_NAMESPACE, agcre_regoff_t) #define agcre_regmatch_t AGCRE_NAMESPACE(LIB_NAMESPACE, agcre_regmatch_t) #define agcre_regex_new AGCRE_NAMESPACE(LIB_NAMESPACE, agcre_regex_new) #define agcre_regcomp AGCRE_NAMESPACE(LIB_NAMESPACE, agcre_regcomp) #define agcre_regexec AGCRE_NAMESPACE(LIB_NAMESPACE, agcre_regexec) #define agcre_rev_regexec AGCRE_NAMESPACE(LIB_NAMESPACE, agcre_rev_regexec) #define agcre_regfree AGCRE_NAMESPACE(LIB_NAMESPACE, agcre_regfree) #define agcre_regerror AGCRE_NAMESPACE(LIB_NAMESPACE, agcre_regerror) #define agcre_regnsub AGCRE_NAMESPACE(LIB_NAMESPACE, agcre_regnsub) #define agcre_regasub AGCRE_NAMESPACE(LIB_NAMESPACE, agcre_regasub) #endif typedef int64_t agcre_regoff_t; /* a match structure */ typedef struct agcre_regmatch_t { agcre_regoff_t rm_so; /* start offset */ agcre_regoff_t rm_eo; /* end offset */ } agcre_regmatch_t; /* a regexp structure */ typedef struct agcre_regex_t { uint32_t re_magic; /* magic number */ size_t re_nsub; /* number of subexpressions */ const char *re_endp; /* pointer to end of expr */ void *re_g; /* internals */ } agcre_regex_t; #ifndef __BEGIN_DECLS # if defined(__cplusplus) # define __BEGIN_DECLS extern "C" { # define __END_DECLS } # else # define __BEGIN_DECLS # define __END_DECLS # endif #endif __BEGIN_DECLS agcre_regex_t *agcre_new(void); int agcre_regcomp(agcre_regex_t */*re*/, const void */*s*/, uint32_t /*flags*/); int agcre_regexec(agcre_regex_t */*re*/, const void */*vs*/, size_t /*mc*/, agcre_regmatch_t */*m*/, uint32_t /*flags*/); int agcre_rev_regexec(agcre_regex_t */*agcre*/, const void */*vs*/, size_t /*matchc*/, agcre_regmatch_t */*m*/, uint32_t /*flags*/); void agcre_regfree(agcre_regex_t */*re*/); size_t agcre_regerror(int /*errcode*/, const agcre_regex_t */*agcre*/, char */*errbuf*/, size_t /*size*/); ssize_t agcre_regnsub(char */*buf*/, size_t /*size*/, const char */*repl*/, const agcre_regmatch_t */*rm*/, const char */*str*/); ssize_t agcre_regasub(char **/*buf*/, const char */*repl*/, const agcre_regmatch_t */*rm*/, const char */*str*/); __END_DECLS #endif @ 1.7 log @agcre: fix up beginning of word and end of word tests - use parentheses to make it obvious to the compiler when to short-circuit. Add tests for beginning word and end of word (with and without \< and \> guards) Bump version to 20250722 @ text @@ 1.6 log @agcre version 20230621 ====================== + agcre - added internal magic numbers to agcre to attempt to catch if misbehaving programs overwrite sections of memory + agcre - check internal magic numbers before attempting to execute regex programs + agcre - bump agcre magic number in the external structure + agcre - bump version number in header file. Fix up tests to ensure correct operation @ text @d2 1 a2 1 * Copyright (c) 2013,2017,2020,2021,2022,2023 Alistair Crooks. All Rights reserved. d32 1 a32 1 #define AGCRE_VERSION 20230621 @ 1.5 log @Update agcre (yet another regexp library) to version 20230224 + revamp the reverse searching functionality + bug fixes + don't terminate searches too early + update namespace protection to just use simple definitions + bump version to 20230224 @ text @d32 1 a32 1 #define AGCRE_VERSION 20230224 d56 1 a56 1 #define REG_MAGIC AGCRE_MAGIC d92 1 a92 1 #define AGCRE_MAGIC 0x20170801 @ 1.4 log @Change HIDE_AGCRE to be a 0/1 value, rather than defined/undef By default, don't hide (i.e. export all symbols) NFC @ text @d2 1 a2 1 * Copyright (c) 2013,2017,2020,2021 Alistair Crooks. All Rights reserved. d32 1 a32 1 #define AGCRE_VERSION 20211001 d98 16 a129 31 #ifndef USE_VISIBILITY # if defined(__GNUC__) # if __GNUC__ >= 4 # define USE_VISIBILITY 1 # else # define USE_VISIBILITY 0 # endif # else # define USE_VISIBILITY 0 # endif #endif #if USE_VISIBILITY # define DLL_PUBLIC __attribute__ ((visibility ("default"))) # define DLL_LOCAL __attribute__ ((visibility ("hidden"))) #else # define DLL_PUBLIC # define DLL_LOCAL #endif /* by default, don't hide external symbols */ #ifndef HIDE_AGCRE #define HIDE_AGCRE 0 #endif #if HIDE_AGCRE #define AGCRE_EXPORT DLL_LOCAL #else #define AGCRE_EXPORT DLL_PUBLIC #endif d142 3 a144 3 AGCRE_EXPORT agcre_regex_t *agcre_new(void); AGCRE_EXPORT int agcre_regcomp(agcre_regex_t */*re*/, const void */*s*/, uint32_t /*flags*/); AGCRE_EXPORT int agcre_regexec(agcre_regex_t */*re*/, const void */*vs*/, size_t /*mc*/, d146 1 a146 1 AGCRE_EXPORT int agcre_rev_regexec(agcre_regex_t */*agcre*/, const void */*vs*/, d148 2 a149 2 AGCRE_EXPORT void agcre_regfree(agcre_regex_t */*re*/); AGCRE_EXPORT size_t agcre_regerror(int /*errcode*/, const agcre_regex_t */*agcre*/, d151 1 a151 1 AGCRE_EXPORT ssize_t agcre_regnsub(char */*buf*/, size_t /*size*/, const char */*repl*/, d153 1 a153 1 AGCRE_EXPORT ssize_t agcre_regasub(char **/*buf*/, const char */*repl*/, @ 1.3 log @Add visibility definitions for agcre. For any sources embedding these routines, simply define HIDE_AGCRE, before including the agcre.h header file, and the routines will have the hidden visibility attribute set on them. For more information on that, see https://gcc.gnu.org/wiki/Visibility To stop agcre routines being exported in a .so, simply define HIDE_AGCRE - I've been doing this successfully in library Makefiles, for example, this is from elex/lib/Makefile (elex is a library that calls the agcre functions): # set symbol visibility for .so CPPFLAGS+= -DHIDE_AGCRE and the agcre symbols will be found just fine when linking and running, but will not be exported by the linker. This can save headaches, and weird crashes, especially when combined with ASLR (when two libraries define the same symbol, but with different structs or arguments). BEFORE: [2021/12/03 Fri 17:47:19] agc@@netbsd-002 ~/local/elex-20211115 [13781] > nm -D lib/libelex.so w _Jv_RegisterClasses w __cxa_finalize w __deregister_frame_info U __fstat50 w __register_frame_info U __sF 000000000020f198 D _end 000000000000c240 T _fini 0000000000000ea0 T _init 000000000000aa13 T agcre_new 000000000000bc48 T agcre_regasub 000000000000aa28 T agcre_regcomp 000000000000adde T agcre_regerror 000000000000ae48 T agcre_regexec 000000000000b8fd T agcre_regfree 000000000000b9a2 T agcre_regnsub 000000000000b7e8 T agcre_rev_regexec U asprintf U calloc 00000000000027f6 T elex_dispose 0000000000002b6a T elex_exec 0000000000002f5b T elex_exec_str 0000000000002982 T elex_make_new_rule 00000000000027bb T elex_new U fclose U fopen U fprintf U free U fwrite U memchr U memcmp U memcpy U memmove U memset U mmap U munmap U printf U putchar U realloc U snprintf U strchr U strcmp U strdup 000000000000c10c T striter_dispose 000000000000c165 T striter_exec 000000000000c1da T striter_exec_mem 000000000000c0f7 T striter_new U strlen U strtol U strtoul U vsnprintf U warn U warnx [2021/12/03 Fri 17:47:22] agc@@netbsd-002 ~/local/elex-20211115 [13782] > AFTER adding HIDE_AGCRE (and HIDE_STRITER) to elex/lib/Makefile: [2021/12/03 Fri 17:47:45] agc@@netbsd-002 ~/local/elex-20211115 [13774] > nm -D lib/libelex.so w _Jv_RegisterClasses w __cxa_finalize w __deregister_frame_info U __fstat50 w __register_frame_info U __sF 000000000020e160 D _end 000000000000bf30 T _fini 0000000000000c00 T _init U asprintf U calloc 00000000000024e6 T elex_dispose 000000000000285a T elex_exec 0000000000002c4b T elex_exec_str 0000000000002672 T elex_make_new_rule 00000000000024ab T elex_new U fclose U fopen U fprintf U free U fwrite U memchr U memcmp U memcpy U memmove U memset U mmap U munmap U printf U putchar U realloc U snprintf U strchr U strcmp U strdup U strlen U strtol U strtoul U vsnprintf U warn U warnx @ text @d134 6 a139 1 #ifdef HIDE_AGCRE @ 1.2 log @Update agcre to version 20211001 20211001 ======== + move to a single source file, which can just be included as a single file (the library method can still be used for this as well - sometimes, it's just easier to drop in a single file to other projects) + add AGCRE_EMBED_CTAGS as a primary regular expresion type (same as basic regexps, but where a '*' occurs as a non-column 0 element of the pattern, it is assumed to be a standard character, as produced by ctags(1) output; basic regular expressions only accept '*' as a standard character as the first element of the expression). Yay. + make the version string in the program a real string, so it can be found using strings(1) + add an agcre_rev_regexec(3) function, which searches the text in an efficient, reverse manner, a la strrchr(3) or memrchr(3) fashion. + add agcre_regnsub(3) and agcre_regasub(3) functions + bump the shared lib version to 1.0 + cut version 20211001 @ text @d114 26 d152 3 a154 3 agcre_regex_t *agcre_new(void); int agcre_regcomp(agcre_regex_t */*re*/, const void */*s*/, uint32_t /*flags*/); int agcre_regexec(agcre_regex_t */*re*/, const void */*vs*/, size_t /*mc*/, d156 1 a156 1 int agcre_rev_regexec(agcre_regex_t */*agcre*/, const void */*vs*/, d158 2 a159 2 void agcre_regfree(agcre_regex_t */*re*/); size_t agcre_regerror(int /*errcode*/, const agcre_regex_t */*agcre*/, d161 1 a161 1 ssize_t agcre_regnsub(char */*buf*/, size_t /*size*/, const char */*repl*/, d163 1 a163 1 ssize_t agcre_regasub(char **/*buf*/, const char */*repl*/, @ 1.1 log @Just what this world needs - another regexp library. However, for something I was doing, I needed a regexp library in C, BSD-licensed, and able to be exposed to a wide range of expressions, some better controlled than others. The resulting library is libagcre, which implements regular expression compilation and execution. It uses the Pike Virtual Machine approach, and features: + standard POSIX features where sane + some/most Perl escapes + lazy matching via '?' + non-capture parenthese (?:...) + in-expression case-insensitive directives are supported (?i)...(?-i) + all case-insensitivity is actioned at expression exec time. Case-insensitivity can be specified at expression compile-time, and, if so, it will be remembered. But the expression itself, once compiled, can be used to match in both a case-sensitive and insensitive manner + utf8 is supported both for expressions and for input text when matching + unicode escapes (in the Java format of \uABCD) are supported + exact multiple repetition specifiers {N}, and {N,M} are supported + backreferences are supported + utf16 (LE and BE) and utf32 (LE and BE) are supported, both for the expression and for the input being searched + at the most basic level, individual 32bit unicode characters are matched + an egrep/grep implementation for matching unicode regexps is included A simple implementation of sets is used to provide inclusion and exclusion information for unicode characters, which is taken directly from unicode.org. No bitmasks are used - ranges are specified by using an upper and a lower bound for the codepoints. Callbacks can also be added to these sets, to provide functionality similar to the ctype macros across the whole unicode character set. The standard regular expression basic3 torture test is passed with 4 known (and, I'd argue, incorrect) results flagged. As expected, the expression '(a?){9999}aaaaaaaaaaaaaaaaaaaaaaaaaaaaa' matches in linear time, as does the expression '((((((((((((((((((((((((((((((x))))))))))))))))))))))))))))))' % time agcre '(a?){9999}aaaaaaaaaaaaaaaaaaaaaaaaaaaaa' dist/tests/2.in aaaaaaaaaaaaaaaaaaaaaaaaaaaaa 0.063u 0.000s 0:00.06 100.0% 0+0k 0+0io 0pf+0w % time egrep '(a?){9999}aaaaaaaaaaaaaaaaaaaaaaaaaaaaa' dist/tests/2.in ^C88.462u 0.730s 1:29.21 99.9% 0+0k 0+0io 0pf+0w % The library and agcre utility have been run through valgrind to confirm no memory leaks. In general, the emphasis is on a modern, predictable, VM-style, well-featured regexp library, in C, with a BSD license. In particular, sljit has not been used to speed up on certain platforms, most Perl regexp features are supported, as are back references, and UTF-8, UTF-16 and UTF32. Once again, I wouldn't expect anyone to use this as the main engine in egrep. But I am always amazed at the uses for some of the things that I write. For more information about the Pike VM, and comparison to other regexp implementations, please see: https://swtch.com/~rsc/regexp/regexp2.html Alistair Crooks Tue Aug 15 07:43:34 PDT 2017 @ text @d2 1 a2 1 * Copyright (c) 2013,2017 Alistair Crooks. All Rights reserved. d32 1 a32 1 #define AGCRE_VERSION 20170801 d55 1 d59 2 d63 1 a63 1 #define regex_t agcre_re_t d86 2 d107 1 a107 1 typedef struct agcre_re_t { d112 1 a112 1 } agcre_re_t; d126 13 a138 7 agcre_re_t *agcre_new(void); int agcre_regcomp(agcre_re_t * /*re*/, const void * /*s*/, uint32_t /*flags*/); int agcre_regexec(agcre_re_t * /*re*/, const void * /*vs*/, size_t /*mc*/, agcre_regmatch_t * /*m*/, uint32_t /*flags*/); void agcre_regfree(agcre_re_t * /*re*/); size_t agcre_regerror(int /*errcode*/, const agcre_re_t * /*agcre*/, char * /*errbuf*/, size_t /*size*/); @