parse.c revision eef02441621aa969f01a1a331e0215dd587d25af
13ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 23ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * This file contains the ini and command liner parser main. 33ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 43ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include <stdio.h> 53ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include <stdlib.h> 63ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include <unistd.h> 73ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include <ctype.h> 83ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include <string.h> 93ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include <errno.h> 103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include <limits.h> 113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include <stdlib.h> 123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include <math.h> 133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include <float.h> 143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "parse.h" 163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "debug.h" 173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "options.h" 183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "minmax.h" 193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "lib/ieee754.h" 2045ef08fd6a09813e4a8f5ddadf85ba9e0ec2cdc7cristy 213ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic struct fio_option *fio_options; 223ed852eea50f9d4cd633efb8c2b054b8e33c253cristyextern unsigned int fio_get_kb_base(void *); 233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 243ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int vp_cmp(const void *p1, const void *p2) 253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const struct value_pair *vp1 = p1; 273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const struct value_pair *vp2 = p2; 283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return strlen(vp2->ival) - strlen(vp1->ival); 303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 323ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void posval_sort(struct fio_option *o, struct value_pair *vpmap) 333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const struct value_pair *vp; 353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy int entries; 363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy memset(vpmap, 0, PARSE_MAX_VP * sizeof(struct value_pair)); 383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (entries = 0; entries < PARSE_MAX_VP; entries++) { 403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy vp = &o->posval[entries]; 413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (!vp->ival || vp->ival[0] == '\0') 424c08aed51c5899665ade97263692328eea4af106cristy break; 434c08aed51c5899665ade97263692328eea4af106cristy 444c08aed51c5899665ade97263692328eea4af106cristy memcpy(&vpmap[entries], vp, sizeof(*vp)); 454c08aed51c5899665ade97263692328eea4af106cristy } 464c08aed51c5899665ade97263692328eea4af106cristy 474c08aed51c5899665ade97263692328eea4af106cristy qsort(vpmap, entries, sizeof(struct value_pair), vp_cmp); 484c08aed51c5899665ade97263692328eea4af106cristy} 494c08aed51c5899665ade97263692328eea4af106cristy 504c08aed51c5899665ade97263692328eea4af106cristystatic void show_option_range(struct fio_option *o, 514c08aed51c5899665ade97263692328eea4af106cristy int (*logger)(const char *format, ...)) 52030436f8fc9854b6bb39f4d7593d9e70ff83a8cacristy{ 534c08aed51c5899665ade97263692328eea4af106cristy if (o->type == FIO_OPT_FLOAT_LIST){ 54c53413df5789700e14e1a67e6cc2716d1716a387cristy if (o->minfp == DBL_MIN && o->maxfp == DBL_MAX) 554c08aed51c5899665ade97263692328eea4af106cristy return; 564c08aed51c5899665ade97263692328eea4af106cristy 574c08aed51c5899665ade97263692328eea4af106cristy logger("%20s: min=%f", "range", o->minfp); 584c08aed51c5899665ade97263692328eea4af106cristy if (o->maxfp != DBL_MAX) 594c08aed51c5899665ade97263692328eea4af106cristy logger(", max=%f", o->maxfp); 604c08aed51c5899665ade97263692328eea4af106cristy logger("\n"); 614c08aed51c5899665ade97263692328eea4af106cristy } else { 624c08aed51c5899665ade97263692328eea4af106cristy if (!o->minval && !o->maxval) 634c08aed51c5899665ade97263692328eea4af106cristy return; 644c08aed51c5899665ade97263692328eea4af106cristy 654c08aed51c5899665ade97263692328eea4af106cristy logger("%20s: min=%d", "range", o->minval); 664c08aed51c5899665ade97263692328eea4af106cristy if (o->maxval) 672c5fc27ae5b613b7fb9fd69c12a47b99c7d4d471cristy logger(", max=%d", o->maxval); 684c08aed51c5899665ade97263692328eea4af106cristy logger("\n"); 694c08aed51c5899665ade97263692328eea4af106cristy } 704c08aed51c5899665ade97263692328eea4af106cristy} 714c08aed51c5899665ade97263692328eea4af106cristy 724c08aed51c5899665ade97263692328eea4af106cristystatic void show_option_values(struct fio_option *o) 734c08aed51c5899665ade97263692328eea4af106cristy{ 744c08aed51c5899665ade97263692328eea4af106cristy int i; 754c08aed51c5899665ade97263692328eea4af106cristy 764c08aed51c5899665ade97263692328eea4af106cristy for (i = 0; i < PARSE_MAX_VP; i++) { 774c08aed51c5899665ade97263692328eea4af106cristy const struct value_pair *vp = &o->posval[i]; 784c08aed51c5899665ade97263692328eea4af106cristy 794c08aed51c5899665ade97263692328eea4af106cristy if (!vp->ival) 8063a81879d3568083e4ee4f78ebcae2bc831cb764cristy continue; 814c08aed51c5899665ade97263692328eea4af106cristy 82d1dd6e4fefa0810b9893e6ac9418f79c97c1b39acristy log_info("%20s: %-10s", i == 0 ? "valid values" : "", vp->ival); 834c08aed51c5899665ade97263692328eea4af106cristy if (vp->help) 84bcbda3fd7d9f3084869f5cebabceb0324c3b2cd7cristy log_info(" %s", vp->help); 854c08aed51c5899665ade97263692328eea4af106cristy log_info("\n"); 864c08aed51c5899665ade97263692328eea4af106cristy } 874c08aed51c5899665ade97263692328eea4af106cristy 883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (i) 893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy log_info("\n"); 903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 923ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void show_option_help(struct fio_option *o, int is_err) 933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const char *typehelp[] = { 953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy "invalid", 963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy "string (opt=bla)", 973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy "string (opt=bla)", 983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy "string with possible k/m/g postfix (opt=4k)", 993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy "string with time postfix (opt=10s)", 1003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy "string (opt=bla)", 1013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy "string with dual range (opt=1k-4k,4k-8k)", 1023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy "integer value (opt=100)", 1033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy "boolean value (opt=1)", 1043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy "list of floating point values separated by ':' (opt=5.9:7.8)", 1053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy "no argument (opt)", 1063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy "deprecated", 1073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy }; 1083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy int (*logger)(const char *format, ...); 1093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (is_err) 1113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy logger = log_err; 112ce70c17bb6433add2eb069515a4f3105989e0662cristy else 1133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy logger = log_info; 1143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1154c08aed51c5899665ade97263692328eea4af106cristy if (o->alias) 1167e9f233e6549b1e1856c1aa85b3f4dee8e9493facristy logger("%20s: %s\n", "alias", o->alias); 1177e9f233e6549b1e1856c1aa85b3f4dee8e9493facristy 1187e9f233e6549b1e1856c1aa85b3f4dee8e9493facristy logger("%20s: %s\n", "type", typehelp[o->type]); 1197e9f233e6549b1e1856c1aa85b3f4dee8e9493facristy logger("%20s: %s\n", "default", o->def ? o->def : "no default"); 1207e9f233e6549b1e1856c1aa85b3f4dee8e9493facristy if (o->prof_name) 1217e9f233e6549b1e1856c1aa85b3f4dee8e9493facristy logger("%20s: only for profile '%s'\n", "valid", o->prof_name); 1224c08aed51c5899665ade97263692328eea4af106cristy show_option_range(o, logger); 1234c08aed51c5899665ade97263692328eea4af106cristy show_option_values(o); 1244c08aed51c5899665ade97263692328eea4af106cristy} 1254c08aed51c5899665ade97263692328eea4af106cristy 1264c08aed51c5899665ade97263692328eea4af106cristystatic unsigned long get_mult_time(char c) 1274c08aed51c5899665ade97263692328eea4af106cristy{ 1284c08aed51c5899665ade97263692328eea4af106cristy switch (c) { 129ce70c17bb6433add2eb069515a4f3105989e0662cristy case 'm': 1303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case 'M': 1313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return 60; 132ce70c17bb6433add2eb069515a4f3105989e0662cristy case 'h': 1333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case 'H': 1343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return 60 * 60; 135bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy case 'd': 1367e9f233e6549b1e1856c1aa85b3f4dee8e9493facristy case 'D': 1377e9f233e6549b1e1856c1aa85b3f4dee8e9493facristy return 24 * 60 * 60; 1387e9f233e6549b1e1856c1aa85b3f4dee8e9493facristy default: 1393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return 1; 1403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 1413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 1423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1433ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic unsigned long long __get_mult_bytes(const char *p, void *data, 1443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy int *percent) 1453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 1463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int kb_base = fio_get_kb_base(data); 1473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned long long ret = 1; 1483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int i, pow = 0, mult = kb_base; 1493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy char *c; 1503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (!p) 1523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return 1; 1533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy c = strdup(p); 1553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (i = 0; i < strlen(c); i++) 1573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy c[i] = tolower(c[i]); 1583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (!strcmp("pib", c)) { 1603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy pow = 5; 1613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy mult = 1000; 1623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } else if (!strcmp("tib", c)) { 1633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy pow = 4; 1643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy mult = 1000; 1653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } else if (!strcmp("gib", c)) { 1663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy pow = 3; 1673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy mult = 1000; 1683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } else if (!strcmp("mib", c)) { 1693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy pow = 2; 1703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy mult = 1000; 1713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } else if (!strcmp("kib", c)) { 1723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy pow = 1; 1733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy mult = 1000; 1743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } else if (!strcmp("p", c) || !strcmp("pb", c)) 1753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy pow = 5; 1763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else if (!strcmp("t", c) || !strcmp("tb", c)) 1773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy pow = 4; 1783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else if (!strcmp("g", c) || !strcmp("gb", c)) 1793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy pow = 3; 1803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else if (!strcmp("m", c) || !strcmp("mb", c)) 1813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy pow = 2; 1823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else if (!strcmp("k", c) || !strcmp("kb", c)) 1833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy pow = 1; 1843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else if (!strcmp("%", c)) { 1853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *percent = 1; 1863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy free(c); 1873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return ret; 1883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 1893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy while (pow--) 1913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ret *= (unsigned long long) mult; 1923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 193bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy free(c); 1943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return ret; 1953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 1963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1973ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic unsigned long long get_mult_bytes(const char *str, int len, void *data, 1983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy int *percent) 1993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 2003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const char *p = str; 2013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy int digit_seen = 0; 2023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (len < 2) 2043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return __get_mult_bytes(str, data, percent); 2053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 2073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * Go forward until we hit a non-digit, or +/- sign 2083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 209a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy while ((p - str) <= len) { 2103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (!isdigit((int) *p) && 2113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (((*p != '+') && (*p != '-')) || digit_seen)) 2123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 2133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy digit_seen |= isdigit((int) *p); 2143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy p++; 2153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 2163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (!isalpha((int) *p) && (*p != '%')) 2183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy p = NULL; 219e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy 2203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return __get_mult_bytes(p, data, percent); 221e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy} 2223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 2243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * Convert string into a floating number. Return 1 for success and 0 otherwise. 2253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 2263ed852eea50f9d4cd633efb8c2b054b8e33c253cristyint str_to_float(const char *str, double *val) 2273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 2283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return (1 == sscanf(str, "%lf", val)); 2293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 2303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 2323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * convert string into decimal value, noting any size suffix 2333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 2343ed852eea50f9d4cd633efb8c2b054b8e33c253cristyint str_to_decimal(const char *str, long long *val, int kilo, void *data) 2353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 2363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy int len, base; 2373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy len = strlen(str); 2393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (!len) 2403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return 1; 2413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (strstr(str, "0x") || strstr(str, "0X")) 2433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy base = 16; 2443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 2453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy base = 10; 2463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *val = strtoll(str, NULL, base); 2483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (*val == LONG_MAX && errno == ERANGE) 2493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return 1; 2503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (kilo) { 2523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned long long mult; 2533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy int perc = 0; 2543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy mult = get_mult_bytes(str, len, data, &perc); 2563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (perc) 2573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *val = -1ULL - *val; 2583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 2593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *val *= mult; 2603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } else 2613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *val *= get_mult_time(str[len - 1]); 2623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return 0; 2643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 2653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2663ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int check_str_bytes(const char *p, long long *val, void *data) 2673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 2683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return str_to_decimal(p, val, 1, data); 2693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 2703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2713ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int check_str_time(const char *p, long long *val) 2723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 2733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return str_to_decimal(p, val, 0, NULL); 2743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 2753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2763ed852eea50f9d4cd633efb8c2b054b8e33c253cristyvoid strip_blank_front(char **p) 2773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 2783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy char *s = *p; 2793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (!strlen(s)) 2813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return; 2823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy while (isspace((int) *s)) 2833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy s++; 2843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *p = s; 2863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 2873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2883ed852eea50f9d4cd633efb8c2b054b8e33c253cristyvoid strip_blank_end(char *p) 2893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 2903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy char *start = p, *s; 2913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (!strlen(p)) 2933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return; 2943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy s = strchr(p, ';'); 2963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (s) 2973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *s = '\0'; 2983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy s = strchr(p, '#'); 2993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (s) 3003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *s = '\0'; 3013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (s) 3023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy p = s; 3033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 3043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy s = p + strlen(p); 3053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy while ((isspace((int) *s) || iscntrl((int) *s)) && (s > start)) 3063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy s--; 3073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 3083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *(s + 1) = '\0'; 3093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 3103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 3113ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int check_range_bytes(const char *str, long *val, void *data) 3123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 3133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy long long __val; 3143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 3153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (!str_to_decimal(str, &__val, 1, data)) { 3163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *val = __val; 3173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return 0; 3183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 3193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 3203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return 1; 3213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 3223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 3233ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int check_int(const char *p, int *val) 3243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 3253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (!strlen(p)) 3263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return 1; 3273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (strstr(p, "0x") || strstr(p, "0X")) { 3283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (sscanf(p, "%x", val) == 1) 3293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return 0; 3303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } else { 3313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (sscanf(p, "%u", val) == 1) 3323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return 0; 3333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 3343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 3353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return 1; 3363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 3373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 3383ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int opt_len(const char *str) 3393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 3403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy char *postfix; 3413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 3423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy postfix = strchr(str, ':'); 3433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (!postfix) 3443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return strlen(str); 3453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 3463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return (int)(postfix - str); 3473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 3483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 3493ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int str_match_len(const struct value_pair *vp, const char *str) 3503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 3513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return max(strlen(vp->ival), opt_len(str)); 3523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 3533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 3543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define val_store(ptr, val, off, or, data) \ 3553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy do { \ 3563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ptr = td_var((data), (off)); \ 3573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if ((or)) \ 3583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *ptr |= (val); \ 3593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else \ 3603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *ptr = (val); \ 3613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } while (0) 3623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 3633ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int __handle_option(struct fio_option *o, const char *ptr, void *data, 3643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy int first, int more, int curr) 3653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 366f2faecf9facdbbb14fcba373365f9f691a9658e0cristy int il, *ilp; 367f2faecf9facdbbb14fcba373365f9f691a9658e0cristy fio_fp64_t *flp; 3683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy long long ull, *ullp; 3693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy long ul1, ul2; 3703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy double uf; 3713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy char **cp = NULL; 3723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy int ret = 0, is_time = 0; 3733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const struct value_pair *vp; 3743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy struct value_pair posval[PARSE_MAX_VP]; 3753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy int i, all_skipped = 1; 376f2faecf9facdbbb14fcba373365f9f691a9658e0cristy 377f2faecf9facdbbb14fcba373365f9f691a9658e0cristy dprint(FD_PARSE, "__handle_option=%s, type=%d, ptr=%s\n", o->name, 3783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy o->type, ptr); 3793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 3803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (!ptr && o->type != FIO_OPT_STR_SET && o->type != FIO_OPT_STR) { 3813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy log_err("Option %s requires an argument\n", o->name); 3823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return 1; 3833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 3843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 3853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy switch (o->type) { 3863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case FIO_OPT_STR: 3873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case FIO_OPT_STR_MULTI: { 3883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy fio_opt_str_fn *fn = o->cb; 3893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 3903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy posval_sort(o, posval); 3913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 3923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ret = 1; 3933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (i = 0; i < PARSE_MAX_VP; i++) { 3943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy vp = &posval[i]; 395c9cc4a7b1dd605daff0dd2e0b0e1c42f178871ddcristy if (!vp->ival || vp->ival[0] == '\0') 396c9cc4a7b1dd605daff0dd2e0b0e1c42f178871ddcristy continue; 397c9cc4a7b1dd605daff0dd2e0b0e1c42f178871ddcristy all_skipped = 0; 398c9cc4a7b1dd605daff0dd2e0b0e1c42f178871ddcristy if (!strncmp(vp->ival, ptr, str_match_len(vp, ptr))) { 399c9cc4a7b1dd605daff0dd2e0b0e1c42f178871ddcristy ret = 0; 400c9cc4a7b1dd605daff0dd2e0b0e1c42f178871ddcristy if (o->roff1) { 4013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (vp->or) 4023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *(unsigned int *) o->roff1 |= vp->oval; 4033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 4043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *(unsigned int *) o->roff1 = vp->oval; 4053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } else { 4063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (!o->off1) 4073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy continue; 4083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy val_store(ilp, vp->oval, o->off1, vp->or, data); 4093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 4103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy continue; 4113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 4123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 4133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 4143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (ret && !all_skipped) 4153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy show_option_values(o); 4163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else if (fn) 4173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ret = fn(data, ptr); 4183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 4193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 4203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case FIO_OPT_STR_VAL_TIME: 4213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy is_time = 1; 4223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case FIO_OPT_INT: 4233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case FIO_OPT_STR_VAL: { 4243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy fio_opt_str_val_fn *fn = o->cb; 4253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy char tmp[128], *p; 4263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 4273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy strncpy(tmp, ptr, sizeof(tmp) - 1); 4283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy p = strchr(tmp, ','); 4293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (p) 4303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *p = '\0'; 4313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 4323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (is_time) 4333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ret = check_str_time(tmp, &ull); 4343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 4353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ret = check_str_bytes(tmp, &ull, data); 4363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 4373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (ret) 4383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 4393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 4403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (o->maxval && ull > o->maxval) { 4413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy log_err("max value out of range: %llu" 4423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy " (%u max)\n", ull, o->maxval); 4433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return 1; 4443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 4453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (o->minval && ull < o->minval) { 4463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy log_err("min value out of range: %llu" 4473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy " (%u min)\n", ull, o->minval); 4487c3af951210f34d3f244b31f06ee291e5be8ecb7cristy return 1; 4497c3af951210f34d3f244b31f06ee291e5be8ecb7cristy } 4503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 4513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (fn) 4523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ret = fn(data, &ull); 4533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else { 4543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (o->type == FIO_OPT_INT) { 4553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (first) { 4563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (o->roff1) 4573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *(unsigned int *) o->roff1 = ull; 4583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 4593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy val_store(ilp, ull, o->off1, 0, data); 4603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 4613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (curr == 1) { 4627c3af951210f34d3f244b31f06ee291e5be8ecb7cristy if (o->roff2) 4637c3af951210f34d3f244b31f06ee291e5be8ecb7cristy *(unsigned int *) o->roff2 = ull; 4643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else if (o->off2) 465bcbda3fd7d9f3084869f5cebabceb0324c3b2cd7cristy val_store(ilp, ull, o->off2, 0, data); 4667c3af951210f34d3f244b31f06ee291e5be8ecb7cristy } 4677c3af951210f34d3f244b31f06ee291e5be8ecb7cristy if (curr == 2) { 4683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (o->roff3) 469c57f694b2d04975a0e501613e34368c464708c19cristy *(unsigned int *) o->roff3 = ull; 470c57f694b2d04975a0e501613e34368c464708c19cristy else if (o->off3) 471c57f694b2d04975a0e501613e34368c464708c19cristy val_store(ilp, ull, o->off3, 0, data); 4723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 4733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (!more) { 4743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (curr < 1) { 4753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (o->roff2) 4763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *(unsigned int *) o->roff2 = ull; 4773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else if (o->off2) 4783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy val_store(ilp, ull, o->off2, 0, data); 4793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 4803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (curr < 2) { 4813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (o->roff3) 482b0a657e13c4aefba39c51292005427b47277869dcristy *(unsigned int *) o->roff3 = ull; 483b0a657e13c4aefba39c51292005427b47277869dcristy else if (o->off3) 4843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy val_store(ilp, ull, o->off3, 0, data); 4853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 4863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 4873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } else { 4883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (first) { 4893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (o->roff1) 4903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *(unsigned long long *) o->roff1 = ull; 4913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 4923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy val_store(ullp, ull, o->off1, 0, data); 4933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 4943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (!more) { 4953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (o->roff2) 4963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *(unsigned long long *) o->roff2 = ull; 4973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else if (o->off2) 4983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy val_store(ullp, ull, o->off2, 0, data); 4993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 5003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 5013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 5023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 5033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 5043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case FIO_OPT_FLOAT_LIST: { 5053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy char *cp2; 5063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 5073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (first) { 5083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 5093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ** Initialize precision to 0 and zero out list 5103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ** in case specified list is shorter than default 5113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 5123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ul2 = 0; 5133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ilp = td_var(data, o->off2); 5143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *ilp = ul2; 5153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 5163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy flp = td_var(data, o->off1); 5173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for(i = 0; i < o->maxlen; i++) 5183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy flp[i].u.f = 0.0; 5193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 5203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (curr >= o->maxlen) { 5213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy log_err("the list exceeding max length %d\n", 5223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy o->maxlen); 523bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy return 1; 5243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 525c57f694b2d04975a0e501613e34368c464708c19cristy if (!str_to_float(ptr, &uf)) { 526c57f694b2d04975a0e501613e34368c464708c19cristy log_err("not a floating point value: %s\n", ptr); 5273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return 1; 5283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 5293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (uf > o->maxfp) { 5303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy log_err("value out of range: %f" 5313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy " (range max: %f)\n", uf, o->maxfp); 5323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return 1; 5333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 5343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (uf < o->minfp) { 5353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy log_err("value out of range: %f" 5363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy " (range min: %f)\n", uf, o->minfp); 5373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return 1; 5383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 5393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 5403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy flp = td_var(data, o->off1); 5413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy flp[curr].u.f = uf; 5423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 5433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 5443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ** Calculate precision for output by counting 5453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ** number of digits after period. Find first 5463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ** period in entire remaining list each time 5476710d8414f0ed06e4eaf9346366be72e2b4719efcristy */ 5483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy cp2 = strchr(ptr, '.'); 5493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (cp2 != NULL) { 5503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy int len = 0; 5513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 5523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy while (*++cp2 != '\0' && *cp2 >= '0' && *cp2 <= '9') 5533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy len++; 5543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 5553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ilp = td_var(data, o->off2); 5563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (len > *ilp) 5573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *ilp = len; 5583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 5593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 560f05d4947caf1bc27fbec041eb37c474a80c83c0bcristy break; 561f05d4947caf1bc27fbec041eb37c474a80c83c0bcristy } 5623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case FIO_OPT_STR_STORE: { 5638a46d827a124555f0c48fb2368ec1bba8e079ab6cristy fio_opt_str_fn *fn = o->cb; 5646f5395df39e037392db46729f9aab05f2a9a428fcristy 5653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (o->roff1 || o->off1) { 5663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (o->roff1) 567c57f694b2d04975a0e501613e34368c464708c19cristy cp = (char **) o->roff1; 5683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else if (o->off1) 5693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy cp = td_var(data, o->off1); 5704c08aed51c5899665ade97263692328eea4af106cristy 571c47d1f8ecfe7d04f0f003cca0fe175658bbf0fb2cristy *cp = strdup(ptr); 5723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 573c57f694b2d04975a0e501613e34368c464708c19cristy 574c57f694b2d04975a0e501613e34368c464708c19cristy if (fn) 575acd2ed254c18c254a0ab5aafa06d1645e5d079d8cristy ret = fn(data, ptr); 5763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else if (o->posval[0].ival) { 577c57f694b2d04975a0e501613e34368c464708c19cristy posval_sort(o, posval); 5783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 5794c08aed51c5899665ade97263692328eea4af106cristy ret = 1; 5803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (i = 0; i < PARSE_MAX_VP; i++) { 5813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy vp = &posval[i]; 5823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (!vp->ival || vp->ival[0] == '\0') 5833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy continue; 5843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy all_skipped = 0; 5854c08aed51c5899665ade97263692328eea4af106cristy if (!strncmp(vp->ival, ptr, str_match_len(vp, ptr))) { 5864c08aed51c5899665ade97263692328eea4af106cristy char *rest; 5874c08aed51c5899665ade97263692328eea4af106cristy 5884c08aed51c5899665ade97263692328eea4af106cristy ret = 0; 5894c08aed51c5899665ade97263692328eea4af106cristy if (vp->cb) 5904c08aed51c5899665ade97263692328eea4af106cristy fn = vp->cb; 5913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy rest = strstr(*cp ?: ptr, ":"); 5923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (rest) { 5934c08aed51c5899665ade97263692328eea4af106cristy if (*cp) 5943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *rest = '\0'; 5953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ptr = rest + 1; 5963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } else 5973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ptr = NULL; 5983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 5993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 6004c08aed51c5899665ade97263692328eea4af106cristy } 6014c08aed51c5899665ade97263692328eea4af106cristy } 6024c08aed51c5899665ade97263692328eea4af106cristy 6034c08aed51c5899665ade97263692328eea4af106cristy if (!all_skipped) { 6044c08aed51c5899665ade97263692328eea4af106cristy if (ret && !*cp) 6054c08aed51c5899665ade97263692328eea4af106cristy show_option_values(o); 6063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else if (ret && *cp) 6074c08aed51c5899665ade97263692328eea4af106cristy ret = 0; 6083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else if (fn && ptr) 609ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy ret = fn(data, ptr); 6103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 611c57f694b2d04975a0e501613e34368c464708c19cristy 6123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 6133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 614c57f694b2d04975a0e501613e34368c464708c19cristy case FIO_OPT_RANGE: { 6153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy char tmp[128]; 6163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy char *p1, *p2; 6173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 6183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy strncpy(tmp, ptr, sizeof(tmp) - 1); 6193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 6203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* Handle bsrange with separate read,write values: */ 6213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy p1 = strchr(tmp, ','); 6223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (p1) 6233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *p1 = '\0'; 6243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 6253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy p1 = strchr(tmp, '-'); 6263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (!p1) { 6273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy p1 = strchr(tmp, ':'); 6283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (!p1) { 629b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy ret = 1; 6303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 631e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy } 632e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy } 6333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 6343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy p2 = p1 + 1; 6353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *p1 = '\0'; 6363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy p1 = tmp; 6373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 6383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ret = 1; 6393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (!check_range_bytes(p1, &ul1, data) && 6403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy !check_range_bytes(p2, &ul2, data)) { 6413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ret = 0; 642a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy if (ul1 > ul2) { 6433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned long foo = ul1; 6443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 6453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ul1 = ul2; 6463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ul2 = foo; 6473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 6486710d8414f0ed06e4eaf9346366be72e2b4719efcristy 6493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (first) { 6503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (o->roff1) 6513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *(unsigned int *) o->roff1 = ul1; 6523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 6533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy val_store(ilp, ul1, o->off1, 0, data); 6543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (o->roff2) 6553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *(unsigned int *) o->roff2 = ul2; 6563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 6573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy val_store(ilp, ul2, o->off2, 0, data); 6583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 6593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (curr == 1) { 6603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (o->roff3 && o->roff4) { 6613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *(unsigned int *) o->roff3 = ul1; 6623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *(unsigned int *) o->roff4 = ul2; 6633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } else if (o->off3 && o->off4) { 6643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy val_store(ilp, ul1, o->off3, 0, data); 6653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy val_store(ilp, ul2, o->off4, 0, data); 6663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 6673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 6683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (curr == 2) { 6693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (o->roff5 && o->roff6) { 6703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *(unsigned int *) o->roff5 = ul1; 6713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *(unsigned int *) o->roff6 = ul2; 6723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } else if (o->off5 && o->off6) { 6733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy val_store(ilp, ul1, o->off5, 0, data); 6743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy val_store(ilp, ul2, o->off6, 0, data); 6753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 6763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 6773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (!more) { 6783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (curr < 1) { 6793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (o->roff3 && o->roff4) { 6803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *(unsigned int *) o->roff3 = ul1; 6813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *(unsigned int *) o->roff4 = ul2; 6823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } else if (o->off3 && o->off4) { 6833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy val_store(ilp, ul1, o->off3, 0, data); 6843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy val_store(ilp, ul2, o->off4, 0, data); 6853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 6863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 6873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (curr < 2) { 6883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (o->roff5 && o->roff6) { 6893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *(unsigned int *) o->roff5 = ul1; 6903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *(unsigned int *) o->roff6 = ul2; 6913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } else if (o->off5 && o->off6) { 6923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy val_store(ilp, ul1, o->off5, 0, data); 6933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy val_store(ilp, ul2, o->off6, 0, data); 6943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 6953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 6963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 6973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 698b0a657e13c4aefba39c51292005427b47277869dcristy 699feb3e9695150978a5d2372d3fe2f60466a7c8066cristy break; 700b0a657e13c4aefba39c51292005427b47277869dcristy } 701b0a657e13c4aefba39c51292005427b47277869dcristy case FIO_OPT_BOOL: 702b0a657e13c4aefba39c51292005427b47277869dcristy case FIO_OPT_STR_SET: { 7033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy fio_opt_int_fn *fn = o->cb; 7043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (ptr) 7063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ret = check_int(ptr, &il); 7073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else if (o->type == FIO_OPT_BOOL) 7083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ret = 1; 7093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 7103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy il = 1; 7113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (ret) 7133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 7143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (o->maxval && il > (int) o->maxval) { 7163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy log_err("max value out of range: %d (%d max)\n", 7173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy il, o->maxval); 7183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return 1; 7193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 7203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (o->minval && il < o->minval) { 7213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy log_err("min value out of range: %d (%d min)\n", 7223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy il, o->minval); 7233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return 1; 7243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 7253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (o->neg) 7273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy il = !il; 7283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (fn) 7303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ret = fn(data, &il); 7313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else { 7323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (first) { 7333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (o->roff1) 7343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *(unsigned int *)o->roff1 = il; 7353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 7363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy val_store(ilp, il, o->off1, 0, data); 7373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 7383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (!more) { 7393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (o->roff2) 7403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *(unsigned int *) o->roff2 = il; 7413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else if (o->off2) 7423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy val_store(ilp, il, o->off2, 0, data); 7433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 7443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 7453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 7463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 7473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case FIO_OPT_DEPRECATED: 7483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy log_info("Option %s is deprecated\n", o->name); 7493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 7503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy default: 7513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy log_err("Bad option type %u\n", o->type); 7523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ret = 1; 7533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 7543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (ret) 7563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return ret; 7573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (o->verify) { 7593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ret = o->verify(o, data); 7603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (ret) { 7613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy log_err("Correct format for offending option\n"); 7623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy log_err("%20s: %s\n", o->name, o->help); 7633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy show_option_help(o, 1); 7643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 7653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 7663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return ret; 7683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 7693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7703ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int handle_option(struct fio_option *o, const char *__ptr, void *data) 7713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 7723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy char *o_ptr, *ptr, *ptr2; 7733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy int ret, done; 7743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy dprint(FD_PARSE, "handle_option=%s, ptr=%s\n", o->name, __ptr); 7763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy o_ptr = ptr = NULL; 7783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (__ptr) 7793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy o_ptr = ptr = strdup(__ptr); 7803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 7823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * See if we have another set of parameters, hidden after a comma. 7833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * Do this before parsing this round, to check if we should 7843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * copy set 1 options to set 2. 7853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 7863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy done = 0; 7873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ret = 1; 7883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy do { 7893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy int __ret; 7903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ptr2 = NULL; 792bcbda3fd7d9f3084869f5cebabceb0324c3b2cd7cristy if (ptr && 7933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (o->type != FIO_OPT_STR_STORE) && 7943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (o->type != FIO_OPT_STR) && 7953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (o->type != FIO_OPT_FLOAT_LIST)) { 7963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ptr2 = strchr(ptr, ','); 7973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (ptr2 && *(ptr2 + 1) == '\0') 7983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *ptr2 = '\0'; 7993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (o->type != FIO_OPT_STR_MULTI && o->type != FIO_OPT_RANGE) { 8003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (!ptr2) 8013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ptr2 = strchr(ptr, ':'); 8023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (!ptr2) 8033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ptr2 = strchr(ptr, '-'); 8043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 8053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } else if (ptr && o->type == FIO_OPT_FLOAT_LIST) { 8063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ptr2 = strchr(ptr, ':'); 8073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 8083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 8093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 8103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * Don't return early if parsing the first option fails - if 8113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * we are doing multiple arguments, we can allow the first one 8123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * being empty. 8133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 8143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy __ret = __handle_option(o, ptr, data, !done, !!ptr2, done); 8153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (ret) 8163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ret = __ret; 8173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 8183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (!ptr2) 8193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 8203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 8213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ptr = ptr2 + 1; 8223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy done++; 8233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } while (1); 8243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 8253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (o_ptr) 8263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy free(o_ptr); 8273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return ret; 8283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 8293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 8303ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic struct fio_option *get_option(char *opt, 8313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy struct fio_option *options, char **post) 8323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 8333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy struct fio_option *o; 8343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy char *ret; 8353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 8363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ret = strchr(opt, '='); 8373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (ret) { 8383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *post = ret; 8393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *ret = '\0'; 8403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ret = opt; 8413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (*post)++; 8423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy strip_blank_end(ret); 8433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy o = find_option(options, ret); 8443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } else { 8453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy o = find_option(options, opt); 8463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *post = NULL; 8473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 8483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 8493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return o; 8503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 8513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 8523ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int opt_cmp(const void *p1, const void *p2) 8533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 8543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy struct fio_option *o; 8553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy char *s, *foo; 8563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy int prio1, prio2; 8573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 8583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy prio1 = prio2 = 0; 8593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 8603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (*(char **)p1) { 8613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy s = strdup(*((char **) p1)); 8623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy o = get_option(s, fio_options, &foo); 8633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (o) 8643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy prio1 = o->prio; 8653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy free(s); 8663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 8673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (*(char **)p2) { 8683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy s = strdup(*((char **) p2)); 8693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy o = get_option(s, fio_options, &foo); 8703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (o) 8713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy prio2 = o->prio; 8723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy free(s); 8733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 8743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 8753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return prio2 - prio1; 8763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 8773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 8783ed852eea50f9d4cd633efb8c2b054b8e33c253cristyvoid sort_options(char **opts, struct fio_option *options, int num_opts) 8793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 8803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy fio_options = options; 8813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy qsort(opts, num_opts, sizeof(char *), opt_cmp); 8823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy fio_options = NULL; 8833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 8843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 8853ed852eea50f9d4cd633efb8c2b054b8e33c253cristyint parse_cmd_option(const char *opt, const char *val, 8863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy struct fio_option *options, void *data) 8873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 8883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy struct fio_option *o; 8893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 8903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy o = find_option(options, opt); 8913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (!o) { 8923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy log_err("Bad option <%s>\n", opt); 8933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return 1; 8943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 8953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 8963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (!handle_option(o, val, data)) 8973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return 0; 8983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 8993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy log_err("fio: failed parsing %s=%s\n", opt, val); 900bcbda3fd7d9f3084869f5cebabceb0324c3b2cd7cristy return 1; 9013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 9023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 9033ed852eea50f9d4cd633efb8c2b054b8e33c253cristyint parse_option(char *opt, const char *input, 9043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy struct fio_option *options, struct fio_option **o, void *data) 9053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 9063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy char *post; 907a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy 9083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (!opt) { 9093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy log_err("fio: failed parsing %s\n", input); 9103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *o = NULL; 9113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return 1; 9123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 9133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 9143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *o = get_option(opt, options, &post); 9153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (!*o) { 9163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (post) { 9173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy int len = strlen(opt); 9183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (opt + len + 1 != post) 9193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy memmove(opt + len + 1, post, strlen(post)); 9203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy opt[len] = '='; 9213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 9223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return 1; 9233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 9243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 9253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (!handle_option(*o, post, data)) { 9263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return 0; 9273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 9283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 9293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy log_err("fio: failed parsing %s\n", input); 9303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return 1; 9313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 9323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 9333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 9343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * Option match, levenshtein distance. Handy for not quite remembering what 9353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * the option name is. 9363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 9373ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int string_distance(const char *s1, const char *s2) 9383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 9393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int s1_len = strlen(s1); 9403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int s2_len = strlen(s2); 9413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int *p, *q, *r; 9423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int i, j; 9433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 9443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy p = malloc(sizeof(unsigned int) * (s2_len + 1)); 9453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy q = malloc(sizeof(unsigned int) * (s2_len + 1)); 9463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 9473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy p[0] = 0; 9483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (i = 1; i <= s2_len; i++) 9493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy p[i] = p[i - 1] + 1; 9503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 9513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (i = 1; i <= s1_len; i++) { 9523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy q[0] = p[0] + 1; 9533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (j = 1; j <= s2_len; j++) { 9543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int sub = p[j - 1]; 9553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 9563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (s1[i - 1] != s2[j - 1]) 9573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy sub++; 9583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 9593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy q[j] = min(p[j] + 1, min(q[j - 1] + 1, sub)); 9603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 9613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy r = p; 9623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy p = q; 9633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy q = r; 9643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 9653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 9663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy i = p[s2_len]; 9673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy free(p); 968a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy free(q); 969a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy return i; 970a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy} 9713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 9723ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic struct fio_option *find_child(struct fio_option *options, 9733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy struct fio_option *o) 9743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 9753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy struct fio_option *__o; 9763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 9773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (__o = options + 1; __o->name; __o++) 9783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (__o->parent && !strcmp(__o->parent, o->name)) 9793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return __o; 9803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 9813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return NULL; 9823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 9833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 9843ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void __print_option(struct fio_option *o, struct fio_option *org, 9853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy int level) 9863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 9873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy char name[256], *p; 9883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy int depth; 9893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 9903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (!o) 9913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return; 9923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (!org) 9933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy org = o; 9943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 9953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy p = name; 9963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy depth = level; 9973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy while (depth--) 9983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy p += sprintf(p, "%s", " "); 9993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 10003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy sprintf(p, "%s", o->name); 10013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 10023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy log_info("%-24s: %s\n", name, o->help); 10033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 10043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 10053ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void print_option(struct fio_option *o) 10063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 10073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy struct fio_option *parent; 10083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy struct fio_option *__o; 10093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int printed; 10103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int level; 10113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 10123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy __print_option(o, NULL, 0); 10133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy parent = o; 10143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy level = 0; 10153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy do { 10163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy level++; 10173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy printed = 0; 10183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 10193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy while ((__o = find_child(o, parent)) != NULL) { 10203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy __print_option(__o, o, level); 10213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy o = __o; 10223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy printed++; 10233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 10243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 10253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy parent = o; 10263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } while (printed); 10273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 1028bcbda3fd7d9f3084869f5cebabceb0324c3b2cd7cristy 10293ed852eea50f9d4cd633efb8c2b054b8e33c253cristyint show_cmd_help(struct fio_option *options, const char *name) 10303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 10313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy struct fio_option *o, *closest; 10323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int best_dist = -1U; 10333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy int found = 0; 10344c08aed51c5899665ade97263692328eea4af106cristy int show_all = 0; 10353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 10363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (!name || !strcmp(name, "all")) 1037a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy show_all = 1; 10383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 10393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy closest = NULL; 1040a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy best_dist = -1; 10413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (o = &options[0]; o->name; o++) { 10423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy int match = 0; 10433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 10443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (o->type == FIO_OPT_DEPRECATED) 10453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy continue; 10463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (!exec_profile && o->prof_name) 10473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy continue; 10483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 10493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (name) { 10503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (!strcmp(name, o->name) || 10513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (o->alias && !strcmp(name, o->alias))) 10523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy match = 1; 10533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else { 10543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int dist; 10553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 10563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy dist = string_distance(name, o->name); 10573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (dist < best_dist) { 10583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy best_dist = dist; 10593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy closest = o; 10603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 10613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 10623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 10633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 10643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (show_all || match) { 10653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy found = 1; 10663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (match) 10673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy log_info("%20s: %s\n", o->name, o->help); 10683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (show_all) { 10693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (!o->parent) 10703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy print_option(o); 10713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy continue; 10723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 1073bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy } 10743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 10753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (!match) 10763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy continue; 10773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1078a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy show_option_help(o, 0); 10793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 10803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 10813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (found) 10823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return 0; 1083a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy 10843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy log_err("No such command: %s", name); 10853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 10863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 1087a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy * Only print an appropriately close option, one where the edit 10883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * distance isn't too big. Otherwise we get crazy matches. 10893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 10903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (closest && best_dist < 3) { 1091a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy log_info(" - showing closest match\n"); 10923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy log_info("%20s: %s\n", closest->name, closest->help); 10933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy show_option_help(closest, 0); 10943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } else 10953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy log_info("\n"); 10963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 10973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return 1; 10983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 10993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 11003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 11013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * Handle parsing of default parameters. 11023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 11033ed852eea50f9d4cd633efb8c2b054b8e33c253cristyvoid fill_default_options(void *data, struct fio_option *options) 11043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 11053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy struct fio_option *o; 11063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 11073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy dprint(FD_PARSE, "filling default options\n"); 11083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 11093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (o = &options[0]; o->name; o++) 11103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (o->def) 11113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy handle_option(o, o->def, data); 11123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 11133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 11143ed852eea50f9d4cd633efb8c2b054b8e33c253cristyvoid option_init(struct fio_option *o) 11153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 11163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (o->type == FIO_OPT_DEPRECATED) 11173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return; 11183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (o->type == FIO_OPT_BOOL) { 11193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy o->minval = 0; 11203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy o->maxval = 1; 11213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 11223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (o->type == FIO_OPT_INT) { 11233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (!o->maxval) 11243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy o->maxval = UINT_MAX; 11253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 11263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (o->type == FIO_OPT_FLOAT_LIST) { 11273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy o->minfp = DBL_MIN; 11283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy o->maxfp = DBL_MAX; 11293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 11303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (o->type == FIO_OPT_STR_SET && o->def) { 11313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy log_err("Option %s: string set option with" 11323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy " default will always be true\n", o->name); 11333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 11343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (!o->cb && (!o->off1 && !o->roff1)) 11353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy log_err("Option %s: neither cb nor offset given\n", o->name); 11363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (o->type == FIO_OPT_STR || o->type == FIO_OPT_STR_STORE || 11373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy o->type == FIO_OPT_STR_MULTI) 11383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return; 11393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (o->cb && ((o->off1 || o->off2 || o->off3 || o->off4) || 11403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (o->roff1 || o->roff2 || o->roff3 || o->roff4))) { 11413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy log_err("Option %s: both cb and offset given\n", o->name); 11423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 11433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 11443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 11453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 11463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * Sanitize the options structure. For now it just sets min/max for bool 11473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * values and whether both callback and offsets are given. 11483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 11493ed852eea50f9d4cd633efb8c2b054b8e33c253cristyvoid options_init(struct fio_option *options) 11503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 11513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy struct fio_option *o; 11523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 11533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy dprint(FD_PARSE, "init options\n"); 11543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 11553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (o = &options[0]; o->name; o++) 11563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy option_init(o); 1157bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy} 11583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 11593ed852eea50f9d4cd633efb8c2b054b8e33c253cristyvoid options_free(struct fio_option *options, void *data) 11603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 11613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy struct fio_option *o; 11623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy char **ptr; 11633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 11643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy dprint(FD_PARSE, "free options\n"); 1165bcbda3fd7d9f3084869f5cebabceb0324c3b2cd7cristy 11663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (o = &options[0]; o->name; o++) { 11673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (o->type != FIO_OPT_STR_STORE || !o->off1) 11683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy continue; 11693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 11703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ptr = td_var(data, o->off1); 11713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (*ptr) { 11723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy free(*ptr); 11733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *ptr = NULL; 11743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 11753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 11763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 11773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy