Beispiel #1
0
int pmatch_quot(const char **P_PtrPtr, const char **S_PtrPtr, int *Flags)
{
    int result=MATCH_FAIL, OldFlags;
    char P_Char, S_Char;
    const char *OldPos, *ptr;

    P_Char=**P_PtrPtr;
    S_Char=**S_PtrPtr;


    result=pmatch_quot_analyze(P_Char, S_Char);

    switch (result)
    {
    case MATCH_ONE:
        (*P_PtrPtr)++;
        break;

    case MATCH_HEX:
        if (! pmatch_ascii((*P_PtrPtr)+1,S_Char,MATCH_HEX)) return(MATCH_FAIL);
        (*P_PtrPtr)+=2;
        break;

    case MATCH_OCTAL:
        if (! pmatch_ascii((*P_PtrPtr)+1,S_Char,MATCH_OCTAL)) return(MATCH_FAIL);
        (*P_PtrPtr)+=3;
        break;

    case MATCH_SWITCH_ON:
    case MATCH_SWITCH_OFF:
        //some switches need to be applied in order for a pattern to match
        //(like the case-insensitive switch) others should only be applied if
        //it matches. So we apply the switch, but if the subsequent pmatch_char fails
        //we unapply it
        OldFlags=*Flags;
        OldPos=*P_PtrPtr;
        (*P_PtrPtr)++; //go past the + or - to the actual type
        pmatch_switch(**P_PtrPtr, result, Flags);
        (*P_PtrPtr)++;
        result=pmatch_char(P_PtrPtr, S_PtrPtr, Flags);

        if (result==MATCH_FAIL)
        {
            *P_PtrPtr=OldPos;
            *Flags=OldFlags;
        }
        return(result);
        break;

    case MATCH_FAIL:
        return(MATCH_FAIL);
        break;
    }

    return(MATCH_ONE);
}
Beispiel #2
0
int pmatch_quot(char **P_PtrPtr, char **S_PtrPtr, int *Flags)
{
    int result=MATCH_FAIL, OldFlags;
    char P_Char, S_Char, *OldPos;

    P_Char=**P_PtrPtr;
    S_Char=**S_PtrPtr;

    switch (P_Char)
    {
    case 'b':
        if (S_Char=='\b') result=MATCH_ONE;
        break;
    case 'e':
        if (S_Char==27) result=MATCH_ONE;
        break; //escape
    case 'n':
        if (S_Char=='\n') result=MATCH_ONE;
        break;
    case 'r':
        if (S_Char=='\r') result=MATCH_ONE;
        break;
    case 't':
        if (S_Char=='	') result=MATCH_ONE;
        break;
    case 'l':
        if (islower(S_Char)) result=MATCH_ONE;
        break;
    case 'x':
        result=MATCH_HEX;
        break;
    case 'A':
        if (isalpha(S_Char)) result=MATCH_ONE;
        break;
    case 'B':
        if (isalnum(S_Char)) result=MATCH_ONE;
        break;
    case 'D':
        if (isdigit(S_Char)) result=MATCH_ONE;
        break;
    case 'S':
        if (isspace(S_Char)) result=MATCH_ONE;
        break;
    case 'P':
        if (ispunct(S_Char)) result=MATCH_ONE;
        break;
    case 'X':
        if (isxdigit(S_Char)) result=MATCH_ONE;
        break;
    case 'U':
        if (isupper(S_Char)) result=MATCH_ONE;
        break;
    case '+':
        result=MATCH_SWITCH_ON;
        break;
    case '-':
        result=MATCH_SWITCH_OFF;
        break;

    default:
        if (S_Char==P_Char) result=MATCH_ONE;
        break;
    }

    switch (result)
    {
    case MATCH_ONE:
        (*P_PtrPtr)++;
        break;

    case MATCH_HEX:
        if (! pmatch_ascii((*P_PtrPtr)+1,S_Char,MATCH_HEX)) return(MATCH_FAIL);
        (*P_PtrPtr)+=2;
        break;

    case MATCH_OCTAL:
        if (! pmatch_ascii((*P_PtrPtr)+1,S_Char,MATCH_OCTAL)) return(MATCH_FAIL);
        (*P_PtrPtr)+=3;
        break;

    case MATCH_SWITCH_ON:
    case MATCH_SWITCH_OFF:


        //some switches need to be applied in order for a pattern to match
        //(like the case-insensitive switch) others should only be applied if
        //it matches. So we apply the switch, but if the subsequent pmatch_char fails
        //we unapply it
        OldFlags=*Flags;
        OldPos=*P_PtrPtr;
        (*P_PtrPtr)++; //go past the + or - to the actual type
        pmatch_switch(**P_PtrPtr, result, Flags);
        (*P_PtrPtr)++;
        result=pmatch_char(P_PtrPtr, S_PtrPtr, Flags);

        if ((result==MATCH_FAIL) || (result==MATCH_CONT))
        {
            *P_PtrPtr=OldPos;
            *Flags=OldFlags;
        }
        return(result);
        break;

    case MATCH_FAIL:
        if (*Flags & PMATCH_SUBSTR) return(MATCH_CONT);
        return(MATCH_FAIL);
        break;
    }

    return(MATCH_ONE);
}
Beispiel #3
0
int pmatch_process(char *Pattern, char *String, char **Start, char **End, int Flags)
{
    char *P_Ptr, *S_Ptr, *ptr;
    int result;


    P_Ptr=Pattern;
    S_Ptr=String;
    if (Start) *Start=NULL;
    if (End) *End=NULL;


    result=pmatch_char(&P_Ptr, &S_Ptr, &Flags);
    while (*S_Ptr)
    {
        switch (result)
        {
        case MATCH_FAIL:
            return(FALSE);
            break;

        //Match failed, but we're looking for a substring of 'String' so continue searching for match
        case MATCH_CONT:
            P_Ptr=Pattern;
            if (Start) *Start=NULL;
            if (End) *End=NULL;
            break;

        case MATCH_START:
            if (S_Ptr != String) return(FALSE);
            if (Flags & PMATCH_NOTSTART) return(FALSE);
            if (! (Flags & PMATCH_NOEXTRACT))
            {
                if (Start && (! *Start)) *Start=S_Ptr;
            }

            S_Ptr--; //naughty, were are now pointing before String, but the
            //S_Ptr++ below will correct this
            break;


        case MATCH_FOUND:
            if (End && (! (Flags & PMATCH_NOEXTRACT)))
            {
                *End=S_Ptr;
            }
            return(TRUE);
            break;

        //Match many is a special case. We have too look ahead to see if the next char
        //Matches, and thust takes us out of 'match many' howerver, If the call to pmatch_char
        //fails then we have to rewind the pattern pointer to match many's '*' and go round again
        case MATCH_MANY:
            ptr=P_Ptr;
            P_Ptr++;
            result=pmatch_char(&P_Ptr, &S_Ptr, &Flags);
            if (result==MATCH_FAIL) P_Ptr=ptr;
            else if (result==MATCH_CONT) P_Ptr=ptr;
            else if (! (Flags & PMATCH_NOEXTRACT))
            {
                if (Start && (! *Start)) *Start=S_Ptr;
            }
            break;

        case MATCH_ONE:
            if (! (Flags & PMATCH_NOEXTRACT))
            {
                if (Start && (! *Start)) *Start=S_Ptr;
            }
            break;
        }

        S_Ptr++;
        if ((End) && (! (Flags & PMATCH_NOEXTRACT))) *End=S_Ptr;

        result=pmatch_char(&P_Ptr, &S_Ptr, &Flags);
    }

//if pattern not exhausted then we didn't get a match
    if (*P_Ptr) return(FALSE);


    return(TRUE);
}
Beispiel #4
0
//Somewhat ugly, as we need to iterate through the string, so we need it passed as a **
int pmatch_search(char *Pattern, char **S_PtrPtr, char *S_End, char **MatchStart, char **MatchEnd, int *Flags)
{
int result;
char *P_Ptr, *ptr, *S_Start;

	if (MatchStart) *MatchStart=NULL;
	if (MatchEnd) *MatchEnd=NULL;

	P_Ptr=Pattern;
	S_Start=*S_PtrPtr;
	result=pmatch_char(&P_Ptr, S_PtrPtr, Flags);
	while (*S_PtrPtr <= S_End) 
	{
		switch (result)
		{
		case MATCH_FAIL: 
			if (*Flags & PMATCH_SUBSTR) return(MATCH_CONT); 
			return(MATCH_FAIL); 
		break;

		//Match failed, but we're looking for a substring of 'String' so continue searching for match
		case MATCH_CONT: 
			if (! (*Flags & PMATCH_SUBSTR)) return(MATCH_FAIL); 
			//if we were some ways through a pattern before hitting the character
			//that failed the match, then we must rewind to reconsider that character
			//as a fresh match
			//if ((*P_Ptr != *Pattern) && (*Pattern != '^')) (*S_PtrPtr)--;
			if ((*P_Ptr != *Pattern) ) (*S_PtrPtr)--;
			P_Ptr=Pattern; 
		break;

		case MATCH_START:
			if (*Flags & PMATCH_NOTSTART) return(MATCH_FAIL);
			(*S_PtrPtr)--; //naughty, were are now pointing before String, but the
							 //S_Ptr++ below will correct this
		break;


		case MATCH_FOUND:
				if (*Flags & PMATCH_NOEXTRACT) 
				{
					//This is to prevent returning NULL strings in 'MatchStart' and 'MatchEnd'
					if (MatchStart && (! *MatchStart)) *MatchStart=S_Start;
					if (MatchEnd && (! *MatchEnd)) *MatchEnd=*MatchStart;
				}
				//else if (MatchEnd) *MatchEnd=*S_PtrPtr;
			return(MATCH_ONE); 
		break;
		
		//Match many is a special case. We have too look ahead to see if the next char
		//Matches, and thus takes us out of 'match many' howerver, If the call to pmatch_char 
		//fails then we have to rewind the pattern pointer to match many's '*' and go round again
		case MATCH_MANY:
			ptr=P_Ptr;
			P_Ptr++;

			//pmatch_char will think that if we've reached the end of the pattern, then we've got
			//a match, regardless of where we are in the string. However, this is the one case where
			//'*' needs to be a little 'greedy'. If the last item in the pattern was '*' (match many)
			//then we need to continue until we read the end of the string
			if (*P_Ptr=='\0') 
			{
				if (*S_PtrPtr == S_End) result=MATCH_FOUND;
				else result=MATCH_FAIL;
			}
			else 
			{
				if (*S_PtrPtr == S_End) result=MATCH_FAIL;
				else result=pmatch_char(&P_Ptr, S_PtrPtr, Flags);
			}

			if ((result==MATCH_FAIL) || (result==MATCH_CONT)) P_Ptr=ptr;
		break;

		case MATCH_REPEAT:
			result=pmatch_repeat(&P_Ptr, S_PtrPtr, S_End, Flags);
			if (result==MATCH_FAIL)
			{
			if (*Flags & PMATCH_SUBSTR) return(MATCH_CONT); 
			return(MATCH_FAIL); 
			}
		break;
		}

		if ((result==MATCH_CONT) )
		{
			if (MatchStart) *MatchStart=NULL;
			if (MatchEnd) *MatchEnd=NULL;
		}
		else if (! (*Flags & PMATCH_NOEXTRACT))
		{
				if (MatchStart && (*S_PtrPtr >= S_Start) && (! *MatchStart)) *MatchStart=*S_PtrPtr;
				if (MatchEnd && ((*(S_PtrPtr)+1) < S_End)) *MatchEnd=(*S_PtrPtr)+1;
		}

		//Handle 'MATCH_FOUND' in the switch statement, don't iterate further through Pattern or String
		if (result==MATCH_FOUND) continue;	

		(*S_PtrPtr)++;	
		//if (*S_PtrPtr > S_End) break;
		
		result=pmatch_char(&P_Ptr, S_PtrPtr, Flags);
	}

//if pattern not exhausted then we didn't get a match
if (*P_Ptr !='\0') return(MATCH_CONT);

return(MATCH_ONE);
}
Beispiel #5
0
//Somewhat ugly, as we need to iterate through the string, so we need it passed as a **
int pmatch_search(const char **P_PtrPtr, const char **S_PtrPtr, const char *S_End, const char **MatchStart, const char **MatchEnd, int *Flags)
{
    const char *ptr, *S_Start, *P_tmp, *S_tmp;
    int result;

    if (MatchStart) *MatchStart=NULL;
    if (MatchEnd) *MatchEnd=NULL;

    if (*Flags & PMATCH_SUBSTR)
    {
        (*Flags) &= ~PMATCH_SUBSTR;
        (*Flags) |= PMATCH_SHORT;
    }

    S_Start=*S_PtrPtr;
    result=pmatch_char(P_PtrPtr, S_PtrPtr, Flags);
    while (*S_PtrPtr < S_End)
    {
        switch (result)
        {
        case MATCH_FAIL:
            return(MATCH_FAIL);
            break;

        case MATCH_START:
            if (*Flags & PMATCH_NOTSTART) return(MATCH_FAIL);
            (*S_PtrPtr)--; //naughty, were are now pointing before String, but the
            //S_Ptr++ below will correct this
            break;


        //Match many is a special case. We have too look ahead to see if the next char
        //Matches, and thus takes us out of 'match many' howerver, If the call to pmatch_char
        //fails then we have to rewind the pattern pointer to match many's '*' and go round again
        case MATCH_MANY:
            result=pmatch_many(P_PtrPtr, S_PtrPtr, S_End, MatchStart, MatchEnd, Flags);
            if (result==MATCH_FAIL) return(MATCH_FAIL);
            break;

        case MATCH_FOUND:

            if (! (*Flags & PMATCH_NOEXTRACT) )
            {
                //This is to prevent returning NULL strings in 'MatchStart' and 'MatchEnd'
                if (MatchStart && (! *MatchStart)) *MatchStart=S_Start;
                if (MatchEnd && (! *MatchEnd)) *MatchEnd=*MatchStart;
            }
            return(MATCH_ONE);
            break;

        case MATCH_REPEAT:
            result=pmatch_repeat(P_PtrPtr, S_PtrPtr, S_End, Flags);
            if (result==MATCH_FAIL) return(MATCH_FAIL);
            break;
        }


        if (result==MATCH_NEXT) /*do nothing */ ;
        else if (result==MATCH_FOUND) continue;
        else if (! (*Flags & PMATCH_NOEXTRACT))
        {
            if (MatchStart && (*S_PtrPtr >= S_Start) && (! *MatchStart)) *MatchStart=*S_PtrPtr;
            if (MatchEnd && ((*(S_PtrPtr)+1) < S_End)) *MatchEnd=(*S_PtrPtr)+1;
        }

        //Handle 'MATCH_FOUND' in the switch statement, don't iterate further through Pattern or String

        if (**S_PtrPtr != '\0') (*S_PtrPtr)++;

        result=pmatch_char(P_PtrPtr, S_PtrPtr, Flags);
    }

//any number of '*' at the end of the pattern don't count once we've run out of string
//? however does, because '?' is saying 'one character' whereas '*' is zero or more
//while (*P_Ptr=='*') P_Ptr++;

//if pattern not exhausted then we didn't get a match
    if (**P_PtrPtr !='\0') return(MATCH_FAIL);

    return(MATCH_ONE);
}