1 |
|
|
/* $OpenBSD: rpc_cout.c,v 1.25 2015/08/20 22:32:41 deraadt Exp $ */ |
2 |
|
|
/* $NetBSD: rpc_cout.c,v 1.6 1996/10/01 04:13:53 cgd Exp $ */ |
3 |
|
|
|
4 |
|
|
/* |
5 |
|
|
* Copyright (c) 2010, Oracle America, Inc. |
6 |
|
|
* |
7 |
|
|
* Redistribution and use in source and binary forms, with or without |
8 |
|
|
* modification, are permitted provided that the following conditions are |
9 |
|
|
* met: |
10 |
|
|
* |
11 |
|
|
* * Redistributions of source code must retain the above copyright |
12 |
|
|
* notice, this list of conditions and the following disclaimer. |
13 |
|
|
* * Redistributions in binary form must reproduce the above |
14 |
|
|
* copyright notice, this list of conditions and the following |
15 |
|
|
* disclaimer in the documentation and/or other materials |
16 |
|
|
* provided with the distribution. |
17 |
|
|
* * Neither the name of the "Oracle America, Inc." nor the names of its |
18 |
|
|
* contributors may be used to endorse or promote products derived |
19 |
|
|
* from this software without specific prior written permission. |
20 |
|
|
* |
21 |
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
22 |
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
23 |
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
24 |
|
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
25 |
|
|
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
26 |
|
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
27 |
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE |
28 |
|
|
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
29 |
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
30 |
|
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
31 |
|
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
32 |
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
33 |
|
|
*/ |
34 |
|
|
|
35 |
|
|
/* |
36 |
|
|
* rpc_cout.c, XDR routine outputter for the RPC protocol compiler |
37 |
|
|
*/ |
38 |
|
|
#include <stdio.h> |
39 |
|
|
#include <stdlib.h> |
40 |
|
|
#include <string.h> |
41 |
|
|
#include <ctype.h> |
42 |
|
|
#include "rpc_parse.h" |
43 |
|
|
#include "rpc_util.h" |
44 |
|
|
|
45 |
|
|
static int findtype(definition *, char *); |
46 |
|
|
static int undefined(char *); |
47 |
|
|
static void print_generic_header(char *, int); |
48 |
|
|
static void print_header(definition *); |
49 |
|
|
static void print_prog_header(proc_list *); |
50 |
|
|
static void print_trailer(void); |
51 |
|
|
static void print_ifopen(int, char *); |
52 |
|
|
static void print_ifarg(char *); |
53 |
|
|
static void print_ifsizeof(char *, char *); |
54 |
|
|
static void print_ifclose(int); |
55 |
|
|
static void print_ifstat(int, char *, char *, relation, char *, char *, char *); |
56 |
|
|
static void emit_program(definition *); |
57 |
|
|
static void emit_enum(definition *); |
58 |
|
|
static void emit_union(definition *); |
59 |
|
|
static void emit_struct(definition *); |
60 |
|
|
static void emit_typedef(definition *); |
61 |
|
|
static void print_stat(int, declaration *); |
62 |
|
|
void emit_inline(declaration *, int); |
63 |
|
|
void emit_single_in_line(declaration *, int, relation); |
64 |
|
|
|
65 |
|
|
/* |
66 |
|
|
* Emit the C-routine for the given definition |
67 |
|
|
*/ |
68 |
|
|
void |
69 |
|
|
emit(def) |
70 |
|
|
definition *def; |
71 |
|
|
{ |
72 |
|
|
if (def->def_kind == DEF_CONST) { |
73 |
|
|
return; |
74 |
|
|
} |
75 |
|
|
if (def->def_kind == DEF_PROGRAM) { |
76 |
|
|
emit_program(def); |
77 |
|
|
return; |
78 |
|
|
} |
79 |
|
|
if (def->def_kind == DEF_TYPEDEF) { |
80 |
|
|
/* now we need to handle declarations like struct typedef foo |
81 |
|
|
* foo; since we dont want this to be expanded into 2 calls to |
82 |
|
|
* xdr_foo */ |
83 |
|
|
|
84 |
|
|
if (strcmp(def->def.ty.old_type, def->def_name) == 0) |
85 |
|
|
return; |
86 |
|
|
} |
87 |
|
|
|
88 |
|
|
print_header(def); |
89 |
|
|
switch (def->def_kind) { |
90 |
|
|
case DEF_UNION: |
91 |
|
|
emit_union(def); |
92 |
|
|
break; |
93 |
|
|
case DEF_ENUM: |
94 |
|
|
emit_enum(def); |
95 |
|
|
break; |
96 |
|
|
case DEF_STRUCT: |
97 |
|
|
emit_struct(def); |
98 |
|
|
break; |
99 |
|
|
case DEF_TYPEDEF: |
100 |
|
|
emit_typedef(def); |
101 |
|
|
break; |
102 |
|
|
} |
103 |
|
|
print_trailer(); |
104 |
|
|
} |
105 |
|
|
|
106 |
|
|
static int |
107 |
|
|
findtype(def, type) |
108 |
|
|
definition *def; |
109 |
|
|
char *type; |
110 |
|
|
{ |
111 |
|
|
|
112 |
|
|
if (def->def_kind == DEF_PROGRAM || def->def_kind == DEF_CONST) { |
113 |
|
|
return (0); |
114 |
|
|
} else { |
115 |
|
|
return (streq(def->def_name, type)); |
116 |
|
|
} |
117 |
|
|
} |
118 |
|
|
|
119 |
|
|
static int |
120 |
|
|
undefined(type) |
121 |
|
|
char *type; |
122 |
|
|
{ |
123 |
|
|
definition *def; |
124 |
|
|
|
125 |
|
|
def = (definition *) FINDVAL(defined, type, findtype); |
126 |
|
|
return (def == NULL); |
127 |
|
|
} |
128 |
|
|
|
129 |
|
|
static void |
130 |
|
|
print_generic_header(procname, pointerp) |
131 |
|
|
char *procname; |
132 |
|
|
int pointerp; |
133 |
|
|
{ |
134 |
|
|
fprintf(fout, "\n"); |
135 |
|
|
fprintf(fout, "bool_t\n"); |
136 |
|
|
if (Cflag) { |
137 |
|
|
fprintf(fout, "xdr_%s(", procname); |
138 |
|
|
fprintf(fout, "XDR *xdrs, "); |
139 |
|
|
fprintf(fout, "%s ", procname); |
140 |
|
|
if (pointerp) |
141 |
|
|
fprintf(fout, "*"); |
142 |
|
|
fprintf(fout, "objp)\n{\n"); |
143 |
|
|
} else { |
144 |
|
|
fprintf(fout, "xdr_%s(xdrs, objp)\n", procname); |
145 |
|
|
fprintf(fout, "\tXDR *xdrs;\n"); |
146 |
|
|
fprintf(fout, "\t%s ", procname); |
147 |
|
|
if (pointerp) |
148 |
|
|
fprintf(fout, "*"); |
149 |
|
|
fprintf(fout, "objp;\n{\n"); |
150 |
|
|
} |
151 |
|
|
} |
152 |
|
|
|
153 |
|
|
static void |
154 |
|
|
print_header(def) |
155 |
|
|
definition *def; |
156 |
|
|
{ |
157 |
|
|
print_generic_header(def->def_name, |
158 |
|
|
def->def_kind != DEF_TYPEDEF || |
159 |
|
|
!isvectordef(def->def.ty.old_type, def->def.ty.rel)); |
160 |
|
|
|
161 |
|
|
/* Now add Inline support */ |
162 |
|
|
|
163 |
|
|
if (doinline == 0) |
164 |
|
|
return; |
165 |
|
|
} |
166 |
|
|
|
167 |
|
|
static void |
168 |
|
|
print_prog_header(plist) |
169 |
|
|
proc_list *plist; |
170 |
|
|
{ |
171 |
|
|
print_generic_header(plist->args.argname, 1); |
172 |
|
|
} |
173 |
|
|
|
174 |
|
|
static void |
175 |
|
|
print_trailer() |
176 |
|
|
{ |
177 |
|
|
fprintf(fout, "\treturn (TRUE);\n"); |
178 |
|
|
fprintf(fout, "}\n"); |
179 |
|
|
} |
180 |
|
|
|
181 |
|
|
static void |
182 |
|
|
print_ifopen(indent, name) |
183 |
|
|
int indent; |
184 |
|
|
char *name; |
185 |
|
|
{ |
186 |
|
|
tabify(fout, indent); |
187 |
|
|
fprintf(fout, "if (!xdr_%s(xdrs", name); |
188 |
|
|
} |
189 |
|
|
|
190 |
|
|
static void |
191 |
|
|
print_ifarg(arg) |
192 |
|
|
char *arg; |
193 |
|
|
{ |
194 |
|
|
fprintf(fout, ", %s", arg); |
195 |
|
|
} |
196 |
|
|
|
197 |
|
|
static void |
198 |
|
|
print_ifsizeof(prefix, type) |
199 |
|
|
char *prefix; |
200 |
|
|
char *type; |
201 |
|
|
{ |
202 |
|
|
if (streq(type, "bool")) { |
203 |
|
|
fprintf(fout, ", sizeof(bool_t), (xdrproc_t)xdr_bool"); |
204 |
|
|
} else { |
205 |
|
|
fprintf(fout, ", sizeof("); |
206 |
|
|
if (undefined(type) && prefix) { |
207 |
|
|
fprintf(fout, "%s ", prefix); |
208 |
|
|
} |
209 |
|
|
fprintf(fout, "%s), (xdrproc_t)xdr_%s", type, type); |
210 |
|
|
} |
211 |
|
|
} |
212 |
|
|
|
213 |
|
|
static void |
214 |
|
|
print_ifclose(indent) |
215 |
|
|
int indent; |
216 |
|
|
{ |
217 |
|
|
fprintf(fout, "))\n"); |
218 |
|
|
tabify(fout, indent); |
219 |
|
|
fprintf(fout, "\treturn (FALSE);\n"); |
220 |
|
|
} |
221 |
|
|
|
222 |
|
|
static void |
223 |
|
|
print_ifstat(indent, prefix, type, rel, amax, objname, name) |
224 |
|
|
int indent; |
225 |
|
|
char *prefix; |
226 |
|
|
char *type; |
227 |
|
|
relation rel; |
228 |
|
|
char *amax; |
229 |
|
|
char *objname; |
230 |
|
|
char *name; |
231 |
|
|
{ |
232 |
|
|
char *alt = NULL; |
233 |
|
|
|
234 |
|
|
switch (rel) { |
235 |
|
|
case REL_POINTER: |
236 |
|
|
print_ifopen(indent, "pointer"); |
237 |
|
|
print_ifarg("(char **)"); |
238 |
|
|
fprintf(fout, "%s", objname); |
239 |
|
|
print_ifsizeof(prefix, type); |
240 |
|
|
break; |
241 |
|
|
case REL_VECTOR: |
242 |
|
|
if (streq(type, "string")) { |
243 |
|
|
alt = "string"; |
244 |
|
|
} else |
245 |
|
|
if (streq(type, "opaque")) { |
246 |
|
|
alt = "opaque"; |
247 |
|
|
} |
248 |
|
|
if (alt) { |
249 |
|
|
print_ifopen(indent, alt); |
250 |
|
|
print_ifarg(objname); |
251 |
|
|
print_ifarg(amax); |
252 |
|
|
} else { |
253 |
|
|
print_ifopen(indent, "vector"); |
254 |
|
|
print_ifarg("(char *)"); |
255 |
|
|
fprintf(fout, "%s,\n", objname); |
256 |
|
|
tabify(fout, indent); |
257 |
|
|
fprintf(fout, " %s", amax); |
258 |
|
|
} |
259 |
|
|
if (!alt) { |
260 |
|
|
print_ifsizeof(prefix, type); |
261 |
|
|
} |
262 |
|
|
break; |
263 |
|
|
case REL_ARRAY: |
264 |
|
|
if (streq(type, "string")) { |
265 |
|
|
alt = "string"; |
266 |
|
|
} else |
267 |
|
|
if (streq(type, "opaque")) { |
268 |
|
|
alt = "bytes"; |
269 |
|
|
} |
270 |
|
|
if (streq(type, "string")) { |
271 |
|
|
print_ifopen(indent, alt); |
272 |
|
|
print_ifarg(objname); |
273 |
|
|
print_ifarg(amax); |
274 |
|
|
} else { |
275 |
|
|
if (alt) { |
276 |
|
|
print_ifopen(indent, alt); |
277 |
|
|
} else { |
278 |
|
|
print_ifopen(indent, "array"); |
279 |
|
|
} |
280 |
|
|
print_ifarg("(char **)"); |
281 |
|
|
if (*objname == '&') { |
282 |
|
|
fprintf(fout, "%s.%s_val,\n\t (u_int *)%s.%s_len", |
283 |
|
|
objname, name, objname, name); |
284 |
|
|
} else { |
285 |
|
|
fprintf(fout, "&%s->%s_val,\n\t (u_int *)&%s->%s_len", |
286 |
|
|
objname, name, objname, name); |
287 |
|
|
} |
288 |
|
|
fprintf(fout, ",\n\t %s", amax); |
289 |
|
|
} |
290 |
|
|
if (!alt) { |
291 |
|
|
print_ifsizeof(prefix, type); |
292 |
|
|
} |
293 |
|
|
break; |
294 |
|
|
case REL_ALIAS: |
295 |
|
|
print_ifopen(indent, type); |
296 |
|
|
print_ifarg(objname); |
297 |
|
|
break; |
298 |
|
|
} |
299 |
|
|
print_ifclose(indent); |
300 |
|
|
} |
301 |
|
|
|
302 |
|
|
/* ARGSUSED */ |
303 |
|
|
static void |
304 |
|
|
emit_enum(def) |
305 |
|
|
definition *def; |
306 |
|
|
{ |
307 |
|
|
fprintf(fout, "\n"); |
308 |
|
|
|
309 |
|
|
print_ifopen(1, "enum"); |
310 |
|
|
print_ifarg("(enum_t *)objp"); |
311 |
|
|
print_ifclose(1); |
312 |
|
|
} |
313 |
|
|
|
314 |
|
|
static void |
315 |
|
|
emit_program(def) |
316 |
|
|
definition *def; |
317 |
|
|
{ |
318 |
|
|
decl_list *dl; |
319 |
|
|
version_list *vlist; |
320 |
|
|
proc_list *plist; |
321 |
|
|
|
322 |
|
|
for (vlist = def->def.pr.versions; vlist != NULL; vlist = vlist->next) |
323 |
|
|
for (plist = vlist->procs; plist != NULL; plist = plist->next) { |
324 |
|
|
if (!newstyle || plist->arg_num < 2) |
325 |
|
|
continue; /* old style, or single |
326 |
|
|
* argument */ |
327 |
|
|
print_prog_header(plist); |
328 |
|
|
for (dl = plist->args.decls; dl != NULL; |
329 |
|
|
dl = dl->next) |
330 |
|
|
print_stat(1, &dl->decl); |
331 |
|
|
print_trailer(); |
332 |
|
|
} |
333 |
|
|
} |
334 |
|
|
|
335 |
|
|
static void |
336 |
|
|
emit_union(def) |
337 |
|
|
definition *def; |
338 |
|
|
{ |
339 |
|
|
declaration *dflt; |
340 |
|
|
case_list *cl; |
341 |
|
|
declaration *cs; |
342 |
|
|
char *object; |
343 |
|
|
static const char vecformat[] = "objp->%s_u.%s"; |
344 |
|
|
static const char format[] = "&objp->%s_u.%s"; |
345 |
|
|
|
346 |
|
|
fprintf(fout, "\n"); |
347 |
|
|
print_stat(1, &def->def.un.enum_decl); |
348 |
|
|
fprintf(fout, "\tswitch (objp->%s) {\n", def->def.un.enum_decl.name); |
349 |
|
|
for (cl = def->def.un.cases; cl != NULL; cl = cl->next) { |
350 |
|
|
fprintf(fout, "\tcase %s:\n", cl->case_name); |
351 |
|
|
if (cl->contflag == 1) /* a continued case statement */ |
352 |
|
|
continue; |
353 |
|
|
cs = &cl->case_decl; |
354 |
|
|
if (!streq(cs->type, "void")) { |
355 |
|
|
int len = strlen(def->def_name) + strlen(format) + |
356 |
|
|
strlen(cs->name) + 1; |
357 |
|
|
|
358 |
|
|
object = malloc(len); |
359 |
|
|
if (object == NULL) { |
360 |
|
|
fprintf(stderr, "Fatal error: no memory\n"); |
361 |
|
|
crash(); |
362 |
|
|
} |
363 |
|
|
if (isvectordef(cs->type, cs->rel)) { |
364 |
|
|
snprintf(object, len, vecformat, def->def_name, |
365 |
|
|
cs->name); |
366 |
|
|
} else { |
367 |
|
|
snprintf(object, len, format, def->def_name, |
368 |
|
|
cs->name); |
369 |
|
|
} |
370 |
|
|
print_ifstat(2, cs->prefix, cs->type, cs->rel, cs->array_max, |
371 |
|
|
object, cs->name); |
372 |
|
|
free(object); |
373 |
|
|
} |
374 |
|
|
fprintf(fout, "\t\tbreak;\n"); |
375 |
|
|
} |
376 |
|
|
dflt = def->def.un.default_decl; |
377 |
|
|
if (dflt != NULL) { |
378 |
|
|
if (!streq(dflt->type, "void")) { |
379 |
|
|
int len = strlen(def->def_name) + strlen(format) + |
380 |
|
|
strlen(dflt->name) + 1; |
381 |
|
|
|
382 |
|
|
fprintf(fout, "\tdefault:\n"); |
383 |
|
|
object = malloc(len); |
384 |
|
|
if (object == NULL) { |
385 |
|
|
fprintf(stderr, "Fatal error: no memory\n"); |
386 |
|
|
crash(); |
387 |
|
|
} |
388 |
|
|
if (isvectordef(dflt->type, dflt->rel)) { |
389 |
|
|
snprintf(object, len, vecformat, def->def_name, |
390 |
|
|
dflt->name); |
391 |
|
|
} else { |
392 |
|
|
snprintf(object, len, format, def->def_name, |
393 |
|
|
dflt->name); |
394 |
|
|
} |
395 |
|
|
|
396 |
|
|
print_ifstat(2, dflt->prefix, dflt->type, dflt->rel, |
397 |
|
|
dflt->array_max, object, dflt->name); |
398 |
|
|
free(object); |
399 |
|
|
fprintf(fout, "\t\tbreak;\n"); |
400 |
|
|
} |
401 |
|
|
} else { |
402 |
|
|
fprintf(fout, "\tdefault:\n"); |
403 |
|
|
fprintf(fout, "\t\treturn (FALSE);\n"); |
404 |
|
|
} |
405 |
|
|
|
406 |
|
|
fprintf(fout, "\t}\n"); |
407 |
|
|
} |
408 |
|
|
|
409 |
|
|
static void |
410 |
|
|
emit_struct(def) |
411 |
|
|
definition *def; |
412 |
|
|
{ |
413 |
|
|
decl_list *dl; |
414 |
|
|
int i, j, size, flag; |
415 |
|
|
decl_list *cur, *psav; |
416 |
|
|
bas_type *ptr; |
417 |
|
|
char *sizestr, *plus; |
418 |
|
|
char ptemp[256]; |
419 |
|
|
int can_inline; |
420 |
|
|
|
421 |
|
|
if (doinline == 0) { |
422 |
|
|
for (dl = def->def.st.decls; dl != NULL; dl = dl->next) |
423 |
|
|
print_stat(1, &dl->decl); |
424 |
|
|
return; |
425 |
|
|
} |
426 |
|
|
for (dl = def->def.st.decls; dl != NULL; dl = dl->next) |
427 |
|
|
if (dl->decl.rel == REL_VECTOR) { |
428 |
|
|
fprintf(fout, "\tint i;\n"); |
429 |
|
|
break; |
430 |
|
|
} |
431 |
|
|
fprintf(fout, "\n"); |
432 |
|
|
|
433 |
|
|
size = 0; |
434 |
|
|
can_inline = 0; |
435 |
|
|
for (dl = def->def.st.decls; dl != NULL; dl = dl->next) |
436 |
|
|
if (dl->decl.prefix == NULL && |
437 |
|
|
(ptr = find_type(dl->decl.type)) != NULL && |
438 |
|
|
(dl->decl.rel == REL_ALIAS || dl->decl.rel == REL_VECTOR)) { |
439 |
|
|
if (dl->decl.rel == REL_ALIAS) |
440 |
|
|
size += ptr->length; |
441 |
|
|
else { |
442 |
|
|
can_inline = 1; |
443 |
|
|
break; /* can be inlined */ |
444 |
|
|
} |
445 |
|
|
} else { |
446 |
|
|
if (size >= doinline) { |
447 |
|
|
can_inline = 1; |
448 |
|
|
break; /* can be inlined */ |
449 |
|
|
} |
450 |
|
|
size = 0; |
451 |
|
|
} |
452 |
|
|
if (size > doinline) |
453 |
|
|
can_inline = 1; |
454 |
|
|
|
455 |
|
|
if (can_inline == 0) { /* can not inline, drop back to old mode */ |
456 |
|
|
fprintf(fout, "\n"); |
457 |
|
|
for (dl = def->def.st.decls; dl != NULL; dl = dl->next) |
458 |
|
|
print_stat(1, &dl->decl); |
459 |
|
|
return; |
460 |
|
|
} |
461 |
|
|
|
462 |
|
|
/* May cause lint to complain. but ... */ |
463 |
|
|
fprintf(fout, "\tint32_t *buf;\n"); |
464 |
|
|
|
465 |
|
|
flag = PUT; |
466 |
|
|
for (j = 0; j < 2; j++) { |
467 |
|
|
if (flag == PUT) |
468 |
|
|
fprintf(fout, "\n\tif (xdrs->x_op == XDR_ENCODE) {\n"); |
469 |
|
|
else |
470 |
|
|
fprintf(fout, "\t\treturn (TRUE);\n\t} else if (xdrs->x_op == XDR_DECODE) {\n"); |
471 |
|
|
|
472 |
|
|
i = 0; |
473 |
|
|
size = 0; |
474 |
|
|
sizestr = NULL; |
475 |
|
|
for (dl = def->def.st.decls; dl != NULL; dl = dl->next) { /* xxx */ |
476 |
|
|
|
477 |
|
|
/* now walk down the list and check for basic types */ |
478 |
|
|
if (dl->decl.prefix == NULL && |
479 |
|
|
(ptr = find_type(dl->decl.type)) != NULL && |
480 |
|
|
(dl->decl.rel == REL_ALIAS || dl->decl.rel == REL_VECTOR)) { |
481 |
|
|
if (i == 0) |
482 |
|
|
cur = dl; |
483 |
|
|
i++; |
484 |
|
|
|
485 |
|
|
if (dl->decl.rel == REL_ALIAS) |
486 |
|
|
size += ptr->length; |
487 |
|
|
else { |
488 |
|
|
/* this is required to handle arrays */ |
489 |
|
|
|
490 |
|
|
if (sizestr == NULL) |
491 |
|
|
plus = ""; |
492 |
|
|
else |
493 |
|
|
plus = "+"; |
494 |
|
|
|
495 |
|
|
if (ptr->length != 1) |
496 |
|
|
snprintf(ptemp, sizeof ptemp, |
497 |
|
|
"%s%s* %d", plus, |
498 |
|
|
dl->decl.array_max, |
499 |
|
|
ptr->length); |
500 |
|
|
else |
501 |
|
|
snprintf(ptemp, sizeof ptemp, |
502 |
|
|
"%s%s", plus, |
503 |
|
|
dl->decl.array_max); |
504 |
|
|
|
505 |
|
|
/* now concatenate to sizestr !!!! */ |
506 |
|
|
if (sizestr == NULL) { |
507 |
|
|
sizestr = strdup(ptemp); |
508 |
|
|
if (sizestr == NULL) { |
509 |
|
|
fprintf(stderr, |
510 |
|
|
"Fatal error: no memory\n"); |
511 |
|
|
crash(); |
512 |
|
|
} |
513 |
|
|
} else { |
514 |
|
|
size_t len; |
515 |
|
|
|
516 |
|
|
len = strlen(sizestr) + |
517 |
|
|
strlen(ptemp) + 1; |
518 |
|
|
sizestr = realloc(sizestr, len); |
519 |
|
|
if (sizestr == NULL) { |
520 |
|
|
fprintf(stderr, |
521 |
|
|
"Fatal error: no memory\n"); |
522 |
|
|
crash(); |
523 |
|
|
} |
524 |
|
|
/* build up length of array */ |
525 |
|
|
strlcat(sizestr, ptemp, len); |
526 |
|
|
} |
527 |
|
|
} |
528 |
|
|
|
529 |
|
|
} else { |
530 |
|
|
if (i > 0) { |
531 |
|
|
if (sizestr == NULL && size < doinline) { |
532 |
|
|
/* don't expand into inline |
533 |
|
|
* code if size < doinline */ |
534 |
|
|
while (cur != dl) { |
535 |
|
|
print_stat(2, &cur->decl); |
536 |
|
|
cur = cur->next; |
537 |
|
|
} |
538 |
|
|
} else { |
539 |
|
|
/* were already looking at a |
540 |
|
|
* xdr_inlineable structure */ |
541 |
|
|
if (sizestr == NULL) |
542 |
|
|
fprintf(fout, |
543 |
|
|
"\t\tbuf = (int32_t *)XDR_INLINE(xdrs,\n\t\t %d * BYTES_PER_XDR_UNIT);", size); |
544 |
|
|
else if (size == 0) |
545 |
|
|
fprintf(fout, |
546 |
|
|
"\t\tbuf = (int32_t *)XDR_INLINE(xdrs,\n\t\t %s * BYTES_PER_XDR_UNIT);", |
547 |
|
|
sizestr); |
548 |
|
|
else |
549 |
|
|
fprintf(fout, |
550 |
|
|
"\t\tbuf = (int32_t *)XDR_INLINE(xdrs,\n\t\t (%d + %s) * BYTES_PER_XDR_UNIT);", size, sizestr); |
551 |
|
|
|
552 |
|
|
fprintf(fout, |
553 |
|
|
"\n\t\tif (buf == NULL) {\n"); |
554 |
|
|
|
555 |
|
|
psav = cur; |
556 |
|
|
while (cur != dl) { |
557 |
|
|
print_stat(3, &cur->decl); |
558 |
|
|
cur = cur->next; |
559 |
|
|
} |
560 |
|
|
|
561 |
|
|
fprintf(fout, "\t\t} else {\n"); |
562 |
|
|
|
563 |
|
|
cur = psav; |
564 |
|
|
while (cur != dl) { |
565 |
|
|
emit_inline(&cur->decl, flag); |
566 |
|
|
cur = cur->next; |
567 |
|
|
} |
568 |
|
|
fprintf(fout, "\t\t}\n"); |
569 |
|
|
} |
570 |
|
|
} |
571 |
|
|
size = 0; |
572 |
|
|
i = 0; |
573 |
|
|
sizestr = NULL; |
574 |
|
|
print_stat(2, &dl->decl); |
575 |
|
|
} |
576 |
|
|
} |
577 |
|
|
if (i > 0) { |
578 |
|
|
if (sizestr == NULL && size < doinline) { |
579 |
|
|
/* don't expand into inline code if size < |
580 |
|
|
* doinline */ |
581 |
|
|
while (cur != dl) { |
582 |
|
|
print_stat(2, &cur->decl); |
583 |
|
|
cur = cur->next; |
584 |
|
|
} |
585 |
|
|
} else { |
586 |
|
|
/* were already looking at a xdr_inlineable |
587 |
|
|
* structure */ |
588 |
|
|
if (sizestr == NULL) |
589 |
|
|
fprintf(fout, "\t\tbuf = (int32_t *)XDR_INLINE(xdrs,\n\t\t %d * BYTES_PER_XDR_UNIT);", |
590 |
|
|
size); |
591 |
|
|
else |
592 |
|
|
if (size == 0) |
593 |
|
|
fprintf(fout, |
594 |
|
|
"\t\tbuf = (int32_t *)XDR_INLINE(xdrs,\n\t\t %s * BYTES_PER_XDR_UNIT);", |
595 |
|
|
sizestr); |
596 |
|
|
else |
597 |
|
|
fprintf(fout, |
598 |
|
|
"\t\tbuf = (int32_t *)XDR_INLINE(xdrs,\n\t\t (%d + %s) * BYTES_PER_XDR_UNIT);", |
599 |
|
|
size, sizestr); |
600 |
|
|
|
601 |
|
|
fprintf(fout, "\n\t\tif (buf == NULL) {\n"); |
602 |
|
|
|
603 |
|
|
psav = cur; |
604 |
|
|
while (cur != NULL) { |
605 |
|
|
print_stat(3, &cur->decl); |
606 |
|
|
cur = cur->next; |
607 |
|
|
} |
608 |
|
|
fprintf(fout, "\t\t} else {\n"); |
609 |
|
|
|
610 |
|
|
cur = psav; |
611 |
|
|
while (cur != dl) { |
612 |
|
|
emit_inline(&cur->decl, flag); |
613 |
|
|
cur = cur->next; |
614 |
|
|
} |
615 |
|
|
|
616 |
|
|
fprintf(fout, "\t\t}\n"); |
617 |
|
|
|
618 |
|
|
} |
619 |
|
|
} |
620 |
|
|
flag = GET; |
621 |
|
|
} |
622 |
|
|
fprintf(fout, "\t\treturn (TRUE);\n\t}\n\n"); |
623 |
|
|
|
624 |
|
|
/* now take care of XDR_FREE case */ |
625 |
|
|
|
626 |
|
|
for (dl = def->def.st.decls; dl != NULL; dl = dl->next) |
627 |
|
|
print_stat(1, &dl->decl); |
628 |
|
|
} |
629 |
|
|
|
630 |
|
|
static void |
631 |
|
|
emit_typedef(def) |
632 |
|
|
definition *def; |
633 |
|
|
{ |
634 |
|
|
char *prefix = def->def.ty.old_prefix; |
635 |
|
|
char *type = def->def.ty.old_type; |
636 |
|
|
char *amax = def->def.ty.array_max; |
637 |
|
|
relation rel = def->def.ty.rel; |
638 |
|
|
|
639 |
|
|
fprintf(fout, "\n"); |
640 |
|
|
print_ifstat(1, prefix, type, rel, amax, "objp", def->def_name); |
641 |
|
|
} |
642 |
|
|
|
643 |
|
|
static void |
644 |
|
|
print_stat(indent, dec) |
645 |
|
|
declaration *dec; |
646 |
|
|
int indent; |
647 |
|
|
{ |
648 |
|
|
char *prefix = dec->prefix; |
649 |
|
|
char *type = dec->type; |
650 |
|
|
char *amax = dec->array_max; |
651 |
|
|
relation rel = dec->rel; |
652 |
|
|
char name[256]; |
653 |
|
|
|
654 |
|
|
if (isvectordef(type, rel)) { |
655 |
|
|
snprintf(name, sizeof name, "objp->%s", dec->name); |
656 |
|
|
} else { |
657 |
|
|
snprintf(name, sizeof name, "&objp->%s", dec->name); |
658 |
|
|
} |
659 |
|
|
print_ifstat(indent, prefix, type, rel, amax, name, dec->name); |
660 |
|
|
} |
661 |
|
|
|
662 |
|
|
char *upcase(char *); |
663 |
|
|
|
664 |
|
|
void |
665 |
|
|
emit_inline(decl, flag) |
666 |
|
|
declaration *decl; |
667 |
|
|
int flag; |
668 |
|
|
{ |
669 |
|
|
/*check whether an array or not */ |
670 |
|
|
|
671 |
|
|
switch (decl->rel) { |
672 |
|
|
case REL_ALIAS: |
673 |
|
|
fprintf(fout, "\t"); |
674 |
|
|
emit_single_in_line(decl, flag, REL_ALIAS); |
675 |
|
|
break; |
676 |
|
|
case REL_VECTOR: |
677 |
|
|
fprintf(fout, "\t\t\t{\n\t\t\t\t%s *genp;\n\n", decl->type); |
678 |
|
|
fprintf(fout, "\t\t\t\tfor (i = 0, genp = objp->%s;\n\t\t\t\t i < %s; i++) {\n\t\t\t", |
679 |
|
|
decl->name, decl->array_max); |
680 |
|
|
emit_single_in_line(decl, flag, REL_VECTOR); |
681 |
|
|
fprintf(fout, "\t\t\t\t}\n\t\t\t}\n"); |
682 |
|
|
|
683 |
|
|
} |
684 |
|
|
} |
685 |
|
|
|
686 |
|
|
void |
687 |
|
|
emit_single_in_line(decl, flag, rel) |
688 |
|
|
declaration *decl; |
689 |
|
|
int flag; |
690 |
|
|
relation rel; |
691 |
|
|
{ |
692 |
|
|
char *upp_case; |
693 |
|
|
int freed = 0; |
694 |
|
|
|
695 |
|
|
if (flag == PUT) |
696 |
|
|
fprintf(fout, "\t\tIXDR_PUT_"); |
697 |
|
|
else |
698 |
|
|
if (rel == REL_ALIAS) |
699 |
|
|
fprintf(fout, "\t\tobjp->%s = IXDR_GET_", decl->name); |
700 |
|
|
else |
701 |
|
|
fprintf(fout, "\t\t*genp++ = IXDR_GET_"); |
702 |
|
|
|
703 |
|
|
upp_case = upcase(decl->type); |
704 |
|
|
|
705 |
|
|
/* hack - XX */ |
706 |
|
|
if (strcmp(upp_case, "INT") == 0) { |
707 |
|
|
free(upp_case); |
708 |
|
|
freed = 1; |
709 |
|
|
upp_case = "LONG"; |
710 |
|
|
} |
711 |
|
|
if (strcmp(upp_case, "U_INT") == 0) { |
712 |
|
|
free(upp_case); |
713 |
|
|
freed = 1; |
714 |
|
|
upp_case = "U_LONG"; |
715 |
|
|
} |
716 |
|
|
if (flag == PUT) |
717 |
|
|
if (rel == REL_ALIAS) |
718 |
|
|
fprintf(fout, "%s(buf, objp->%s);\n", upp_case, decl->name); |
719 |
|
|
else |
720 |
|
|
fprintf(fout, "%s(buf, *genp++);\n", upp_case); |
721 |
|
|
|
722 |
|
|
else |
723 |
|
|
fprintf(fout, "%s(buf);\n", upp_case); |
724 |
|
|
if (!freed) |
725 |
|
|
free(upp_case); |
726 |
|
|
} |
727 |
|
|
|
728 |
|
|
char * |
729 |
|
|
upcase(str) |
730 |
|
|
char *str; |
731 |
|
|
{ |
732 |
|
|
char *ptr, *hptr; |
733 |
|
|
|
734 |
|
|
ptr = malloc(strlen(str)+1); |
735 |
|
|
if (ptr == (char *) NULL) { |
736 |
|
|
fprintf(stderr, "malloc failed\n"); |
737 |
|
|
exit(1); |
738 |
|
|
} |
739 |
|
|
|
740 |
|
|
hptr = ptr; |
741 |
|
|
while (*str != '\0') |
742 |
|
|
*ptr++ = toupper((unsigned char)*str++); |
743 |
|
|
|
744 |
|
|
*ptr = '\0'; |
745 |
|
|
return (hptr); |
746 |
|
|
} |