The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/lib/parser.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * lib/parser.c - simple parser for mount, etc. options.
    3  *
    4  * This source code is licensed under the GNU General Public License,
    5  * Version 2.  See the file COPYING for more details.
    6  */
    7 
    8 #include <linux/ctype.h>
    9 #include <linux/types.h>
   10 #include <linux/export.h>
   11 #include <linux/parser.h>
   12 #include <linux/slab.h>
   13 #include <linux/string.h>
   14 
   15 /**
   16  * match_one: - Determines if a string matches a simple pattern
   17  * @s: the string to examine for presence of the pattern
   18  * @p: the string containing the pattern
   19  * @args: array of %MAX_OPT_ARGS &substring_t elements. Used to return match
   20  * locations.
   21  *
   22  * Description: Determines if the pattern @p is present in string @s. Can only
   23  * match extremely simple token=arg style patterns. If the pattern is found,
   24  * the location(s) of the arguments will be returned in the @args array.
   25  */
   26 static int match_one(char *s, const char *p, substring_t args[])
   27 {
   28         char *meta;
   29         int argc = 0;
   30 
   31         if (!p)
   32                 return 1;
   33 
   34         while(1) {
   35                 int len = -1;
   36                 meta = strchr(p, '%');
   37                 if (!meta)
   38                         return strcmp(p, s) == 0;
   39 
   40                 if (strncmp(p, s, meta-p))
   41                         return 0;
   42 
   43                 s += meta - p;
   44                 p = meta + 1;
   45 
   46                 if (isdigit(*p))
   47                         len = simple_strtoul(p, (char **) &p, 10);
   48                 else if (*p == '%') {
   49                         if (*s++ != '%')
   50                                 return 0;
   51                         p++;
   52                         continue;
   53                 }
   54 
   55                 if (argc >= MAX_OPT_ARGS)
   56                         return 0;
   57 
   58                 args[argc].from = s;
   59                 switch (*p++) {
   60                 case 's': {
   61                         size_t str_len = strlen(s);
   62 
   63                         if (str_len == 0)
   64                                 return 0;
   65                         if (len == -1 || len > str_len)
   66                                 len = str_len;
   67                         args[argc].to = s + len;
   68                         break;
   69                 }
   70                 case 'd':
   71                         simple_strtol(s, &args[argc].to, 0);
   72                         goto num;
   73                 case 'u':
   74                         simple_strtoul(s, &args[argc].to, 0);
   75                         goto num;
   76                 case 'o':
   77                         simple_strtoul(s, &args[argc].to, 8);
   78                         goto num;
   79                 case 'x':
   80                         simple_strtoul(s, &args[argc].to, 16);
   81                 num:
   82                         if (args[argc].to == args[argc].from)
   83                                 return 0;
   84                         break;
   85                 default:
   86                         return 0;
   87                 }
   88                 s = args[argc].to;
   89                 argc++;
   90         }
   91 }
   92 
   93 /**
   94  * match_token: - Find a token (and optional args) in a string
   95  * @s: the string to examine for token/argument pairs
   96  * @table: match_table_t describing the set of allowed option tokens and the
   97  * arguments that may be associated with them. Must be terminated with a
   98  * &struct match_token whose pattern is set to the NULL pointer.
   99  * @args: array of %MAX_OPT_ARGS &substring_t elements. Used to return match
  100  * locations.
  101  *
  102  * Description: Detects which if any of a set of token strings has been passed
  103  * to it. Tokens can include up to MAX_OPT_ARGS instances of basic c-style
  104  * format identifiers which will be taken into account when matching the
  105  * tokens, and whose locations will be returned in the @args array.
  106  */
  107 int match_token(char *s, const match_table_t table, substring_t args[])
  108 {
  109         const struct match_token *p;
  110 
  111         for (p = table; !match_one(s, p->pattern, args) ; p++)
  112                 ;
  113 
  114         return p->token;
  115 }
  116 
  117 /**
  118  * match_number: scan a number in the given base from a substring_t
  119  * @s: substring to be scanned
  120  * @result: resulting integer on success
  121  * @base: base to use when converting string
  122  *
  123  * Description: Given a &substring_t and a base, attempts to parse the substring
  124  * as a number in that base. On success, sets @result to the integer represented
  125  * by the string and returns 0. Returns -ENOMEM, -EINVAL, or -ERANGE on failure.
  126  */
  127 static int match_number(substring_t *s, int *result, int base)
  128 {
  129         char *endp;
  130         char *buf;
  131         int ret;
  132         long val;
  133         size_t len = s->to - s->from;
  134 
  135         buf = kmalloc(len + 1, GFP_KERNEL);
  136         if (!buf)
  137                 return -ENOMEM;
  138         memcpy(buf, s->from, len);
  139         buf[len] = '\0';
  140 
  141         ret = 0;
  142         val = simple_strtol(buf, &endp, base);
  143         if (endp == buf)
  144                 ret = -EINVAL;
  145         else if (val < (long)INT_MIN || val > (long)INT_MAX)
  146                 ret = -ERANGE;
  147         else
  148                 *result = (int) val;
  149         kfree(buf);
  150         return ret;
  151 }
  152 
  153 /**
  154  * match_int: - scan a decimal representation of an integer from a substring_t
  155  * @s: substring_t to be scanned
  156  * @result: resulting integer on success
  157  *
  158  * Description: Attempts to parse the &substring_t @s as a decimal integer. On
  159  * success, sets @result to the integer represented by the string and returns 0.
  160  * Returns either -ENOMEM or -EINVAL on failure.
  161  */
  162 int match_int(substring_t *s, int *result)
  163 {
  164         return match_number(s, result, 0);
  165 }
  166 
  167 /**
  168  * match_octal: - scan an octal representation of an integer from a substring_t
  169  * @s: substring_t to be scanned
  170  * @result: resulting integer on success
  171  *
  172  * Description: Attempts to parse the &substring_t @s as an octal integer. On
  173  * success, sets @result to the integer represented by the string and returns
  174  * 0. Returns either -ENOMEM or -EINVAL on failure.
  175  */
  176 int match_octal(substring_t *s, int *result)
  177 {
  178         return match_number(s, result, 8);
  179 }
  180 
  181 /**
  182  * match_hex: - scan a hex representation of an integer from a substring_t
  183  * @s: substring_t to be scanned
  184  * @result: resulting integer on success
  185  *
  186  * Description: Attempts to parse the &substring_t @s as a hexadecimal integer.
  187  * On success, sets @result to the integer represented by the string and
  188  * returns 0. Returns either -ENOMEM or -EINVAL on failure.
  189  */
  190 int match_hex(substring_t *s, int *result)
  191 {
  192         return match_number(s, result, 16);
  193 }
  194 
  195 /**
  196  * match_strlcpy: - Copy the characters from a substring_t to a sized buffer
  197  * @dest: where to copy to
  198  * @src: &substring_t to copy
  199  * @size: size of destination buffer
  200  *
  201  * Description: Copy the characters in &substring_t @src to the
  202  * c-style string @dest.  Copy no more than @size - 1 characters, plus
  203  * the terminating NUL.  Return length of @src.
  204  */
  205 size_t match_strlcpy(char *dest, const substring_t *src, size_t size)
  206 {
  207         size_t ret = src->to - src->from;
  208 
  209         if (size) {
  210                 size_t len = ret >= size ? size - 1 : ret;
  211                 memcpy(dest, src->from, len);
  212                 dest[len] = '\0';
  213         }
  214         return ret;
  215 }
  216 
  217 /**
  218  * match_strdup: - allocate a new string with the contents of a substring_t
  219  * @s: &substring_t to copy
  220  *
  221  * Description: Allocates and returns a string filled with the contents of
  222  * the &substring_t @s. The caller is responsible for freeing the returned
  223  * string with kfree().
  224  */
  225 char *match_strdup(const substring_t *s)
  226 {
  227         size_t sz = s->to - s->from + 1;
  228         char *p = kmalloc(sz, GFP_KERNEL);
  229         if (p)
  230                 match_strlcpy(p, s, sz);
  231         return p;
  232 }
  233 
  234 EXPORT_SYMBOL(match_token);
  235 EXPORT_SYMBOL(match_int);
  236 EXPORT_SYMBOL(match_octal);
  237 EXPORT_SYMBOL(match_hex);
  238 EXPORT_SYMBOL(match_strlcpy);
  239 EXPORT_SYMBOL(match_strdup);

Cache object: 9d65eeab69afe531d6601fd473769edb


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.