Motr  M0
gen.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 
29 #include <stdbool.h>
30 #include <stdio.h>
31 #include <assert.h>
32 #include <string.h> /* strcpy, strcat, strrchr */
33 
34 #include "xcode/ff2c/lex.h"
35 #include "xcode/ff2c/parser.h"
36 #include "xcode/ff2c/sem.h"
37 #include "xcode/ff2c/gen.h"
38 
39 FILE *thefile;
40 
41 #define out(...) fprintf(thefile, __VA_ARGS__)
42 
43 static void indent(int depth)
44 {
45  static const char ruler[] = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
46 
47  out("%*.*s", depth, depth, ruler);
48 }
49 
50 #define TOK(tok) (int)(tok)->ft_len, (int)(tok)->ft_len, (tok)->ft_val
51 #define T(term) TOK(&(term)->fn_tok)
52 
53 static void type_h(const struct ff2c_type *t, int depth);
54 
55 static void field_h(const struct ff2c_field *f, int depth)
56 {
57  if (f->f_decl != NULL) {
58  indent(depth);
59  out("%s", f->f_decl);
60  } else {
61  type_h(f->f_type, depth);
62  out(" %s", f->f_name);
63  }
64  if (f->f_parent->t_array)
65  out("[%s]", f->f_tag);
66  out(";\n");
67 }
68 
69 static void type_h(const struct ff2c_type *t, int depth)
70 {
71  const struct ff2c_field *f = t->t_field.l_head;
72 
73  indent(depth);
74  out("%s {\n", t->t_c_name);
75  if (t->t_union) {
76  field_h(f, depth + 1);
77  f = f->f_next;
78  indent(depth + 1);
79  out("union {\n");
80  depth++;
81  }
82  for (; f != NULL; f = f->f_next)
83  field_h(f, depth + 1);
84  if (t->t_union) {
85  indent(depth);
86  out("} u;\n");
87  depth--;
88  }
89  indent(depth);
90  out("}");
91 }
92 
93 int ff2c_h_gen(const struct ff2c_ff *ff, const struct ff2c_gen_opt *opt)
94 {
95  const struct ff2c_require *r;
96  const struct ff2c_type *t;
97 
98  thefile = opt->go_out;
99 
100  out("/* This file is automatically generated from %s.ff */\n\n",
101  opt->go_basename);
102  out("#pragma once\n\n");
103  out("#ifndef %s\n"
104  "#define %s\n\n", opt->go_guardname, opt->go_guardname);
105  out("#ifndef __KERNEL__\n");
106  out("#include <sys/types.h>\n");
107  out("#endif /* __KERNEL__ */\n\n");
108  out("#include \"xcode/xcode.h\"\n\n");
109 
110  for (r = ff->ff_require.l_head; r != NULL; r = r->r_next)
111  out("#include %s\n", r->r_path);
112  out("\n");
113  for (t = ff->ff_type.l_head; t != NULL; t = t->t_next) {
114  if (t->t_public) {
115  type_h(t, 0);
116  out(";\n\n");
117  }
118  }
119  out("\n");
120  for (t = ff->ff_type.l_head; t != NULL; t = t->t_next) {
121  if (t->t_public)
122  out("extern struct m0_xcode_type *%s;\n", t->t_xc_name);
123  }
124  out("\n"
125  "M0_INTERNAL void m0_xc_%s_init(void);\n"
126  "M0_INTERNAL void m0_xc_%s_fini(void);\n\n", opt->go_basename,
127  opt->go_basename);
128  out("/* %s */\n"
129  "#endif\n\n", opt->go_guardname);
130  return 0;
131 }
132 
133 static void field_def(const struct ff2c_type *t,
134  const struct ff2c_field *f, int i)
135 {
136  out("\t_%s._child[%i] = (struct m0_xcode_field) {\n"
137  "\t\t.xf_name = \"%s\",\n"
138  "\t\t.xf_type = %s,\n"
139  "\t\t.xf_tag = %s,\n"
140  "\t\t.xf_opaque = %s,\n"
141  "\t\t.xf_offset = offsetof(%s, %s)\n"
142  "\t};\n",
143  t->t_name, i, f->f_name, f->f_xc_type,
144  f->f_tag ?: "0",
145  f->f_escape ?: "NULL",
146  t->t_c_name, f->f_c_name);
147 }
148 
149 static void type_fields(const struct ff2c_type *t)
150 {
151  const struct ff2c_field *f;
152  int i;
153 
154  for (i = 0, f = t->t_field.l_head; f != NULL; f = f->f_next, i++)
155  field_def(t, f, i);
156 }
157 
158 static void type_decl(const struct ff2c_type *t)
159 {
160  out("%sstruct m0_xcode_type *%s",
161  t->t_public ? "" : "static ", t->t_xc_name);
162 }
163 
164 static void type_def(const struct ff2c_type *t)
165 {
166  static const char *caggr[] = {
167  [FTT_VOID] = "M0_XA_ATOM",
168  [FTT_U8] = "M0_XA_ATOM",
169  [FTT_U32] = "M0_XA_ATOM",
170  [FTT_U64] = "M0_XA_ATOM",
171  [FTT_OPAQUE] = "M0_XA_OPAQUE",
172  [FTT_RECORD] = "M0_XA_RECORD",
173  [FTT_UNION] = "M0_XA_UNION",
174  [FTT_SEQUENCE] = "M0_XA_SEQUENCE",
175  [FTT_ARRAY] = "M0_XA_ARRAY"
176  };
177  out("static struct _%s_s {\n"
178  "\tstruct m0_xcode_type _type;\n"
179  "\tstruct m0_xcode_field _child[%i];\n"
180  "} _%s = {\n"
181  "\t._type = {\n"
182  "\t\t.xct_aggr = %s,\n"
183  "\t\t.xct_name = \"%s\",\n"
184  "\t\t.xct_sizeof = sizeof (%s),\n"
185  "\t\t.xct_nr = %i\n"
186  "\t}\n"
187  "};\n\n",
188  t->t_name, t->t_nr, t->t_name,
189  caggr[t->t_term->fn_head->fn_tok.ft_type],
190  t->t_name, t->t_c_name, t->t_nr);
191  type_decl(t);
192  out(" = &_%s._type;\n"
193  "M0_BASSERT(offsetof(struct _%s_s, _child[0]) ==\n"
194  "\toffsetof(struct m0_xcode_type, xct_child[0]));\n\n",
195  t->t_name, t->t_name);
196 }
197 
198 int ff2c_c_gen(const struct ff2c_ff *ff, const struct ff2c_gen_opt *opt)
199 {
200  const struct ff2c_type *t;
201  const struct ff2c_escape *e;
202 
203  thefile = opt->go_out;
204 
205  out("/* This file is automatically generated from %s.ff */\n\n",
206  opt->go_basename);
207 
208  out("#include \"lib/misc.h\" /* offsetof */\n");
209  out("#include \"lib/assert.h\"\n");
210  out("#include \"xcode/xcode.h\"\n\n");
211  out("#include \"%s_ff.h\"\n\n", opt->go_basename);
212 
213  for (t = ff->ff_type.l_head; t != NULL; t = t->t_next) {
214  if (t->t_public) {
215  type_decl(t);
216  out(";\n");
217  }
218  }
219  out("\n");
220  for (t = ff->ff_type.l_head; t != NULL; t = t->t_next) {
221  if (!t->t_public) {
222  type_decl(t);
223  out(";\n");
224  }
225  }
226  out("\n");
227  for (e = ff->ff_escape.l_head; e != NULL; e = e->e_next) {
228  out("int %s(const struct m0_xcode_obj *par,\n"
229  "\t\tconst struct m0_xcode_type **out);\n", e->e_escape);
230  }
231  out("\n");
232  for (t = ff->ff_type.l_head; t != NULL; t = t->t_next)
233  type_def(t);
234 
235  out("\n\n"
236  "M0_INTERNAL void m0_xc_%s_init(void)\n"
237  "{\n", opt->go_basename);
238 
239  for (t = ff->ff_type.l_head; t != NULL; t = t->t_next) {
240  type_fields(t);
241  out("\n");
242  }
243  out("}\n"
244  "M0_INTERNAL void m0_xc_%s_fini(void)\n{}\n", opt->go_basename);
245 
246  return 0;
247 }
248 
251 /*
252  * Local variables:
253  * c-indentation-style: "K&R"
254  * c-basic-offset: 8
255  * tab-width: 8
256  * fill-column: 80
257  * scroll-step: 1
258  * End:
259  */
Definition: lex.h:63
static void field_def(const struct ff2c_type *t, const struct ff2c_field *f, int i)
Definition: gen.c:133
#define NULL
Definition: misc.h:38
FILE * thefile
Definition: gen.c:39
static FILE * f
Definition: adieu.c:79
Definition: lex.h:65
static void type_decl(const struct ff2c_type *t)
Definition: gen.c:158
Definition: sem.h:73
Definition: sem.h:90
FILE * go_out
Definition: gen.h:41
const char * go_guardname
Definition: gen.h:40
static int ff(struct ff2c_context *ctx, struct ff2c_term *term)
Definition: parser.c:212
int i
Definition: dir.c:1033
static unsigned depth
Definition: base.c:377
int ff2c_c_gen(const struct ff2c_ff *ff, const struct ff2c_gen_opt *opt)
Definition: gen.c:198
Definition: lex.h:73
static struct m0_thread t[8]
Definition: service_ut.c:1230
int ff2c_h_gen(const struct ff2c_ff *ff, const struct ff2c_gen_opt *opt)
Definition: gen.c:93
static void indent(int depth)
Definition: gen.c:43
Definition: lex.h:67
static void type_def(const struct ff2c_type *t)
Definition: gen.c:164
static int r[NR]
Definition: thread.c:46
static void field_h(const struct ff2c_field *f, int depth)
Definition: gen.c:55
const char * e_escape
Definition: sem.h:87
Definition: lex.h:61
const char * go_basename
Definition: gen.h:39
static void type_h(const struct ff2c_type *t, int depth)
Definition: gen.c:69
Definition: lex.h:77
Definition: sem.h:55
#define out(...)
Definition: gen.c:41
static void type_fields(const struct ff2c_type *t)
Definition: gen.c:149
struct ff2c_escape * e_next
Definition: sem.h:86
Definition: lex.h:71
Definition: lex.h:69