"Fossies" - the Fresh Open Source Software Archive

Member "glusterfs-8.2/libglusterfs/src/parse-utils.c" (16 Sep 2020, 4770 Bytes) of package /linux/misc/glusterfs-8.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "parse-utils.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2    Copyright 2014-present Facebook. All Rights Reserved
    3 
    4    This file is part of GlusterFS.
    5 
    6    Author :
    7    Shreyas Siravara <shreyas.siravara@gmail.com>
    8 
    9    This file is licensed to you under your choice of the GNU Lesser
   10    General Public License, version 3 or any later version (LGPLv3 or
   11    later), or the GNU General Public License, version 2 (GPLv2), in all
   12    cases as published by the Free Software Foundation.
   13 */
   14 
   15 #include <regex.h>
   16 #include <stdio.h>
   17 
   18 #include "glusterfs/parse-utils.h"
   19 #include "glusterfs/mem-pool.h"
   20 #include "glusterfs/common-utils.h"
   21 #include "glusterfs/libglusterfs-messages.h"
   22 
   23 /**
   24  * parser_init: Initialize a parser with the a string to parse and
   25  * the regex we want to use to parse it.
   26  *
   27  * @complete_str: the string to parse
   28  * @regex       : the regex to use
   29  *
   30  * Notes        : It is up to the caller to call the parser_deinit () function
   31  *                to free the allocated parser.
   32  *
   33  * @return      : success: parser ptr (on successful compilation and allocation)
   34  *              : failure: NULL (on failure to compile regex or allocate memory)
   35  */
   36 struct parser *
   37 parser_init(const char *regex)
   38 {
   39     int rc = 0;
   40     struct parser *parser = NULL;
   41 
   42     parser = GF_MALLOC(sizeof(*parser), gf_common_mt_parser_t);
   43     if (!parser)
   44         goto out;
   45 
   46     parser->regex = gf_strdup(regex);
   47     if (!parser->regex) {
   48         GF_FREE(parser);
   49         parser = NULL;
   50         goto out;
   51     }
   52 
   53     rc = regcomp(&parser->preg, parser->regex, REG_EXTENDED);
   54     if (rc != 0) {
   55         gf_msg(GF_PARSE, GF_LOG_INFO, 0, LG_MSG_REGEX_OP_FAILED,
   56                "Failed to compile regex pattern.");
   57         parser_deinit(parser);
   58         parser = NULL;
   59         goto out;
   60     }
   61     parser->complete_str = NULL;
   62 out:
   63     return parser;
   64 }
   65 
   66 /**
   67  * parser_set_string -- Set the string in the parser that we want to parse.
   68  *                      Subsequent calls to get_next_match () will use this
   69  *                      string along with the regex that the parser was
   70  *                      initialized with.
   71  *
   72  * @parser      : The parser to use
   73  * @complete_str: The string to set in the parser (what we are going parse)
   74  *
   75  * @return: success: 0
   76  *          failure: -EINVAL for NULL args, -ENOMEM for allocation errors
   77  */
   78 int
   79 parser_set_string(struct parser *parser, const char *complete_str)
   80 {
   81     int ret = -EINVAL;
   82 
   83     GF_VALIDATE_OR_GOTO(GF_PARSE, parser, out);
   84     GF_VALIDATE_OR_GOTO(GF_PARSE, complete_str, out);
   85 
   86     parser->complete_str = gf_strdup(complete_str);
   87     GF_CHECK_ALLOC_AND_LOG(GF_PARSE, parser, ret, "Failed to duplicate string!",
   88                            out);
   89 
   90     /* Point the temp internal string to what we just dup'ed */
   91     parser->_rstr = (char *)parser->complete_str;
   92     ret = 0;
   93 out:
   94     return ret;
   95 }
   96 
   97 /**
   98  * parser_unset_string -- Free the string that was set to be parsed.
   99  *                        This function needs to be called after
  100  *                        parser_set_string and parser_get_next_match
  101  *                        in order to free memory used by the string.
  102  *
  103  * @parser      : The parser to free memory in
  104  * @return      : success: 0
  105  *              : failure: -EINVAL on NULL args
  106  */
  107 int
  108 parser_unset_string(struct parser *parser)
  109 {
  110     int ret = -EINVAL;
  111 
  112     GF_VALIDATE_OR_GOTO(GF_PARSE, parser, out);
  113 
  114     GF_FREE(parser->complete_str);
  115     parser->complete_str = NULL; /* Avoid double frees in parser_deinit */
  116     ret = 0;
  117 out:
  118     return ret;
  119 }
  120 
  121 /**
  122  * parser_deinit: Free the parser and all the memory allocated by it
  123  *
  124  * @parser    : Parser to free
  125  *
  126  * @return    : nothing
  127  */
  128 void
  129 parser_deinit(struct parser *ptr)
  130 {
  131     if (!ptr)
  132         return;
  133 
  134     regfree(&ptr->preg);
  135     GF_FREE(ptr->complete_str);
  136     GF_FREE(ptr->regex);
  137     GF_FREE(ptr);
  138 }
  139 
  140 /**
  141  * parser_get_match: Given the parser that is configured with a compiled regex,
  142  * return the next match in the string.
  143  *
  144  * @parser    : Parser to use
  145  *
  146  * @return    : success: Pointer to matched character
  147  *            : failure: NULL
  148  */
  149 char *
  150 parser_get_next_match(struct parser *parser)
  151 {
  152     int rc = -EINVAL;
  153     size_t copy_len = 0;
  154     char *match = NULL;
  155 
  156     GF_VALIDATE_OR_GOTO(GF_PARSE, parser, out);
  157 
  158     rc = regexec(&parser->preg, parser->_rstr, 1, parser->pmatch, 0);
  159     if (rc != 0) {
  160         gf_msg_debug(GF_PARSE, 0, "Could not match %s with regex %s",
  161                      parser->_rstr, parser->regex);
  162         goto out;
  163     }
  164 
  165     copy_len = parser->pmatch[0].rm_eo - parser->pmatch[0].rm_so;
  166 
  167     match = gf_strndup(parser->_rstr + parser->pmatch[0].rm_so, copy_len);
  168     GF_CHECK_ALLOC_AND_LOG(GF_PARSE, match, rc, "Duplicating match failed!",
  169                            out);
  170 
  171     parser->_rstr = &parser->_rstr[parser->pmatch[0].rm_eo];
  172 out:
  173     return match;
  174 }