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