Annotation of qemu/qemu-option.c, revision 1.1.1.1

1.1       root        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