e74221db5022366f4a67416bf47e79d16cd33acc
[openafs.git] / src / rx / test / tableGen.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
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
8  */
9
10 /*
11  * The program will create a file that contains descriptions
12  * of a set of rx rpc's.  The output of this program is used
13  * as input to generator.c.
14  *
15  * Changing the output format of this program will necessitate
16  * a change in generator.c
17  */
18
19 #include <afsconfig.h>
20 #include <afs/param.h>
21
22
23 #include <stdio.h>
24 #include <string.h>
25 #include <stdlib.h>
26
27 #define PRIVATE static
28 #define IN
29 #define MACRO_BEGIN     do {
30 #define MACRO_END       } while (0)
31
32 #if defined(WIN32)
33 #include <io.h>
34 #define close(x)                _close(x)
35 #endif
36
37 #define ATTR_COUNT              3
38 #define MAX_NO_OF_ARGUMENTS     2
39 #define MAX_TYPE_NAME_LEN       10
40 #define MAX_DIRECTION_NAME_LEN  6
41 #define MAX_ATTR_NAME_LEN       7
42 #define MAX_SIGNATURE_LEN       100000
43
44 #define NEXT_SEQ(S,M)   (((S) >= ((M)-1)) ? 0 : (S)+1)
45
46 #define MEM_CHK(x, y) if(!x) {fprintf(stderr, y); exit(1);}
47 #define FATAL( y ) {fprintf(stderr, y); exit(1);}
48 #define PrintShortUsage \
49     MACRO_BEGIN \
50         fprintf( stderr, \
51 "Usage: tableGen [-h] [-a] <appendFileName> -d <list of dirs> \
52 [-o] <outputFile> -t <list of types>\n"); \
53     MACRO_END
54 #define PrintLongUsage \
55     MACRO_BEGIN \
56         PrintShortUsage; \
57         fprintf( stderr, \
58 "\nCommand line options(case insensitive):\
59 \n\t-h = help message \
60 \n\t-a = set the file to append\
61 \n\t-d = set the list of directions (IN OUT INOUT)\
62 \n\t-o = set output file (mandatory)\
63 \n\t-t = set the list of types (char int8 short afs_int32 \
64 \n\t\tfloat double string ar_char ar_int8 ar_short \
65 \n\t\tar_int32 ar_float ar_double \
66 \n"); \
67     MACRO_END
68
69 /* macro which sets if attributes for var/conf found */
70 #define SET_ATTR_FLAGS( x ) \
71     MACRO_BEGIN \
72         if (!strcmp(attrib[x], "size")) SIZE = TRUE;\
73         else if (!strcmp(attrib[x], "max")) MAX = TRUE; \
74         else if (!strcmp(attrib[x], "length")) LENGTH = TRUE;\
75         else if (!strcmp(attrib[x], "last")) LAST = TRUE;\
76     MACRO_END
77
78 static char **dir;
79 static char **typ;
80 static int dir_size;
81 static int typ_size;
82 static int attr_size;
83
84 PRIVATE char *init_dir[] = { "IN", "OUT", "INOUT" };
85
86 PRIVATE char *init_typ[] = {
87     "char",
88     "short",
89     "afs_int32",
90     "varString",
91     "ar_char",
92     "ar_short",
93     "ar_int32",
94 };
95 PRIVATE char *attrib[] = {
96     "1 max",
97     "1 size",
98     "1 first",
99     "1 last",
100     "1 length",
101     "2 max first",
102     "2 max last",
103     "2 max length",
104     "2 size first",
105     "2 size last",
106     "2 size length",
107     "2 first last",
108     "2 first length",
109     "3 max first last",
110     "3 max first length",
111     "3 size first last",
112     "3 size first length"
113 };
114
115 /*
116  * 31 bit random number generator, we don't really care how random
117  * these numbers are, it is more important that identical IDL files
118  * are generated no matter what platform the generator runs on
119  */
120 static unsigned long randVal = 0x330E16;
121
122 PRIVATE double
123 drand32()
124 {
125     randVal = ((randVal * 0xEECE66D) + 0xB) & 0xFFFFFFFF;
126     return ((double)(randVal) / 4294967296.0);
127 }
128
129 /*
130  * BunchArg -- prints signature for lots of arguments
131  */
132 #define MAX_ARGS 10
133
134 PRIVATE void
135 BunchArg(FILE * O_FP)
136 {
137     int num_args = ((int)((double)MAX_ARGS * drand32()));
138     int i;
139     int dir_index, typ_index;
140
141     if (num_args == 0)
142         num_args = 1;
143     fprintf(O_FP, "%d ", num_args);
144
145     for (i = 0; i < num_args; i++) {
146         typ_index = ((int)((double)typ_size * drand32()));
147         do {
148             dir_index = ((int)((double)dir_size * drand32()));
149         } while (!strcmp(dir[dir_index], "INOUT")
150                  && (!strcmp(typ[typ_index], "varString")));
151
152         fprintf(O_FP, "( %s %s ) ", dir[dir_index], typ[typ_index]);
153     }
154     fprintf(O_FP, "\n");
155 }
156
157 /*
158  * SingleArg -- prints signature for single argument of given type
159  */
160 PRIVATE void
161 SingleArg(O_FP, typ_index)
162      FILE *O_FP;
163      IN int typ_index;
164 {
165     int dir_index;
166
167     /*
168      * choose random argument direction, cannot use ref string
169      * pointers for output parameters
170      */
171     do {
172         dir_index = ((int)((double)dir_size * drand32()));
173     } while (!strcmp(dir[dir_index], "INOUT")
174              && (!strcmp(typ[typ_index], "varString")));
175
176     fprintf(O_FP, "1 ( %s %s )\n", dir[dir_index], typ[typ_index]);
177 }
178
179 /*
180  * DoubleArg -- prints signature for two arguments of given types
181  */
182 PRIVATE void
183 DoubleArg(O_FP, typ_index1, typ_index2)
184      FILE *O_FP;
185      IN int typ_index1;
186      IN int typ_index2;
187 {
188     int dir_index1;
189     int dir_index2;
190
191     /*
192      * choose random argument direction, cannot use ref string
193      * pointers for output parameters
194      */
195     do {
196         dir_index1 = ((int)((double)dir_size * drand32()));
197     } while (!strcmp(dir[dir_index1], "INOUT")
198              && (!strcmp(typ[typ_index1], "varString")));
199     do {
200         dir_index2 = ((int)((double)dir_size * drand32()));
201     } while (!strcmp(dir[dir_index2], "INOUT")
202              && (!strcmp(typ[typ_index2], "varString")));
203
204     fprintf(O_FP, "2 ( %s %s ) ", dir[dir_index1], typ[typ_index1]);
205     fprintf(O_FP, "( %s %s )\n", dir[dir_index2], typ[typ_index2]);
206 }
207
208 /*
209  * ProcessCmdLine -- processes the command line args 
210  */
211 PRIVATE void
212 ProcessCmdLine(argc, argv, apFileNamePP, outputFileP)
213      int argc;
214      char **argv;
215      char **apFileNamePP;
216      char **outputFileP;
217 {
218     int i, n;
219     char **p;
220
221     dir_size = 0;
222     typ_size = 0;
223     *outputFileP = NULL;
224     if (argc == 1) {
225         PrintShortUsage;
226         exit(1);
227     }
228     /* command line processing */
229     while (--argc > 0) {
230         if ((*++argv)[0] == '-') {
231             switch ((*argv)[1]) {
232
233             case 'a':
234             case 'A':           /* input table file */
235                 *apFileNamePP = *++argv;
236                 --argc;
237                 break;
238             case 'd':
239             case 'D':
240                 n = 0;
241                 p = argv;
242                 while (argc > 1 && (*++p)[0] != '-') {
243                     argc--;
244                     n++;
245                 }
246                 if (n == 0)
247                     FATAL("ProcessCmdLine: must give dir with -d\n");
248                 dir_size = n;
249                 dir = (char **)malloc(sizeof(char *) * n);
250                 MEM_CHK(dir, "ProcessCmdLine: out of mem dir\n");
251                 for (i = 0; i < n; i++)
252                     *(dir + i) = *++argv;
253                 break;
254             case 'h':           /* display help */
255             case 'H':
256                 PrintLongUsage;
257                 exit(0);
258                 break;
259             case 'o':
260             case 'O':
261                 *outputFileP = *(++argv);
262                 --argc;
263                 break;
264             case 't':
265             case 'T':
266                 n = 0;
267                 p = argv;
268                 while (argc > 1 && (*++p)[0] != '-') {
269                     --argc;
270                     n++;
271                 }
272                 if (n == 0)
273                     FATAL("ProcessCmdLine: must give typ with -t\n");
274                 typ_size = n;
275                 typ = (char **)malloc(sizeof(char *) * n);
276                 MEM_CHK(typ, "ProcessCmdLine: out of mem typ\n");
277                 for (i = 0; i < n; i++)
278                     *(typ + i) = *++argv;
279                 break;
280             default:
281                 PrintLongUsage;
282                 exit(1);
283                 break;
284             }
285         } else {
286             PrintShortUsage;
287             exit(1);
288         }
289     }
290     if (*outputFileP == 0)
291         FATAL("Please set output filename(s) using -o switch\n");
292
293     if (dir_size == 0) {
294         dir_size = sizeof(init_dir) / sizeof(init_dir[0]);
295         dir = &init_dir[0];
296     }
297
298     if (typ_size == 0) {
299         typ_size = sizeof(init_typ) / sizeof(init_typ[0]);
300         typ = &init_typ[0];
301     }
302
303     attr_size = sizeof(attrib) / sizeof(attrib[0]);
304 }
305
306 void
307 main(argc, argv)
308      int argc;
309      char **argv;
310 {
311     int i, j;
312     char *apFileName = NULL;
313     char *outputFile;
314     FILE *A_FP;
315     FILE *O_FP;
316     char max_buf[MAX_SIGNATURE_LEN];
317
318     ProcessCmdLine(argc, argv, &apFileName, &outputFile);
319
320     /* open the files */
321     O_FP = fopen(outputFile, "w");
322     MEM_CHK(O_FP, "main: Unable to open output file\n");
323     if (apFileName) {
324         A_FP = fopen(apFileName, "r");
325         MEM_CHK(A_FP, "main: Unable to open append file\n");
326         while (fgets(max_buf, MAX_SIGNATURE_LEN, A_FP)) {
327             fputs(max_buf, O_FP);
328         }
329         fclose(A_FP);
330     }
331
332     for (i = 0; i < typ_size; i++) {
333         SingleArg(O_FP, i);
334         for (j = 0; j < typ_size; j++) {
335             DoubleArg(O_FP, i, j);
336         }
337     }
338     for (i = 0; i < 100; i++) {
339         BunchArg(O_FP);
340     }
341
342     fclose(O_FP);
343     exit(0);
344 }