Exemplo n.º 1
0
Arquivo: qpak.cpp Projeto: msdsgn/qpak
int matche (register char *p, register char *t)
{
  register char range_start, range_end;  /* start and end in range */

  char invert;     /* is this [..] or [!..] */
  char member_match;   /* have I matched the [..] construct? */
  char loop;       /* should I terminate? */

  for ( ; *p; p++, t++)
  {
    /* if this is the end of the text
       then this is the end of the match */

    if (!*t)
    {
      return ( *p == '*' && *++p == '\0' ) ?
        MATCH_VALID : MATCH_ABORT;
    }

    /* determine and react to pattern type */

    switch (*p)
    {
    case '?':         /* single any character match */
      break;

    case '*':         /* multiple any character match */
      return matche_after_star (p, t);

    /* [..] construct, single member/exclusion character match */
    case '[':
    {
      /* move to beginning of range */

      p++;

      /* check if this is a member match or exclusion match */

      invert = 0;
      if (*p == '!' || *p == '^')
      {
        invert = 1;
        p++;
      }

      /* if closing bracket here or at range start then we have a
        malformed pattern */

      if (*p == ']')
      {
        return MATCH_PATTERN;
      }

      member_match = 0;
      loop = 1;

      while (loop)
      {
        /* if end of construct then loop is done */

        if (*p == ']')
        {
          loop = 0;
          continue;
        }

        /* matching a '!', '^', '-', '\' or a ']' */

        if (*p == '\\')
        {
          range_start = range_end = *++p;
        }
        else  range_start = range_end = *p;

        /* if end of pattern then bad pattern (Missing ']') */

        if (!*p)
          return MATCH_PATTERN;

        /* check for range bar */
        if (*++p == '-')
        {
          /* get the range end */

          range_end = *++p;

          /* if end of pattern or construct
             then bad pattern */

          if (range_end == '\0' || range_end == ']')
            return MATCH_PATTERN;

          /* special character range end */
          if (range_end == '\\')
          {
            range_end = *++p;

            /* if end of text then
               we have a bad pattern */
            if (!range_end)
              return MATCH_PATTERN;
          }

          /* move just beyond this range */
          p++;
        }

        /* if the text character is in range then match found.
           make sure the range letters have the proper
           relationship to one another before comparison */

        if (range_start < range_end)
        {
          if (*t >= range_start && *t <= range_end)
          {
            member_match = 1;
            loop = 0;
          }
        }
        else
        {
          if (*t >= range_end && *t <= range_start)
          {
            member_match = 1;
            loop = 0;
          }
        }
      }

      /* if there was a match in an exclusion set then no match */
      /* if there was no match in a member set then no match */

      if ((invert && member_match) || !(invert || member_match))
        return MATCH_RANGE;

      /* if this is not an exclusion then skip the rest of
         the [...] construct that already matched. */

      if (member_match)
      {
        while (*p != ']')
        {
          /* bad pattern (Missing ']') */
          if (!*p)
            return MATCH_PATTERN;

          /* skip exact match */
          if (*p == '\\')
          {
            p++;

            /* if end of text then
               we have a bad pattern */

            if (!*p)
              return MATCH_PATTERN;
          }

          /* move to next pattern char */

          p++;
        }
      }
      break;
    }
    case '\\':  /* next character is quoted and must match exactly */

      /* move pattern pointer to quoted char and fall through */

      p++;

      /* if end of text then we have a bad pattern */

      if (!*p)
        return MATCH_PATTERN;

      /* must match this character exactly */

    default:
      if (*p != *t)
        return MATCH_LITERAL;
    }
  }
  /* if end of text not reached then the pattern fails */

  if (*t)
    return MATCH_END;
  else  return MATCH_VALID;
}
Exemplo n.º 2
0
static int matche(register char *p, register char *t)
{
   register char range_start, range_end;

   BOOLEAN invert;
   BOOLEAN member_match;
   BOOLEAN loop;

   for ( ; *p; p++, t++ ) {
      if (!*t) {
	 return ( *p == '*' && *++p == '\0' ) ? MATCH_VALID : MATCH_ABORT;
      }
      switch ( *p ) {
      case '?':
	 break;
      case '*':
	 return matche_after_star (p, t);
      case '[':
	 {
	    p++;
	    invert = FALSE;
	    if ( *p == '!' || *p == '^') {
	       invert = TRUE;
	       p++;
	    }
	    if ( *p == ']' ) {
	       return MATCH_PATTERN;
	    }

	    member_match = FALSE;
	    loop = TRUE;
	    while ( loop ) {
	       if (*p == ']') {
		  loop = FALSE;
		  continue;
	       }
	       if ( *p == '\\' ) {
		  range_start = range_end = *++p;
	       }
	       else {
		  range_start = range_end = *p;
	       }
	       if (!*p)
		  return MATCH_PATTERN;
	       if (*++p == '-') {
		  range_end = *++p;
		  if (range_end == '\0' || range_end == ']')
		     return MATCH_PATTERN;
		  if (range_end == '\\') {
		     range_end = *++p;
		     if (!range_end)
			return MATCH_PATTERN;
		  }
		  p++;
	       }
	       if ( range_start < range_end ) {
		  if (*t >= range_start && *t <= range_end) {
		     member_match = TRUE;
		     loop = FALSE;
		  }
	       }
	       else {
		  if (*t >= range_end && *t <= range_start) {
		     member_match = TRUE;
		     loop = FALSE;
		  }
	       }
	    }

	    if ((invert && member_match) ||
	       !(invert || member_match))
	       return MATCH_RANGE;
	    if (member_match) {
	       while (*p != ']') {
		  if (!*p)
		     return MATCH_PATTERN;
		  if (*p == '\\') {
		     p++;
		     if (!*p)
			return MATCH_PATTERN;
		  }
		  p++;
	       }
	    }
	    break;
	 }
      default:
	 if (*p != *t)
	    return MATCH_LITERAL;
      }
   }

   if ( *t )
      return MATCH_END;
   else
      return MATCH_VALID;
}