124 # include <vcl_msvc_warnings.h> 134 for (ind=this->
progsize; ind-- != 0;)
136 this->startp[0] = rxp.
startp[0];
137 this->endp[0] = rxp.
endp[0];
251 #define END 0 // no End of program. 252 #define BOL 1 // no Match "" at beginning of line. 253 #define EOL 2 // no Match "" at end of line. 254 #define ANY 3 // no Match any one character. 255 #define ANYOF 4 // str Match any character in this string. 256 #define ANYBUT 5 // str Match any character not in this string. 257 #define BRANCH 6 // node Match this alternative, or the next... 258 #define BACK 7 // no Match "", "next" ptr points backward. 259 #define EXACTLY 8 // str Match this string. 260 #define NOTHING 9 // no Match empty string. 261 #define STAR 10 // node Match this (simple) thing 0 or more times. 262 #define PLUS 11 // node Match this (simple) thing 1 or more times. 263 #define OPEN 20 // no Mark this point in input as start of #n. 265 #define CLOSE 30 // no Analogous to OPEN. 301 #define NEXT(p) (((*((p)+1)&0377)<<8) + (*((p)+2)&0377)) 302 #define OPERAND(p) ((p) + 3) 304 constexpr
unsigned char MAGIC = 0234;
309 #define UCHARAT(p) ((const unsigned char*)(p))[0] 311 #define FAIL(m) { regerror(m); return NULL; } 312 #define ISMULT(c) ((c) == '*' || (c) == '+' || (c) == '?') 313 #define META "^$.[()|?+*\\" 318 #define HASWIDTH 01 // Known never to match null string. 319 #define SIMPLE 02 // Simple enough to be STAR/PLUS operand. 320 #define SPSTART 04 // Starts with * or +. 321 #define WORST 0 // Worst case. 330 static char pattern[3];
332 if (std::strchr(
META, c) !=
nullptr)
357 static const char* regparse;
359 static char regdummy;
360 static char* regcode;
366 static char* reg (
int,
int*);
367 static char* regbranch (
int*);
368 static char* regpiece (
int*);
369 static char* regatom (
int*);
370 static char* regnode (
char);
371 static const char* regnext (
const char*);
372 static char* regnext (
char*);
373 static void regc (
unsigned char);
374 static void reginsert (
char,
char*);
375 static void regtail (
char*,
const char*);
376 static void regoptail (
char*,
const char*);
403 if (exp ==
nullptr) {
405 std::cout <<
"vul_reg_exp::compile(): No expression supplied.\n";
417 std::cout <<
"vul_reg_exp::compile(): Error in compile.\n";
423 if (regsize >= 32767L)
426 std::cout <<
"vul_reg_exp::compile(): Expression too big.\n";
434 this->
program =
new char[regsize];
437 if (this->
program ==
nullptr) {
439 std::cout <<
"vul_reg_exp::compile(): Out of memory.\n";
456 if (
OP(regnext(scan)) ==
END)
463 else if (
OP(scan) ==
BOL)
477 for (; scan !=
nullptr; scan = regnext(scan))
480 len = (
unsigned long)std::strlen(
OPERAND(scan));
497 static char* reg (
int paren,
int *flagp)
511 std::cout <<
"vul_reg_exp::compile(): Too many parentheses.\n";
516 ret = regnode(
char(
OPEN + parno));
522 br = regbranch(&flags);
532 while (*regparse ==
'|')
535 br = regbranch(&flags);
545 ender = regnode((paren) ?
char(
CLOSE + parno) :
char(
END));
549 for (br = ret; br !=
nullptr; br = regnext(br))
550 regoptail(br, ender);
553 if (paren && *regparse++ !=
')') {
555 std::cout <<
"vul_reg_exp::compile(): Unmatched parentheses.\n";
558 else if (!paren && *regparse !=
'\0') {
559 if (*regparse ==
')') {
561 std::cout <<
"vul_reg_exp::compile(): Unmatched parentheses.\n";
566 std::cout <<
"vul_reg_exp::compile(): Internal error.\n";
579 static char* regbranch (
int *flagp)
590 while (*regparse !=
'\0' && *regparse !=
'|' && *regparse !=
')')
592 latest = regpiece(&flags);
593 if (latest ==
nullptr)
596 if (chain ==
nullptr)
599 regtail(chain, latest);
602 if (chain ==
nullptr)
618 static char* regpiece (
int *flagp)
625 ret = regatom(&flags);
635 if (!(flags &
HASWIDTH) && op !=
'?') {
637 std::cout <<
"vul_reg_exp::compile() : *+ operand could be empty.\n";
642 if (op ==
'*' && (flags &
SIMPLE))
643 reginsert(
STAR, ret);
644 else if (op ==
'*') {
647 regoptail(ret, regnode(
BACK));
649 regtail(ret, regnode(
BRANCH));
650 regtail(ret, regnode(
NOTHING));
652 else if (op ==
'+' && (flags &
SIMPLE))
653 reginsert(
PLUS, ret);
654 else if (op ==
'+') {
658 regtail(regnode(
BACK), ret);
659 regtail(next, regnode(
BRANCH));
660 regtail(ret, regnode(
NOTHING));
662 else if (op ==
'?') {
665 regtail(ret, regnode(
BRANCH));
668 regoptail(ret, next);
673 std::cout <<
"vul_reg_exp::compile(): Nested *?+.\n";
687 static char* regatom (
int *flagp)
711 if (*regparse ==
'^') {
716 ret = regnode(
ANYOF);
717 if (*regparse ==
']' || *regparse ==
'-')
719 while (*regparse !=
'\0' && *regparse !=
']')
721 if (*regparse ==
'-')
724 if (*regparse ==
']' || *regparse ==
'\0')
727 rxpclass =
UCHARAT(regparse - 2) + 1;
728 rxpclassend =
UCHARAT(regparse);
729 if (rxpclass > rxpclassend + 1) {
731 std::cout <<
"vul_reg_exp::compile(): Invalid range in [].\n";
734 for (; rxpclass <= rxpclassend; rxpclass++)
735 regc(static_cast<unsigned char>(rxpclass));
743 if (*regparse !=
']') {
745 std::cout <<
"vul_reg_exp::compile(): Unmatched [].\n";
753 ret = reg(1, &flags);
762 std::cout <<
"vul_reg_exp::compile(): Internal error.\n";
768 std::cout <<
"vul_reg_exp::compile(): ?+* follows nothing.\n";
771 if (*regparse ==
'\0') {
773 std::cout <<
"vul_reg_exp::compile(): Trailing backslash.\n";
787 len = (int)std::strcspn(regparse,
META);
790 std::cout <<
"vul_reg_exp::compile(): Internal error.\n";
793 ender = *(regparse + len);
794 if (len > 1 &&
ISMULT(ender))
815 static char* regnode (
char op)
821 if (ret == ®dummy) {
838 static void regc (
unsigned char b)
840 if (regcode != ®dummy)
851 static void reginsert (
char op,
char* opnd)
857 if (regcode == ®dummy) {
877 static void regtail (
char* p,
const char* val)
881 std::ptrdiff_t offset;
889 temp = regnext(scan);
896 offset = (
const char*)scan - val;
899 *(scan + 1) = (
char)((offset >> 8) & 0377);
900 *(scan + 2) = (
char)(offset & 0377);
906 static void regoptail (
char* p,
const char* val)
909 if (p ==
nullptr || p == ®dummy ||
OP(p) !=
BRANCH)
925 static const char* reginput;
926 static const char* regbol;
927 static const char* *regstartp;
928 static const char* *regendp;
933 static int regtry (
const char*,
const char* *,
const char* *,
const char*);
934 static int regmatch (
const char*);
935 static int regrepeat (
const char*);
940 static char* regprop ();
945 return find(s.c_str());
961 std::cout <<
"vul_reg_exp::find(): Compiled regular expression corrupted.\n";
969 while ((s = std::strchr(s, this->
regmust[0])) !=
nullptr) {
989 while ((s = std::strchr(s, this->
regstart)) !=
nullptr) {
999 }
while (*s++ !=
'\0');
1009 static int regtry(
const char*
string,
const char* *start,
1010 const char* *end,
const char* prog)
1026 if (regmatch(prog + 1)) {
1046 static int regmatch(
const char* prog)
1053 while (scan !=
nullptr)
1055 next = regnext(scan);
1060 if (reginput != regbol)
1064 if (*reginput !=
'\0')
1068 if (*reginput ==
'\0')
1079 if (*opnd != *reginput)
1081 len = (int)std::strlen(opnd);
1082 if (len > 1 && std::strncmp(opnd, reginput, len) != 0)
1088 if (*reginput ==
'\0' || std::strchr(
OPERAND(scan), *reginput) ==
nullptr)
1093 if (*reginput ==
'\0' || std::strchr(
OPERAND(scan), *reginput) !=
nullptr)
1115 if (regstartp[no] ==
nullptr)
1116 regstartp[no] = save;
1136 if (regendp[no] ==
nullptr)
1155 scan = regnext(scan);
1156 }
while (scan !=
nullptr &&
OP(scan) ==
BRANCH);
1177 min_no = (
OP(scan) ==
STAR) ? 0 : 1;
1179 no = regrepeat(
OPERAND(scan));
1180 while (no >= min_no) {
1182 if (nextch ==
'\0' || *reginput == nextch)
1187 reginput = save + no;
1196 std::cout <<
"vul_reg_exp::find(): Internal error -- memory corrupted.\n";
1207 std::cout <<
"vul_reg_exp::find(): Internal error -- corrupted pointers.\n";
1214 static int regrepeat(
const char* p)
1225 count = (int)std::strlen(scan);
1229 while (*opnd == *scan) {
1235 while (*scan !=
'\0' && std::strchr(opnd, *scan) !=
nullptr) {
1241 while (*scan !=
'\0' && std::strchr(opnd, *scan) ==
nullptr) {
1248 std::cout <<
"vul_reg_exp::find(): Internal error.\n";
1258 static const char* regnext(
const char* p)
1276 static char* regnext(
char* p)
const char * startp[vul_reg_exp_nsubexp]
anchor point of start position for n-th matching regular expression.
Pattern matching with regular expressions.
char regstart
Internal use only.
bool find(char const *)
true if regexp in char* arg.
static const char * protect(char c)
Return an expression that will match precisely c.
const char * regmust
Internal use only.
bool operator==(vul_reg_exp const &) const
Equality operator.
const char * endp[vul_reg_exp_nsubexp]
anchor point of end position for n-th matching regular expression.
const char * searchstring
constexpr int vul_reg_exp_nsubexp
contains class for pattern matching with regular expressions
constexpr unsigned char MAGIC
bool deep_equal(vul_reg_exp const &) const
Same regexp and state?.
int regmlen
Internal use only.
vul_reg_exp()
Creates an empty regular expression.
char reganch
Internal use only.
void compile(char const *)
Compiles char* --> regexp.