]>
Commit | Line | Data |
---|---|---|
28f540f4 | 1 | /* |
a7ab6ec8 | 2 | * From: @(#)rpc_util.c 1.11 89/02/22 |
cb636bb2 | 3 | * |
a7ab6ec8 UD |
4 | * Copyright (c) 2010, Oracle America, Inc. |
5 | * Redistribution and use in source and binary forms, with or without | |
6 | * modification, are permitted provided that the following conditions are | |
7 | * met: | |
cbd3dceb | 8 | * |
a7ab6ec8 UD |
9 | * * Redistributions of source code must retain the above copyright |
10 | * notice, this list of conditions and the following disclaimer. | |
11 | * * Redistributions in binary form must reproduce the above | |
12 | * copyright notice, this list of conditions and the following | |
13 | * disclaimer in the documentation and/or other materials | |
14 | * provided with the distribution. | |
15 | * * Neither the name of the "Oracle America, Inc." nor the names of its | |
16 | * contributors may be used to endorse or promote products derived | |
17 | * from this software without specific prior written permission. | |
cbd3dceb | 18 | * |
a7ab6ec8 UD |
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
20 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | |
22 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | |
23 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, | |
24 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
25 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE | |
26 | * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | |
28 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |
29 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
0d204b0a | 31 | */ |
28f540f4 RM |
32 | |
33 | /* | |
e7fd8a39 | 34 | * rpc_util.c, Utility routines for the RPC protocol compiler |
28f540f4 RM |
35 | */ |
36 | #include <stdio.h> | |
0d204b0a UD |
37 | #include <ctype.h> |
38 | #include <string.h> | |
39 | #include <unistd.h> | |
28f540f4 RM |
40 | #include "rpc_scan.h" |
41 | #include "rpc_parse.h" | |
42 | #include "rpc_util.h" | |
0d204b0a UD |
43 | #include "proto.h" |
44 | ||
45 | #define ARGEXT "argument" | |
28f540f4 RM |
46 | |
47 | char curline[MAXLINESIZE]; /* current read line */ | |
0d204b0a UD |
48 | const char *where = curline; /* current point in line */ |
49 | int linenum = 0; /* current line number */ | |
28f540f4 | 50 | |
0d204b0a | 51 | const char *infilename; /* input filename */ |
28f540f4 | 52 | |
0d204b0a UD |
53 | #define NFILES 7 |
54 | const char *outfiles[NFILES]; /* output file names */ | |
28f540f4 RM |
55 | int nfiles; |
56 | ||
0d204b0a UD |
57 | FILE *fout; /* file pointer of current output */ |
58 | FILE *fin; /* file pointer of current input */ | |
28f540f4 | 59 | |
0d204b0a UD |
60 | list *defined; /* list of defined things */ |
61 | ||
e7fd8a39 UD |
62 | static int findit (const definition * def, const char *type); |
63 | static const char *fixit (const char *type, const char *orig); | |
64 | static int typedefed (const definition * def, const char *type); | |
65 | static const char *toktostr (tok_kind kind); | |
66 | static void printbuf (void); | |
67 | static void printwhere (void); | |
28f540f4 RM |
68 | |
69 | /* | |
e7fd8a39 | 70 | * Reinitialize the world |
28f540f4 | 71 | */ |
0d204b0a | 72 | void |
e7fd8a39 | 73 | reinitialize (void) |
28f540f4 | 74 | { |
e7fd8a39 UD |
75 | memset (curline, 0, MAXLINESIZE); |
76 | where = curline; | |
77 | linenum = 0; | |
78 | defined = NULL; | |
28f540f4 RM |
79 | } |
80 | ||
81 | /* | |
e7fd8a39 | 82 | * string equality |
28f540f4 | 83 | */ |
0d204b0a | 84 | int |
e7fd8a39 | 85 | streq (const char *a, const char *b) |
28f540f4 | 86 | { |
e7fd8a39 | 87 | return strcmp (a, b) == 0; |
28f540f4 RM |
88 | } |
89 | ||
90 | /* | |
e7fd8a39 | 91 | * find a value in a list |
28f540f4 | 92 | */ |
0d204b0a | 93 | definition * |
880f421f | 94 | findval (list *lst, const char *val, |
e7fd8a39 | 95 | int (*cmp) (const definition *, const char *)) |
28f540f4 | 96 | { |
e7fd8a39 UD |
97 | |
98 | for (; lst != NULL; lst = lst->next) | |
99 | { | |
100 | if (cmp (lst->val, val)) | |
101 | { | |
102 | return lst->val; | |
28f540f4 | 103 | } |
e7fd8a39 UD |
104 | } |
105 | return NULL; | |
28f540f4 RM |
106 | } |
107 | ||
108 | /* | |
e7fd8a39 | 109 | * store a value in a list |
28f540f4 RM |
110 | */ |
111 | void | |
880f421f | 112 | storeval (list **lstp, definition *val) |
28f540f4 | 113 | { |
e7fd8a39 UD |
114 | list **l; |
115 | list *lst; | |
116 | ||
117 | ||
118 | for (l = lstp; *l != NULL; l = (list **) & (*l)->next); | |
119 | lst = ALLOC (list); | |
120 | lst->val = val; | |
121 | lst->next = NULL; | |
122 | *l = lst; | |
28f540f4 RM |
123 | } |
124 | ||
0d204b0a | 125 | static int |
e7fd8a39 | 126 | findit (const definition * def, const char *type) |
28f540f4 | 127 | { |
e7fd8a39 | 128 | return streq (def->def_name, type); |
28f540f4 RM |
129 | } |
130 | ||
0d204b0a | 131 | static const char * |
e7fd8a39 | 132 | fixit (const char *type, const char *orig) |
28f540f4 | 133 | { |
e7fd8a39 | 134 | definition *def; |
28f540f4 | 135 | |
e7fd8a39 UD |
136 | def = findval (defined, type, findit); |
137 | if (def == NULL || def->def_kind != DEF_TYPEDEF) | |
138 | { | |
139 | return orig; | |
140 | } | |
141 | switch (def->def.ty.rel) | |
142 | { | |
143 | case REL_VECTOR: | |
880f421f UD |
144 | if (streq (def->def.ty.old_type, "opaque")) |
145 | return ("char"); | |
146 | else | |
147 | return (def->def.ty.old_type); | |
e7fd8a39 UD |
148 | case REL_ALIAS: |
149 | return (fixit (def->def.ty.old_type, orig)); | |
150 | default: | |
151 | return orig; | |
152 | } | |
28f540f4 RM |
153 | } |
154 | ||
0d204b0a | 155 | const char * |
e7fd8a39 | 156 | fixtype (const char *type) |
28f540f4 | 157 | { |
e7fd8a39 | 158 | return fixit (type, type); |
28f540f4 RM |
159 | } |
160 | ||
0d204b0a | 161 | const char * |
e7fd8a39 | 162 | stringfix (const char *type) |
28f540f4 | 163 | { |
e7fd8a39 UD |
164 | if (streq (type, "string")) |
165 | { | |
166 | return "wrapstring"; | |
167 | } | |
168 | else | |
169 | { | |
170 | return type; | |
171 | } | |
28f540f4 RM |
172 | } |
173 | ||
174 | void | |
e7fd8a39 | 175 | ptype (const char *prefix, const char *type, int follow) |
28f540f4 | 176 | { |
e7fd8a39 UD |
177 | if (prefix != NULL) |
178 | { | |
179 | if (streq (prefix, "enum")) | |
180 | { | |
181 | f_print (fout, "enum "); | |
28f540f4 | 182 | } |
e7fd8a39 UD |
183 | else |
184 | { | |
185 | f_print (fout, "struct "); | |
28f540f4 | 186 | } |
e7fd8a39 UD |
187 | } |
188 | if (streq (type, "bool")) | |
189 | { | |
190 | f_print (fout, "bool_t "); | |
191 | } | |
192 | else if (streq (type, "string")) | |
193 | { | |
194 | f_print (fout, "char *"); | |
195 | } | |
196 | else | |
197 | { | |
198 | f_print (fout, "%s ", follow ? fixtype (type) : type); | |
199 | } | |
28f540f4 RM |
200 | } |
201 | ||
0d204b0a | 202 | static int |
e7fd8a39 | 203 | typedefed (const definition * def, const char *type) |
28f540f4 | 204 | { |
e7fd8a39 UD |
205 | if (def->def_kind != DEF_TYPEDEF || def->def.ty.old_prefix != NULL) |
206 | { | |
207 | return 0; | |
208 | } | |
209 | else | |
210 | { | |
211 | return streq (def->def_name, type); | |
212 | } | |
28f540f4 RM |
213 | } |
214 | ||
0d204b0a | 215 | int |
e7fd8a39 | 216 | isvectordef (const char *type, relation rel) |
28f540f4 | 217 | { |
e7fd8a39 UD |
218 | definition *def; |
219 | ||
220 | for (;;) | |
221 | { | |
222 | switch (rel) | |
223 | { | |
224 | case REL_VECTOR: | |
225 | return !streq (type, "string"); | |
226 | case REL_ARRAY: | |
227 | return 0; | |
228 | case REL_POINTER: | |
880f421f | 229 | return 0; |
e7fd8a39 UD |
230 | case REL_ALIAS: |
231 | def = findval (defined, type, typedefed); | |
232 | if (def == NULL) | |
233 | { | |
234 | return 0; | |
235 | } | |
236 | type = def->def.ty.old_type; | |
237 | rel = def->def.ty.rel; | |
28f540f4 | 238 | } |
e7fd8a39 | 239 | } |
28f540f4 RM |
240 | } |
241 | ||
0d204b0a | 242 | char * |
e7fd8a39 | 243 | locase (const char *str) |
28f540f4 | 244 | { |
e7fd8a39 UD |
245 | char c; |
246 | static char buf[100]; | |
247 | char *p = buf; | |
28f540f4 | 248 | |
e7fd8a39 UD |
249 | while ((c = *str++) != 0) |
250 | { | |
251 | *p++ = (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c; | |
252 | } | |
253 | *p = 0; | |
254 | return buf; | |
28f540f4 RM |
255 | } |
256 | ||
0d204b0a | 257 | void |
e7fd8a39 | 258 | pvname_svc (const char *pname, const char *vnum) |
0d204b0a | 259 | { |
e7fd8a39 | 260 | f_print (fout, "%s_%s_svc", locase (pname), vnum); |
0d204b0a | 261 | } |
28f540f4 RM |
262 | |
263 | void | |
e7fd8a39 | 264 | pvname (const char *pname, const char *vnum) |
28f540f4 | 265 | { |
e7fd8a39 | 266 | f_print (fout, "%s_%s", locase (pname), vnum); |
28f540f4 RM |
267 | } |
268 | ||
28f540f4 | 269 | /* |
e7fd8a39 | 270 | * print a useful (?) error message, and then die |
28f540f4 RM |
271 | */ |
272 | void | |
e7fd8a39 | 273 | error (const char *msg) |
28f540f4 | 274 | { |
e7fd8a39 UD |
275 | printwhere (); |
276 | f_print (stderr, "%s, line %d: ", infilename, linenum); | |
277 | f_print (stderr, "%s\n", msg); | |
278 | crash (); | |
28f540f4 RM |
279 | } |
280 | ||
281 | /* | |
282 | * Something went wrong, unlink any files that we may have created and then | |
e7fd8a39 | 283 | * die. |
28f540f4 | 284 | */ |
0d204b0a | 285 | void |
e7fd8a39 | 286 | crash (void) |
28f540f4 | 287 | { |
e7fd8a39 | 288 | int i; |
28f540f4 | 289 | |
e7fd8a39 UD |
290 | for (i = 0; i < nfiles; i++) |
291 | { | |
880f421f | 292 | unlink (outfiles[i]); |
e7fd8a39 UD |
293 | } |
294 | exit (1); | |
28f540f4 RM |
295 | } |
296 | ||
28f540f4 | 297 | void |
e7fd8a39 | 298 | record_open (const char *file) |
28f540f4 | 299 | { |
e7fd8a39 UD |
300 | if (nfiles < NFILES) |
301 | { | |
302 | outfiles[nfiles++] = file; | |
303 | } | |
304 | else | |
305 | { | |
306 | f_print (stderr, "too many files!\n"); | |
307 | crash (); | |
308 | } | |
28f540f4 RM |
309 | } |
310 | ||
311 | static char expectbuf[100]; | |
28f540f4 RM |
312 | |
313 | /* | |
e7fd8a39 | 314 | * error, token encountered was not the expected one |
28f540f4 RM |
315 | */ |
316 | void | |
e7fd8a39 | 317 | expected1 (tok_kind exp1) |
28f540f4 | 318 | { |
e7fd8a39 UD |
319 | s_print (expectbuf, "expected '%s'", |
320 | toktostr (exp1)); | |
321 | error (expectbuf); | |
28f540f4 RM |
322 | } |
323 | ||
324 | /* | |
e7fd8a39 | 325 | * error, token encountered was not one of two expected ones |
28f540f4 RM |
326 | */ |
327 | void | |
e7fd8a39 | 328 | expected2 (tok_kind exp1, tok_kind exp2) |
28f540f4 | 329 | { |
e7fd8a39 UD |
330 | s_print (expectbuf, "expected '%s' or '%s'", |
331 | toktostr (exp1), | |
332 | toktostr (exp2)); | |
333 | error (expectbuf); | |
28f540f4 RM |
334 | } |
335 | ||
336 | /* | |
e7fd8a39 | 337 | * error, token encountered was not one of 3 expected ones |
28f540f4 RM |
338 | */ |
339 | void | |
e7fd8a39 | 340 | expected3 (tok_kind exp1, tok_kind exp2, tok_kind exp3) |
28f540f4 | 341 | { |
e7fd8a39 UD |
342 | s_print (expectbuf, "expected '%s', '%s' or '%s'", |
343 | toktostr (exp1), | |
344 | toktostr (exp2), | |
345 | toktostr (exp3)); | |
346 | error (expectbuf); | |
28f540f4 RM |
347 | } |
348 | ||
349 | void | |
e7fd8a39 | 350 | tabify (FILE * f, int tab) |
28f540f4 | 351 | { |
e7fd8a39 UD |
352 | while (tab--) |
353 | { | |
354 | (void) fputc ('\t', f); | |
355 | } | |
28f540f4 RM |
356 | } |
357 | ||
358 | ||
e7fd8a39 UD |
359 | static const token tokstrings[] = |
360 | { | |
361 | {TOK_IDENT, "identifier"}, | |
362 | {TOK_CONST, "const"}, | |
363 | {TOK_RPAREN, ")"}, | |
364 | {TOK_LPAREN, "("}, | |
365 | {TOK_RBRACE, "}"}, | |
366 | {TOK_LBRACE, "{"}, | |
367 | {TOK_LBRACKET, "["}, | |
368 | {TOK_RBRACKET, "]"}, | |
369 | {TOK_STAR, "*"}, | |
370 | {TOK_COMMA, ","}, | |
371 | {TOK_EQUAL, "="}, | |
372 | {TOK_COLON, ":"}, | |
373 | {TOK_SEMICOLON, ";"}, | |
374 | {TOK_UNION, "union"}, | |
375 | {TOK_STRUCT, "struct"}, | |
376 | {TOK_SWITCH, "switch"}, | |
377 | {TOK_CASE, "case"}, | |
378 | {TOK_DEFAULT, "default"}, | |
379 | {TOK_ENUM, "enum"}, | |
380 | {TOK_TYPEDEF, "typedef"}, | |
381 | {TOK_INT, "int"}, | |
382 | {TOK_SHORT, "short"}, | |
383 | {TOK_LONG, "long"}, | |
384 | {TOK_UNSIGNED, "unsigned"}, | |
385 | {TOK_DOUBLE, "double"}, | |
386 | {TOK_FLOAT, "float"}, | |
387 | {TOK_CHAR, "char"}, | |
388 | {TOK_STRING, "string"}, | |
389 | {TOK_OPAQUE, "opaque"}, | |
390 | {TOK_BOOL, "bool"}, | |
391 | {TOK_VOID, "void"}, | |
392 | {TOK_PROGRAM, "program"}, | |
393 | {TOK_VERSION, "version"}, | |
394 | {TOK_EOF, "??????"} | |
28f540f4 RM |
395 | }; |
396 | ||
0d204b0a | 397 | static const char * |
e7fd8a39 | 398 | toktostr (tok_kind kind) |
28f540f4 | 399 | { |
b13927da | 400 | const token *sp; |
28f540f4 | 401 | |
e7fd8a39 | 402 | for (sp = tokstrings; sp->kind != TOK_EOF && sp->kind != kind; sp++); |
b13927da | 403 | return sp->str; |
28f540f4 RM |
404 | } |
405 | ||
0d204b0a | 406 | static void |
e7fd8a39 | 407 | printbuf (void) |
28f540f4 | 408 | { |
e7fd8a39 UD |
409 | char c; |
410 | int i; | |
411 | int cnt; | |
412 | ||
413 | #define TABSIZE 4 | |
414 | ||
415 | for (i = 0; (c = curline[i]) != 0; i++) | |
416 | { | |
417 | if (c == '\t') | |
418 | { | |
419 | cnt = 8 - (i % TABSIZE); | |
420 | c = ' '; | |
421 | } | |
422 | else | |
423 | { | |
424 | cnt = 1; | |
28f540f4 | 425 | } |
e7fd8a39 UD |
426 | while (cnt--) |
427 | { | |
428 | (void) fputc (c, stderr); | |
429 | } | |
430 | } | |
28f540f4 RM |
431 | } |
432 | ||
0d204b0a | 433 | static void |
e7fd8a39 | 434 | printwhere (void) |
28f540f4 | 435 | { |
e7fd8a39 UD |
436 | int i; |
437 | char c; | |
438 | int cnt; | |
439 | ||
440 | printbuf (); | |
441 | for (i = 0; i < where - curline; i++) | |
442 | { | |
443 | c = curline[i]; | |
444 | if (c == '\t') | |
445 | { | |
446 | cnt = 8 - (i % TABSIZE); | |
447 | } | |
448 | else | |
449 | { | |
450 | cnt = 1; | |
451 | } | |
452 | while (cnt--) | |
453 | { | |
454 | (void) fputc ('^', stderr); | |
28f540f4 | 455 | } |
e7fd8a39 UD |
456 | } |
457 | (void) fputc ('\n', stderr); | |
28f540f4 | 458 | } |
0d204b0a | 459 | |
e7fd8a39 UD |
460 | char * |
461 | make_argname (const char *pname, const char *vname) | |
0d204b0a | 462 | { |
e7fd8a39 UD |
463 | char *name; |
464 | ||
465 | name = malloc (strlen (pname) + strlen (vname) + strlen (ARGEXT) + 3); | |
466 | if (!name) | |
467 | { | |
468 | fprintf (stderr, "failed in malloc"); | |
469 | exit (1); | |
470 | } | |
471 | sprintf (name, "%s_%s_%s", locase (pname), vname, ARGEXT); | |
472 | return name; | |
0d204b0a UD |
473 | } |
474 | ||
475 | bas_type *typ_list_h; | |
476 | bas_type *typ_list_t; | |
477 | ||
478 | void | |
e7fd8a39 | 479 | add_type (int len, const char *type) |
0d204b0a UD |
480 | { |
481 | bas_type *ptr; | |
482 | ||
483 | ||
e7fd8a39 UD |
484 | if ((ptr = malloc (sizeof (bas_type))) == NULL) |
485 | { | |
486 | fprintf (stderr, "failed in malloc"); | |
487 | exit (1); | |
488 | } | |
0d204b0a | 489 | |
e7fd8a39 UD |
490 | ptr->name = type; |
491 | ptr->length = len; | |
492 | ptr->next = NULL; | |
493 | if (typ_list_t == NULL) | |
0d204b0a UD |
494 | { |
495 | ||
e7fd8a39 UD |
496 | typ_list_t = ptr; |
497 | typ_list_h = ptr; | |
0d204b0a UD |
498 | } |
499 | else | |
500 | { | |
501 | ||
e7fd8a39 UD |
502 | typ_list_t->next = ptr; |
503 | typ_list_t = ptr; | |
0d204b0a UD |
504 | } |
505 | ||
506 | } | |
507 | ||
508 | ||
e7fd8a39 UD |
509 | bas_type * |
510 | find_type (const char *type) | |
0d204b0a UD |
511 | { |
512 | bas_type *ptr; | |
513 | ||
e7fd8a39 | 514 | ptr = typ_list_h; |
0d204b0a UD |
515 | |
516 | ||
e7fd8a39 | 517 | while (ptr != NULL) |
0d204b0a | 518 | { |
e7fd8a39 UD |
519 | if (strcmp (ptr->name, type) == 0) |
520 | return ptr; | |
521 | else | |
522 | ptr = ptr->next; | |
0d204b0a | 523 | }; |
e7fd8a39 | 524 | return NULL; |
0d204b0a | 525 | } |