Import Upstream version 1.8.5
[hcoop/debian/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 = 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 = 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 }