]> git.decadent.org.uk Git - nfs-utils.git/blob - tools/rpcgen/rpc_util.c
mount.nfs: Support double-wide characters in printed strings
[nfs-utils.git] / tools / 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 or with the express written consent of
8  * Sun Microsystems, Inc.
9  *
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.
13  *
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.
17  *
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.
21  *
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.
25  *
26  * Sun Microsystems, Inc.
27  * 2550 Garcia Avenue
28  * Mountain View, California  94043
29  */
30
31 #if 0
32 static char sccsid[] = "@(#)rpc_util.c 1.11 89/02/22 (C) 1987 SMI";
33 #endif
34
35 /*
36  * rpc_util.c, Utility routines for the RPC protocol compiler 
37  */
38 #include <stdio.h>
39 #include <memory.h>
40 #include <ctype.h>
41 #include <unistd.h>
42 #include "rpc_scan.h"
43 #include "rpc_parse.h"
44 #include "rpc_util.h"
45
46 static void     printwhere(void);
47
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 /*
67  * Reinitialize the world 
68  */
69 void
70 reinitialize(void)
71 {
72         memset(curline, 0, MAXLINESIZE);
73         where = curline;
74         linenum = 0;
75         defined = NULL;
76 }
77
78 /*
79  * string equality 
80  */
81 int
82 streq(char *a, char *b)
83 {
84         return (strcmp(a, b) == 0);
85 }
86
87 /*
88  * find a value in a list 
89  */
90 definition *
91 findval(list *lst, char *val, int (*cmp)(definition *, char *))
92 {
93          
94         for (; lst != NULL; lst = lst->next) {
95                 if ((*cmp) (lst->val, val)) {
96                         return (lst->val);
97                 }
98         }
99         return (NULL);
100 }
101
102 /*
103  * store a value in a list 
104  */
105 void
106 storeval(lstp, val)
107         list **lstp;
108         definition *val;
109 {
110         list **l;
111         list *lst;
112
113         
114         for (l = lstp; *l != NULL; l = (list **) & (*l)->next);
115         lst = ALLOC(list);
116         lst->val = val;
117         lst->next = NULL;
118         *l = lst;
119 }
120
121 static int
122 findit(definition *def, char *type)
123 {
124         return (streq(def->def_name, type));
125 }
126
127 static char *
128 fixit(char *type, 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                 return (def->def.ty.old_type);
139         case REL_ALIAS:
140                 return (fixit(def->def.ty.old_type, orig));
141         default:
142                 return (orig);
143         }
144 }
145
146 char *
147 fixtype(char *type)
148 {
149         return (fixit(type, type));
150 }
151
152 char *
153 stringfix(char *type)
154 {
155         if (streq(type, "string")) {
156                 return ("wrapstring");
157         } else {
158                 return (type);
159         }
160 }
161
162 void
163 ptype(char *prefix, char *type, int follow)
164 {
165         if (prefix != NULL) {
166                 if (streq(prefix, "enum")) {
167                         f_print(fout, "enum ");
168                 } else {
169                         f_print(fout, "struct ");
170                 }
171         }
172         if (streq(type, "bool")) {
173                 f_print(fout, "bool_t ");
174         } else if (streq(type, "string")) {
175                 f_print(fout, "char *");
176         } else {
177                 f_print(fout, "%s ", follow ? fixtype(type) : type);
178         }
179 }
180
181 static int
182 typedefed(definition *def, char *type)
183 {
184         if (def->def_kind != DEF_TYPEDEF || def->def.ty.old_prefix != NULL) {
185                 return (0);
186         } else {
187                 return (streq(def->def_name, type));
188         }
189 }
190
191 int
192 isvectordef(char *type, relation rel)
193 {
194         definition *def;
195
196         for (;;) {
197                 switch (rel) {
198                 case REL_VECTOR:
199                         return (!streq(type, "string"));
200                 case REL_ARRAY:
201                         return (0);
202                 case REL_POINTER:
203                         return (0);
204                 case REL_ALIAS:
205                         def = (definition *) FINDVAL(defined, type, typedefed);
206                         if (def == NULL) {
207                                 return (0);
208                         }
209                         type = def->def.ty.old_type;
210                         rel = def->def.ty.rel;
211                 }
212         }
213 }
214
215 char *
216 locase(char *str)
217 {
218         char c;
219         static char buf[100];
220         char *p = buf;
221
222         while ((c = *str++) != '\0') {
223                 *p++ = (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c;
224         }
225         *p = 0;
226         return (buf);
227 }
228
229 void
230 pvname_svc(char *pname, char *vnum)
231 {
232         f_print(fout, "%s_%s_svc", locase(pname), vnum);
233 }
234
235 void
236 pvname(char *pname, char *vnum)
237 {
238         f_print(fout, "%s_%s", locase(pname), vnum);
239 }
240
241 /*
242  * print a useful (?) error message, and then die 
243  */
244 void
245 error(char *msg)
246 {
247         printwhere();
248         f_print(stderr, "%s, line %d: ", infilename, linenum);
249         f_print(stderr, "%s\n", msg);
250         crash();
251 }
252
253 /*
254  * Something went wrong, unlink any files that we may have created and then
255  * die. 
256  */
257 void
258 crash(void)
259 {
260         int i;
261
262         for (i = 0; i < nfiles; i++) {
263                 (void) unlink(outfiles[i]);
264         }
265         exit(1);
266 }
267
268 void
269 record_open(char *file)
270 {
271         if (nfiles < NFILES) {
272                 outfiles[nfiles++] = file;
273         } else {
274                 f_print(stderr, "too many files!\n");
275                 crash();
276         }
277 }
278
279 static char expectbuf[100];
280 static char *toktostr();
281
282 /*
283  * error, token encountered was not the expected one 
284  */
285 void
286 expected1(exp1)
287         tok_kind exp1;
288 {
289         s_print(expectbuf, "expected '%s'",
290                 toktostr(exp1));
291         error(expectbuf);
292 }
293
294 /*
295  * error, token encountered was not one of two expected ones 
296  */
297 void
298 expected2(exp1, exp2)
299         tok_kind exp1, exp2;
300 {
301         s_print(expectbuf, "expected '%s' or '%s'",
302                 toktostr(exp1),
303                 toktostr(exp2));
304         error(expectbuf);
305 }
306
307 /*
308  * error, token encountered was not one of 3 expected ones 
309  */
310 void
311 expected3(exp1, exp2, exp3)
312         tok_kind exp1, exp2, exp3;
313 {
314         s_print(expectbuf, "expected '%s', '%s' or '%s'",
315                 toktostr(exp1),
316                 toktostr(exp2),
317                 toktostr(exp3));
318         error(expectbuf);
319 }
320
321 void
322 tabify(f, tab)
323         FILE *f;
324         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_INT32, "int32"},
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 char *
370 toktostr(kind)
371         tok_kind kind;
372 {
373         token *sp;
374
375         for (sp = tokstrings; sp->kind != TOK_EOF && sp->kind != kind; sp++);
376         return (sp->str);
377 }
378
379 static void
380 printbuf(void)
381 {
382         char c;
383         int i;
384         int cnt;
385
386 #       define TABSIZE 4
387
388         for (i = 0; (c = curline[i]) != '\0'; i++) {
389                 if (c == '\t') {
390                         cnt = 8 - (i % TABSIZE);
391                         c = ' ';
392                 } else {
393                         cnt = 1;
394                 }
395                 while (cnt--) {
396                         (void) fputc(c, stderr);
397                 }
398         }
399 }
400
401 static void
402 printwhere(void)
403 {
404         int i;
405         char c;
406         int cnt;
407
408         printbuf();
409         for (i = 0; i < where - curline; i++) {
410                 c = curline[i];
411                 if (c == '\t') {
412                         cnt = 8 - (i % TABSIZE);
413                 } else {
414                         cnt = 1;
415                 }
416                 while (cnt--) {
417                         (void) fputc('^', stderr);
418                 }
419         }
420         (void) fputc('\n', stderr);
421 }
422
423 char * 
424 make_argname(char *pname, char *vname) 
425 {
426         char *name;
427         
428         name = malloc(strlen(pname) + strlen(vname) + strlen(ARGEXT) + 3);
429         if (!name) {
430                 fprintf(stderr, "failed in malloc");
431                 exit(1);
432         }
433         sprintf(name, "%s_%s_%s", locase(pname), vname, ARGEXT);
434         return(name);
435 }
436
437 bas_type *typ_list_h;
438 bas_type *typ_list_t;
439
440 void
441 add_type(int len, char *type)
442 {
443         bas_type       *ptr;
444
445
446         if ((ptr = (bas_type *) malloc(sizeof(bas_type))) == (bas_type *) NULL) {
447                 fprintf(stderr, "failed in malloc");
448                 exit(1);
449         }
450         ptr->name = type;
451         ptr->length = len;
452         ptr->next = NULL;
453         if (typ_list_t == NULL) {
454
455                 typ_list_t = ptr;
456                 typ_list_h = ptr;
457         } else {
458
459                 typ_list_t->next = ptr;
460                 typ_list_t = ptr;
461         }
462 }
463
464
465 bas_type *
466 find_type(char *type)
467 {
468         bas_type       *ptr;
469
470         ptr = typ_list_h;
471
472
473         while (ptr != NULL) {
474                 if (strcmp(ptr->name, type) == 0)
475                         return (ptr);
476                 else
477                         ptr = ptr->next;
478         };
479         return (NULL);
480 }
481