Windows: official port -- UCRT static build, UTF-8 throughout, Low IL sandbox, ncurses TUI, installer; v0.6.0
ci / linux (clang) (push) Canceled after 0s
ci / linux (gcc) (push) Canceled after 0s
ci / sanitizers (push) Canceled after 0s
ci / musl (push) Canceled after 0s
ci / macos (push) Canceled after 0s

Build
  * cross build switches to pkgsCross.ucrt64 (shell-win.nix); curl (Schannel),
    winpthreads and ncurses 6.6 are linked statically, so the release is
    cst-agent.exe + busybox.exe (busybox-w32 Unicode) with no extra DLLs
  * windres embeds a manifest with activeCodePage=UTF-8 and a version resource
  * ncurses 6.6 Windows console driver patches (mouse button state, A_DIM,
    wide-char declarations): scripts/patches/
  * scripts/bootstrap_msys2.sh builds the same release natively in MSYS2
    UCRT64; PR #1's MINGW64 notes now point there
  * vendor/tre-regex (musl's TRE) provides <regex.h> on MinGW

UTF-8
  * paths cross the system call boundary as UTF-16 (*W APIs); console code
    pages set to 65001 and restored on exit; files are read and written in
    binary mode
  * child output that is not valid UTF-8 is decoded from the console, OEM or
    ANSI system code page
  * read_file hides CR; edit_file, apply_patch and write_file keep CRLF line
    endings and a UTF-8 BOM

OS layer and processes
  * os_dir_* and cst_fnmatch replace the POSIX-only directory walks in
    subagent, plugins, skills, undo and fs_tools; realpath / path_under and
    symlink rejection work on Windows
  * every child goes through CreateProcessW with its own environment block
    inside a Job Object, so timeouts and Esc end the whole process tree

Sandbox (auto mode, "auto · lowil")
  * run_shell runs with a restricted Low integrity token; the workspace gets
    an inheritable Low label once, the sandbox TEMP is labeled Low, and the
    credentials file gets a no-read-up label
  * drive roots, the profile and system folders are never labeled
  * network commands still ask, since Low IL does not block the network;
    Access denied and MSYS2's 0xc0000142 offer a rerun outside the sandbox
  * /sandbox lists labeled folders, /sandbox reset-labels restores them

TUI
  * raster console fonts are switched to Consolas / NSimSun while running
  * the home logo falls back to text when the console font lacks U+2580
  * mouse drag copy goes to the Windows clipboard

Distribution
  * scripts/install_windows.ps1 installs a Gitea release into
    %LOCALAPPDATA%\Programs\cst-agent and adds it to the user PATH;
    cst-agent-update.cmd reruns it; scripts/release_windows.sh uploads the
    zip with the token taken from the environment
  * scripts/run_windows.bat is gone; docs/README-windows.md is rewritten

Tests
  * new test_lowil, test_win_utf8 and test_os_dir; tests made portable
    (cst_test_util.h)
  * scripts/win_test.sh and scripts/winvm/ run the suite on English and
    Chinese Windows Server VMs as Administrator, a standard user and a
    Chinese user name: 29/29 on all six
This commit is contained in:
WHC
2026-10-06 23:08:14 +08:00
parent 9862c29f58
commit 2a43ae6622
84 changed files with 9784 additions and 1083 deletions
+193
View File
@@ -0,0 +1,193 @@
musl as a whole is licensed under the following standard MIT license:
----------------------------------------------------------------------
Copyright © 2005-2020 Rich Felker, et al.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------
Authors/contributors include:
A. Wilcox
Ada Worcester
Alex Dowad
Alex Suykov
Alexander Monakov
Andre McCurdy
Andrew Kelley
Anthony G. Basile
Aric Belsito
Arvid Picciani
Bartosz Brachaczek
Benjamin Peterson
Bobby Bingham
Boris Brezillon
Brent Cook
Chris Spiegel
Clément Vasseur
Daniel Micay
Daniel Sabogal
Daurnimator
David Carlier
David Edelsohn
Denys Vlasenko
Dmitry Ivanov
Dmitry V. Levin
Drew DeVault
Emil Renner Berthing
Fangrui Song
Felix Fietkau
Felix Janda
Gianluca Anzolin
Hauke Mehrtens
He X
Hiltjo Posthuma
Isaac Dunham
Jaydeep Patil
Jens Gustedt
Jeremy Huntwork
Jo-Philipp Wich
Joakim Sindholt
John Spencer
Julien Ramseier
Justin Cormack
Kaarle Ritvanen
Khem Raj
Kylie McClain
Leah Neukirchen
Luca Barbato
Luka Perkov
M Farkas-Dyck (Strake)
Mahesh Bodapati
Markus Wichmann
Masanori Ogino
Michael Clark
Michael Forney
Mikhail Kremnyov
Natanael Copa
Nicholas J. Kain
orc
Pascal Cuoq
Patrick Oppenlander
Petr Hosek
Petr Skocik
Pierre Carrier
Reini Urban
Rich Felker
Richard Pennington
Ryan Fairfax
Samuel Holland
Segev Finer
Shiz
sin
Solar Designer
Stefan Kristiansson
Stefan O'Rear
Szabolcs Nagy
Timo Teräs
Trutz Behn
Valentin Ochs
Will Dietz
William Haddon
William Pitcock
Portions of this software are derived from third-party works licensed
under terms compatible with the above MIT license:
The TRE regular expression implementation (src/regex/reg* and
src/regex/tre*) is Copyright © 2001-2008 Ville Laurikari and licensed
under a 2-clause BSD license (license text in the source files). The
included version has been heavily modified by Rich Felker in 2012, in
the interests of size, simplicity, and namespace cleanliness.
Much of the math library code (src/math/* and src/complex/*) is
Copyright © 1993,2004 Sun Microsystems or
Copyright © 2003-2011 David Schultz or
Copyright © 2003-2009 Steven G. Kargl or
Copyright © 2003-2009 Bruce D. Evans or
Copyright © 2008 Stephen L. Moshier or
Copyright © 2017-2018 Arm Limited
and labelled as such in comments in the individual source files. All
have been licensed under extremely permissive terms.
The ARM memcpy code (src/string/arm/memcpy.S) is Copyright © 2008
The Android Open Source Project and is licensed under a two-clause BSD
license. It was taken from Bionic libc, used on Android.
The AArch64 memcpy and memset code (src/string/aarch64/*) are
Copyright © 1999-2019, Arm Limited.
The implementation of DES for crypt (src/crypt/crypt_des.c) is
Copyright © 1994 David Burren. It is licensed under a BSD license.
The implementation of blowfish crypt (src/crypt/crypt_blowfish.c) was
originally written by Solar Designer and placed into the public
domain. The code also comes with a fallback permissive license for use
in jurisdictions that may not recognize the public domain.
The smoothsort implementation (src/stdlib/qsort.c) is Copyright © 2011
Valentin Ochs and is licensed under an MIT-style license.
The x86_64 port was written by Nicholas J. Kain and is licensed under
the standard MIT terms.
The mips and microblaze ports were originally written by Richard
Pennington for use in the ellcc project. The original code was adapted
by Rich Felker for build system and code conventions during upstream
integration. It is licensed under the standard MIT terms.
The mips64 port was contributed by Imagination Technologies and is
licensed under the standard MIT terms.
The powerpc port was also originally written by Richard Pennington,
and later supplemented and integrated by John Spencer. It is licensed
under the standard MIT terms.
All other files which have no copyright comments are original works
produced specifically for use as part of this library, written either
by Rich Felker, the main author of the library, or by one or more
contibutors listed above. Details on authorship of individual files
can be found in the git version control history of the project. The
omission of copyright and license comments in each file is in the
interest of source tree size.
In addition, permission is hereby granted for all public header files
(include/* and arch/*/bits/*) and crt files intended to be linked into
applications (crt/*, ldso/dlstart.c, and arch/*/crt_arch.h) to omit
the copyright notice and permission notice otherwise required by the
license, and to use these files without any requirement of
attribution. These files include substantial contributions from:
Bobby Bingham
John Spencer
Nicholas J. Kain
Rich Felker
Richard Pennington
Stefan Kristiansson
Szabolcs Nagy
all of whom have explicitly granted such permission.
This file previously contained text expressing a belief that most of
the files covered by the above exception were sufficiently trivial not
to be subject to copyright, resulting in confusion over whether it
negated the permissions granted in the license. In the spirit of
permissive licensing, and of not having licensing issues being an
obstacle to adoption, that text has been removed.
+2953
View File
File diff suppressed because it is too large Load Diff
+36
View File
@@ -0,0 +1,36 @@
#include <string.h>
#include "regex.h"
#include <stdio.h>
/* Error message strings for error codes listed in `regex.h'. This list
needs to be in sync with the codes listed there, naturally. */
/* Converted to single string by Rich Felker to remove the need for
* data relocations at runtime, 27 Feb 2006. */
static const char messages[] = {
"No error\0"
"No match\0"
"Invalid regexp\0"
"Unknown collating element\0"
"Unknown character class name\0"
"Trailing backslash\0"
"Invalid back reference\0"
"Missing ']'\0"
"Missing ')'\0"
"Missing '}'\0"
"Invalid contents of {}\0"
"Invalid character range\0"
"Out of memory\0"
"Repetition not preceded by valid expression\0"
"\0Unknown error"
};
size_t regerror(int e, const regex_t *restrict preg, char *restrict buf, size_t size)
{
const char *s;
(void)preg;
for (s=messages; e && *s; e--, s+=strlen(s)+1);
if (!*s) s++;
return 1+snprintf(buf, size, "%s", s);
}
+62
View File
@@ -0,0 +1,62 @@
/* POSIX <regex.h> for platforms without one (MinGW). The engine is musl's
* TRE (vendor/tre-regex, musl 1.2.5) patched to decode UTF-8 itself, so
* patterns and subjects are UTF-8 regardless of wchar_t width. */
#ifndef _REGEX_H
#define _REGEX_H
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef ptrdiff_t regoff_t;
typedef struct re_pattern_buffer {
size_t re_nsub;
void *__opaque, *__padding[4];
size_t __nsub2;
char __padding2;
} regex_t;
typedef struct {
regoff_t rm_so;
regoff_t rm_eo;
} regmatch_t;
#define REG_EXTENDED 1
#define REG_ICASE 2
#define REG_NEWLINE 4
#define REG_NOSUB 8
#define REG_NOTBOL 1
#define REG_NOTEOL 2
#define REG_OK 0
#define REG_NOMATCH 1
#define REG_BADPAT 2
#define REG_ECOLLATE 3
#define REG_ECTYPE 4
#define REG_EESCAPE 5
#define REG_ESUBREG 6
#define REG_EBRACK 7
#define REG_EPAREN 8
#define REG_EBRACE 9
#define REG_BADBR 10
#define REG_ERANGE 11
#define REG_ESPACE 12
#define REG_BADRPT 13
#define REG_ENOSYS -1
int regcomp(regex_t *__restrict, const char *__restrict, int);
int regexec(const regex_t *__restrict, const char *__restrict, size_t, regmatch_t *__restrict, int);
void regfree(regex_t *);
size_t regerror(int, const regex_t *__restrict, char *__restrict, size_t);
#ifdef __cplusplus
}
#endif
#endif
+1028
View File
File diff suppressed because it is too large Load Diff
+158
View File
@@ -0,0 +1,158 @@
/*
tre-mem.c - TRE memory allocator
Copyright (c) 2001-2009 Ville Laurikari <vl@iki.fi>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. 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.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER 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
HOLDER 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.
*/
/*
This memory allocator is for allocating small memory blocks efficiently
in terms of memory overhead and execution speed. The allocated blocks
cannot be freed individually, only all at once. There can be multiple
allocators, though.
*/
#include <stdlib.h>
#include <string.h>
#include "tre.h"
/*
This memory allocator is for allocating small memory blocks efficiently
in terms of memory overhead and execution speed. The allocated blocks
cannot be freed individually, only all at once. There can be multiple
allocators, though.
*/
/* Returns a new memory allocator or NULL if out of memory. */
tre_mem_t
tre_mem_new_impl(int provided, void *provided_block)
{
tre_mem_t mem;
if (provided)
{
mem = provided_block;
memset(mem, 0, sizeof(*mem));
}
else
mem = xcalloc(1, sizeof(*mem));
if (mem == NULL)
return NULL;
return mem;
}
/* Frees the memory allocator and all memory allocated with it. */
void
tre_mem_destroy(tre_mem_t mem)
{
tre_list_t *tmp, *l = mem->blocks;
while (l != NULL)
{
xfree(l->data);
tmp = l->next;
xfree(l);
l = tmp;
}
xfree(mem);
}
/* Allocates a block of `size' bytes from `mem'. Returns a pointer to the
allocated block or NULL if an underlying malloc() failed. */
void *
tre_mem_alloc_impl(tre_mem_t mem, int provided, void *provided_block,
int zero, size_t size)
{
void *ptr;
if (mem->failed)
{
return NULL;
}
if (mem->n < size)
{
/* We need more memory than is available in the current block.
Allocate a new block. */
tre_list_t *l;
if (provided)
{
if (provided_block == NULL)
{
mem->failed = 1;
return NULL;
}
mem->ptr = provided_block;
mem->n = TRE_MEM_BLOCK_SIZE;
}
else
{
int block_size;
if (size * 8 > TRE_MEM_BLOCK_SIZE)
block_size = size * 8;
else
block_size = TRE_MEM_BLOCK_SIZE;
l = xmalloc(sizeof(*l));
if (l == NULL)
{
mem->failed = 1;
return NULL;
}
l->data = xmalloc(block_size);
if (l->data == NULL)
{
xfree(l);
mem->failed = 1;
return NULL;
}
l->next = NULL;
if (mem->current != NULL)
mem->current->next = l;
if (mem->blocks == NULL)
mem->blocks = l;
mem->current = l;
mem->ptr = l->data;
mem->n = block_size;
}
}
/* Make sure the next pointer will be aligned. */
size += ALIGN(mem->ptr + size, long);
/* Allocate from current block. */
ptr = mem->ptr;
mem->ptr += size;
mem->n -= size;
/* Set to zero if needed. */
if (zero)
memset(ptr, 0, size);
return ptr;
}
+267
View File
@@ -0,0 +1,267 @@
/*
tre-internal.h - TRE internal definitions
Copyright (c) 2001-2009 Ville Laurikari <vl@iki.fi>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. 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.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER 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
HOLDER 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.
*/
#include "regex.h"
#include <stdint.h>
#include <wchar.h>
#include <wctype.h>
#define hidden
#undef TRE_MBSTATE
#ifndef NDEBUG
#define NDEBUG
#endif
#ifndef CHARCLASS_NAME_MAX
#define CHARCLASS_NAME_MAX 14
#endif
#ifndef RE_DUP_MAX
#define RE_DUP_MAX 255
#endif
#define TRE_REGEX_T_FIELD __opaque
typedef int reg_errcode_t;
typedef int tre_char_t;
#define DPRINT(msg) do { } while(0)
#define elementsof(x) ( sizeof(x) / sizeof(x[0]) )
/* wchar_t is 16 bits on Windows: decode UTF-8 to code points ourselves.
Returns the sequence length, 0 at NUL, -1 on invalid input. */
static inline int tre_mbtowc(tre_char_t *pwc, const char *s, size_t n)
{
const unsigned char *p = (const unsigned char *)s;
int c, len, i;
if (n == 0) return -1;
c = p[0];
if (c < 0x80) { *pwc = c; return c ? 1 : 0; }
if (c < 0xC2) return -1;
if (c < 0xE0) { len = 2; c &= 0x1F; }
else if (c < 0xF0) { len = 3; c &= 0x0F; }
else if (c < 0xF5) { len = 4; c &= 0x07; }
else return -1;
if ((size_t)len > n) return -1;
for (i = 1; i < len; i++) {
if ((p[i] & 0xC0) != 0x80) return -1;
c = (c << 6) | (p[i] & 0x3F);
}
if ((len == 3 && c < 0x800) || (len == 4 && (c < 0x10000 || c > 0x10FFFF))
|| (c >= 0xD800 && c <= 0xDFFF)) return -1;
*pwc = c;
return len;
}
#define tre_mbrtowc(pwc, s, n, ps) (tre_mbtowc((pwc), (s), (n)))
/* Wide characters. */
typedef int tre_cint_t;
#define TRE_CHAR_MAX 0x10ffff
#define tre_isalnum(c) ((c) <= 0xFFFF ? iswalnum((wint_t)(c)) : 1)
#define tre_isalpha(c) ((c) <= 0xFFFF ? iswalpha((wint_t)(c)) : 1)
#define tre_isblank(c) ((c) <= 0xFFFF ? iswblank((wint_t)(c)) : 0)
#define tre_iscntrl(c) ((c) <= 0xFFFF ? iswcntrl((wint_t)(c)) : 0)
#define tre_isdigit(c) ((c) <= 0xFFFF ? iswdigit((wint_t)(c)) : 0)
#define tre_isgraph(c) ((c) <= 0xFFFF ? iswgraph((wint_t)(c)) : 1)
#define tre_islower(c) ((c) <= 0xFFFF ? iswlower((wint_t)(c)) : 0)
#define tre_isprint(c) ((c) <= 0xFFFF ? iswprint((wint_t)(c)) : 1)
#define tre_ispunct(c) ((c) <= 0xFFFF ? iswpunct((wint_t)(c)) : 0)
#define tre_isspace(c) ((c) <= 0xFFFF ? iswspace((wint_t)(c)) : 0)
#define tre_isupper(c) ((c) <= 0xFFFF ? iswupper((wint_t)(c)) : 0)
#define tre_isxdigit(c) ((c) <= 0xFFFF ? iswxdigit((wint_t)(c)) : 0)
#define tre_tolower(c) ((c) <= 0xFFFF ? (int)towlower((wint_t)(c)) : (c))
#define tre_toupper(c) ((c) <= 0xFFFF ? (int)towupper((wint_t)(c)) : (c))
#define tre_strlen wcslen
/* Use system provided iswctype() and wctype(). */
typedef wctype_t tre_ctype_t;
#define tre_isctype(c, t) ((c) <= 0xFFFF ? iswctype((wint_t)(c), (t)) : 0)
#define tre_ctype wctype
/* Returns number of bytes to add to (char *)ptr to make it
properly aligned for the type. */
#define ALIGN(ptr, type) \
((((uintptr_t)ptr) % sizeof(type)) \
? (sizeof(type) - (((uintptr_t)ptr) % sizeof(type))) \
: 0)
#undef MAX
#undef MIN
#define MAX(a, b) (((a) >= (b)) ? (a) : (b))
#define MIN(a, b) (((a) <= (b)) ? (a) : (b))
/* TNFA transition type. A TNFA state is an array of transitions,
the terminator is a transition with NULL `state'. */
typedef struct tnfa_transition tre_tnfa_transition_t;
struct tnfa_transition {
/* Range of accepted characters. */
tre_cint_t code_min;
tre_cint_t code_max;
/* Pointer to the destination state. */
tre_tnfa_transition_t *state;
/* ID number of the destination state. */
int state_id;
/* -1 terminated array of tags (or NULL). */
int *tags;
/* Assertion bitmap. */
int assertions;
/* Assertion parameters. */
union {
/* Character class assertion. */
tre_ctype_t class;
/* Back reference assertion. */
int backref;
} u;
/* Negative character class assertions. */
tre_ctype_t *neg_classes;
};
/* Assertions. */
#define ASSERT_AT_BOL 1 /* Beginning of line. */
#define ASSERT_AT_EOL 2 /* End of line. */
#define ASSERT_CHAR_CLASS 4 /* Character class in `class'. */
#define ASSERT_CHAR_CLASS_NEG 8 /* Character classes in `neg_classes'. */
#define ASSERT_AT_BOW 16 /* Beginning of word. */
#define ASSERT_AT_EOW 32 /* End of word. */
#define ASSERT_AT_WB 64 /* Word boundary. */
#define ASSERT_AT_WB_NEG 128 /* Not a word boundary. */
#define ASSERT_BACKREF 256 /* A back reference in `backref'. */
#define ASSERT_LAST 256
/* Tag directions. */
typedef enum {
TRE_TAG_MINIMIZE = 0,
TRE_TAG_MAXIMIZE = 1
} tre_tag_direction_t;
/* Instructions to compute submatch register values from tag values
after a successful match. */
struct tre_submatch_data {
/* Tag that gives the value for rm_so (submatch start offset). */
int so_tag;
/* Tag that gives the value for rm_eo (submatch end offset). */
int eo_tag;
/* List of submatches this submatch is contained in. */
int *parents;
};
typedef struct tre_submatch_data tre_submatch_data_t;
/* TNFA definition. */
typedef struct tnfa tre_tnfa_t;
struct tnfa {
tre_tnfa_transition_t *transitions;
unsigned int num_transitions;
tre_tnfa_transition_t *initial;
tre_tnfa_transition_t *final;
tre_submatch_data_t *submatch_data;
char *firstpos_chars;
int first_char;
unsigned int num_submatches;
tre_tag_direction_t *tag_directions;
int *minimal_tags;
int num_tags;
int num_minimals;
int end_tag;
int num_states;
int cflags;
int have_backrefs;
int have_approx;
};
/* from tre-mem.h: */
#define TRE_MEM_BLOCK_SIZE 1024
typedef struct tre_list {
void *data;
struct tre_list *next;
} tre_list_t;
typedef struct tre_mem_struct {
tre_list_t *blocks;
tre_list_t *current;
char *ptr;
size_t n;
int failed;
void **provided;
} *tre_mem_t;
#define tre_mem_new_impl __tre_mem_new_impl
#define tre_mem_alloc_impl __tre_mem_alloc_impl
#define tre_mem_destroy __tre_mem_destroy
hidden tre_mem_t tre_mem_new_impl(int provided, void *provided_block);
hidden void *tre_mem_alloc_impl(tre_mem_t mem, int provided, void *provided_block,
int zero, size_t size);
/* Returns a new memory allocator or NULL if out of memory. */
#define tre_mem_new() tre_mem_new_impl(0, NULL)
/* Allocates a block of `size' bytes from `mem'. Returns a pointer to the
allocated block or NULL if an underlying malloc() failed. */
#define tre_mem_alloc(mem, size) tre_mem_alloc_impl(mem, 0, NULL, 0, size)
/* Allocates a block of `size' bytes from `mem'. Returns a pointer to the
allocated block or NULL if an underlying malloc() failed. The memory
is set to zero. */
#define tre_mem_calloc(mem, size) tre_mem_alloc_impl(mem, 0, NULL, 1, size)
#ifdef TRE_USE_ALLOCA
/* alloca() versions. Like above, but memory is allocated with alloca()
instead of malloc(). */
#define tre_mem_newa() \
tre_mem_new_impl(1, alloca(sizeof(struct tre_mem_struct)))
#define tre_mem_alloca(mem, size) \
((mem)->n >= (size) \
? tre_mem_alloc_impl((mem), 1, NULL, 0, (size)) \
: tre_mem_alloc_impl((mem), 1, alloca(TRE_MEM_BLOCK_SIZE), 0, (size)))
#endif /* TRE_USE_ALLOCA */
/* Frees the memory allocator and all memory allocated with it. */
hidden void tre_mem_destroy(tre_mem_t mem);
#define xmalloc malloc
#define xcalloc calloc
#define xfree free
#define xrealloc realloc