Skip to content

Commit

Permalink
Merge branch 'mx_util/units'
Browse files Browse the repository at this point in the history
* mx_util/units:
  mxqd: Use mx_strtobytes() to parse --memory and --max-memory-per-slot options
  mxqsub: Use mx_strtobytes() to parse --memory option
  mx_util: Add mxq_strtobytes()
  mxqsub: Use mx_strtominutes() to parse --runtime option
  mx_util: Add mxq_strto{seconds,minutes}()
  • Loading branch information
mariux committed Aug 26, 2015
2 parents 9aa0024 + 1cf6306 commit 5703845
Show file tree
Hide file tree
Showing 5 changed files with 279 additions and 8 deletions.
148 changes: 148 additions & 0 deletions mx_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,154 @@ inline int mx_stribeginswithany(char *str, char **starts, char **endptr)
return _mx_strbeginswithany(str, starts, endptr, 1);
}

inline int mx_strtobytes(char *str, unsigned long long int *bytes)
{
unsigned long long int s = 0;
unsigned long long int t;

char *end;

if (!str || !*str)
return -(errno=EINVAL);

if (strchr(str, '-'))
return -(errno=ERANGE);

do {
errno = 0;
t = strtoull(str, &end, 10);

if (errno)
return -errno;

if (str == end)
return -(errno=EINVAL);

for (;*end && *end == ' '; end++)
/* empty */;

switch (*end) {

case 'T': /* tebi */
t *= 1024;

case 'G': /* gibi */
t *= 1024;

case 'M': /* mebi */
t *= 1024;

case 'k': /* kibi */
case 'K':
t *= 1024;

case 'B': /* bytes */
end++;
break;

default:
return -(errno=EINVAL);
}

if (s+t < s)
return -(errno=ERANGE);

s += t;

for (;*end && *end == ' '; end++)
/* empty */;

str = end;

} while (*str);

*bytes = s;

return 0;
}

inline int mx_strtoseconds(char *str, unsigned long long int *seconds)
{
unsigned long long int s = 0;
unsigned long long int t;

char *end;

if (!str || !*str)
return -(errno=EINVAL);

if (strchr(str, '-'))
return -(errno=ERANGE);

do {
errno = 0;
t = strtoull(str, &end, 10);

if (errno)
return -errno;

if (str == end)
return -(errno=EINVAL);

for (;*end && *end == ' '; end++)
/* empty */;

//if (mx_strtounit(end, &end));

switch (*end) {

case 'y': /* years */
t *= 52;

case 'w': /* weeks */
t *= 7;

case 'd': /* days */
t *= 24;

case 'h': /* hours */
t *= 60;

case 'm': /* minutes */
t *= 60;

case 's': /* seconds */
end++;
break;

default:
return -(errno=EINVAL);
}

if (s+t < s)
return -(errno=ERANGE);

s += t;

for (;*end && *end == ' '; end++)
/* empty */;

str = end;

} while (*str);

*seconds = s;

return 0;
}

inline int mx_strtominutes(char *str, unsigned long long int *minutes)
{
int res;

res = mx_strtoseconds(str, minutes);

if (res >= 0)
*minutes /= 60;

return res;
}

inline char *mx_strskipwhitespaces(char *str)
{
char *s;
Expand Down
5 changes: 5 additions & 0 deletions mx_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ int mx_strbeginswithany(char *str, char **starts, char **endptr);

char *mx_strskipwhitespaces(char *str);

int mx_strtobytes(char *str, unsigned long long int *bytes);

int mx_strtoseconds(char *str, unsigned long long int *seconds);
int mx_strtominutes(char *str, unsigned long long int *minutes);

int mx_strtoul(char *str, unsigned long int *to);
int mx_strtoull(char *str, unsigned long long int *to);

Expand Down
18 changes: 14 additions & 4 deletions mxqd.c
Original file line number Diff line number Diff line change
Expand Up @@ -290,17 +290,27 @@ int server_init(struct mxq_server *server, int argc, char *argv[])

case 'm':
if (mx_strtoul(optctl.optarg, &memory_total) < 0) {
mx_log_err("Invalid argument supplied for option --memory '%s': %m", optctl.optarg);
exit(1);
unsigned long long int bytes;

if(mx_strtobytes(optctl.optarg, &bytes) < 0) {
mx_log_err("Invalid argument supplied for option --memory '%s': %m", optctl.optarg);
exit(1);
}
memory_total = bytes/1024/1024;
}
if (!memory_total)
memory_total = 2048;
break;

case 'x':
if (mx_strtoul(optctl.optarg, &memory_max) < 0) {
mx_log_err("Invalid argument supplied for option --max-memory-per-slot '%s': %m", optctl.optarg);
exit(1);
unsigned long long int bytes;

if(mx_strtobytes(optctl.optarg, &bytes) < 0) {
mx_log_err("Invalid argument supplied for option --max-memory-per-slot '%s': %m", optctl.optarg);
exit(1);
}
memory_max = bytes/1024/1024;
}
break;

Expand Down
23 changes: 19 additions & 4 deletions mxqsub.c
Original file line number Diff line number Diff line change
Expand Up @@ -775,17 +775,32 @@ int main(int argc, char *argv[])

case 'm':
if (mx_strtou64(optctl.optarg, &arg_memory) < 0) {
mx_log_crit("--memory '%s': %m", optctl.optarg);
exit(EX_CONFIG);
unsigned long long int bytes;

if(mx_strtobytes(optctl.optarg, &bytes) < 0) {
mx_log_crit("--memory '%s': %m", optctl.optarg);
exit(EX_CONFIG);
}
arg_memory = bytes/1024/1024;
}
break;

case 4:
mx_log_warning("option '--time' is deprecated. please use '--runtime' or '-t' in future calls.");
case 't':
if (mx_strtou32(optctl.optarg, &arg_time) < 0) {
mx_log_crit("--runtime '%s': %m", optctl.optarg);
exit(EX_CONFIG);
unsigned long long int minutes;

if(mx_strtominutes(optctl.optarg, &minutes) < 0) {
mx_log_crit("--runtime '%s': %m", optctl.optarg);
exit(EX_CONFIG);
}
if ((unsigned long long int)(uint32_t)minutes != minutes) {
errno = ERANGE;
mx_log_crit("--runtime '%s': %m", optctl.optarg);
exit(EX_CONFIG);
}
arg_time = (uint32_t)minutes;
}
break;

Expand Down
93 changes: 93 additions & 0 deletions test_mx_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ static void test_mx_strtoul(void)
assert(mx_strtoul("-1", &l) == -ERANGE);
assert(mx_strtoul(" -1", &l) == -ERANGE);

assert(mx_strtoul("123s", &l) == -EINVAL);
assert(mx_strtoul("0888", &l) == -EINVAL);
assert(mx_strtoul("1.2", &l) == -EINVAL);
assert(mx_strtoul("1,2", &l) == -EINVAL);
Expand Down Expand Up @@ -181,6 +182,95 @@ static void test_mx_strbeginswithany(void)
assert(end == NULL);
}

static void test_mx_strtoseconds(void)
{
unsigned long long int l;

assert(mx_strtoseconds("123s", &l) == 0);
assert(l == 123);

assert(mx_strtoseconds("0123s", &l) == 0);
assert(l == 123);

assert(mx_strtoseconds("123s0s", &l) == 0);
assert(l == 123);

assert(mx_strtoseconds("2m3s", &l) == 0);
assert(l == 123);

assert(mx_strtoseconds(" 2 m 3 s ", &l) == 0);
assert(l == 123);

assert(mx_strtoseconds("1h 2m 3s", &l) == 0);
assert(l == 60*60 + 2*60 + 3);

assert(mx_strtoseconds("2m 3s 1h", &l) == 0);
assert(l == 60*60 + 2*60 + 3);

assert(mx_strtoseconds("2m 3s 1h1y", &l) == 0);
assert(l == 60*60 + 2*60 + 3 + 52*7*24*60*60);

assert(mx_strtoseconds("2m 3s 1h1y", &l) == 0);
assert(l == 60*60 + 2*60 + 3 + 52*7*24*60*60);

assert(mx_strtoseconds("-1", &l) == -ERANGE);
assert(mx_strtoseconds(" -1", &l) == -ERANGE);

assert(mx_strtoseconds("123", &l) == -EINVAL);
assert(mx_strtoseconds("0123", &l) == -EINVAL);
assert(mx_strtoseconds("1.2", &l) == -EINVAL);
assert(mx_strtoseconds("1,2", &l) == -EINVAL);
assert(mx_strtoseconds("test", &l) == -EINVAL);
}

static void test_mx_strtominutes(void)
{
unsigned long long int l;

assert(mx_strtominutes("123s", &l) == 0);
assert(l == 2);

assert(mx_strtominutes("20d", &l) == 0);
assert(l == 20*24*60);


assert(mx_strtominutes("-1", &l) == -ERANGE);
assert(mx_strtominutes(" -1", &l) == -ERANGE);

assert(mx_strtominutes("123", &l) == -EINVAL);
assert(mx_strtominutes("0123", &l) == -EINVAL);
assert(mx_strtominutes("1.2", &l) == -EINVAL);
assert(mx_strtominutes("1,2", &l) == -EINVAL);
assert(mx_strtominutes("test", &l) == -EINVAL);
}

static void test_mx_strtobytes(void)
{
unsigned long long int l;

assert(mx_strtobytes("123B", &l) == 0);
assert(l == 123);

assert(mx_strtobytes("2M", &l) == 0);
assert(l == 2*1024*1024);

assert(mx_strtobytes("1M1024k", &l) == 0);
assert(l == 2*1024*1024);

assert(mx_strtobytes("1024k1024K", &l) == 0);
assert(l == 2*1024*1024);

assert(mx_strtobytes("-1", &l) == -ERANGE);
assert(mx_strtobytes(" -1", &l) == -ERANGE);

assert(mx_strtobytes("2.5M", &l) == -EINVAL);
assert(mx_strtobytes("123", &l) == -EINVAL);
assert(mx_strtobytes("0123", &l) == -EINVAL);
assert(mx_strtobytes("1.2", &l) == -EINVAL);
assert(mx_strtobytes("1,2", &l) == -EINVAL);
assert(mx_strtobytes("test", &l) == -EINVAL);
}

int main(int argc, char *argv[])
{
test_mx_strskipwhitespaces();
Expand All @@ -191,5 +281,8 @@ int main(int argc, char *argv[])
test_mx_strbeginswith();
test_mx_stribeginswith();
test_mx_strbeginswithany();
test_mx_strtoseconds();
test_mx_strtominutes();
test_mx_strtobytes();
return 0;
}

0 comments on commit 5703845

Please sign in to comment.