File:  [Qemu by Fabrice Bellard] / qemu / qemu-option.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:20:12 2018 UTC (2 years, 6 months ago) by root
Branches: qemu, MAIN
CVS tags: qemu0111, qemu0110, HEAD
qemu 0.11.0

    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: }
  350: 
  351: /*
  352:  * Prints an overview of all available options
  353:  */
  354: void print_option_help(QEMUOptionParameter *list)
  355: {
  356:     printf("Supported options:\n");
  357:     while (list && list->name) {
  358:         printf("%-16s %s\n", list->name,
  359:             list->help ? list->help : "No description available");
  360:         list++;
  361:     }
  362: }

unix.superglobalmegacorp.com