📄 slpd_predicate.c
字号:
return FR_EVAL_FALSE; } /***** Find text following wildcard *****/ /**** Find end of WCs ****/ text_start = pattern; text_len = 0; while(*text_start == WILDCARD) { text_start++; if(text_start == pattern + pattern_len) { /* No following text. Therefore we match. */ return FR_EVAL_TRUE; } } /**** Find end of text. ****/ found = memchr(text_start, WILDCARD, pattern_len - text_len); if(found == NULL) { /* No trailing WC. Set to end. */ found = pattern + pattern_len; } text_len = found - text_start; /***** Look for the text in the source string *****/ rem_start = str; rem_len = str_len; while(1) { int result; int match_len; found = my_memmem(rem_start, rem_len, text_start, text_len, &match_len); assert(found == NULL || ((found >= rem_start) && (found <= rem_start + rem_len))); if(found == NULL) { /* Desired text is not in the string. */ return FR_EVAL_FALSE; } rem_len = str_len - (found - str); rem_start = found + 1; /**** Make recursive call. ****/ result = wildcard_wc_str(text_start + text_len, (pattern + pattern_len) - (text_start + text_len), found + text_len, rem_len - match_len); if(result != FR_EVAL_FALSE) { return result; } } /*NOTREACHED*/ assert(0);}/*--------------------------------------------------------------------------*/FilterResult wildcard(const char *pattern, int pattern_len, const char *str, int str_len)/* Check the pattern against the given string. Public interface to wildcard *//* functionality. *//* *//* Params: *//* pattern -- the pattern to evaluate *//* pattern_len -- the length of the pattern (in bytes) *//* str -- the string to test the pattern on *//* str_len -- the length of the string *//* *//* Returns: *//* -1 error, 0 success, 1 failure *//* *//* Implementation: *//* This is the interface to wildcard finding. It actually just prepares *//* for repeated calls to wildcard_wc_str() *//*--------------------------------------------------------------------------*/{ char *first_wc; /* Position of the first WC in the pattern. */ int first_wc_len; /* Position of first_wc in pattern. */ int unescaped_first_wc_len; /* Position of first_wc in unescaped version of pattern. */ /***** Check text up to first WC *****/ /**** Get text ****/ first_wc = memchr(pattern, WILDCARD, pattern_len); if(first_wc == NULL) { /* No wc */ return unescape_cmp(pattern, pattern_len, str, str_len, SLP_TRUE, NULL); } else { first_wc_len = first_wc - pattern; } /**** Compare. ****/ unescaped_first_wc_len = first_wc_len; if(first_wc_len > 0) { FilterResult err; err = unescape_cmp(pattern, first_wc_len, str, str_len, SLP_FALSE, &unescaped_first_wc_len); if(err != FR_EVAL_TRUE) { /* The leading text is different. */ return err; } } /***** Start recursive call. *****/ return wildcard_wc_str(first_wc, pattern_len - first_wc_len, (char *)str + unescaped_first_wc_len, str_len - unescaped_first_wc_len);}/*--------------------------------------------------------------------------*/int is_bool_string(const char *str, int str_len, SLPBoolean *val)/* Tests a string to see if it is a boolean. *//*--------------------------------------------------------------------------*/{ if(str_len == 4 && memcmp(str, "true", 4) == 0) /* 4 -> length of string "true" */ { *val = SLP_TRUE; return 1; } if(str_len == 5 && memcmp(str, "false", 5) == 0) /* 5 -> len of "false" */ { *val = SLP_FALSE; return 1; } return 0;}/*--------------------------------------------------------------------------*/typedef enum{ EQUAL, APPROX, GREATER, LESS, PRESENT} Operation;/*--------------------------------------------------------------------------*//*--------------------------------------------------------------------------*/FilterResult int_op(SLPAttributes slp_attr, char *tag, int tag_len, char *rhs, Operation op)/* Perform an integer operation. *//*--------------------------------------------------------------------------*/{ int rhs_val; /* The converted value of rhs. */ char *end; /* Pointer to the end of op. */ var_t *var; /* Pointer to the variable named by tag. */ value_t *value; /* A value in var. */ FilterResult result; /* Value to return. */ assert(op != PRESENT); result = FR_UNSET; /* For verification. */ /* TODO Only do this in debug. */ /***** Verify and convert rhs. *****/ rhs_val = strtol(rhs, &end, 10); if(*end != 0 && *end != BRACKET_CLOSE) { /* Trying to compare an int with a non-int. */ return FR_EVAL_FALSE; } /***** Get variable. *****/ var = attr_val_find_str((struct xx_SLPAttributes *)slp_attr, tag, tag_len); if(var == NULL) { return FR_EVAL_FALSE; } /**** Check type. ****/ if(var->type != SLP_INTEGER) { return FR_EVAL_FALSE; } /***** Compare. *****/ value = var->list; assert(value != NULL); assert(op != PRESENT); switch(op) { case(EQUAL): result = FR_EVAL_FALSE; for(; value; value = value->next) { if(value->data.va_int == rhs_val) { result = FR_EVAL_TRUE; break; } } break; case(APPROX): assert(0); /* TODO: Figure out how this works later. */ result = FR_EVAL_FALSE; break; case(GREATER): result = FR_EVAL_FALSE; for(; value; value = value->next) { if(value->data.va_int >= rhs_val) { result = FR_EVAL_TRUE; break; } } break; case(LESS): result = FR_EVAL_FALSE; for(; value; value = value->next) { if(value->data.va_int <= rhs_val) { result = FR_EVAL_TRUE; break; } } break; default: assert(0); } assert(result != FR_UNSET); return result;}/*--------------------------------------------------------------------------*/FilterResult keyw_op(SLPAttributes slp_attr, char *tag, char *rhs, Operation op)/* Perform a keyword operation. *//*--------------------------------------------------------------------------*/{ /* Note that the only test keywords are allowed to undergo is PRESENT, * also note that PRESENT is handled by our calling function. * * We are therefore quite justified in saying: */ assert(op != PRESENT); return FR_EVAL_FALSE;}/*--------------------------------------------------------------------------*/FilterResult bool_op(SLPAttributes slp_attr, char *tag, int tag_len, char *rhs, int rhs_len, Operation op)/* Perform a boolean operation. *//*--------------------------------------------------------------------------*/{ SLPBoolean rhs_val; /* The value of the rhs. */ var_t *var; FilterResult result; assert(op != PRESENT); result = FR_UNSET; /* Note that the only valid non-PRESENT operator is EQUAL. */ if(op != EQUAL) { return FR_EVAL_FALSE; } /***** Get and check the rhs value. *****/ if(!is_bool_string(rhs, rhs_len, &rhs_val)) { return FR_EVAL_FALSE; } /***** Get the tag value. *****/ var = attr_val_find_str((struct xx_SLPAttributes *)slp_attr, tag, tag_len); if(var == NULL) { return FR_EVAL_FALSE; } /**** Check type. ****/ if(var->type != SLP_BOOLEAN) { return FR_EVAL_FALSE; } /***** Compare. *****/ if(var->list->data.va_bool == rhs_val) { result = FR_EVAL_TRUE; } else { result = FR_EVAL_FALSE; } assert(result != FR_UNSET); return result;}/*--------------------------------------------------------------------------*/FilterResult str_op(SLPAttributes slp_attr, char *tag, int tag_len, char *rhs, int rhs_len, Operation op)/* Perform a string operation. *//*--------------------------------------------------------------------------*/{ char *str_val; /* Converted value of rhs. */ int str_len; /* Length of converted value. */ var_t *var; assert(op != PRESENT); /***** Verify rhs. *****/ str_val = rhs; str_len = rhs_len; /***** Get tag value. *****/ var = attr_val_find_str((struct xx_SLPAttributes *)slp_attr, tag, tag_len); if(var == NULL) { return FR_EVAL_FALSE; } /**** Check type. ****/ if(var->type != SLP_STRING) { return FR_EVAL_FALSE; } /***** Compare. *****/ assert(op != PRESENT); if(op == APPROX) { assert(0); /* TODO: Figure out how this works later. */ } else if(op == EQUAL) { int result; value_t *value; for(value = var->list; value; value = value->next) { result = wildcard(str_val, str_len, value->data.va_str, value->unescaped_len); /* We only keep going if the test fails. Let caller handle other problems. */ if(result != FR_EVAL_FALSE) { return result; } } } else { value_t *value; /* We know that the op must be comparative. */ assert(op == LESS || op == GREATER); for(value = var->list; value; value = value->next) { int result; result = memcmp(value->data.va_str, str_val, MIN(str_len, value->unescaped_len)); if( (result <= 0 && op == LESS) || (result >= 0 && op == GREATER) ) { return FR_EVAL_TRUE; } } } return FR_EVAL_FALSE;}/*--------------------------------------------------------------------------*/FilterResult opaque_op(SLPAttributes slp_attr, char *tag, int tag_len, char *rhs, int rhs_len, Operation op)/* Perform an opaque operation. *//*--------------------------------------------------------------------------*/{ char *str_val; /* Converted value of rhs. */ int str_len; /* Length of converted value. */ var_t *var; assert(op != PRESENT);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -