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