qemu-option.c (74c3c19765c1abf202561af20dfc8f52d9cff808) | qemu-option.c (c282e1fdf7ec9659c7f320123be397477a359d01) |
---|---|
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 --- 109 unchanged lines hidden (view full) --- 118} 119 120int get_param_value(char *buf, int buf_size, 121 const char *tag, const char *str) 122{ 123 return get_next_param_value(buf, buf_size, tag, &str); 124} 125 | 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 --- 109 unchanged lines hidden (view full) --- 118} 119 120int get_param_value(char *buf, int buf_size, 121 const char *tag, const char *str) 122{ 123 return get_next_param_value(buf, buf_size, tag, &str); 124} 125 |
126/* 127 * Searches an option list for an option with the given name 128 */ 129QEMUOptionParameter *get_option_parameter(QEMUOptionParameter *list, 130 const char *name) 131{ 132 while (list && list->name) { 133 if (!strcmp(list->name, name)) { 134 return list; 135 } 136 list++; 137 } 138 139 return NULL; 140} 141 | |
142static void parse_option_bool(const char *name, const char *value, bool *ret, 143 Error **errp) 144{ 145 if (value != NULL) { 146 if (!strcmp(value, "on")) { 147 *ret = 1; 148 } else if (!strcmp(value, "off")) { 149 *ret = 0; --- 71 unchanged lines hidden (view full) --- 221#endif 222 return; 223 } 224 } else { 225 error_set(errp, QERR_INVALID_PARAMETER_VALUE, name, "a size"); 226 } 227} 228 | 126static void parse_option_bool(const char *name, const char *value, bool *ret, 127 Error **errp) 128{ 129 if (value != NULL) { 130 if (!strcmp(value, "on")) { 131 *ret = 1; 132 } else if (!strcmp(value, "off")) { 133 *ret = 0; --- 71 unchanged lines hidden (view full) --- 205#endif 206 return; 207 } 208 } else { 209 error_set(errp, QERR_INVALID_PARAMETER_VALUE, name, "a size"); 210 } 211} 212 |
229/* 230 * Sets the value of a parameter in a given option list. The parsing of the 231 * value depends on the type of option: 232 * 233 * OPT_FLAG (uses value.n): 234 * If no value is given, the flag is set to 1. 235 * Otherwise the value must be "on" (set to 1) or "off" (set to 0) 236 * 237 * OPT_STRING (uses value.s): 238 * value is strdup()ed and assigned as option value 239 * 240 * OPT_SIZE (uses value.n): 241 * The value is converted to an integer. Suffixes for kilobytes etc. are 242 * allowed (powers of 1024). 243 * 244 * Returns 0 on succes, -1 in error cases 245 */ 246int set_option_parameter(QEMUOptionParameter *list, const char *name, 247 const char *value) 248{ 249 bool flag; 250 Error *local_err = NULL; 251 252 // Find a matching parameter 253 list = get_option_parameter(list, name); 254 if (list == NULL) { 255 fprintf(stderr, "Unknown option '%s'\n", name); 256 return -1; 257 } 258 259 // Process parameter 260 switch (list->type) { 261 case OPT_FLAG: 262 parse_option_bool(name, value, &flag, &local_err); 263 if (!local_err) { 264 list->value.n = flag; 265 } 266 break; 267 268 case OPT_STRING: 269 if (value != NULL) { 270 list->value.s = g_strdup(value); 271 } else { 272 fprintf(stderr, "Option '%s' needs a parameter\n", name); 273 return -1; 274 } 275 break; 276 277 case OPT_SIZE: 278 parse_option_size(name, value, &list->value.n, &local_err); 279 break; 280 281 default: 282 fprintf(stderr, "Bug: Option '%s' has an unknown type\n", name); 283 return -1; 284 } 285 286 if (local_err) { 287 qerror_report_err(local_err); 288 error_free(local_err); 289 return -1; 290 } 291 292 list->assigned = true; 293 294 return 0; 295} 296 297/* 298 * Sets the given parameter to an integer instead of a string. 299 * This function cannot be used to set string options. 300 * 301 * Returns 0 on success, -1 in error cases 302 */ 303int set_option_parameter_int(QEMUOptionParameter *list, const char *name, 304 uint64_t value) 305{ 306 // Find a matching parameter 307 list = get_option_parameter(list, name); 308 if (list == NULL) { 309 fprintf(stderr, "Unknown option '%s'\n", name); 310 return -1; 311 } 312 313 // Process parameter 314 switch (list->type) { 315 case OPT_FLAG: 316 case OPT_NUMBER: 317 case OPT_SIZE: 318 list->value.n = value; 319 break; 320 321 default: 322 return -1; 323 } 324 325 list->assigned = true; 326 327 return 0; 328} 329 330/* 331 * Frees a option list. If it contains strings, the strings are freed as well. 332 */ 333void free_option_parameters(QEMUOptionParameter *list) 334{ 335 QEMUOptionParameter *cur = list; 336 337 while (cur && cur->name) { 338 if (cur->type == OPT_STRING) { 339 g_free(cur->value.s); 340 } 341 cur++; 342 } 343 344 g_free(list); 345} 346 347/* 348 * Count valid options in list 349 */ 350static size_t count_option_parameters(QEMUOptionParameter *list) 351{ 352 size_t num_options = 0; 353 354 while (list && list->name) { 355 num_options++; 356 list++; 357 } 358 359 return num_options; 360} 361 362/* 363 * Append an option list (list) to an option list (dest). 364 * 365 * If dest is NULL, a new copy of list is created. 366 * 367 * Returns a pointer to the first element of dest (or the newly allocated copy) 368 */ 369QEMUOptionParameter *append_option_parameters(QEMUOptionParameter *dest, 370 QEMUOptionParameter *list) 371{ 372 size_t num_options, num_dest_options; 373 374 num_options = count_option_parameters(dest); 375 num_dest_options = num_options; 376 377 num_options += count_option_parameters(list); 378 379 dest = g_realloc(dest, (num_options + 1) * sizeof(QEMUOptionParameter)); 380 dest[num_dest_options].name = NULL; 381 382 while (list && list->name) { 383 if (get_option_parameter(dest, list->name) == NULL) { 384 dest[num_dest_options++] = *list; 385 dest[num_dest_options].name = NULL; 386 } 387 list++; 388 } 389 390 return dest; 391} 392 393/* 394 * Parses a parameter string (param) into an option list (dest). 395 * 396 * list is the template option list. If dest is NULL, a new copy of list is 397 * created. If list is NULL, this function fails. 398 * 399 * A parameter string consists of one or more parameters, separated by commas. 400 * Each parameter consists of its name and possibly of a value. In the latter 401 * case, the value is delimited by an = character. To specify a value which 402 * contains commas, double each comma so it won't be recognized as the end of 403 * the parameter. 404 * 405 * For more details of the parsing see above. 406 * 407 * Returns a pointer to the first element of dest (or the newly allocated copy) 408 * or NULL in error cases 409 */ 410QEMUOptionParameter *parse_option_parameters(const char *param, 411 QEMUOptionParameter *list, QEMUOptionParameter *dest) 412{ 413 QEMUOptionParameter *allocated = NULL; 414 char name[256]; 415 char value[256]; 416 char *param_delim, *value_delim; 417 char next_delim; 418 int i; 419 420 if (list == NULL) { 421 return NULL; 422 } 423 424 if (dest == NULL) { 425 dest = allocated = append_option_parameters(NULL, list); 426 } 427 428 for (i = 0; dest[i].name; i++) { 429 dest[i].assigned = false; 430 } 431 432 while (*param) { 433 434 // Find parameter name and value in the string 435 param_delim = strchr(param, ','); 436 value_delim = strchr(param, '='); 437 438 if (value_delim && (value_delim < param_delim || !param_delim)) { 439 next_delim = '='; 440 } else { 441 next_delim = ','; 442 value_delim = NULL; 443 } 444 445 param = get_opt_name(name, sizeof(name), param, next_delim); 446 if (value_delim) { 447 param = get_opt_value(value, sizeof(value), param + 1); 448 } 449 if (*param != '\0') { 450 param++; 451 } 452 453 // Set the parameter 454 if (set_option_parameter(dest, name, value_delim ? value : NULL)) { 455 goto fail; 456 } 457 } 458 459 return dest; 460 461fail: 462 // Only free the list if it was newly allocated 463 free_option_parameters(allocated); 464 return NULL; 465} 466 | |
467bool has_help_option(const char *param) 468{ 469 size_t buflen = strlen(param) + 1; 470 char *buf = g_malloc0(buflen); 471 const char *p = param; 472 bool result = false; 473 474 while (*p) { --- 33 unchanged lines hidden (view full) --- 508 } 509 } 510 511out: 512 free(buf); 513 return result; 514} 515 | 213bool has_help_option(const char *param) 214{ 215 size_t buflen = strlen(param) + 1; 216 char *buf = g_malloc0(buflen); 217 const char *p = param; 218 bool result = false; 219 220 while (*p) { --- 33 unchanged lines hidden (view full) --- 254 } 255 } 256 257out: 258 free(buf); 259 return result; 260} 261 |
516/* 517 * Prints all options of a list that have a value to stdout 518 */ 519void print_option_parameters(QEMUOptionParameter *list) 520{ 521 while (list && list->name) { 522 switch (list->type) { 523 case OPT_STRING: 524 if (list->value.s != NULL) { 525 printf("%s='%s' ", list->name, list->value.s); 526 } 527 break; 528 case OPT_FLAG: 529 printf("%s=%s ", list->name, list->value.n ? "on" : "off"); 530 break; 531 case OPT_SIZE: 532 case OPT_NUMBER: 533 printf("%s=%" PRId64 " ", list->name, list->value.n); 534 break; 535 default: 536 printf("%s=(unknown type) ", list->name); 537 break; 538 } 539 list++; 540 } 541} 542 543/* 544 * Prints an overview of all available options 545 */ 546void print_option_help(QEMUOptionParameter *list) 547{ 548 printf("Supported options:\n"); 549 while (list && list->name) { 550 printf("%-16s %s\n", list->name, 551 list->help ? list->help : "No description available"); 552 list++; 553 } 554} 555 | |
556void qemu_opts_print_help(QemuOptsList *list) 557{ 558 QemuOptDesc *desc; 559 560 assert(list); 561 desc = list->desc; 562 printf("Supported options:\n"); 563 while (desc && desc->name) { --- 800 unchanged lines hidden (view full) --- 1364 while (desc && desc->name) { 1365 num_opts++; 1366 desc++; 1367 } 1368 1369 return num_opts; 1370} 1371 | 262void qemu_opts_print_help(QemuOptsList *list) 263{ 264 QemuOptDesc *desc; 265 266 assert(list); 267 desc = list->desc; 268 printf("Supported options:\n"); 269 while (desc && desc->name) { --- 800 unchanged lines hidden (view full) --- 1070 while (desc && desc->name) { 1071 num_opts++; 1072 desc++; 1073 } 1074 1075 return num_opts; 1076} 1077 |
1372/* Convert QEMUOptionParameter to QemuOpts 1373 * FIXME: this function will be removed after all drivers 1374 * switch to QemuOpts 1375 */ 1376QemuOptsList *params_to_opts(QEMUOptionParameter *list) 1377{ 1378 QemuOptsList *opts = NULL; 1379 size_t num_opts, i = 0; 1380 1381 if (!list) { 1382 return NULL; 1383 } 1384 1385 num_opts = count_option_parameters(list); 1386 opts = g_malloc0(sizeof(QemuOptsList) + 1387 (num_opts + 1) * sizeof(QemuOptDesc)); 1388 QTAILQ_INIT(&opts->head); 1389 /* (const char *) members will point to malloced space and need to free */ 1390 opts->allocated = true; 1391 1392 while (list && list->name) { 1393 opts->desc[i].name = g_strdup(list->name); 1394 opts->desc[i].help = g_strdup(list->help); 1395 switch (list->type) { 1396 case OPT_FLAG: 1397 opts->desc[i].type = QEMU_OPT_BOOL; 1398 opts->desc[i].def_value_str = 1399 g_strdup(list->value.n ? "on" : "off"); 1400 break; 1401 1402 case OPT_NUMBER: 1403 opts->desc[i].type = QEMU_OPT_NUMBER; 1404 if (list->value.n) { 1405 opts->desc[i].def_value_str = 1406 g_strdup_printf("%" PRIu64, list->value.n); 1407 } 1408 break; 1409 1410 case OPT_SIZE: 1411 opts->desc[i].type = QEMU_OPT_SIZE; 1412 if (list->value.n) { 1413 opts->desc[i].def_value_str = 1414 g_strdup_printf("%" PRIu64, list->value.n); 1415 } 1416 break; 1417 1418 case OPT_STRING: 1419 opts->desc[i].type = QEMU_OPT_STRING; 1420 opts->desc[i].def_value_str = g_strdup(list->value.s); 1421 break; 1422 } 1423 1424 i++; 1425 list++; 1426 } 1427 1428 return opts; 1429} 1430 1431/* convert QemuOpts to QEMUOptionParameter 1432 * Note: result QEMUOptionParameter has shorter lifetime than 1433 * input QemuOpts. 1434 * FIXME: this function will be removed after all drivers 1435 * switch to QemuOpts 1436 */ 1437QEMUOptionParameter *opts_to_params(QemuOpts *opts) 1438{ 1439 QEMUOptionParameter *dest = NULL; 1440 QemuOptDesc *desc; 1441 size_t num_opts, i = 0; 1442 const char *tmp; 1443 1444 if (!opts || !opts->list || !opts->list->desc) { 1445 return NULL; 1446 } 1447 assert(!opts_accepts_any(opts)); 1448 1449 num_opts = count_opts_list(opts->list); 1450 dest = g_malloc0((num_opts + 1) * sizeof(QEMUOptionParameter)); 1451 1452 desc = opts->list->desc; 1453 while (desc && desc->name) { 1454 dest[i].name = desc->name; 1455 dest[i].help = desc->help; 1456 dest[i].assigned = qemu_opt_find(opts, desc->name) ? true : false; 1457 switch (desc->type) { 1458 case QEMU_OPT_STRING: 1459 dest[i].type = OPT_STRING; 1460 tmp = qemu_opt_get(opts, desc->name); 1461 dest[i].value.s = g_strdup(tmp); 1462 break; 1463 1464 case QEMU_OPT_BOOL: 1465 dest[i].type = OPT_FLAG; 1466 dest[i].value.n = qemu_opt_get_bool(opts, desc->name, 0) ? 1 : 0; 1467 break; 1468 1469 case QEMU_OPT_NUMBER: 1470 dest[i].type = OPT_NUMBER; 1471 dest[i].value.n = qemu_opt_get_number(opts, desc->name, 0); 1472 break; 1473 1474 case QEMU_OPT_SIZE: 1475 dest[i].type = OPT_SIZE; 1476 dest[i].value.n = qemu_opt_get_size(opts, desc->name, 0); 1477 break; 1478 } 1479 1480 i++; 1481 desc++; 1482 } 1483 1484 return dest; 1485} 1486 | |
1487void qemu_opts_free(QemuOptsList *list) 1488{ 1489 /* List members point to new malloced space and need to be freed. 1490 * FIXME: 1491 * Introduced for QEMUOptionParamter->QemuOpts conversion. 1492 * Will remove after all drivers switch to QemuOpts. 1493 */ 1494 if (list && list->allocated) { --- 4 unchanged lines hidden (view full) --- 1499 g_free((char *)desc->def_value_str); 1500 desc++; 1501 } 1502 } 1503 1504 g_free(list); 1505} 1506 | 1078void qemu_opts_free(QemuOptsList *list) 1079{ 1080 /* List members point to new malloced space and need to be freed. 1081 * FIXME: 1082 * Introduced for QEMUOptionParamter->QemuOpts conversion. 1083 * Will remove after all drivers switch to QemuOpts. 1084 */ 1085 if (list && list->allocated) { --- 4 unchanged lines hidden (view full) --- 1090 g_free((char *)desc->def_value_str); 1091 desc++; 1092 } 1093 } 1094 1095 g_free(list); 1096} 1097 |
1507/* Realloc dst option list and append options either from an option list (list) 1508 * or a QEMUOptionParameter (param) to it. dst could be NULL or a malloced list. 1509 * FIXME: will remove QEMUOptionParameter after all drivers switch to QemuOpts. | 1098/* Realloc dst option list and append options from an option list (list) 1099 * to it. dst could be NULL or a malloced list. |
1510 */ 1511QemuOptsList *qemu_opts_append(QemuOptsList *dst, | 1100 */ 1101QemuOptsList *qemu_opts_append(QemuOptsList *dst, |
1512 QemuOptsList *list, 1513 QEMUOptionParameter *param) | 1102 QemuOptsList *list) |
1514{ 1515 size_t num_opts, num_dst_opts; 1516 QemuOptDesc *desc; 1517 bool need_init = false; 1518 | 1103{ 1104 size_t num_opts, num_dst_opts; 1105 QemuOptDesc *desc; 1106 bool need_init = false; 1107 |
1519 assert(!(list && param)); 1520 if (!param && !list) { | 1108 if (!list) { |
1521 return dst; 1522 } 1523 | 1109 return dst; 1110 } 1111 |
1524 if (param) { 1525 list = params_to_opts(param); 1526 } 1527 | |
1528 /* If dst is NULL, after realloc, some area of dst should be initialized 1529 * before adding options to it. 1530 */ 1531 if (!dst) { 1532 need_init = true; 1533 } 1534 1535 num_opts = count_opts_list(dst); --- 24 unchanged lines hidden (view full) --- 1560 g_strdup(desc->def_value_str); 1561 num_dst_opts++; 1562 dst->desc[num_dst_opts].name = NULL; 1563 } 1564 desc++; 1565 } 1566 } 1567 | 1112 /* If dst is NULL, after realloc, some area of dst should be initialized 1113 * before adding options to it. 1114 */ 1115 if (!dst) { 1116 need_init = true; 1117 } 1118 1119 num_opts = count_opts_list(dst); --- 24 unchanged lines hidden (view full) --- 1144 g_strdup(desc->def_value_str); 1145 num_dst_opts++; 1146 dst->desc[num_dst_opts].name = NULL; 1147 } 1148 desc++; 1149 } 1150 } 1151 |
1568 if (param) { 1569 qemu_opts_free(list); 1570 } | |
1571 return dst; 1572} | 1152 return dst; 1153} |