Mercurial > hg > openjdk > jigsaw > bdb
view dist/gen_msg.awk @ 0:a1985f14b030
Initial load
author | chegar |
---|---|
date | Fri, 11 May 2012 10:42:02 +0100 |
parents | |
children |
line wrap: on
line source
# # See the file LICENSE for redistribution information. # # Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 only, as # published by the Free Software Foundation. Oracle designates this # particular file as subject to the "Classpath" exception as provided # by Oracle in the LICENSE file that accompanied this code. # # This code is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # version 2 for more details (a copy is included in the LICENSE file that # accompanied this code). # # You should have received a copy of the GNU General Public License version # 2 along with this work; if not, write to the Free Software Foundation, # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. # # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA # or visit www.oracle.com if you need additional information or have any # questions. # # $Id$ # BEGIN { if (source_file == "" || header_file == "") { print "Usage: gen_msg.awk requires these variables to be set:"; print "\theader_file\t-- the message #include file being created"; print "\tsource_file\t-- the message source file being created"; exit; } CFILE=source_file; HFILE=header_file; maxmsg = 0; } /^[ ]*PREFIX/ { prefix = $2; # Start .c files. printf("/* Do not edit: automatically built by gen_msg.awk.\n *\n") \ > CFILE printf(" * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.")\ >> CFILE printf(" *\n */\n\n") >> CFILE printf("#include \"db_config.h\"\n\n") >> CFILE # Start .h file, make the entire file conditional. printf("/* Do not edit: automatically built by gen_msg.awk.\n *\n") \ > HFILE printf(" * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.")\ >> HFILE printf(" *\n */\n\n") >> HFILE printf("#ifndef\t%s_AUTOMSG_H\n#define\t%s_AUTOMSG_H\n\n", prefix, prefix) \ >> HFILE; printf("/*\n") >> HFILE; printf(" * Message sizes are simply the sum of field sizes (not\n") \ >> HFILE; printf(" * counting variable size parts, when DBTs are present),\n") \ >> HFILE; printf(" * and may be different from struct sizes due to padding.\n") \ >> HFILE; printf(" */\n") >> HFILE; } /^[ ]*INCLUDE/ { for (i = 2; i < NF; i++) printf("%s ", $i) >> CFILE; printf("%s\n", $i) >> CFILE; } /^[ ]*BEGIN_MSG/ { if (in_begin) { print "Invalid format: missing END statement"; exit; } in_begin = 1; nvars = 0; thismsg = $2; for (i = 2; i<= NF; i++) { if ($i == "alloc") alloc = 1; else if ($i == "check_length") check_length = 1; else if ($i == "version") version = 1; } base_name = sprintf("%s_%s", prefix, thismsg); typedef_name = sprintf("%s_args", base_name); msg_size_name = toupper(sprintf("%s_SIZE", base_name)); max_name = toupper(sprintf("%s_MAXMSG_SIZE", prefix)); } /^[ ]*ARG/ { vars[nvars] = $2; types[nvars] = $3; if (types[nvars] == "DBT") has_dbt = 1; nvars++; } /^[ ]*END/ { if (!in_begin) { print "Invalid format: missing BEGIN statement"; exit; } if (nvars == 0) { printf("%s needs at least one field\n", thismsg); exit; } sum = 0; for (i = 0; i < nvars; i++) sum += type_length(types[i]); printf("#define\t%s\t%d\n", msg_size_name, sum) >> HFILE; if (sum > maxmsg) maxmsg = sum; printf("typedef struct _%s {\n", typedef_name) >> HFILE; for (i = 0; i < nvars; i++) { if (types[i] == "DB_LSN" || types[i] == "DBT") printf("\t%s\t\t%s;\n", types[i], vars[i]) >> HFILE; else printf("\t%s\t%s;\n", types[i], vars[i]) >> HFILE; } printf("} %s;\n\n", typedef_name) >> HFILE; emit_marshal(); emit_unmarshal(); # Reinitialize variables for next time. in_begin = 0; alloc = 0; check_length = 0; version = 0; has_dbt = 0; } END { # End the conditional for the HFILE printf("#define\t%s\t%d\n", max_name, maxmsg) >> HFILE; printf("#endif\n") >> HFILE; } # Length of fixed part of message. Does not count variable-length data portion # of DBT. # function type_length(type) { if (type == "DB_LSN") return (8); if (type == "DBT" || type == "u_int32_t" || type == "db_pgno_t") return (4); if (type == "u_int16_t") return (2); if (type == "u_int8_t") return (1); printf("unknown field type: %s", type); exit(1); } function emit_marshal() { pi = 1; if (check_length) p[pi++] = "int "; else p[pi++] = "void "; function_name = sprintf("%s_marshal", base_name); p[pi++] = function_name; p[pi++] = " __P((ENV *, "; if (version) p[pi++] = "u_int32_t, "; p[pi++] = sprintf("%s *, u_int8_t *", typedef_name); if (check_length) p[pi++] = ", size_t, size_t *"; p[pi++] = "));"; proto_format(p, CFILE); if (check_length) printf("int\n") >> CFILE; else printf("void\n") >> CFILE; printf("%s(env", function_name) >> CFILE; if (version) printf(", version") >> CFILE; printf(", argp, bp") >> CFILE; if (check_length) printf(", max, lenp") >> CFILE; printf(")\n") >> CFILE; printf("\tENV *env;\n") >> CFILE; if (version) printf("\tu_int32_t version;\n") >> CFILE; printf("\t%s *argp;\n", typedef_name) >> CFILE; printf("\tu_int8_t *bp;\n") >> CFILE; if (check_length) printf("\tsize_t *lenp, max;\n") >> CFILE; printf("{\n") >> CFILE; if (version) printf("\tint copy_only;\n") >> CFILE; if (check_length) { printf("\tu_int8_t *start;\n\n") >> CFILE; printf("\tif (max < %s", msg_size_name) >> CFILE; for (i = 0; i < nvars; i++) if (types[i] == "DBT") printf("\n\t + (size_t)argp->%s.size", \ vars[i]) >> CFILE; # add in dbt sizes printf(")\n") >> CFILE; printf("\t\treturn (ENOMEM);\n") >> CFILE; printf("\tstart = bp;\n\n") >> CFILE; } if (version) { printf("\tcopy_only = 0;\n") >> CFILE; printf("\tif (version < DB_REPVERSION_47)\n") >> CFILE; printf("\t\tcopy_only = 1;\n") >> CFILE; } for (i = 0; i < nvars; i++) { if (types[i] == "u_int32_t" || types[i] == "db_pgno_t") { if (version) { printf("\tif (copy_only) {\n") >> CFILE; printf(\ "\t\tmemcpy(bp, &argp->%s, sizeof(u_int32_t));\n", vars[i]) >> CFILE; printf(\ "\t\tbp += sizeof(u_int32_t);\n") >> CFILE; printf("\t} else\n\t") >> CFILE; } printf("\tDB_HTONL_COPYOUT(env, bp, argp->%s);\n", \ vars[i]) >> CFILE; } else if (types[i] == "u_int16_t") { if (version) { printf("\tif (copy_only) {\n") >> CFILE; printf(\ "\t\tmemcpy(bp, &argp->%s, sizeof(u_int16_t));\n", vars[i]) >> CFILE; printf(\ "\t\tbp += sizeof(u_int16_t);\n") >> CFILE; printf("\t} else\n\t") >> CFILE; } printf("\tDB_HTONS_COPYOUT(env, bp, argp->%s);\n", \ vars[i]) >> CFILE; } else if (types[i] == "u_int8_t") { printf(\ "\t*bp++ = argp->%s;\n", vars[i]) >> CFILE; } else if (types[i] == "DB_LSN") { if (version) { printf("\tif (copy_only) {\n") >> CFILE; printf(\ "\t\tmemcpy(bp, &argp->%s.file, sizeof(u_int32_t));\n", vars[i]) >> CFILE; printf(\ "\t\tbp += sizeof(u_int32_t);\n") >> CFILE; printf(\ "\t\tmemcpy(bp, &argp->%s.offset, sizeof(u_int32_t));\n", vars[i]) >> CFILE; printf(\ "\t\tbp += sizeof(u_int32_t);\n") >> CFILE; printf("\t} else {\n\t") >> CFILE; } printf("\tDB_HTONL_COPYOUT(env, bp, argp->%s.file);\n",\ vars[i]) >> CFILE; if (version) printf("\t") >> CFILE; printf( \ "\tDB_HTONL_COPYOUT(env, bp, argp->%s.offset);\n", \ vars[i]) >> CFILE; if (version) printf("\t}\n") >> CFILE; } else if (types[i] == "DBT") { if (version) { printf("\tif (copy_only) {\n") >> CFILE; printf(\ "\t\tmemcpy(bp, &argp->%s.size, sizeof(u_int32_t));\n", vars[i]) >> CFILE; printf(\ "\t\tbp += sizeof(u_int32_t);\n") >> CFILE; printf("\t} else\n\t") >> CFILE; } printf("\tDB_HTONL_COPYOUT(env, bp, argp->%s.size);\n",\ vars[i]) >> CFILE; printf("\tif (argp->%s.size > 0) {\n", vars[i]) \ >> CFILE; printf( \ "\t\tmemcpy(bp, argp->%s.data, argp->%s.size);\n", \ vars[i], vars[i]) >> CFILE; printf("\t\tbp += argp->%s.size;\n", vars[i]) >> CFILE; printf("\t}\n") >> CFILE; } else { printf("unknown field type: %s", types[i]); exit(1); } } if (check_length) { printf("\n\t*lenp = (size_t)(bp - start);\n") >> CFILE; printf("\treturn (0);\n") >> CFILE; } printf("}\n\n") >> CFILE; } function emit_unmarshal() { pi = 1; p[pi++] = "int "; function_name = sprintf("%s_unmarshal", base_name); p[pi++] = function_name; p[pi++] = " __P((ENV *, "; if (version) p[pi++] = sprintf("u_int32_t, "); if (alloc) p[pi++] = sprintf("%s **, u_int8_t *, ", typedef_name); else p[pi++] = sprintf("%s *, u_int8_t *, ", typedef_name); p[pi++] = sprintf("size_t, u_int8_t **));"); proto_format(p, CFILE); printf("int\n") >> CFILE; if (alloc) arg_name = "argpp"; else arg_name = "argp"; printf("%s(env, ", function_name) >> CFILE; if (version) printf("version, ") >> CFILE; printf("%s, bp, ", arg_name) >> CFILE; printf("max, nextp)\n") >> CFILE; printf("\tENV *env;\n") >> CFILE; if (version) printf("\tu_int32_t version;\n") >> CFILE; if (alloc) printf("\t%s **argpp;\n", typedef_name) >> CFILE; else printf("\t%s *argp;\n", typedef_name) >> CFILE; printf("\tu_int8_t *bp;\n") >> CFILE; printf("\tsize_t max;\n") >> CFILE; printf("\tu_int8_t **nextp;\n") >> CFILE; printf("{\n") >> CFILE; has_locals = 0; if (has_dbt) { printf("\tsize_t needed;\n") >> CFILE; has_locals = 1; } if (alloc) { printf("\t%s *argp;\n", typedef_name) >> CFILE; printf("\tint ret;\n") >> CFILE; has_locals = 1; } if (version) { printf("\tint copy_only;\n") >> CFILE; has_locals = 1; } if (has_locals) printf("\n") >> CFILE; # Check that input byte buffer is long enough. # if (has_dbt) { printf("\tneeded = %s;\n", msg_size_name) >> CFILE; printf("\tif (max < needed)\n") >> CFILE; } else printf("\tif (max < %s)\n", msg_size_name) >> CFILE; printf("\t\tgoto too_few;\n") >> CFILE; if (alloc) { printf( \ "\tif ((ret = __os_malloc(env, sizeof(*argp), &argp)) != 0)\n") \ >> CFILE; printf("\t\treturn (ret);\n\n") >> CFILE; } if (version) { printf("\tcopy_only = 0;\n") >> CFILE; printf("\tif (version < DB_REPVERSION_47)\n") >> CFILE; printf("\t\tcopy_only = 1;\n") >> CFILE; } for (i = 0; i < nvars; i++) { if (types[i] == "u_int32_t" || types[i] == "db_pgno_t") { if (version) { printf("\tif (copy_only) {\n") >> CFILE; printf(\ "\t\tmemcpy(&argp->%s, bp, sizeof(u_int32_t));\n", vars[i]) >> CFILE; printf(\ "\t\tbp += sizeof(u_int32_t);\n") >> CFILE; printf("\t} else\n\t") >> CFILE; } printf("\tDB_NTOHL_COPYIN(env, argp->%s, bp);\n", \ vars[i]) >> CFILE; } else if (types[i] == "u_int16_t") { if (version) { printf("\tif (copy_only) {\n") >> CFILE; printf(\ "\t\tmemcpy(&argp->%s, bp, sizeof(u_int16_t));\n", vars[i]) >> CFILE; printf(\ "\t\tbp += sizeof(u_int16_t);\n") >> CFILE; printf("\t} else\n\t") >> CFILE; } printf("\tDB_NTOHS_COPYIN(env, argp->%s, bp);\n", \ vars[i]) >> CFILE; } else if (types[i] == "u_int8_t") { printf(\ "\targp->%s = *bp++;\n", vars[i]) >> CFILE; } else if (types[i] == "DB_LSN") { if (version) { printf("\tif (copy_only) {\n") >> CFILE; printf(\ "\t\tmemcpy(&argp->%s.file, bp, sizeof(u_int32_t));\n", vars[i]) >> CFILE; printf(\ "\t\tbp += sizeof(u_int32_t);\n") >> CFILE; printf(\ "\t\tmemcpy(&argp->%s.offset, bp, sizeof(u_int32_t));\n", vars[i]) >> CFILE; printf(\ "\t\tbp += sizeof(u_int32_t);\n") >> CFILE; printf("\t} else {\n\t") >> CFILE; } printf("\tDB_NTOHL_COPYIN(env, argp->%s.file, bp);\n", \ vars[i]) >> CFILE; if (version) printf("\t") >> CFILE; printf( \ "\tDB_NTOHL_COPYIN(env, argp->%s.offset, bp);\n", \ vars[i]) >> CFILE; if (version) printf("\t}\n") >> CFILE; } else if (types[i] == "DBT") { if (version) { printf("\tif (copy_only) {\n") >> CFILE; printf(\ "\t\tmemcpy(&argp->%s.size, bp, sizeof(u_int32_t));\n", vars[i]) >> CFILE; printf(\ "\t\tbp += sizeof(u_int32_t);\n") >> CFILE; printf("\t} else\n\t") >> CFILE; } printf("\tDB_NTOHL_COPYIN(env, argp->%s.size, bp);\n", \ vars[i]) >> CFILE; printf("\tif (argp->%s.size == 0)\n", vars[i]) >> CFILE; printf("\t\targp->%s.data = NULL;\n", vars[i]) >> CFILE; printf("\telse\n") >> CFILE; printf("\t\targp->%s.data = bp;\n", vars[i]) >> CFILE; printf("\tneeded += (size_t)argp->%s.size;\n", \ vars[i]) >> CFILE; printf("\tif (max < needed)\n") >> CFILE; printf("\t\tgoto too_few;\n") >> CFILE; printf("\tbp += argp->%s.size;\n", vars[i]) >> CFILE; } else { printf("unknown field type: %s", types[i]); exit(1); } } printf("\n\tif (nextp != NULL)\n") >> CFILE; printf("\t\t*nextp = bp;\n") >> CFILE; if (alloc) { printf("\t*argpp = argp;\n") >> CFILE; } printf("\treturn (0);\n\n") >> CFILE; printf("too_few:\n") >> CFILE; printf("\t__db_errx(env, DB_STR(\"3675\",\n") >> CFILE; printf("\t \"Not enough input bytes to fill a %s message\"));\n", \ base_name) >> CFILE; printf("\treturn (EINVAL);\n") >> CFILE; printf("}\n\n") >> CFILE; } # proto_format -- # Pretty-print a function prototype. function proto_format(p, fp) { printf("/*\n") >> fp; s = ""; for (i = 1; i in p; ++i) s = s p[i]; t = " * PUBLIC: " if (length(s) + length(t) < 80) printf("%s%s", t, s) >> fp; else { split(s, p, "__P"); len = length(t) + length(p[1]); printf("%s%s", t, p[1]) >> fp n = split(p[2], comma, ","); comma[1] = "__P" comma[1]; for (i = 1; i <= n; i++) { if (len + length(comma[i]) > 70) { printf("\n * PUBLIC: ") >> fp; len = 0; } printf("%s%s", comma[i], i == n ? "" : ",") >> fp; len += length(comma[i]) + 2; } } printf("\n */\n") >> fp; delete p; }