parse.c revision 0c9baf913d6d251973798048d29c60507f486ee6
1afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner/* 27c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell * This file contains the ini and command liner parser main. 37c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell */ 47c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell#include <stdio.h> 57c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell#include <stdlib.h> 67c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell#include <unistd.h> 77c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell#include <ctype.h> 87c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell#include <string.h> 9afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner#include <errno.h> 10efdc0b505712d1ca4460def27e51c430f033d58dChris Lattner#include <limits.h> 11efdc0b505712d1ca4460def27e51c430f033d58dChris Lattner 12afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner#include "parse.h" 13afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 14afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattnerstatic unsigned long get_mult_time(char c) 15afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner{ 16e49603d79d220a795bd50684c8b1f503ee40f97fMisha Brukman switch (c) { 17afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner case 'm': 18afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner case 'M': 19d1a85a744cc1001c2b7fc37cf37aca266964f519Brian Gaeke return 60; 20e49603d79d220a795bd50684c8b1f503ee40f97fMisha Brukman case 'h': 21e49603d79d220a795bd50684c8b1f503ee40f97fMisha Brukman case 'H': 22afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner return 60 * 60; 236520785dcd22012535934098942d57c07c7631c2Chris Lattner case 'd': 24afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner case 'D': 255e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner return 24 * 60 * 60; 265da69c79f9c4490c6657c207430dfeb1060fc4ddChris Lattner default: 27551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer return 1; 28551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer } 29551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer} 30fb4b96e77e2930bf3d0c148f1c3685b6a4434666Chris Lattner 31c6b519d64ef55d39e66a49510d4703a49bf228ccChris Lattnerstatic unsigned long get_mult_bytes(char c) 32d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke{ 33d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke switch (c) { 34c6b519d64ef55d39e66a49510d4703a49bf228ccChris Lattner case 'k': 35d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke case 'K': 36d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke return 1024; 376db70ef879916e6115ac97eb76e4fea973652e2cChris Lattner case 'm': 386db70ef879916e6115ac97eb76e4fea973652e2cChris Lattner case 'M': 396db70ef879916e6115ac97eb76e4fea973652e2cChris Lattner return 1024 * 1024; 406db70ef879916e6115ac97eb76e4fea973652e2cChris Lattner case 'g': 4147ae4a1cee5eec5767a11403c0fac7c91ec45461Chris Lattner case 'G': 4247ae4a1cee5eec5767a11403c0fac7c91ec45461Chris Lattner return 1024 * 1024 * 1024; 436db70ef879916e6115ac97eb76e4fea973652e2cChris Lattner default: 446db70ef879916e6115ac97eb76e4fea973652e2cChris Lattner return 1; 45afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner } 466520785dcd22012535934098942d57c07c7631c2Chris Lattner} 476520785dcd22012535934098942d57c07c7631c2Chris Lattner 486520785dcd22012535934098942d57c07c7631c2Chris Lattner/* 496520785dcd22012535934098942d57c07c7631c2Chris Lattner * convert string into decimal value, noting any size suffix 506520785dcd22012535934098942d57c07c7631c2Chris Lattner */ 510cc8807029f577996a442b96d24c3346ed6de091Chris Lattnerstatic int str_to_decimal(const char *str, long long *val, int kilo) 526520785dcd22012535934098942d57c07c7631c2Chris Lattner{ 536520785dcd22012535934098942d57c07c7631c2Chris Lattner int len; 546520785dcd22012535934098942d57c07c7631c2Chris Lattner 550cc8807029f577996a442b96d24c3346ed6de091Chris Lattner len = strlen(str); 560cc8807029f577996a442b96d24c3346ed6de091Chris Lattner if (!len) 576520785dcd22012535934098942d57c07c7631c2Chris Lattner return 1; 586520785dcd22012535934098942d57c07c7631c2Chris Lattner 590cc8807029f577996a442b96d24c3346ed6de091Chris Lattner *val = strtol(str, NULL, 10); 600cc8807029f577996a442b96d24c3346ed6de091Chris Lattner if (*val == LONG_MAX && errno == ERANGE) 616520785dcd22012535934098942d57c07c7631c2Chris Lattner return 1; 626520785dcd22012535934098942d57c07c7631c2Chris Lattner 630cc8807029f577996a442b96d24c3346ed6de091Chris Lattner if (kilo) 646520785dcd22012535934098942d57c07c7631c2Chris Lattner *val *= get_mult_bytes(str[len - 1]); 656520785dcd22012535934098942d57c07c7631c2Chris Lattner else 660cc8807029f577996a442b96d24c3346ed6de091Chris Lattner *val *= get_mult_time(str[len - 1]); 670cc8807029f577996a442b96d24c3346ed6de091Chris Lattner 686520785dcd22012535934098942d57c07c7631c2Chris Lattner return 0; 696520785dcd22012535934098942d57c07c7631c2Chris Lattner} 700cc8807029f577996a442b96d24c3346ed6de091Chris Lattner 710cc8807029f577996a442b96d24c3346ed6de091Chris Lattnerstatic int check_str_bytes(const char *p, long long *val) 726520785dcd22012535934098942d57c07c7631c2Chris Lattner{ 736520785dcd22012535934098942d57c07c7631c2Chris Lattner return str_to_decimal(p, val, 1); 740cc8807029f577996a442b96d24c3346ed6de091Chris Lattner} 756520785dcd22012535934098942d57c07c7631c2Chris Lattner 7644be25716628941b4cccccf56a28ee0ba2606850Chris Lattnerstatic int check_str_time(const char *p, long long *val) 776520785dcd22012535934098942d57c07c7631c2Chris Lattner{ 785da69c79f9c4490c6657c207430dfeb1060fc4ddChris Lattner return str_to_decimal(p, val, 0); 795da69c79f9c4490c6657c207430dfeb1060fc4ddChris Lattner} 805da69c79f9c4490c6657c207430dfeb1060fc4ddChris Lattner 81efdc0b505712d1ca4460def27e51c430f033d58dChris Lattnervoid strip_blank_front(char **p) 82efdc0b505712d1ca4460def27e51c430f033d58dChris Lattner{ 836db70ef879916e6115ac97eb76e4fea973652e2cChris Lattner char *s = *p; 846520785dcd22012535934098942d57c07c7631c2Chris Lattner 8547ae4a1cee5eec5767a11403c0fac7c91ec45461Chris Lattner while (isspace(*s)) 866520785dcd22012535934098942d57c07c7631c2Chris Lattner s++; 8710f22cb1a0f2755050218cd0e07221a0985c6b63Chris Lattner} 8810f22cb1a0f2755050218cd0e07221a0985c6b63Chris Lattner 896520785dcd22012535934098942d57c07c7631c2Chris Lattnervoid strip_blank_end(char *p) 906520785dcd22012535934098942d57c07c7631c2Chris Lattner{ 916520785dcd22012535934098942d57c07c7631c2Chris Lattner char *s = p + strlen(p) - 1; 92ba386d943f4a83095d9c625cb0d46c1afe45ed1fChris Lattner 93fcb6ec0c7e37c2d15ddb04878f05cbd69d1da036Chris Lattner while (isspace(*s) || iscntrl(*s)) 94fcb6ec0c7e37c2d15ddb04878f05cbd69d1da036Chris Lattner s--; 95fcb6ec0c7e37c2d15ddb04878f05cbd69d1da036Chris Lattner 96fcb6ec0c7e37c2d15ddb04878f05cbd69d1da036Chris Lattner *(s + 1) = '\0'; 97fcb6ec0c7e37c2d15ddb04878f05cbd69d1da036Chris Lattner} 98fcb6ec0c7e37c2d15ddb04878f05cbd69d1da036Chris Lattner 99ba386d943f4a83095d9c625cb0d46c1afe45ed1fChris Lattnerstatic int check_range_bytes(const char *str, long *val) 100ba386d943f4a83095d9c625cb0d46c1afe45ed1fChris Lattner{ 101ba386d943f4a83095d9c625cb0d46c1afe45ed1fChris Lattner char suffix; 102ba386d943f4a83095d9c625cb0d46c1afe45ed1fChris Lattner 103fcb6ec0c7e37c2d15ddb04878f05cbd69d1da036Chris Lattner if (!strlen(str)) 10428b8ed90c75ce6c271500fa778fef252f267a5ffChris Lattner return 1; 10528b8ed90c75ce6c271500fa778fef252f267a5ffChris Lattner 10628b8ed90c75ce6c271500fa778fef252f267a5ffChris Lattner if (sscanf(str, "%lu%c", val, &suffix) == 2) { 107dbe48dcaec69ff78e39e2d5faf4323ade6fffb04Chris Lattner *val *= get_mult_bytes(suffix); 108fcb6ec0c7e37c2d15ddb04878f05cbd69d1da036Chris Lattner return 0; 109fcb6ec0c7e37c2d15ddb04878f05cbd69d1da036Chris Lattner } 110fcb6ec0c7e37c2d15ddb04878f05cbd69d1da036Chris Lattner 111fcb6ec0c7e37c2d15ddb04878f05cbd69d1da036Chris Lattner if (sscanf(str, "%lu", val) == 1) 112fcb6ec0c7e37c2d15ddb04878f05cbd69d1da036Chris Lattner return 0; 113c6b519d64ef55d39e66a49510d4703a49bf228ccChris Lattner 114c6b519d64ef55d39e66a49510d4703a49bf228ccChris Lattner return 1; 115c6b519d64ef55d39e66a49510d4703a49bf228ccChris Lattner} 116c6b519d64ef55d39e66a49510d4703a49bf228ccChris Lattner 117fcb6ec0c7e37c2d15ddb04878f05cbd69d1da036Chris Lattnerstatic int check_int(const char *p, int *val) 118a75766a6c14b364b74b30546802e26d4b4b36a9bChris Lattner{ 119a75766a6c14b364b74b30546802e26d4b4b36a9bChris Lattner if (!strlen(p)) 1207546c3884a400b72d10fc19f120c6798b294a39dChris Lattner return 1; 121fcb6ec0c7e37c2d15ddb04878f05cbd69d1da036Chris Lattner if (sscanf(p, "%u", val) == 1) 122a75766a6c14b364b74b30546802e26d4b4b36a9bChris Lattner return 0; 123a75766a6c14b364b74b30546802e26d4b4b36a9bChris Lattner 124ba386d943f4a83095d9c625cb0d46c1afe45ed1fChris Lattner return 1; 125be21ca54e08339ede5dd4bbb882182d22e274988Chris Lattner} 126be21ca54e08339ede5dd4bbb882182d22e274988Chris Lattner 1277546c3884a400b72d10fc19f120c6798b294a39dChris Lattnerstatic struct fio_option *find_option(struct fio_option *options, 1287546c3884a400b72d10fc19f120c6798b294a39dChris Lattner const char *opt) 1297546c3884a400b72d10fc19f120c6798b294a39dChris Lattner{ 1307546c3884a400b72d10fc19f120c6798b294a39dChris Lattner struct fio_option *o; 1317546c3884a400b72d10fc19f120c6798b294a39dChris Lattner 1327546c3884a400b72d10fc19f120c6798b294a39dChris Lattner for (o = &options[0]; o->name; o++) { 1337546c3884a400b72d10fc19f120c6798b294a39dChris Lattner if (!strcmp(o->name, opt)) 134a75766a6c14b364b74b30546802e26d4b4b36a9bChris Lattner return o; 135a75766a6c14b364b74b30546802e26d4b4b36a9bChris Lattner else if (o->alias && !strcmp(o->alias, opt)) 136a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner return o; 137a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner } 138a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner 139a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner return NULL; 140a1cf1c8c87f10f12343ff6ae75f332390e7205abChris Lattner} 1417546c3884a400b72d10fc19f120c6798b294a39dChris Lattner 1427546c3884a400b72d10fc19f120c6798b294a39dChris Lattner#define val_store(ptr, val, off, data) \ 143a75766a6c14b364b74b30546802e26d4b4b36a9bChris Lattner do { \ 144a75766a6c14b364b74b30546802e26d4b4b36a9bChris Lattner ptr = td_var((data), (off)); \ 145a269ec7b0a83d3b20730fd2d9f7c3ed5a552da90Chris Lattner *ptr = (val); \ 146a269ec7b0a83d3b20730fd2d9f7c3ed5a552da90Chris Lattner } while (0) 147a269ec7b0a83d3b20730fd2d9f7c3ed5a552da90Chris Lattner 14890c18c5c69d9c451e5fdca1e4b4b95e8ed13291aChris Lattnerstatic int __handle_option(struct fio_option *o, const char *ptr, void *data, 149a75766a6c14b364b74b30546802e26d4b4b36a9bChris Lattner int first, int more) 150a75766a6c14b364b74b30546802e26d4b4b36a9bChris Lattner{ 15190c18c5c69d9c451e5fdca1e4b4b95e8ed13291aChris Lattner int il, *ilp; 15290c18c5c69d9c451e5fdca1e4b4b95e8ed13291aChris Lattner long long ull, *ullp; 15390c18c5c69d9c451e5fdca1e4b4b95e8ed13291aChris Lattner long ul1, ul2; 15490c18c5c69d9c451e5fdca1e4b4b95e8ed13291aChris Lattner char **cp; 15590c18c5c69d9c451e5fdca1e4b4b95e8ed13291aChris Lattner int ret = 0, is_time = 0; 156a75766a6c14b364b74b30546802e26d4b4b36a9bChris Lattner 157a75766a6c14b364b74b30546802e26d4b4b36a9bChris Lattner if (!ptr && o->type != FIO_OPT_STR_SET) { 158a75766a6c14b364b74b30546802e26d4b4b36a9bChris Lattner fprintf(stderr, "Option %s requires an argument\n", o->name); 1597546c3884a400b72d10fc19f120c6798b294a39dChris Lattner return 1; 1607546c3884a400b72d10fc19f120c6798b294a39dChris Lattner } 1617546c3884a400b72d10fc19f120c6798b294a39dChris Lattner 162be21ca54e08339ede5dd4bbb882182d22e274988Chris Lattner switch (o->type) { 163be21ca54e08339ede5dd4bbb882182d22e274988Chris Lattner case FIO_OPT_STR: { 164be21ca54e08339ede5dd4bbb882182d22e274988Chris Lattner fio_opt_str_fn *fn = o->cb; 165be21ca54e08339ede5dd4bbb882182d22e274988Chris Lattner 166be21ca54e08339ede5dd4bbb882182d22e274988Chris Lattner ret = fn(data, ptr); 167be21ca54e08339ede5dd4bbb882182d22e274988Chris Lattner break; 168be21ca54e08339ede5dd4bbb882182d22e274988Chris Lattner } 169be21ca54e08339ede5dd4bbb882182d22e274988Chris Lattner case FIO_OPT_STR_VAL_TIME: 170be21ca54e08339ede5dd4bbb882182d22e274988Chris Lattner is_time = 1; 171be21ca54e08339ede5dd4bbb882182d22e274988Chris Lattner case FIO_OPT_STR_VAL: 172be21ca54e08339ede5dd4bbb882182d22e274988Chris Lattner case FIO_OPT_STR_VAL_INT: { 173be21ca54e08339ede5dd4bbb882182d22e274988Chris Lattner fio_opt_str_val_fn *fn = o->cb; 1745eda1f2f65941a24ef9a5a85addf4d90eb13fa9dChris Lattner 1755eda1f2f65941a24ef9a5a85addf4d90eb13fa9dChris Lattner if (is_time) 1765eda1f2f65941a24ef9a5a85addf4d90eb13fa9dChris Lattner ret = check_str_time(ptr, &ull); 1775eda1f2f65941a24ef9a5a85addf4d90eb13fa9dChris Lattner else 1785eda1f2f65941a24ef9a5a85addf4d90eb13fa9dChris Lattner ret = check_str_bytes(ptr, &ull); 179be21ca54e08339ede5dd4bbb882182d22e274988Chris Lattner 180be21ca54e08339ede5dd4bbb882182d22e274988Chris Lattner if (ret) 181be21ca54e08339ede5dd4bbb882182d22e274988Chris Lattner break; 182be21ca54e08339ede5dd4bbb882182d22e274988Chris Lattner 183be21ca54e08339ede5dd4bbb882182d22e274988Chris Lattner if (o->maxval && ull > o->maxval) { 184be21ca54e08339ede5dd4bbb882182d22e274988Chris Lattner fprintf(stderr, "max value out of range: %lld (%d max)\n", ull, o->maxval); 185be21ca54e08339ede5dd4bbb882182d22e274988Chris Lattner return 1; 186be21ca54e08339ede5dd4bbb882182d22e274988Chris Lattner } 187be21ca54e08339ede5dd4bbb882182d22e274988Chris Lattner if (o->minval && ull < o->minval) { 188be21ca54e08339ede5dd4bbb882182d22e274988Chris Lattner fprintf(stderr, "min value out of range: %lld (%d min)\n", ull, o->minval); 189be21ca54e08339ede5dd4bbb882182d22e274988Chris Lattner return 1; 190be21ca54e08339ede5dd4bbb882182d22e274988Chris Lattner } 191be21ca54e08339ede5dd4bbb882182d22e274988Chris Lattner 192be21ca54e08339ede5dd4bbb882182d22e274988Chris Lattner if (fn) 193be21ca54e08339ede5dd4bbb882182d22e274988Chris Lattner ret = fn(data, &ull); 194be21ca54e08339ede5dd4bbb882182d22e274988Chris Lattner else { 195fb4b96e77e2930bf3d0c148f1c3685b6a4434666Chris Lattner if (o->type == FIO_OPT_STR_VAL_INT) { 196be21ca54e08339ede5dd4bbb882182d22e274988Chris Lattner if (first) 197fb4b96e77e2930bf3d0c148f1c3685b6a4434666Chris Lattner val_store(ilp, ull, o->off1, data); 198be21ca54e08339ede5dd4bbb882182d22e274988Chris Lattner if (!more && o->off2) 199be21ca54e08339ede5dd4bbb882182d22e274988Chris Lattner val_store(ilp, ull, o->off2, data); 200be21ca54e08339ede5dd4bbb882182d22e274988Chris Lattner } else { 201be21ca54e08339ede5dd4bbb882182d22e274988Chris Lattner if (first) 202be21ca54e08339ede5dd4bbb882182d22e274988Chris Lattner val_store(ullp, ull, o->off1, data); 203be21ca54e08339ede5dd4bbb882182d22e274988Chris Lattner if (!more && o->off2) 204be21ca54e08339ede5dd4bbb882182d22e274988Chris Lattner val_store(ullp, ull, o->off2, data); 205fb4b96e77e2930bf3d0c148f1c3685b6a4434666Chris Lattner } 206fb4b96e77e2930bf3d0c148f1c3685b6a4434666Chris Lattner } 207be21ca54e08339ede5dd4bbb882182d22e274988Chris Lattner break; 208be21ca54e08339ede5dd4bbb882182d22e274988Chris Lattner } 209be21ca54e08339ede5dd4bbb882182d22e274988Chris Lattner case FIO_OPT_STR_STORE: 2105e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner cp = td_var(data, o->off1); 2115e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner *cp = strdup(ptr); 2125e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner break; 2135e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner case FIO_OPT_RANGE: { 2145e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner char tmp[128]; 2155e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner char *p1, *p2; 2165e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner 2175e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner strncpy(tmp, ptr, sizeof(tmp) - 1); 2185e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner 2195e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner p1 = strchr(tmp, '-'); 2205e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner if (!p1) { 221b12914bfc0f76a7a48357162d5f4c39a1343e69bChris Lattner p1 = strchr(tmp, ':'); 222b12914bfc0f76a7a48357162d5f4c39a1343e69bChris Lattner if (!p1) { 2235e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner ret = 1; 2245e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner break; 2255e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner } 2265e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner } 2275e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner 228b12914bfc0f76a7a48357162d5f4c39a1343e69bChris Lattner p2 = p1 + 1; 2295e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner *p1 = '\0'; 2305e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner p1 = tmp; 2315e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner 2325e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner ret = 1; 2335e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner if (!check_range_bytes(p1, &ul1) && !check_range_bytes(p2, &ul2)) { 2345e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner ret = 0; 2355e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner if (ul1 > ul2) { 2365e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner unsigned long foo = ul1; 2375e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner 2385e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner ul1 = ul2; 2395e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner ul2 = foo; 2405e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner } 2415e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner 2425e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner if (first) { 2435e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner val_store(ilp, ul1, o->off1, data); 2445e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner val_store(ilp, ul2, o->off2, data); 2455e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner } 2465e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner if (!more && o->off3 && o->off4) { 2475e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner val_store(ilp, ul1, o->off3, data); 2485e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner val_store(ilp, ul2, o->off4, data); 2495e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner } 2505e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner } 2515e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner 2525e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner break; 2535e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner } 2545e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner case FIO_OPT_INT: 2555e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner case FIO_OPT_BOOL: { 2565e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner fio_opt_int_fn *fn = o->cb; 2575e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner 2585e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner ret = check_int(ptr, &il); 2595e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner if (ret) 2605e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner break; 2615e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner 2625e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner if (o->maxval && il > (int) o->maxval) { 2635e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner fprintf(stderr, "max value out of range: %d (%d max)\n", il, o->maxval); 2645e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner return 1; 2655e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner } 2665e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner if (o->minval && il < o->minval) { 2675e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner fprintf(stderr, "min value out of range: %d (%d min)\n", il, o->minval); 2685e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner return 1; 2695e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner } 2705e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner 2715e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner if (o->neg) 272891150f0b2a124a75c9f31516182ce864ae69ef8Chris Lattner il = !il; 2735e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner 274891150f0b2a124a75c9f31516182ce864ae69ef8Chris Lattner if (fn) 275891150f0b2a124a75c9f31516182ce864ae69ef8Chris Lattner ret = fn(data, &il); 276891150f0b2a124a75c9f31516182ce864ae69ef8Chris Lattner else { 277891150f0b2a124a75c9f31516182ce864ae69ef8Chris Lattner if (first) 2785e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner val_store(ilp, il, o->off1, data); 2795e783ab0b5fc3407ec59f1a598fdb9ef3b96b287Chris Lattner if (!more && o->off2) 280 val_store(ilp, il, o->off2, data); 281 } 282 break; 283 } 284 case FIO_OPT_STR_SET: { 285 fio_opt_str_set_fn *fn = o->cb; 286 287 if (fn) 288 ret = fn(data); 289 else { 290 if (first) 291 val_store(ilp, 1, o->off1, data); 292 if (!more && o->off2) 293 val_store(ilp, 1, o->off2, data); 294 } 295 break; 296 } 297 default: 298 fprintf(stderr, "Bad option type %u\n", o->type); 299 ret = 1; 300 } 301 302 return ret; 303} 304 305static int handle_option(struct fio_option *o, const char *ptr, void *data) 306{ 307 const char *ptr2 = NULL; 308 int r1, r2; 309 310 /* 311 * See if we have a second set of parameters, hidden after a comma. 312 * Do this before parsing the first round, to check if we should 313 * copy set 1 options to set 2. 314 */ 315 if (ptr) { 316 ptr2 = strchr(ptr, ','); 317 if (!ptr2) 318 ptr2 = strchr(ptr, ':'); 319 } 320 321 /* 322 * Don't return early if parsing the first option fails - if 323 * we are doing multiple arguments, we can allow the first one 324 * being empty. 325 */ 326 r1 = __handle_option(o, ptr, data, 1, !!ptr2); 327 328 if (!ptr2) 329 return r1; 330 331 ptr2++; 332 r2 = __handle_option(o, ptr2, data, 0, 0); 333 334 return r1 && r2; 335} 336 337int parse_cmd_option(const char *opt, const char *val, 338 struct fio_option *options, void *data) 339{ 340 struct fio_option *o; 341 342 o = find_option(options, opt); 343 if (!o) { 344 fprintf(stderr, "Bad option %s\n", opt); 345 return 1; 346 } 347 348 if (!handle_option(o, val, data)) 349 return 0; 350 351 fprintf(stderr, "fio: failed parsing %s=%s\n", opt, val); 352 return 1; 353} 354 355int parse_option(const char *opt, struct fio_option *options, void *data) 356{ 357 struct fio_option *o; 358 char *pre, *post; 359 char tmp[64]; 360 361 strncpy(tmp, opt, sizeof(tmp) - 1); 362 363 pre = strchr(tmp, '='); 364 if (pre) { 365 post = pre; 366 *pre = '\0'; 367 pre = tmp; 368 post++; 369 o = find_option(options, pre); 370 } else { 371 o = find_option(options, tmp); 372 post = NULL; 373 } 374 375 if (!o) { 376 fprintf(stderr, "Bad option %s\n", tmp); 377 return 1; 378 } 379 380 if (!handle_option(o, post, data)) 381 return 0; 382 383 fprintf(stderr, "fio: failed parsing %s\n", opt); 384 return 1; 385} 386 387static void show_option_range(struct fio_option *o) 388{ 389 if (!o->minval && !o->maxval) 390 return; 391 392 printf("%16s: min=%d, max=%d\n", "range", o->minval, o->maxval); 393} 394 395static void show_option_values(struct fio_option *o) 396{ 397 const char *msg; 398 int i = 0; 399 400 if (!o->posval) 401 return; 402 403 do { 404 msg = o->posval[i]; 405 if (!msg) 406 break; 407 408 if (!i) 409 printf("%16s: ", "valid values"); 410 411 printf("%s,", msg); 412 i++; 413 } while (1); 414 415 if (i) 416 printf("\n"); 417} 418 419int show_cmd_help(struct fio_option *options, const char *name) 420{ 421 int show_all = !strcmp(name, "all"); 422 const char *typehelp[] = { 423 "string (opt=bla)", 424 "string with possible k/m/g postfix (opt=4k)", 425 "string with range and postfix (opt=1k-4k)", 426 "string with time postfix (opt=10s)", 427 "string (opt=bla)", 428 "string with dual range (opt=1k-4k,4k-8k)", 429 "integer value (opt=100)", 430 "boolean value (opt=1)", 431 "no argument (opt)", 432 }; 433 struct fio_option *o; 434 int found = 0; 435 436 for (o = &options[0]; o->name; o++) { 437 int match = !strcmp(name, o->name); 438 439 if (show_all || match) { 440 found = 1; 441 printf("%16s: %s\n", o->name, o->help); 442 if (show_all) 443 continue; 444 } 445 446 if (!match) 447 continue; 448 449 printf("%16s: %s\n", "type", typehelp[o->type]); 450 printf("%16s: %s\n", "default", o->def ? o->def : "no default"); 451 show_option_range(o); 452 show_option_values(o); 453 } 454 455 if (found) 456 return 0; 457 458 printf("No such command: %s\n", name); 459 return 1; 460} 461 462/* 463 * Handle parsing of default parameters. 464 */ 465void fill_default_options(void *data, struct fio_option *options) 466{ 467 struct fio_option *o; 468 469 for (o = &options[0]; o->name; o++) 470 if (o->def) 471 handle_option(o, o->def, data); 472} 473 474/* 475 * Sanitize the options structure. For now it just sets min/max for bool 476 * values and whether both callback and offsets are given. 477 */ 478void options_init(struct fio_option *options) 479{ 480 struct fio_option *o; 481 482 for (o = &options[0]; o->name; o++) { 483 if (o->type == FIO_OPT_BOOL) { 484 o->minval = 0; 485 o->maxval = 1; 486 } 487 if (o->cb && (o->off1 || o->off2 || o->off3 || o->off4)) 488 fprintf(stderr, "Option %s: both cb and offset given\n", o->name); 489 } 490} 491