Subversion Repositories DevTools

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
227 dpurdie 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
#ifndef lint
32
static char sccsid[] = "@(#)rpc_cout.c 1.13 89/02/22 (C) 1987 SMI";
33
#endif
34
 
35
/*
36
 * rpc_cout.c, XDR routine outputter for the RPC protocol compiler 
37
 */
38
#include <stdio.h>
39
#include <string.h>
40
#include "rpc_parse.h"
41
#include "rpc_util.h"
42
 
43
/*
44
 * Emit the C-routine for the given definition 
45
 */
46
void
47
emit(def)
48
	definition *def;
49
{
50
	if (def->def_kind == DEF_CONST) {
51
		return;
52
	}
53
	if (def->def_kind == DEF_PROGRAM) {
54
		emit_program(def);
55
		return;
56
	}
57
	if(def->def_kind == DEF_TYPEDEF)
58
	  {
59
	  /* now we need to handle declarations like 
60
   struct typedef foo foo; 
61
   since we dont want this to be expanded into 2 calls to xdr_foo */
62
 
63
 	if(strcmp(def->def.ty.old_type,def->def_name)==0)
64
	  return;
65
      };
66
 
67
	print_header(def);
68
	switch (def->def_kind) {
69
	case DEF_UNION:
70
		emit_union(def);
71
		break;
72
	case DEF_ENUM:
73
		emit_enum(def);
74
		break;
75
	case DEF_STRUCT:
76
		emit_struct(def);
77
		break;
78
	case DEF_TYPEDEF:
79
		emit_typedef(def);
80
		break;
81
	}
82
	print_trailer();
83
}
84
 
85
static
86
findtype(def, type)
87
	definition *def;
88
	char *type;
89
{
90
 
91
	if (def->def_kind == DEF_PROGRAM || def->def_kind == DEF_CONST) {
92
		return (0);
93
	} else {
94
		return (streq(def->def_name, type));
95
	}
96
}
97
 
98
static
99
undefined(type)
100
	char *type;
101
{
102
	definition *def;
103
 
104
	def = (definition *) FINDVAL(defined, type, findtype);
105
 
106
 
107
	return (def == NULL);
108
}
109
 
110
 
111
static
112
print_generic_header(procname, pointerp )
113
     char* procname;
114
     int pointerp;
115
{
116
	f_print(fout, "\n");
117
	f_print(fout, "bool_t\n");
118
	if (Cflag) {
119
	   f_print(fout, "xdr_%s(", procname);
120
	   f_print(fout, "XDR *xdrs, ");
121
	   f_print(fout, "%s ", procname);
122
	   if( pointerp )
123
	     f_print(fout, "*");
124
	   f_print(fout, "objp)\n{\n\n");
125
	} else {
126
	  f_print(fout, "xdr_%s(xdrs, objp)\n", procname);
127
	  f_print(fout, "\tXDR *xdrs;\n");
128
	  f_print(fout, "\t%s ", procname);
129
	  if( pointerp )
130
	    f_print(fout, "*");
131
	  f_print(fout, "objp;\n{\n\n");
132
	}
133
}
134
 
135
static
136
print_header(def)
137
	definition *def;
138
{
139
 
140
  decl_list *dl;
141
  bas_type *ptr;
142
  int i;
143
 
144
 
145
  print_generic_header( def->def_name,
146
		       def->def_kind != DEF_TYPEDEF ||
147
		       !isvectordef(def->def.ty.old_type, def->def.ty.rel));
148
 
149
  /* Now add Inline support */
150
 
151
 
152
  if(inline == 0 )
153
    return;
154
  /*May cause lint to complain. but  ... */
155
f_print(fout, "\t register long *buf;\n\n");
156
 
157
}
158
 
159
static
160
print_prog_header(plist)
161
	proc_list *plist;
162
{
163
  print_generic_header( plist->args.argname, 1 );
164
}
165
 
166
static
167
print_trailer()
168
{
169
	f_print(fout, "\treturn (TRUE);\n");
170
	f_print(fout, "}\n");
171
}
172
 
173
 
174
static
175
print_ifopen(indent, name)
176
	int indent;
177
	char *name;
178
{
179
	tabify(fout, indent);
180
	f_print(fout, " if (!xdr_%s(xdrs", name);
181
}
182
 
183
static
184
print_ifarg(arg)
185
	char *arg;
186
{
187
	f_print(fout, ", %s", arg);
188
}
189
 
190
static
191
print_ifsizeof(prefix, type)
192
	char *prefix;
193
	char *type;
194
{
195
	if (streq(type, "bool")) {
196
		f_print(fout, ", sizeof(bool_t), (xdrproc_t)xdr_bool");
197
	} else {
198
		f_print(fout, ", sizeof(");
199
		if (undefined(type) && prefix) {
200
			f_print(fout, "%s ", prefix);
201
		}
202
		f_print(fout, "%s), (xdrproc_t)xdr_%s", type, type);
203
	}
204
}
205
 
206
static
207
print_ifclose(indent)
208
	int indent;
209
{
210
	f_print(fout, ")) {\n");
211
	tabify(fout, indent);
212
	f_print(fout, "\t return (FALSE);\n");
213
	tabify(fout, indent);
214
	f_print(fout, " }\n");
215
}
216
 
217
static
218
print_ifstat(indent, prefix, type, rel, amax, objname, name)
219
	int indent;
220
	char *prefix;
221
	char *type;
222
	relation rel;
223
	char *amax;
224
	char *objname;
225
	char *name;
226
{
227
	char *alt = NULL;
228
 
229
	switch (rel) {
230
	case REL_POINTER:
231
		print_ifopen(indent, "pointer");
232
		print_ifarg("(char **)");
233
		f_print(fout, "%s", objname);
234
		print_ifsizeof(prefix, type);
235
		break;
236
	case REL_VECTOR:
237
		if (streq(type, "string")) {
238
			alt = "string";
239
		} else if (streq(type, "opaque")) {
240
			alt = "opaque";
241
		}
242
		if (alt) {
243
			print_ifopen(indent, alt);
244
			print_ifarg(objname);
245
		} else {
246
			print_ifopen(indent, "vector");
247
			print_ifarg("(char *)");
248
			f_print(fout, "%s", objname);
249
		}
250
		print_ifarg(amax);
251
		if (!alt) {
252
			print_ifsizeof(prefix, type);
253
		}
254
		break;
255
	case REL_ARRAY:
256
		if (streq(type, "string")) {
257
			alt = "string";
258
		} else if (streq(type, "opaque")) {
259
			alt = "bytes";
260
		}
261
		if (streq(type, "string")) {
262
			print_ifopen(indent, alt);
263
			print_ifarg(objname);
264
		} else {
265
			if (alt) {
266
				print_ifopen(indent, alt);
267
			} else {
268
				print_ifopen(indent, "array");
269
			}
270
			print_ifarg("(char **)");
271
			if (*objname == '&') {
272
				f_print(fout, "%s.%s_val, (u_int *)%s.%s_len",
273
					objname, name, objname, name);
274
			} else {
275
				f_print(fout, "&%s->%s_val, (u_int *)&%s->%s_len",
276
					objname, name, objname, name);
277
			}
278
		}
279
		print_ifarg(amax);
280
		if (!alt) {
281
			print_ifsizeof(prefix, type);
282
		}
283
		break;
284
	case REL_ALIAS:
285
		print_ifopen(indent, type);
286
		print_ifarg(objname);
287
		break;
288
	}
289
	print_ifclose(indent);
290
}
291
 
292
/* ARGSUSED */
293
static
294
emit_enum(def)
295
	definition *def;
296
{
297
	print_ifopen(1, "enum");
298
	print_ifarg("(enum_t *)objp");
299
	print_ifclose(1);
300
}
301
 
302
static
303
emit_program(def)
304
	definition *def;
305
{
306
	decl_list *dl;
307
	version_list *vlist;
308
	proc_list *plist;
309
 
310
	for (vlist = def->def.pr.versions; vlist != NULL;vlist = vlist->next) 
311
	  for(plist = vlist->procs; plist != NULL; plist = plist->next) {
312
		  if (!newstyle || plist->arg_num < 2) 
313
		    continue; /* old style, or single argument */
314
		  print_prog_header(plist);
315
		  for (dl = plist->args.decls; dl != NULL; 
316
		       dl = dl->next) 
317
			  print_stat(1,&dl->decl);
318
		  print_trailer();
319
	  }
320
}
321
 
322
 
323
static
324
emit_union(def)
325
	definition *def;
326
{
327
  declaration *dflt;
328
  case_list *cl;
329
  declaration *cs;
330
  char *object;
331
  char *vecformat = "objp->%s_u.%s";
332
  char *format = "&objp->%s_u.%s";
333
 
334
  print_stat(1,&def->def.un.enum_decl);
335
  f_print(fout, "\tswitch (objp->%s) {\n", def->def.un.enum_decl.name);
336
  for (cl = def->def.un.cases; cl != NULL; cl = cl->next) {
337
 
338
    f_print(fout, "\tcase %s:\n", cl->case_name);
339
    if(cl->contflag == 1)	/* a continued case statement */
340
      continue;
341
    cs = &cl->case_decl;
342
    if (!streq(cs->type, "void")) {
343
      object = alloc(strlen(def->def_name) + strlen(format) +
344
		     strlen(cs->name) + 1);
345
      if (isvectordef (cs->type, cs->rel)) {
346
	s_print(object, vecformat, def->def_name, 
347
		cs->name);
348
      } else {
349
	s_print(object, format, def->def_name, 
350
		cs->name);
351
      }
352
      print_ifstat(2, cs->prefix, cs->type, cs->rel, cs->array_max,
353
		   object, cs->name);
354
      free(object);
355
    }
356
    f_print(fout, "\t\tbreak;\n");
357
  }
358
  dflt = def->def.un.default_decl;
359
  if (dflt != NULL) {
360
    if (!streq(dflt->type, "void")) {
361
      f_print(fout, "\tdefault:\n");
362
      object = alloc(strlen(def->def_name) + strlen(format) +
363
		     strlen(dflt->name) + 1);
364
      if (isvectordef (dflt->type, dflt->rel)) {
365
	s_print(object, vecformat, def->def_name, 
366
		dflt->name);
367
      } else {
368
	s_print(object, format, def->def_name, 
369
		dflt->name);
370
      }
371
 
372
      print_ifstat(2, dflt->prefix, dflt->type, dflt->rel,
373
		   dflt->array_max, object, dflt->name);
374
      free(object);
375
      f_print(fout, "\t\tbreak;\n");
376
    }
377
  } else {
378
    f_print(fout, "\tdefault:\n");
379
    f_print(fout, "\t\treturn (FALSE);\n");
380
  }
381
 
382
  f_print(fout, "\t}\n");
383
}
384
 
385
static
386
emit_struct(def)
387
	definition *def;
388
{
389
	decl_list *dl;
390
	int i,j,size,flag;
391
	decl_list *cur,*psav;
392
	bas_type *ptr;
393
	char *sizestr,*plus;
394
	char ptemp[256];
395
	int can_inline;
396
 
397
 
398
	if(inline  == 0)	{
399
		for (dl = def->def.st.decls; dl != NULL; dl = dl->next) 
400
			print_stat(1,&dl->decl);
401
	}
402
 
403
	else	{
404
 
405
		for (dl = def->def.st.decls; dl != NULL; dl = dl->next) 
406
			if(dl->decl.rel == REL_VECTOR){
407
				f_print(fout,"\t int i;\n");
408
				break;
409
			}
410
 
411
		size=0;can_inline=0;
412
		for (dl = def->def.st.decls; dl != NULL; dl = dl->next) 
413
			if((dl->decl.prefix == NULL) && ((ptr=find_type(dl->decl.type))!= NULL) && 		 ((dl->decl.rel == REL_ALIAS)||(dl->decl.rel == REL_VECTOR))){
414
 
415
				if(dl->decl.rel == REL_ALIAS) 
416
					size+=ptr->length;
417
				else {
418
					can_inline=1;
419
					break; /* can be inlined */
420
				};
421
			}
422
			else {
423
				if(size >= inline){
424
					can_inline=1;
425
					break; /* can be inlined */
426
				}
427
				size=0;
428
			}
429
		if(size > inline)
430
			can_inline=1;
431
 
432
		if(can_inline == 0){ /* can not inline, drop back to old mode */
433
			for (dl = def->def.st.decls; dl != NULL; dl = dl->next) 
434
				print_stat(1,&dl->decl);
435
			return;
436
		};
437
 
438
 
439
 
440
 
441
		flag=PUT;
442
		for(j=0; j<2; j++){
443
 
444
			if(flag == PUT)
445
				f_print(fout,"\n\t if (xdrs->x_op == XDR_ENCODE) {\n");
446
			else
447
				f_print(fout,"\n \t return (TRUE);\n\t} else if (xdrs->x_op == XDR_DECODE) {\n");
448
 
449
 
450
			i=0;
451
			size=0;
452
			sizestr=NULL;
453
			for (dl = def->def.st.decls; dl != NULL; dl = dl->next) { /* xxx */
454
 
455
				/* now walk down the list and check for basic types */
456
				if((dl->decl.prefix == NULL) && ((ptr=find_type(dl->decl.type))!= NULL) && 		 ((dl->decl.rel == REL_ALIAS)||(dl->decl.rel == REL_VECTOR))){
457
					if(i ==0 ) 
458
						cur=dl;
459
					i++;
460
 
461
					if(dl->decl.rel == REL_ALIAS) 
462
						size+=ptr->length;
463
					else {
464
						/* this is required to handle arrays */
465
 
466
						if(sizestr == NULL)
467
							plus = " ";
468
						else
469
							plus = "+";
470
 
471
						if(ptr->length != 1)
472
							s_print(ptemp," %s %s * %d",plus,dl->decl.array_max,ptr->length);
473
						else
474
							s_print(ptemp," %s %s ",plus,dl->decl.array_max);
475
 
476
						/*now concatenate to sizestr !!!! */
477
						if (sizestr == NULL)
478
							sizestr=strdup(ptemp);
479
						else{
480
							sizestr=realloc(sizestr,strlen(sizestr)+strlen(ptemp)+1);
481
							if(sizestr == NULL){
482
 
483
								f_print(stderr, "Fatal error : no memory \n");
484
								crash();
485
							};
486
							sizestr=strcat(sizestr,ptemp); /*build up length of array */
487
 
488
						}
489
					}
490
 
491
				}
492
				else{
493
					if(i > 0 )
494
						if(sizestr == NULL && size < inline){	
495
							/* don't expand into inline code if size < inline */
496
							while(cur != dl){
497
								print_stat(1,&cur->decl);
498
								cur=cur->next;
499
							} 
500
						}
501
						else{
502
 
503
 
504
 
505
							/* were already looking at a xdr_inlineable structure */
506
							if(sizestr == NULL)
507
								f_print(fout,"\t buf = XDR_INLINE(xdrs,%d * BYTES_PER_XDR_UNIT);",
508
									size);
509
							else
510
								if(size == 0)
511
									f_print(fout,
512
										"\t buf = XDR_INLINE(xdrs,%s * BYTES_PER_XDR_UNIT);",
513
										sizestr);
514
								else
515
									f_print(fout,
516
										"\t buf = XDR_INLINE(xdrs,(%d + %s)* BYTES_PER_XDR_UNIT);",
517
										size,sizestr);
518
 
519
							f_print(fout,"\n\t   if (buf == NULL) {\n");
520
 
521
							psav=cur;
522
							while(cur != dl){
523
								print_stat(2,&cur->decl);
524
								cur=cur->next;
525
							}
526
 
527
							f_print(fout,"\n\t  }\n\t  else {\n");
528
 
529
							cur=psav;
530
							while(cur != dl){
531
								emit_inline(&cur->decl,flag);
532
								cur=cur->next;
533
							}
534
 
535
							f_print(fout,"\t  }\n");
536
						}
537
					size=0;i=0;sizestr=NULL;
538
					print_stat(1,&dl->decl);
539
				}
540
 
541
			}
542
			if(i > 0 )
543
				if(sizestr == NULL && size < inline){
544
					/* don't expand into inline code if size < inline */
545
					while(cur != dl){
546
						print_stat(1,&cur->decl);
547
						cur=cur->next;
548
					} 
549
				}
550
				else{
551
 
552
					/* were already looking at a xdr_inlineable structure */
553
					if(sizestr == NULL)
554
						f_print(fout,"\t\tbuf = XDR_INLINE(xdrs,%d * BYTES_PER_XDR_UNIT);",
555
							size);
556
					else
557
						if(size == 0)
558
							f_print(fout,
559
								"\t\tbuf = XDR_INLINE(xdrs,%s * BYTES_PER_XDR_UNIT);",
560
								sizestr);
561
						else
562
							f_print(fout,
563
								"\t\tbuf = XDR_INLINE(xdrs,(%d + %s)* BYTES_PER_XDR_UNIT);",
564
								size,sizestr);
565
 
566
					f_print(fout,"\n\t\tif (buf == NULL) {\n");
567
 
568
					psav=cur;
569
					while(cur != NULL){
570
						print_stat(2,&cur->decl);
571
						cur=cur->next;
572
					}
573
					f_print(fout,"\n\t  }\n\t  else {\n");
574
 
575
					cur=psav;
576
					while(cur != dl){
577
						emit_inline(&cur->decl,flag);
578
						cur=cur->next;
579
					}
580
 
581
					f_print(fout,"\t  }\n");
582
 
583
				}
584
			flag=GET;
585
		}
586
		f_print(fout,"\t return(TRUE);\n\t}\n\n");
587
 
588
		/* now take care of XDR_FREE case */
589
 
590
		for (dl = def->def.st.decls; dl != NULL; dl = dl->next) 
591
			print_stat(1,&dl->decl);
592
	}	
593
}
594
 
595
 
596
 
597
 
598
static
599
emit_typedef(def)
600
	definition *def;
601
{
602
	char *prefix = def->def.ty.old_prefix;
603
	char *type = def->def.ty.old_type;
604
	char *amax = def->def.ty.array_max;
605
	relation rel = def->def.ty.rel;
606
 
607
 
608
	  print_ifstat(1, prefix, type, rel, amax, "objp", def->def_name);
609
}
610
 
611
static
612
print_stat(indent,dec)
613
	declaration *dec;
614
     int indent;
615
{
616
	char *prefix = dec->prefix;
617
	char *type = dec->type;
618
	char *amax = dec->array_max;
619
	relation rel = dec->rel;
620
	char name[256];
621
 
622
	if (isvectordef(type, rel)) {
623
		s_print(name, "objp->%s", dec->name);
624
	} else {
625
		s_print(name, "&objp->%s", dec->name);
626
	}
627
	print_ifstat(indent, prefix, type, rel, amax, name, dec->name);
628
}
629
 
630
 
631
char *upcase ();
632
 
633
 
634
emit_inline(decl,flag)
635
declaration *decl;
636
int flag;
637
{
638
 
639
/*check whether an array or not */
640
 
641
switch(decl->rel)
642
  {
643
 case  REL_ALIAS :
644
  emit_single_in_line(decl,flag,REL_ALIAS);
645
  break;
646
 case REL_VECTOR :
647
   f_print(fout,"\t\t{ register %s *genp; \n",decl->type);
648
   f_print(fout,"\t\t  for ( i = 0,genp=objp->%s;\n \t\t\ti < %s; i++){\n\t\t",
649
	   decl->name,decl->array_max);
650
  emit_single_in_line(decl,flag,REL_VECTOR);
651
    f_print(fout,"\t\t   }\n\t\t };\n");
652
 
653
  }
654
}
655
 
656
emit_single_in_line(decl,flag,rel)
657
declaration *decl;
658
int flag;
659
relation rel;
660
{
661
	char *upp_case;
662
	int freed=0;
663
 
664
 
665
 
666
	if(flag == PUT)
667
		f_print(fout,"\t\t IXDR_PUT_");
668
	else    
669
		if(rel== REL_ALIAS)
670
			f_print(fout,"\t\t objp->%s = IXDR_GET_",decl->name);
671
		else
672
			f_print(fout,"\t\t *genp++ = IXDR_GET_");
673
 
674
	upp_case=upcase(decl->type);
675
 
676
	/* hack  - XX */
677
	if(strcmp(upp_case,"INT") == 0)
678
	{
679
		free(upp_case);
680
		freed=1;
681
		upp_case="LONG";
682
	}
683
 
684
	if(strcmp(upp_case,"U_INT") == 0)
685
	{
686
		free(upp_case);
687
		freed=1;
688
		upp_case="U_LONG";
689
	}
690
 
691
 
692
	if(flag == PUT) 
693
		if(rel== REL_ALIAS)
694
			f_print(fout,"%s(buf,objp->%s);\n",upp_case,decl->name);
695
		else
696
			f_print(fout,"%s(buf,*genp++);\n",upp_case);
697
 
698
	else
699
		f_print(fout,"%s(buf);\n",upp_case);
700
	if(!freed)
701
		free(upp_case);
702
 
703
}
704
 
705
 
706
char * upcase(str)
707
char *str;
708
{
709
char *ptr,*hptr;
710
 
711
 
712
ptr =  (char * )malloc(strlen(str));
713
if(ptr == (char * ) NULL)
714
  {
715
    f_print(stderr,"malloc failed \n");
716
    exit(1);
717
  };
718
 
719
hptr=ptr;
720
while (*str != '\0')
721
    *ptr++=toupper(*str++);
722
 
723
*ptr='\0';
724
return(hptr);
725
 
726
}