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