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