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