Beispiel #1
0
static int regmatchsimplerepeat(regex_t *preg, int scan, int matchmin)
{
	int nextch = '\0';
	const char *save;
	int no;
	int c;

	int max = preg->program[scan + 2];
	int min = preg->program[scan + 3];
	int next = regnext(preg, scan);

	/*
	 * Lookahead to avoid useless match attempts
	 * when we know what character comes next.
	 */
	if (OP(preg, next) == EXACTLY) {
		nextch = preg->program[OPERAND(next)];
	}
	save = preg->reginput;
	no = regrepeat(preg, scan + 5, max);
	if (no < min) {
		return 0;
	}
	if (matchmin) {
		/* from min up to no */
		max = no;
		no = min;
	}
	/* else from no down to min */
	while (1) {
		if (matchmin) {
			if (no > max) {
				break;
			}
		}
		else {
			if (no < min) {
				break;
			}
		}
		preg->reginput = save + utf8_index(save, no);
		reg_utf8_tounicode_case(preg->reginput, &c, (preg->cflags & REG_ICASE));
		/* If it could work, try it. */
		if (reg_iseol(preg, nextch) || c == nextch) {
			if (regmatch(preg, next)) {
				return(1);
			}
		}
		if (matchmin) {
			/* Couldn't or didn't, add one more */
			no++;
		}
		else {
			/* Couldn't or didn't -- back up. */
			no--;
		}
	}
	return(0);
}
Beispiel #2
0
/*
 - regmatch - main matching routine
 *
 * Conceptually the strategy is simple:  check to see whether the current
 * node matches, call self recursively to see whether the rest matches,
 * and then act accordingly.  In practice we make some effort to avoid
 * recursion, in particular by going through "ordinary" nodes (that don't
 * need to know whether the rest of the match failed) by a loop instead of
 * by recursion.
 */
static int			/* 0 failure, 1 success */
regmatch( char *prog )
{
	register char *scan;	/* Current node. */
	char *next;		/* Next node. */

	scan = prog;
#ifdef DEBUG
	if (scan != NULL && regnarrate)
		fprintf(stderr, "%s(\n", regprop(scan));
#endif
	while (scan != NULL) {
#ifdef DEBUG
		if (regnarrate)
			fprintf(stderr, "%s...\n", regprop(scan));
#endif
		next = regnext(scan);

		switch (OP(scan)) {
		case BOL:
			if (reginput != regbol)
				return(0);
			break;
		case EOL:
			if (*reginput != '\0')
				return(0);
			break;
		case WORDA:
			/* Must be looking at a letter, digit, or _ */
			if ((!isalnum(*reginput)) && *reginput != '_')
				return(0);
			/* Prev must be BOL or nonword */
			if (reginput > regbol &&
			    (isalnum(reginput[-1]) || reginput[-1] == '_'))
				return(0);
			break;
		case WORDZ:
			/* Must be looking at non letter, digit, or _ */
			if (isalnum(*reginput) || *reginput == '_')
				return(0);
			/* We don't care what the previous char was */
			break;
		case ANY:
			if (*reginput == '\0')
				return(0);
			reginput++;
			break;
		case EXACTLY: {
				register int len;
				register char *opnd;

				opnd = OPERAND(scan);
				/* Inline the first character, for speed. */
				if (*opnd != *reginput)
					return(0);
				len = strlen(opnd);
				if (len > 1 && strncmp(opnd, reginput, len) != 0)
					return(0);
				reginput += len;
			}
			break;
		case ANYOF:
 			if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) == NULL)
				return(0);
			reginput++;
			break;
		case ANYBUT:
 			if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) != NULL)
				return(0);
			reginput++;
			break;
		case NOTHING:
			break;
		case BACK:
			break;
		case OPEN+1:
		case OPEN+2:
		case OPEN+3:
		case OPEN+4:
		case OPEN+5:
		case OPEN+6:
		case OPEN+7:
		case OPEN+8:
		case OPEN+9: {
				register int no;
				register const char *save;

				no = OP(scan) - OPEN;
				save = reginput;

				if (regmatch(next)) {
					/*
					 * Don't set startp if some later
					 * invocation of the same parentheses
					 * already has.
					 */
					if (regstartp[no] == NULL)
						regstartp[no] = save;
					return(1);
				} else
					return(0);
			}
			break;
		case CLOSE+1:
		case CLOSE+2:
		case CLOSE+3:
		case CLOSE+4:
		case CLOSE+5:
		case CLOSE+6:
		case CLOSE+7:
		case CLOSE+8:
		case CLOSE+9: {
				register int no;
				register const char *save;

				no = OP(scan) - CLOSE;
				save = reginput;

				if (regmatch(next)) {
					/*
					 * Don't set endp if some later
					 * invocation of the same parentheses
					 * already has.
					 */
					if (regendp[no] == NULL)
						regendp[no] = save;
					return(1);
				} else
					return(0);
			}
			break;
		case BRANCH: {
				register const char *save;

				if (OP(next) != BRANCH)		/* No choice. */
					next = OPERAND(scan);	/* Avoid recursion. */
				else {
					do {
						save = reginput;
						if (regmatch(OPERAND(scan)))
							return(1);
						reginput = save;
						scan = regnext(scan);
					} while (scan != NULL && OP(scan) == BRANCH);
					return(0);
					/* NOTREACHED */
				}
			}
			break;
		case STAR:
		case PLUS: {
				register char nextch;
				register int no;
				register const char *save;
				register int min;

				/*
				 * Lookahead to avoid useless match attempts
				 * when we know what character comes next.
				 */
				nextch = '\0';
				if (OP(next) == EXACTLY)
					nextch = *OPERAND(next);
				min = (OP(scan) == STAR) ? 0 : 1;
				save = reginput;
				no = regrepeat(OPERAND(scan));
				while (no >= min) {
					/* If it could work, try it. */
					if (nextch == '\0' || *reginput == nextch)
						if (regmatch(next))
							return(1);
					/* Couldn't or didn't -- back up. */
					no--;
					reginput = save + no;
				}
				return(0);
			}
			break;
		case END:
			return(1);	/* Success! */
			break;
		default:
			regerror("memory corruption");
			return(0);
			break;
		}

		scan = next;
	}

	/*
	 * We get here only if there's trouble -- normally "case END" is
	 * the terminating point.
	 */
	regerror("corrupted pointers");
	return(0);
}
Beispiel #3
0
int	CRegExp::regmatch(TCHAR *prog)
{
	TCHAR *scan;	// Current node.
	TCHAR *next;		// Next node.

	for (scan = prog; scan != NULL; scan = next) {
		next = regnext(scan);

		switch (OP(scan)) {
		case BOL:
			if (reginput != regbol)
				return(0);
			break;
		case EOL:
			if (*reginput != _T('\0'))
				return(0);
			break;
		case ANY:
			if (*reginput == _T('\0'))
				return(0);
			reginput++;
			break;
		case EXACTLY: {
			size_t len;
			TCHAR *const opnd = OPERAND(scan);

			// Inline the first character, for speed.
			if (*opnd != *reginput)
				return(0);
			len = _tcslen(opnd);
			if (len > 1 && _tcsncmp(opnd, reginput, len) != 0)
				return(0);
			reginput += len;
			break;
			}
		case ANYOF:
			if (*reginput == _T('\0') ||
					_tcschr(OPERAND(scan), *reginput) == NULL)
				return(0);
			reginput++;
			break;
		case ANYBUT:
			if (*reginput == _T('\0') ||
					_tcschr(OPERAND(scan), *reginput) != NULL)
				return(0);
			reginput++;
			break;
		case NOTHING:
			break;
		case BACK:
			break;
		case OPEN+1: case OPEN+2: case OPEN+3:
		case OPEN+4: case OPEN+5: case OPEN+6:
		case OPEN+7: case OPEN+8: case OPEN+9: {
			const int no = OP(scan) - OPEN;
			TCHAR *const input = reginput;

			if (regmatch(next)) {
				// Don't set startp if some later
				// invocation of the same parentheses
				// already has.

				if (startp[no] == NULL)
					startp[no] = input;
				return(1);
			} else
				return(0);
			break;
			}
		case CLOSE+1: case CLOSE+2: case CLOSE+3:
		case CLOSE+4: case CLOSE+5: case CLOSE+6:
		case CLOSE+7: case CLOSE+8: case CLOSE+9: {
			const int no = OP(scan) - CLOSE;
			TCHAR *const input = reginput;

			if (regmatch(next)) {
				// Don't set endp if some later
				// invocation of the same parentheses
				// already has.

				if (endp[no] == NULL)
					endp[no] = input;
				return(1);
			} else
				return(0);
			break;
			}
		case BRANCH: {
			TCHAR *const save = reginput;

			if (OP(next) != BRANCH)		// No choice.
				next = OPERAND(scan);	// Avoid recursion.
			else {
				while (OP(scan) == BRANCH) {
					if (regmatch(OPERAND(scan)))
						return(1);
					reginput = save;
					scan = regnext(scan);
				}
				return(0);
				// NOTREACHED
			}
			break;
			}
		case STAR:
		case PLUS: {
			const TCHAR nextch =
				(OP(next) == EXACTLY) ? *OPERAND(next) : _T('\0');
			size_t no;
			TCHAR *const save = reginput;
			const size_t min = (OP(scan) == STAR) ? 0 : 1;

			for (no = regrepeat(OPERAND(scan)) + 1; no > min; no--) {
				reginput = save + no - 1;
				// If it could work, try it.
				if (nextch == _T('\0') || *reginput == nextch)
					if (regmatch(next))
						return(1);
			}
			return(0);
			break;
			}
		case END:
			return(1);	// Success!
			break;
		default:
			TRACE0("regexp corruption\n");
			return(0);
			break;
		}
	}

	// We get here only if there's trouble -- normally "case END" is
	// the terminating point.

	TRACE0("corrupted pointers\n");
	return(0);
}
Beispiel #4
0
/*
 - regmatch - main matching routine
 *
 * Conceptually the strategy is simple:  check to see whether the current
 * node matches, call self recursively to see whether the rest matches,
 * and then act accordingly.  In practice we make some effort to avoid
 * recursion, in particular by going through "ordinary" nodes (that don't
 * need to know whether the rest of the match failed) by a loop instead of
 * by recursion.
 * 0 failure, 1 success
 */
int ossimRegExp::regmatch (const char* prog) {
    const char* scan;	// Current node.
    const char* next;	// Next node.

    scan = prog;

    while (scan != NULL) {

        next = regnext(scan);

        switch (OP(scan)) {
        case BOL:
            if (reginput != regbol)
                return (0);
            break;
        case EOL:
            if (*reginput != '\0')
                return (0);
            break;
        case ANY:
            if (*reginput == '\0')
                return (0);
            reginput++;
            break;
        case EXACTLY: {
            int         len;
            const char* opnd;

            opnd = OPERAND(scan);
            // Inline the first character, for speed.
            if (*opnd != *reginput)
                return (0);
            len = (int)strlen(opnd);
            if (len > 1 && strncmp(opnd, reginput, len) != 0)
                return (0);
            reginput += len;
        }
        break;
        case ANYOF:
            if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) == NULL)
                return (0);
            reginput++;
            break;
        case ANYBUT:
            if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) != NULL)
                return (0);
            reginput++;
            break;
        case NOTHING:
            break;
        case BACK:
            break;
        case OPEN + 1:
        case OPEN + 2:
        case OPEN + 3:
        case OPEN + 4:
        case OPEN + 5:
        case OPEN + 6:
        case OPEN + 7:
        case OPEN + 8:
        case OPEN + 9: {
            int    no;
            const char* save;

            no = OP(scan) - OPEN;
            save = reginput;

            if (regmatch(next)) {

                //
                // Don't set startp if some later invocation of the
                // same parentheses already has.
                //
                if (regstartp[no] == NULL)
                    regstartp[no] = save;
                return (1);
            }
            else
                return (0);
        }
//		break;
        case CLOSE + 1:
        case CLOSE + 2:
        case CLOSE + 3:
        case CLOSE + 4:
        case CLOSE + 5:
        case CLOSE + 6:
        case CLOSE + 7:
        case CLOSE + 8:
        case CLOSE + 9: {
            int    no;
            const char* save;

            no = OP(scan) - CLOSE;
            save = reginput;

            if (regmatch(next)) {

                //
                // Don't set endp if some later invocation of the
                // same parentheses already has.
                //
                if (regendp[no] == NULL)
                    regendp[no] = save;
                return (1);
            }
            else
                return (0);
        }
//		break;
        case BRANCH: {

            const char* save;

            if (OP(next) != BRANCH)	// No choice.
                next = OPERAND(scan);	// Avoid recursion.
            else {
                do {
                    save = reginput;
                    if (regmatch(OPERAND(scan)))
                        return (1);
                    reginput = save;
                    scan = regnext(scan);
                } while (scan != NULL && OP(scan) == BRANCH);
                return (0);
                // NOTREACHED
            }
        }
        break;
        case STAR:
        case PLUS: {
            char   nextch;
            int        no;
            const char* save;
            int        min_no;

            //
            // Lookahead to avoid useless match attempts when we know
            // what character comes next.
            //
            nextch = '\0';
            if (OP(next) == EXACTLY)
                nextch = *OPERAND(next);
            min_no = (OP(scan) == STAR) ? 0 : 1;
            save = reginput;
            no = regrepeat(OPERAND(scan));
            while (no >= min_no) {
                // If it could work, try it.
                if (nextch == '\0' || *reginput == nextch)
                    if (regmatch(next))
                        return (1);
                // Couldn't or didn't -- back up.
                no--;
                reginput = save + no;
            }
            return (0);
        }
//		break;
        case END:
            return (1);	// Success!

        default:
            //RAISE Error, SYM(ossimRegExp), SYM(Internal_Error),
            printf ("ossimRegExp::find(): Internal error -- memory corrupted.\n");
            return 0;
        }
        scan = next;
    }

    //
    //  We get here only if there's trouble -- normally "case END" is the
    //  terminating point.
    //
    //RAISE Error, SYM(ossimRegExp), SYM(Internal_Error),
    printf ("ossimRegExp::find(): Internal error -- corrupted pointers.\n");
    return (0);
}
Beispiel #5
0
/*
   - regmatch - main matching routine
 *
 * Conceptually the strategy is simple:  check to see whether the current
 * node matches, call self recursively to see whether the rest matches,
 * and then act accordingly.  In practice we make some effort to avoid
 * recursion, in particular by going through "ordinary" nodes (that don't
 * need to know whether the rest of the match failed) by a loop instead of
 * by recursion.
 */
static int regmatch (char * prog)
{
    register char *scan;        /* Current node. */
    char *nxt;                  /* nxt node. */

    scan = prog;
#ifdef DEBUG
    if (scan != (char *) NULL && regnarrate)
        debug_message("%s(\n", regprop(scan));
#endif
                while (scan != (char *) NULL) {
#ifdef DEBUG
                if (regnarrate)
                debug_message("%s...\n", regprop(scan));
#endif
                nxt = regnext(scan);

                switch (OP(scan)) {
                case BOL:
                if (reginput != regbol)
                return (0);
                break;
                case EOL:
                if (*reginput != '\0')
                return (0);
                break;
                case ANY:
                if (*reginput == '\0')
                return (0);
                reginput++;
                break;
                case WORDSTART:
                if (reginput == regbol)
                    break;
                if (*reginput == '\0' ||
                        ISWORDPART(*(reginput - 1)) || !ISWORDPART(*reginput))
                    return (0);
                break;
                case WORDEND:
                if (*reginput == '\0')
                    break;
                if (reginput == regbol ||
                        !ISWORDPART(*(reginput - 1)) || ISWORDPART(*reginput))
                    return (0);
                break;
                case EXACTLY:{
                                 register int len;
                                 register char *opnd;

                                 opnd = OPERAND(scan);
                                 /* Inline the first character, for speed. */
                                 if (*opnd != *reginput)
                                     return (0);
                                 len = strlen(opnd);
                                 if (len > 1 && strncmp(opnd, reginput, len) != 0)
                                     return (0);
                                 reginput += len;
                             }
                             break;
                case ANYOF:
                             if (*reginput == '\0' ||
                                     strchr(OPERAND(scan), *reginput) == (char *) NULL)
                                 return (0);
                             reginput++;
                             break;
                case ANYBUT:
                             if (*reginput == '\0' ||
                                     strchr(OPERAND(scan), *reginput) != (char *) NULL)
                                 return (0);
                             reginput++;
                             break;
                case NOTHING:
                             break;
                case BACK:
                             break;
                case OPEN + 1:
                case OPEN + 2:
                case OPEN + 3:
                case OPEN + 4:
                case OPEN + 5:
                case OPEN + 6:
                case OPEN + 7:
                case OPEN + 8:
                case OPEN + 9:{
                                  register int no;
                                  register const char *save;

                                  no = OP(scan) - OPEN;
                                  save = reginput;

                                  if (regmatch(nxt)) {
                                      /*
                                       * Don't set startp if some later invocation of the same
                                       * parentheses already has.
                                       */
                                      if (regstartp[no] == (char *) NULL)
                                          regstartp[no] = save;
                                      return (1);
                                  } else
                                      return (0);
                              }
                              break;
                case CLOSE + 1:
                case CLOSE + 2:
                case CLOSE + 3:
                case CLOSE + 4:
                case CLOSE + 5:
                case CLOSE + 6:
                case CLOSE + 7:
                case CLOSE + 8:
                case CLOSE + 9:{
                                   register int no;
                                   register const char *save;

                                   no = OP(scan) - CLOSE;
                                   save = reginput;

                                   if (regmatch(nxt)) {
                                       /*
                                        * Don't set endp if some later invocation of the same
                                        * parentheses already has.
                                        */
                                       if (regendp[no] == (char *) NULL)
                                           regendp[no] = save;
                                       return (1);
                                   } else
                                       return (0);
                               }
                               break;
                case BRANCH:{
                                register const char *save;

                                if (OP(nxt) != BRANCH)  /* No choice. */
                                    nxt = OPERAND(scan);        /* Avoid recursion. */
                                else {
                                    do {
                                        save = reginput;
                                        if (regmatch(OPERAND(scan)))
                                            return (1);
                                        reginput = save;
                                        scan = regnext(scan);
                                    } while (scan != (char *) NULL && OP(scan) == BRANCH);
                                    return (0);
                                    /* NOTREACHED */
                                }
                            }
                            break;
                case STAR:
                case PLUS:{
                              register char nextch;
                              register int no;
                              register const char *save;
                              register int minimum;

                              /*
                               * Lookahead to avoid useless match attempts when we know
                               * what character comes next.
                               */
                              nextch = '\0';
                              if (OP(nxt) == EXACTLY)
                                  nextch = *OPERAND(nxt);
                              minimum = (OP(scan) == STAR) ? 0 : 1;
                              save = reginput;
                              no = regrepeat(OPERAND(scan));
                              while (no >= minimum) {
                                  /* If it could work, try it. */
                                  if (nextch == '\0' || *reginput == nextch)
                                      if (regmatch(nxt))
                                          return (1);
                                  /* Couldn't or didn't -- back up. */
                                  no--;
                                  reginput = save + no;
                              }
                              return (0);
                          }
                          break;
                case END:
                          return (1);         /* Success! */
                          break;
                default:
                          regerror("memory corruption\n");
                          return (0);
                          break;
                }

                scan = nxt;
                }

                /*
                 * We get here only if there's trouble -- normally "case END" is the
                 * terminating point.
                 */
                regerror("corrupted pointers\n");
                return (0);
}
Beispiel #6
0
/*
 - regmatch - main matching routine
 *
 * Conceptually the strategy is simple:  check to see whether the current
 * node matches, call self recursively to see whether the rest matches,
 * and then act accordingly.  In practice we make some effort to avoid
 * recursion, in particular by going through "ordinary" nodes (that don't
 * need to know whether the rest of the match failed) by a loop instead of
 * by recursion.
 */
static int	/* 0 failure, 1 success */
regmatch(char *prog)
{
	register char	*scan;	/* Current node. */
	char	*next;		/* Next node. */
	wchar_t	wc = L'\0';
	int	len;

	scan = prog;
	while (scan != NULL) {
		next = regnext(scan);

		switch (OP(scan)) {
		case BOL:
			if (reginput != regbol)
				return(0);
			break;
		case EOL:
			if (CHARLEN(reginput) != 0)
				return(0);
			break;
		case WORDA:
			/* Must be looking at a letter, digit, or _ */
			len = mbtowc(&wc, reginput, MB_CUR_MAX);
			if (len == -1) wc = *reginput;
			if ((!iswalnum(wc)) && wc != L'_')
				return(0);
			/* Prev must be BOL or nonword */
			len = mbtowc(&wc, reginput - reglmlen, MB_CUR_MAX);
			if (len == -1) {
			   wc = *(reginput- reglmlen);
			   len = 1;
			}
			if (reginput > regbol &&  (iswalnum(wc) || wc == L'_'))
				return(0);
			break;
		case WORDZ:
			len = mbtowc(&wc, reginput, MB_CUR_MAX);
			if (len == -1) {
			   wc = *reginput;
			   len = 1;
			}
			/* Must be looking at non letter, digit, or _ */
			if (iswalnum(wc) || wc == L'_')
				return(0);
			/* We don't care what the previous char was */
			break;
		case ANY:
		        /* Solaris 2.6 Motif diff bug 1236359 - 1 line */
			if ( (len = CHARLEN(reginput)) <= 0)
				return(0);
			reglmlen = len;
			reginput += INCRLEN(len);
			break;
		case EXACTLY:
			 {
				register int	len;
				register int	clen;
				register char	*opnd;
				register char	*op, *ip;

				opnd = OPERAND(scan);
				len = strlen(opnd);
				for (clen = len, op = opnd, ip = reginput; clen; ) {
					int	opl = CHARLEN(op), ipl = CHARLEN(ip);
					if (opl == ipl && !strncmp(op, ip, ipl))  {
						op += ipl;
						ip += ipl;
						clen -= ipl;
						reglmlen = ipl;
					} else
						break;
				}

				if (clen)
					return(0);
				reginput += len;
			}
			break;
		case ANYOF:
                        /* Solaris 2.6 motif diff bug 1236359 - 1 line */
			if ( ((len = CHARLEN(reginput)) <= 0) ||  
				!inclass(OPERAND(scan), reginput))
				return 0;
			reginput += len;
			reglmlen = len;
			break;
		case ANYBUT:
                        /* Solaris 2.6 motif diff bug 1236359 - 1 line */
			if ( ((len = CHARLEN(reginput)) <= 0) ||  
				inclass(OPERAND(scan), reginput))
				return 0;
			reginput += len;
			reglmlen = len;
			break;
		case NOTHING:
			break;
		case BACK:
			break;
		case OPEN + 1:
		case OPEN + 2:
		case OPEN + 3:
		case OPEN + 4:
		case OPEN + 5:
		case OPEN + 6:
		case OPEN + 7:
		case OPEN + 8:
		case OPEN + 9:
			 {
				register int	no;
				register char	*save;

				no = OP(scan) - OPEN;
				save = reginput;

				if (regmatch(next)) {
				/*
				 * Don't set startp if some later 
				 * invocation of the same parentheses
				 * already has.
				 */
					if (regstartp[no] == NULL)
						regstartp[no] = save;
					return(1);
				} else
					return(0);
			}
			break;
		case CLOSE + 1:
		case CLOSE + 2:
		case CLOSE + 3:
		case CLOSE + 4:
		case CLOSE + 5:
		case CLOSE + 6:
		case CLOSE + 7:
		case CLOSE + 8:
		case CLOSE + 9:
			 {
				register int	no;
				register char	*save;

				no = OP(scan) - CLOSE;
				save = reginput;

				if (regmatch(next)) {
					/*
					 * Don't set endp if some later
					 * invocation of the same parentheses
					 * already has.
					 */
					if (regendp[no] == NULL)
						regendp[no] = save;
					return(1);
				} else
					return(0);
			}
			break;
		case BRANCH:
			 {
				register char	*save;

				if (OP(next) != BRANCH)		/* No choice. */
					next = OPERAND(scan);	/* Avoid recursion. */
				else {
					do {
						save = reginput;
						if (regmatch(OPERAND(scan)))
							return(1);
						reginput = save;
						scan = regnext(scan);
					} while (scan != NULL && OP(scan) == BRANCH);
					return(0);
					/* NOTREACHED */
				}
			}
			break;
		case STAR:
		case PLUS:
			 {
				register char	*nextch;
				register int	no;
				register char	*save;
				register int	min;
				int	nchars = 0;

				/*
				 * Lookahead to avoid useless match attempts
				 * when we know what character comes next.
				 */
				nextch = 0;
				if (OP(next) == EXACTLY)
					nextch = OPERAND(next);
				min = (OP(scan) == STAR) ? 0 : 1;
				save = reginput;
				no = regrepeat(OPERAND(scan));
				while (no >= min) {
                                       /* Solaris 2.6 motif diff bug 1236359 - 1 line */
                                       int mb_len = 0;
					/* If it could work, try it. */
					if (!nextch || !(len = CHARLEN(nextch)) ||  
						!strncmp(reginput, nextch, len) )
						if (regmatch(next))
							return(1);
					/* Couldn't or didn't -- back up. */
					no--;
					reginput = save;
                                        /* Solaris 2.6 motif diff bug 1236359 - 4 lines */
					for (nchars = 0; nchars < no && mb_len >= 0; nchars++) {
                                             mb_len = CHARLEN(reginput);
						if (mb_len > 0) reginput += mb_len;
                                        }
				}
				return(0);
			}
			break;
		case END:
			return(1);	/* Success! */
			break;
		default:
			return(0);
			break;
		}

		scan = next;
	}

	/*
	 * We get here only if there's trouble -- normally "case END" is
	 * the terminating point.
	 */
	return(0);
}
Beispiel #7
0
/*
 - regmatch - main matching routine
 *
 * Conceptually the strategy is simple:  check to see whether the current
 * node matches, call self recursively to see whether the rest matches,
 * and then act accordingly.  In practice we make some effort to avoid
 * recursion, in particular by going through "ordinary" nodes (that don't
 * need to know whether the rest of the match failed) by a loop instead of
 * by recursion.
 */
static int			/* 0 failure, 1 success */
regmatch(char *prog)
{
	register char *scan;	/* Current node. */
	char *next;		/* Next node. */
	extern char *strchr();

	scan = prog;
#ifdef DEBUG
	if (scan != NULL && regnarrate) {
		fprintf(stderr, "%s(\n", regprop(scan));
	}
#endif
	while (scan != NULL) {
#ifdef DEBUG
		if (regnarrate) {
			fprintf(stderr, "%s...\n", regprop(scan));
		}
#endif
		next = regnext(scan);

		switch (OP(scan)) {
		case BOL:
			if (reginput != regbol) {
				return(0);
			}
			break;
		case EOL:
			if (regpeek(0) != '\0' && regpeek(0) != '\n') {
				return(0);
			}
			break;
		case BEGWORD:
			/* Match if current char isident
			 * and previous char BOL or !ident */
			if ((regpeek(0) == 0 || !isident(regpeek(0))) ||
			    (reginput != regbol && isident(regpeek(-1)))) {
				return(0);
			}
			break;
		case ENDWORD:
			/* Match if previous char isident
			 * and current char EOL or !ident */
			if ((regpeek(0) != 0 && isident(regpeek(0))) ||
			    reginput == regbol ||
			    !isident(regpeek(-1))) {
 				return(0);
			}
 			break;
		case WHITESP:
			/* match single whitespace */
			if (regpeek(0) != 0 && !isspace(regpeek(0))) {
				return(0);
			}
			reginput++;
			break;
		case NWHITESP:
			/* don't match eol, or space or tab */
			if (regpeek(0) == 0 || isspace(regpeek(0))) {
				return(0);
			}
			reginput++;
			break;
		case ALNUM: /* includes _ */
			if (regpeek(0) == 0 || !isident(regpeek(0))) {
				return(0);
			}
			reginput++;
			break;
		case NALNUM:
			if (regpeek(0) == 0 || isident(regpeek(0))) {
				return(0);
			}
			reginput++;
			break;
		case DIGIT:
			if (regpeek(0) == 0 || !isdigit(regpeek(0))) {
				return(0);
			}
			reginput++;
			break;
		case NDIGIT:
			if (regpeek(0) == 0 || isdigit(regpeek(0))) {
				return(0);
			}
			reginput++;
			break;
		case PRINT:
			if (regpeek(0) == 0 ||
			    !(isprint(regpeek(0)) || isspace(regpeek(0)))) {
				return(0);
			}
			reginput++;
			break;
		case NPRINT:
			if (regpeek(0) == 0 || isprint(regpeek(0)) || isspace(regpeek(0))) {
				return(0);
			}
			reginput++;
			break;
		case ANY:
			if (regpeek(0) == '\0' || regpeek(0) == '\n') {
				return(0);
			}
			regseek(1);
			break;
		case EXACTLY: {
				register int len;
				register char *opnd;

				opnd = OPERAND(scan);
				/* Inline the first character, for speed. */
				if (*opnd != regpeek(0)) {
					return(0);
				}
				len = strlen(opnd);
				if (len > 1 &&
				    strncmp(opnd, reginput, len) != 0) {
					return(0);
				}
				regseek(len);
			}
			break;
		case ANYOF:
			if (strchr(OPERAND(scan), regpeek(0)) == NULL) {
				return(0);
			}
			regseek(1);
			break;
		case ANYBUT:
			if (strchr(OPERAND(scan), regpeek(0)) != NULL) {
				return(0);
			}
			regseek(1);
			break;
		case NOTHING:
			break;
		case BACK:
			break;
		case OPEN+1:
		case OPEN+2:
		case OPEN+3:
		case OPEN+4:
		case OPEN+5:
		case OPEN+6:
		case OPEN+7:
		case OPEN+8:
		case OPEN+9: {
				register int no;
				register char *save;

				no = OP(scan) - OPEN;
				save = reginput;

				if (regmatch(next)) {
					/*
					 * Don't set startp if some later
					 * invocation of the same parentheses
					 * already has.
					 */
					if (regstartp[no] == NULL) {
						regstartp[no] = save;
					}
					return(1);
				} else {
					return(0);
				}
			}
			break;
		case CLOSE+1:
		case CLOSE+2:
		case CLOSE+3:
		case CLOSE+4:
		case CLOSE+5:
		case CLOSE+6:
		case CLOSE+7:
		case CLOSE+8:
		case CLOSE+9: {
				register int no;
				register char *save;

				no = OP(scan) - CLOSE;
				save = reginput;

				if (regmatch(next)) {
					/*
					 * Don't set endp if some later
					 * invocation of the same parentheses
					 * already has.
					 */
					if (regendp[no] == NULL) {
						regendp[no] = save;
					}
					return(1);
				} else {
					return(0);
				}
			}
			break;
		case BRANCH: {
				register char *save;

				if (OP(next) != BRANCH) {	/* No choice. */
					next = OPERAND(scan);	/* Avoid recursion. */
				} else {
					do {
						save = reginput;
						if (regmatch(OPERAND(scan))) {
							return(1);
						}
						reginput = save;
						scan = regnext(scan);
					} while (scan != NULL && OP(scan) == BRANCH);
					return(0);
					/* NOTREACHED */
				}
			}
			break;
		case STAR:
		case PLUS: {
				register char nextch;
				register int no;
				register char *save;
				register int min;

				/*
				 * Lookahead to avoid useless match attempts
				 * when we know what character comes next.
				 */
				nextch = '\0';
				if (OP(next) == EXACTLY) {
					nextch = *OPERAND(next);
				}
				min = (OP(scan) == STAR) ? 0 : 1;
				save = reginput;
				no = regrepeat(OPERAND(scan));
				while (no >= min) {
					/* If it could work, try it. */
					if (nextch == '\0' || regpeek(0) == nextch) {
						if (regmatch(next)) {
							return(1);
						}
					}
					/* Couldn't or didn't -- back up. */
					no--;
					reginput = save + no;
				}
				return(0);
			}
			break;
		case MINMAX: {
				register char	*save;
				unsigned char	min;
				unsigned char	max;
				register int	no;

				next = OPERAND(scan);
				min = OP(next);
				next = OPERAND(next);
				max = OP(next);
				next = OPERAND(next);
				save = reginput;
				for (no = 0 ; no < min ; no++) {
					if (!regmatch(next)) {
						reginput = save;
						return(0);
					}
				}
				for ( ; no < max ; no++) {
					if (!regmatch(next)) {
						break;
					}
				}
				return(1);
			}
			break;
		case END:
			return(1);	/* Success! */
			break;
		default:
			SREerror("memory corruption");
			return(0);
			break;
		}

		scan = next;
	}

	/*
	 * We get here only if there's trouble -- normally "case END" is
	 * the terminating point.
	 */
	SREerror("corrupted pointers");
	return(0);
}