Motr  M0
getopts.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2012-2020 Seagate Technology LLC and/or its Affiliates
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * For any questions about this software or licensing,
18  * please email opensource@seagate.com or cortx-questions@seagate.com.
19  *
20  */
21 
22 
23 #include "lib/getopts.h"
24 
25 #include "lib/misc.h" /* strchr, m0_strtou64 */
26 #include "lib/errno.h" /* EINVAL */
27 #include "lib/assert.h" /* M0_CASSSERT */
28 #include "lib/types.h" /* UINT64_MAX */
29 
30 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_LIB
31 #include "lib/trace.h"
32 
33 const char M0_GETOPTS_DECIMAL_POINT = '.';
34 
35 M0_INTERNAL int m0_bcount_get(const char *arg, m0_bcount_t *out)
36 {
37  char *end = NULL;
38  char *pos;
39  static const char suffix[] = "bkmgKMG";
40  int rc = 0;
41 
42  static const uint64_t multiplier[] = {
43  1 << 9,
44  1 << 10,
45  1 << 20,
46  1 << 30,
47  1000,
48  1000 * 1000,
49  1000 * 1000 * 1000
50  };
51 
52  M0_CASSERT(ARRAY_SIZE(suffix) - 1 == ARRAY_SIZE(multiplier));
53 
54  *out = m0_strtou64(arg, &end, 0);
55 
56  if (*end != 0) {
57  pos = strchr(suffix, *end);
58  if (pos != NULL) {
59  if (*out <= M0_BCOUNT_MAX / multiplier[pos - suffix])
60  *out *= multiplier[pos - suffix];
61  else
62  rc = -EOVERFLOW;
63  } else
64  rc = -EINVAL;
65  }
66  return rc;
67 }
68 
69 M0_INTERNAL int m0_time_get(const char *arg, m0_time_t *out)
70 {
71  char *end = NULL;
72  uint64_t before; /* before decimal point */
73  uint64_t after = 0; /* after decimal point */
74  int rc = 0;
75  uint64_t unit_mul = 1000000000;
76  int i;
77  uint64_t pow_of_10 = 1;
78 
79  static const char *unit[] = {
80  "s",
81  "ms",
82  "us",
83  "ns",
84  };
85  static const uint64_t multiplier[] = {
86  1000000000,
87  1000000,
88  1000,
89  1,
90  };
91 
92  M0_CASSERT(ARRAY_SIZE(unit) == ARRAY_SIZE(multiplier));
93 
94  before = m0_strtou64(arg, &end, 10);
95  if (*end == M0_GETOPTS_DECIMAL_POINT) {
96  arg = ++end;
97  after = m0_strtou64(arg, &end, 10);
98  for (i = 0; i < end - arg; ++i) {
99  pow_of_10 = pow_of_10 >= UINT64_MAX / 10 ? UINT64_MAX :
100  pow_of_10 * 10;
101  }
102  }
103  if (before == UINT64_MAX || after == UINT64_MAX)
104  rc = -E2BIG;
105 
106  if (rc == 0 && *end != '\0') {
107  for (i = 0; i < ARRAY_SIZE(unit); ++i) {
108  if (strncmp(end, unit[i], strlen(unit[i]) + 1) == 0) {
109  unit_mul = multiplier[i];
110  break;
111  }
112  }
113  if (i == ARRAY_SIZE(unit))
114  rc = -EINVAL;
115  }
116  if (rc == 0)
117  *out = before * unit_mul + after * unit_mul / pow_of_10;
118  return rc;
119 }
120 
121 #undef M0_TRACE_SUBSYSTEM
122 
123 /*
124  * Local variables:
125  * c-indentation-style: "K&R"
126  * c-basic-offset: 8
127  * tab-width: 8
128  * fill-column: 80
129  * scroll-step: 1
130  * End:
131  */
#define NULL
Definition: misc.h:38
uint64_t m0_time_t
Definition: time.h:37
#define M0_CASSERT(cond)
uint64_t m0_bcount_t
Definition: types.h:77
int i
Definition: dir.c:1033
const char M0_GETOPTS_DECIMAL_POINT
Definition: getopts.c:33
uint64_t m0_strtou64(const char *str, char **endptr, int base)
Definition: kmisc.c:26
M0_INTERNAL int m0_time_get(const char *arg, m0_time_t *out)
Definition: getopts.c:69
#define UINT64_MAX
Definition: types.h:44
M0_INTERNAL int m0_bcount_get(const char *arg, m0_bcount_t *out)
Definition: getopts.c:35
#define out(...)
Definition: gen.c:41
int32_t rc
Definition: trigger_fop.h:47
#define ARRAY_SIZE(a)
Definition: misc.h:45