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}