working on it
This commit is contained in:
parent
56a6e78765
commit
35a88970c2
1094 changed files with 51093 additions and 51 deletions
150
05/musl-final/src/regex/fnmatch.c
Normal file
150
05/musl-final/src/regex/fnmatch.c
Normal file
|
@ -0,0 +1,150 @@
|
|||
#include <fnmatch.h>
|
||||
#include <wctype.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
|
||||
static int next(const char **s)
|
||||
{
|
||||
wchar_t c;
|
||||
int l = mbtowc(&c, *s, MB_LEN_MAX);
|
||||
/* hack to allow literal matches of invalid byte sequences */
|
||||
if (l < 0) return (unsigned char)*(*s)++ - 0x100;
|
||||
*s += l;
|
||||
return c;
|
||||
}
|
||||
|
||||
#define BRACKET_ERROR -0x100
|
||||
#define BRACKET_NOCHAR -0x101
|
||||
|
||||
static int bracket_next(const char **s)
|
||||
{
|
||||
int c;
|
||||
int type;
|
||||
if (**s == '[') {
|
||||
type = *(*s+1);
|
||||
if (type == '.' || type == '=') {
|
||||
*s += 2;
|
||||
c = next(s);
|
||||
if (c <= 0) return BRACKET_ERROR;
|
||||
if (**s == type && *(*s+1) == ']') {
|
||||
*s += 2;
|
||||
return c;
|
||||
}
|
||||
for (; **s && (**s != type || *(*s+1) != ']'); (*s)++);
|
||||
if (!**s) return BRACKET_ERROR;
|
||||
*s += 2;
|
||||
return BRACKET_NOCHAR;
|
||||
}
|
||||
}
|
||||
c = next(s);
|
||||
if (c <= 0) return BRACKET_ERROR;
|
||||
return c;
|
||||
}
|
||||
|
||||
#define __FNM_CONT 0x8000
|
||||
|
||||
int fnmatch(const char *p, const char *s, int flags)
|
||||
{
|
||||
int c, d, k;
|
||||
int not;
|
||||
int match;
|
||||
int first;
|
||||
int no_slash = (flags & FNM_PATHNAME) ? '/' : 0;
|
||||
int no_period = (flags & FNM_PERIOD) && !(flags & __FNM_CONT) ? '.' : 0x100;
|
||||
|
||||
flags |= __FNM_CONT;
|
||||
|
||||
while ((c = *p++)) {
|
||||
switch (c) {
|
||||
case '?':
|
||||
k = next(&s);
|
||||
if (!k || k == no_period || k == no_slash)
|
||||
return FNM_NOMATCH;
|
||||
break;
|
||||
case '\\':
|
||||
if (!(flags & FNM_NOESCAPE)) {
|
||||
c = *p++;
|
||||
goto literal;
|
||||
}
|
||||
if (*s++ != c) return FNM_NOMATCH;
|
||||
break;
|
||||
case '*':
|
||||
for (; *p == '*'; p++);
|
||||
if (*p && !*s) return FNM_NOMATCH;
|
||||
if (*s == no_period)
|
||||
return FNM_NOMATCH;
|
||||
if (!*p && (!no_slash || !strchr(s, no_slash)))
|
||||
return 0;
|
||||
for (; *s; s++)
|
||||
if (!fnmatch(p, s, flags))
|
||||
return 0;
|
||||
else if (*s == no_slash)
|
||||
break;
|
||||
return FNM_NOMATCH;
|
||||
case '[':
|
||||
not = (*p == '!' || *p == '^');
|
||||
if (not) p++;
|
||||
k = next(&s);
|
||||
if (!k || k == no_slash || k == no_period)
|
||||
return FNM_NOMATCH;
|
||||
match = 0;
|
||||
first = 1;
|
||||
for (;;) {
|
||||
if (!*p) return FNM_NOMATCH;
|
||||
if (*p == ']' && !first) break;
|
||||
first = 0;
|
||||
if (*p == '[' && *(p+1) == ':') {
|
||||
const char *z;
|
||||
p += 2;
|
||||
for (z=p; *z && (*z != ':' || *(z+1) != ']'); z++);
|
||||
if (!*z || z-p > 32) { /* FIXME: symbolic const? */
|
||||
return FNM_NOMATCH;
|
||||
} else {
|
||||
char class[z-p+1];
|
||||
memcpy(class, p, z-p);
|
||||
class[z-p] = 0;
|
||||
if (iswctype(k, wctype(class)))
|
||||
match = 1;
|
||||
}
|
||||
p = z+2;
|
||||
continue;
|
||||
}
|
||||
c = bracket_next(&p);
|
||||
if (c == BRACKET_ERROR)
|
||||
return FNM_NOMATCH;
|
||||
if (c == BRACKET_NOCHAR)
|
||||
continue;
|
||||
if (*p == '-' && *(p+1) != ']') {
|
||||
p++;
|
||||
d = bracket_next(&p);
|
||||
if (d == BRACKET_ERROR)
|
||||
return FNM_NOMATCH;
|
||||
if (d == BRACKET_NOCHAR)
|
||||
continue;
|
||||
if (k >= c && k <= d)
|
||||
match = 1;
|
||||
continue;
|
||||
}
|
||||
if (k == c) match = 1;
|
||||
}
|
||||
p++;
|
||||
if (not == match)
|
||||
return FNM_NOMATCH;
|
||||
break;
|
||||
default:
|
||||
literal:
|
||||
if (*s++ != c)
|
||||
return FNM_NOMATCH;
|
||||
if (c == no_slash && (flags & FNM_PERIOD)) {
|
||||
no_period = '.';
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
no_period = 0x100;
|
||||
}
|
||||
if (*s) return FNM_NOMATCH;
|
||||
return 0;
|
||||
}
|
238
05/musl-final/src/regex/glob.c
Normal file
238
05/musl-final/src/regex/glob.c
Normal file
|
@ -0,0 +1,238 @@
|
|||
#include <glob.h>
|
||||
#include <fnmatch.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <stddef.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include "libc.h"
|
||||
|
||||
struct match
|
||||
{
|
||||
struct match *next;
|
||||
char name[1];
|
||||
};
|
||||
|
||||
static int is_literal(const char *p, int useesc)
|
||||
{
|
||||
int bracket = 0;
|
||||
for (; *p; p++) {
|
||||
switch (*p) {
|
||||
case '\\':
|
||||
if (!useesc) break;
|
||||
case '?':
|
||||
case '*':
|
||||
return 0;
|
||||
case '[':
|
||||
bracket = 1;
|
||||
break;
|
||||
case ']':
|
||||
if (bracket) return 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int append(struct match **tail, const char *name, size_t len, int mark)
|
||||
{
|
||||
struct match *new = malloc(sizeof(struct match) + len + 1);
|
||||
if (!new) return -1;
|
||||
(*tail)->next = new;
|
||||
new->next = NULL;
|
||||
strcpy(new->name, name);
|
||||
if (mark) strcat(new->name, "/");
|
||||
*tail = new;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int match_in_dir(const char *d, const char *p, int flags, int (*errfunc)(const char *path, int err), struct match **tail)
|
||||
{
|
||||
DIR *dir;
|
||||
long long de_buf[(sizeof(struct dirent) + NAME_MAX + sizeof(long long))/sizeof(long long)];
|
||||
struct dirent *de;
|
||||
char pat[strlen(p)+1];
|
||||
char *p2;
|
||||
size_t l = strlen(d);
|
||||
int literal;
|
||||
int fnm_flags= ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0) | FNM_PERIOD;
|
||||
int error;
|
||||
|
||||
if ((p2 = strchr(p, '/'))) {
|
||||
strcpy(pat, p);
|
||||
pat[p2-p] = 0;
|
||||
for (; *p2 == '/'; p2++);
|
||||
p = pat;
|
||||
}
|
||||
literal = is_literal(p, !(flags & GLOB_NOESCAPE));
|
||||
if (*d == '/' && !*(d+1)) l = 0;
|
||||
|
||||
/* rely on opendir failing for nondirectory objects */
|
||||
dir = opendir(*d ? d : ".");
|
||||
error = errno;
|
||||
if (!dir) {
|
||||
/* this is not an error -- we let opendir call stat for us */
|
||||
if (error == ENOTDIR) return 0;
|
||||
if (error == EACCES && !*p) {
|
||||
struct stat st;
|
||||
if (!stat(d, &st) && S_ISDIR(st.st_mode)) {
|
||||
if (append(tail, d, l, l))
|
||||
return GLOB_NOSPACE;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (errfunc(d, error) || (flags & GLOB_ERR))
|
||||
return GLOB_ABORTED;
|
||||
return 0;
|
||||
}
|
||||
if (!*p) {
|
||||
error = append(tail, d, l, l) ? GLOB_NOSPACE : 0;
|
||||
closedir(dir);
|
||||
return error;
|
||||
}
|
||||
while (!(error = readdir_r(dir, (void *)de_buf, &de)) && de) {
|
||||
char namebuf[l+de->d_reclen+2], *name = namebuf;
|
||||
if (!literal && fnmatch(p, de->d_name, fnm_flags))
|
||||
continue;
|
||||
if (literal && strcmp(p, de->d_name))
|
||||
continue;
|
||||
if (p2 && de->d_type && !S_ISDIR(de->d_type<<12) && !S_ISLNK(de->d_type<<12))
|
||||
continue;
|
||||
if (*d) {
|
||||
memcpy(name, d, l);
|
||||
name[l] = '/';
|
||||
strcpy(name+l+1, de->d_name);
|
||||
} else {
|
||||
name = de->d_name;
|
||||
}
|
||||
if (p2) {
|
||||
if ((error = match_in_dir(name, p2, flags, errfunc, tail))) {
|
||||
closedir(dir);
|
||||
return error;
|
||||
}
|
||||
} else {
|
||||
int mark = 0;
|
||||
if (flags & GLOB_MARK) {
|
||||
if (de->d_type)
|
||||
mark = S_ISDIR(de->d_type<<12);
|
||||
else {
|
||||
struct stat st;
|
||||
stat(name, &st);
|
||||
mark = S_ISDIR(st.st_mode);
|
||||
}
|
||||
}
|
||||
if (append(tail, name, l+de->d_reclen+1, mark)) {
|
||||
closedir(dir);
|
||||
return GLOB_NOSPACE;
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
if (error && (errfunc(d, error) || (flags & GLOB_ERR)))
|
||||
return GLOB_ABORTED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ignore_err(const char *path, int err)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void freelist(struct match *head)
|
||||
{
|
||||
struct match *match, *next;
|
||||
for (match=head->next; match; match=next) {
|
||||
next = match->next;
|
||||
free(match);
|
||||
}
|
||||
}
|
||||
|
||||
static int sort(const void *a, const void *b)
|
||||
{
|
||||
return strcmp(*(const char **)a, *(const char **)b);
|
||||
}
|
||||
|
||||
int glob(const char *pat, int flags, int (*errfunc)(const char *path, int err), glob_t *g)
|
||||
{
|
||||
const char *p=pat, *d;
|
||||
struct match head = { .next = NULL }, *tail = &head;
|
||||
size_t cnt, i;
|
||||
size_t offs = (flags & GLOB_DOOFFS) ? g->gl_offs : 0;
|
||||
int error = 0;
|
||||
|
||||
if (*p == '/') {
|
||||
for (; *p == '/'; p++);
|
||||
d = "/";
|
||||
} else {
|
||||
d = "";
|
||||
}
|
||||
|
||||
if (!errfunc) errfunc = ignore_err;
|
||||
|
||||
if (!(flags & GLOB_APPEND)) {
|
||||
g->gl_offs = offs;
|
||||
g->gl_pathc = 0;
|
||||
g->gl_pathv = NULL;
|
||||
}
|
||||
|
||||
if (*p) error = match_in_dir(d, p, flags, errfunc, &tail);
|
||||
if (error == GLOB_NOSPACE) {
|
||||
freelist(&head);
|
||||
return error;
|
||||
}
|
||||
|
||||
for (cnt=0, tail=head.next; tail; tail=tail->next, cnt++);
|
||||
if (!cnt) {
|
||||
if (flags & GLOB_NOCHECK) {
|
||||
tail = &head;
|
||||
if (append(&tail, pat, strlen(pat), 0))
|
||||
return GLOB_NOSPACE;
|
||||
cnt++;
|
||||
} else
|
||||
return GLOB_NOMATCH;
|
||||
}
|
||||
|
||||
if (flags & GLOB_APPEND) {
|
||||
char **pathv = realloc(g->gl_pathv, (offs + g->gl_pathc + cnt + 1) * sizeof(char *));
|
||||
if (!pathv) {
|
||||
freelist(&head);
|
||||
return GLOB_NOSPACE;
|
||||
}
|
||||
g->gl_pathv = pathv;
|
||||
offs += g->gl_pathc;
|
||||
} else {
|
||||
g->gl_pathv = malloc((offs + cnt + 1) * sizeof(char *));
|
||||
if (!g->gl_pathv) {
|
||||
freelist(&head);
|
||||
return GLOB_NOSPACE;
|
||||
}
|
||||
for (i=0; i<offs; i++)
|
||||
g->gl_pathv[i] = NULL;
|
||||
}
|
||||
for (i=0, tail=head.next; i<cnt; tail=tail->next, i++)
|
||||
g->gl_pathv[offs + i] = tail->name;
|
||||
g->gl_pathv[offs + i] = NULL;
|
||||
g->gl_pathc += cnt;
|
||||
|
||||
if (!(flags & GLOB_NOSORT))
|
||||
qsort(g->gl_pathv+offs, cnt, sizeof(char *), sort);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
void globfree(glob_t *g)
|
||||
{
|
||||
size_t i;
|
||||
for (i=0; i<g->gl_pathc; i++)
|
||||
free(g->gl_pathv[g->gl_offs + i] - offsetof(struct match, name));
|
||||
free(g->gl_pathv);
|
||||
g->gl_pathc = 0;
|
||||
g->gl_pathv = NULL;
|
||||
}
|
||||
|
||||
LFS64(glob);
|
||||
LFS64(globfree);
|
3362
05/musl-final/src/regex/regcomp.c
Normal file
3362
05/musl-final/src/regex/regcomp.c
Normal file
File diff suppressed because it is too large
Load diff
75
05/musl-final/src/regex/regerror.c
Normal file
75
05/musl-final/src/regex/regerror.c
Normal file
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
regerror.c - POSIX regerror() implementation for TRE.
|
||||
|
||||
Copyright (c) 2001-2006 Ville Laurikari <vl@iki.fi>.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <regex.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 tre_error_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"
|
||||
"XXX\0"
|
||||
};
|
||||
|
||||
size_t
|
||||
regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size)
|
||||
{
|
||||
const char *err;
|
||||
size_t err_len;
|
||||
|
||||
if (errcode >= 0 && errcode <= REG_BADRPT)
|
||||
for (err=tre_error_messages; errcode; errcode--, err+=strlen(err)+1);
|
||||
else
|
||||
err = "Unknown error";
|
||||
|
||||
err_len = strlen(err) + 1;
|
||||
if (errbuf_size > 0 && errbuf != NULL)
|
||||
{
|
||||
if (err_len > errbuf_size)
|
||||
{
|
||||
memcpy(errbuf, err, errbuf_size - 1);
|
||||
errbuf[errbuf_size - 1] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(errbuf, err);
|
||||
}
|
||||
}
|
||||
return err_len;
|
||||
}
|
||||
|
||||
/* EOF */
|
1107
05/musl-final/src/regex/regexec.c
Normal file
1107
05/musl-final/src/regex/regexec.c
Normal file
File diff suppressed because it is too large
Load diff
163
05/musl-final/src/regex/tre-mem.c
Normal file
163
05/musl-final/src/regex/tre-mem.c
Normal file
|
@ -0,0 +1,163 @@
|
|||
/*
|
||||
tre-mem.c - TRE memory allocator
|
||||
|
||||
Copyright (c) 2001-2006 Ville Laurikari <vl@iki.fi>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
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"
|
||||
|
||||
|
||||
/* 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)
|
||||
{
|
||||
DPRINT(("tre_mem_alloc: oops, called after failure?!\n"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef MALLOC_DEBUGGING
|
||||
if (!provided)
|
||||
{
|
||||
ptr = xmalloc(1);
|
||||
if (ptr == NULL)
|
||||
{
|
||||
DPRINT(("tre_mem_alloc: xmalloc forced failure\n"));
|
||||
mem->failed = 1;
|
||||
return NULL;
|
||||
}
|
||||
xfree(ptr);
|
||||
}
|
||||
#endif /* MALLOC_DEBUGGING */
|
||||
|
||||
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)
|
||||
{
|
||||
DPRINT(("tre_mem_alloc: using provided block\n"));
|
||||
if (provided_block == NULL)
|
||||
{
|
||||
DPRINT(("tre_mem_alloc: provided block was NULL\n"));
|
||||
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;
|
||||
DPRINT(("tre_mem_alloc: allocating new %d byte block\n",
|
||||
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;
|
||||
}
|
||||
|
||||
/* EOF */
|
269
05/musl-final/src/regex/tre.h
Normal file
269
05/musl-final/src/regex/tre.h
Normal file
|
@ -0,0 +1,269 @@
|
|||
/*
|
||||
tre-internal.h - TRE internal definitions
|
||||
|
||||
Copyright (c) 2001-2006 Ville Laurikari <vl@iki.fi>.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
#include <regex.h>
|
||||
#include <wchar.h>
|
||||
#include <wctype.h>
|
||||
|
||||
#define TRE_MULTIBYTE 1
|
||||
#undef TRE_MBSTATE
|
||||
#define TRE_WCHAR 1
|
||||
#define TRE_USE_SYSTEM_WCTYPE 1
|
||||
#define HAVE_WCSTOMBS 1
|
||||
#define TRE_MB_CUR_MAX MB_CUR_MAX
|
||||
|
||||
#define NDEBUG
|
||||
|
||||
#define TRE_REGEX_T_FIELD __opaque
|
||||
typedef int reg_errcode_t;
|
||||
|
||||
typedef wchar_t tre_char_t;
|
||||
|
||||
|
||||
#ifdef TRE_DEBUG
|
||||
#include <stdio.h>
|
||||
#define DPRINT(msg) do {printf msg; fflush(stdout);} while(0)
|
||||
#else /* !TRE_DEBUG */
|
||||
#define DPRINT(msg) do { } while(0)
|
||||
#endif /* !TRE_DEBUG */
|
||||
|
||||
#define elementsof(x) ( sizeof(x) / sizeof(x[0]) )
|
||||
|
||||
#if 1
|
||||
int __mbtowc(wchar_t *, const char *);
|
||||
#define tre_mbrtowc(pwc, s, n, ps) (__mbtowc((pwc), (s)))
|
||||
#else
|
||||
#define tre_mbrtowc(pwc, s, n, ps) (mbtowc((pwc), (s), (n)))
|
||||
#endif
|
||||
|
||||
/* Wide characters. */
|
||||
typedef wint_t tre_cint_t;
|
||||
#define TRE_CHAR_MAX WCHAR_MAX
|
||||
|
||||
#ifdef TRE_MULTIBYTE
|
||||
#define TRE_MB_CUR_MAX MB_CUR_MAX
|
||||
#else /* !TRE_MULTIBYTE */
|
||||
#define TRE_MB_CUR_MAX 1
|
||||
#endif /* !TRE_MULTIBYTE */
|
||||
|
||||
#define tre_isalnum iswalnum
|
||||
#define tre_isalpha iswalpha
|
||||
#define tre_isblank iswblank
|
||||
#define tre_iscntrl iswcntrl
|
||||
#define tre_isdigit iswdigit
|
||||
#define tre_isgraph iswgraph
|
||||
#define tre_islower iswlower
|
||||
#define tre_isprint iswprint
|
||||
#define tre_ispunct iswpunct
|
||||
#define tre_isspace iswspace
|
||||
#define tre_isupper iswupper
|
||||
#define tre_isxdigit iswxdigit
|
||||
|
||||
#define tre_tolower towlower
|
||||
#define tre_toupper towupper
|
||||
#define tre_strlen wcslen
|
||||
|
||||
/* Use system provided iswctype() and wctype(). */
|
||||
typedef wctype_t tre_ctype_t;
|
||||
#define tre_isctype iswctype
|
||||
#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) \
|
||||
((((long)ptr) % sizeof(type)) \
|
||||
? (sizeof(type) - (((long)ptr) % sizeof(type))) \
|
||||
: 0)
|
||||
|
||||
#undef MAX
|
||||
#undef MIN
|
||||
#define MAX(a, b) (((a) >= (b)) ? (a) : (b))
|
||||
#define MIN(a, b) (((a) <= (b)) ? (a) : (b))
|
||||
|
||||
/* Define STRF to the correct printf formatter for strings. */
|
||||
#define STRF "ls"
|
||||
|
||||
/* 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;
|
||||
unsigned int num_submatches;
|
||||
tre_tag_direction_t *tag_directions;
|
||||
int num_tags;
|
||||
int end_tag;
|
||||
int num_states;
|
||||
int cflags;
|
||||
int have_backrefs;
|
||||
};
|
||||
|
||||
#if 0
|
||||
static int
|
||||
tre_compile(regex_t *preg, const tre_char_t *regex, size_t n, int cflags);
|
||||
|
||||
static void
|
||||
tre_free(regex_t *preg);
|
||||
|
||||
static void
|
||||
tre_fill_pmatch(size_t nmatch, regmatch_t pmatch[], int cflags,
|
||||
const tre_tnfa_t *tnfa, int *tags, int match_eo);
|
||||
|
||||
static reg_errcode_t
|
||||
tre_tnfa_run_parallel(const tre_tnfa_t *tnfa, const void *string, int len,
|
||||
tre_str_type_t type, int *match_tags, int eflags,
|
||||
int *match_end_ofs);
|
||||
|
||||
static reg_errcode_t
|
||||
tre_tnfa_run_parallel(const tre_tnfa_t *tnfa, const void *string, int len,
|
||||
tre_str_type_t type, int *match_tags, int eflags,
|
||||
int *match_end_ofs);
|
||||
|
||||
static reg_errcode_t
|
||||
tre_tnfa_run_backtrack(const tre_tnfa_t *tnfa, const void *string,
|
||||
int len, tre_str_type_t type, int *match_tags,
|
||||
int eflags, int *match_end_ofs);
|
||||
#endif
|
||||
|
||||
/* 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
|
||||
|
||||
tre_mem_t tre_mem_new_impl(int provided, void *provided_block);
|
||||
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. */
|
||||
void tre_mem_destroy(tre_mem_t mem);
|
||||
|
||||
#define xmalloc malloc
|
||||
#define xcalloc calloc
|
||||
#define xfree free
|
||||
#define xrealloc realloc
|
||||
|
||||
/* EOF */
|
Loading…
Add table
Add a link
Reference in a new issue