Motr  M0
enum.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2017-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 
29 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_XCODE
30 #include "lib/trace.h"
31 #include "lib/errno.h" /* EPROTO */
32 #include "lib/misc.h" /* M0_BITS, m0_strtou64 */
33 
34 #include "xcode/xcode.h"
35 #include "xcode/enum.h"
36 
37 static const struct m0_xcode_enum_val *valget(const struct m0_xcode_enum *en,
38  uint64_t val);
39 static const struct m0_xcode_enum_val *nameget(const struct m0_xcode_enum *en,
40  const char *name, int nr);
41 static int enum_getnum(const char *buf, uint64_t *out);
42 static const char *enum_id (const char *buf);
43 static const char *bitmask_id(const char *buf);
44 
45 bool m0_xcode_enum_is_valid(const struct m0_xcode_enum *en, uint64_t val)
46 {
47  return valget(en, val)->xev_idx >= 0;
48 }
49 M0_EXPORTED(m0_xcode_enum_is_valid);
50 
51 const char *m0_xcode_enum_print(const struct m0_xcode_enum *en, uint64_t val,
52  char *buf)
53 {
54  const struct m0_xcode_enum_val *v = valget(en, val);
55 
56  if (v->xev_idx >= 0 || buf == NULL)
57  return v->xev_name;
58  else {
59  sprintf(buf, "%"PRIx64, val);
60  return buf;
61  }
62 }
63 M0_EXPORTED(m0_xcode_enum_print);
64 
65 int m0_xcode_enum_read(const struct m0_xcode_enum *en,
66  const char *buf, int nr, uint64_t *val)
67 {
68  const struct m0_xcode_enum_val *v = nameget(en, buf, nr);
69 
70  if (v->xev_idx >= 0) {
71  *val = v->xev_val;
72  return 0;
73  } else
74  return enum_getnum(buf, val) == nr ? 0 : M0_ERR(-EPROTO);
75 }
76 M0_EXPORTED(m0_xcode_enum_read);
77 
78 bool m0_xcode_bitmask_is_valid(const struct m0_xcode_enum *en, uint64_t val)
79 {
80  return m0_forall(i, 64, ergo(val & M0_BITS(i),
82 }
83 M0_EXPORTED(m0_xcode_bitmask_is_valid);
84 
86  uint64_t val, char *buf, int nr)
87 {
88  int i;
89  int nob;
90 #define P(fmt, val) \
91 ({ \
92  nob += snprintf(buf + nob, nr - nob, "%s" fmt, \
93  nob == 0 ? "" : "|", val); \
94 })
95 
96  for (i = 0, nob = 0; i < en->xe_nr; ++i) {
97  const struct m0_xcode_enum_val *v = &en->xe_val[i];
98 
99  if ((val & v->xev_val) != 0) {
100  P("%s", v->xev_name);
101  val &= ~v->xev_val;
102  }
103  }
104  if (val != 0)
105  /* Print remaining bits in sexadecimal. */
106  P("%"PRIx64, val);
107  return nob;
108 #undef P
109 }
110 M0_EXPORTED(m0_xcode_bitmask_print);
111 
113  const char *buf, int nr, uint64_t *val)
114 {
115  *val = 0ULL;
116  while (nr > 0) {
117  int nob;
118  const struct m0_xcode_enum_val *v;
119 
120  for (nob = 0; nob < nr && buf[nob] != '|'; ++nob)
121  ;
122  v = nameget(en, buf, nob);
123  if (v->xev_idx < 0) {
124  uint64_t num;
125 
126  nob = enum_getnum(buf, &num);
127  if (nob > 0)
128  *val |= num;
129  else
130  return M0_ERR(-EPROTO);
131  } else
132  *val |= v->xev_val;
133  if (buf[nob] == '|')
134  nob++;
135  buf += nob;
136  nr -= nob;
137  }
138  return 0;
139 }
140 M0_EXPORTED(m0_xcode_bitmask_read);
141 
142 M0_INTERNAL int m0_xcode_enum_field_read(const struct m0_xcode_cursor *it,
143  struct m0_xcode_obj *obj,
144  const char *str)
145 {
146  const struct m0_xcode_field *f = m0_xcode_cursor_field(it);
147  const struct m0_xcode_enum *en = f->xf_decor[M0_XCODE_DECOR_READ];
148  int nr = enum_id(str) - str;
149 
150  M0_PRE(M0_IN(f->xf_type, (&M0_XT_U8, &M0_XT_U32, &M0_XT_U64)));
151  M0_PRE(en != NULL);
152  return m0_xcode_enum_read(en, str, nr, obj->xo_ptr) ?: nr;
153 }
154 
155 M0_INTERNAL int m0_xcode_bitmask_field_read(const struct m0_xcode_cursor *it,
156  struct m0_xcode_obj *obj,
157  const char *str)
158 {
159  const struct m0_xcode_field *f = m0_xcode_cursor_field(it);
160  const struct m0_xcode_enum *en = f->xf_decor[M0_XCODE_DECOR_READ];
161  int nr = bitmask_id(str) - str;
162 
163  M0_PRE(M0_IN(f->xf_type, (&M0_XT_U8, &M0_XT_U32, &M0_XT_U64)));
164  M0_PRE(en != NULL);
165  return m0_xcode_bitmask_read(en, str, nr, obj->xo_ptr) ?: nr;
166 }
167 
168 static const struct m0_xcode_enum_val *valget(const struct m0_xcode_enum *en,
169  uint64_t val)
170 {
171  int i;
172 
173  for (i = 0; i < en->xe_nr; ++i) {
174  if (en->xe_val[i].xev_val == val)
175  break;
176  }
177  return &en->xe_val[i];
178 }
179 
180 static const struct m0_xcode_enum_val *nameget(const struct m0_xcode_enum *en,
181  const char *name, int nr)
182 {
183  int i;
184 
185  for (i = 0; i < en->xe_nr; ++i) {
186  if (strncmp(en->xe_val[i].xev_name, name, nr) == 0 &&
187  nr == strlen(en->xe_val[i].xev_name))
188  break;
189  }
190  return &en->xe_val[i];
191 }
192 
193 static int enum_getnum(const char *buf, uint64_t *out)
194 {
195  char *endp;
196 
197  *out = m0_strtou64(buf, &endp, 0x10);
198  return endp - buf;
199 }
200 
201 static bool enum_char(char ch)
202 {
203 #define BETWEEN(ch, l, h) ((l) <= (ch) && (ch) <= (h))
204  return BETWEEN(ch, 'a', 'z') || BETWEEN(ch, 'A', 'Z') ||
205  BETWEEN(ch, '0', '9') || ch == '_';
206 #undef BETWEEN
207 }
208 
209 static const char *enum_id(const char *b)
210 {
211  while (*b != 0 && enum_char(*b))
212  b++;
213  return b;
214 }
215 
216 static const char *bitmask_id(const char *b)
217 {
218  while (*b != 0 && (enum_char(*b) || *b == '|'))
219  b++;
220  return b;
221 }
222 
223 #undef M0_TRACE_SUBSYSTEM
224 
227 /*
228  * Local variables:
229  * c-indentation-style: "K&R"
230  * c-basic-offset: 8
231  * tab-width: 8
232  * fill-column: 80
233  * scroll-step: 1
234  * End:
235  */
236 /*
237  * vim: tabstop=8 shiftwidth=8 noexpandtab textwidth=80 nowrap
238  */
static size_t nr
Definition: dump.c:1505
#define M0_PRE(cond)
static const char * bitmask_id(const char *buf)
Definition: enum.c:216
#define NULL
Definition: misc.h:38
static int enum_getnum(const char *buf, uint64_t *out)
Definition: enum.c:193
Definition: idx_mock.c:52
#define ergo(a, b)
Definition: misc.h:293
const struct m0_xcode_enum_val * xe_val
Definition: enum.h:67
static FILE * f
Definition: adieu.c:79
#define BETWEEN(ch, l, h)
static struct m0_be_emap_cursor it
Definition: extmap.c:46
#define M0_BITS(...)
Definition: misc.h:236
static int void * buf
Definition: dir.c:1019
static struct foo * obj
Definition: tlist.c:302
#define PRIx64
Definition: types.h:61
Definition: sock.c:887
bool m0_xcode_enum_is_valid(const struct m0_xcode_enum *en, uint64_t val)
Definition: enum.c:45
int i
Definition: dir.c:1033
return M0_ERR(-EOPNOTSUPP)
const char * name
Definition: trace.c:110
uint64_t xev_val
Definition: enum.h:90
uint64_t m0_strtou64(const char *str, char **endptr, int base)
Definition: kmisc.c:26
int m0_xcode_bitmask_print(const struct m0_xcode_enum *en, uint64_t val, char *buf, int nr)
Definition: enum.c:85
int m0_xcode_bitmask_read(const struct m0_xcode_enum *en, const char *buf, int nr, uint64_t *val)
Definition: enum.c:112
static bool enum_char(char ch)
Definition: enum.c:201
uint32_t xe_nr
Definition: enum.h:60
const char * m0_xcode_enum_print(const struct m0_xcode_enum *en, uint64_t val, char *buf)
Definition: enum.c:51
const char * xev_name
Definition: enum.h:97
#define m0_forall(var, nr,...)
Definition: misc.h:112
bool m0_xcode_bitmask_is_valid(const struct m0_xcode_enum *en, uint64_t val)
Definition: enum.c:78
const struct m0_xcode_type M0_XT_U32
Definition: xcode.c:932
M0_INTERNAL int m0_xcode_bitmask_field_read(const struct m0_xcode_cursor *it, struct m0_xcode_obj *obj, const char *str)
Definition: enum.c:155
static const struct m0_xcode_enum_val * valget(const struct m0_xcode_enum *en, uint64_t val)
Definition: enum.c:168
const struct m0_xcode_type M0_XT_U8
Definition: xcode.c:924
static const struct m0_xcode_enum_val * nameget(const struct m0_xcode_enum *en, const char *name, int nr)
Definition: enum.c:180
M0_INTERNAL const struct m0_xcode_field * m0_xcode_cursor_field(const struct m0_xcode_cursor *it)
Definition: cursor.c:48
int m0_xcode_enum_read(const struct m0_xcode_enum *en, const char *buf, int nr, uint64_t *val)
Definition: enum.c:65
#define out(...)
Definition: gen.c:41
static const char * enum_id(const char *buf)
Definition: enum.c:209
int num
Definition: bulk_if.c:54
#define P(fmt, val)
const struct m0_xcode_type M0_XT_U64
Definition: xcode.c:940
M0_INTERNAL int m0_xcode_enum_field_read(const struct m0_xcode_cursor *it, struct m0_xcode_obj *obj, const char *str)
Definition: enum.c:142