Motr  M0
sem.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2011-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 #include <err.h>
30 #include <sysexits.h>
31 #include <stdio.h> /* asprintf */
32 #include <stdarg.h>
33 #include <assert.h>
34 #include <stdlib.h> /* malloc */
35 #include <string.h> /* memset, strrchr */
36 
37 #include "xcode/ff2c/parser.h"
38 #include "xcode/ff2c/sem.h"
39 
40 static void *alloc(size_t nr)
41 {
42  void *data;
43 
44  data = malloc(nr);
45  if (data == NULL)
46  err(EX_TEMPFAIL, "cannot allocate %zu bytes.", nr);
47  memset(data, 0, nr);
48  return data;
49 }
50 
51 __attribute__((format(printf, 1, 2)))
52 char *fmt(const char *format, ...)
53 {
54  va_list args;
55  char *out;
56 
57  va_start(args, format);
58  if (vasprintf(&out, format, args) == -1)
59  err(EX_TEMPFAIL, "cannot allocate string.");
60  va_end(args);
61  return out;
62 }
63 
64 static void *add(struct ff2c_list *list, void *obj)
65 {
66  return list->l_tail = *(list->l_head == NULL ?
67  &list->l_head : (void **)list->l_tail) = obj;
68 }
69 
70 static void *add_new(struct ff2c_list *list, size_t size)
71 {
72  return add(list, alloc(size));
73 }
74 
75 #define TOK(tok) (int)(tok)->ft_len, (int)(tok)->ft_len, (tok)->ft_val
76 #define T(term) TOK(&(term)->fn_tok)
77 
78 void require_init(struct ff2c_ff *ff,
79  struct ff2c_require *r, const struct ff2c_term *term)
80 {
81  char *buf = fmt("%*.*s ", T(term));
82 
83  *strrchr(buf, '"') = 0;
84  r->r_path = fmt("%s.h\"", buf);
85  free(buf);
86 }
87 
88 void type_init(struct ff2c_ff *ff, struct ff2c_type *t,
89  const struct ff2c_term *term);
90 
91 static const char *name[][3] = {
92  [FTT_VOID] = { "void", "&M0_XT_VOID", "m0_void_t" },
93  [FTT_U8] = { "u8", "&M0_XT_U8", "uint8_t" },
94  [FTT_U32] = { "u32", "&M0_XT_U32", "uint32_t" },
95  [FTT_U64] = { "u64", "&M0_XT_U64", "uint64_t" },
96  [FTT_OPAQUE] = { NULL, "&M0_XT_OPAQUE", NULL }
97 };
98 
99 void field_init(struct ff2c_ff *ff,
100  struct ff2c_type *t, struct ff2c_field *f, int i,
101  const struct ff2c_term *term)
102 {
103  const struct ff2c_term *inner;
104  const struct ff2c_term *sub;
105  const struct ff2c_token *tok;
106  struct ff2c_type *comp;
107  const char *ptr;
108 
109  inner = term->fn_head;
110  assert(inner != NULL);
111  tok = &inner->fn_tok;
112 
113  ptr = t->t_sequence && i > 0 ? "*" : "";
114  t->t_nr++;
115  f->f_parent = t;
116  f->f_name = fmt("%*.*s", T(term));
117  f->f_c_name = fmt("%s%*.*s", t->t_union && i > 0 ? "u." : "", T(term));
118  for (sub = term->fn_head; sub != NULL; sub = sub->fn_next) {
119  if (sub->fn_type == FNT_TAG) {
120  assert(f->f_tag == NULL);
121  f->f_tag = fmt("%*.*s", T(sub));
122  } else if (sub->fn_type == FNT_ESCAPE) {
123  struct ff2c_escape *esc;
124 
125  assert(f->f_escape == NULL);
126  f->f_escape = fmt("%*.*s", T(sub));
127  esc = alloc(sizeof *esc);
128  esc->e_escape = f->f_escape;
129  add(&ff->ff_escape, esc);
130  }
131  }
132  switch (inner->fn_type) {
133  case FNT_ATOMIC:
134  if (tok->ft_type == FTT_OPAQUE) {
135  assert(f->f_escape != NULL);
136  f->f_decl = fmt("struct %*.*s *%s%s",
137  T(inner), ptr, f->f_name);
138  } else {
139  f->f_decl = fmt("%s %s%s",
140  name[tok->ft_type][2], ptr, f->f_name);
141  }
142  break;
143  case FNT_TYPENAME:
144  f->f_decl = fmt("struct %*.*s %s%s", T(inner), ptr, f->f_name);
145  break;
146  case FNT_COMPOUND:
147  for (comp = ff->ff_type.l_head;
148  comp != NULL; comp = comp->t_next) {
149  if (comp->t_term == term) {
150  f->f_type = comp;
151  break;
152  }
153  }
154  assert(f->f_type != NULL);
155  break;
156  default:
157  assert(0);
158  }
159  if (inner->fn_type == FNT_ATOMIC)
160  f->f_xc_type = fmt("%s", name[tok->ft_type][1]);
161  else if (inner->fn_type == FNT_COMPOUND)
162  f->f_xc_type = fmt("%s", f->f_type->t_xc_name);
163  else
164  f->f_xc_type = fmt("%*.*s_xc", T(inner));
165 }
166 
167 void type_init(struct ff2c_ff *ff, struct ff2c_type *t,
168  const struct ff2c_term *term)
169 {
170  const struct ff2c_term *inner;
171  const struct ff2c_term *grand;
172  enum ff2c_token_type itype;
173 
174  t->t_term = term;
175 
176  inner = term->fn_head;
177  assert(term->fn_parent != NULL);
178  assert(inner != NULL);
179  itype = inner->fn_tok.ft_type;
180 
181  if (inner->fn_type == FNT_ATOMIC) {
182  if (itype == FTT_OPAQUE) {
183  t->t_name = fmt("[@MUST NOT HAPPEN@]");
184  t->t_xc_name = fmt("[@MUST NOT HAPPEN@]");
185  t->t_c_name = fmt("%*.*s", T(inner));
186  t->t_opaque = true;
187  } else {
188  t->t_name = fmt("%s", name[itype][0]);
189  t->t_xc_name = fmt("%s", name[itype][1]);
190  t->t_c_name = fmt("%s", name[itype][2]);
191  t->t_atomic = true;
192  }
193  } else {
194  grand = term->fn_parent->fn_parent;
195  t->t_public = grand == NULL;
196  if (inner->fn_type == FNT_COMPOUND && grand != NULL)
197  t->t_name = fmt("%*.*s_%*.*s", T(grand), T(term));
198  else
199  t->t_name = fmt("%*.*s", T(term));
200  t->t_xc_name = fmt("%s_xc", t->t_name);
201  t->t_c_name = fmt("struct %s", t->t_name);
202  t->t_compound = true;
203  switch (itype) {
204  case FTT_SEQUENCE:
205  t->t_sequence = true;
206  break;
207  case FTT_ARRAY:
208  t->t_array = true;
209  break;
210  case FTT_UNION:
211  t->t_union = true;
212  break;
213  case FTT_RECORD:
214  t->t_record = true;
215  break;
216  case FTT_IDENTIFIER:
217  break;
218  default:
219  assert(0);
220  }
221  }
222 }
223 
224 void tree_walk(struct ff2c_ff *ff, const struct ff2c_term *top)
225 {
226  const struct ff2c_term *child;
227 
228  switch (top->fn_type) {
229  case FNT_REQUIRE:
230  require_init(ff, add_new(&ff->ff_require,
231  sizeof(struct ff2c_require)), top);
232  break;
233  case FNT_DECLARATION:
234  if (top->fn_head->fn_type == FNT_COMPOUND) {
235  type_init(ff, add_new(&ff->ff_type,
236  sizeof(struct ff2c_type)),
237  top);
238  }
239  break;
240  default:
241  break;
242  }
243  for (child = top->fn_head; child != NULL; child = child->fn_next)
244  tree_walk(ff, child);
245 }
246 
247 void ff2c_sem_init(struct ff2c_ff *ff, struct ff2c_term *top)
248 {
249  struct ff2c_type *t;
250 
251  tree_walk(ff, top);
252 
253  for (t = ff->ff_type.l_head; t != NULL; t = t->t_next) {
254  const struct ff2c_term *inner;
255  const struct ff2c_term *f;
256  int i;
257 
258  inner = t->t_term->fn_head;
259  for(i = 0, f = inner->fn_head; f != NULL; f = f->fn_next, ++i) {
260  field_init(ff, t, add_new(&t->t_field,
261  sizeof(struct ff2c_field)),
262  i, f);
263  }
264  }
265 }
266 
267 void ff2c_sem_fini(struct ff2c_ff *ff)
268 {
269 }
270 
273 /*
274  * Local variables:
275  * c-indentation-style: "K&R"
276  * c-basic-offset: 8
277  * tab-width: 8
278  * fill-column: 80
279  * scroll-step: 1
280  * End:
281  */
ff2c_token_type
Definition: lex.h:53
static void ptr(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
Definition: dump.c:440
Definition: parser.h:49
static size_t nr
Definition: dump.c:1505
Definition: lex.h:63
static struct m0_list list
Definition: list.c:144
struct ff2c_token fn_tok
Definition: parser.h:61
#define NULL
Definition: misc.h:38
void require_init(struct ff2c_ff *ff, struct ff2c_require *r, const struct ff2c_term *term)
Definition: sem.c:78
static FILE * f
Definition: adieu.c:79
struct m0_list_link * l_tail
Definition: list.h:80
Definition: lex.h:65
void ff2c_sem_fini(struct ff2c_ff *ff)
Definition: sem.c:267
Definition: sem.h:73
Definition: sem.h:90
struct m0_bufvec data
Definition: di.c:40
static void * add_new(struct ff2c_list *list, size_t size)
Definition: sem.c:70
Definition: xcode.c:59
Definition: ub.c:49
static struct foo * obj
Definition: tlist.c:302
Definition: sock.c:887
enum ff2c_term_type fn_type
Definition: parser.h:56
static int ff(struct ff2c_context *ctx, struct ff2c_term *term)
Definition: parser.c:212
const struct ff2c_term * t_term
Definition: sem.h:57
int i
Definition: dir.c:1033
static const char * name[][3]
Definition: sem.c:91
def args
Definition: addb2db.py:716
Definition: sem.h:45
struct m0_list_link * l_head
Definition: list.h:76
enum ff2c_token_type ft_type
Definition: lex.h:95
Definition: lex.h:73
static void * add(struct ff2c_list *list, void *obj)
Definition: sem.c:64
void field_init(struct ff2c_ff *ff, struct ff2c_type *t, struct ff2c_field *f, int i, const struct ff2c_term *term)
Definition: sem.c:99
static struct m0_thread t[8]
Definition: service_ut.c:1230
struct ff2c_term * fn_head
Definition: parser.h:58
static void * alloc(size_t nr)
Definition: sem.c:40
char * fmt(const char *format,...) __attribute__((format(printf
void ff2c_sem_init(struct ff2c_ff *ff, struct ff2c_term *top)
Definition: sem.c:247
struct ff2c_type * t_next
Definition: sem.h:56
format
Definition: hist.py:128
int vasprintf(char **strp, const char *fmt, va_list ap)
Definition: lex.h:67
void tree_walk(struct ff2c_ff *ff, const struct ff2c_term *top)
Definition: sem.c:224
static int r[NR]
Definition: thread.c:46
struct ff2c_term * fn_next
Definition: parser.h:60
Definition: lex.h:94
m0_bcount_t size
Definition: di.c:39
const char * e_escape
Definition: sem.h:87
Definition: lex.h:61
__attribute__((format(printf, 1, 2)))
Definition: sem.c:51
#define T(term)
Definition: sem.c:76
Definition: lex.h:77
Definition: sem.h:55
struct m0_rpc_fop_session_terminate term
Definition: session.c:53
#define out(...)
Definition: gen.c:41
void type_init(struct ff2c_ff *ff, struct ff2c_type *t, const struct ff2c_term *term)
Definition: sem.c:167
Definition: lex.h:71
Definition: lex.h:69