2 # See the file LICENSE for redistribution information.
4 # Copyright (c) 1996-2009 Oracle. All rights reserved.
10 if (source_file == "" || header_file == "") {
11 print "Usage: gen_msg.awk requires these variables to be set:";
12 print "\theader_file\t-- the message #include file being created";
13 print "\tsource_file\t-- the message source file being created";
24 printf("/* Do not edit: automatically built by gen_msg.awk. */\n\n") \
26 printf("#include \"db_config.h\"\n\n") >> CFILE
28 # Start .h file, make the entire file conditional.
29 printf("/* Do not edit: automatically built by gen_msg.awk. */\n\n") \
31 printf("#ifndef\t%s_AUTO_H\n#define\t%s_AUTO_H\n\n", prefix, prefix) \
33 printf("/*\n") >> HFILE;
34 printf(" * Message sizes are simply the sum of field sizes (not\n") \
36 printf(" * counting variable size parts, when DBTs are present),\n") \
38 printf(" * and may be different from struct sizes due to padding.\n") \
40 printf(" */\n") >> HFILE;
43 for (i = 2; i < NF; i++)
44 printf("%s ", $i) >> CFILE;
45 printf("%s\n", $i) >> CFILE;
49 print "Invalid format: missing END statement";
55 for (i = 2; i<= NF; i++) {
58 else if ($i == "check_length")
60 else if ($i == "version")
64 base_name = sprintf("%s_%s", prefix, thismsg);
65 typedef_name = sprintf("%s_args", base_name);
66 msg_size_name = toupper(sprintf("%s_SIZE", base_name));
67 max_name = toupper(sprintf("%s_MAXMSG_SIZE", prefix));
72 if (types[nvars] == "DBT")
78 print "Invalid format: missing BEGIN statement";
82 printf("%s needs at least one field\n", thismsg);
87 for (i = 0; i < nvars; i++)
88 sum += type_length(types[i]);
89 printf("#define\t%s\t%d\n", msg_size_name, sum) >> HFILE;
93 printf("typedef struct _%s {\n", typedef_name) >> HFILE;
94 for (i = 0; i < nvars; i++) {
95 if (types[i] == "DB_LSN" || types[i] == "DBT")
96 printf("\t%s\t\t%s;\n", types[i], vars[i]) >> HFILE;
98 printf("\t%s\t%s;\n", types[i], vars[i]) >> HFILE;
100 printf("} %s;\n\n", typedef_name) >> HFILE;
105 # Reinitialize variables for next time.
113 # End the conditional for the HFILE
114 printf("#define\t%s\t%d\n", max_name, maxmsg) >> HFILE;
115 printf("#endif\n") >> HFILE;
118 # Length of fixed part of message. Does not count variable-length data portion
121 function type_length(type)
123 if (type == "DB_LSN")
125 if (type == "DBT" || type == "u_int32_t" || type == "db_pgno_t")
127 if (type == "u_int16_t")
129 printf("unknown field type: %s", type);
133 function emit_marshal()
140 function_name = sprintf("%s_marshal", base_name);
141 p[pi++] = function_name;
142 p[pi++] = " __P((ENV *, ";
144 p[pi++] = "u_int32_t, ";
145 p[pi++] = sprintf("%s *, u_int8_t *", typedef_name);
147 p[pi++] = ", size_t, size_t *";
149 proto_format(p, CFILE);
152 printf("int\n") >> CFILE;
154 printf("void\n") >> CFILE;
155 printf("%s(env", function_name) >> CFILE;
157 printf(", version") >> CFILE;
158 printf(", argp, bp") >> CFILE;
160 printf(", max, lenp") >> CFILE;
161 printf(")\n") >> CFILE;
163 printf("\tENV *env;\n") >> CFILE;
165 printf("\tu_int32_t version;\n") >> CFILE;
166 printf("\t%s *argp;\n", typedef_name) >> CFILE;
167 printf("\tu_int8_t *bp;\n") >> CFILE;
169 printf("\tsize_t *lenp, max;\n") >> CFILE;
170 printf("{\n") >> CFILE;
173 printf("\tint copy_only;\n") >> CFILE;
175 printf("\tu_int8_t *start;\n\n") >> CFILE;
176 printf("\tif (max < %s", msg_size_name) >> CFILE;
177 for (i = 0; i < nvars; i++)
178 if (types[i] == "DBT")
179 printf("\n\t + (size_t)argp->%s.size", \
182 printf(")\n") >> CFILE;
183 printf("\t\treturn (ENOMEM);\n") >> CFILE;
184 printf("\tstart = bp;\n\n") >> CFILE;
188 printf("\tcopy_only = 0;\n") >> CFILE;
189 printf("\tif (version < DB_REPVERSION_47)\n") >> CFILE;
190 printf("\t\tcopy_only = 1;\n") >> CFILE;
192 for (i = 0; i < nvars; i++) {
193 if (types[i] == "u_int32_t" || types[i] == "db_pgno_t") {
195 printf("\tif (copy_only) {\n") >> CFILE;
197 "\t\tmemcpy(bp, &argp->%s, sizeof(u_int32_t));\n", vars[i]) >> CFILE;
199 "\t\tbp += sizeof(u_int32_t);\n") >> CFILE;
200 printf("\t} else\n\t") >> CFILE;
202 printf("\tDB_HTONL_COPYOUT(env, bp, argp->%s);\n", \
204 } else if (types[i] == "u_int16_t") {
206 printf("\tif (copy_only) {\n") >> CFILE;
208 "\t\tmemcpy(bp, &argp->%s, sizeof(u_int16_t));\n", vars[i]) >> CFILE;
210 "\t\tbp += sizeof(u_int16_t);\n") >> CFILE;
211 printf("\t} else\n\t") >> CFILE;
213 printf("\tDB_HTONS_COPYOUT(env, bp, argp->%s);\n", \
215 } else if (types[i] == "DB_LSN") {
217 printf("\tif (copy_only) {\n") >> CFILE;
219 "\t\tmemcpy(bp, &argp->%s.file, sizeof(u_int32_t));\n", vars[i]) >> CFILE;
221 "\t\tbp += sizeof(u_int32_t);\n") >> CFILE;
223 "\t\tmemcpy(bp, &argp->%s.offset, sizeof(u_int32_t));\n", vars[i]) >> CFILE;
225 "\t\tbp += sizeof(u_int32_t);\n") >> CFILE;
226 printf("\t} else {\n\t") >> CFILE;
228 printf("\tDB_HTONL_COPYOUT(env, bp, argp->%s.file);\n",\
231 printf("\t") >> CFILE;
233 "\tDB_HTONL_COPYOUT(env, bp, argp->%s.offset);\n", \
236 printf("\t}\n") >> CFILE;
237 } else if (types[i] == "DBT") {
239 printf("\tif (copy_only) {\n") >> CFILE;
241 "\t\tmemcpy(bp, &argp->%s.size, sizeof(u_int32_t));\n", vars[i]) >> CFILE;
243 "\t\tbp += sizeof(u_int32_t);\n") >> CFILE;
244 printf("\t} else\n\t") >> CFILE;
246 printf("\tDB_HTONL_COPYOUT(env, bp, argp->%s.size);\n",\
248 printf("\tif (argp->%s.size > 0) {\n", vars[i]) \
251 "\t\tmemcpy(bp, argp->%s.data, argp->%s.size);\n", \
252 vars[i], vars[i]) >> CFILE;
253 printf("\t\tbp += argp->%s.size;\n", vars[i]) >> CFILE;
254 printf("\t}\n") >> CFILE;
256 printf("unknown field type: %s", types[i]);
262 printf("\n\t*lenp = (size_t)(bp - start);\n") >> CFILE;
263 printf("\treturn (0);\n") >> CFILE;
265 printf("}\n\n") >> CFILE;
268 function emit_unmarshal()
272 function_name = sprintf("%s_unmarshal", base_name);
273 p[pi++] = function_name;
274 p[pi++] = " __P((ENV *, ";
276 p[pi++] = sprintf("u_int32_t, ");
278 p[pi++] = sprintf("%s **, u_int8_t *, ", typedef_name);
280 p[pi++] = sprintf("%s *, u_int8_t *, ", typedef_name);
281 p[pi++] = sprintf("size_t, u_int8_t **));");
282 proto_format(p, CFILE);
284 printf("int\n") >> CFILE;
289 printf("%s(env, ", function_name) >> CFILE;
291 printf("version, ") >> CFILE;
292 printf("%s, bp, ", arg_name) >> CFILE;
293 printf("max, nextp)\n") >> CFILE;
294 printf("\tENV *env;\n") >> CFILE;
296 printf("\tu_int32_t version;\n") >> CFILE;
298 printf("\t%s **argpp;\n", typedef_name) >> CFILE;
300 printf("\t%s *argp;\n", typedef_name) >> CFILE;
301 printf("\tu_int8_t *bp;\n") >> CFILE;
302 printf("\tsize_t max;\n") >> CFILE;
303 printf("\tu_int8_t **nextp;\n") >> CFILE;
304 printf("{\n") >> CFILE;
307 printf("\tsize_t needed;\n") >> CFILE;
311 printf("\t%s *argp;\n", typedef_name) >> CFILE;
312 printf("\tint ret;\n") >> CFILE;
316 printf("\tint copy_only;\n") >> CFILE;
320 printf("\n") >> CFILE;
322 # Check that input byte buffer is long enough.
325 printf("\tneeded = %s;\n", msg_size_name) >> CFILE;
326 printf("\tif (max < needed)\n") >> CFILE;
328 printf("\tif (max < %s)\n", msg_size_name) >> CFILE;
329 printf("\t\tgoto too_few;\n") >> CFILE;
333 "\tif ((ret = __os_malloc(env, sizeof(*argp), &argp)) != 0)\n") \
335 printf("\t\treturn (ret);\n\n") >> CFILE;
338 printf("\tcopy_only = 0;\n") >> CFILE;
339 printf("\tif (version < DB_REPVERSION_47)\n") >> CFILE;
340 printf("\t\tcopy_only = 1;\n") >> CFILE;
343 for (i = 0; i < nvars; i++) {
344 if (types[i] == "u_int32_t" || types[i] == "db_pgno_t") {
346 printf("\tif (copy_only) {\n") >> CFILE;
348 "\t\tmemcpy(&argp->%s, bp, sizeof(u_int32_t));\n", vars[i]) >> CFILE;
350 "\t\tbp += sizeof(u_int32_t);\n") >> CFILE;
351 printf("\t} else\n\t") >> CFILE;
353 printf("\tDB_NTOHL_COPYIN(env, argp->%s, bp);\n", \
355 } else if (types[i] == "u_int16_t") {
357 printf("\tif (copy_only) {\n") >> CFILE;
359 "\t\tmemcpy(&argp->%s, bp, sizeof(u_int16_t));\n", vars[i]) >> CFILE;
361 "\t\tbp += sizeof(u_int16_t);\n") >> CFILE;
362 printf("\t} else\n\t") >> CFILE;
364 printf("\tDB_NTOHS_COPYIN(env, argp->%s, bp);\n", \
366 } else if (types[i] == "DB_LSN") {
368 printf("\tif (copy_only) {\n") >> CFILE;
370 "\t\tmemcpy(&argp->%s.file, bp, sizeof(u_int32_t));\n", vars[i]) >> CFILE;
372 "\t\tbp += sizeof(u_int32_t);\n") >> CFILE;
374 "\t\tmemcpy(&argp->%s.offset, bp, sizeof(u_int32_t));\n", vars[i]) >> CFILE;
376 "\t\tbp += sizeof(u_int32_t);\n") >> CFILE;
377 printf("\t} else {\n\t") >> CFILE;
379 printf("\tDB_NTOHL_COPYIN(env, argp->%s.file, bp);\n", \
382 printf("\t") >> CFILE;
384 "\tDB_NTOHL_COPYIN(env, argp->%s.offset, bp);\n", \
387 printf("\t}\n") >> CFILE;
388 } else if (types[i] == "DBT") {
390 printf("\tif (copy_only) {\n") >> CFILE;
392 "\t\tmemcpy(&argp->%s.size, bp, sizeof(u_int32_t));\n", vars[i]) >> CFILE;
394 "\t\tbp += sizeof(u_int32_t);\n") >> CFILE;
395 printf("\t} else\n\t") >> CFILE;
397 printf("\tDB_NTOHL_COPYIN(env, argp->%s.size, bp);\n", \
399 printf("\targp->%s.data = bp;\n", vars[i]) >> CFILE;
400 printf("\tneeded += (size_t)argp->%s.size;\n", \
402 printf("\tif (max < needed)\n") >> CFILE;
403 printf("\t\tgoto too_few;\n") >> CFILE;
404 printf("\tbp += argp->%s.size;\n", vars[i]) >> CFILE;
406 printf("unknown field type: %s", types[i]);
411 printf("\n\tif (nextp != NULL)\n") >> CFILE;
412 printf("\t\t*nextp = bp;\n") >> CFILE;
414 printf("\t*argpp = argp;\n") >> CFILE;
416 printf("\treturn (0);\n\n") >> CFILE;
418 printf("too_few:\n") >> CFILE;
419 printf("\t__db_errx(env,\n") >> CFILE;
420 printf("\t \"Not enough input bytes to fill a %s message\");\n", \
422 printf("\treturn (EINVAL);\n") >> CFILE;
423 printf("}\n\n") >> CFILE;
427 # Pretty-print a function prototype.
428 function proto_format(p, fp)
430 printf("/*\n") >> fp;
433 for (i = 1; i in p; ++i)
437 if (length(s) + length(t) < 80)
438 printf("%s%s", t, s) >> fp;
441 len = length(t) + length(p[1]);
442 printf("%s%s", t, p[1]) >> fp
444 n = split(p[2], comma, ",");
445 comma[1] = "__P" comma[1];
446 for (i = 1; i <= n; i++) {
447 if (len + length(comma[i]) > 70) {
448 printf("\n * PUBLIC: ") >> fp;
451 printf("%s%s", comma[i], i == n ? "" : ",") >> fp;
452 len += length(comma[i]) + 2;
455 printf("\n */\n") >> fp;