15d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* 25d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Commandline option parsing functions 35d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * 45d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Copyright (c) 2003-2008 Fabrice Bellard 55d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Copyright (c) 2009 Kevin Wolf <kwolf@redhat.com> 65d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * 75d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Permission is hereby granted, free of charge, to any person obtaining a copy 85d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * of this software and associated documentation files (the "Software"), to deal 95d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * in the Software without restriction, including without limitation the rights 105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * copies of the Software, and to permit persons to whom the Software is 125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * furnished to do so, subject to the following conditions: 135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * 145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * The above copyright notice and this permission notice shall be included in 155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * all copies or substantial portions of the Software. 165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * 175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * THE SOFTWARE. 245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */ 255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <stdio.h> 275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <string.h> 285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "qemu-common.h" 301c31e3e43ce4cca85a707dfff631e5e102fdecedDavid 'Digit' Turner#include "qemu/error-report.h" 312a7dde0b2f96b05048320a0840cde7ab3d4be9feDavid 'Digit' Turner#include "qapi/qmp/types.h" 3293e0d9cfb6d950b638ba93cf5318e5689e4ba64eDavid 'Digit' Turner#include "qemu/option.h" 331c31e3e43ce4cca85a707dfff631e5e102fdecedDavid 'Digit' Turner#include "qapi/qmp/qerror.h" 345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* 365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Extracts the name of an option from the parameter string (p points at the 375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * first byte of the option name) 385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * 395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * The option name is delimited by delim (usually , or =) or the string end 405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * and is copied into buf. If the option name is longer than buf_size, it is 415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * truncated. buf is always zero terminated. 425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * 435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * The return value is the position of the delimiter/zero byte after the option 445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * name in p. 455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */ 465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerconst char *get_opt_name(char *buf, int buf_size, const char *p, char delim) 475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner char *q; 495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner q = buf; 515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner while (*p != '\0' && *p != delim) { 525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (q && (q - buf) < buf_size - 1) 535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *q++ = *p; 545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner p++; 555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (q) 575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *q = '\0'; 585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return p; 605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* 635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Extracts the value of an option from the parameter string p (p points at the 645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * first byte of the option value) 655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * 665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * This function is comparable to get_opt_name with the difference that the 675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * delimiter is fixed to be comma which starts a new option. To specify an 685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * option value that contains commas, double each comma. 695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */ 705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerconst char *get_opt_value(char *buf, int buf_size, const char *p) 715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner char *q; 735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner q = buf; 755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner while (*p != '\0') { 765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (*p == ',') { 775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (*(p + 1) != ',') 785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner break; 795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner p++; 805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (q && (q - buf) < buf_size - 1) 825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *q++ = *p; 835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner p++; 845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (q) 865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *q = '\0'; 875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return p; 895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 912910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerint get_next_param_value(char *buf, int buf_size, 922910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner const char *tag, const char **pstr) 932910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{ 942910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner const char *p; 952910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner char option[128]; 962910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 972910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner p = *pstr; 982910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner for(;;) { 992910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner p = get_opt_name(option, sizeof(option), p, '='); 1002910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (*p != '=') 1012910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner break; 1022910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner p++; 1032910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (!strcmp(tag, option)) { 1042910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner *pstr = get_opt_value(buf, buf_size, p); 1052910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (**pstr == ',') { 1062910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner (*pstr)++; 1072910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 1082910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return strlen(buf); 1092910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } else { 1102910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner p = get_opt_value(NULL, 0, p); 1112910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 1122910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (*p != ',') 1132910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner break; 1142910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner p++; 1152910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 1162910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return 0; 1172910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} 1182910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 1192910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerint get_param_value(char *buf, int buf_size, 1202910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner const char *tag, const char *str) 1212910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{ 1222910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return get_next_param_value(buf, buf_size, tag, &str); 1232910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} 1242910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 1252910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerint check_params(char *buf, int buf_size, 1262910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner const char * const *params, const char *str) 1272910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{ 1282910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner const char *p; 1292910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner int i; 1302910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 1312910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner p = str; 1322910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner while (*p != '\0') { 1332910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner p = get_opt_name(buf, buf_size, p, '='); 1342910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (*p != '=') { 1352910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return -1; 1362910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 1372910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner p++; 1382910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner for (i = 0; params[i] != NULL; i++) { 1392910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (!strcmp(params[i], buf)) { 1402910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner break; 1412910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 1422910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 1432910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (params[i] == NULL) { 1442910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return -1; 1452910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 1462910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner p = get_opt_value(NULL, 0, p); 1472910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (*p != ',') { 1482910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner break; 1492910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 1502910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner p++; 1512910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 1522910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return 0; 1532910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} 1542910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 1555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* 1565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Searches an option list for an option with the given name 1575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */ 1585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerQEMUOptionParameter *get_option_parameter(QEMUOptionParameter *list, 1595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner const char *name) 1605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 1615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner while (list && list->name) { 1625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (!strcmp(list->name, name)) { 1635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return list; 1645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 1655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner list++; 1665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 1675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return NULL; 1695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 1705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1712910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerstatic int parse_option_bool(const char *name, const char *value, int *ret) 1722910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{ 1732abe02c0511b2278af9386e7ac5e266d890a38b1David Turner if (value != NULL) { 1742abe02c0511b2278af9386e7ac5e266d890a38b1David Turner if (!strcmp(value, "on")) { 1752910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner *ret = 1; 1762abe02c0511b2278af9386e7ac5e266d890a38b1David Turner } else if (!strcmp(value, "off")) { 1772910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner *ret = 0; 1782910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } else { 1792abe02c0511b2278af9386e7ac5e266d890a38b1David Turner qerror_report(QERR_INVALID_PARAMETER_VALUE, name, "'on' or 'off'"); 1802abe02c0511b2278af9386e7ac5e266d890a38b1David Turner return -1; 1812abe02c0511b2278af9386e7ac5e266d890a38b1David Turner } 1822abe02c0511b2278af9386e7ac5e266d890a38b1David Turner } else { 1832910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner *ret = 1; 1842910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 1852910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return 0; 1862910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} 1872910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 1882910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerstatic int parse_option_number(const char *name, const char *value, uint64_t *ret) 1892910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{ 1902910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner char *postfix; 1912910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner uint64_t number; 1922910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 1932abe02c0511b2278af9386e7ac5e266d890a38b1David Turner if (value != NULL) { 1942910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner number = strtoull(value, &postfix, 0); 1952910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (*postfix != '\0') { 1962abe02c0511b2278af9386e7ac5e266d890a38b1David Turner qerror_report(QERR_INVALID_PARAMETER_VALUE, name, "a number"); 1972910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return -1; 1982910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 1992910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner *ret = number; 2002abe02c0511b2278af9386e7ac5e266d890a38b1David Turner } else { 2012abe02c0511b2278af9386e7ac5e266d890a38b1David Turner qerror_report(QERR_INVALID_PARAMETER_VALUE, name, "a number"); 2022abe02c0511b2278af9386e7ac5e266d890a38b1David Turner return -1; 2032abe02c0511b2278af9386e7ac5e266d890a38b1David Turner } 2042910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return 0; 2052910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} 2062910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 2072910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerstatic int parse_option_size(const char *name, const char *value, uint64_t *ret) 2082910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{ 2092910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner char *postfix; 2102910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner double sizef; 2112910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 2122abe02c0511b2278af9386e7ac5e266d890a38b1David Turner if (value != NULL) { 2132910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner sizef = strtod(value, &postfix); 2142910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner switch (*postfix) { 2152abe02c0511b2278af9386e7ac5e266d890a38b1David Turner case 'T': 2162abe02c0511b2278af9386e7ac5e266d890a38b1David Turner sizef *= 1024; 2172abe02c0511b2278af9386e7ac5e266d890a38b1David Turner case 'G': 2182abe02c0511b2278af9386e7ac5e266d890a38b1David Turner sizef *= 1024; 2192abe02c0511b2278af9386e7ac5e266d890a38b1David Turner case 'M': 2202abe02c0511b2278af9386e7ac5e266d890a38b1David Turner sizef *= 1024; 2212abe02c0511b2278af9386e7ac5e266d890a38b1David Turner case 'K': 2222abe02c0511b2278af9386e7ac5e266d890a38b1David Turner case 'k': 2232abe02c0511b2278af9386e7ac5e266d890a38b1David Turner sizef *= 1024; 2242abe02c0511b2278af9386e7ac5e266d890a38b1David Turner case 'b': 2252abe02c0511b2278af9386e7ac5e266d890a38b1David Turner case '\0': 2262910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner *ret = (uint64_t) sizef; 2272abe02c0511b2278af9386e7ac5e266d890a38b1David Turner break; 2282abe02c0511b2278af9386e7ac5e266d890a38b1David Turner default: 2292abe02c0511b2278af9386e7ac5e266d890a38b1David Turner qerror_report(QERR_INVALID_PARAMETER_VALUE, name, "a size"); 2302abe02c0511b2278af9386e7ac5e266d890a38b1David Turner error_printf_unless_qmp("You may use k, M, G or T suffixes for " 2312910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner "kilobytes, megabytes, gigabytes and terabytes.\n"); 2322910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return -1; 2332910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 2342abe02c0511b2278af9386e7ac5e266d890a38b1David Turner } else { 2352abe02c0511b2278af9386e7ac5e266d890a38b1David Turner qerror_report(QERR_INVALID_PARAMETER_VALUE, name, "a size"); 2362abe02c0511b2278af9386e7ac5e266d890a38b1David Turner return -1; 2372abe02c0511b2278af9386e7ac5e266d890a38b1David Turner } 2382910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return 0; 2392910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} 2402910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 2415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* 2425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Sets the value of a parameter in a given option list. The parsing of the 2435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * value depends on the type of option: 2445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * 2455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * OPT_FLAG (uses value.n): 2465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * If no value is given, the flag is set to 1. 2475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Otherwise the value must be "on" (set to 1) or "off" (set to 0) 2485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * 2495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * OPT_STRING (uses value.s): 2505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * value is strdup()ed and assigned as option value 2515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * 2525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * OPT_SIZE (uses value.n): 2535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * The value is converted to an integer. Suffixes for kilobytes etc. are 2545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * allowed (powers of 1024). 2555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * 2565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Returns 0 on succes, -1 in error cases 2575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */ 2585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint set_option_parameter(QEMUOptionParameter *list, const char *name, 2595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner const char *value) 2605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 2612910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner int flag; 2622910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 2635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner // Find a matching parameter 2645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner list = get_option_parameter(list, name); 2655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (list == NULL) { 2665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner fprintf(stderr, "Unknown option '%s'\n", name); 2675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return -1; 2685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 2695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 2705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner // Process parameter 2715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner switch (list->type) { 2725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner case OPT_FLAG: 2732910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (parse_option_bool(name, value, &flag) == -1) 2742910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return -1; 2752910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner list->value.n = flag; 2765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner break; 2775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 2785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner case OPT_STRING: 2795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (value != NULL) { 280aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner list->value.s = g_strdup(value); 2815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else { 2825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner fprintf(stderr, "Option '%s' needs a parameter\n", name); 2835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return -1; 2845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 2855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner break; 2865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 2875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner case OPT_SIZE: 2882910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (parse_option_size(name, value, &list->value.n) == -1) 2895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return -1; 2905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner break; 2912910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 2925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner default: 2935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner fprintf(stderr, "Bug: Option '%s' has an unknown type\n", name); 2945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return -1; 2955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 2965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 2975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 2985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 2995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 3005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* 3015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Sets the given parameter to an integer instead of a string. 3025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * This function cannot be used to set string options. 3035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * 3045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Returns 0 on success, -1 in error cases 3055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */ 3065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint set_option_parameter_int(QEMUOptionParameter *list, const char *name, 3075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint64_t value) 3085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 3095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner // Find a matching parameter 3105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner list = get_option_parameter(list, name); 3115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (list == NULL) { 3125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner fprintf(stderr, "Unknown option '%s'\n", name); 3135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return -1; 3145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 3155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 3165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner // Process parameter 3175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner switch (list->type) { 3185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner case OPT_FLAG: 3195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner case OPT_NUMBER: 3205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner case OPT_SIZE: 3215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner list->value.n = value; 3225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner break; 3235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 3245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner default: 3255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return -1; 3265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 3275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 3285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 3295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 3305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 3315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* 3325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Frees a option list. If it contains strings, the strings are freed as well. 3335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */ 3345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid free_option_parameters(QEMUOptionParameter *list) 3355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 3365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner QEMUOptionParameter *cur = list; 3375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 3385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner while (cur && cur->name) { 3395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (cur->type == OPT_STRING) { 340aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner g_free(cur->value.s); 3415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 3425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner cur++; 3435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 3445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 345aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner g_free(list); 3465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 3475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 3485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* 3492abe02c0511b2278af9386e7ac5e266d890a38b1David Turner * Count valid options in list 3502abe02c0511b2278af9386e7ac5e266d890a38b1David Turner */ 3512abe02c0511b2278af9386e7ac5e266d890a38b1David Turnerstatic size_t count_option_parameters(QEMUOptionParameter *list) 3522abe02c0511b2278af9386e7ac5e266d890a38b1David Turner{ 3532abe02c0511b2278af9386e7ac5e266d890a38b1David Turner size_t num_options = 0; 3542abe02c0511b2278af9386e7ac5e266d890a38b1David Turner 3552abe02c0511b2278af9386e7ac5e266d890a38b1David Turner while (list && list->name) { 3562abe02c0511b2278af9386e7ac5e266d890a38b1David Turner num_options++; 3572abe02c0511b2278af9386e7ac5e266d890a38b1David Turner list++; 3582abe02c0511b2278af9386e7ac5e266d890a38b1David Turner } 3592abe02c0511b2278af9386e7ac5e266d890a38b1David Turner 3602abe02c0511b2278af9386e7ac5e266d890a38b1David Turner return num_options; 3612abe02c0511b2278af9386e7ac5e266d890a38b1David Turner} 3622abe02c0511b2278af9386e7ac5e266d890a38b1David Turner 3632abe02c0511b2278af9386e7ac5e266d890a38b1David Turner/* 3642abe02c0511b2278af9386e7ac5e266d890a38b1David Turner * Append an option list (list) to an option list (dest). 3652abe02c0511b2278af9386e7ac5e266d890a38b1David Turner * 3662abe02c0511b2278af9386e7ac5e266d890a38b1David Turner * If dest is NULL, a new copy of list is created. 3672abe02c0511b2278af9386e7ac5e266d890a38b1David Turner * 3682abe02c0511b2278af9386e7ac5e266d890a38b1David Turner * Returns a pointer to the first element of dest (or the newly allocated copy) 3692abe02c0511b2278af9386e7ac5e266d890a38b1David Turner */ 3702abe02c0511b2278af9386e7ac5e266d890a38b1David TurnerQEMUOptionParameter *append_option_parameters(QEMUOptionParameter *dest, 3712abe02c0511b2278af9386e7ac5e266d890a38b1David Turner QEMUOptionParameter *list) 3722abe02c0511b2278af9386e7ac5e266d890a38b1David Turner{ 3732abe02c0511b2278af9386e7ac5e266d890a38b1David Turner size_t num_options, num_dest_options; 3742abe02c0511b2278af9386e7ac5e266d890a38b1David Turner 3752abe02c0511b2278af9386e7ac5e266d890a38b1David Turner num_options = count_option_parameters(dest); 3762abe02c0511b2278af9386e7ac5e266d890a38b1David Turner num_dest_options = num_options; 3772abe02c0511b2278af9386e7ac5e266d890a38b1David Turner 3782abe02c0511b2278af9386e7ac5e266d890a38b1David Turner num_options += count_option_parameters(list); 3792abe02c0511b2278af9386e7ac5e266d890a38b1David Turner 380aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner dest = g_realloc(dest, (num_options + 1) * sizeof(QEMUOptionParameter)); 3812abe02c0511b2278af9386e7ac5e266d890a38b1David Turner dest[num_dest_options].name = NULL; 3822abe02c0511b2278af9386e7ac5e266d890a38b1David Turner 3832abe02c0511b2278af9386e7ac5e266d890a38b1David Turner while (list && list->name) { 3842abe02c0511b2278af9386e7ac5e266d890a38b1David Turner if (get_option_parameter(dest, list->name) == NULL) { 3852abe02c0511b2278af9386e7ac5e266d890a38b1David Turner dest[num_dest_options++] = *list; 3862abe02c0511b2278af9386e7ac5e266d890a38b1David Turner dest[num_dest_options].name = NULL; 3872abe02c0511b2278af9386e7ac5e266d890a38b1David Turner } 3882abe02c0511b2278af9386e7ac5e266d890a38b1David Turner list++; 3892abe02c0511b2278af9386e7ac5e266d890a38b1David Turner } 3902abe02c0511b2278af9386e7ac5e266d890a38b1David Turner 3912abe02c0511b2278af9386e7ac5e266d890a38b1David Turner return dest; 3922abe02c0511b2278af9386e7ac5e266d890a38b1David Turner} 3932abe02c0511b2278af9386e7ac5e266d890a38b1David Turner 3942abe02c0511b2278af9386e7ac5e266d890a38b1David Turner/* 3955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Parses a parameter string (param) into an option list (dest). 3965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * 397488bfd506a283c648f559140f51f125847d68664David 'Digit' Turner * list is the template option list. If dest is NULL, a new copy of list is 398488bfd506a283c648f559140f51f125847d68664David 'Digit' Turner * created. If list is NULL, this function fails. 3995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * 4005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * A parameter string consists of one or more parameters, separated by commas. 4015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Each parameter consists of its name and possibly of a value. In the latter 4025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * case, the value is delimited by an = character. To specify a value which 4035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * contains commas, double each comma so it won't be recognized as the end of 4045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * the parameter. 4055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * 4065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * For more details of the parsing see above. 4075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * 4085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Returns a pointer to the first element of dest (or the newly allocated copy) 4095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * or NULL in error cases 4105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */ 4115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerQEMUOptionParameter *parse_option_parameters(const char *param, 4125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner QEMUOptionParameter *list, QEMUOptionParameter *dest) 4135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 4145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner QEMUOptionParameter *allocated = NULL; 4155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner char name[256]; 4165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner char value[256]; 4175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner char *param_delim, *value_delim; 4185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner char next_delim; 4195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 4205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (list == NULL) { 4215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return NULL; 4225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 4235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 4245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (dest == NULL) { 425488bfd506a283c648f559140f51f125847d68664David 'Digit' Turner dest = allocated = append_option_parameters(NULL, list); 4265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 4275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 4285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner while (*param) { 4295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 4305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner // Find parameter name and value in the string 4315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner param_delim = strchr(param, ','); 4325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner value_delim = strchr(param, '='); 4335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 4345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (value_delim && (value_delim < param_delim || !param_delim)) { 4355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner next_delim = '='; 4365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else { 4375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner next_delim = ','; 4385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner value_delim = NULL; 4395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 4405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 4415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner param = get_opt_name(name, sizeof(name), param, next_delim); 4425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (value_delim) { 4435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner param = get_opt_value(value, sizeof(value), param + 1); 4445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 4455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (*param != '\0') { 4465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner param++; 4475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 4485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 4495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner // Set the parameter 4505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (set_option_parameter(dest, name, value_delim ? value : NULL)) { 4515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner goto fail; 4525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 4535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 4545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 4555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return dest; 4565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 4575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerfail: 4585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner // Only free the list if it was newly allocated 4595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner free_option_parameters(allocated); 4605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return NULL; 4615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 4625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 4635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* 4645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Prints all options of a list that have a value to stdout 4655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */ 4665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid print_option_parameters(QEMUOptionParameter *list) 4675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 4685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner while (list && list->name) { 4695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner switch (list->type) { 4705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner case OPT_STRING: 4715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (list->value.s != NULL) { 4725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner printf("%s='%s' ", list->name, list->value.s); 4735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 4745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner break; 4755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner case OPT_FLAG: 4765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner printf("%s=%s ", list->name, list->value.n ? "on" : "off"); 4775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner break; 4785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner case OPT_SIZE: 4795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner case OPT_NUMBER: 4805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner printf("%s=%" PRId64 " ", list->name, list->value.n); 4815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner break; 4825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner default: 4835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner printf("%s=(unkown type) ", list->name); 4845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner break; 4855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 4865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner list++; 4875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 4885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 4895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 4905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* 4915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Prints an overview of all available options 4925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */ 4935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid print_option_help(QEMUOptionParameter *list) 4945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 4955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner printf("Supported options:\n"); 4965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner while (list && list->name) { 4975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner printf("%-16s %s\n", list->name, 4985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner list->help ? list->help : "No description available"); 4995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner list++; 5005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 5015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 5022910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 5032910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/* ------------------------------------------------------------------ */ 5042910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 5052910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerstruct QemuOpt { 5062910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner const char *name; 5072910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner const char *str; 5082910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 5099251866320b5f8329a043bb56b3a794f78d12849David 'Digit' Turner const QemuOptDesc *desc; 5102910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner union { 5112910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner int boolean; 5122910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner uint64_t uint; 5132910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } value; 5142910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 5152910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QemuOpts *opts; 5162910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QTAILQ_ENTRY(QemuOpt) next; 5172910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner}; 5182910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 5192910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerstruct QemuOpts { 5202910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner char *id; 5212910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QemuOptsList *list; 5222abe02c0511b2278af9386e7ac5e266d890a38b1David Turner Location loc; 5232910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QTAILQ_HEAD(QemuOptHead, QemuOpt) head; 5242910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QTAILQ_ENTRY(QemuOpts) next; 5252910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner}; 5262910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 5272910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerstatic QemuOpt *qemu_opt_find(QemuOpts *opts, const char *name) 5282910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{ 5292910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QemuOpt *opt; 5302910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 5312910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QTAILQ_FOREACH_REVERSE(opt, &opts->head, QemuOptHead, next) { 5322910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (strcmp(opt->name, name) != 0) 5332910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner continue; 5342910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return opt; 5352910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 5362910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return NULL; 5372910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} 5382910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 5392910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerconst char *qemu_opt_get(QemuOpts *opts, const char *name) 5402910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{ 5412910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QemuOpt *opt = qemu_opt_find(opts, name); 5422910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return opt ? opt->str : NULL; 5432910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} 5442910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 5452910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerint qemu_opt_get_bool(QemuOpts *opts, const char *name, int defval) 5462910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{ 5472910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QemuOpt *opt = qemu_opt_find(opts, name); 5482910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 5492910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (opt == NULL) 5502910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return defval; 5512910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner assert(opt->desc && opt->desc->type == QEMU_OPT_BOOL); 5522910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return opt->value.boolean; 5532910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} 5542910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 5552910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turneruint64_t qemu_opt_get_number(QemuOpts *opts, const char *name, uint64_t defval) 5562910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{ 5572910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QemuOpt *opt = qemu_opt_find(opts, name); 5582910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 5592910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (opt == NULL) 5602910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return defval; 5612910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner assert(opt->desc && opt->desc->type == QEMU_OPT_NUMBER); 5622910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return opt->value.uint; 5632910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} 5642910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 5652910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turneruint64_t qemu_opt_get_size(QemuOpts *opts, const char *name, uint64_t defval) 5662910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{ 5672910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QemuOpt *opt = qemu_opt_find(opts, name); 5682910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 5692910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (opt == NULL) 5702910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return defval; 5712910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner assert(opt->desc && opt->desc->type == QEMU_OPT_SIZE); 5722910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return opt->value.uint; 5732910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} 5742910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 5752910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerstatic int qemu_opt_parse(QemuOpt *opt) 5762910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{ 5772910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (opt->desc == NULL) 5782910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return 0; 5792910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner switch (opt->desc->type) { 5802910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner case QEMU_OPT_STRING: 5812910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner /* nothing */ 5822910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return 0; 5832910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner case QEMU_OPT_BOOL: 5842910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return parse_option_bool(opt->name, opt->str, &opt->value.boolean); 5852910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner case QEMU_OPT_NUMBER: 5862910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return parse_option_number(opt->name, opt->str, &opt->value.uint); 5872910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner case QEMU_OPT_SIZE: 5882910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return parse_option_size(opt->name, opt->str, &opt->value.uint); 5892910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner default: 5902910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner abort(); 5912910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 5922910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} 5932910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 5942910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerstatic void qemu_opt_del(QemuOpt *opt) 5952910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{ 5962910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QTAILQ_REMOVE(&opt->opts->head, opt, next); 597aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner g_free((/* !const */ char*)opt->name); 598aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner g_free((/* !const */ char*)opt->str); 599aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner g_free(opt); 6002910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} 6012910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 6022910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerint qemu_opt_set(QemuOpts *opts, const char *name, const char *value) 6032910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{ 6042910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QemuOpt *opt; 6059251866320b5f8329a043bb56b3a794f78d12849David 'Digit' Turner const QemuOptDesc *desc = opts->list->desc; 6062910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner int i; 6072910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 6082910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner for (i = 0; desc[i].name != NULL; i++) { 6092910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (strcmp(desc[i].name, name) == 0) { 6102910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner break; 6112910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 6122910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 6132910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (desc[i].name == NULL) { 6142910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (i == 0) { 6152910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner /* empty list -> allow any */; 6162910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } else { 6172abe02c0511b2278af9386e7ac5e266d890a38b1David Turner qerror_report(QERR_INVALID_PARAMETER, name); 6182910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return -1; 6192910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 6202910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 6212910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 622aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner opt = g_malloc0(sizeof(*opt)); 623aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner opt->name = g_strdup(name); 6242910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner opt->opts = opts; 6252910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QTAILQ_INSERT_TAIL(&opts->head, opt, next); 6262910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (desc[i].name != NULL) { 6272910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner opt->desc = desc+i; 6282910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 6292910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (value) { 630aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner opt->str = g_strdup(value); 6312910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 6322910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (qemu_opt_parse(opt) < 0) { 6332910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner qemu_opt_del(opt); 6342910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return -1; 6352910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 6362910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return 0; 6372910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} 6382910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 6392910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerint qemu_opt_foreach(QemuOpts *opts, qemu_opt_loopfunc func, void *opaque, 6402910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner int abort_on_failure) 6412910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{ 6422910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QemuOpt *opt; 6432910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner int rc = 0; 6442910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 6452910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QTAILQ_FOREACH(opt, &opts->head, next) { 6462910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner rc = func(opt->name, opt->str, opaque); 6472910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (abort_on_failure && rc != 0) 6482910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner break; 6492910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 6502910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return rc; 6512910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} 6522910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 6532910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' TurnerQemuOpts *qemu_opts_find(QemuOptsList *list, const char *id) 6542910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{ 6552910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QemuOpts *opts; 6562910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 6572910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QTAILQ_FOREACH(opts, &list->head, next) { 6582910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (!opts->id) { 6592910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner continue; 6602910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 6612910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (strcmp(opts->id, id) != 0) { 6622910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner continue; 6632910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 6642910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return opts; 6652910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 6662910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return NULL; 6672910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} 6682910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 6692abe02c0511b2278af9386e7ac5e266d890a38b1David Turnerstatic int id_wellformed(const char *id) 6702abe02c0511b2278af9386e7ac5e266d890a38b1David Turner{ 6712abe02c0511b2278af9386e7ac5e266d890a38b1David Turner int i; 6722abe02c0511b2278af9386e7ac5e266d890a38b1David Turner 6732abe02c0511b2278af9386e7ac5e266d890a38b1David Turner if (!qemu_isalpha(id[0])) { 6742abe02c0511b2278af9386e7ac5e266d890a38b1David Turner return 0; 6752abe02c0511b2278af9386e7ac5e266d890a38b1David Turner } 6762abe02c0511b2278af9386e7ac5e266d890a38b1David Turner for (i = 1; id[i]; i++) { 6772abe02c0511b2278af9386e7ac5e266d890a38b1David Turner if (!qemu_isalnum(id[i]) && !strchr("-._", id[i])) { 6782abe02c0511b2278af9386e7ac5e266d890a38b1David Turner return 0; 6792abe02c0511b2278af9386e7ac5e266d890a38b1David Turner } 6802abe02c0511b2278af9386e7ac5e266d890a38b1David Turner } 6812abe02c0511b2278af9386e7ac5e266d890a38b1David Turner return 1; 6822abe02c0511b2278af9386e7ac5e266d890a38b1David Turner} 6832abe02c0511b2278af9386e7ac5e266d890a38b1David Turner 6842910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' TurnerQemuOpts *qemu_opts_create(QemuOptsList *list, const char *id, int fail_if_exists) 6852910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{ 6862910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QemuOpts *opts = NULL; 6872910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 6882910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (id) { 6892abe02c0511b2278af9386e7ac5e266d890a38b1David Turner if (!id_wellformed(id)) { 6902abe02c0511b2278af9386e7ac5e266d890a38b1David Turner qerror_report(QERR_INVALID_PARAMETER_VALUE, "id", "an identifier"); 6912abe02c0511b2278af9386e7ac5e266d890a38b1David Turner error_printf_unless_qmp("Identifiers consist of letters, digits, '-', '.', '_', starting with a letter.\n"); 6922abe02c0511b2278af9386e7ac5e266d890a38b1David Turner return NULL; 6932abe02c0511b2278af9386e7ac5e266d890a38b1David Turner } 6942910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner opts = qemu_opts_find(list, id); 6952910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (opts != NULL) { 6962910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (fail_if_exists) { 6972abe02c0511b2278af9386e7ac5e266d890a38b1David Turner qerror_report(QERR_DUPLICATE_ID, id, list->name); 6982910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return NULL; 6992910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } else { 7002910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return opts; 7012910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 7022910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 7032910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 704aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner opts = g_malloc0(sizeof(*opts)); 7052910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (id) { 706aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner opts->id = g_strdup(id); 7072910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 7082910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner opts->list = list; 7092abe02c0511b2278af9386e7ac5e266d890a38b1David Turner loc_save(&opts->loc); 7102910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QTAILQ_INIT(&opts->head); 7112910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QTAILQ_INSERT_TAIL(&list->head, opts, next); 7122910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return opts; 7132910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} 7142910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 7152abe02c0511b2278af9386e7ac5e266d890a38b1David Turnervoid qemu_opts_reset(QemuOptsList *list) 7162abe02c0511b2278af9386e7ac5e266d890a38b1David Turner{ 7172abe02c0511b2278af9386e7ac5e266d890a38b1David Turner QemuOpts *opts, *next_opts; 7182abe02c0511b2278af9386e7ac5e266d890a38b1David Turner 7192abe02c0511b2278af9386e7ac5e266d890a38b1David Turner QTAILQ_FOREACH_SAFE(opts, &list->head, next, next_opts) { 7202abe02c0511b2278af9386e7ac5e266d890a38b1David Turner qemu_opts_del(opts); 7212abe02c0511b2278af9386e7ac5e266d890a38b1David Turner } 7222abe02c0511b2278af9386e7ac5e266d890a38b1David Turner} 7232abe02c0511b2278af9386e7ac5e266d890a38b1David Turner 7242abe02c0511b2278af9386e7ac5e266d890a38b1David Turnervoid qemu_opts_loc_restore(QemuOpts *opts) 7252abe02c0511b2278af9386e7ac5e266d890a38b1David Turner{ 7262abe02c0511b2278af9386e7ac5e266d890a38b1David Turner loc_restore(&opts->loc); 7272abe02c0511b2278af9386e7ac5e266d890a38b1David Turner} 7282abe02c0511b2278af9386e7ac5e266d890a38b1David Turner 7292910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerint qemu_opts_set(QemuOptsList *list, const char *id, 7302910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner const char *name, const char *value) 7312910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{ 7322910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QemuOpts *opts; 7332910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 7342910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner opts = qemu_opts_create(list, id, 1); 7352910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (opts == NULL) { 7362910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return -1; 7372910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 7382910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return qemu_opt_set(opts, name, value); 7392910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} 7402910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 7412910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerconst char *qemu_opts_id(QemuOpts *opts) 7422910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{ 7432910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return opts->id; 7442910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} 7452910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 7462910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnervoid qemu_opts_del(QemuOpts *opts) 7472910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{ 7482910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QemuOpt *opt; 7492910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 7502910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner for (;;) { 7512910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner opt = QTAILQ_FIRST(&opts->head); 7522910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (opt == NULL) 7532910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner break; 7542910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner qemu_opt_del(opt); 7552910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 7562910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QTAILQ_REMOVE(&opts->list->head, opts, next); 757aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner g_free(opts->id); 758aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner g_free(opts); 7592910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} 7602910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 7612910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerint qemu_opts_print(QemuOpts *opts, void *dummy) 7622910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{ 7632910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QemuOpt *opt; 7642910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 7652910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner fprintf(stderr, "%s: %s:", opts->list->name, 7662910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner opts->id ? opts->id : "<noid>"); 7672910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QTAILQ_FOREACH(opt, &opts->head, next) { 7682910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner fprintf(stderr, " %s=\"%s\"", opt->name, opt->str); 7692910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 7702910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner fprintf(stderr, "\n"); 7712910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return 0; 7722910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} 7732910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 7742910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerint qemu_opts_do_parse(QemuOpts *opts, const char *params, const char *firstname) 7752910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{ 7762910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner char option[128], value[1024]; 7772910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner const char *p,*pe,*pc; 7782910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 7792910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner for (p = params; *p != '\0'; p++) { 7802910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner pe = strchr(p, '='); 7812910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner pc = strchr(p, ','); 7822910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (!pe || (pc && pc < pe)) { 7832910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner /* found "foo,more" */ 7842910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (p == params && firstname) { 7852910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner /* implicitly named first option */ 7862910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner pstrcpy(option, sizeof(option), firstname); 7872910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner p = get_opt_value(value, sizeof(value), p); 7882910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } else { 7892910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner /* option without value, probably a flag */ 7902910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner p = get_opt_name(option, sizeof(option), p, ','); 7912910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (strncmp(option, "no", 2) == 0) { 7922910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner memmove(option, option+2, strlen(option+2)+1); 7932910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner pstrcpy(value, sizeof(value), "off"); 7942910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } else { 7952910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner pstrcpy(value, sizeof(value), "on"); 7962910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 7972910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 7982910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } else { 7992910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner /* found "foo=bar,more" */ 8002910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner p = get_opt_name(option, sizeof(option), p, '='); 8012910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (*p != '=') { 8022910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner break; 8032910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 8042910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner p++; 8052910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner p = get_opt_value(value, sizeof(value), p); 8062910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 8072910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (strcmp(option, "id") != 0) { 8082910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner /* store and parse */ 8092910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (qemu_opt_set(opts, option, value) == -1) { 8102910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return -1; 8112910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 8122910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 8132910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (*p != ',') { 8142910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner break; 8152910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 8162910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 8172910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return 0; 8182910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} 8192910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 8202abe02c0511b2278af9386e7ac5e266d890a38b1David TurnerQemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params, 8212abe02c0511b2278af9386e7ac5e266d890a38b1David Turner int permit_abbrev) 8222910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{ 8232abe02c0511b2278af9386e7ac5e266d890a38b1David Turner const char *firstname; 8242910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner char value[1024], *id = NULL; 8252910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner const char *p; 8262910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QemuOpts *opts; 8272910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 8282abe02c0511b2278af9386e7ac5e266d890a38b1David Turner assert(!permit_abbrev || list->implied_opt_name); 8292abe02c0511b2278af9386e7ac5e266d890a38b1David Turner firstname = permit_abbrev ? list->implied_opt_name : NULL; 8302abe02c0511b2278af9386e7ac5e266d890a38b1David Turner 8312910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (strncmp(params, "id=", 3) == 0) { 8322910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner get_opt_value(value, sizeof(value), params+3); 8332abe02c0511b2278af9386e7ac5e266d890a38b1David Turner id = value; 8342910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } else if ((p = strstr(params, ",id=")) != NULL) { 8352910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner get_opt_value(value, sizeof(value), p+4); 8362abe02c0511b2278af9386e7ac5e266d890a38b1David Turner id = value; 8372910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 8382910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner opts = qemu_opts_create(list, id, 1); 8392910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (opts == NULL) 8402910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return NULL; 8412910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 8422910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (qemu_opts_do_parse(opts, params, firstname) != 0) { 8432910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner qemu_opts_del(opts); 8442910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return NULL; 8452910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 8462910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 8472910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return opts; 8482910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} 8492910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 8502abe02c0511b2278af9386e7ac5e266d890a38b1David Turnerstatic void qemu_opts_from_qdict_1(const char *key, QObject *obj, void *opaque) 8512abe02c0511b2278af9386e7ac5e266d890a38b1David Turner{ 8522abe02c0511b2278af9386e7ac5e266d890a38b1David Turner char buf[32]; 8532abe02c0511b2278af9386e7ac5e266d890a38b1David Turner const char *value; 8542abe02c0511b2278af9386e7ac5e266d890a38b1David Turner int n; 8552abe02c0511b2278af9386e7ac5e266d890a38b1David Turner 8562abe02c0511b2278af9386e7ac5e266d890a38b1David Turner if (!strcmp(key, "id")) { 8572abe02c0511b2278af9386e7ac5e266d890a38b1David Turner return; 8582abe02c0511b2278af9386e7ac5e266d890a38b1David Turner } 8592abe02c0511b2278af9386e7ac5e266d890a38b1David Turner 8602abe02c0511b2278af9386e7ac5e266d890a38b1David Turner switch (qobject_type(obj)) { 8612abe02c0511b2278af9386e7ac5e266d890a38b1David Turner case QTYPE_QSTRING: 8622abe02c0511b2278af9386e7ac5e266d890a38b1David Turner value = qstring_get_str(qobject_to_qstring(obj)); 8632abe02c0511b2278af9386e7ac5e266d890a38b1David Turner break; 8642abe02c0511b2278af9386e7ac5e266d890a38b1David Turner case QTYPE_QINT: 8652abe02c0511b2278af9386e7ac5e266d890a38b1David Turner n = snprintf(buf, sizeof(buf), "%" PRId64, 8662abe02c0511b2278af9386e7ac5e266d890a38b1David Turner qint_get_int(qobject_to_qint(obj))); 8672abe02c0511b2278af9386e7ac5e266d890a38b1David Turner assert(n < sizeof(buf)); 8682abe02c0511b2278af9386e7ac5e266d890a38b1David Turner value = buf; 8692abe02c0511b2278af9386e7ac5e266d890a38b1David Turner break; 8702abe02c0511b2278af9386e7ac5e266d890a38b1David Turner case QTYPE_QFLOAT: 8712abe02c0511b2278af9386e7ac5e266d890a38b1David Turner n = snprintf(buf, sizeof(buf), "%.17g", 8722abe02c0511b2278af9386e7ac5e266d890a38b1David Turner qfloat_get_double(qobject_to_qfloat(obj))); 8732abe02c0511b2278af9386e7ac5e266d890a38b1David Turner assert(n < sizeof(buf)); 8742abe02c0511b2278af9386e7ac5e266d890a38b1David Turner value = buf; 8752abe02c0511b2278af9386e7ac5e266d890a38b1David Turner break; 8762abe02c0511b2278af9386e7ac5e266d890a38b1David Turner case QTYPE_QBOOL: 8772abe02c0511b2278af9386e7ac5e266d890a38b1David Turner pstrcpy(buf, sizeof(buf), 8782abe02c0511b2278af9386e7ac5e266d890a38b1David Turner qbool_get_int(qobject_to_qbool(obj)) ? "on" : "off"); 8792abe02c0511b2278af9386e7ac5e266d890a38b1David Turner value = buf; 8802abe02c0511b2278af9386e7ac5e266d890a38b1David Turner break; 8812abe02c0511b2278af9386e7ac5e266d890a38b1David Turner default: 8822abe02c0511b2278af9386e7ac5e266d890a38b1David Turner return; 8832abe02c0511b2278af9386e7ac5e266d890a38b1David Turner } 8842abe02c0511b2278af9386e7ac5e266d890a38b1David Turner qemu_opt_set(opaque, key, value); 8852abe02c0511b2278af9386e7ac5e266d890a38b1David Turner} 8862abe02c0511b2278af9386e7ac5e266d890a38b1David Turner 8872abe02c0511b2278af9386e7ac5e266d890a38b1David Turner/* 8882abe02c0511b2278af9386e7ac5e266d890a38b1David Turner * Create QemuOpts from a QDict. 8892abe02c0511b2278af9386e7ac5e266d890a38b1David Turner * Use value of key "id" as ID if it exists and is a QString. 8902abe02c0511b2278af9386e7ac5e266d890a38b1David Turner * Only QStrings, QInts, QFloats and QBools are copied. Entries with 8912abe02c0511b2278af9386e7ac5e266d890a38b1David Turner * other types are silently ignored. 8922abe02c0511b2278af9386e7ac5e266d890a38b1David Turner */ 8932abe02c0511b2278af9386e7ac5e266d890a38b1David TurnerQemuOpts *qemu_opts_from_qdict(QemuOptsList *list, const QDict *qdict) 8942abe02c0511b2278af9386e7ac5e266d890a38b1David Turner{ 8952abe02c0511b2278af9386e7ac5e266d890a38b1David Turner QemuOpts *opts; 8962abe02c0511b2278af9386e7ac5e266d890a38b1David Turner 8972abe02c0511b2278af9386e7ac5e266d890a38b1David Turner opts = qemu_opts_create(list, qdict_get_try_str(qdict, "id"), 1); 8982abe02c0511b2278af9386e7ac5e266d890a38b1David Turner if (opts == NULL) 8992abe02c0511b2278af9386e7ac5e266d890a38b1David Turner return NULL; 9002abe02c0511b2278af9386e7ac5e266d890a38b1David Turner 9012abe02c0511b2278af9386e7ac5e266d890a38b1David Turner qdict_iter(qdict, qemu_opts_from_qdict_1, opts); 9022abe02c0511b2278af9386e7ac5e266d890a38b1David Turner return opts; 9032abe02c0511b2278af9386e7ac5e266d890a38b1David Turner} 9042abe02c0511b2278af9386e7ac5e266d890a38b1David Turner 9052abe02c0511b2278af9386e7ac5e266d890a38b1David Turner/* 9062abe02c0511b2278af9386e7ac5e266d890a38b1David Turner * Convert from QemuOpts to QDict. 9072abe02c0511b2278af9386e7ac5e266d890a38b1David Turner * The QDict values are of type QString. 9082abe02c0511b2278af9386e7ac5e266d890a38b1David Turner * TODO We'll want to use types appropriate for opt->desc->type, but 9092abe02c0511b2278af9386e7ac5e266d890a38b1David Turner * this is enough for now. 9102abe02c0511b2278af9386e7ac5e266d890a38b1David Turner */ 9112abe02c0511b2278af9386e7ac5e266d890a38b1David TurnerQDict *qemu_opts_to_qdict(QemuOpts *opts, QDict *qdict) 9122abe02c0511b2278af9386e7ac5e266d890a38b1David Turner{ 9132abe02c0511b2278af9386e7ac5e266d890a38b1David Turner QemuOpt *opt; 9142abe02c0511b2278af9386e7ac5e266d890a38b1David Turner QObject *val; 9152abe02c0511b2278af9386e7ac5e266d890a38b1David Turner 9162abe02c0511b2278af9386e7ac5e266d890a38b1David Turner if (!qdict) { 9172abe02c0511b2278af9386e7ac5e266d890a38b1David Turner qdict = qdict_new(); 9182abe02c0511b2278af9386e7ac5e266d890a38b1David Turner } 9192abe02c0511b2278af9386e7ac5e266d890a38b1David Turner if (opts->id) { 9202abe02c0511b2278af9386e7ac5e266d890a38b1David Turner qdict_put(qdict, "id", qstring_from_str(opts->id)); 9212abe02c0511b2278af9386e7ac5e266d890a38b1David Turner } 9222abe02c0511b2278af9386e7ac5e266d890a38b1David Turner QTAILQ_FOREACH(opt, &opts->head, next) { 9232abe02c0511b2278af9386e7ac5e266d890a38b1David Turner val = QOBJECT(qstring_from_str(opt->str)); 9242abe02c0511b2278af9386e7ac5e266d890a38b1David Turner qdict_put_obj(qdict, opt->name, val); 9252abe02c0511b2278af9386e7ac5e266d890a38b1David Turner } 9262abe02c0511b2278af9386e7ac5e266d890a38b1David Turner return qdict; 9272abe02c0511b2278af9386e7ac5e266d890a38b1David Turner} 9282abe02c0511b2278af9386e7ac5e266d890a38b1David Turner 9292910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/* Validate parsed opts against descriptions where no 9302910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * descriptions were provided in the QemuOptsList. 9312910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner */ 9329251866320b5f8329a043bb56b3a794f78d12849David 'Digit' Turnerint qemu_opts_validate(QemuOpts *opts, const QemuOptDesc *desc) 9332910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{ 9342910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QemuOpt *opt; 9352910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 9362910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner assert(opts->list->desc[0].name == NULL); 9372910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 9382910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QTAILQ_FOREACH(opt, &opts->head, next) { 9392910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner int i; 9402910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 9412910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner for (i = 0; desc[i].name != NULL; i++) { 9422910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (strcmp(desc[i].name, opt->name) == 0) { 9432910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner break; 9442910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 9452910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 9462910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (desc[i].name == NULL) { 9472abe02c0511b2278af9386e7ac5e266d890a38b1David Turner qerror_report(QERR_INVALID_PARAMETER, opt->name); 9482910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return -1; 9492910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 9502910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 9512910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner opt->desc = &desc[i]; 9522910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 9532910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (qemu_opt_parse(opt) < 0) { 9542910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return -1; 9552910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 9562910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 9572910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 9582910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return 0; 9592910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} 9602910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 9612910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerint qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func, void *opaque, 9622910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner int abort_on_failure) 9632910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{ 9642abe02c0511b2278af9386e7ac5e266d890a38b1David Turner Location loc; 9652910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QemuOpts *opts; 9662910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner int rc = 0; 9672910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 9682abe02c0511b2278af9386e7ac5e266d890a38b1David Turner loc_push_none(&loc); 9692910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QTAILQ_FOREACH(opts, &list->head, next) { 9702abe02c0511b2278af9386e7ac5e266d890a38b1David Turner loc_restore(&opts->loc); 9719251866320b5f8329a043bb56b3a794f78d12849David 'Digit' Turner rc |= func(opts, opaque); 9722910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (abort_on_failure && rc != 0) 9732910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner break; 9742910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 9752abe02c0511b2278af9386e7ac5e266d890a38b1David Turner loc_pop(&loc); 9762910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return rc; 9772910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} 978