Example #1
0
static  i4
ad0_cqmatch(
ADULcstate	*pat,	    /* the string holding the pattern matching char */
u_char		*endpat,    /* pointer to end of char string */
ADULcstate	*str,	    /* the other string */
u_char		*endstr,    /* pointer to the end */
bool		bignore)    /* If TRUE, ignored blanks and null chars */
{
    adulnext(pat);

    /* find a non-blank, non-null char in str, if ignoring these */
    if (bignore)
    {
	while (adulptr(str) < endstr)
	{
	    if ((!adulspace(str)  &&  adultrans(str) != 0))
		break;

	    adulnext(str);
	}
    }
    
    if (adulptr(str) < endstr)
    {
	_VOID_ adultrans(str);
	adulnext(str);
	return (ad0_3clexc_pm(pat, endpat, str, endstr, FALSE, bignore));
    }
    else
    {
	return (1);
    }
}
Example #2
0
static	DB_STATUS
ad0_llkqmatch(
ADF_CB		    *adf_scb,
register ADULcstate *sst,
u_char		    *ends,
register ADULcstate *pst,
u_char		    *endp,
ADULcstate	    *est,
bool		    bignore,
i4		    n,
i4		    *rcmp)
{
    adulnext(sst);

    while (adulptr(sst) < ends)
    {
	if (bignore  &&  (adulspace(sst)  || adulisnull(sst)))
	{
	    _VOID_ adultrans(sst);
	    adulnext(sst);
	}
	else
	{
	    _VOID_ adultrans(sst);
	    adulnext(sst);
	    if (!--n)
		return (ad0_llike(adf_scb, sst, ends, pst, endp, est,
							bignore, rcmp));
	}
    }
    *rcmp = -1;	/* string is shorter than pattern */
    return (E_DB_OK);
}
Example #3
0
static  bool
ad0_cpmchk(
ADULcstate	*str,	    /* string to look for PM chars in */
u_char		*endstr)    /* end of str */
{
    ADULcstate	st;

    STRUCT_ASSIGN_MACRO(*str, st);

    while (adulptr(&st) < endstr)
    {
	switch (adultrans(&st)/COL_MULTI)
	{
	  case DB_PAT_ONE:
	  case DB_PAT_ANY:
	  case DB_PAT_LBRAC:	/* Don't want to look for RBRAC */
	    return (TRUE);

	  default:
	    adulnext(&st);
	    break;
	}
    }
    
    return (FALSE);
}
Example #4
0
DB_STATUS
ad0_llike(
ADF_CB		    *adf_scb,
register ADULcstate *sst,
u_char		    *ends,
register ADULcstate *pst,
u_char		    *endp,
ADULcstate	    *est,
bool		    bignore,
i4		    *rcmp)
{
    i4			cc;	/* the `character class' for pch */
    i4			stat;
    u_char		match;  /* the untranslated character */

    for (;;)	/* loop through pattern string */
    {
	int count = 0;
	DB_STATUS (*llkmatch)(ADF_CB *,ADULcstate *,u_char*,ADULcstate*,u_char*,
	                      ADULcstate*,bool,i4,i4*) = ad0_llkpmatch;
	/*
	** Get the next character from the pattern string,
	** handling escape sequences, and ignoring blanks if required.
	** -----------------------------------------------------------
	*/
	if (adulptr(pst) >= endp)
	{
	    /* end of pattern string */
	    cc = AD_CC6_EOS;
	}
	else
	{
	    if (est != NULL && !adulcmp(pst, est))
	    {
		adulnext(pst);
		/* we have an escape sequence */
		if (adulptr(pst) >= endp)
		{
		    /* ERROR:  escape at end of pattern string not allowed */
		    return (adu_error(adf_scb, E_AD1017_ESC_AT_ENDSTR, 0));
		}
		match = *(pst->lstr);
		_VOID_ adultrans(pst); /* increment pointer, ignore return */
		switch (match) /* the RAW character value */
		{
		  case AD_1LIKE_ONE:
		  case AD_2LIKE_ANY:
		  case '-':
		    cc = AD_CC0_NORMAL;
		    break;

		  case AD_3LIKE_LBRAC:
		    cc = AD_CC4_LBRAC;
		    break;

		  case AD_4LIKE_RBRAC:
		    cc = AD_CC5_RBRAC;
		    break;

		  default:
		    if (!adulcmp(pst, est))
			cc = AD_CC0_NORMAL;
		    else
			/* ERROR:  illegal escape sequence */
			return (adu_error(adf_scb, E_AD1018_BAD_ESC_SEQ, 0));
		    break;
		}
	    }
	    else
	    {
		/* not an escape character */
		match = *(pst->lstr);
		_VOID_ adultrans(pst); /* increment pointer, ignore return */
		switch (match) /* the RAW character value */
		{
		  case AD_1LIKE_ONE:
		    cc = AD_CC2_ONE;
		    break;

		  case AD_2LIKE_ANY:
		    cc = AD_CC3_ANY;
		    break;

		  case '-':
		    cc = AD_CC1_DASH;
		    break;

		  case AD_3LIKE_LBRAC:
		  case AD_4LIKE_RBRAC:
		  default:
		    cc = AD_CC0_NORMAL;
		    break;
		}
	    }
	}

	if (	bignore
	    &&	cc == AD_CC0_NORMAL
	    &&	(adulspace(pst)  || adulisnull(pst))
	   )
	{
	    adulnext(pst);
	    continue;	/* ignore blanks and null chars for the C datatype */
	}


	/* Now we have the next pattern string character and its class */
	/* ----------------------------------------------------------- */

	switch (cc)
	{
	  case AD_CC0_NORMAL:
	  case AD_CC1_DASH:
	    for (;;)
	    {
		if (adulptr(sst) >= ends)
		{
		    *rcmp = -1;	/* string is shorter than pattern */
		    return (E_DB_OK);
		}
		if (!bignore  ||  (!adulspace(sst)  && !adulisnull(sst)))
		    break;
		    
		adulnext(sst);
	    }

	    if ((stat = adulcmp(sst, pst)) != 0)
	    {
		*rcmp = stat;
		return (E_DB_OK);
	    }
	    break;

	  case AD_CC2_ONE:
		count = 1;
		adulnext(pst);
		llkmatch = ad0_llkqmatch;
		/*FALLTHROUGH*/
	  case AD_CC3_ANY:
	    while (adulptr(pst) < endp)
	    {
		match = *(pst->lstr);
		if (match == AD_1LIKE_ONE)
		{
		    _VOID_ adultrans(pst); /* increment pointer, ignore return */
		    count++;
		}
		else if (match == AD_2LIKE_ANY)
		{
		    _VOID_ adultrans(pst); /* increment pointer, ignore return */
		    llkmatch = ad0_llkpmatch;
		}
		else if (!bignore || !adulspace(pst) && !adulisnull(pst))
		    break;
		adulnext(pst);
	    }
	    return llkmatch(adf_scb, sst, ends, pst, endp,
					est, bignore, count, rcmp);

	  case AD_CC4_LBRAC:
	    return (ad0_llklmatch(adf_scb, sst, ends, pst, endp,
					est, bignore, rcmp));

	  case AD_CC5_RBRAC:
	    /*
	    ** ERROR:  bad range specification.
	    */
	    return (adu_error(adf_scb, E_AD1015_BAD_RANGE, 0));

	  case AD_CC6_EOS:
	    /*
	    ** End of pattern string.  Check for rest of other string.
	    */
	    while (adulptr(sst) < ends)
	    {
		if (!bignore  ||  (!adulspace(sst)  && !adulisnull(sst)))
		{
		    *rcmp = 1;	    /* string is longer than pattern */
		    return (E_DB_OK);
		}
		adulnext(sst);
	    }
	    *rcmp = 0;
	    return (E_DB_OK);

	  default:
	    /*
	    ** ERROR:  should *NEVER* get here.
	    */
	    return (adu_error(adf_scb, E_AD9999_INTERNAL_ERROR, 0));
	}
	adulnext(pst);
    	adulnext(sst);

    }
}
Example #5
0
static  i4
ad0_clmatch(
ADULcstate	*pat,	    /* the string holding the pattern matching char */
u_char		*endpat,    /* end of the pattern string */
ADULcstate	*str,	    /* the other string */
u_char		*endstr,    /* end of the string */
bool		bignore)    /* If TRUE, ignore blanks and null chars */
{
    i4			oldc;
    i4			found;
    i4			bfound;
    i4			ret_val = -1;
    auto ADULcstate	sst, pst;

    oldc = 0;

    adulnext(pat);

    /* Look for an empty range, if found, just ignore it */
    while (adulptr(pat) < endpat)
    {
	if (adultrans(pat)/COL_MULTI == DB_PAT_RBRAC)
	{
	    /* empty range, ignore it */
	    adulnext(pat);
	    return (ad0_3clexc_pm(pat, endpat, str, endstr, FALSE, bignore));
	}
	else
	{
	    if (bignore && (adulspace(pat)  || adultrans(pat) == 0))
		adulnext(pat);
	    else
		break;
	}
    }


    /* find a non-blank, non-null char in s, if ignoring these */
    while (adulptr(str) < endstr)
    {
	if (bignore && (adulspace(str)  || adultrans(str) == 0))
	{
	    adulnext(str);
	    continue;
	}

	/* search for a match on 'c' */
	found = 0;	/* assume failure */
	bfound = 0;	/* assume failure */

	while (adulptr(pat) < endpat)
	{
	    switch(adultrans(pat)/COL_MULTI)
	    {
	      case DB_PAT_RBRAC:
		{
		    adulnext(pat);
		    if (bfound)
		    {   /*
			** Since we found a blank or null char in the pattern
			** range, and blanks and null chars are being ignored,
			** try this first to see if the two are equal by
			** ignoring the range altogether.
			*/
			STRUCT_ASSIGN_MACRO(*pat, pst);
			STRUCT_ASSIGN_MACRO(*str, sst);
			ret_val = ad0_3clexc_pm(&pst, endpat,
						&sst, endstr, FALSE, bignore);
		    }

		    if (ret_val != 0  && found)
		    {
			adulnext(str);
			ret_val = ad0_3clexc_pm(pat, endpat,
						str, endstr, FALSE, bignore);
		    }
		    return (ret_val);
		}

	      case AD_DASH_CHAR:
		if (oldc == 0 || (adulnext(pat), adulptr(pat) >= endpat))
		    return (-1);    /* not found ... really an error */
	    
		if (oldc - adultrans(str) <= 0 && adulcmp(pat, str) >= 0)
		    found++;
		break;

	      default:
		oldc = adultrans(pat);

		if (bignore && (adulspace(pat) || oldc == 0))
		    bfound++;

		if (adultrans(str) == oldc)
		    found++;
	    }
	    adulnext(pat);
	}
	return (-1);    /* no match ... this should actually be an error,
			** because if we reach here, we would have an LBRAC
			** without an associated RBRAC.
			*/
    }
    return (1);
}
Example #6
0
static  i4
ad0_cpmatch(
ADULcstate      *pat,       /* the string holding the pattern matching char */
u_char	    	*endpat,    /* pointer to end of pattern char string */
ADULcstate	*str,       /* the string to be checked */
u_char	    	*endstr,    /* pointer to end of string */
bool		bignore)    /* if TRUE, we ignore blanks and null chars */
{
    ADULcstate	    psave;
    ADULcstate	    ssave;
    u_i4	    c;
    u_i4	    d;

    adulnext(pat);

    /*
    ** Skip over blanks and null chars if requested -- This fixes a
    ** bug where "a* " would not match "aaa".  The extra space after
    ** the '*' is often put in by EQUEL programs.
    */
    while (    adulptr(pat) < endpat
	    && bignore
	    && (adulspace(pat)  ||  (c = adultrans(pat)) == 0)
	  )
    {
        adulnext(pat);
    }

    if (adulptr(pat) >= endpat)
        return  (0);    /* a match if no more chars in p */

    /*
    ** If the next character in "pat" is not another
    ** pattern matching character, then scan until
    ** first matching char and continue comparison.
    */
    c = adultrans(pat)/COL_MULTI;
    if (c != DB_PAT_ANY && c != DB_PAT_LBRAC && c != DB_PAT_ONE)
    {
        while (adulptr(str) < endstr)
        {
            d = adultrans(str)/COL_MULTI;
            if (    adulcmp(pat, str) == 0
		||  d == DB_PAT_ANY
		||  d == DB_PAT_LBRAC
		||  d == DB_PAT_ONE
	       )
            {
		STRUCT_ASSIGN_MACRO(*pat, psave);
		STRUCT_ASSIGN_MACRO(*str, ssave);
                if (ad0_3clexc_pm(&psave, endpat, &ssave, endstr,
				  FALSE, bignore) == 0)
                    return (0);
            }
            adulnext(str);
        }
    }
    else
    {
        while (adulptr(str) < endstr)
	{
	    STRUCT_ASSIGN_MACRO(*pat, psave);
	    STRUCT_ASSIGN_MACRO(*str, ssave);
            if (ad0_3clexc_pm(&psave, endpat, &ssave, endstr,
			      FALSE, bignore) == 0)
                return (0); /* match */
	    _VOID_ adultrans(str);
	    adulnext(str);
	}
    }
    return (-1);    /* no match */
}
Example #7
0
i4
ad0_3clexc_pm(
register ADULcstate *str1,
u_char		    *endstr1,
register ADULcstate *str2,
u_char		    *endstr2,
bool		    bpad,
bool		    bignore)
{
    u_i4	    ch1;
    u_i4	    ch2;
    i4		    stat;
    bool	    have_bpadded = FALSE;
    u_char	    blank = AD_BLANK_CHAR;


loop:
    while (adulptr(str1) < endstr1)
    {
	ch1 = adultrans(str1);

	switch (ch1/COL_MULTI)
	{
	  case DB_PAT_ONE:
	    if (have_bpadded)
		return (1);	/* must have bpadded str2 */
	    else
		return (ad0_cqmatch(str1, endstr1, str2, endstr2, bignore));

	  case DB_PAT_ANY:
	    if (have_bpadded)
		return (1);	/* must have bpadded str2 */
	    else
		return (ad0_cpmatch(str1, endstr1, str2, endstr2, bignore));

	  case DB_PAT_LBRAC:
	    if (have_bpadded)
		return (1);	/* must have bpadded str2 */
	    else
		return (ad0_clmatch(str1, endstr1, str2, endstr2, bignore));

	  case NULLCHAR:
	    if (bignore)
		break;

	    /* else, fall thru to `default:' */

	  default:
	    if (bignore && adulspace(str1))
		break;
		
            while (adulptr(str2) < endstr2)
            {
		ch2 = adultrans(str2);

		switch (ch2/COL_MULTI)
		{
		  case DB_PAT_ONE:
		    if (have_bpadded)
			return (-1);	/* must have bpadded str1 */
		    else
			return (-ad0_cqmatch(str2,
					    endstr2, str1, endstr1, bignore));

		  case DB_PAT_ANY:
		    if (have_bpadded)
			return (-1);	/* must have bpadded str1 */
		    else
			return (-ad0_cpmatch(str2,
					    endstr2, str1, endstr1, bignore));

		  case DB_PAT_LBRAC:
		    if (have_bpadded)
			return (-1);	/* must have bpadded str1 */
		    else
			return (-ad0_clmatch(str2,
					    endstr2, str1, endstr1, bignore));

		  case NULLCHAR:
		    if (bignore)
		    {
			adulnext(str2);
			continue;
		    }
		    /* else, fall thru to `default:' */

		  default:
		    if (bignore && adulspace(str2))
		    {
			adulnext(str2);
			continue;
		    }
		    
                    if ((stat = ch1 - ch2) == 0)
		    {
			adulnext(str1);
			adulnext(str2);
                        goto loop;
		    }
		    else
		    {
			return (stat);
		    }
                }
            }

	    /* string 2 is out of characters, string 1 still has some */
	    /* examine remainder of string 1 for any characters */
	    while (adulptr(str1) < endstr1)
	    {
		ch1 = adultrans(str1);
		switch (ch1/COL_MULTI)
		{
		  case DB_PAT_ONE:
		    return (1);		/* must have bpadded str2 */

		  case DB_PAT_ANY:
		    if (have_bpadded)
			return (1);	/* must have bpadded str2 */
		    else
			bpad = FALSE;
		    continue;

		  case DB_PAT_LBRAC:
		    if (have_bpadded)
			return (1);	/* must have bpadded str2 */
		    else
			return (ad0_clmatch(str1, endstr1, str2, endstr2, 
					    bignore));

		  case NULLCHAR:
		    adulnext(str1);
		    if (bignore)
			continue;
		    if (bpad  &&  !ad0_cpmchk(str1, endstr1))
			return (-1);	/* nullchar < padded blank */
		    else
			return (1);	/* str1 longer than str2 */

		  default:
		    if (adulspace(str1))
		    {
			adulnext(str1);
			if (bignore)
			    continue;
			if (bpad)
			{
			    have_bpadded = TRUE;
			    continue;	/* blank = blank */
			}
			else
			{
			    return (1);	/* str1 longer than str2 */
			}
		    }
		    else
		    {
			if (    bpad
			    &&  adulccmp(str1, (u_char *)" ") < 0
			    &&  (adulnext(str1), !ad0_cpmchk(str1, endstr1))
			   )
			    return (-1);
			else
			    return (1);	/* str1 longer than str2, or
					** ch1 greater than a blank.
					*/
		    }
		}
	    }
			
	    return (0);	    /* str1 = str2 */
        }
	adulnext(str1);
    }

    /* string 1 is out of characters */
    /* examine remainder of string 2 for any characters */
    while (adulptr(str2) < endstr2)
    {
	ch2 = adultrans(str2);
	switch (ch2/COL_MULTI)
	{
	  case DB_PAT_ONE:
	    return (-1);	/* must have bpadded str1 */

	  case DB_PAT_ANY:
	    adulnext(str2);
	    if (have_bpadded)
		return (-1);	/* must have bpadded str1 */
	    else
		bpad = FALSE;
	    continue;

	  case DB_PAT_LBRAC:
	    if (have_bpadded)
		return (-1);	/* must have bpadded str1 */
	    else
		return (-ad0_clmatch(str2,
			    endstr2, str1, endstr1, bignore));

	  case NULLCHAR:
	    adulnext(str2);
	    if (bignore)
		continue;
	    if (bpad  &&  !ad0_cpmchk(str2, endstr2))
		return (1);	/* blank > nullchar */
	    else
		return (-1);	/* str1 shorter than str2 */

	  default:
	    if (adulspace(str2))
	    {
		adulnext(str2);
		if (bignore)
		    continue;
		if (bpad)
		{
		    have_bpadded = TRUE;
		    continue;	/* blank = blank */
		}
		else
		{
		    return (-1);	/* str1 shorter than str2 */
		}
	    }
	    else
	    {
		if (   bpad
		    && adulccmp(str2, (u_char *)" ") < 0
		    && (adulnext(str2), !ad0_cpmchk(str2, endstr2))
		   )
		    return (1);
		else
		    return (-1);	/* str1 shorter than str2, or
					** ch2 greater than a blank.
					*/
	    }
	}
    }
		
    return (0);	    /* str1 = str2 */
}
Example #8
0
static	DB_STATUS
ad0_llklmatch(
ADF_CB		    *adf_scb,
register ADULcstate *sst,
u_char		    *ends,
register ADULcstate *pst,
u_char		    *endp,
ADULcstate	    *est,
bool		    bignore,
i4		    *rcmp)
{
    ADULcstate		savep;
    i4			cc;
    i4			cur_state = AD_S1_IN_RANGE_DASH_NORM;
    bool		empty_range = TRUE;
    bool		match_found = FALSE;

    adulnext(pst);
    for (;;)
    {
	/*
	** Get the next character from the pattern string,
	** handling escape sequences, and ignoring blanks if required.
	** -----------------------------------------------------------
	*/
	if (adulptr(pst) >= endp)
	{
	    return (adu_error(adf_scb, E_AD1015_BAD_RANGE, 0));
	}
	else
	{
	    if (est != NULL  && !adulcmp(pst, est))
	    {
		/* we have an escape sequence */
		adulnext(pst);
		if (adulptr(pst) >= endp)
		{
		    /* ERROR:  escape at end of pattern string not allowed */
		    return (adu_error(adf_scb, E_AD1017_ESC_AT_ENDSTR, 0));
		}
		switch (adultrans(pst)/COL_MULTI)
		{
		  case AD_1LIKE_ONE:
		  case AD_2LIKE_ANY:
		  case '-':
		    cc = AD_CC0_NORMAL;
		    break;

		  case AD_3LIKE_LBRAC:
		    cc = AD_CC4_LBRAC;
		    break;

		  case AD_4LIKE_RBRAC:
		    cc = AD_CC5_RBRAC;
		    break;

		  default:
		    if (!adulcmp(pst, est))
			cc = AD_CC0_NORMAL;
		    else
			/* ERROR:  illegal escape sequence */
			return (adu_error(adf_scb, E_AD1018_BAD_ESC_SEQ, 0));
		    break;
		}
	    }
	    else
	    {
		/* not an escape character */
		switch (adultrans(pst)/COL_MULTI)
		{
		  case AD_1LIKE_ONE:
		    cc = AD_CC2_ONE;
		    break;

		  case AD_2LIKE_ANY:
		    cc = AD_CC3_ANY;
		    break;

		  case '-':
		    cc = AD_CC1_DASH;
		    break;

		  case AD_3LIKE_LBRAC:
		  case AD_4LIKE_RBRAC:
		  default:
		    cc = AD_CC0_NORMAL;
		    break;
		}
	    }
	}

	if (cc == AD_CC6_EOS)
	    return (adu_error(adf_scb, E_AD1015_BAD_RANGE, 0));

	if (cc == AD_CC2_ONE  ||  cc == AD_CC3_ANY  ||  cc == AD_CC4_LBRAC)
	    return (adu_error(adf_scb, E_AD1016_PMCHARS_IN_RANGE, 0));

	if (	bignore
	    &&	cc == AD_CC0_NORMAL
	    &&	(adulspace(pst)  || adulisnull(pst))
	   )
	{
	    adulnext(pst);
	    continue;	/* ignore blanks and null chars for the C datatype */
	}


	/*
	** Now, we have the next pattern character.  Switch on the current
	** state, then do something depending on what character class
	** the next pattern character falls in.  Note, that we should be
	** guaranteed at this point to have either `NORMAL', `DASH', or `RBRAC'.
	** All other cases have been handled above as error conditions.
	*/

	switch (cur_state)
	{
	  case AD_S1_IN_RANGE_DASH_NORM:
	    switch (cc)
	    {
	      case AD_CC0_NORMAL:
	      case AD_CC1_DASH:
		empty_range = FALSE;
		STRUCT_ASSIGN_MACRO(*pst, savep);
		cur_state = AD_S2_IN_RANGE_DASH_IS_OK;
	        break;

	      case AD_CC5_RBRAC:
		/* end of the range spec, range *MUST* have been empty. */
		adulnext(pst);
		return (ad0_llike(adf_scb, sst, ends, pst, endp,
					    est, bignore, rcmp));

	      default:
		/* should *NEVER* get here */
		return (adu_error(adf_scb, E_AD9999_INTERNAL_ERROR, 0));
	    }
	    break;

	  case AD_S2_IN_RANGE_DASH_IS_OK:
	    switch (cc)
	    {
	      case AD_CC0_NORMAL:
		if (adulptr(sst) < ends && adulcmp(sst, &savep) == 0)
		    match_found = TRUE;
		STRUCT_ASSIGN_MACRO(*pst, savep);
		/* cur_state remains AD_S2_IN_RANGE_DASH_IS_OK */
	        break;

	      case AD_CC1_DASH:
		/* do nothing, but change cur_state */
		cur_state = AD_S3_IN_RANGE_AFTER_DASH;
	        break;

	      case AD_CC5_RBRAC:
		/* end of the range spec, and we have a saved char so range */
		/* was not empty.					    */
		if (adulptr(sst) < ends && adulcmp(sst, &savep) == 0)
		    match_found = TRUE;

		if (match_found)
		{
		    adulnext(sst);
		    adulnext(pst);
		    return (ad0_llike(adf_scb, sst, ends, pst, endp,
					    est, bignore, rcmp));
		}
		*rcmp = -1;	/* if string not in range, call it < pat */
		return (E_DB_OK);

	      default:
		/* should *NEVER* get here */
		return (adu_error(adf_scb, E_AD9999_INTERNAL_ERROR, 0));
	    }
	    break;

	  case AD_S3_IN_RANGE_AFTER_DASH:
	    switch (cc)
	    {
	      case AD_CC0_NORMAL:
		if (adulcmp(&savep, pst) <= 0)
		{
		    if (    adulptr(sst) < ends
			&&  adulcmp(sst, &savep) >= 0
		        &&  adulcmp(sst, pst) <= 0
		       )
		    {
			match_found = TRUE;
		    }
		    cur_state = AD_S4_IN_RANGE_DASH_NOT_OK;
		    break;
		}
		/* fall through to BAD-RANGE ... x-y, where x > y */

	      case AD_CC1_DASH:
	      case AD_CC5_RBRAC:
		return (adu_error(adf_scb, E_AD1015_BAD_RANGE, 0));

	      default:
		/* should *NEVER* get here */
		return (adu_error(adf_scb, E_AD9999_INTERNAL_ERROR, 0));
	    }
	    break;

	  case AD_S4_IN_RANGE_DASH_NOT_OK:
	    switch (cc)
	    {
	      case AD_CC0_NORMAL:
		STRUCT_ASSIGN_MACRO(*pst, savep);
		cur_state = AD_S2_IN_RANGE_DASH_IS_OK;
	        break;

	      case AD_CC1_DASH:
		return (adu_error(adf_scb, E_AD1015_BAD_RANGE, 0));

	      case AD_CC5_RBRAC:
		/* end of the range spec, no saved char, and range was not  */
		/* empty.						    */
		if (match_found)
		{
		    adulnext(sst);
		    adulnext(pst);
		    return (ad0_llike(adf_scb, sst, ends, pst, endp,
					    est, bignore, rcmp));
		}
		*rcmp = -1;	/* if string not in range, call it < pat */
		return (E_DB_OK);

	      default:
		/* should *NEVER* get here */
		return (adu_error(adf_scb, E_AD9999_INTERNAL_ERROR, 0));
	    }
	    break;

	  default:
	    /* should *NEVER* get here */
	    return (adu_error(adf_scb, E_AD9999_INTERNAL_ERROR, 0));
	}
	adulnext(pst);
    }
}
Example #9
0
static	DB_STATUS
ad0_llkpmatch(
ADF_CB		    *adf_scb,
register ADULcstate *sst,
u_char		    *ends,
register ADULcstate *pst,
u_char		    *endp,
ADULcstate	    *est,
bool		    bignore,
i4		    n,
i4		    *rcmp)
{
    DB_STATUS		db_stat;
    ADULcstate		nsst, npst;

    adulnext(sst);

    while (n && adulptr(sst) < ends)
    {
	if (!bignore ||  !adulspace(sst) && !adulisnull(sst))
	    n--;
	_VOID_ adultrans(sst);
	adulnext(sst);
    }

    if (n > 0)
    {
	/* String too short for pattern */
	*rcmp = -1;
	return (E_DB_OK);
    }

    if (adulptr(pst) >= endp)
    {
	/* Last relevant char in pattern was `MATCH-ANY' so we have a match. */
	*rcmp = 0;
	return (E_DB_OK);
    }


    while (adulptr(sst) <= ends)	    /* must be `<=', not just `<' */
    {
	STRUCT_ASSIGN_MACRO(*sst, nsst);
	STRUCT_ASSIGN_MACRO(*pst, npst);

	if (db_stat = ad0_llike(adf_scb, &nsst, ends, &npst, endp,
				    est, bignore, rcmp)
	   )
	    return (db_stat);

	if (*rcmp == 0)
	    return (E_DB_OK);	/* match */

	_VOID_ adultrans(sst);
	adulnext(sst);
    }

    /* Finished with string and no match found ... call it `<' by convention. */
    *rcmp = -1;
    return (E_DB_OK);
}
Example #10
0
/*{
** Name: maketable - compile a collation description
**
** Description:
**	Read a collation description file and create a collation table.
**	The table is a modified TRIE structure with a complete map
**	at the top level and sparse maps below.
**
** Inputs:
**	desfile			collation description filename
**
** Outputs:
**	none
**
**	Returns:
**	    pointer to collation table on success
**	    NULL	on failure
**
**	Exceptions:
**	    none
**
** Side Effects:
**	    none
**
** History:
**      03-may-89 (anton)
**          Created.
**	17-Jun-89 (anton)
**	    Moved to ADU from CL
**	17-Jul-89 (anton)
**	    replace 16 with COL_MULTI and use adulstrinit not aducolinit
**	21-jun-93 (geri)
**	    Added 2 bugfixes which were in the the 6.4 version:
**	    31892: better syntax checking and sane delimiter
**	    handling; 31993: multiple character pattern match
**	    rules were not handled correctly.
**	1-oct-04 (toumi01)
**	    On file-not-found error, make that clear rather than just issuing
**	    a bogus and misleading syntax error message.
**	1-May-2008 (kibro01) b120307
**	    When we find a "+", just check the next character isn't also a "+",
**	    since it ought to be possible to set the collation relative to "+"
**	    by having a line "++1:<".
*/
static ADULTABLE *
maketable(
char	*desfile)
{
    FILE      	*fp;
    i4        	n;
    char     	buf[MAX_LOC];
    u_char     	*s;
    register i4  lno = 0;
    register i4  errcnt = 0;
    i2        	*sp, v, t, tt;
    struct	ADUL_tstate *ts;
    LOCATION   	loc;
    ADULcstate	cs;
 
    STcopy(desfile, buf);
    LOfroms(FILENAME, buf, &loc);
    if (SIopen(&loc, "r", &fp) != OK)
    {
	SIprintf("aducompile: Unable to open input file \"%s\".\n",
		 loc.string );
        return NULL;    
    }

    w.tab.magic = ADUL_MAGIC;
    w.tab.nstate = 0;
    for (n = 0; n < 256; n++)
        w.tab.firstchar[n] = n * COL_MULTI;
 
    while (SIgetrec(buf, sizeof buf, fp) != ENDFILE)
    {
        lno++;
        if (*buf == ':')
        {
            /* line is a comment */
            continue;
        }
        adulstrinit(&w.tab, (u_char*)buf, &cs);
        v = 0;
        sp = NULL;
        while ((t = *(s = adulptr(&cs))) != ':')
        {
	    /* If this is '+', just confirm that the next character isn't,
	    ** since the construction "++1:<" would be fine, setting < as the
	    ** character 1 place beyond + (kibro01) b120307
	    */
            if (t == '+' && (*(s+1) != '+'))
            {
                if (*++s == '*')
                {
                    v = ADUL_SKVAL;
                    while (*++s != ':' && *s != '\n')
                        continue;
                    if (*s == '\n')
                    {
                        /* syntax error: report line and line number  */
                        SIprintf("Syntax error on line %d: %s", lno, buf);
                        errcnt++;
                        s = NULL;
                    }
                    break;
                }
                tt = 0;
                while ((t = *s - '0') <= 9 && t >= 0)
                {
                    tt = tt * 10 + t;
                    s++;
                }
                adulstrinit(&w.tab, s, &cs);
                if (sp == NULL)
                    sp = &v;
                *sp += tt;
                continue;
            }
            if (t == '\n')
            {
                /* syntax error - line has no ':' */
                SIprintf("Syntax error on line %d: %s", lno, buf);
                errcnt++;
                s = NULL;
                break;
            }
            t = adultrans(&cs);
            adulnext(&cs);
            if (sp == NULL)
            {
                v = t;
                sp = &v;
            }
            else
            {
                ts = &w.tab.statetab[w.tab.nstate];
                ts->match = *sp;
                ts->flags = ADUL_LMULT;
                *sp = w.tab.nstate++ | ADUL_TMULT;
                ts->nomatch = t;
                sp = &ts->nomatch;
            }
        }
 
        if (s == NULL)
        {
            /* syntax error occurred */
            continue;	/* to the next line */
        }

        sp = &w.tab.firstchar[255 & *++s];

        ts = NULL;

        if (*s == '\n')
        {
            SIprintf("Syntax error on line %d (no substitution string): %s",
                lno, buf);
            continue;
        }

        while (*++s != '\n')
        {
            while (*sp & ADUL_TMULT)
            {
                ts = &w.tab.statetab[*sp & ADUL_TDATA];
                if (ts->testchr == *s)
                {
                    sp = &ts->match;
                    if (*++s == '\n')
                    {
                        goto done;
                    }
                }
                else
                {
                    sp = &ts->nomatch;
                }
            }
            ts = &w.tab.statetab[w.tab.nstate];
            ts->match = ts->nomatch = *sp;
            *sp = ADUL_TMULT | w.tab.nstate++;
            sp = &ts->match;
            ts->testchr = *s;
            ts->flags = ADUL_FINAL;
        }
    done:
        if (ts)
            ts->flags ^= ADUL_FINAL;
        *sp = v;
    }
 
    if (errcnt == 0)
        return &w.tab;

    return NULL;
}