130 #define NEXT(p) (((*((p)+1)&0377)<<8) + (*((p)+2)&0377)) 131 #define OPERAND(p) ((p) + 3) 142 #define UCHARAT(p) ((int)*(unsigned char *)(p)) 144 #define UCHARAT(p) ((int)*(p)&CHARBITS) 147 #define FAIL(m) { hs_regerror(m); return(NULL); } 148 #define ISMULT(c) ((c) == '*' || (c) == '+' || (c) == '?') 161 static const char *regparse;
163 static char regdummy;
164 static char *regcode;
171 #define STATIC static 211 FAIL(
"NULL argument");
215 if (exp[0] ==
'.' && exp[1] ==
'*') exp += 2;
226 if (regsize >= 32767L)
227 FAIL(
"regexp too big");
232 FAIL(
"out of space");
255 else if (
OP(scan) ==
BOL)
271 (strlen(
OPERAND(scan)) >= len)) {
293 reg(
int paren,
int *flagp)
326 while (*regparse ==
'|' || *regparse ==
'\n') {
332 if (!(flags&HASWIDTH))
346 if (paren && *regparse++ !=
')') {
347 FAIL(
"unmatched ()");
348 }
else if (!paren && *regparse !=
'\0') {
349 if (*regparse ==
')') {
350 FAIL(
"unmatched ()");
376 while (*regparse !=
'\0' && *regparse !=
')' &&
377 *regparse !=
'\n' && *regparse !=
'|') {
422 FAIL(
"*+ operand could be empty");
425 if (op ==
'*' && (flags&
SIMPLE))
427 else if (op ==
'*') {
434 }
else if (op ==
'+' && (flags&SIMPLE))
436 else if (op ==
'+') {
443 }
else if (op ==
'?') {
474 switch (*regparse++) {
490 if (*regparse ==
'^') {
495 if (*regparse ==
']' || *regparse ==
'-')
497 while (*regparse !=
'\0' && *regparse !=
']') {
498 if (*regparse ==
'-') {
500 if (*regparse ==
']' || *regparse ==
'\0')
503 class1 =
UCHARAT(regparse-2)+1;
505 if (class1 > classend+1)
506 FAIL(
"invalid [] range");
507 for (; class1 <= classend; class1++)
515 if (*regparse !=
']')
516 FAIL(
"unmatched []");
522 ret =
reg(1, &flags);
531 FAIL(
"internal urp");
536 FAIL(
"?+* follows nothing");
539 switch (*regparse++) {
587 for ( regprev = 0 ; ; ) {
595 case '.':
case '[':
case '(':
596 case ')':
case '|':
case '\n':
604 case '?':
case '+':
case '*':
613 switch (regparse[1]){
650 if (ret == ®dummy) {
670 if (regcode != ®dummy)
688 if (regcode == ®dummy) {
731 *(scan+1) = (offset>>8)&0377;
732 *(scan+2) = offset&0377;
754 static const char *reginput;
755 static const char *regbol;
756 static const char **regstartp;
757 static const char **regendp;
767 FILE *regnarrate = stdout;
769 STATIC char *regprop(
char *scan);
781 if (prog ==
NULL ||
string ==
NULL) {
795 while ((s = strchr(s, prog->
regmust[0])) !=
NULL) {
805 regbol = (
char *)
string;
825 }
while (*s++ !=
'\0');
842 regstartp = (
const char **)prog->
startp;
843 regendp = (
const char **)prog->
endp;
847 for (i =
NSUBEXP; i > 0; i--) {
852 prog->
startp[0] = (
char *)
string;
853 prog->
endp[0] = (
char *)reginput;
877 if (scan !=
NULL && regnarrate)
878 fprintf(regnarrate,
"%s(\n", regprop(scan));
880 while (scan !=
NULL) {
883 fprintf(regnarrate,
"%s...\n", regprop(scan));
889 if (reginput != regbol)
893 if (*reginput !=
'\0')
898 if ((!isalnum((
int)*reginput)) && *reginput !=
'_')
901 if (reginput > regbol &&
902 (isalnum((
int)reginput[-1]) || reginput[-1] ==
'_'))
907 if (isalnum((
int)*reginput) || *reginput ==
'_')
912 if (*reginput ==
'\0')
922 if (*opnd != *reginput)
925 if (len > 1 && strncmp(opnd, reginput, len) != 0)
931 if (*reginput ==
'\0' || strchr(
OPERAND(scan), *reginput) ==
NULL)
936 if (*reginput ==
'\0' || strchr(
OPERAND(scan), *reginput) !=
NULL)
965 if (regstartp[no] ==
NULL)
966 regstartp[no] =
save;
993 if (regendp[no] ==
NULL)
1032 min = (
OP(scan) ==
STAR) ? 0 : 1;
1038 if (nextch ==
'\0' || *reginput == nextch)
1045 reginput = save + no;
1084 count = strlen(scan);
1088 while (*opnd == *scan) {
1094 while (*scan !=
'\0' && strchr(opnd, *scan) !=
NULL) {
1100 while (*scan !=
'\0' && strchr(opnd, *scan) ==
NULL) {
1138 STATIC char *regprop(
char *scan);
1153 printf(
"%2d%s", s-r->
program, regprop(s));
1158 printf(
"(%d)", (s-r->
program)+(next-s));
1162 while (*s !=
'\0') {
1173 printf(
"start `%c' ", r->
regstart);
1175 printf(
"anchored ");
1177 printf(
"must have \"%s\"", r->
regmust);
1188 static char buf[50];
1190 (void) strcpy(buf,
":");
1232 sprintf(buf+strlen(buf),
"OPEN%d",
OP(op)-
OPEN);
1244 sprintf(buf+strlen(buf),
"CLOSE%d",
OP(op)-
CLOSE);
1264 (void) strcat(buf, p);
1291 for (scan1 = s1; *scan1 !=
'\0'; scan1++) {
1292 for (scan2 = s2; *scan2 !=
'\0';)
1293 if (*scan1 == *scan2++)
STATIC char * regnode(char op)
STATIC void regc(unsigned char b)
STATIC char * regbranch(int *flagp)
void hs_regerror(char *s) const
STATIC char * regpiece(int *flagp)
bool save(Lattice &lattice, EST_String filename)
STATIC int regrepeat(char *p)
STATIC char * reg(int paren, int *flagp)
STATIC int regmatch(char *prog)
hs_regexp * hs_regcomp(const char *exp)
float min(float a, float b)
int hs_regexec(const hs_regexp *prog, const char *string)
STATIC void regoptail(char *p, char *val)
STATIC char * regnext(register char *p)
STATIC int regtry(hs_regexp *prog, const char *string)
STATIC void regtail(char *p, char *val)
STATIC char * regatom(int *flagp)
STATIC void reginsert(char op, char *opnd)