| /* |
| * librdkafka - The Apache Kafka C/C++ library |
| * |
| * Copyright (c) 2016 Magnus Edenhill |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are met: |
| * |
| * 1. Redistributions of source code must retain the above copyright notice, |
| * this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright notice, |
| * this list of conditions and the following disclaimer in the documentation |
| * and/or other materials provided with the distribution. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
| * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| * POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| |
| #include "rd.h" |
| #include "rdregex.h" |
| |
| #if HAVE_REGEX |
| #include <regex.h> |
| struct rd_regex_s { |
| regex_t re; |
| }; |
| |
| #else |
| |
| #include "regexp.h" |
| struct rd_regex_s { |
| Reprog *re; |
| }; |
| #endif |
| |
| |
| /** |
| * @brief Destroy compiled regex |
| */ |
| void rd_regex_destroy (rd_regex_t *re) { |
| #if HAVE_REGEX |
| regfree(&re->re); |
| #else |
| re_regfree(re->re); |
| #endif |
| rd_free(re); |
| } |
| |
| |
| /** |
| * @brief Compile regex \p pattern |
| * @returns Compiled regex object on success on error. |
| */ |
| rd_regex_t * |
| rd_regex_comp (const char *pattern, char *errstr, size_t errstr_size) { |
| rd_regex_t *re = rd_calloc(1, sizeof(*re)); |
| #if HAVE_REGEX |
| int r; |
| |
| r = regcomp(&re->re, pattern, REG_EXTENDED|REG_NOSUB); |
| if (r) { |
| if (errstr) |
| regerror(r, &re->re, errstr, errstr_size); |
| rd_free(re); |
| return NULL; |
| } |
| #else |
| const char *errstr2; |
| |
| re->re = re_regcomp(pattern, 0, &errstr2); |
| if (!re->re) { |
| if (errstr) { |
| strncpy(errstr, errstr2, errstr_size-1); |
| errstr[errstr_size-1] = '\0'; |
| } |
| rd_free(re); |
| return NULL; |
| } |
| #endif |
| |
| return re; |
| } |
| |
| |
| /** |
| * @brief Match \p str to pre-compiled regex \p re |
| * @returns 1 on match, else 0 |
| */ |
| int rd_regex_exec (rd_regex_t *re, const char *str) { |
| #if HAVE_REGEX |
| return regexec(&re->re, str, 0, NULL, 0) != REG_NOMATCH; |
| #else |
| return !re_regexec(re->re, str, NULL, 0); |
| #endif |
| } |
| |
| |
| /** |
| * @brief Perform regex match of \p str using regex \p pattern. |
| * |
| * @returns 1 on match, 0 on non-match or -1 on regex compilation error |
| * in which case a human readable error string is written to |
| * \p errstr (if not NULL). |
| */ |
| int rd_regex_match (const char *pattern, const char *str, |
| char *errstr, size_t errstr_size) { |
| #if HAVE_REGEX /* use libc regex */ |
| regex_t re; |
| int r; |
| |
| /* FIXME: cache compiled regex */ |
| r = regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB); |
| if (r) { |
| if (errstr) |
| regerror(r, &re, errstr, errstr_size); |
| return 0; |
| } |
| |
| r = regexec(&re, str, 0, NULL, 0) != REG_NOMATCH; |
| |
| regfree(&re); |
| |
| return r; |
| |
| #else /* Using regexp.h from minilibs (included) */ |
| Reprog *re; |
| int r; |
| const char *errstr2; |
| |
| /* FIXME: cache compiled regex */ |
| re = re_regcomp(pattern, 0, &errstr2); |
| if (!re) { |
| if (errstr) { |
| strncpy(errstr, errstr2, errstr_size-1); |
| errstr[errstr_size-1] = '\0'; |
| } |
| return -1; |
| } |
| |
| r = !re_regexec(re, str, NULL, 0); |
| |
| re_regfree(re); |
| |
| return r; |
| #endif |
| } |