parseoffset.c - sbase - suckless unix tools
(HTM) git clone git://git.suckless.org/sbase
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
parseoffset.c (1148B)
---
1 /* See LICENSE file for copyright and license details. */
2 #include <ctype.h>
3 #include <errno.h>
4 #include <inttypes.h>
5 #include <stdlib.h>
6 #include <string.h>
7
8 #include "../util.h"
9
10 off_t
11 parseoffset(const char *str)
12 {
13 off_t res, scale = 1;
14 char *end;
15
16 /* strictly check what strtol() usually would let pass */
17 if (!str || !*str || isspace(*str) || *str == '+' || *str == '-') {
18 weprintf("parseoffset %s: invalid value\n", str);
19 return -1;
20 }
21
22 errno = 0;
23 res = strtol(str, &end, 0);
24 if (errno) {
25 weprintf("parseoffset %s: invalid value\n", str);
26 return -1;
27 }
28 if (res < 0) {
29 weprintf("parseoffset %s: negative value\n", str);
30 return -1;
31 }
32
33 /* suffix */
34 if (*end) {
35 switch (toupper((int)*end)) {
36 case 'B':
37 scale = 512L;
38 break;
39 case 'K':
40 scale = 1024L;
41 break;
42 case 'M':
43 scale = 1024L * 1024L;
44 break;
45 case 'G':
46 scale = 1024L * 1024L * 1024L;
47 break;
48 default:
49 weprintf("parseoffset %s: invalid suffix '%s'\n", str, end);
50 return -1;
51 }
52 }
53
54 /* prevent overflow */
55 if (res > (SSIZE_MAX / scale)) {
56 weprintf("parseoffset %s: out of range\n", str);
57 return -1;
58 }
59
60 return res * scale;
61 }