Changeset 437


Ignore:
Timestamp:
11/22/08 00:44:27 (3 years ago)
Author:
mooneer
Message:

Applied patch (ticket #68) by anonymous contributor to fix leaks.

Location:
microregex/trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • microregex/trunk/ChangeLog

    r436 r437  
     111/22/2008: 
     2    * Applied patch (ticket #68) by anonymous contributor to fix leaks. 
     3 
    1411/15/2008: 
    25    * Fixed double free issue by adding reference counting. (ticket #66) 
  • microregex/trunk/microregex.h

    r362 r437  
    5454 * @return The created regular expression object. 
    5555 */ 
    56 microregex_t microregex_create(char *regex); 
     56microregex_t microregex_create(const char *regex); 
    5757 
    5858/** 
     
    9191 */ 
    9292microregex_state_t  
    93 microregex_match(microregex_t regex_obj, char *str, int start); 
     93microregex_match(microregex_t regex_obj, const char *str, int start); 
    9494 
    9595/** 
  • microregex/trunk/microregex_internal.h

    r436 r437  
    5757 
    5858    struct microregex_nfa_t *next1, *next2; 
     59    microregex_nfa_t prevL, nextL; 
    5960}; 
    6061 
     
    6465struct microregex_t 
    6566{ 
    66     char *regex; 
     67    const char *regex; 
    6768    int paren_count; 
    6869    int max_paren_count; 
     
    7071    int case_insensitive; 
    7172    microregex_nfa_t nfa; 
     73    microregex_nfa_t nlist; 
    7274}; 
    7375 
     
    8789    int loop_count; 
    8890    struct microregex_state_t *prev, *next; 
     91    struct microregex_state_t *prevL, *nextL; /* allocation list, used to free all re's */ 
    8992}; 
    9093 
  • microregex/trunk/microregex_matcher.c

    r411 r437  
    3333#include "microregex_internal.h" 
    3434  
     35typedef struct tsmstList tMstList; 
     36 
     37struct tsmstList { 
     38  microregex_state_t *state; 
     39  tMstList *prev; 
     40}; 
     41 
     42 
    3543static microregex_state_t 
    36 microregex_state_new() 
     44microregex_state_new(microregex_state_t *lst) 
    3745{ 
    3846    microregex_state_t ret = malloc(sizeof(struct microregex_state_t)); 
     
    5058    ret->match_end = 0; 
    5159    ret->insensitive = 0; 
     60    if (*lst) { 
     61      ret->prevL = (*lst); 
     62      ret->nextL = (*lst)->nextL; 
     63      if (ret->nextL) ret->nextL->prevL = ret; 
     64      (*lst)->nextL = ret; 
     65    } else { 
     66      ret->prevL = ret->nextL = NULL; 
     67      *lst = ret; 
     68    } 
    5269    return ret; 
    5370} 
    5471 
    5572static microregex_state_t 
    56 microregex_state_clone(microregex_state_t st) 
     73microregex_state_clone_ex(microregex_state_t st, int addToList) 
    5774{ 
    5875    int i; 
     
    7491    ret->loop_count = st->loop_count; 
    7592    ret->insensitive = st->insensitive; 
     93    if (addToList) { 
     94      ret->prevL = st; 
     95      ret->nextL = st->nextL; 
     96      if (ret->nextL) ret->nextL->prevL = ret; 
     97      st->nextL = ret; 
     98    } else ret->prevL = ret->nextL = NULL; 
    7699    return ret; 
    77100} 
    78101 
     102static microregex_state_t 
     103microregex_state_clone(microregex_state_t st) 
     104{ 
     105    return microregex_state_clone_ex(st, 1); 
     106} 
     107 
    79108void 
    80 microregex_state_destroy(microregex_state_t *st) 
    81 { 
     109microregex_state_destroy_ex(microregex_state_t *st, int removeFromList) 
     110{ 
     111    if (!st || !*st) return; 
    82112    int i; 
     113    if (removeFromList) { 
     114      if ((*st)->nextL) (*st)->nextL->prevL = (*st)->prevL; 
     115      if ((*st)->prevL) (*st)->prevL->nextL = (*st)->nextL; 
     116    } 
    83117    free((*st)->se_stack); 
    84118    for (i = 0; i < (*st)->num_ses; i++) 
     
    92126 
    93127 
     128static void microregex_state_destroy_list (microregex_state_t st) { 
     129  if (!st) return; 
     130  while (st->prevL) st = st->prevL; 
     131  while (st) { 
     132    microregex_state_t p = st->nextL; 
     133    microregex_state_destroy_ex(&st, 0); 
     134    st = p; 
     135  } 
     136} 
     137 
     138void microregex_state_destroy (microregex_state_t *st) { 
     139  if (!st || !*st) return; 
     140  microregex_state_destroy_list(*st); 
     141  *st = NULL; 
     142} 
     143 
     144 
     145 
    94146/****************************************************************************** 
    95147 * State machine. 
     
    97149static void 
    98150microregex_regex_push_submatch(microregex_state_t *st_lst, microregex_state_t cur,  
    99                                char *str, char *c); 
     151                               const char *str, const char *c); 
    100152static void 
    101153microregex_regex_pop_submatch(microregex_state_t *st_lst, microregex_state_t cur,  
    102                               char *str, char *c); 
     154                              const char *str, const char *c); 
    103155static void 
    104156microregex_regex_character_class(microregex_state_t *st_lst, microregex_state_t cur,  
    105                                  char *str, char *c); 
     157                                 const char *str, const char *c); 
    106158static void 
    107159microregex_regex_alteration(microregex_state_t *st_lst, microregex_state_t cur,  
    108                             char *str, char *c); 
     160                            const char *str, const char *c); 
    109161static void 
    110162microregex_regex_assert_beginning(microregex_state_t *st_lst, microregex_state_t cur,  
    111                                   char *str, char *c); 
     163                                  const char *str, const char *c); 
    112164static void 
    113165microregex_regex_assert_end(microregex_state_t *st_lst, microregex_state_t cur,  
    114                             char *str, char *c); 
     166                            const char *str, const char *c); 
    115167static void 
    116168microregex_regex_counted_loop(microregex_state_t *st_lst, microregex_state_t cur,  
    117                               char *str, char *c); 
     169                              const char *str, const char *c); 
    118170static void 
    119171microregex_regex_counted_end(microregex_state_t *st_lst, microregex_state_t cur,  
    120                              char *str, char *c); 
     172                             const char *str, const char *c); 
    121173static void 
    122174microregex_regex_counted_begin(microregex_state_t *st_lst, microregex_state_t cur,  
    123                                char *str, char *c); 
     175                               const char *str, const char *c); 
    124176static void 
    125177microregex_regex_pass(microregex_state_t *st_lst, microregex_state_t cur,  
    126                       char *str, char *c); 
     178                      const char *str, const char *c); 
    127179static void 
    128180microregex_regex_word_boundary(microregex_state_t *st_lst, microregex_state_t cur,  
    129                       char *str, char *c); 
     181                      const char *str, const char *c); 
    130182static void 
    131183microregex_regex_backtrack_check(microregex_state_t *st_lst, microregex_state_t cur,  
    132                       char *str, char *c); 
     184                      const char *str, const char *c); 
    133185typedef void  
    134 (*state_machine_func_t)(microregex_state_t *, microregex_state_t, char *, char *); 
     186(*state_machine_func_t)(microregex_state_t *, microregex_state_t, const char *, const char *); 
    135187static state_machine_func_t state_functions[] = { 
    136188    microregex_regex_push_submatch, 
     
    201253static void 
    202254microregex_regex_push_submatch(microregex_state_t *st_lst, microregex_state_t cur,  
    203                                char *str, char *c) 
     255                               const char *str, const char *c) 
    204256{ 
    205257    (void)st_lst; 
     
    225277static void 
    226278microregex_regex_pop_submatch(microregex_state_t *st_lst, microregex_state_t cur,  
    227                               char *str, char *c) 
     279                              const char *str, const char *c) 
    228280{ 
    229281    (void)st_lst; 
     
    243295static void 
    244296microregex_regex_pass(microregex_state_t *st_lst, microregex_state_t cur,  
    245                       char *str, char *c) 
     297                      const char *str, const char *c) 
    246298{ 
    247299    (void)st_lst; 
     
    258310static void 
    259311microregex_regex_backtrack_check(microregex_state_t *st_lst, microregex_state_t cur,  
    260                                  char *str, char *c) 
     312                                 const char *str, const char *c) 
    261313{ 
    262314    char *curstr = cur->ses[cur->state->loop_to]; 
     
    281333static void 
    282334microregex_regex_alteration(microregex_state_t *st_lst, microregex_state_t cur,  
    283                             char *str, char *c) 
     335                            const char *str, const char *c) 
    284336{ 
    285337    (void)st_lst; 
     
    303355static void 
    304356microregex_regex_counted_loop(microregex_state_t *st_lst, microregex_state_t cur,  
    305                              char *str, char *c) 
     357                             const char *str, const char *c) 
    306358{ 
    307359    (void)st_lst; 
     
    334386static void 
    335387microregex_regex_counted_end(microregex_state_t *st_lst, microregex_state_t cur,  
    336                              char *str, char *c) 
     388                             const char *str, const char *c) 
    337389{ 
    338390    (void)st_lst; 
     
    350402static void 
    351403microregex_regex_counted_begin(microregex_state_t *st_lst, microregex_state_t cur,  
    352                                char *str, char *c) 
     404                               const char *str, const char *c) 
    353405{ 
    354406    (void)st_lst; 
     
    367419static void 
    368420microregex_regex_assert_end(microregex_state_t *st_lst, microregex_state_t cur,  
    369                             char *str, char *c) 
     421                            const char *str, const char *c) 
    370422{ 
    371423    (void)st_lst; 
     
    382434static void 
    383435microregex_regex_assert_beginning(microregex_state_t *st_lst, microregex_state_t cur,  
    384                                   char *str, char *c) 
     436                                  const char *str, const char *c) 
    385437{ 
    386438    (void)st_lst; 
     
    396448static void 
    397449microregex_regex_character_class(microregex_state_t *st_lst, microregex_state_t cur,  
    398                                  char *str, char *c) 
     450                                 const char *str, const char *c) 
    399451{ 
    400452    (void)st_lst; 
     
    446498static void 
    447499microregex_regex_word_boundary(microregex_state_t *st_lst, microregex_state_t cur,  
    448                                char *str, char *c) 
     500                               const char *str, const char *c) 
    449501{ 
    450502    int left = 0, right = 0; 
     
    463515    else 
    464516    { 
    465         if (left = !(isalnum(*c) || (*c == '_'))) 
     517        if ((left = !(isalnum(*c) || (*c == '_')))) 
    466518        { 
    467519            right = isalnum(*(c+1)) || (*(c+1) == '_'); 
     
    482534 
    483535microregex_state_t  
    484 microregex_match(microregex_t regex_obj, char *str, int start) 
     536microregex_match(microregex_t regex_obj, const char *str, int start) 
    485537{ 
    486538    microregex_state_t st_lst = NULL; 
    487     microregex_state_t begin = microregex_state_new(); 
     539    microregex_state_t flist = NULL; 
     540    microregex_state_t begin = microregex_state_new(&flist); 
    488541    begin->state = regex_obj->nfa; 
    489542    begin->insensitive = regex_obj->case_insensitive; 
    490543    begin->match_begin = begin->match_end = start; 
    491     microregex_nfa_addstateforward(&st_lst, microregex_state_new()); 
     544    microregex_nfa_addstateforward(&st_lst, microregex_state_new(&flist)); 
    492545    microregex_nfa_addstateforward(&st_lst, begin); 
    493546    microregex_state_t cur = begin, ret = NULL; 
    494     char *curstr = str + start; 
     547    const char *curstr = str + start; 
    495548 
    496549    while(*curstr) 
     
    517570        if (*(curstr + 1)) 
    518571        { 
    519             microregex_state_t newbegin = microregex_state_new(); 
     572            microregex_state_t newbegin = microregex_state_new(&flist); 
    520573            newbegin->state = regex_obj->nfa; 
    521574            newbegin->insensitive = regex_obj->case_insensitive; 
     
    542595        else 
    543596        { 
    544             ret = microregex_state_clone(cur); 
    545             while(st_lst != NULL) 
    546             { 
    547                 cur = st_lst; 
    548                 microregex_nfa_remove(&st_lst); 
    549                 microregex_state_destroy(&cur); 
    550             } 
     597            ret = microregex_state_clone_ex(cur, 0); 
     598            microregex_state_destroy_list(flist); 
    551599            return ret; 
    552600        } 
     
    554602        cur = next; 
    555603    } 
    556      
    557     /* Find longest leftmost match. */ 
    558 #if 0 
    559     int matchstart = strlen(str + start); 
    560     int matchlength = 0; 
    561 #endif 
    562      
    563     while(st_lst != NULL) 
    564     { 
    565         cur = st_lst; 
    566  
    567         /* This might be necessary, but I don't think it is. 
    568          * If there's a bug that requires the following code to fix, I'll remove 
    569          * the #ifdef. */ 
    570 #if 0 
    571         if (cur->state && cur->state->state_type == REGEX_END) 
    572         { 
    573             if (matchstart > cur->match_begin || 
    574                 (matchstart == cur->match_begin && matchlength < strlen(cur->ses[0])) 
    575                ) 
    576             { 
    577                 if (ret) microregex_state_destroy(&ret); 
    578                 ret = microregex_state_clone(cur); 
    579                 matchstart = cur->match_begin; 
    580                 matchlength = strlen(cur->ses[0]); 
    581             } 
    582         } 
    583 #endif 
    584          
    585         microregex_nfa_remove(&st_lst); 
    586         microregex_state_destroy(&cur); 
    587     } 
     604    microregex_state_destroy_list(flist); 
    588605    return ret; 
    589606} 
  • microregex/trunk/microregex_parser.c

    r436 r437  
    3333#include "microregex_internal.h" 
    3434 
    35 microregex_nfa_t microregex_parse_regex(microregex_t, char *, char **, int); 
    36 void microregex_destroy_nfa(microregex_nfa_t *); 
    37  
    38 static void 
     35static microregex_nfa_t microregex_parse_regex(microregex_t, const char *, char **, int, microregex_nfa_t *); 
     36 
     37static int 
    3938microregex_nfa_append(microregex_nfa_t *nfa, microregex_nfa_t end) 
    4039{ 
    4140    if (!*nfa) 
    4241    { 
    43         end->ref++; 
    4442        *nfa = end; 
    45         return; 
    46     } 
    47  
     43        return 1; 
     44    } 
     45    int added = 0; 
    4846    if ((*nfa)->state_type != PASS && (*nfa)->state_type != REGEX_END && (*nfa)->next1 != end) 
    49         microregex_nfa_append(&(*nfa)->next1, end); 
     47        added = microregex_nfa_append(&(*nfa)->next1, end); 
    5048    if ((*nfa)->state_type == ALTERATION || (*nfa)->state_type == COUNTED_LOOP) 
    51         if ((*nfa)->next2 != end) 
    52             microregex_nfa_append(&(*nfa)->next2, end); 
    53 } 
    54  
    55 static microregex_nfa_t 
    56 microregex_nfa_backtrack_check(int backtrack) 
    57 { 
    58     microregex_nfa_t ret = (microregex_nfa_t)malloc(sizeof(struct microregex_nfa_t)); 
     49        if ((*nfa)->next2 != end) { 
     50            int added2 = microregex_nfa_append(&(*nfa)->next2, end); 
     51            added |= added2; 
     52        } 
     53    return added; 
     54} 
     55 
     56 
     57static void microregex_nfa_tolist (microregex_nfa_t ret, microregex_nfa_t *lst) { 
     58  if (*lst) { 
     59    ret->prevL = (*lst); 
     60    ret->nextL = (*lst)->nextL; 
     61    if (ret->nextL) ret->nextL->prevL = ret; 
     62    (*lst)->nextL = ret; 
     63  } else { 
     64    ret->prevL = ret->nextL = NULL; 
     65    *lst = ret; 
     66  } 
     67} 
     68 
     69 
     70static microregex_nfa_t 
     71microregex_nfa_backtrack_check(int backtrack, microregex_nfa_t *lst) 
     72{ 
     73    microregex_nfa_t ret = (microregex_nfa_t)malloc(sizeof(struct microregex_nfa_t)); 
     74    microregex_nfa_tolist(ret, lst); 
    5975    ret->state_type = BACKTRACK_CHECK; 
    6076    ret->character_class = NULL; 
    6177    ret->invert = 0; 
    62     ret->ref = 0; 
    6378    ret->loop_to = backtrack; 
    6479    ret->next1 = NULL; 
     
    6883 
    6984static microregex_nfa_t 
    70 microregex_nfa_alteration(microregex_nfa_t next1, microregex_nfa_t next2) 
    71 { 
    72     microregex_nfa_t ret = (microregex_nfa_t)malloc(sizeof(struct microregex_nfa_t)); 
     85microregex_nfa_alteration(microregex_nfa_t next1, microregex_nfa_t next2, microregex_nfa_t *lst) 
     86{ 
     87    microregex_nfa_t ret = (microregex_nfa_t)malloc(sizeof(struct microregex_nfa_t)); 
     88    microregex_nfa_tolist(ret, lst); 
    7389    ret->state_type = ALTERATION; 
    7490    ret->character_class = NULL; 
    7591    ret->invert = 0; 
    76     ret->ref = 0; 
    7792    ret->next1 = next1; 
    7893    ret->next2 = next2; 
     
    8196 
    8297static microregex_nfa_t 
    83 microregex_nfa_assert_beginning() 
    84 { 
    85     microregex_nfa_t ret = (microregex_nfa_t)malloc(sizeof(struct microregex_nfa_t)); 
     98microregex_nfa_assert_beginning(microregex_nfa_t *lst) 
     99{ 
     100    microregex_nfa_t ret = (microregex_nfa_t)malloc(sizeof(struct microregex_nfa_t)); 
     101    microregex_nfa_tolist(ret, lst); 
    86102    ret->state_type = ASSERT_BEGINNING; 
    87103    ret->character_class = NULL; 
    88104    ret->invert = 0; 
    89     ret->ref = 0; 
    90     ret->next1 = NULL; 
    91     ret->next2 = NULL; 
    92     return ret; 
    93 } 
    94  
    95 static microregex_nfa_t 
    96 microregex_nfa_assert_end() 
    97 { 
    98     microregex_nfa_t ret = (microregex_nfa_t)malloc(sizeof(struct microregex_nfa_t)); 
     105    ret->next1 = NULL; 
     106    ret->next2 = NULL; 
     107    return ret; 
     108} 
     109 
     110static microregex_nfa_t 
     111microregex_nfa_assert_end(microregex_nfa_t *lst) 
     112{ 
     113    microregex_nfa_t ret = (microregex_nfa_t)malloc(sizeof(struct microregex_nfa_t)); 
     114    microregex_nfa_tolist(ret, lst); 
    99115    ret->state_type = ASSERT_END; 
    100116    ret->character_class = NULL; 
    101117    ret->invert = 0; 
    102     ret->ref = 0; 
    103     ret->next1 = NULL; 
    104     ret->next2 = NULL; 
    105     return ret; 
    106 } 
    107  
    108 static microregex_nfa_t 
    109 microregex_nfa_counted_begin() 
    110 { 
    111     microregex_nfa_t ret = (microregex_nfa_t)malloc(sizeof(struct microregex_nfa_t)); 
     118    ret->next1 = NULL; 
     119    ret->next2 = NULL; 
     120    return ret; 
     121} 
     122 
     123static microregex_nfa_t 
     124microregex_nfa_counted_begin(microregex_nfa_t *lst) 
     125{ 
     126    microregex_nfa_t ret = (microregex_nfa_t)malloc(sizeof(struct microregex_nfa_t)); 
     127    microregex_nfa_tolist(ret, lst); 
    112128    ret->state_type = COUNTED_BEGIN; 
    113129    ret->character_class = NULL; 
    114130    ret->invert = 0; 
    115     ret->ref = 0; 
    116     ret->next1 = NULL; 
    117     ret->next2 = NULL; 
    118     return ret; 
    119 } 
    120  
    121 static microregex_nfa_t 
    122 microregex_nfa_counted_loop(int from, int to) 
    123 { 
    124     microregex_nfa_t ret = (microregex_nfa_t)malloc(sizeof(struct microregex_nfa_t)); 
     131    ret->next1 = NULL; 
     132    ret->next2 = NULL; 
     133    return ret; 
     134} 
     135 
     136static microregex_nfa_t 
     137microregex_nfa_counted_loop(int from, int to, microregex_nfa_t *lst) 
     138{ 
     139    microregex_nfa_t ret = (microregex_nfa_t)malloc(sizeof(struct microregex_nfa_t)); 
     140    microregex_nfa_tolist(ret, lst); 
    125141    ret->state_type = COUNTED_LOOP; 
    126142    ret->character_class = NULL; 
    127143    ret->invert = 0; 
    128     ret->ref = 0; 
    129144    ret->loop_from = from; 
    130145    ret->loop_to = to; 
     
    135150 
    136151static microregex_nfa_t 
    137 microregex_nfa_counted_end() 
    138 { 
    139     microregex_nfa_t ret = (microregex_nfa_t)malloc(sizeof(struct microregex_nfa_t)); 
     152microregex_nfa_counted_end(microregex_nfa_t *lst) 
     153{ 
     154    microregex_nfa_t ret = (microregex_nfa_t)malloc(sizeof(struct microregex_nfa_t)); 
     155    microregex_nfa_tolist(ret, lst); 
    140156    ret->state_type = COUNTED_END; 
    141157    ret->character_class = NULL; 
    142158    ret->invert = 0; 
    143     ret->ref = 0; 
    144     ret->next1 = NULL; 
    145     ret->next2 = NULL; 
    146     return ret; 
    147 } 
    148  
    149 static microregex_nfa_t 
    150 microregex_nfa_push_submatch() 
    151 { 
    152     microregex_nfa_t ret = (microregex_nfa_t)malloc(sizeof(struct microregex_nfa_t)); 
     159    ret->next1 = NULL; 
     160    ret->next2 = NULL; 
     161    return ret; 
     162} 
     163 
     164static microregex_nfa_t 
     165microregex_nfa_push_submatch(microregex_nfa_t *lst) 
     166{ 
     167    microregex_nfa_t ret = (microregex_nfa_t)malloc(sizeof(struct microregex_nfa_t)); 
     168    microregex_nfa_tolist(ret, lst); 
    153169    ret->state_type = PUSH_SUBMATCH; 
    154170    ret->character_class = NULL; 
    155171    ret->invert = 0; 
    156     ret->ref = 0; 
    157     ret->next1 = NULL; 
    158     ret->next2 = NULL; 
    159     return ret; 
    160 } 
    161  
    162 static microregex_nfa_t 
    163 microregex_nfa_pop_submatch() 
    164 { 
    165     microregex_nfa_t ret = (microregex_nfa_t)malloc(sizeof(struct microregex_nfa_t)); 
     172    ret->next1 = NULL; 
     173    ret->next2 = NULL; 
     174    return ret; 
     175} 
     176 
     177static microregex_nfa_t 
     178microregex_nfa_pop_submatch(microregex_nfa_t *lst) 
     179{ 
     180    microregex_nfa_t ret = (microregex_nfa_t)malloc(sizeof(struct microregex_nfa_t)); 
     181    microregex_nfa_tolist(ret, lst); 
    166182    ret->state_type = POP_SUBMATCH; 
    167183    ret->character_class = NULL; 
    168184    ret->invert = 0; 
    169     ret->ref = 0; 
    170     ret->next1 = NULL; 
    171     ret->next2 = NULL; 
    172     return ret; 
    173 } 
    174  
    175 static microregex_nfa_t 
    176 microregex_nfa_end() 
    177 { 
    178     microregex_nfa_t ret = (microregex_nfa_t)malloc(sizeof(struct microregex_nfa_t)); 
     185    ret->next1 = NULL; 
     186    ret->next2 = NULL; 
     187    return ret; 
     188} 
     189 
     190static microregex_nfa_t 
     191microregex_nfa_end(microregex_nfa_t *lst) 
     192{ 
     193    microregex_nfa_t ret = (microregex_nfa_t)malloc(sizeof(struct microregex_nfa_t)); 
     194    microregex_nfa_tolist(ret, lst); 
    179195    ret->state_type = REGEX_END; 
    180196    ret->character_class = NULL; 
    181197    ret->invert = 0; 
    182     ret->ref = 0; 
    183     ret->next1 = NULL; 
    184     ret->next2 = NULL; 
    185     return ret; 
    186 } 
    187  
    188 static microregex_nfa_t 
    189 microregex_nfa_pass() 
    190 { 
    191     microregex_nfa_t ret = (microregex_nfa_t)malloc(sizeof(struct microregex_nfa_t)); 
     198    ret->next1 = NULL; 
     199    ret->next2 = NULL; 
     200    return ret; 
     201} 
     202 
     203static microregex_nfa_t 
     204microregex_nfa_pass(microregex_nfa_t *lst) 
     205{ 
     206    microregex_nfa_t ret = (microregex_nfa_t)malloc(sizeof(struct microregex_nfa_t)); 
     207    microregex_nfa_tolist(ret, lst); 
    192208    ret->state_type = PASS; 
    193209    ret->character_class = NULL; 
    194210    ret->invert = 0; 
    195     ret->ref = 0; 
    196     ret->next1 = NULL; 
    197     ret->next2 = NULL; 
    198     return ret; 
    199 } 
    200  
    201 static microregex_nfa_t 
    202 microregex_nfa_oneplus(microregex_nfa_t one, int greedy) 
    203 { 
    204     microregex_nfa_t pass = microregex_nfa_pass(); 
     211    ret->next1 = NULL; 
     212    ret->next2 = NULL; 
     213    return ret; 
     214} 
     215 
     216static microregex_nfa_t 
     217microregex_nfa_oneplus(microregex_nfa_t one, int greedy, microregex_nfa_t *lst) 
     218{ 
     219    microregex_nfa_t pass = microregex_nfa_pass(lst); 
    205220    microregex_nfa_t ret =  
    206221        microregex_nfa_alteration( 
    207222            greedy ? pass : NULL, 
    208223            greedy ? NULL : pass 
    209         ); 
     224        , lst); 
    210225    microregex_nfa_append(&one, ret); 
    211226    pass->next1 = one; 
     
    214229 
    215230static microregex_nfa_t 
    216 microregex_nfa_zeroplus(microregex_nfa_t one, int greedy) 
     231microregex_nfa_zeroplus(microregex_nfa_t one, int greedy, microregex_nfa_t *lst) 
    217232{ 
    218233    microregex_nfa_t ret =  
     
    220235            greedy ? one : NULL,  
    221236            greedy ? NULL : one 
    222         ); 
    223     microregex_nfa_t pass = microregex_nfa_pass(); 
     237        , lst); 
     238    microregex_nfa_t pass = microregex_nfa_pass(lst); 
    224239    microregex_nfa_append(&one, pass); 
    225240    pass->next1 = ret; 
     
    228243 
    229244static microregex_nfa_t 
    230 microregex_nfa_zeroone(microregex_t regex, microregex_nfa_t one, int greedy, int p) 
    231 { 
    232     microregex_nfa_t pass = microregex_nfa_pass(); 
    233     microregex_nfa_t ce = microregex_nfa_counted_end(); 
     245microregex_nfa_zeroone(microregex_t regex, microregex_nfa_t one, int greedy, int p, microregex_nfa_t *lst) 
     246{ 
     247    microregex_nfa_t pass = microregex_nfa_pass(lst); 
     248    microregex_nfa_t ce = microregex_nfa_counted_end(lst); 
    234249 
    235250    microregex_nfa_t parens = NULL; 
    236251    int i; 
    237252    for (i = p; i < regex->max_paren_count; i++) { 
    238         microregex_nfa_append(&parens, microregex_nfa_push_submatch()); 
     253        microregex_nfa_append(&parens, microregex_nfa_push_submatch(lst)); 
    239254    } 
    240255    for (i = regex->max_paren_count; i > p; i--) { 
    241         microregex_nfa_append(&parens, microregex_nfa_pop_submatch()); 
     256        microregex_nfa_append(&parens, microregex_nfa_pop_submatch(lst)); 
    242257    } 
    243258    microregex_nfa_append(&parens, ce); 
     
    247262            greedy ? one : parens,  
    248263            greedy ? parens : one 
    249         ); 
     264        , lst); 
    250265    microregex_nfa_append(&one, pass); 
    251266    pass->next1 = ce; 
     
    253268} 
    254269 
    255 static char * 
    256 microregex_nfa_charliteral_process(char *regex, char *buf) 
     270static const char * 
     271microregex_nfa_charliteral_process(const char *regex, char *buf) 
    257272{ 
    258273    int i, j; 
     
    308323            } 
    309324            case '0': 
    310             { 
    311                 buf[0] = (char)strtol(regex, &regex, 8); 
     325            {   char *tt; 
     326                buf[0] = (char)strtol(regex, &tt, 8); 
     327                regex = tt; 
    312328                break; 
    313329            } 
    314330            case 'x': 
    315             { 
    316                 buf[0] = (char)strtol(regex, &regex, 16); 
     331            {   char *tt; 
     332                buf[0] = (char)strtol(regex, &tt, 16); 
     333                regex = tt; 
    317334                break; 
    318335            } 
     
    399416 
    400417static microregex_nfa_t 
    401 microregex_nfa_charliteral(char *regex, char **end_location) 
    402 { 
    403     microregex_nfa_t ret = (microregex_nfa_t)malloc(sizeof(struct microregex_nfa_t)); 
     418microregex_nfa_charliteral(const char *regex, const char **end_location, microregex_nfa_t *lst) 
     419{ 
     420    microregex_nfa_t ret = (microregex_nfa_t)malloc(sizeof(struct microregex_nfa_t)); 
     421    microregex_nfa_tolist(ret, lst); 
    404422    char tmp_buf[256]; 
    405423 
     
    407425    ret->character_class = NULL; 
    408426    ret->invert = 0; 
    409     ret->ref = 0; 
    410427    ret->next1 = NULL; 
    411428    ret->next2 = NULL; 
     
    417434    if (*regex == '[') 
    418435    { 
    419         char *tmp = regex + 1; 
     436        const char *tmp = regex + 1; 
    420437        if (*tmp == '^')  
    421438        { 
     
    503520             
    504521            ret->state_type = COUNTED_BEGIN; 
    505             microregex_nfa_t bt = microregex_nfa_backtrack_check(backtrack); 
     522            microregex_nfa_t bt = microregex_nfa_backtrack_check(backtrack, lst); 
    506523            ret->next1 = bt; 
    507524        } 
     
    529546 */ 
    530547microregex_t 
    531 microregex_create(char *regex) 
     548microregex_create(const char *regex) 
    532549{ 
    533550    microregex_t ret = (microregex_t)malloc(sizeof(struct microregex_t)); 
     
    536553    ret->regex = regex; 
    537554    ret->err_string = NULL; 
    538     ret->nfa = microregex_parse_regex(ret, regex, NULL, 0); 
    539     microregex_nfa_append(&ret->nfa, microregex_nfa_end()); 
    540  
    541     return ret; 
    542 } 
    543  
    544 /** 
    545  * Destroy regular expression object. 
    546  * @param regex_obj The regular expression object to destroy. 
    547  */ 
    548 void 
    549 microregex_destroy_nfa(microregex_nfa_t *regex_obj) 
    550 { 
    551     if (regex_obj == NULL || (*regex_obj) == NULL) return; 
    552  
    553     if ((*regex_obj)->state_type != PASS) 
    554     { 
    555         microregex_destroy_nfa(&(*regex_obj)->next1); 
    556         microregex_destroy_nfa(&(*regex_obj)->next2); 
    557     } 
    558  
    559     (*regex_obj)->ref--; 
    560     if ((*regex_obj)->ref <= 0) 
    561     { 
    562         free((*regex_obj)->character_class); 
    563         free(*regex_obj); 
    564     } 
    565     *regex_obj = NULL; 
     555    ret->nlist = NULL; 
     556    ret->nfa = microregex_parse_regex(ret, regex, NULL, 0, &ret->nlist); 
     557    microregex_nfa_append(&ret->nfa, microregex_nfa_end(&ret->nlist)); 
     558 
     559    return ret; 
    566560} 
    567561 
     
    576570 
    577571    if ((*regex_obj)->err_string) free((*regex_obj)->err_string); 
    578     if ((*regex_obj)->nfa) microregex_destroy_nfa(&(*regex_obj)->nfa); 
     572 
     573    microregex_nfa_t lst = (*regex_obj)->nlist, nn; 
     574    while (lst) { 
     575      nn = lst->nextL; 
     576      free(lst->character_class); 
     577      free(lst); 
     578      lst = nn; 
     579    } 
     580 
    579581    free(*regex_obj); 
    580582    *regex_obj = NULL; 
     
    599601 * @return The created NFA object. 
    600602 */ 
    601 microregex_nfa_t 
    602 microregex_parse_regex(microregex_t regex_obj, char *regex, char **end_char, int paren_start) 
     603static microregex_nfa_t 
     604microregex_parse_regex(microregex_t regex_obj, const char *regex, char **end_char, int paren_start, microregex_nfa_t *lst) 
    603605{ 
    604606    int cur_paren = regex_obj->paren_count; 
     
    624626                microregex_nfa_append( 
    625627                    &prev, 
    626                     microregex_nfa_push_submatch() 
     628                    microregex_nfa_push_submatch(lst) 
    627629                ); 
    628630                microregex_nfa_append( 
     
    632634                        regex + 1, 
    633635                        &end_location, 
    634                         paren_start + 1 
     636                        paren_start + 1, 
     637                        lst 
    635638                    ) 
    636639                ); 
     
    645648                    microregex_nfa_append( 
    646649                        &prev, 
    647                         microregex_nfa_pop_submatch() 
     650                        microregex_nfa_pop_submatch(lst) 
    648651                    ); 
    649652                } 
     
    666669                        regex + 1, 
    667670                        &end_location, 
    668                         paren_start 
    669                     ) 
     671                        paren_start, 
     672                        lst 
     673                    ), lst 
    670674                ); 
    671675 
     
    683687                    microregex_nfa_oneplus( 
    684688                        prev, 
    685                         greedy 
     689                        greedy, 
     690                        lst 
    686691                    ); 
    687692 
     
    697702                    microregex_nfa_zeroplus( 
    698703                        prev, 
    699                         greedy 
     704                        greedy, 
     705                        lst 
    700706                    ); 
    701707 
     
    713719                        prev, 
    714720                        greedy, 
    715                         cur_paren 
     721                        cur_paren, 
     722                        lst 
    716723                    ); 
    717724 
     
    722729            { 
    723730                /* Counted repetition */ 
    724                 char *cur_pos = regex; 
    725                 int from = strtol(regex + 1, &regex, 10); 
     731                const char *cur_pos = regex; char *tt; 
     732                int from = strtol(regex + 1, &tt, 10); 
     733                regex = tt; 
    726734                int to; 
    727735                if (!*regex || (*regex != ',' && *regex != '}')) 
     
    732740                else if (*regex == ',') 
    733741                { 
    734                     to = strtol(regex + 1, &regex, 10); 
     742                    to = strtol(regex + 1, &tt, 10); 
     743                    regex = tt; 
    735744                    if (*regex != '}') 
    736745                    { 
     
    748757                } 
    749758 
    750                 microregex_nfa_t tmpnfa = microregex_nfa_counted_begin(); 
    751                 microregex_nfa_t counted_loop = microregex_nfa_counted_loop(from, to); 
     759                microregex_nfa_t tmpnfa = microregex_nfa_counted_begin(lst); 
     760                microregex_nfa_t counted_loop = microregex_nfa_counted_loop(from, to, lst); 
    752761                greedy = (*(++regex) != '?'); 
    753                 microregex_nfa_t tmppass = microregex_nfa_pass(); 
     762                microregex_nfa_t tmppass = microregex_nfa_pass(lst); 
    754763                tmppass->next1 = counted_loop; 
    755764 
    756                 counted_loop->next1 = greedy ? prev : microregex_nfa_counted_end(); 
    757                 counted_loop->next2 = greedy ? microregex_nfa_counted_end() : prev; 
     765                counted_loop->next1 = greedy ? prev : microregex_nfa_counted_end(lst); 
     766                counted_loop->next2 = greedy ? microregex_nfa_counted_end(lst) : prev; 
    758767                microregex_nfa_append( 
    759768                    &prev, 
     
    772781                microregex_nfa_append( 
    773782                    &nfa, 
    774                     microregex_nfa_assert_beginning() 
     783                    microregex_nfa_assert_beginning(lst) 
    775784                ); 
    776785                break; 
     
    781790                microregex_nfa_append( 
    782791                    &nfa, 
    783                     microregex_nfa_assert_end() 
     792                    microregex_nfa_assert_end(lst) 
    784793                ); 
    785794                break; 
     
    792801                prev = microregex_nfa_charliteral( 
    793802                    regex, 
    794                     &end_location 
     803                    (const char **)(&end_location), 
     804                    lst 
    795805                ); 
    796  
    797806                regex = end_location; 
    798807            } 
     
    803812 
    804813    if (prev) microregex_nfa_append(&nfa, prev); 
    805     if (end_char) *end_char = regex; 
     814    if (end_char) *end_char = (char *)regex; 
    806815    return nfa; 
    807816} 
Note: See TracChangeset for help on using the changeset viewer.