/* * This function is recursive.. I wish I knew a nonrecursive way but * I dont. anyway, recursion is fun.. :) * DO NOT CALL THIS FUNTION WITH A POINTER TO A NULL POINTER * (ie: If *elem is NULL, you're doing it wrong - seg fault) */ void crule_free(struct CRuleNode** elem) { int arg, numargs; if ((*(elem))->funcptr == crule__not) { /* type conversions and ()'s are fun! ;) here have an asprin.. */ if ((*(elem))->arg[0] != NULL) crule_free((struct CRuleNode**) &((*(elem))->arg[0])); } else if ((*(elem))->funcptr == crule__andor) { crule_free((struct CRuleNode**) &((*(elem))->arg[0])); if ((*(elem))->arg[1] != NULL) crule_free((struct CRuleNode**) &((*(elem))->arg[1])); } else { numargs = (*(elem))->numargs; for (arg = 0; arg < numargs; arg++) MyFree((*(elem))->arg[arg]); } #ifdef CR_DEBUG fprintf(stderr, "freeing element at %ld\n", *elem); #endif MyFree(*elem); *elem = 0; }
/* * Grammar * rule: * orexpr END END is end of input or : * orexpr: * andexpr * andexpr || orexpr * andexpr: * primary * primary && andexpr * primary: * function * ! primary * ( orexpr ) * function: * word ( ) word is alphanumeric string, first character * word ( arglist ) must be a letter * arglist: * word * word , arglist */ struct CRuleNode* crule_parse(const char *rule) { const char* ruleptr = rule; int next_tok; struct CRuleNode* ruleroot = 0; int errcode = CR_NOERR; if ((errcode = crule_gettoken(&next_tok, &ruleptr)) == CR_NOERR) { if ((errcode = crule_parseorexpr(&ruleroot, &next_tok, &ruleptr)) == CR_NOERR) { if (ruleroot != NULL) { if (next_tok == CR_END) return (ruleroot); else errcode = CR_UNEXPCTTOK; } else errcode = CR_EXPCTOR; } } if (ruleroot != NULL) crule_free(&ruleroot); #if !defined(CR_DEBUG) && !defined(CR_CHKCONF) Debug((DEBUG_ERROR, "%s in rule: %s", crule_errstr[errcode], rule)); #else fprintf(stderr, "%s in rule: %s\n", crule_errstr[errcode], rule); #endif return 0; }
/** Free all CRules from #cruleConfList. */ void conf_erase_crule_list(void) { struct CRuleConf* next; struct CRuleConf* p = cruleConfList; for ( ; p; p = next) { next = p->next; crule_free(&p->node); MyFree(p->hostmask); MyFree(p->rule); MyFree(p); } cruleConfList = 0; }
int main(void) { char indata[256]; CRuleNode* rule; printf("rule: "); while (fgets(indata, 256, stdin) != NULL) { indata[strlen(indata) - 1] = '\0'; /* lose the newline */ if ((rule = crule_parse(indata)) != NULL) { printf("equivalent rule: "); print_tree((CRuleNodePtr) rule); printf("\n"); crule_free(&rule); } printf("\nrule: "); } printf("\n"); return 0; }