src/regex_parser.c

changeset 34
fa9bda32de17
parent 29
fa625066ae52
child 36
a7ff583e153f
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/regex_parser.c	Fri Dec 28 15:44:28 2012 +0100
     1.3 @@ -0,0 +1,134 @@
     1.4 +/*
     1.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 
     1.6 + * Copyright 2011 Mike Becker. All rights reserved.
     1.7 + * 
     1.8 + * Redistribution and use in source and binary forms, with or without
     1.9 + * modification, are permitted provided that the following conditions are met:
    1.10 + * 
    1.11 + * 1. Redistributions of source code must retain the above copyright
    1.12 + * notice, this list of conditions and the following disclaimer.
    1.13 + * 
    1.14 + * 2. Redistributions in binary form must reproduce the above copyright
    1.15 + * notice, this list of conditions and the following disclaimer in the
    1.16 + * documentation and/or other materials provided with the distribution.
    1.17 + * 
    1.18 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    1.19 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    1.20 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    1.21 + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
    1.22 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    1.23 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
    1.24 + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
    1.25 + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
    1.26 + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    1.27 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
    1.28 + *
    1.29 + * regex_parser.c
    1.30 + *
    1.31 + *  Created on: 26.01.2012
    1.32 + *      Author: Mike
    1.33 + */
    1.34 +
    1.35 +#include "regex_parser.h"
    1.36 +
    1.37 +regex_parser_t* new_regex_parser_t() {
    1.38 +  regex_parser_t* ret = malloc(sizeof(regex_parser_t));
    1.39 +  if (ret != NULL) {
    1.40 +    ret->pattern_list = new_string_list_t();
    1.41 +    ret->matched_lines = 0;
    1.42 +    ret->pattern_match = 0;
    1.43 +    ret->compiled_patterns = NULL;
    1.44 +    ret->compiled_pattern_count = 0;
    1.45 +  }
    1.46 +  return ret;
    1.47 +}
    1.48 +
    1.49 +void regex_destcomppats(regex_parser_t* parser) {
    1.50 +  if (parser->compiled_patterns != NULL) {
    1.51 +    for (int i = 0 ; i < parser->compiled_pattern_count ; i++) {
    1.52 +      if (parser->compiled_patterns[i] != NULL) {
    1.53 +        free(parser->compiled_patterns[i]);
    1.54 +      }
    1.55 +    }
    1.56 +    free(parser->compiled_patterns);
    1.57 +    parser->compiled_patterns = NULL;
    1.58 +    parser->compiled_pattern_count = 0;
    1.59 +  }
    1.60 +}
    1.61 +
    1.62 +void destroy_regex_parser_t(regex_parser_t* parser) {
    1.63 +  regex_destcomppats(parser);
    1.64 +  destroy_string_list_t(parser->pattern_list);
    1.65 +  free(parser);
    1.66 +}
    1.67 +
    1.68 +bool regex_parser_matching(regex_parser_t* parser) {
    1.69 +  return parser->pattern_match > 0;
    1.70 +}
    1.71 +
    1.72 +int regex_parser_do(regex_parser_t* parser, char* input) {
    1.73 +  int err = REG_NOMATCH;
    1.74 +  if (parser->compiled_pattern_count > 0) {
    1.75 +    regmatch_t match;
    1.76 +
    1.77 +    if (regex_parser_matching(parser)) {
    1.78 +      parser->matched_lines++;
    1.79 +
    1.80 +      err = regexec(parser->compiled_patterns[parser->pattern_match],
    1.81 +          input, 1, &match, 0);
    1.82 +      if (err > 0 && err != REG_NOMATCH) {
    1.83 +        fprintf(stderr, "Regex-Error: 0x%08x", err);
    1.84 +      }
    1.85 +      if (err == 0) {
    1.86 +        parser->pattern_match = 0;
    1.87 +        /* do not match line, if it does not end with the pattern */
    1.88 +        if (match.rm_eo < strlen(input)) {
    1.89 +          parser->matched_lines--;
    1.90 +        }
    1.91 +      }
    1.92 +    } else {
    1.93 +      for (int i = 0 ; i < parser->compiled_pattern_count - 1 ; i += 2) {
    1.94 +        err = regexec(parser->compiled_patterns[i], input, 1, &match, 0);
    1.95 +        if (err > 0 && err != REG_NOMATCH) {
    1.96 +          fprintf(stderr, "Regex-Error: 0x%08x", err);
    1.97 +        }
    1.98 +        if (err == 0) {
    1.99 +          parser->pattern_match = i+1;
   1.100 +          parser->matched_lines = 0;
   1.101 +          /* Check, if end pattern is also in this line */
   1.102 +          regex_parser_do(parser, input);
   1.103 +          /* do not match line, if it does not start with the pattern */
   1.104 +          if (match.rm_so > 0 && parser->matched_lines > 0) {
   1.105 +            parser->matched_lines--;
   1.106 +          }
   1.107 +          break;
   1.108 +        }
   1.109 +      }
   1.110 +    }
   1.111 +  }
   1.112 +  return err;
   1.113 +}
   1.114 +
   1.115 +bool regex_compile_all(regex_parser_t* parser) {
   1.116 +  bool success = true;
   1.117 +  size_t pcount = parser->pattern_list->count;
   1.118 +  if (pcount > 0) {
   1.119 +    regex_destcomppats(parser);
   1.120 +    parser->compiled_patterns = calloc(pcount, sizeof(regex_t));
   1.121 +    parser->compiled_pattern_count = pcount;
   1.122 +
   1.123 +    regex_t* re;
   1.124 +    for (int i = 0 ; i < pcount ; i++) {
   1.125 +      re = malloc(sizeof(regex_t));
   1.126 +      if (regcomp(re, parser->pattern_list->items[i], REG_EXTENDED) == 0) {
   1.127 +        parser->compiled_patterns[i] = re;
   1.128 +      } else {
   1.129 +        fprintf(stderr, "Cannot compile pattern: %s\n",
   1.130 +            (parser->pattern_list->items[i]));
   1.131 +        parser->compiled_patterns[i] = NULL;
   1.132 +        success = false;
   1.133 +      }
   1.134 +    }
   1.135 +  }
   1.136 +  return success;
   1.137 +}

mercurial