2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
11 * generator.c -- phase 2 of the generator.
13 * takes a file, which has a list of signature as input,
14 * and outputs the client, server, .xg, and makefiles
15 * This file is normally created by running tableGen.c,
16 * but theoretically could be generated by a human.
18 * Format of the signatures : no_of_args list_of_arg_signs
19 * arg_sign : (dir type)
22 * This program is used to generate client/server pairs that
23 * make and verify random rpcs. It can be used to generate
24 * both pthread and lwp versions of the client and server.
25 * It was designed to verify that the new pthread rx library
26 * was functioning correctly.
28 * The key to understanding how this program works is to realize
29 * that all the data necessary to generate the client/server
30 * code is generated first, in char string format.
31 * For example, if you are generating 10 rpc's, the input and
32 * output values of all the parameters are generated - and
33 * stored as strings. This allows you to write out the values
34 * as the client and server are created without having to worry
35 * about data type conversion.
37 * In addition, these strings (along with other information) are
38 * stored in a structure that is iterated over many times during
39 * the construction of the client and server.
41 * Often this iteration takes the form of:
42 * for (i=0; i < argsP->argCount; i++)
44 * It may be possible to eliminate some of these iterations for
45 * efficiency sake, but this was not done - allowing an easier
48 * The bulk of this code was lifted from the delight project.
52 #include <afsconfig.h>
53 #include <afs/param.h>
64 #include "generator.h"
66 static char *unix_symbols[] = {
68 "include ../../../config/Makefile.$(SYS_NAME)\n",
71 "#include <netdb.h>\n",
75 "LIBS = $(DESTDIR)lib/libafsrpc.so \\\n"
76 "\t$(DESTDIR)lib/afs/libcmd.a \\\n"
77 "\t$(DESTDIR)lib/afs/libcom_err.a \\\n"
78 "\t$(DESTDIR)lib/afs/util.a \n",
81 "LIBS = $(DESTDIR)lib/librxkad.a \\\n"
82 "\t$(DESTDIR)lib/libdes.a \\\n"
83 "\t$(DESTDIR)lib/librx.a \\\n"
84 "\t$(DESTDIR)lib/liblwp.a \\\n"
85 "\t$(DESTDIR)lib/afs/libcmd.a \\\n"
86 "\t$(DESTDIR)lib/afs/libcom_err.a \\\n"
87 "\t$(DESTDIR)lib/afs/util.a \\\n"
88 "\t/usr/ucblib/libucb.a \n",
91 "\t@if [ ! -r DEST ] ; \\\n"
93 "\t\techo \"Must create DEST link by hand before building tests\"; \\\n"
98 static char *nt_symbols[] = {
100 "!INCLUDE ../../../config/NTMakefile.$(SYS_NAME)\n",
103 "#include <windows.h>\n",
107 "LIBS = $(DESTDIR)/lib/afsrpc.lib \\\n"
108 "\t$(DESTDIR)/lib/afs/afscmd.lib \\\n"
109 "\t$(DESTDIR)/lib/afs/afscom_err.lib \\\n"
110 "\t$(DESTDIR)/lib/afs/afsutil.lib \\\n"
111 "\t$(DESTDIR)/lib/pthread.lib \\\n"
112 "\t$(DESTDIR)/lib/afsreg.lib \\\n"
116 "LIBS = $(DESTDIR)/lib/afsrxkad.lib \\\n"
117 "\t$(DESTDIR)/lib/afsdes.lib \\\n"
118 "\t$(DESTDIR)/lib/afsrx.lib \\\n"
119 "\t$(DESTDIR)/lib/afslwp.lib \\\n"
120 "\t$(DESTDIR)/lib/afs/afscmd.lib \\\n"
121 "\t$(DESTDIR)/lib/afs/afscom_err.lib \\\n"
122 "\t$(DESTDIR)/lib/afs/afsutil.lib \\\n"
123 "\t$(DESTDIR)/lib/afsreg.lib \n",
126 "!\tIF (!EXIST(DEST))\n"
127 "!\t\tERROR Must create DEST link by hand before building tests\n"
131 static char **platform = nt_symbols;
134 #define strdup(x) _strdup(x)
138 * 31 bit random number generator, we don't really care how random
139 * these numbers are, it is more important that identical rx files
140 * are generated no matter what platform the generator runs on
142 static unsigned long randVal = 0x330E16;
149 static threadModel_t threadModel = PTHREADS;
151 PRIVATE double drand32(void)
153 randVal = ((randVal * 0xEECE66D) + 0xB) & 0xFFFFFFFF;
154 return ((double)(randVal) / 4294967296.0);
158 * GetDescription writes a one line comment describing the parameters
159 * used in an rpc in the client program
161 PRIVATE char *GetDescription(rpcArgs *argsP)
166 bufP2 = (char *) calloc((MAX_TYP_STR+MAX_DIR_STR+ATTRIB_LEN*ATTRIB_NO)
167 *argsP->argCount+3, sizeof(char));
168 MEM_CHK(bufP2, "GetDescription: out of mem bufP2\n");
170 for (i=0; i < argsP->argCount; i++) {
171 strcat(bufP2, argsP->argDescr[i].direction);
172 strcat(bufP2, argsP->argDescr[i].type);
178 * GetName -- get the name of the current server/instance
180 PRIVATE char *GetName(char *serverName, int sign_no)
182 /* itl file name 8.3 format*/
185 bufP = (char *) malloc(32 * sizeof(char));
186 MEM_CHK(bufP, "GetName: bufP out of mem\n");
188 sprintf(bufP, "%s%d", serverName, sign_no);
193 * OpenOutFile -- open a file in the output directory
195 PRIVATE FILE *OpenOutFile(char *outDir, char *fileName, char *tailStr)
201 bufP = (char *) malloc(sizeof(char)*(strlen(fileName)+
202 strlen(tailStr)+strlen(outDir)+2));
203 MEM_CHK(bufP, "OpenOutFile : Out of mem -- bufP\n");
204 sprintf(bufP, "%s/%s%s", outDir, fileName, tailStr);
206 bufP = (char *) malloc(sizeof(char)*(strlen(fileName)+
208 MEM_CHK(bufP, "OpenOutFile : Out of mem -- bufP\n");
209 sprintf(bufP, "%s%s", fileName, tailStr);
211 fP = fopen(bufP, "w");
212 MEM_CHK(fP, "main: Unable to open output file\n");
218 * WriteXGDecl -- write the declaration for a parameter
220 PRIVATE void WriteXGDecl(arg_tuple *arg, FILE *xg_h, int i,
221 int structFlag, int lastFlag)
224 if (!strcmp(arg->type, "varString")) {
225 fprintf(xg_h, "\tchar a%d[STR_MAX];\n", i);
228 fprintf(xg_h, "\tdrpc_%s_t a%d;\n", arg->type, i);
231 if (!strncmp(arg->type, "ar_", 2)) {
232 fprintf(xg_h, "\t%s drpc_out_%s_t *a%d",
233 arg->direction, arg->type, i);
235 else if (!strcmp(arg->type, "varString")) {
236 fprintf(xg_h, "\t%s string a%d<STR_MAX>",
239 else if (!strcmp(arg->direction, "IN")) {
240 fprintf(xg_h, "\t%s drpc_%s_t a%d",
241 arg->direction, arg->type, i);
243 fprintf(xg_h, "\t%s drpc_%s_t *a%d",
244 arg->direction, arg->type, i);
255 * WriteXG -- write the body of the xg interface
257 PRIVATE void WriteXG(rpcArgs *argsP, FILE *xg_h, char *serverName, int sign_no)
260 char *name = GetName(serverName, sign_no);
263 * CASE 1: all arguments passed as parameters
266 fprintf(xg_h, "\nproc %s(\n", name);
268 /* declare each arg */
269 for (i=0; i < argsP->argCount; i++) {
270 WriteXGDecl(&argsP->argDescr[i], xg_h, i, FALSE,
271 (i==argsP->argCount-1));
274 /* Now pass the paramaters inside a structure */
275 fprintf(xg_h, "\nstruct %s_t {\n", name);
276 for (i=0; i < argsP->argCount; i++) {
277 WriteXGDecl(&argsP->argDescr[i], xg_h, i, TRUE,
278 (i==argsP->argCount-1));
280 fprintf(xg_h, "} ;\n");
281 fprintf(xg_h, "\nproc %s_s(\n", name);
282 fprintf(xg_h, "\tINOUT struct %s_t *s);\n", name);
288 * GetRandStr -- get a random string
290 PRIVATE void GetRandStr(int strLen, char **ret, int *rP)
298 randI = 'A' + ('Z' - 'A')*drand32();
299 sprintf(buf, "%c", randI);
308 * GetRandP -- sets a string to a random value of the data type
309 * inthe case of a char type, ret holds "%c" and ret2 holds '%c'
311 PRIVATE void GetRandP(char *typ, char **ret, char **ret2)
318 *ret = (char *) calloc(MAX_RAND_LENGTH+1, sizeof(char));
319 *ret2 = (char *) calloc(MAX_RAND_LENGTH+1, sizeof(char));
321 if (strstr(typ, "char")) {
322 GetRandStr(1, ret2, &randI);
324 strcpy(*ret2, "'\\\\'");
325 else if(randI == '\'')
326 strcpy(*ret2, "'\\''");
328 sprintf(*ret, "'%c'", randI);
330 } else if (strstr(typ, "short")) {
331 shI = SHRT_MIN + (SHRT_MAX - SHRT_MIN) * drand32();
332 sprintf(*ret, "%d", shI);
334 } else if (strstr(typ, "afs_int32")) {
335 randI = INT_MIN + UINT_MAX * drand32();
336 if (randI < INT_MIN || randI > INT_MAX) {
337 fprintf(stderr, "GetRandP: afs_int32 %d out of bounds\n", randI);
340 sprintf(*ret, "%d", randI);
342 } else if (strstr(typ, "float")) {
345 sprintf(*ret, "%2.8e", f);
348 } else if (strstr(typ, "double")) {
350 sprintf(*ret, "%2.16e", d1);
353 } else if (strstr(typ, "String")) {
354 strLen = (MAX_RAND_LENGTH-2)*drand32();
355 GetRandStr(strLen, ret, &randI);
362 * GenParamValues -- generate the parameter values for an rpc
364 PRIVATE void GenParamValues(rpcArgs *argsP)
369 /* generate random values for each argument */
370 for (i=0; i < argsP->argCount; i++) {
372 argsP->argDescr[i].vc_low = 0;
373 argsP->argDescr[i].vc_max = IDL_FIX_ARRAY_SIZE-1;
374 argsP->argDescr[i].vc_high = IDL_FIX_ARRAY_SIZE-1;
375 argsP->argDescr[i].ovc_low = 0;
376 argsP->argDescr[i].ovc_high = IDL_FIX_ARRAY_SIZE-1;
378 if (!strncmp(argsP->argDescr[i].type, "ar_", 3)) {
379 typ = argsP->argDescr[i].type + 3;
380 for (j = 0 ; j < IDL_FIX_ARRAY_SIZE ; j++) {
381 GetRandP(typ, &argsP->argDescr[i].inValue[j],
382 &argsP->argDescr[i].inValue2[j]);
383 GetRandP(typ, &argsP->argDescr[i].outValue[j],
384 &argsP->argDescr[i].outValue2[j]);
387 GetRandP(argsP->argDescr[i].type,
388 &argsP->argDescr[i].inValue[0],
389 &argsP->argDescr[i].inValue2[0]);
390 GetRandP(argsP->argDescr[i].type,
391 &argsP->argDescr[i].outValue[0],
392 &argsP->argDescr[i].outValue2[0]);
398 * WriteServC -- write the rpcs in the server file
400 PRIVATE void WriteServC(rpcArgs *argsP, FILE *srv_h, char *serverName, int sign_no)
405 name = GetName(serverName, sign_no);
406 fprintf(srv_h, "\nint A%s(struct rx_call *c,\n", name);
408 /* declare each arg */
409 for (i=0; i < argsP->argCount; i++) {
411 if (!strcmp(argsP->argDescr[i].type, "varString")) {
412 if (!strcmp(argsP->argDescr[i].direction, "IN")) {
413 fprintf(srv_h, "\tchar *a%d", i);
416 fprintf(srv_h, "\tchar **a%d", i);
419 else if (strncmp(argsP->argDescr[i].type, "ar_", 3) &&
420 (!strcmp(argsP->argDescr[i].direction, "IN"))) {
421 fprintf(srv_h, "\tdrpc_%s_t a%d", argsP->argDescr[i].type, i);
423 if (!strncmp(argsP->argDescr[i].type, "ar_", 3)) {
424 fprintf(srv_h, "\tdrpc_out_%s_t *a%d", argsP->argDescr[i].type, i);
427 fprintf(srv_h, "\tdrpc_%s_t *a%d", argsP->argDescr[i].type, i);
430 if(i < (argsP->argCount - 1)) {
431 fprintf(srv_h, ",\n");
434 fputs(")\n{\n", srv_h); /* balance the } */
435 fputs("\tint errFlag = 0;", srv_h);
438 * check the in and inout parameters
440 for (i=0; i < argsP->argCount; i++) {
442 if (!strcmp(argsP->argDescr[i].direction, "IN") ||
443 (!strcmp(argsP->argDescr[i].direction, "INOUT") &&
444 !strcmp(argsP->argDescr[i].type, "varString"))) {
446 typ = argsP->argDescr[i].type;
448 if (strstr(typ, "String")) {
449 if(!strcmp(argsP->argDescr[i].direction, "INOUT")) {
450 fprintf(srv_h, "\n\tCHECK%s((char *)*a%d, %s, \"%s\");",
451 typ, i, argsP->argDescr[i].inValue[0], name);
453 fprintf(srv_h, "\n\tCHECK%s((char *)a%d, %s, \"%s\");",
454 typ, i, argsP->argDescr[i].inValue[0], name);
456 } else if (!strcmp(typ, "afs_int32")) {
457 fprintf(srv_h, "\n\tCHECK%s(a%d, %sL, \"%s\");",
458 typ, i, argsP->argDescr[i].inValue[0], name);
460 if(!strncmp(typ, "ar_", 3)) {
461 for(j=0;j<IDL_FIX_ARRAY_SIZE;j++)
462 fprintf(srv_h, "\n\tCHECK%s(a%d->drpc_out_%s_t_val[%d], %s, \"%s\");",
463 (typ+3), i, typ, j, argsP->argDescr[i].inValue[j],
467 fprintf(srv_h, "\n\tCHECK%s(a%d, %s, \"%s\");",
468 typ, i, argsP->argDescr[i].inValue[0], name);
471 } else if (!strcmp(argsP->argDescr[i].direction, "INOUT")) {
473 typ = argsP->argDescr[i].type;
475 if (strstr(typ, "String")) {
476 fprintf(srv_h, "\n\tCHECK%s((char *)*a%d, %s, \"%s\");",
477 typ, i, argsP->argDescr[i].inValue[0], name);
478 } else if (!strcmp(typ, "afs_int32")) {
479 fprintf(srv_h, "\n\tCHECK%s(*a%d, %sL, \"%s\");",
480 typ, i, argsP->argDescr[i].inValue[0], name);
482 if(!strncmp(typ, "ar_", 3)) {
483 for(j=0;j<IDL_FIX_ARRAY_SIZE;j++)
484 fprintf(srv_h, "\n\tCHECK%s(a%d->drpc_out_%s_t_val[%d], %s, \"%s\");",
485 (typ+3), i, typ, j, argsP->argDescr[i].inValue[j],
489 fprintf(srv_h, "\n\tCHECK%s(*a%d, %s, \"%s\");",
490 typ, i, argsP->argDescr[i].inValue[0], name);
497 * free up memory for dynamic input args
499 for (i=0; i < argsP->argCount; i++) {
500 if (!strncmp(argsP->argDescr[i].type, "ar_", 3)) {
501 typ = argsP->argDescr[i].type;
502 if(!strcmp(argsP->argDescr[i].direction, "INOUT")) {
503 fprintf(srv_h, "\n\tif (a%d->drpc_out_%s_t_val) "
504 "free(a%d->drpc_out_%s_t_val);", i, typ, i, typ);
506 if(!strcmp(argsP->argDescr[i].direction, "INOUT") ||
507 !strcmp(argsP->argDescr[i].direction, "OUT")) {
508 fprintf(srv_h, "\n\ta%d->drpc_out_%s_t_val = (%s *) "
509 "malloc(FIX_ARRAY_SIZE * sizeof(%s));",
510 i, typ, (typ+3), (typ+3));
511 fprintf(srv_h, "\n\ta%d->drpc_out_%s_t_len = FIX_ARRAY_SIZE;",
518 * set the inout and out parameters
520 for (i=0; i < argsP->argCount; i++) {
522 if (!strcmp(argsP->argDescr[i].direction, "INOUT") ||
523 !strcmp(argsP->argDescr[i].direction, "OUT")) {
525 typ = argsP->argDescr[i].type;
527 if (!strncmp(typ, "ar_", 3)) {
528 for(j=0;j<IDL_FIX_ARRAY_SIZE;j++)
529 fprintf(srv_h, "\n\ta%d->drpc_out_%s_t_val[%d] = %s;",
530 i, typ, j, argsP->argDescr[i].outValue[j]);
531 } else if (!strcmp(typ, "afs_int32")) {
532 fprintf(srv_h, "\n\t*a%d = %sL;",
533 i, argsP->argDescr[i].outValue[0]);
534 } else if (!strcmp(typ, "varString")) {
535 if(!strcmp(argsP->argDescr[i].direction, "OUT")) {
536 fprintf(srv_h, "\n\t*a%d = (char *) malloc(STR_MAX);", i);
538 fprintf(srv_h, "\n\tstrcpy((char *)*a%d, %s);",
539 i, argsP->argDescr[i].outValue[0]);
540 } else if (strstr(typ, "String")) {
542 "\n\t*a%d = (drpc_%s_t)rpc_ss_allocate(%d);",
543 i, typ, strlen(argsP->argDescr[i].outValue[0])-1);
544 fprintf(srv_h, "\n\tstrcpy((char *)*a%d, %s);",
545 i, argsP->argDescr[i].outValue[0]);
547 fprintf(srv_h, "\n\t*a%d = %s;",
548 i, argsP->argDescr[i].outValue[0]);
555 "\n\t\tprintf(\"%s: failed\\n\");"
556 "\n\t\tfflush(stdout);"
558 "\n\treturn errFlag;\n}\n",
562 * second routine with arguments inside a structure
564 fprintf(srv_h, "\nint A%s_s(struct rx_call *c,\n\t%s_t *s)\n{"
565 "\n\tint errFlag = 0;", name, name);
568 * check the in and inout parameters
570 for (i=0; i < argsP->argCount; i++) {
572 if (!strcmp(argsP->argDescr[i].direction, "IN") ||
573 (!strstr(argsP->argDescr[i].type, "String") &&
574 !strcmp(argsP->argDescr[i].direction, "INOUT"))) {
576 typ = argsP->argDescr[i].type;
578 if(!strncmp(typ, "ar_", 3)) {
579 for(j=0;j<IDL_FIX_ARRAY_SIZE;j++)
580 fprintf(srv_h, "\n\tCHECK%s(s->a%d[%d], %s, \"%s_s\");",
581 (typ+3), i, j, argsP->argDescr[i].inValue[j],
584 else if (strstr(typ, "String")) {
585 fprintf(srv_h, "\n\tCHECK%s((char *)s->a%d, %s, \"%s_s\");",
586 typ, i, argsP->argDescr[i].inValue[0], name);
587 } else if (!strcmp(typ, "afs_int32")) {
588 fprintf(srv_h, "\n\tCHECK%s(s->a%d, %sL, \"%s_s\");",
589 typ, i, argsP->argDescr[i].inValue[0], name);
591 fprintf(srv_h, "\n\tCHECK%s(s->a%d, %s, \"%s_s\");",
592 typ, i, argsP->argDescr[i].inValue[0], name);
598 * set the inout and out parameters
600 for (i=0; i < argsP->argCount; i++) {
602 if (!strcmp(argsP->argDescr[i].direction, "INOUT") ||
603 !strcmp(argsP->argDescr[i].direction, "OUT")) {
605 typ = argsP->argDescr[i].type;
607 if(!strncmp(typ, "ar_", 3)) {
608 for(j=0;j<IDL_FIX_ARRAY_SIZE;j++)
609 fprintf(srv_h, "\n\ts->a%d[%d]= %s;",
610 i, j, argsP->argDescr[i].outValue[j]);
612 else if (!strcmp(typ, "afs_int32")) {
613 fprintf(srv_h, "\n\ts->a%d = %sL;",
614 i, argsP->argDescr[i].outValue[0]);
615 } else if (!strcmp(typ, "varString")) {
616 fprintf(srv_h, "\n\tstrcpy((char *)s->a%d, %s);",
617 i, argsP->argDescr[i].outValue[0]);
618 } else if (strstr(typ, "String")) {
619 fprintf(srv_h, "\n\ts->a%d = rpc_ss_allocate(%d);",
620 i, strlen(argsP->argDescr[i].outValue[0])-1);
621 fprintf(srv_h, "\n\tstrcpy((char *)s->a%d, %s);",
622 i, argsP->argDescr[i].outValue[0]);
624 fprintf(srv_h, "\n\ts->a%d = %s;",
625 i, argsP->argDescr[i].outValue[0]);
632 "\n\t\tprintf(\"%s_s: failed\\n\");"
634 "\n\tfflush(stdout);"
635 "\n\treturn errFlag;\n}\n",
643 * WriteMake - write the makefile for a particular client/server pair
645 PRIVATE void WriteMake(char *serverName, int srv_no, FILE *mak_h)
648 char *obj=platform[2];
650 sprintf(p,"%s%d", serverName, srv_no);
651 fprintf(mak_h, "%s", platform[1]);
652 if (threadModel == PTHREADS) {
654 "CFLAGS = -KPIC -g -mt -I$(DESTDIR)include\n"
660 "CFLAGS = -g -I$(DESTDIR)include\n"
666 "\n\ntest: all\ntests: all\nall: %sClt %sSrv\n\n"
667 "%sClt: %s.cs.%s %s.xdr.%s %sClt.%s $(LIBS)\n",
668 p,p,p,p,obj,p,obj,p,obj
670 if(platform == nt_symbols) {
671 fprintf(mak_h, "\t$(EXECONLINK)\n\n");
674 "\t$(CC) $(CFLAGS) -o $@ %sClt.%s %s.cs.%s %s.xdr.%s "
675 "$(LIBS) $(XLIBS)\n\n",
680 "%s.xdr.c: %s.xg\n\n"
681 "%s.h %s.cs.c %s.ss.c: %s.xg\n"
685 p,p,p,p,p,p,p,platform[3],p,platform[3],p);
687 "%sSrv: %s.ss.%s %s.xdr.%s %sSrv.%s $(LIBS)\n",
688 p,p,obj,p,obj,p,obj);
690 if(platform == nt_symbols) {
691 fprintf(mak_h, "\t$(EXECONLINK)\n\n");
694 "\t$(CC) $(CFLAGS) -o $@ %sSrv.o %s.ss.o %s.xdr.o "
695 "$(LIBS) $(XLIBS)\n\n",
700 if(platform == unix_symbols) {
703 "\t/bin/rm -f %sClt %s.h %s.cs.c %s.ss.c core "
705 "\t%sClt.o %s.cs.o %s.ss.o %s.xdr.c %s.xdr.o\n",
706 p,p,p,p,p,p,p,p,p,p,p);
712 * WriteCltTrailer - finish writing client source
714 PRIVATE void WriteCltTrailer(char *serverName, int first, int last, FILE *itl_h)
719 * Write out 1 function that calls all the manager functions
721 if (threadModel == PTHREADS) {
722 fprintf(itl_h, "\n\nvoid *threadFunc(void *arg) {\n");
724 fprintf(itl_h, "\n\nint threadFunc(int *arg) {\n");
728 "\tstruct rx_connection *conn;\n"
730 "\tint i = (int) arg;\n\n"
733 fprintf(itl_h, "\tconn = rx_GetCachedConnection(serverAddr,serverPort,4,secClass,secIndex);\n");
735 fprintf(itl_h, "\twhile(i--) {\n");
737 if (first == 0) first = 1;
738 for(i=first;i<last;i++) {
739 fprintf(itl_h, "\t\tC_%s%d(conn);\n",serverName, i);
740 fprintf(itl_h, "\t\tC_%s%d_s(conn);\n",serverName, i);
742 fprintf(itl_h, "\t}\n");
744 fprintf(itl_h, "\trx_ReleaseCachedConnection(conn);\n");
746 if (threadModel == PTHREADS) {
747 fprintf(itl_h, "\treturn (void *) 0;\n");
750 "\tLWP_CALL(LWP_SignalProcess,(&done));\n"
755 fprintf(itl_h, "}\n");
758 "\n\nstatic void DoRun(struct cmd_syndesc *as, char *arock) {\n"
761 if (threadModel == PTHREADS) {
762 fprintf(itl_h, "\tpthread_t *tid;\n");
764 fprintf(itl_h, "\tPROCESS *tid;\n");
769 "\tunsigned int numThreads=0,numIterations=0;\n"
771 "\tstruct hostent *host=NULL;\n\n"
772 "\tnumThreads = atoi(as->parms[0].items->data);\n"
773 "\tnumIterations = atoi(as->parms[1].items->data);\n"
774 "\tsecType = atoi(as->parms[2].items->data);\n"
775 "\tencLevel = atoi(as->parms[3].items->data);\n"
776 "\tserverPort = htons(atoi(as->parms[4].items->data));\n"
777 "\tif ((host = hostutil_GetHostByName(as->parms[5].items->data))==0) {\n"
781 "\t\tmemcpy((void *) &serverAddr, (const void *)host->h_addr, sizeof(serverAddr));\n"
783 "\tif ((secType<1) || (secType>2)) errflg++;\n"
784 "\tif ((encLevel<0) || (encLevel>2)) errflg++;\n"
785 "\tif ((serverPort == 0) ||(numThreads == 0) ||(numIterations == 0)) errflg++;\n"
787 "\t\tprintf(\"invalid argument\\n\");\n"
790 "\tif(rx_Init(htons(0)) < 0) {\n"
793 "\tswitch(secType) {\n"
795 "\t\t\tsecIndex = 0;\n"
796 "\t\t\tsecClass = rxnull_NewClientSecurityObject();\n"
799 "\t\t\tif (GetTicket (&kvno, &Ksession, &ticketLen, ticket) == 0) {\n"
800 "\t\t\t\tsecIndex = 2;\n"
801 "\t\t\t\tsecClass = rxkad_NewClientSecurityObject(encLevel,\n"
802 "\t\t\t\t&Ksession, kvno, ticketLen, ticket);\n"
808 "\tassert(secClass);\n\n"
810 if (threadModel == PTHREADS) {
813 "\tthr_setconcurrency(numThreads);\n"
815 "\ttid = (pthread_t *) "
816 "malloc(numThreads*(sizeof(pthread_t)));\n"
820 "\ttid = (PROCESS *) malloc(numThreads*(sizeof(PROCESS *)));\n"
826 "\tfor(j=0;j<numThreads;j++) {\n"
828 if (threadModel == PTHREADS) {
830 "\t\ti = pthread_create(&tid[j], (const pthread_attr_t *) 0,\n"
831 "\t\tthreadFunc, (void *) numIterations);\n"
832 "\t\tassert(i==0);\n"
836 "\t\tLWP_CALL(LWP_CreateProcess,(threadFunc, 10*4096, LWP_NORMAL_PRIORITY, numIterations, \"foo\", &tid[j]));\n"
842 "\tfor(j=0;j<numThreads;j++) {\n"
844 if (threadModel == PTHREADS) {
846 "\t\ti = pthread_join(tid[j], (void **) 0);\n"
847 "\t\tassert(i==0);\n"
850 fprintf(itl_h, "\t\tLWP_CALL(LWP_WaitProcess,(&done));\n");
860 * Write command syntax function
864 "static void SetupRunCmd(void) {\n"
865 "\tstruct cmd_syndesc *ts;\n"
866 "\tts = cmd_CreateSyntax((char *) 0,DoRun, 0, \"run the test client program\");\n"
867 "\tcmd_AddParm(ts, \"-threadCount\", CMD_SINGLE, CMD_REQUIRED, \"number of threads to spawn\");\n"
868 "\tcmd_AddParm(ts, \"-iterationCount\", CMD_SINGLE, CMD_REQUIRED, \"number of iterations to make over entire interface for each thread\");\n"
869 "\tcmd_AddParm(ts, \"-secType\", CMD_SINGLE, CMD_REQUIRED, \"security level to use (1 -> unauthenticated, 2 -> authenticated)\");\n"
870 "\tcmd_AddParm(ts, \"-encLevel\", CMD_SINGLE, CMD_REQUIRED, \"encryption level to use, (0-> rxkad_clear, 1 -> rxkad_auth, 2 -> rxkad_crypt)\");\n"
871 "\tcmd_AddParm(ts, \"-serverPort\", CMD_SINGLE, CMD_REQUIRED, \"port that server is using\");\n"
872 "\tcmd_AddParm(ts, \"-serverHost\", CMD_SINGLE, CMD_REQUIRED, \"host where server is running\");\n"
881 "int main (int argc, char *argv[]) {\n"
883 "\tinitialize_cmd_error_table();\n"
885 "\tcode = cmd_Dispatch(argc, argv);\n\n"
893 * Create macros useful for checking input/output parameters
896 PRIVATE void WriteTestMacros(FILE *f) {
898 "\n#define CHECKchar(x,y,z) if ((x)!=(y)) { printf(\"%%s: Got '%%c',"
899 "expected '%%c'\\n\", z, (char)x, (char)(y)); fflush(stdout); "
901 "\n#define CHECKshort(x,y,z) if ((x)!=(y)) "
902 "{ printf(\"%%s: Got 0x%%04x, "
903 "expected 0x%%04x\\n\", z, x, y); fflush(stdout); "
905 "\n#define CHECKint32(x,y,z) if ((x)!=(y)) "
906 "{ printf(\"%%s: Got 0x%%08x, "
907 "expected 0x%%08x\\n\", z, x, y); fflush(stdout); "
909 "\n#define CHECKfloat(x,y,z) if (((x)/(y)<.999999) "
910 "|| ((x)/(y)>1.000001)) "
911 "{ printf(\"%%s: Got %%2.8e, expected %%2.8e\\n\", z, x, y); "
914 "\n#define CHECKdouble(x,y,z) if (((x)/(y)<.999999999999999) || "
915 "((x)/(y)>1.000000000000001)) { printf(\"%%s: Got %%2.16e, "
916 "expected %%2.16e\\n\", z, x, y); fflush(stdout); errFlag = 1; }"
917 "\n#define CHECKvarString(x,y,z) if (strcmp((x),(y))) { printf(\"%%s: "
918 "Got \\\"%%s\\\", expected \\\"%%s\\\"\\n\", z, x, y); fflush(stdout); "
919 "errFlag = 1; } \n");
923 * WriteCltHeader - write the begining of the client code.
925 PRIVATE void WriteCltHeader(char *serverName, int srv_no, FILE *itl_h)
927 fprintf(itl_h, "#include <stdio.h>\n");
928 if (threadModel == PTHREADS) {
929 fprintf(itl_h,"#include <pthread.h>\n");
933 "#include <assert.h>\n"
934 "#include <rx/rx.h>\n"
935 "#include <rx/rx_null.h>\n"
936 "#include <rx/rxkad.h>\n"
937 "#include <afs/cmd.h>\n"
938 "#include \"%s%d.h\"\n"
940 platform[4], serverName, srv_no);
941 if (threadModel == LWPS) {
943 "\n\n#define LWP_CALL(fnName, params) \\\n"
946 "\trc = fnName params; \\\n"
947 "\tif (rc != LWP_SUCCESS) { \\\n"
948 "\t\tprintf(\"call to %%s failed with %%d\\n\", # fnName, rc); \\\n"
956 "struct ktc_encryptionKey serviceKey =\n"
957 "\t{0x45, 0xe3, 0x3d, 0x16, 0x29, 0x64, 0x8a, 0x8f};\n"
958 "long serviceKeyVersion = 7;\n"
959 "\nextern struct hostent *hostutil_GetHostByName();\n\n"
960 "static long GetTicket (long *versionP,\n"
961 "\tstruct ktc_encryptionKey *session,\n"
962 "\tint * ticketLenP, char *ticket)\n"
965 "\tdes_init_random_number_generator (&serviceKey);\n"
966 "\tcode = des_random_key (session);\n"
967 "\tif (code) return code;\n"
968 "\t*ticketLenP = 0;\n"
969 "\tcode = tkt_MakeTicket(ticket, ticketLenP, &serviceKey,\n"
970 "\t\t\"tclnt\", \"\", \"\",\n"
971 "\t\t0, 0xffffffff, session, 0,\n"
972 "\t\t\"tsrvr\", \"\");\n"
973 "\tif (code) return code;\n"
974 "\t*versionP = serviceKeyVersion;\n"
977 "static int secType,encLevel,serverPort,serverAddr;\n"
978 "struct rx_securityClass *secClass;\n"
981 "char ticket[MAXKTCTICKETLEN];\n"
983 "struct ktc_encryptionKey Ksession;\n\n"
985 WriteTestMacros(itl_h);
990 * WriteCltInit -- write the initialization for each param
992 PRIVATE void WriteCltInit(arg_tuple *arg, FILE *itl_h, int i,
996 char *s = (structFlag) ? "s." : "";
998 if ((!strncmp(arg->direction, "IN", 2) || structFlag)) {
999 if (!strncmp(arg->type, "varString", 9)) {
1000 fprintf(itl_h, "\tstrcpy(%sa%d, %s);\n", s, i, arg->inValue[0]);
1002 else if (!strncmp(arg->type, "ar_", 3)) {
1004 fprintf(itl_h, "\t%sa%d.drpc_out_%s_t_len = FIX_ARRAY_SIZE;\n",
1007 "\t%sa%d.drpc_out_%s_t_val = "
1008 "(%s *) malloc(FIX_ARRAY_SIZE * sizeof(%s));\n",
1009 s, i, arg->type, (arg->type + 3), (arg->type + 3));
1011 for(j=0;j<IDL_FIX_ARRAY_SIZE;j++) {
1014 "\t%sa%d[%d] = %s;\n",
1015 s, i, j,arg->inValue[j]);
1019 "\t%sa%d.drpc_out_%s_t_val[%d] = %s;\n",
1020 s, i, arg->type,j,arg->inValue[j]);
1025 fprintf(itl_h, "\t%sa%d = %s;\n", s, i, arg->inValue[0]);
1031 * WriteCltCall -- write each parameter for a call
1033 PRIVATE void WriteCltCall(arg_tuple *arg, FILE *itl_h, int i) {
1035 if (!strncmp(arg->type, "varString", 9)) {
1036 if ((!strncmp(arg->direction, "OUT", 3)) ||
1037 (!strncmp(arg->direction, "INOUT", 5))) {
1038 fprintf(itl_h, "&a%d_p", i);
1041 fprintf(itl_h, "a%d_p", i);
1045 if ((!strncmp(arg->direction, "OUT", 3)) ||
1046 (!strncmp(arg->direction, "INOUT", 5)) ||
1047 (!strncmp(arg->type, "ar_", 3))) {
1048 fprintf(itl_h, "&a%d", i);
1051 fprintf(itl_h, "a%d", i);
1057 * WriteCltDecl -- write the declaration for a parameter
1059 PRIVATE void WriteCltDecl(arg_tuple *arg, FILE *itl_h, int i) {
1061 if (!strncmp(arg->type, "ar_", 3)) {
1062 if (!strncmp(arg->direction, "OUT", 3)) {
1063 fprintf(itl_h, "\tdrpc_out_%s_t a%d = {0,0};\n", arg->type, i);
1066 fprintf(itl_h, "\tdrpc_out_%s_t a%d;\n", arg->type, i);
1069 else if (!strncmp(arg->type, "varString", 9)) {
1070 fprintf(itl_h, "\tchar a%d[STR_MAX];\n", i);
1071 fprintf(itl_h, "\tchar *a%d_p = a%d;\n", i, i);
1074 fprintf(itl_h, "\t%s a%d;\n", arg->type, i);
1080 * WriteClt -- write the rpcs in the client
1082 PRIVATE void WriteClt(rpcArgs *argsP, char *serverName, int sign_no, FILE *itl_h)
1084 char *name, *name2, *typ;
1087 name = GetName(serverName, sign_no);
1088 name2 = GetDescription(argsP);
1090 fprintf(itl_h, "\n/* %s */\n\n", name2);
1092 fprintf(itl_h, "\nvoid C_%s(struct rx_connection *conn) {\n", name);
1094 /* declare each arg */
1095 for (i=0; i < argsP->argCount; i++) {
1096 WriteCltDecl(&argsP->argDescr[i], itl_h, i);
1098 fprintf(itl_h, "\tint error;\n\tint errFlag;\n\n");
1100 /* initialize IN/INOUT args */
1101 for (i=0; i < argsP->argCount; i++) {
1102 WriteCltInit(&argsP->argDescr[i], itl_h, i, FALSE);
1105 /* call the server */
1106 fprintf(itl_h, "\terror = A%s(conn, ", name);
1109 for (i=0; i < argsP->argCount; i++) {
1110 WriteCltCall(&argsP->argDescr[i], itl_h, i);
1111 fprintf(itl_h, ((i < (argsP->argCount -1))) ? "," : ");\n");
1115 "\tif (error != 0) {\n"
1116 "\t\tprintf(\"C_%s failed %%d\\n\", error);\n"
1117 "\t\tfflush(stdout);\n"
1123 * check the in and inout parameters
1125 for (i=0; i < argsP->argCount; i++) {
1127 if ((!strcmp(argsP->argDescr[i].direction, "OUT")) ||
1128 (!strcmp(argsP->argDescr[i].direction, "INOUT"))) {
1130 typ = argsP->argDescr[i].type;
1132 if(!strncmp(typ, "ar_", 3)) {
1133 for(j=0;j<IDL_FIX_ARRAY_SIZE;j++)
1134 fprintf(itl_h, "\n\tCHECK%s(a%d.drpc_out_%s_t_val[%d], %s, \"C_%s_s\");",
1135 (typ+3), i, typ, j, argsP->argDescr[i].outValue[j],
1138 else if (strstr(typ, "String")) {
1139 fprintf(itl_h, "\n\tCHECK%s((char *)a%d, %s, \"C_%s_s\");",
1140 typ, i, argsP->argDescr[i].outValue[0], name);
1141 } else if (!strcmp(typ, "afs_int32")) {
1142 fprintf(itl_h, "\n\tCHECK%s(a%d, %sL, \"C_%s_s\");",
1143 typ, i, argsP->argDescr[i].outValue[0], name);
1145 fprintf(itl_h, "\n\tCHECK%s(a%d, %s, \"C_%s_s\");",
1146 typ, i, argsP->argDescr[i].outValue[0], name);
1152 * free up memory for dynamic input args
1154 for (i=0; i < argsP->argCount; i++) {
1155 if (!strncmp(argsP->argDescr[i].type, "ar_", 3)) {
1156 typ = argsP->argDescr[i].type;
1157 fprintf(itl_h, "\n\tif (a%d.drpc_out_%s_t_val) "
1158 "free(a%d.drpc_out_%s_t_val);", i, typ, i, typ);
1163 fprintf(itl_h, "\n}\n");
1166 * Call the structure oriented rpc interface
1169 fprintf(itl_h, "\nvoid C_%s_s(struct rx_connection *conn) {\n", name);
1170 fprintf(itl_h, "\tstruct %s_t s;\n", name);
1171 fprintf(itl_h, "\tint error;\n\tint errFlag;\n\n");
1173 /* initialize IN/INOUT args */
1174 for (i=0; i < argsP->argCount; i++) {
1175 WriteCltInit(&argsP->argDescr[i], itl_h, i, TRUE);
1178 /* call the server */
1179 fprintf(itl_h, "\terror = A%s_s(conn, &s);\n", name);
1182 "\tif (error != 0) {\n"
1183 "\t\tprintf(\"C_%s_s failed %%d\\n\", error);\n"
1184 "\t\tfflush(stdout);\n"
1190 * check the in and inout parameters
1192 for (i=0; i < argsP->argCount; i++) {
1194 if ((!strcmp(argsP->argDescr[i].direction, "OUT")) ||
1195 (!strcmp(argsP->argDescr[i].direction, "INOUT"))) {
1197 typ = argsP->argDescr[i].type;
1199 if(!strncmp(typ, "ar_", 3)) {
1200 for(j=0;j<IDL_FIX_ARRAY_SIZE;j++)
1201 fprintf(itl_h, "\n\tCHECK%s(s.a%d[%d], %s, \"C_%s_s\");",
1202 (typ+3), i, j, argsP->argDescr[i].outValue[j],
1205 else if (strstr(typ, "String")) {
1206 fprintf(itl_h, "\n\tCHECK%s((char *)s.a%d, %s, \"C_%s_s\");",
1207 typ, i, argsP->argDescr[i].outValue[0], name);
1208 } else if (!strcmp(typ, "afs_int32")) {
1209 fprintf(itl_h, "\n\tCHECK%s(s.a%d, %sL, \"C_%s_s\");",
1210 typ, i, argsP->argDescr[i].outValue[0], name);
1212 fprintf(itl_h, "\n\tCHECK%s(s.a%d, %s, \"C_%s_s\");",
1213 typ, i, argsP->argDescr[i].outValue[0], name);
1219 fprintf(itl_h, "\n}\n");
1226 * WriteXGHeader -- fill in Header info in the xg file
1228 PRIVATE void WriteXGHeader(char *serverName, FILE *xg_h, int srv_no)
1231 /* create the interface header */
1234 "\n/* Do not edit this file -- it was created by a generator */\n"
1236 "const STR_MAX = %d; \n"
1237 "const FIX_ARRAY_SIZE = %d; \n"
1238 "typedef char drpc_char_t; \n"
1239 "typedef short drpc_short_t; \n"
1240 "typedef long drpc_int32_t; \n"
1241 "typedef string drpc_varString_t<STR_MAX>; \n"
1242 "typedef drpc_char_t drpc_ar_char_t[FIX_ARRAY_SIZE]; \n"
1243 "typedef drpc_char_t drpc_out_ar_char_t<FIX_ARRAY_SIZE>; \n"
1244 "typedef drpc_short_t drpc_ar_short_t[FIX_ARRAY_SIZE]; \n"
1245 "typedef drpc_short_t drpc_out_ar_short_t<FIX_ARRAY_SIZE>; \n"
1246 "typedef drpc_int32_t drpc_ar_int32_t[FIX_ARRAY_SIZE]; \n"
1247 "typedef drpc_int32_t drpc_out_ar_int32_t<FIX_ARRAY_SIZE>; \n"
1249 IDL_STR_MAX, IDL_FIX_ARRAY_SIZE);
1253 * WriteServHeader -- fill in the Header info in the server file
1255 PRIVATE void WriteServHeader(FILE *srv_h, char *serverName, int srv_no)
1259 name = GetName(serverName, srv_no);
1262 "\n/* Do not edit this file -- it's been created by a generator */\n\n"
1264 "#include <stdio.h>\n"
1265 "#include <string.h>\n"
1266 "#include <stdlib.h>\n"
1267 "#include <rx/rx.h>\n"
1268 "#include <rx/rx_null.h>\n"
1269 "#include <rx/rxkad.h>\n"
1270 "#include <afs/cmd.h>\n"
1271 "#include \"%s.h\"\n\n"
1272 "struct ktc_encryptionKey serviceKey =\n"
1273 "\t{0x45, 0xe3, 0x3d, 0x16, 0x29, 0x64, 0x8a, 0x8f};\n"
1274 "long serviceKeyVersion = 7;\n\n"
1275 "extern int AExecuteRequest();\n"
1276 "extern char *optarg;\n"
1277 "extern int optind, opterr, optopt;\n\n"
1278 "#define VERIFY(x,y) if (!(x)) { printf y ; exit(1); }\n"
1279 "#define CHECK(x) ASSERT(x)\n"
1283 WriteTestMacros(srv_h);
1288 * WriteServTrailer -- finish up the server file
1290 PRIVATE void WriteServTrailer(FILE *srv_h) {
1293 "\nstatic long GetKey (char *rock, long kvno, struct ktc_encryptionKey *key) {\n"
1294 "\tmemcpy ((void *) key, (void *) &serviceKey, sizeof(*key));\n"
1298 "static void DoRun(struct cmd_syndesc *as, char *arock) {\n"
1299 "\tstruct rx_service *serv;\n"
1300 "\tstruct rx_securityClass *sc[3];\n\n"
1301 "\tint port=0, errflg=0;\n"
1303 "\tint lowThreads=4, highThreads=8;\n"
1304 "\tlowThreads = atoi(as->parms[0].items->data);\n"
1305 "\thighThreads = atoi(as->parms[1].items->data);\n"
1306 "\tport = atoi(as->parms[2].items->data);\n"
1308 "\tif (port == 0) errflg++;\n"
1311 "\t\tprintf(\"invalid argument\\n\");\n"
1315 "\trx_Init(htons(port));\n"
1316 "\tsc[0] = rxnull_NewServerSecurityObject();\n"
1318 "\tsc[2] = rxkad_NewServerSecurityObject (rxkad_clear, 0, GetKey, 0);\n"
1319 "\tif (serv = rx_NewService(0,4,\"foo\",sc,3,AExecuteRequest)) {\n"
1320 "\t\trx_SetMinProcs(serv,lowThreads);\n"
1321 "\t\trx_SetMaxProcs(serv,highThreads);\n"
1322 "\t\trx_StartServer(1);\n"
1327 "static void SetupRunCmd(void) {\n"
1328 "\tstruct cmd_syndesc *ts;\n"
1329 "\tts = cmd_CreateSyntax((char *) 0,DoRun, 0, \"run the test server program\");\n"
1330 "\tcmd_AddParm(ts, \"-lowThreadCount\", CMD_SINGLE, CMD_REQUIRED, \"minimum number of threads to spawn\");\n"
1331 "\tcmd_AddParm(ts, \"-highThreadCount\", CMD_SINGLE, CMD_REQUIRED, \"maximum number of threads to spawn\");\n"
1332 "\tcmd_AddParm(ts, \"-serverPort\", CMD_SINGLE, CMD_REQUIRED, \"port that server is using\");\n"
1335 "int main(int argc, char **argv) {\n"
1337 "\tinitialize_cmd_error_table();\n"
1338 "\tSetupRunCmd();\n"
1339 "\tcode = cmd_Dispatch(argc, argv);\n"
1346 * ProcessCmdLine -- processes the command line args
1348 PRIVATE void ProcessCmdLine(int argc, char **argv, char **serverName,
1349 char **ipFileName, char **outputDir)
1355 /* command line processing */
1356 while (--argc > 0) {
1357 if ((*++argv)[0] == '-') {
1358 switch ((*argv)[1]) {
1361 case 'F': /* input table file */
1362 *ipFileName = *++argv;
1365 case 'h': /* display help */
1371 case 'L': /* use LWP threads */
1375 case 'S': /* serverName */
1376 *serverName = *++argv;
1377 /* need 8 char file name, and so truncate the server name*/
1378 if ((int)strlen(*serverName) > MAX_SERV_NAME)
1379 *(*serverName+MAX_SERV_NAME) = '\0';
1384 *outputDir = *++argv;
1389 if(strcmp(*++argv,"NT")) platform = unix_symbols;
1403 FATAL("Please set server name using -s switch\n");
1407 void main(int argc, char **argv)
1409 FILE *table_h, *srv_h, *xg_h, *clt_h, *mak_h;
1412 char *name, *ifName;
1413 char *serverName = NULL;
1414 char *ipFileName = NULL;
1415 char *outputDir = NULL;
1416 int sign_no=0, start_no, srv_no;
1418 ProcessCmdLine(argc, argv, &serverName, &ipFileName, &outputDir);
1420 /* open input file */
1421 table_h = fopen(ipFileName, "r");
1422 MEM_CHK(table_h, "main: Unable to open input file\n");
1428 * open the first set of output files
1431 name = GetName(serverName, srv_no);
1433 srv_h = OpenOutFile(outputDir, name, "Srv.c");
1434 xg_h = OpenOutFile(outputDir, name, ".xg");
1435 clt_h = OpenOutFile(outputDir, name, "Clt.c");
1436 mak_h = OpenOutFile(outputDir, name, ".mak");
1438 WriteXGHeader(serverName, xg_h, srv_no);
1439 WriteServHeader(srv_h, serverName, srv_no);
1440 WriteCltHeader(serverName, srv_no, clt_h);
1441 WriteMake(serverName, srv_no, mak_h);
1445 /* read the table */
1446 while (fscanf(table_h, "%d", &(args.argCount)) != EOF) {
1448 /* increment signature number 8.3 format-- only 10^7 dif sign */
1450 if (sign_no > 1.0e+7)
1451 FATAL("Max no: of signatures overflow\n");
1453 /* allocate for the arg struct */
1454 args.argDescr = (arg_tuple *)calloc(args.argCount, sizeof(arg_tuple));
1455 MEM_CHK(args.argDescr, "main: Out of memory -- args.argDescr\n");
1457 /* pick out the dirs and the types */
1458 for (i=0; i < args.argCount; i++) {
1459 if(!fscanf(table_h, " ( %s %s )", args.argDescr[i].direction,
1460 args.argDescr[i].type)) {
1461 FATAL("main: Incorrect input file format\n");
1466 * switch files when we hit TESTS_PER_FILE
1468 if (sign_no - start_no >= TESTS_PER_FILE) {
1470 * Finish up the current files
1472 WriteServTrailer(srv_h);
1473 WriteCltTrailer(serverName, start_no, sign_no, clt_h);
1480 * Open the next set of output files
1485 name = GetName(serverName, srv_no);
1487 srv_h = OpenOutFile(outputDir, name, "Srv.c");
1488 xg_h = OpenOutFile(outputDir, name, ".xg");
1489 clt_h = OpenOutFile(outputDir, name, "Clt.c");
1490 mak_h = OpenOutFile(outputDir, name, ".mak");
1491 WriteXGHeader(serverName, xg_h, srv_no);
1492 WriteServHeader(srv_h, serverName, srv_no);
1493 WriteCltHeader(serverName, srv_no, clt_h);
1494 WriteMake(serverName, srv_no, mak_h);
1500 /* initialize parameter values */
1501 for (i=0; i<args.argCount; i++) {
1502 for (j = 0 ; j < IDL_FIX_ARRAY_SIZE ; j++) {
1503 args.argDescr[i].inValue[j] = NULL;
1504 args.argDescr[i].inValue2[j] = NULL;
1505 args.argDescr[i].outValue[j] = NULL;
1506 args.argDescr[i].outValue2[j] = NULL;
1509 GenParamValues(&args);
1511 /* write rpc desc into body of the interface */
1512 WriteXG(&args, xg_h, serverName, sign_no);
1514 /* write the rpc into the manager file */
1515 WriteServC(&args, srv_h, serverName, sign_no);
1517 /* write out ITL test */
1518 WriteClt(&args, serverName, sign_no, clt_h);
1520 /* free saved values */
1521 for (i=0; i<args.argCount; i++) {
1522 for (j = 0 ; j < IDL_FIX_ARRAY_SIZE ; j++) {
1523 if (args.argDescr[i].inValue[j])
1524 free(args.argDescr[i].inValue[j]);
1525 if (args.argDescr[i].inValue2[j])
1526 free(args.argDescr[i].inValue2[j]);
1527 if (args.argDescr[i].outValue[j])
1528 free(args.argDescr[i].outValue[j]);
1529 if (args.argDescr[i].outValue2[j])
1530 free(args.argDescr[i].outValue2[j]);
1533 free(args.argDescr);
1536 WriteServTrailer(srv_h);
1537 WriteCltTrailer(serverName, start_no, (sign_no +1), clt_h);
1547 * create 1 makefile that drives all the rest
1550 mak_h = OpenOutFile(outputDir, "Makefile", "");
1551 fprintf(mak_h, "\ntest:all\ntests:all\nall:\n");
1552 fprintf(mak_h, "%s", platform[8]);
1553 for(i=1;i<=srv_no;i++)
1554 fprintf(mak_h, "\t%s %s%d.mak %s\n",
1555 platform[0], serverName, i, platform[5]);
1556 fprintf(mak_h, "\nclean:\n");
1557 for(i=1;i<=srv_no;i++)
1558 fprintf(mak_h, "\t%s %s%d.mak clean\n", platform[0], serverName, i);