/* Converts an attribute string into an attr struct. * * Note that the attribute string is trashed. * * Returns: * SLP_PARAMETER_BAD -- If there is a parse error in the attribute string. * SLP_OK -- If everything went okay. */ SLPError attr_destringify( struct xx_SLPAttributes *slp_attr, char *str, SLPInsertionPolicy policy ) { char *cur; /* Current index into str. */ enum { /* Note: everything contained in []s in this enum is a production from * RFC 2608's grammar defining attribute lists. */ START_ATTR /* The start of an individual [attribute]. */, START_TAG /* The start of a [attr-tag]. */, VALUE /* The start of an [attr-val]. */, STOP_VALUE /* The end of an [attr-val]. */ } state = START_ATTR; /* The current state of the parse. */ char *tag; /* A tag that has been parsed. (carries data across state changes)*/ assert(str != NULL); if (strlen(str) == 0) { return SLP_OK; } tag = NULL; cur = str; /***** Pull apart str. *****/ while (*cur) { char *end; /* The end of a parse entity. */ switch (state) { case(START_ATTR): /* At the beginning of an attribute. */ if (strncmp(cur, VAR_PREFIX, VAR_PREFIX_LEN) == 0) { /* At the start of a non-keyword. */ state = START_TAG; cur += VAR_PREFIX_LEN; } else { /* At the start of a keyword: * Gobble up the keyword and set it. */ end = find_tag_end(cur); if (end == NULL) { /* FIXME Ummm, I dunno. */ assert(0); } /*** Check that the tag ends on a legal ending char. ***/ if (*end == ',') { /** Add the keyword. **/ *end = '\0'; SLPAttrSet_keyw((SLPAttributes)slp_attr, cur); cur = end + 1; break; } else if (*end == '\0') { SLPAttrSet_keyw((SLPAttributes)slp_attr, cur); return SLP_OK; /* FIXME Return success. */ break; } else { return SLP_PARAMETER_BAD; /* FIXME Return error code. -- Illegal tag char */ } } break; case(START_TAG): /* At the beginning of a tag, in brackets. */ end = find_tag_end(cur); if (end == NULL) { return SLP_PARAMETER_BAD; /* FIXME Err. code -- Illegal char. */ } if (*end == '\0') { return SLP_PARAMETER_BAD; /* FIXME err: Premature end. */ } /*** Check the the end character is valid. ***/ if (strncmp(end, VAR_INFIX, VAR_INFIX_LEN) == 0) { size_t len = end - cur; /* Note that end is on the character _after_ the last character of the tag (the =). */ assert(tag == NULL); tag = (char *)malloc(len + 1); /* TODO This is incorporated into the corresponding attribute. It is therefore free()'d in the var_free(). */ strncpy(tag, cur, len); tag[len] = '\0'; cur = end + VAR_INFIX_LEN; state = VALUE; } else { /** ERROR! **/ return SLP_PARAMETER_BAD; /* FIXME Err. code.-- Logic error. */ } break; case(VALUE): /* At the beginning of the value portion. */ assert(tag != NULL); /* We should not be able to get into this state is the string is malformed. */ /*** Find the end of the value. ***/ end = find_value_end(cur); /*** Check the validity of the end chararcter. */ if ((strncmp(end, VAR_SUFFIX, VAR_SUFFIX_LEN) == 0) || strncmp(end, VAR_SEPARATOR, VAR_SEPARATOR_LEN) == 0 ) { SLPAttrStore(slp_attr, tag, cur, end - cur, policy); cur = end; state = STOP_VALUE; } else { /*** ERROR! ***/ return SLP_PARAMETER_BAD; /* FIXME err -- invalid value terminator. */ } break; case(STOP_VALUE): /* At the end of a value. */ /***** Check to see which state we should move into next.*****/ /*** Done? ***/ if (*cur == '\0') { return SLP_OK; } /*** Another value? (ie, we're in a value list) ***/ else if (strncmp(cur, VAR_SEPARATOR, VAR_SEPARATOR_LEN)==0) { cur += VAR_SEPARATOR_LEN; state = VALUE; } /*** End of the attribute? ***/ else if (strncmp(cur, VAR_SUFFIX, VAR_SUFFIX_LEN) == 0) { assert(tag != NULL); free(tag); tag = NULL; cur += VAR_SUFFIX_LEN; /*** Are we at string end? ***/ if (*cur == '\0') { return SLP_OK; } /*** Ensure that there is a seperator ***/ if (strncmp(cur, VAR_SEPARATOR, VAR_SEPARATOR_LEN) != 0) { return SLP_PARAMETER_BAD; /* FIXME err -- unexpected character. */ } cur += VAR_SEPARATOR_LEN; state = START_ATTR; } /*** Error. ***/ else { return SLP_PARAMETER_BAD; /* FIXME err -- Illegal char at value end. */ } break; default: printf("Unknown state %d\n", state); } } return SLP_OK; }
void test_predicate() { char *str; int ierr; SLPAttributes slp_attr; SLPError err; /******************** Test int stuff. *********************/ err = SLPAttrAlloc("en", NULL, SLP_FALSE, &slp_attr); assert(err == SLP_OK); SLPAttrSet_int(slp_attr, "int", (int)23, SLP_ADD); SLPAttrSet_int(slp_attr, "int", (int)25, SLP_ADD); SLPAttrSet_int(slp_attr, "int", (int)27, SLP_ADD); /* Test equals. */ str = "(&(&(int=23)(int=25))(int=26))"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > 0); /* False. */ str = "(&(&(int=24)(int=25))(int=26))"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > 0); /* False. */ str = "(&(&(int=24)(int=28))(int=26))"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > 0); /* False. */ str = "(&(&(int=23)(int=25))(int=27))"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* True. */ /* Test greater. */ str = "(int>=29)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > 0); /* f. */ str = "(int>=26)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* T. */ str = "(int>=24)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t. */ str = "(int>=22)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t. */ /* Test lesser. */ str = "(int<=22)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > 0); /* f */ str = "(int<=23)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ SLPAttrFree(slp_attr); /* Simple equality. */ err = SLPAttrAllocStr("en", NULL, SLP_FALSE, &slp_attr, "(a=1)"); assert(err == SLP_OK); str = "(a=1)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ SLPAttrFree(slp_attr); /******************** Test opaque stuff. *********************/ err = SLPAttrAlloc("en", NULL, SLP_FALSE, &slp_attr); assert(err == SLP_OK); err = SLPAttrSet_str(slp_attr, "op", "\\00\\12\\24\\36", SLP_REPLACE); assert(err == SLP_OK); /* Test less (single-valued). */ str = "(op<=\\00\\12\\10\\43)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > 0); /* f */ str = "(op<=\\00\\12\\24\\36)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ str = "(op<=\\00\\12\\24\\36\\12)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ str = "(op>=\\00\\12\\24\\36)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ SLPAttrFree(slp_attr); /******************** Test string stuff. *********************/ err = SLPAttrAlloc("en", NULL, SLP_FALSE, &slp_attr); assert(err == SLP_OK); err = SLPAttrSet_str(slp_attr, "str", "string", SLP_REPLACE); assert(err == SLP_OK); /* Test less (single-valued). */ str = "(str<=a)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > 0); /* f */ str = "(str<=string)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ str = "(str<=strinx)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ /* Test greater (single-valued). */ str = "(str>=a)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ str = "(str>=string)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ str = "(str>=strinx)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > 0); /* f */ /* Test equal (single valued). */ str = "(str=a)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > 0); /* f */ str = "(str=*ing)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ str = "(str=stri*)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ str = "(str=*tri*)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ str = "(str=\\73*)"; /* s* */ ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ str = "(str=\\73\\74\\72\\69*)"; /* stri* */ ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ str = "(str=*\\73\\74\\72\\69*)"; /* *stri* */ ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ str = "(str=s*t*r*i*n*g)"; /* s*t*r*i* */ ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ str = "(str=s*t*r*i*ng)"; /* s*t*r*i* */ ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ str = "(str=\\73\\74\\72\\69ng)"; /* s*t*r*i* */ ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ str = "(str=s*tring)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ str = "(str=\\73*\\74ring)"; /* s*t*r*i* */ ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ /* TODO Test escaped '*'s. */ /* TODO Test multivalued. */ SLPAttrFree(slp_attr); /******************** Test boolean stuff. *********************/ err = SLPAttrAlloc("en", NULL, SLP_FALSE, &slp_attr); assert(err == SLP_OK); err = SLPAttrSet_bool(slp_attr, "bool", SLP_TRUE); assert(err == SLP_OK); /* Test equal. */ str = "(bool=true)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ str = "(bool=false)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > 0); /* f */ /* Test bad strings. */ str = "(bool=falsew)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > 0); /* f */ str = "(bool=*false)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > 0); /* f */ str = "(bool=truee)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > 0); /* f */ str = "(bool= true)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > 0); /* f */ SLPAttrFree(slp_attr); /******************** Test keyword stuff. *********************/ err = SLPAttrAlloc("en", NULL, SLP_FALSE, &slp_attr); assert(err == SLP_OK); err = SLPAttrSet_keyw(slp_attr, "keyw"); assert(err == SLP_OK); /* Test present. */ str = "(keyw=*)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ str = "(keyw=sd)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > 0); /* f */ str = "(keyw<=adf)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > 0); /* f */ SLPAttrFree(slp_attr); /********************* Test boolean operators. *********************/ err = SLPAttrAlloc("en", NULL, SLP_FALSE, &slp_attr); assert(err == SLP_OK); err = SLPAttrSet_keyw(slp_attr, "keyw"); assert(err == SLP_OK); str = "(keyw=*)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ /* Test not. */ str = "(!(keyw=*))"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > 0); /* f */ str = "(!(!(keyw=*)))"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ str = "(!(!(!(keyw=*))))"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > 0); /* f */ str = "(!(!(!(!(keyw=*)))))"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ /* Build up to testing binary ops. */ err = SLPAttrSet_bool(slp_attr, "bool", SLP_TRUE); assert(err == SLP_OK); /* Test and. */ str = "(&(keyw=*)(bool=true))"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ str = "(&(keyw=*)(bool=false))"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > 0); /* f */ str = "(&(keyw=*)(!(bool=false)))"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ str = "(&(keywx=*)(bool=true))"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > 0); /* f */ str = "(&(!(keywx=*))(bool=true))"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ str = "(&(lkeyw=*)(bool=false))"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > 0); /* f */ str = "(&(!(lkeyw=*))(!(bool=false)))"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ str = "(&(&(keyw=*)(bool=true))(&(keyw=*)(bool=true)))"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ str = "(&(&(!(keyw=*))(bool=true))(&(keyw=*)(bool=true)))"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > 0); /* f */ str = "(!(&(&(!(keyw=*))(bool=true))(&(keyw=*)(bool=true))))"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ /* Test sytax errors. */ /* No preceeding bracket. */ str = "asdf=log"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr < 0); /* No trailing bracket. */ str = "(asdf=log"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr < 0); /* Unbalanced brackets. */ str = "(asdf=log))"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr < 0); str = "((asdf=log)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr < 0); /* Missing operators. */ str = "(asdflog)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr < 0); /* Check that the leaf operator isn't causing the problem. */ str = "(asdflog=q)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > 0); /* Missing logical unary. */ str = "((asdflog=q))"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr < 0); /* Missing logical binary. */ str = "((asdflog=q)(asdflog=q))"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr < 0); /* Missing operands and operator. */ str = "()"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr < 0); /* Missing unary operands. */ str = "(!)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr < 0); /* Missing binary operands. */ str = "(&)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr < 0); /* Missing binary operands. */ str = "(=)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr < 0); /* Missing binary operands. I _guess_ this is legal... */ str = "(thingy=)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > -1); /* Trailing trash. */ str = "(&(a=b)(c=d))"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > -1); /* Check that the following test will not be short circuited. */ str = "(a=b)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > 0); /* f */ str = "(|(a=b)(c=d)w)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr < 0); SLPAttrFree(slp_attr); /* Check multiple (more than two) subexpressions. */ err = SLPAttrAlloc("en", NULL, SLP_FALSE, &slp_attr); assert(err == SLP_OK); err = SLPAttrSet_int(slp_attr, "x", 1, SLP_ADD); assert(err == SLP_OK); str = "(&(x=1)(!(x=1)))"; ierr = SLPDPredicateTest((SLPDPredicate)str, slp_attr); assert(ierr > 0); /* f */ str = "(&(x=1))"; ierr = SLPDPredicateTest((SLPDPredicate)str, slp_attr); assert(ierr == 0); /* t */ str = "(&(x=1)(x=1)(x=1))"; ierr = SLPDPredicateTest((SLPDPredicate)str, slp_attr); assert(ierr == 0); /* t */ SLPAttrFree(slp_attr); }