Software: Apache. PHP/5.4.45 

uname -a: Linux webm056.cluster010.gra.hosting.ovh.net 5.15.167-ovh-vps-grsec-zfs-classid #1 SMP Tue
Sep 17 08:14:20 UTC 2024 x86_64
 

uid=243112(mycochar) gid=100(users) groups=100(users)  

Safe-mode: OFF (not secure)

/home/mycochar/www/image/photo/go/src/regexp/testdata/   drwxr-xr-x
Free 0 B of 0 B (0%)
Your ip: 216.73.216.77 - Server ip: 213.186.33.19
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    

[Enumerate]    [Encoder]    [Tools]    [Proc.]    [FTP Brute]    [Sec.]    [SQL]    [PHP-Code]    [Backdoor Host]    [Back-Connection]    [milw0rm it!]    [PHP-Proxy]    [Self remove]
    


Viewing file:     testregex.c (51.34 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
#pragma prototyped noticed

/*
 * regex(3) test harness
 *
 * build:    cc -o testregex testregex.c
 * help:    testregex --man
 * note:    REG_* features are detected by #ifdef; if REG_* are enums
 *        then supply #define REG_foo REG_foo for each enum REG_foo
 *
 *    Glenn Fowler <gsf@research.att.com>
 *    AT&T Research
 *
 * PLEASE: publish your tests so everyone can benefit
 *
 * The following license covers testregex.c and all associated test data.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of THIS SOFTWARE FILE (the "Software"), to deal in the Software
 * without restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, and/or sell copies of the
 * Software, and to permit persons to whom the Software is furnished to do
 * so, subject to the following disclaimer:
 *
 * THIS SOFTWARE IS PROVIDED BY AT&T ``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 AT&T 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.
 */

static const char id[] = "\n@(#)$Id: testregex (AT&T Research) 2010-06-10 $\0\n";

#if _PACKAGE_ast
#include <ast.h>
#else
#include <sys/types.h>
#endif

#include <stdio.h>
#include <regex.h>
#include <ctype.h>
#include <setjmp.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>

#ifdef    __STDC__
#include <stdlib.h>
#include <locale.h>
#endif

#ifndef RE_DUP_MAX
#define RE_DUP_MAX    32767
#endif

#if !_PACKAGE_ast
#undef    REG_DISCIPLINE
#endif

#ifndef REG_DELIMITED
#undef    _REG_subcomp
#endif

#define TEST_ARE        0x00000001
#define TEST_BRE        0x00000002
#define TEST_ERE        0x00000004
#define TEST_KRE        0x00000008
#define TEST_LRE        0x00000010
#define TEST_SRE        0x00000020

#define TEST_EXPAND        0x00000100
#define TEST_LENIENT        0x00000200

#define TEST_QUERY        0x00000400
#define TEST_SUB        0x00000800
#define TEST_UNSPECIFIED    0x00001000
#define TEST_VERIFY        0x00002000
#define TEST_AND        0x00004000
#define TEST_OR            0x00008000

#define TEST_DELIMIT        0x00010000
#define TEST_OK            0x00020000
#define TEST_SAME        0x00040000

#define TEST_ACTUAL        0x00100000
#define TEST_BASELINE        0x00200000
#define TEST_FAIL        0x00400000
#define TEST_PASS        0x00800000
#define TEST_SUMMARY        0x01000000

#define TEST_IGNORE_ERROR    0x02000000
#define TEST_IGNORE_OVER    0x04000000
#define TEST_IGNORE_POSITION    0x08000000

#define TEST_CATCH        0x10000000
#define TEST_VERBOSE        0x20000000

#define TEST_DECOMP        0x40000000

#define TEST_GLOBAL        (TEST_ACTUAL|TEST_AND|TEST_BASELINE|TEST_CATCH|TEST_FAIL|TEST_IGNORE_ERROR|TEST_IGNORE_OVER|TEST_IGNORE_POSITION|TEST_OR|TEST_PASS|TEST_SUMMARY|TEST_VERBOSE)

#ifdef REG_DISCIPLINE


#include <stk.h>

typedef struct Disc_s
{
    regdisc_t    disc;
    int        ordinal;
    Sfio_t*        sp;
} Disc_t;

static void*
compf(const regex_t* re, const char* xstr, size_t xlen, regdisc_t* disc)
{
    Disc_t*        dp = (Disc_t*)disc;

    return (void*)((char*)0 + ++dp->ordinal);
}

static int
execf(const regex_t* re, void* data, const char* xstr, size_t xlen, const char* sstr, size_t slen, char** snxt, regdisc_t* disc)
{
    Disc_t*        dp = (Disc_t*)disc;

    sfprintf(dp->sp, "{%-.*s}(%lu:%d)", xlen, xstr, (char*)data - (char*)0, slen);
    return atoi(xstr);
}

static void*
resizef(void* handle, void* data, size_t size)
{
    if (!size)
        return 0;
    return stkalloc((Sfio_t*)handle, size);
}

#endif

#ifndef NiL
#ifdef    __STDC__
#define NiL        0
#else
#define NiL        (char*)0
#endif
#endif

#define H(x)        do{if(html)fprintf(stderr,x);}while(0)
#define T(x)        fprintf(stderr,x)

static void
help(int html)
{
H("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">\n");
H("<HTML>\n");
H("<HEAD>\n");
H("<TITLE>testregex man document</TITLE>\n");
H("</HEAD>\n");
H("<BODY bgcolor=white>\n");
H("<PRE>\n");
T("NAME\n");
T("  testregex - regex(3) test harness\n");
T("\n");
T("SYNOPSIS\n");
T("  testregex [ options ]\n");
T("\n");
T("DESCRIPTION\n");
T("  testregex reads regex(3) test specifications, one per line, from the\n");
T("  standard input and writes one output line for each failed test. A\n");
T("  summary line is written after all tests are done. Each successful\n");
T("  test is run again with REG_NOSUB. Unsupported features are noted\n");
T("  before the first test, and tests requiring these features are\n");
T("  silently ignored.\n");
T("\n");
T("OPTIONS\n");
T("  -c    catch signals and non-terminating calls\n");
T("  -e    ignore error return mismatches\n");
T("  -h    list help on standard error\n");
T("  -n    do not repeat successful tests with regnexec()\n");
T("  -o    ignore match[] overrun errors\n");
T("  -p    ignore negative position mismatches\n");
T("  -s    use stack instead of malloc\n");
T("  -x    do not repeat successful tests with REG_NOSUB\n");
T("  -v    list each test line\n");
T("  -A    list failed test lines with actual answers\n");
T("  -B    list all test lines with actual answers\n");
T("  -F    list failed test lines\n");
T("  -P    list passed test lines\n");
T("  -S    output one summary line\n");
T("\n");
T("INPUT FORMAT\n");
T("  Input lines may be blank, a comment beginning with #, or a test\n");
T("  specification. A specification is five fields separated by one\n");
T("  or more tabs. NULL denotes the empty string and NIL denotes the\n");
T("  0 pointer.\n");
T("\n");
T("  Field 1: the regex(3) flags to apply, one character per REG_feature\n");
T("  flag. The test is skipped if REG_feature is not supported by the\n");
T("  implementation. If the first character is not [BEASKLP] then the\n");
T("  specification is a global control line. One or more of [BEASKLP] may be\n");
T("  specified; the test will be repeated for each mode.\n");
T("\n");
T("    B     basic            BRE    (grep, ed, sed)\n");
T("    E     REG_EXTENDED        ERE    (egrep)\n");
T("    A    REG_AUGMENTED        ARE    (egrep with negation)\n");
T("    S    REG_SHELL        SRE    (sh glob)\n");
T("    K    REG_SHELL|REG_AUGMENTED    KRE    (ksh glob)\n");
T("    L    REG_LITERAL        LRE    (fgrep)\n");
T("\n");
T("    a    REG_LEFT|REG_RIGHT    implicit ^...$\n");
T("    b    REG_NOTBOL        lhs does not match ^\n");
T("    c    REG_COMMENT        ignore space and #...\\n\n");
T("    d    REG_SHELL_DOT        explicit leading . match\n");
T("    e    REG_NOTEOL        rhs does not match $\n");
T("    f    REG_MULTIPLE        multiple \\n separated patterns\n");
T("    g    FNM_LEADING_DIR        testfnmatch only -- match until /\n");
T("    h    REG_MULTIREF        multiple digit backref\n");
T("    i    REG_ICASE        ignore case\n");
T("    j    REG_SPAN        . matches \\n\n");
T("    k    REG_ESCAPE        \\ to ecape [...] delimiter\n");
T("    l    REG_LEFT        implicit ^...\n");
T("    m    REG_MINIMAL        minimal match\n");
T("    n    REG_NEWLINE        explicit \\n match\n");
T("    o    REG_ENCLOSED        (|&) magic inside [@|&](...)\n");
T("    p    REG_SHELL_PATH        explicit / match\n");
T("    q    REG_DELIMITED        delimited pattern\n");
T("    r    REG_RIGHT        implicit ...$\n");
T("    s    REG_SHELL_ESCAPED    \\ not special\n");
T("    t    REG_MUSTDELIM        all delimiters must be specified\n");
T("    u    standard unspecified behavior -- errors not counted\n");
T("    v    REG_CLASS_ESCAPE    \\ special inside [...]\n");
T("    w    REG_NOSUB        no subexpression match array\n");
T("    x    REG_LENIENT        let some errors slide\n");
T("    y    REG_LEFT        regexec() implicit ^...\n");
T("    z    REG_NULL        NULL subexpressions ok\n");
T("    $                            expand C \\c escapes in fields 2 and 3\n");
T("    /                            field 2 is a regsubcomp() expression\n");
T("    =                            field 3 is a regdecomp() expression\n");
T("\n");
T("  Field 1 control lines:\n");
T("\n");
T("    C        set LC_COLLATE and LC_CTYPE to locale in field 2\n");
T("\n");
T("    ?test ...    output field 5 if passed and != EXPECTED, silent otherwise\n");
T("    &test ...    output field 5 if current and previous passed\n");
T("    |test ...    output field 5 if current passed and previous failed\n");
T("    ; ...    output field 2 if previous failed\n");
T("    {test ...    skip if failed until }\n");
T("    }        end of skip\n");
T("\n");
T("    : comment        comment copied as output NOTE\n");
T("    :comment:test    :comment: ignored\n");
T("    N[OTE] comment    comment copied as output NOTE\n");
T("    T[EST] comment    comment\n");
T("\n");
T("    number        use number for nmatch (20 by default)\n");
T("\n");
T("  Field 2: the regular expression pattern; SAME uses the pattern from\n");
T("    the previous specification. RE_DUP_MAX inside {...} expands to the\n");
T("    value from <limits.h>.\n");
T("\n");
T("  Field 3: the string to match. X...{RE_DUP_MAX} expands to RE_DUP_MAX\n");
T("    copies of X.\n");
T("\n");
T("  Field 4: the test outcome. This is either one of the posix error\n");
T("    codes (with REG_ omitted) or the match array, a list of (m,n)\n");
T("    entries with m and n being first and last+1 positions in the\n");
T("    field 3 string, or NULL if REG_NOSUB is in effect and success\n");
T("    is expected. BADPAT is acceptable in place of any regcomp(3)\n");
T("    error code. The match[] array is initialized to (-2,-2) before\n");
T("    each test. All array elements from 0 to nmatch-1 must be specified\n");
T("    in the outcome. Unspecified endpoints (offset -1) are denoted by ?.\n");
T("    Unset endpoints (offset -2) are denoted by X. {x}(o:n) denotes a\n");
T("    matched (?{...}) expression, where x is the text enclosed by {...},\n");
T("    o is the expression ordinal counting from 1, and n is the length of\n");
T("    the unmatched portion of the subject string. If x starts with a\n");
T("    number then that is the return value of re_execf(), otherwise 0 is\n");
T("    returned. RE_DUP_MAX[-+]N expands to the <limits.h> value -+N.\n");
T("\n");
T("  Field 5: optional comment appended to the report.\n");
T("\n");
T("CAVEAT\n");
T("    If a regex implementation misbehaves with memory then all bets are off.\n");
T("\n");
T("CONTRIBUTORS\n");
T("  Glenn Fowler    gsf@research.att.com        (ksh strmatch, regex extensions)\n");
T("  David Korn      dgk@research.att.com        (ksh glob matcher)\n");
T("  Doug McIlroy    mcilroy@dartmouth.edu       (ast regex/testre in C++)\n");
T("  Tom Lord        lord@regexps.com            (rx tests)\n");
T("  Henry Spencer   henry@zoo.toronto.edu       (original public regex)\n");
T("  Andrew Hume     andrew@research.att.com     (gre tests)\n");
T("  John Maddock    John_Maddock@compuserve.com (regex++ tests)\n");
T("  Philip Hazel    ph10@cam.ac.uk              (pcre tests)\n");
T("  Ville Laurikari vl@iki.fi                   (libtre tests)\n");
H("</PRE>\n");
H("</BODY>\n");
H("</HTML>\n");
}

#ifndef elementsof
#define elementsof(x)    (sizeof(x)/sizeof(x[0]))
#endif

#ifndef streq
#define streq(a,b)    (*(a)==*(b)&&!strcmp(a,b))
#endif

#define HUNG        2
#define NOTEST        (~0)

#ifndef REG_TEST_DEFAULT
#define REG_TEST_DEFAULT    0
#endif

#ifndef REG_EXEC_DEFAULT
#define REG_EXEC_DEFAULT    0
#endif

static const char* unsupported[] =
{
    "BASIC",
#ifndef REG_EXTENDED
    "EXTENDED",
#endif
#ifndef REG_AUGMENTED
    "AUGMENTED",
#endif
#ifndef REG_SHELL
    "SHELL",
#endif

#ifndef REG_CLASS_ESCAPE
    "CLASS_ESCAPE",
#endif
#ifndef REG_COMMENT
    "COMMENT",
#endif
#ifndef REG_DELIMITED
    "DELIMITED",
#endif
#ifndef REG_DISCIPLINE
    "DISCIPLINE",
#endif
#ifndef REG_ESCAPE
    "ESCAPE",
#endif
#ifndef REG_ICASE
    "ICASE",
#endif
#ifndef REG_LEFT
    "LEFT",
#endif
#ifndef REG_LENIENT
    "LENIENT",
#endif
#ifndef REG_LITERAL
    "LITERAL",
#endif
#ifndef REG_MINIMAL
    "MINIMAL",
#endif
#ifndef REG_MULTIPLE
    "MULTIPLE",
#endif
#ifndef REG_MULTIREF
    "MULTIREF",
#endif
#ifndef REG_MUSTDELIM
    "MUSTDELIM",
#endif
#ifndef REG_NEWLINE
    "NEWLINE",
#endif
#ifndef REG_NOTBOL
    "NOTBOL",
#endif
#ifndef REG_NOTEOL
    "NOTEOL",
#endif
#ifndef REG_NULL
    "NULL",
#endif
#ifndef REG_RIGHT
    "RIGHT",
#endif
#ifndef REG_SHELL_DOT
    "SHELL_DOT",
#endif
#ifndef REG_SHELL_ESCAPED
    "SHELL_ESCAPED",
#endif
#ifndef REG_SHELL_GROUP
    "SHELL_GROUP",
#endif
#ifndef REG_SHELL_PATH
    "SHELL_PATH",
#endif
#ifndef REG_SPAN
    "SPAN",
#endif
#if REG_NOSUB & REG_TEST_DEFAULT
    "SUBMATCH",
#endif
#if !_REG_nexec
    "regnexec",
#endif
#if !_REG_subcomp
    "regsubcomp",
#endif
#if !_REG_decomp
    "redecomp",
#endif
    0
};

#ifndef REG_CLASS_ESCAPE
#define REG_CLASS_ESCAPE    NOTEST
#endif
#ifndef REG_COMMENT
#define REG_COMMENT    NOTEST
#endif
#ifndef REG_DELIMITED
#define REG_DELIMITED    NOTEST
#endif
#ifndef REG_ESCAPE
#define REG_ESCAPE    NOTEST
#endif
#ifndef REG_ICASE
#define REG_ICASE    NOTEST
#endif
#ifndef REG_LEFT
#define REG_LEFT    NOTEST
#endif
#ifndef REG_LENIENT
#define REG_LENIENT    0
#endif
#ifndef REG_MINIMAL
#define REG_MINIMAL    NOTEST
#endif
#ifndef REG_MULTIPLE
#define REG_MULTIPLE    NOTEST
#endif
#ifndef REG_MULTIREF
#define REG_MULTIREF    NOTEST
#endif
#ifndef REG_MUSTDELIM
#define REG_MUSTDELIM    NOTEST
#endif
#ifndef REG_NEWLINE
#define REG_NEWLINE    NOTEST
#endif
#ifndef REG_NOTBOL
#define REG_NOTBOL    NOTEST
#endif
#ifndef REG_NOTEOL
#define REG_NOTEOL    NOTEST
#endif
#ifndef REG_NULL
#define REG_NULL    NOTEST
#endif
#ifndef REG_RIGHT
#define REG_RIGHT    NOTEST
#endif
#ifndef REG_SHELL_DOT
#define REG_SHELL_DOT    NOTEST
#endif
#ifndef REG_SHELL_ESCAPED
#define REG_SHELL_ESCAPED    NOTEST
#endif
#ifndef REG_SHELL_GROUP
#define REG_SHELL_GROUP    NOTEST
#endif
#ifndef REG_SHELL_PATH
#define REG_SHELL_PATH    NOTEST
#endif
#ifndef REG_SPAN
#define REG_SPAN    NOTEST
#endif

#define REG_UNKNOWN    (-1)

#ifndef REG_ENEWLINE
#define REG_ENEWLINE    (REG_UNKNOWN-1)
#endif
#ifndef REG_ENULL
#ifndef REG_EMPTY
#define REG_ENULL    (REG_UNKNOWN-2)
#else
#define REG_ENULL    REG_EMPTY
#endif
#endif
#ifndef REG_ECOUNT
#define REG_ECOUNT    (REG_UNKNOWN-3)
#endif
#ifndef REG_BADESC
#define REG_BADESC    (REG_UNKNOWN-4)
#endif
#ifndef REG_EMEM
#define REG_EMEM    (REG_UNKNOWN-5)
#endif
#ifndef REG_EHUNG
#define REG_EHUNG    (REG_UNKNOWN-6)
#endif
#ifndef REG_EBUS
#define REG_EBUS    (REG_UNKNOWN-7)
#endif
#ifndef REG_EFAULT
#define REG_EFAULT    (REG_UNKNOWN-8)
#endif
#ifndef REG_EFLAGS
#define REG_EFLAGS    (REG_UNKNOWN-9)
#endif
#ifndef REG_EDELIM
#define REG_EDELIM    (REG_UNKNOWN-9)
#endif

static const struct { int code; char* name; } codes[] =
{
    REG_UNKNOWN,    "UNKNOWN",
    REG_NOMATCH,    "NOMATCH",
    REG_BADPAT,    "BADPAT",
    REG_ECOLLATE,    "ECOLLATE",
    REG_ECTYPE,    "ECTYPE",
    REG_EESCAPE,    "EESCAPE",
    REG_ESUBREG,    "ESUBREG",
    REG_EBRACK,    "EBRACK",
    REG_EPAREN,    "EPAREN",
    REG_EBRACE,    "EBRACE",
    REG_BADBR,    "BADBR",
    REG_ERANGE,    "ERANGE",
    REG_ESPACE,    "ESPACE",
    REG_BADRPT,    "BADRPT",
    REG_ENEWLINE,    "ENEWLINE",
    REG_ENULL,    "ENULL",
    REG_ECOUNT,    "ECOUNT",
    REG_BADESC,    "BADESC",
    REG_EMEM,    "EMEM",
    REG_EHUNG,    "EHUNG",
    REG_EBUS,    "EBUS",
    REG_EFAULT,    "EFAULT",
    REG_EFLAGS,    "EFLAGS",
    REG_EDELIM,    "EDELIM",
};

static struct
{
    regmatch_t    NOMATCH;
    int        errors;
    int        extracted;
    int        ignored;
    int        lineno;
    int        passed;
    int        signals;
    int        unspecified;
    int        verify;
    int        warnings;
    char*        file;
    char*        stack;
    char*        which;
    jmp_buf        gotcha;
#ifdef REG_DISCIPLINE
    Disc_t        disc;
#endif
} state;

static void
quote(char* s, int len, unsigned long test)
{
    unsigned char*    u = (unsigned char*)s;
    unsigned char*    e;
    int        c;
#ifdef MB_CUR_MAX
    int        w;
#endif

    if (!u)
        printf("NIL");
    else if (!*u && len <= 1)
        printf("NULL");
    else if (test & TEST_EXPAND)
    {
        if (len < 0)
            len = strlen((char*)u);
        e = u + len;
        if (test & TEST_DELIMIT)
            printf("\"");
        while (u < e)
            switch (c = *u++)
            {
            case '\\':
                printf("\\\\");
                break;
            case '"':
                if (test & TEST_DELIMIT)
                    printf("\\\"");
                else
                    printf("\"");
                break;
            case '\a':
                printf("\\a");
                break;
            case '\b':
                printf("\\b");
                break;
            case 033:
                printf("\\e");
                break;
            case '\f':
                printf("\\f");
                break;
            case '\n':
                printf("\\n");
                break;
            case '\r':
                printf("\\r");
                break;
            case '\t':
                printf("\\t");
                break;
            case '\v':
                printf("\\v");
                break;
            default:
#ifdef MB_CUR_MAX
                s = (char*)u - 1;
                if ((w = mblen(s, (char*)e - s)) > 1)
                {
                    u += w - 1;
                    fwrite(s, 1, w, stdout);
                }
                else
#endif
                if (!iscntrl(c) && isprint(c))
                    putchar(c);
                else
                    printf("\\x%02x", c);
                break;
            }
        if (test & TEST_DELIMIT)
            printf("\"");
    }
    else
        printf("%s", s);
}

static void
report(char* comment, char* fun, char* re, char* s, int len, char* msg, int flags, unsigned long test)
{
    if (state.file)
        printf("%s:", state.file);
    printf("%d:", state.lineno);
    if (re)
    {
        printf(" ");
        quote(re, -1, test|TEST_DELIMIT);
        if (s)
        {
            printf(" versus ");
            quote(s, len, test|TEST_DELIMIT);
        }
    }
    if (test & TEST_UNSPECIFIED)
    {
        state.unspecified++;
        printf(" unspecified behavior");
    }
    else
        state.errors++;
    if (state.which)
        printf(" %s", state.which);
    if (flags & REG_NOSUB)
        printf(" NOSUB");
    if (fun)
        printf(" %s", fun);
    if (comment[strlen(comment)-1] == '\n')
        printf(" %s", comment);
    else
    {
        printf(" %s: ", comment);
        if (msg)
            printf("%s: ", msg);
    }
}

static void
error(regex_t* preg, int code)
{
    char*    msg;
    char    buf[256];

    switch (code)
    {
    case REG_EBUS:
        msg = "bus error";
        break;
    case REG_EFAULT:
        msg = "memory fault";
        break;
    case REG_EHUNG:
        msg = "did not terminate";
        break;
    default:
        regerror(code, preg, msg = buf, sizeof buf);
        break;
    }
    printf("%s\n", msg);
}

static void
bad(char* comment, char* re, char* s, int len, unsigned long test)
{
    printf("bad test case ");
    report(comment, NiL, re, s, len, NiL, 0, test);
    exit(1);
}

static int
escape(char* s)
{
    char*    b;
    char*    t;
    char*    q;
    char*    e;
    int    c;

    for (b = t = s; *t = *s; s++, t++)
        if (*s == '\\')
            switch (*++s)
            {
            case '\\':
                break;
            case 'a':
                *t = '\a';
                break;
            case 'b':
                *t = '\b';
                break;
            case 'c':
                if (*t = *++s)
                    *t &= 037;
                else
                    s--;
                break;
            case 'e':
            case 'E':
                *t = 033;
                break;
            case 'f':
                *t = '\f';
                break;
            case 'n':
                *t = '\n';
                break;
            case 'r':
                *t = '\r';
                break;
            case 's':
                *t = ' ';
                break;
            case 't':
                *t = '\t';
                break;
            case 'v':
                *t = '\v';
                break;
            case 'u':
            case 'x':
                c = 0;
                q = c == 'u' ? (s + 5) : (char*)0;
                e = s + 1;
                while (!e || !q || s < q)
                {
                    switch (*++s)
                    {
                    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
                        c = (c << 4) + *s - 'a' + 10;
                        continue;
                    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
                        c = (c << 4) + *s - 'A' + 10;
                        continue;
                    case '0': case '1': case '2': case '3': case '4':
                    case '5': case '6': case '7': case '8': case '9':
                        c = (c << 4) + *s - '0';
                        continue;
                    case '{':
                    case '[':
                        if (s != e)
                        {
                            s--;
                            break;
                        }
                        e = 0;
                        continue;
                    case '}':
                    case ']':
                        if (e)
                            s--;
                        break;
                    default:
                        s--;
                        break;
                    }
                    break;
                }
                *t = c;
                break;
            case '0': case '1': case '2': case '3':
            case '4': case '5': case '6': case '7':
                c = *s - '0';
                q = s + 2;
                while (s < q)
                {
                    switch (*++s)
                    {
                    case '0': case '1': case '2': case '3':
                    case '4': case '5': case '6': case '7':
                        c = (c << 3) + *s - '0';
                        break;
                    default:
                        q = --s;
                        break;
                    }
                }
                *t = c;
                break;
            default:
                *(s + 1) = 0;
                bad("invalid C \\ escape\n", s - 1, NiL, 0, 0);
            }
    return t - b;
}

static void
matchoffprint(int off)
{
    switch (off)
    {
    case -2:
        printf("X");
        break;
    case -1:
        printf("?");
        break;
    default:
        printf("%d", off);
        break;
    }
}

static void
matchprint(regmatch_t* match, int nmatch, int nsub, char* ans, unsigned long test)
{
    int    i;

    for (; nmatch > nsub + 1; nmatch--)
        if ((match[nmatch-1].rm_so != -1 || match[nmatch-1].rm_eo != -1) && (!(test & TEST_IGNORE_POSITION) || match[nmatch-1].rm_so >= 0 && match[nmatch-1].rm_eo >= 0))
            break;
    for (i = 0; i < nmatch; i++)
    {
        printf("(");
        matchoffprint(match[i].rm_so);
        printf(",");
        matchoffprint(match[i].rm_eo);
        printf(")");
    }
    if (!(test & (TEST_ACTUAL|TEST_BASELINE)))
    {
        if (ans)
            printf(" expected: %s", ans);
        printf("\n");
    }
}

static int
matchcheck(regmatch_t* match, int nmatch, int nsub, char* ans, char* re, char* s, int len, int flags, unsigned long test)
{
    char*    p;
    int    i;
    int    m;
    int    n;

    if (streq(ans, "OK"))
        return test & (TEST_BASELINE|TEST_PASS|TEST_VERIFY);
    for (i = 0, p = ans; i < nmatch && *p; i++)
    {
        if (*p == '{')
        {
#ifdef REG_DISCIPLINE
            char*    x;

            if (!(x = sfstruse(state.disc.sp)))
                bad("out of space [discipline string]\n", NiL, NiL, 0, 0);
            if (strcmp(p, x))
            {
                if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY))
                    return 0;
                report("callout failed", NiL, re, s, len, NiL, flags, test);
                quote(p, -1, test);
                printf(" expected, ");
                quote(x, -1, test);
                printf(" returned\n");
            }
#endif
            break;
        }
        if (*p++ != '(')
            bad("improper answer\n", re, s, -1, test);
        if (*p == '?')
        {
            m = -1;
            p++;
        }
        else if (*p == 'R' && !memcmp(p, "RE_DUP_MAX", 10))
        {
            m = RE_DUP_MAX;
            p += 10;
            if (*p == '+' || *p == '-')
                m += strtol(p, &p, 10);
        }
        else
            m = strtol(p, &p, 10);
        if (*p++ != ',')
            bad("improper answer\n", re, s, -1, test);
        if (*p == '?')
        {
            n = -1;
            p++;
        }
        else if (*p == 'R' && !memcmp(p, "RE_DUP_MAX", 10))
        {
            n = RE_DUP_MAX;
            p += 10;
            if (*p == '+' || *p == '-')
                n += strtol(p, &p, 10);
        }
        else
            n = strtol(p, &p, 10);
        if (*p++ != ')')
            bad("improper answer\n", re, s, -1, test);
        if (m!=match[i].rm_so || n!=match[i].rm_eo)
        {
            if (!(test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY)))
            {
                report("failed: match was", NiL, re, s, len, NiL, flags, test);
                matchprint(match, nmatch, nsub, ans, test);
            }
            return 0;
        }
    }
    for (; i < nmatch; i++)
    {
        if (match[i].rm_so!=-1 || match[i].rm_eo!=-1)
        {
            if (!(test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_VERIFY)))
            {
                if ((test & TEST_IGNORE_POSITION) && (match[i].rm_so<0 || match[i].rm_eo<0))
                {
                    state.ignored++;
                    return 0;
                }
                if (!(test & TEST_SUMMARY))
                {
                    report("failed: match was", NiL, re, s, len, NiL, flags, test);
                    matchprint(match, nmatch, nsub, ans, test);
                }
            }
            return 0;
        }
    }
    if (!(test & TEST_IGNORE_OVER) && match[nmatch].rm_so != state.NOMATCH.rm_so)
    {
        if (!(test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY)))
        {
            report("failed: overran match array", NiL, re, s, len, NiL, flags, test);
            matchprint(match, nmatch + 1, nsub, NiL, test);
        }
        return 0;
    }
    return 1;
}

static void
sigunblock(int s)
{
#ifdef SIG_SETMASK
    int        op;
    sigset_t    mask;

    sigemptyset(&mask);
    if (s)
    {
        sigaddset(&mask, s);
        op = SIG_UNBLOCK;
    }
    else op = SIG_SETMASK;
    sigprocmask(op, &mask, NiL);
#else
#ifdef sigmask
    sigsetmask(s ? (sigsetmask(0L) & ~sigmask(s)) : 0L);
#endif
#endif
}

static void
gotcha(int sig)
{
    int    ret;

    signal(sig, gotcha);
    alarm(0);
    state.signals++;
    switch (sig)
    {
    case SIGALRM:
        ret = REG_EHUNG;
        break;
    case SIGBUS:
        ret = REG_EBUS;
        break;
    default:
        ret = REG_EFAULT;
        break;
    }
    sigunblock(sig);
    longjmp(state.gotcha, ret);
}

static char*
getline(FILE* fp)
{
    static char    buf[32 * 1024];

    register char*    s = buf;
    register char*    e = &buf[sizeof(buf)];
    register char*    b;

    for (;;)
    {
        if (!(b = fgets(s, e - s, fp)))
            return 0;
        state.lineno++;
        s += strlen(s);
        if (s == b || *--s != '\n' || s == b || *(s - 1) != '\\')
        {
            *s = 0;
            break;
        }
        s--;
    }
    return buf;
}

static unsigned long
note(unsigned long level, char* msg, unsigned long skip, unsigned long test)
{
    if (!(test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_SUMMARY)) && !skip)
    {
        printf("NOTE\t");
        if (msg)
            printf("%s: ", msg);
        printf("skipping lines %d", state.lineno);
    }
    return skip | level;
}

#define TABS(n)        &ts[7-((n)&7)]

static char        ts[] = "\t\t\t\t\t\t\t";

static unsigned long
extract(int* tabs, char* spec, char* re, char* s, char* ans, char* msg, char* accept, regmatch_t* match, int nmatch, int nsub, unsigned long skip, unsigned long level, unsigned long test)
{
    if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_OK|TEST_PASS|TEST_SUMMARY))
    {
        state.extracted = 1;
        if (test & TEST_OK)
        {
            state.passed++;
            if ((test & TEST_VERIFY) && !(test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_SUMMARY)))
            {
                if (msg && strcmp(msg, "EXPECTED"))
                    printf("NOTE\t%s\n", msg);
                return skip;
            }
            test &= ~(TEST_PASS|TEST_QUERY);
        }
        if (test & (TEST_QUERY|TEST_VERIFY))
        {
            if (test & TEST_BASELINE)
                test &= ~(TEST_BASELINE|TEST_PASS);
            else
                test |= TEST_PASS;
            skip |= level;
        }
        if (!(test & TEST_OK))
        {
            if (test & TEST_UNSPECIFIED)
                state.unspecified++;
            else
                state.errors++;
        }
        if (test & (TEST_PASS|TEST_SUMMARY))
            return skip;
        test &= ~TEST_DELIMIT;
        printf("%s%s", spec, TABS(*tabs++));
        if ((test & (TEST_BASELINE|TEST_SAME)) == (TEST_BASELINE|TEST_SAME))
            printf("SAME");
        else
            quote(re, -1, test);
        printf("%s", TABS(*tabs++));
        quote(s, -1, test);
        printf("%s", TABS(*tabs++));
        if (!(test & (TEST_ACTUAL|TEST_BASELINE)) || !accept && !match)
            printf("%s", ans);
        else if (accept)
            printf("%s", accept);
        else
            matchprint(match, nmatch, nsub, NiL, test);
        if (msg)
            printf("%s%s", TABS(*tabs++), msg);
        putchar('\n');
    }
    else if (test & TEST_QUERY)
        skip = note(level, msg, skip, test);
    else if (test & TEST_VERIFY)
        state.extracted = 1;
    return skip;
}

static int
catchfree(regex_t* preg, int flags, int* tabs, char* spec, char* re, char* s, char* ans, char* msg, char* accept, regmatch_t* match, int nmatch, int nsub, unsigned long skip, unsigned long level, unsigned long test)
{
    int    eret;

    if (!(test & TEST_CATCH))
    {
        regfree(preg);
        eret = 0;
    }
    else if (!(eret = setjmp(state.gotcha)))
    {
        alarm(HUNG);
        regfree(preg);
        alarm(0);
    }
    else if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY))
        extract(tabs, spec, re, s, ans, msg, NiL, NiL, 0, 0, skip, level, test);
    else
    {
        report("failed", "regfree", re, NiL, -1, msg, flags, test);
        error(preg, eret);
    }
    return eret;
}

static char*
expand(char* os, char* ot)
{
    char*    s = os;
    char*    t;
    int    n = 0;
    int    r;
    long    m;

    for (;;)
    {
        switch (*s++)
        {
        case 0:
            break;
        case '{':
            n++;
            continue;
        case '}':
            n--;
            continue;
        case 'R':
            if (n == 1 && !memcmp(s, "E_DUP_MAX", 9))
            {
                s--;
                for (t = ot; os < s; *t++ = *os++);
                r = ((t - ot) >= 5 && t[-1] == '{' && t[-2] == '.' && t[-3] == '.' && t[-4] == '.') ? t[-5] : 0;
                os = ot;
                m = RE_DUP_MAX;
                if (*(s += 10) == '+' || *s == '-')
                    m += strtol(s, &s, 10);
                if (r)
                {
                    t -= 5;
                    while (m-- > 0)
                        *t++ = r;
                    while (*s && *s++ != '}');
                }
                else
                    t += snprintf(t, 32, "%ld", m);
                while (*t = *s++)
                    t++;
                break;
            }
            continue;
        default:
            continue;
        }
        break;
    }
    return os;
}

int
main(int argc, char** argv)
{
    int        flags;
    int        cflags;
    int        eflags;
    int        nmatch;
    int        nexec;
    int        nstr;
    int        cret;
    int        eret;
    int        nsub;
    int        i;
    int        j;
    int        expected;
    int        got;
    int        locale;
    int        subunitlen;
    int        testno;
    unsigned long    level;
    unsigned long    skip;
    char*        p;
    char*        line;
    char*        spec;
    char*        re;
    char*        s;
    char*        ans;
    char*        msg;
    char*        fun;
    char*        ppat;
    char*        subunit;
    char*        version;
    char*        field[6];
    char*        delim[6];
    FILE*        fp;
    int        tabs[6];
    char        unit[64];
    regmatch_t    match[100];
    regex_t        preg;

    static char    pat[32 * 1024];
    static char    patbuf[32 * 1024];
    static char    strbuf[32 * 1024];

    int        nonosub = REG_NOSUB == 0;
    int        nonexec = 0;

    unsigned long    test = 0;

    static char*    filter[] = { "-", 0 };

    state.NOMATCH.rm_so = state.NOMATCH.rm_eo = -2;
    p = unit;
    version = (char*)id + 10;
    while (p < &unit[sizeof(unit)-1] && (*p = *version++) && !isspace(*p))
        p++;
    *p = 0;
    while ((p = *++argv) && *p == '-')
        for (;;)
        {
            switch (*++p)
            {
            case 0:
                break;
            case 'c':
                test |= TEST_CATCH;
                continue;
            case 'e':
                test |= TEST_IGNORE_ERROR;
                continue;
            case 'h':
            case '?':
                help(0);
                return 2;
            case '-':
                help(p[1] == 'h');
                return 2;
            case 'n':
                nonexec = 1;
                continue;
            case 'o':
                test |= TEST_IGNORE_OVER;
                continue;
            case 'p':
                test |= TEST_IGNORE_POSITION;
                continue;
            case 's':
#ifdef REG_DISCIPLINE
                if (!(state.stack = stkalloc(stkstd, 0)))
                    fprintf(stderr, "%s: out of space [stack]", unit);
                state.disc.disc.re_resizef = resizef;
                state.disc.disc.re_resizehandle = (void*)stkstd;
#endif
                continue;
            case 'x':
                nonosub = 1;
                continue;
            case 'v':
                test |= TEST_VERBOSE;
                continue;
            case 'A':
                test |= TEST_ACTUAL;
                continue;
            case 'B':
                test |= TEST_BASELINE;
                continue;
            case 'F':
                test |= TEST_FAIL;
                continue;
            case 'P':
                test |= TEST_PASS;
                continue;
            case 'S':
                test |= TEST_SUMMARY;
                continue;
            default:
                fprintf(stderr, "%s: %c: invalid option\n", unit, *p);
                return 2;
            }
            break;
        }
    if (!*argv)
        argv = filter;
    locale = 0;
    while (state.file = *argv++)
    {
        if (streq(state.file, "-") || streq(state.file, "/dev/stdin") || streq(state.file, "/dev/fd/0"))
        {
            state.file = 0;
            fp = stdin;
        }
        else if (!(fp = fopen(state.file, "r")))
        {
            fprintf(stderr, "%s: %s: cannot read\n", unit, state.file);
            return 2;
        }
        testno = state.errors = state.ignored = state.lineno = state.passed =
        state.signals = state.unspecified = state.warnings = 0;
        skip = 0;
        level = 1;
        if (!(test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_SUMMARY)))
        {
            printf("TEST\t%s ", unit);
            if (s = state.file)
            {
                subunit = p = 0;
                for (;;)
                {
                    switch (*s++)
                    {
                    case 0:
                        break;
                    case '/':
                        subunit = s;
                        continue;
                    case '.':
                        p = s - 1;
                        continue;
                    default:
                        continue;
                    }
                    break;
                }
                if (!subunit)
                    subunit = state.file;
                if (p < subunit)
                    p = s - 1;
                subunitlen = p - subunit;
                printf("%-.*s ", subunitlen, subunit);
            }
            else
                subunit = 0;
            for (s = version; *s && (*s != ' ' || *(s + 1) != '$'); s++)
                putchar(*s);
            if (test & TEST_CATCH)
                printf(", catch");
            if (test & TEST_IGNORE_ERROR)
                printf(", ignore error code mismatches");
            if (test & TEST_IGNORE_POSITION)
                printf(", ignore negative position mismatches");
#ifdef REG_DISCIPLINE
            if (state.stack)
                printf(", stack");
#endif
            if (test & TEST_VERBOSE)
                printf(", verbose");
            printf("\n");
#ifdef REG_VERSIONID
            if (regerror(REG_VERSIONID, NiL, pat, sizeof(pat)) > 0)
                s = pat;
            else
#endif
#ifdef REG_TEST_VERSION
            s = REG_TEST_VERSION;
#else
            s = "regex";
#endif
            printf("NOTE\t%s\n", s);
            if (elementsof(unsupported) > 1)
            {
#if (REG_TEST_DEFAULT & (REG_AUGMENTED|REG_EXTENDED|REG_SHELL)) || !defined(REG_EXTENDED)
                i = 0;
#else
                i = REG_EXTENDED != 0;
#endif
                for (got = 0; i < elementsof(unsupported) - 1; i++)
                {
                    if (!got)
                    {
                        got = 1;
                        printf("NOTE\tunsupported: %s", unsupported[i]);
                    }
                    else
                        printf(",%s", unsupported[i]);
                }
                if (got)
                    printf("\n");
            }
        }
#ifdef REG_DISCIPLINE
        state.disc.disc.re_version = REG_VERSION;
        state.disc.disc.re_compf = compf;
        state.disc.disc.re_execf = execf;
        if (!(state.disc.sp = sfstropen()))
            bad("out of space [discipline string stream]\n", NiL, NiL, 0, 0);
        preg.re_disc = &state.disc.disc;
#endif
        if (test & TEST_CATCH)
        {
            signal(SIGALRM, gotcha);
            signal(SIGBUS, gotcha);
            signal(SIGSEGV, gotcha);
        }
        while (p = getline(fp))
        {

        /* parse: */

            line = p;
            if (*p == ':' && !isspace(*(p + 1)))
            {
                while (*++p && *p != ':');
                if (!*p++)
                {
                    if (test & TEST_BASELINE)
                        printf("%s\n", line);
                    continue;
                }
            }
            while (isspace(*p))
                p++;
            if (*p == 0 || *p == '#' || *p == 'T')
            {
                if (test & TEST_BASELINE)
                    printf("%s\n", line);
                continue;
            }
            if (*p == ':' || *p == 'N')
            {
                if (test & TEST_BASELINE)
                    printf("%s\n", line);
                else if (!(test & (TEST_ACTUAL|TEST_FAIL|TEST_PASS|TEST_SUMMARY)))
                {
                    while (*++p && !isspace(*p));
                    while (isspace(*p))
                        p++;
                    printf("NOTE    %s\n", p);
                }
                continue;
            }
            j = 0;
            i = 0;
            field[i++] = p;
            for (;;)
            {
                switch (*p++)
                {
                case 0:
                    p--;
                    j = 0;
                    goto checkfield;
                case '\t':
                    *(delim[i] = p - 1) = 0;
                    j = 1;
                checkfield:
                    s = field[i - 1];
                    if (streq(s, "NIL"))
                        field[i - 1] = 0;
                    else if (streq(s, "NULL"))
                        *s = 0;
                    while (*p == '\t')
                    {
                        p++;
                        j++;
                    }
                    tabs[i - 1] = j;
                    if (!*p)
                        break;
                    if (i >= elementsof(field))
                        bad("too many fields\n", NiL, NiL, 0, 0);
                    field[i++] = p;
                    /*FALLTHROUGH*/
                default:
                    continue;
                }
                break;
            }
            if (!(spec = field[0]))
                bad("NIL spec\n", NiL, NiL, 0, 0);

        /* interpret: */

            cflags = REG_TEST_DEFAULT;
            eflags = REG_EXEC_DEFAULT;
            test &= TEST_GLOBAL;
            state.extracted = 0;
            nmatch = 20;
            nsub = -1;
            for (p = spec; *p; p++)
            {
                if (isdigit(*p))
                {
                    nmatch = strtol(p, &p, 10);
                    if (nmatch >= elementsof(match))
                        bad("nmatch must be < 100\n", NiL, NiL, 0, 0);
                    p--;
                    continue;
                }
                switch (*p)
                {
                case 'A':
                    test |= TEST_ARE;
                    continue;
                case 'B':
                    test |= TEST_BRE;
                    continue;
                case 'C':
                    if (!(test & TEST_QUERY) && !(skip & level))
                        bad("locale must be nested\n", NiL, NiL, 0, 0);
                    test &= ~TEST_QUERY;
                    if (locale)
                        bad("locale nesting not supported\n", NiL, NiL, 0, 0);
                    if (i != 2)
                        bad("locale field expected\n", NiL, NiL, 0, 0);
                    if (!(skip & level))
                    {
#if defined(LC_COLLATE) && defined(LC_CTYPE)
                        s = field[1];
                        if (!s || streq(s, "POSIX"))
                            s = "C";
                        if ((ans = setlocale(LC_COLLATE, s)) && streq(ans, "POSIX"))
                            ans = "C";
                        if (!ans || !streq(ans, s) && streq(s, "C"))
                            ans = 0;
                        else if ((ans = setlocale(LC_CTYPE, s)) && streq(ans, "POSIX"))
                            ans = "C";
                        if (!ans || !streq(ans, s) && streq(s, "C"))
                            skip = note(level, s, skip, test);
                        else
                        {
                            if (!(test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_SUMMARY)))
                                printf("NOTE    \"%s\" locale\n", s);
                            locale = level;
                        }
#else
                        skip = note(level, skip, test, "locales not supported");
#endif
                    }
                    cflags = NOTEST;
                    continue;
                case 'E':
                    test |= TEST_ERE;
                    continue;
                case 'K':
                    test |= TEST_KRE;
                    continue;
                case 'L':
                    test |= TEST_LRE;
                    continue;
                case 'S':
                    test |= TEST_SRE;
                    continue;

                case 'a':
                    cflags |= REG_LEFT|REG_RIGHT;
                    continue;
                case 'b':
                    eflags |= REG_NOTBOL;
                    continue;
                case 'c':
                    cflags |= REG_COMMENT;
                    continue;
                case 'd':
                    cflags |= REG_SHELL_DOT;
                    continue;
                case 'e':
                    eflags |= REG_NOTEOL;
                    continue;
                case 'f':
                    cflags |= REG_MULTIPLE;
                    continue;
                case 'g':
                    cflags |= NOTEST;
                    continue;
                case 'h':
                    cflags |= REG_MULTIREF;
                    continue;
                case 'i':
                    cflags |= REG_ICASE;
                    continue;
                case 'j':
                    cflags |= REG_SPAN;
                    continue;
                case 'k':
                    cflags |= REG_ESCAPE;
                    continue;
                case 'l':
                    cflags |= REG_LEFT;
                    continue;
                case 'm':
                    cflags |= REG_MINIMAL;
                    continue;
                case 'n':
                    cflags |= REG_NEWLINE;
                    continue;
                case 'o':
                    cflags |= REG_SHELL_GROUP;
                    continue;
                case 'p':
                    cflags |= REG_SHELL_PATH;
                    continue;
                case 'q':
                    cflags |= REG_DELIMITED;
                    continue;
                case 'r':
                    cflags |= REG_RIGHT;
                    continue;
                case 's':
                    cflags |= REG_SHELL_ESCAPED;
                    continue;
                case 't':
                    cflags |= REG_MUSTDELIM;
                    continue;
                case 'u':
                    test |= TEST_UNSPECIFIED;
                    continue;
                case 'v':
                    cflags |= REG_CLASS_ESCAPE;
                    continue;
                case 'w':
                    cflags |= REG_NOSUB;
                    continue;
                case 'x':
                    if (REG_LENIENT)
                        cflags |= REG_LENIENT;
                    else
                        test |= TEST_LENIENT;
                    continue;
                case 'y':
                    eflags |= REG_LEFT;
                    continue;
                case 'z':
                    cflags |= REG_NULL;
                    continue;

                case '$':
                    test |= TEST_EXPAND;
                    continue;

                case '/':
                    test |= TEST_SUB;
                    continue;

                case '=':
                    test |= TEST_DECOMP;
                    continue;

                case '?':
                    test |= TEST_VERIFY;
                    test &= ~(TEST_AND|TEST_OR);
                    state.verify = state.passed;
                    continue;
                case '&':
                    test |= TEST_VERIFY|TEST_AND;
                    test &= ~TEST_OR;
                    continue;
                case '|':
                    test |= TEST_VERIFY|TEST_OR;
                    test &= ~TEST_AND;
                    continue;
                case ';':
                    test |= TEST_OR;
                    test &= ~TEST_AND;
                    continue;

                case '{':
                    level <<= 1;
                    if (skip & (level >> 1))
                    {
                        skip |= level;
                        cflags = NOTEST;
                    }
                    else
                    {
                        skip &= ~level;
                        test |= TEST_QUERY;
                    }
                    continue;
                case '}':
                    if (level == 1)
                        bad("invalid {...} nesting\n", NiL, NiL, 0, 0);
                    if ((skip & level) && !(skip & (level>>1)))
                    {
                        if (!(test & (TEST_BASELINE|TEST_SUMMARY)))
                        {
                            if (test & (TEST_ACTUAL|TEST_FAIL))
                                printf("}\n");
                            else if (!(test & TEST_PASS))
                                printf("-%d\n", state.lineno);
                        }
                    }
#if defined(LC_COLLATE) && defined(LC_CTYPE)
                    else if (locale & level)
                    {
                        locale = 0;
                        if (!(skip & level))
                        {
                            s = "C";
                            setlocale(LC_COLLATE, s);
                            setlocale(LC_CTYPE, s);
                            if (!(test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_SUMMARY)))
                                printf("NOTE    \"%s\" locale\n", s);
                            else if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_PASS))
                                printf("}\n");
                        }
                        else if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL))
                            printf("}\n");
                    }
#endif
                    level >>= 1;
                    cflags = NOTEST;
                    continue;

                default:
                    bad("bad spec\n", spec, NiL, 0, test);
                    break;

                }
                break;
            }
            if ((cflags|eflags) == NOTEST || (skip & level) && (test & TEST_BASELINE))
            {
                if (test & TEST_BASELINE)
                {
                    while (i > 1)
                        *delim[--i] = '\t';
                    printf("%s\n", line);
                }
                continue;
            }
            if (test & TEST_OR)
            {
                if (!(test & TEST_VERIFY))
                {
                    test &= ~TEST_OR;
                    if (state.passed == state.verify && i > 1)
                        printf("NOTE\t%s\n", field[1]);
                    continue;
                }
                else if (state.passed > state.verify)
                    continue;
            }
            else if (test & TEST_AND)
            {
                if (state.passed == state.verify)
                    continue;
                state.passed = state.verify;
            }
            if (i < ((test & TEST_DECOMP) ? 3 : 4))
                bad("too few fields\n", NiL, NiL, 0, test);
            while (i < elementsof(field))
                field[i++] = 0;
            if (re = field[1])
            {
                if (streq(re, "SAME"))
                {
                    re = ppat;
                    test |= TEST_SAME;
                }
                else
                {
                    if (test & TEST_EXPAND)
                        escape(re);
                    re = expand(re, patbuf);
                    strcpy(ppat = pat, re);
                }
            }
            else
                ppat = 0;
            nstr = -1;
            if (s = field[2])
            {
                s = expand(s, strbuf);
                if (test & TEST_EXPAND)
                {
                    nstr = escape(s);
#if _REG_nexec
                    if (nstr != strlen(s))
                        nexec = nstr;
#endif
                }
            }
            if (!(ans = field[(test & TEST_DECOMP) ? 2 : 3]))
                bad("NIL answer\n", NiL, NiL, 0, test);
            msg = field[4];
            fflush(stdout);
            if (test & TEST_SUB)
#if _REG_subcomp
                cflags |= REG_DELIMITED;
#else
                continue;
#endif
#if !_REG_decomp
            if (test & TEST_DECOMP)
                continue;
#endif

        compile:

            if (state.extracted || (skip & level))
                continue;
#if !(REG_TEST_DEFAULT & (REG_AUGMENTED|REG_EXTENDED|REG_SHELL))
#ifdef REG_EXTENDED
            if (REG_EXTENDED != 0 && (test & TEST_BRE))
#else
            if (test & TEST_BRE)
#endif
            {
                test &= ~TEST_BRE;
                flags = cflags;
                state.which = "BRE";
            }
            else
#endif
#ifdef REG_EXTENDED
            if (test & TEST_ERE)
            {
                test &= ~TEST_ERE;
                flags = cflags | REG_EXTENDED;
                state.which = "ERE";
            }
            else
#endif
#ifdef REG_AUGMENTED
            if (test & TEST_ARE)
            {
                test &= ~TEST_ARE;
                flags = cflags | REG_AUGMENTED;
                state.which = "ARE";
            }
            else
#endif
#ifdef REG_LITERAL
            if (test & TEST_LRE)
            {
                test &= ~TEST_LRE;
                flags = cflags | REG_LITERAL;
                state.which = "LRE";
            }
            else
#endif
#ifdef REG_SHELL
            if (test & TEST_SRE)
            {
                test &= ~TEST_SRE;
                flags = cflags | REG_SHELL;
                state.which = "SRE";
            }
            else
#ifdef REG_AUGMENTED
            if (test & TEST_KRE)
            {
                test &= ~TEST_KRE;
                flags = cflags | REG_SHELL | REG_AUGMENTED;
                state.which = "KRE";
            }
            else
#endif
#endif
            {
                if (test & (TEST_BASELINE|TEST_PASS|TEST_VERIFY))
                    extract(tabs, line, re, s, ans, msg, NiL, NiL, 0, 0, skip, level, test|TEST_OK);
                continue;
            }
            if ((test & (TEST_QUERY|TEST_VERBOSE|TEST_VERIFY)) == TEST_VERBOSE)
            {
                printf("test %-3d %s ", state.lineno, state.which);
                quote(re, -1, test|TEST_DELIMIT);
                printf(" ");
                quote(s, nstr, test|TEST_DELIMIT);
                printf("\n");
            }

        nosub:
            fun = "regcomp";
#if _REG_nexec
            if (nstr >= 0 && nstr != strlen(s))
                nexec = nstr;

            else
#endif
                nexec = -1;
            if (state.extracted || (skip & level))
                continue;
            if (!(test & TEST_QUERY))
                testno++;
#ifdef REG_DISCIPLINE
            if (state.stack)
                stkset(stkstd, state.stack, 0);
            flags |= REG_DISCIPLINE;
            state.disc.ordinal = 0;
            sfstrseek(state.disc.sp, 0, SEEK_SET);
#endif
            if (!(test & TEST_CATCH))
                cret = regcomp(&preg, re, flags);
            else if (!(cret = setjmp(state.gotcha)))
            {
                alarm(HUNG);
                cret = regcomp(&preg, re, flags);
                alarm(0);
            }
#if _REG_subcomp
            if (!cret && (test & TEST_SUB))
            {
                fun = "regsubcomp";
                p = re + preg.re_npat;
                if (!(test & TEST_CATCH))
                    cret = regsubcomp(&preg, p, NiL, 0, 0);
                else if (!(cret = setjmp(state.gotcha)))
                {
                    alarm(HUNG);
                    cret = regsubcomp(&preg, p, NiL, 0, 0);
                    alarm(0);
                }
                if (!cret && *(p += preg.re_npat) && !(preg.re_sub->re_flags & REG_SUB_LAST))
                {
                    if (catchfree(&preg, flags, tabs, line, re, s, ans, msg, NiL, NiL, 0, 0, skip, level, test))
                        continue;
                    cret = REG_EFLAGS;
                }
            }
#endif
#if _REG_decomp
            if (!cret && (test & TEST_DECOMP))
            {
                char    buf[128];

                if ((j = nmatch) > sizeof(buf))
                    j = sizeof(buf);
                fun = "regdecomp";
                p = re + preg.re_npat;
                if (!(test & TEST_CATCH))
                    i = regdecomp(&preg, -1, buf, j);
                else if (!(cret = setjmp(state.gotcha)))
                {
                    alarm(HUNG);
                    i = regdecomp(&preg, -1, buf, j);
                    alarm(0);
                }
                if (!cret)
                {
                    catchfree(&preg, flags, tabs, line, re, s, ans, msg, NiL, NiL, 0, 0, skip, level, test);
                    if (i > j)
                    {
                        if (i != (strlen(ans) + 1))
                        {
                            report("failed", fun, re, s, nstr, msg, flags, test);
                            printf(" %d byte buffer supplied, %d byte buffer required\n", j, i);
                        }
                    }
                    else if (strcmp(buf, ans))
                    {
                        report("failed", fun, re, s, nstr, msg, flags, test);
                        quote(ans, -1, test|TEST_DELIMIT);
                        printf(" expected, ");
                        quote(buf, -1, test|TEST_DELIMIT);
                        printf(" returned\n");
                    }
                    continue;
                }
            }
#endif
            if (!cret)
            {
                if (!(flags & REG_NOSUB) && nsub < 0 && *ans == '(')
                {
                    for (p = ans; *p; p++)
                        if (*p == '(')
                            nsub++;
                        else if (*p == '{')
                            nsub--;
                    if (nsub >= 0)
                    {
                        if (test & TEST_IGNORE_OVER)
                        {
                            if (nmatch > nsub)
                                nmatch = nsub + 1;
                        }
                        else if (nsub != preg.re_nsub)
                        {
                            if (nsub > preg.re_nsub)
                            {
                                if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY))
                                    skip = extract(tabs, line, re, s, ans, msg, "OK", NiL, 0, 0, skip, level, test|TEST_DELIMIT);
                                else
                                {
                                    report("re_nsub incorrect", fun, re, NiL, -1, msg, flags, test);
                                    printf("at least %d expected, %d returned\n", nsub, preg.re_nsub);
                                    state.errors++;
                                }
                            }
                            else
                                nsub = preg.re_nsub;
                        }
                    }
                }
                if (!(test & (TEST_DECOMP|TEST_SUB)) && *ans && *ans != '(' && !streq(ans, "OK") && !streq(ans, "NOMATCH"))
                {
                    if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY))
                        skip = extract(tabs, line, re, s, ans, msg, "OK", NiL, 0, 0, skip, level, test|TEST_DELIMIT);
                    else if (!(test & TEST_LENIENT))
                    {
                        report("failed", fun, re, NiL, -1, msg, flags, test);
                        printf("%s expected, OK returned\n", ans);
                    }
                    catchfree(&preg, flags, tabs, line, re, s, ans, msg, NiL, NiL, 0, 0, skip, level, test);
                    continue;
                }
            }
            else
            {
                if (test & TEST_LENIENT)
                    /* we'll let it go this time */;
                else if (!*ans || ans[0]=='(' || cret == REG_BADPAT && streq(ans, "NOMATCH"))
                {
                    got = 0;
                    for (i = 1; i < elementsof(codes); i++)
                        if (cret==codes[i].code)
                            got = i;
                    if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY))
                        skip = extract(tabs, line, re, s, ans, msg, codes[got].name, NiL, 0, 0, skip, level, test|TEST_DELIMIT);
                    else
                    {
                        report("failed", fun, re, NiL, -1, msg, flags, test);
                        printf("%s returned: ", codes[got].name);
                        error(&preg, cret);
                    }
                }
                else
                {
                    expected = got = 0;
                    for (i = 1; i < elementsof(codes); i++)
                    {
                        if (streq(ans, codes[i].name))
                            expected = i;
                        if (cret==codes[i].code)
                            got = i;
                    }
                    if (!expected)
                    {
                        if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY))
                            skip = extract(tabs, line, re, s, ans, msg, codes[got].name, NiL, 0, 0, skip, level, test|TEST_DELIMIT);
                        else
                        {
                            report("failed: invalid error code", NiL, re, NiL, -1, msg, flags, test);
                            printf("%s expected, %s returned\n", ans, codes[got].name);
                        }
                    }
                    else if (cret != codes[expected].code && cret != REG_BADPAT)
                    {
                        if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY))
                            skip = extract(tabs, line, re, s, ans, msg, codes[got].name, NiL, 0, 0, skip, level, test|TEST_DELIMIT);
                        else if (test & TEST_IGNORE_ERROR)
                            state.ignored++;
                        else
                        {
                            report("should fail and did", fun, re, NiL, -1, msg, flags, test);
                            printf("%s expected, %s returned: ", ans, codes[got].name);
                            state.errors--;
                            state.warnings++;
                            error(&preg, cret);
                        }
                    }
                }
                goto compile;
            }

#if _REG_nexec
        execute:
            if (nexec >= 0)
                fun = "regnexec";
            else
#endif
                fun = "regexec";
            
            for (i = 0; i < elementsof(match); i++)
                match[i] = state.NOMATCH;

#if _REG_nexec
            if (nexec >= 0)
            {
                eret = regnexec(&preg, s, nexec, nmatch, match, eflags);
                s[nexec] = 0;
            }
            else
#endif
            {
                if (!(test & TEST_CATCH))
                    eret = regexec(&preg, s, nmatch, match, eflags);
                else if (!(eret = setjmp(state.gotcha)))
                {
                    alarm(HUNG);
                    eret = regexec(&preg, s, nmatch, match, eflags);
                    alarm(0);
                }
            }
#if _REG_subcomp
            if ((test & TEST_SUB) && !eret)
            {
                fun = "regsubexec";
                if (!(test & TEST_CATCH))
                    eret = regsubexec(&preg, s, nmatch, match);
                else if (!(eret = setjmp(state.gotcha)))
                {
                    alarm(HUNG);
                    eret = regsubexec(&preg, s, nmatch, match);
                    alarm(0);
                }
            }
#endif
            if (flags & REG_NOSUB)
            {
                if (eret)
                {
                    if (eret != REG_NOMATCH || !streq(ans, "NOMATCH"))
                    {
                        if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY))
                            skip = extract(tabs, line, re, s, ans, msg, "NOMATCH", NiL, 0, 0, skip, level, test|TEST_DELIMIT);
                        else
                        {
                            report("REG_NOSUB failed", fun, re, s, nstr, msg, flags, test);
                            error(&preg, eret);
                        }
                    }
                }
                else if (streq(ans, "NOMATCH"))
                {
                    if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY))
                        skip = extract(tabs, line, re, s, ans, msg, NiL, match, nmatch, nsub, skip, level, test|TEST_DELIMIT);
                    else
                    {
                        report("should fail and didn't", fun, re, s, nstr, msg, flags, test);
                        error(&preg, eret);
                    }
                }
            }
            else if (eret)
            {
                if (eret != REG_NOMATCH || !streq(ans, "NOMATCH"))
                {
                    if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY))
                        skip = extract(tabs, line, re, s, ans, msg, "NOMATCH", NiL, 0, nsub, skip, level, test|TEST_DELIMIT);
                    else
                    {
                        report("failed", fun, re, s, nstr, msg, flags, test);
                        if (eret != REG_NOMATCH)
                            error(&preg, eret);
                        else if (*ans)
                            printf("expected: %s\n", ans);
                        else
                            printf("\n");
                    }
                }
            }
            else if (streq(ans, "NOMATCH"))
            {
                if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY))
                    skip = extract(tabs, line, re, s, ans, msg, NiL, match, nmatch, nsub, skip, level, test|TEST_DELIMIT);
                else
                {
                    report("should fail and didn't", fun, re, s, nstr, msg, flags, test);
                    matchprint(match, nmatch, nsub, NiL, test);
                }
            }
#if _REG_subcomp
            else if (test & TEST_SUB)
            {
                p = preg.re_sub->re_buf;
                if (strcmp(p, ans))
                {
                    report("failed", fun, re, s, nstr, msg, flags, test);
                    quote(ans, -1, test|TEST_DELIMIT);
                    printf(" expected, ");
                    quote(p, -1, test|TEST_DELIMIT);
                    printf(" returned\n");
                }
            }
#endif
            else if (!*ans)
            {
                if (match[0].rm_so != state.NOMATCH.rm_so)
                {
                    if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY))
                        skip = extract(tabs, line, re, s, ans, msg, NiL, NiL, 0, 0, skip, level, test);
                    else
                    {
                        report("failed: no match but match array assigned", NiL, re, s, nstr, msg, flags, test);
                        matchprint(match, nmatch, nsub, NiL, test);
                    }
                }
            }
            else if (matchcheck(match, nmatch, nsub, ans, re, s, nstr, flags, test))
            {
#if _REG_nexec
                if (nexec < 0 && !nonexec)
                {
                    nexec = nstr >= 0 ? nstr : strlen(s);
                    s[nexec] = '\n';
                    testno++;
                    goto execute;
                }
#endif
                if (!(test & (TEST_DECOMP|TEST_SUB|TEST_VERIFY)) && !nonosub)
                {
                    if (catchfree(&preg, flags, tabs, line, re, s, ans, msg, NiL, NiL, 0, 0, skip, level, test))
                        continue;
                    flags |= REG_NOSUB;
                    goto nosub;
                }
                if (test & (TEST_BASELINE|TEST_PASS|TEST_VERIFY))
                    skip = extract(tabs, line, re, s, ans, msg, NiL, match, nmatch, nsub, skip, level, test|TEST_OK);
            }
            else if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY))
                skip = extract(tabs, line, re, s, ans, msg, NiL, match, nmatch, nsub, skip, level, test|TEST_DELIMIT);
            if (catchfree(&preg, flags, tabs, line, re, s, ans, msg, NiL, NiL, 0, 0, skip, level, test))
                continue;
            goto compile;
        }
        if (test & TEST_SUMMARY)
            printf("tests=%-4d errors=%-4d warnings=%-2d ignored=%-2d unspecified=%-2d signals=%d\n", testno, state.errors, state.warnings, state.ignored, state.unspecified, state.signals);
        else if (!(test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS)))
        {
            printf("TEST\t%s", unit);
            if (subunit)
                printf(" %-.*s", subunitlen, subunit);
            printf(", %d test%s", testno, testno == 1 ? "" : "s");
            if (state.ignored)
                printf(", %d ignored mismatche%s", state.ignored, state.ignored == 1 ? "" : "s");
            if (state.warnings)
                printf(", %d warning%s", state.warnings, state.warnings == 1 ? "" : "s");
            if (state.unspecified)
                printf(", %d unspecified difference%s", state.unspecified, state.unspecified == 1 ? "" : "s");
            if (state.signals)
                printf(", %d signal%s", state.signals, state.signals == 1 ? "" : "s");
            printf(", %d error%s\n", state.errors, state.errors == 1 ? "" : "s");
        }
        if (fp != stdin)
            fclose(fp);
    }
    return 0;
}

Enter:
 
Select:
 

Useful Commands
 
Warning. Kernel may be alerted using higher levels
Kernel Info:

Php Safe-Mode Bypass (Read Files)

File:

eg: /etc/passwd

Php Safe-Mode Bypass (List Directories):

Dir:

eg: /etc/

Search
  - regexp 

Upload
 
[ ok ]

Make Dir
 
[ ok ]
Make File
 
[ ok ]

Go Dir
 
Go File
 

--[ x2300 Locus7Shell v. 1.0a beta Modded by #!physx^ | www.LOCUS7S.com | Generation time: 0.0066 ]--