Esempio n. 1
0
/* 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;
}
Esempio n. 2
0
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);
}