void vle_aucmd_execute(const char event[], const char path[], void *arg) { size_t i; char canonic_path[PATH_MAX]; canonicalize_path(path, canonic_path, sizeof(canonic_path)); if(!is_root_dir(canonic_path)) { chosp(canonic_path); } for(i = 0U; i < DA_SIZE(autocmds); ++i) { if(strcasecmp(event, autocmds[i].event) == 0 && is_pattern_match(&autocmds[i], canonic_path)) { autocmds[i].handler(autocmds[i].action, arg); } } }
// given a token list .. try to repeatedly match the rules and turning tokens into elements // - when a run through all the rules effects no match, we're done // - for each rule (since highest priority is listed first), do that rule, starting at right and sliding left // - then next match rule // - when a rule does match, call the parse function for it, that swallows some tokens and replaces them with an element // // This is the part where I should go look up Red Dragon or Compiler Design in C again, but what the hell, I'm writing this // silly toy language in 6 hours just for laughs. // void sb_match_reduce ( sb_token_t *tlist[], unsigned char *tmaxp ) { sb_parse_match_rule_t *p = rules; unsigned char i, cmax, start; unsigned char foundmatch; // do we need to set up the rules? if ( rules [ 0 ]._width == 0 ) { sb_setup_match_rules(); } // what do we have? if ( g_sb_debug > 1 ) { unsigned char i; printf ( "Line produced token list:\n" ); for ( i = 0; i < *tmaxp; i++ ) { lex_dump_token ( tlist [ i ] ); } } // token list dump while ( 1 ) { start_rules: foundmatch = 0; // run the rules.. while ( p -> t [ 0 ] != sbt_error ) { if ( p -> _width > *tmaxp ) { // obviously not a match if the rule requirements are longer than the token count } else { // figure out how many checks to do; if there are 7 tokens, and the match-rule is 4 .. // then we have 7-4+1->4 searches; 7-4, 7-5, 7-6, 7-7 cmax = *tmaxp - p -> _width + 1; //printf ( "cmax %d ... *tmaxp %d width %d\n", cmax, *tmaxp, p -> _width ); start = *tmaxp - p -> _width; for ( i = 0; i < cmax; i++ ) { //printf ( "tmax %d p->width %d i %d\n", *tmaxp, p -> _width, i ); if ( is_pattern_match ( tlist, start - i, p ) ) { sb_element_t *node; foundmatch ++; if ( g_sb_debug > 1 ) { printf ( "MATCH %s\n", p -> name ); // dump token list before reduce printf ( "Token list before match reduce\n" ); dump_tlist ( tlist, *tmaxp ); } // call parse_f function; we want to get back a struct or multiple-retval // .. the success code (success, and assume tmax/tlist have been changed // .. or in failure .. a soft fail (keep trying, such as wrong operator to match) if ( p -> parse_f ) { node = p -> parse_f ( tlist, start - i, p ); // it "compiled" to an element? if ( node ) { // i) substitute the returned node in for the token // ii) remove extra consumed tokens // iii) slide remainder to the left to fill the gap // ex: if a match of 4 tokens 'compiled' down to 1 element, we need 1 token slot now (for the new element), and can free up 3 // swap in new element tlist [ start - i ] -> type = sbt_element; tlist [ start - i ] -> data.e = node; // copy remaining tokens over, fill the rest with nil memmove ( &(tlist [ start - i + 1 ]), &(tlist [ start - i + p -> _width ]), MAXMATCHRULETOKENS - start - i + p -> _width ); // TBD: memset to sbt_error anything now off the end, to avoid accidental matches? *tmaxp -= ( p -> _width - 1 ); } else { printf ( "ERROR: Syntax error; parse function couldn't parse tokens\n" ); goto exit_parsing; } // dump token list after reduce if ( g_sb_debug > 1 ) { printf ( "Token list after match reduce\n" ); dump_tlist ( tlist, *tmaxp ); } } // got a parse handler for this rule? goto start_rules; // start over, in case we've spit out new elements that would match higher-precedence rules now.. break; } else { //printf ( "no match: %s\n", p -> name ); } // matched? } // for (working right to left) } // if length is doable at all // next p++; } // while if ( ! foundmatch ) { break; } } // while forever exit_parsing: return; }