Commit d3f243676addaef6c8d818934565292c698f91cc

Authored by Kevin Wolf
Committed by Anthony Liguori
1 parent daa91de2

Create qemu-option.h

This patch creates a new header file and the corresponding implementation file
for parsing of parameter strings for options (like used in -drive). Part of
this is code moved from vl.c (so qemu-img can use it later).

The idea is to have a data structure describing all accepted parameters. When
parsing a parameter string, the structure is copied and filled with the
parameter values.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Makefile
... ... @@ -65,7 +65,7 @@ recurse-all: $(SUBDIR_RULES)
65 65 #######################################################################
66 66 # BLOCK_OBJS is code used by both qemu system emulation and qemu-img
67 67  
68   -BLOCK_OBJS=cutils.o cache-utils.o qemu-malloc.o module.o
  68 +BLOCK_OBJS=cutils.o cache-utils.o qemu-malloc.o qemu-option.o module.o
69 69 BLOCK_OBJS+=block/cow.o block/qcow.o aes.o block/vmdk.o block/cloop.o
70 70 BLOCK_OBJS+=block/dmg.o block/bochs.o block/vpc.o block/vvfat.o
71 71 BLOCK_OBJS+=block/qcow2.o block/parallels.o block/nbd.o
... ...
qemu-option.c 0 → 100644
  1 +/*
  2 + * Commandline option parsing functions
  3 + *
  4 + * Copyright (c) 2003-2008 Fabrice Bellard
  5 + * Copyright (c) 2009 Kevin Wolf <kwolf@redhat.com>
  6 + *
  7 + * Permission is hereby granted, free of charge, to any person obtaining a copy
  8 + * of this software and associated documentation files (the "Software"), to deal
  9 + * in the Software without restriction, including without limitation the rights
  10 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11 + * copies of the Software, and to permit persons to whom the Software is
  12 + * furnished to do so, subject to the following conditions:
  13 + *
  14 + * The above copyright notice and this permission notice shall be included in
  15 + * all copies or substantial portions of the Software.
  16 + *
  17 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  20 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23 + * THE SOFTWARE.
  24 + */
  25 +
  26 +#include <stdio.h>
  27 +#include <string.h>
  28 +
  29 +#include "qemu-common.h"
  30 +#include "qemu-option.h"
  31 +
  32 +/*
  33 + * Extracts the name of an option from the parameter string (p points at the
  34 + * first byte of the option name)
  35 + *
  36 + * The option name is delimited by delim (usually , or =) or the string end
  37 + * and is copied into buf. If the option name is longer than buf_size, it is
  38 + * truncated. buf is always zero terminated.
  39 + *
  40 + * The return value is the position of the delimiter/zero byte after the option
  41 + * name in p.
  42 + */
  43 +const char *get_opt_name(char *buf, int buf_size, const char *p, char delim)
  44 +{
  45 + char *q;
  46 +
  47 + q = buf;
  48 + while (*p != '\0' && *p != delim) {
  49 + if (q && (q - buf) < buf_size - 1)
  50 + *q++ = *p;
  51 + p++;
  52 + }
  53 + if (q)
  54 + *q = '\0';
  55 +
  56 + return p;
  57 +}
  58 +
  59 +/*
  60 + * Extracts the value of an option from the parameter string p (p points at the
  61 + * first byte of the option value)
  62 + *
  63 + * This function is comparable to get_opt_name with the difference that the
  64 + * delimiter is fixed to be comma which starts a new option. To specify an
  65 + * option value that contains commas, double each comma.
  66 + */
  67 +const char *get_opt_value(char *buf, int buf_size, const char *p)
  68 +{
  69 + char *q;
  70 +
  71 + q = buf;
  72 + while (*p != '\0') {
  73 + if (*p == ',') {
  74 + if (*(p + 1) != ',')
  75 + break;
  76 + p++;
  77 + }
  78 + if (q && (q - buf) < buf_size - 1)
  79 + *q++ = *p;
  80 + p++;
  81 + }
  82 + if (q)
  83 + *q = '\0';
  84 +
  85 + return p;
  86 +}
  87 +
  88 +/*
  89 + * Searches an option list for an option with the given name
  90 + */
  91 +QEMUOptionParameter *get_option_parameter(QEMUOptionParameter *list,
  92 + const char *name)
  93 +{
  94 + while (list && list->name) {
  95 + if (!strcmp(list->name, name)) {
  96 + return list;
  97 + }
  98 + list++;
  99 + }
  100 +
  101 + return NULL;
  102 +}
  103 +
  104 +/*
  105 + * Sets the value of a parameter in a given option list. The parsing of the
  106 + * value depends on the type of option:
  107 + *
  108 + * OPT_FLAG (uses value.n):
  109 + * If no value is given, the flag is set to 1.
  110 + * Otherwise the value must be "on" (set to 1) or "off" (set to 0)
  111 + *
  112 + * OPT_STRING (uses value.s):
  113 + * value is strdup()ed and assigned as option value
  114 + *
  115 + * OPT_SIZE (uses value.n):
  116 + * The value is converted to an integer. Suffixes for kilobytes etc. are
  117 + * allowed (powers of 1024).
  118 + *
  119 + * Returns 0 on succes, -1 in error cases
  120 + */
  121 +int set_option_parameter(QEMUOptionParameter *list, const char *name,
  122 + const char *value)
  123 +{
  124 + // Find a matching parameter
  125 + list = get_option_parameter(list, name);
  126 + if (list == NULL) {
  127 + fprintf(stderr, "Unknown option '%s'\n", name);
  128 + return -1;
  129 + }
  130 +
  131 + // Process parameter
  132 + switch (list->type) {
  133 + case OPT_FLAG:
  134 + if (value != NULL) {
  135 + if (!strcmp(value, "on")) {
  136 + list->value.n = 1;
  137 + } else if (!strcmp(value, "off")) {
  138 + list->value.n = 0;
  139 + } else {
  140 + fprintf(stderr, "Option '%s': Use 'on' or 'off'\n", name);
  141 + return -1;
  142 + }
  143 + } else {
  144 + list->value.n = 1;
  145 + }
  146 + break;
  147 +
  148 + case OPT_STRING:
  149 + if (value != NULL) {
  150 + list->value.s = strdup(value);
  151 + } else {
  152 + fprintf(stderr, "Option '%s' needs a parameter\n", name);
  153 + return -1;
  154 + }
  155 + break;
  156 +
  157 + case OPT_SIZE:
  158 + if (value != NULL) {
  159 + double sizef = strtod(value, (char**) &value);
  160 +
  161 + switch (*value) {
  162 + case 'T':
  163 + sizef *= 1024;
  164 + case 'G':
  165 + sizef *= 1024;
  166 + case 'M':
  167 + sizef *= 1024;
  168 + case 'K':
  169 + case 'k':
  170 + sizef *= 1024;
  171 + case 'b':
  172 + case '\0':
  173 + list->value.n = (uint64_t) sizef;
  174 + break;
  175 + default:
  176 + fprintf(stderr, "Option '%s' needs size as parameter\n", name);
  177 + fprintf(stderr, "You may use k, M, G or T suffixes for "
  178 + "kilobytes, megabytes, gigabytes and terabytes.\n");
  179 + return -1;
  180 + }
  181 + } else {
  182 + fprintf(stderr, "Option '%s' needs a parameter\n", name);
  183 + return -1;
  184 + }
  185 + break;
  186 + default:
  187 + fprintf(stderr, "Bug: Option '%s' has an unknown type\n", name);
  188 + return -1;
  189 + }
  190 +
  191 + return 0;
  192 +}
  193 +
  194 +/*
  195 + * Sets the given parameter to an integer instead of a string.
  196 + * This function cannot be used to set string options.
  197 + *
  198 + * Returns 0 on success, -1 in error cases
  199 + */
  200 +int set_option_parameter_int(QEMUOptionParameter *list, const char *name,
  201 + uint64_t value)
  202 +{
  203 + // Find a matching parameter
  204 + list = get_option_parameter(list, name);
  205 + if (list == NULL) {
  206 + fprintf(stderr, "Unknown option '%s'\n", name);
  207 + return -1;
  208 + }
  209 +
  210 + // Process parameter
  211 + switch (list->type) {
  212 + case OPT_FLAG:
  213 + case OPT_NUMBER:
  214 + case OPT_SIZE:
  215 + list->value.n = value;
  216 + break;
  217 +
  218 + default:
  219 + return -1;
  220 + }
  221 +
  222 + return 0;
  223 +}
  224 +
  225 +/*
  226 + * Frees a option list. If it contains strings, the strings are freed as well.
  227 + */
  228 +void free_option_parameters(QEMUOptionParameter *list)
  229 +{
  230 + QEMUOptionParameter *cur = list;
  231 +
  232 + while (cur && cur->name) {
  233 + if (cur->type == OPT_STRING) {
  234 + free(cur->value.s);
  235 + }
  236 + cur++;
  237 + }
  238 +
  239 + free(list);
  240 +}
  241 +
  242 +/*
  243 + * Parses a parameter string (param) into an option list (dest).
  244 + *
  245 + * list is the templace is. If dest is NULL, a new copy of list is created for
  246 + * it. If list is NULL, this function fails.
  247 + *
  248 + * A parameter string consists of one or more parameters, separated by commas.
  249 + * Each parameter consists of its name and possibly of a value. In the latter
  250 + * case, the value is delimited by an = character. To specify a value which
  251 + * contains commas, double each comma so it won't be recognized as the end of
  252 + * the parameter.
  253 + *
  254 + * For more details of the parsing see above.
  255 + *
  256 + * Returns a pointer to the first element of dest (or the newly allocated copy)
  257 + * or NULL in error cases
  258 + */
  259 +QEMUOptionParameter *parse_option_parameters(const char *param,
  260 + QEMUOptionParameter *list, QEMUOptionParameter *dest)
  261 +{
  262 + QEMUOptionParameter *cur;
  263 + QEMUOptionParameter *allocated = NULL;
  264 + char name[256];
  265 + char value[256];
  266 + char *param_delim, *value_delim;
  267 + char next_delim;
  268 + size_t num_options;
  269 +
  270 + if (list == NULL) {
  271 + return NULL;
  272 + }
  273 +
  274 + if (dest == NULL) {
  275 + // Count valid options
  276 + num_options = 0;
  277 + cur = list;
  278 + while (cur->name) {
  279 + num_options++;
  280 + cur++;
  281 + }
  282 +
  283 + // Create a copy of the option list to fill in values
  284 + dest = qemu_mallocz((num_options + 1) * sizeof(QEMUOptionParameter));
  285 + allocated = dest;
  286 + memcpy(dest, list, (num_options + 1) * sizeof(QEMUOptionParameter));
  287 + }
  288 +
  289 + while (*param) {
  290 +
  291 + // Find parameter name and value in the string
  292 + param_delim = strchr(param, ',');
  293 + value_delim = strchr(param, '=');
  294 +
  295 + if (value_delim && (value_delim < param_delim || !param_delim)) {
  296 + next_delim = '=';
  297 + } else {
  298 + next_delim = ',';
  299 + value_delim = NULL;
  300 + }
  301 +
  302 + param = get_opt_name(name, sizeof(name), param, next_delim);
  303 + if (value_delim) {
  304 + param = get_opt_value(value, sizeof(value), param + 1);
  305 + }
  306 + if (*param != '\0') {
  307 + param++;
  308 + }
  309 +
  310 + // Set the parameter
  311 + if (set_option_parameter(dest, name, value_delim ? value : NULL)) {
  312 + goto fail;
  313 + }
  314 + }
  315 +
  316 + return dest;
  317 +
  318 +fail:
  319 + // Only free the list if it was newly allocated
  320 + free_option_parameters(allocated);
  321 + return NULL;
  322 +}
  323 +
  324 +/*
  325 + * Prints all options of a list that have a value to stdout
  326 + */
  327 +void print_option_parameters(QEMUOptionParameter *list)
  328 +{
  329 + while (list && list->name) {
  330 + switch (list->type) {
  331 + case OPT_STRING:
  332 + if (list->value.s != NULL) {
  333 + printf("%s='%s' ", list->name, list->value.s);
  334 + }
  335 + break;
  336 + case OPT_FLAG:
  337 + printf("%s=%s ", list->name, list->value.n ? "on" : "off");
  338 + break;
  339 + case OPT_SIZE:
  340 + case OPT_NUMBER:
  341 + printf("%s=%" PRId64 " ", list->name, list->value.n);
  342 + break;
  343 + default:
  344 + printf("%s=(unkown type) ", list->name);
  345 + break;
  346 + }
  347 + list++;
  348 + }
  349 +}
... ...
qemu-option.h 0 → 100644
  1 +/*
  2 + * Commandline option parsing functions
  3 + *
  4 + * Copyright (c) 2003-2008 Fabrice Bellard
  5 + * Copyright (c) 2009 Kevin Wolf <kwolf@redhat.com>
  6 + *
  7 + * Permission is hereby granted, free of charge, to any person obtaining a copy
  8 + * of this software and associated documentation files (the "Software"), to deal
  9 + * in the Software without restriction, including without limitation the rights
  10 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11 + * copies of the Software, and to permit persons to whom the Software is
  12 + * furnished to do so, subject to the following conditions:
  13 + *
  14 + * The above copyright notice and this permission notice shall be included in
  15 + * all copies or substantial portions of the Software.
  16 + *
  17 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  20 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23 + * THE SOFTWARE.
  24 + */
  25 +
  26 +#ifndef QEMU_OPTIONS_H
  27 +#define QEMU_OPTIONS_H
  28 +
  29 +enum QEMUOptionParType {
  30 + OPT_FLAG,
  31 + OPT_NUMBER,
  32 + OPT_SIZE,
  33 + OPT_STRING,
  34 +};
  35 +
  36 +typedef struct QEMUOptionParameter {
  37 + const char *name;
  38 + enum QEMUOptionParType type;
  39 + union {
  40 + uint64_t n;
  41 + char* s;
  42 + } value;
  43 +} QEMUOptionParameter;
  44 +
  45 +
  46 +const char *get_opt_name(char *buf, int buf_size, const char *p, char delim);
  47 +const char *get_opt_value(char *buf, int buf_size, const char *p);
  48 +
  49 +
  50 +/*
  51 + * The following functions take a parameter list as input. This is a pointer to
  52 + * the first element of a QEMUOptionParameter array which is terminated by an
  53 + * entry with entry->name == NULL.
  54 + */
  55 +
  56 +QEMUOptionParameter *get_option_parameter(QEMUOptionParameter *list,
  57 + const char *name);
  58 +int set_option_parameter(QEMUOptionParameter *list, const char *name,
  59 + const char *value);
  60 +int set_option_parameter_int(QEMUOptionParameter *list, const char *name,
  61 + uint64_t value);
  62 +QEMUOptionParameter *parse_option_parameters(const char *param,
  63 + QEMUOptionParameter *list, QEMUOptionParameter *dest);
  64 +void free_option_parameters(QEMUOptionParameter *list);
  65 +void print_option_parameters(QEMUOptionParameter *list);
  66 +
  67 +#endif
... ...
sysemu.h
... ... @@ -265,8 +265,6 @@ void do_usb_add(Monitor *mon, const char *devname);
265 265 void do_usb_del(Monitor *mon, const char *devname);
266 266 void usb_info(Monitor *mon);
267 267  
268   -const char *get_opt_name(char *buf, int buf_size, const char *p, char delim);
269   -const char *get_opt_value(char *buf, int buf_size, const char *p);
270 268 int get_param_value(char *buf, int buf_size,
271 269 const char *tag, const char *str);
272 270 int check_params(const char * const *params, const char *str);
... ...
... ... @@ -156,6 +156,7 @@ int main(int argc, char **argv)
156 156 #include "migration.h"
157 157 #include "kvm.h"
158 158 #include "balloon.h"
  159 +#include "qemu-option.h"
159 160  
160 161 #include "disas.h"
161 162  
... ... @@ -1809,43 +1810,6 @@ static int socket_init(void)
1809 1810 }
1810 1811 #endif
1811 1812  
1812   -const char *get_opt_name(char *buf, int buf_size, const char *p, char delim)
1813   -{
1814   - char *q;
1815   -
1816   - q = buf;
1817   - while (*p != '\0' && *p != delim) {
1818   - if (q && (q - buf) < buf_size - 1)
1819   - *q++ = *p;
1820   - p++;
1821   - }
1822   - if (q)
1823   - *q = '\0';
1824   -
1825   - return p;
1826   -}
1827   -
1828   -const char *get_opt_value(char *buf, int buf_size, const char *p)
1829   -{
1830   - char *q;
1831   -
1832   - q = buf;
1833   - while (*p != '\0') {
1834   - if (*p == ',') {
1835   - if (*(p + 1) != ',')
1836   - break;
1837   - p++;
1838   - }
1839   - if (q && (q - buf) < buf_size - 1)
1840   - *q++ = *p;
1841   - p++;
1842   - }
1843   - if (q)
1844   - *q = '\0';
1845   -
1846   - return p;
1847   -}
1848   -
1849 1813 int get_param_value(char *buf, int buf_size,
1850 1814 const char *tag, const char *str)
1851 1815 {
... ...