gen_rec.awk
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:15k
- #!/bin/sh -
- #
- # See the file LICENSE for redistribution information.
- #
- # Copyright (c) 1996, 1997, 1998, 1999, 2000
- # Sleepycat Software. All rights reserved.
- #
- # $Id: gen_rec.awk,v 11.26 2001/01/08 21:06:46 bostic Exp $
- #
- # This awk script generates all the log, print, and read routines for the DB
- # logging. It also generates a template for the recovery functions (these
- # functions must still be edited, but are highly stylized and the initial
- # template gets you a fair way along the path).
- #
- # For a given file prefix.src, we generate a file prefix_auto.c, and a file
- # prefix_auto.h that contains:
- #
- # external declarations for the file's functions
- # defines for the physical record types
- # (logical types are defined in each subsystem manually)
- # structures to contain the data unmarshalled from the log.
- #
- # This awk script requires that five variables be set when it is called:
- #
- # source_file -- the C source file being created
- # subsystem -- the subsystem prefix, e.g., "db"
- # header_file -- the C #include file being created
- # template_file -- the template file being created
- # template_dir -- the directory to find the source template
- #
- # And stdin must be the input file that defines the recovery setup.
- BEGIN {
- if (source_file == "" || subsystem == "" ||
- header_file == "" || template_file == "" || template_dir == "") {
- print "Usage: gen_rec.awk requires five variables to be set:"
- print "tsource_filet-- the C source file being created"
- print "tsubsystemt-- the subsystem prefix, e.g., "db""
- print "theader_filet-- the C #include file being created"
- print "ttemplate_filet-- the template file being created"
- print "ttemplate_dirt-- the directory to find the source template"
- exit
- }
- FS="[t ][t ]*"
- CFILE=source_file
- NAME=subsystem
- HFILE=header_file
- TFILE=template_file
- TDIR=template_dir
- }
- /^[ ]*PREFIX/ {
- prefix = $2
- num_funcs = 0;
- # Start .c file.
- printf("/* Do not edit: automatically built by gen_rec.awk. */n")
- > CFILE
- # Start .h file, make the entire file conditional.
- printf("/* Do not edit: automatically built by gen_rec.awk. */nn")
- > HFILE
- printf("#ifndeft%s_AUTO_Hn#definet%s_AUTO_Hn", prefix, prefix)
- >> HFILE;
- # Write recovery template file headers
- # This assumes we're doing DB recovery.
- printf("#include "db_config.h"nn") > TFILE
- printf("#ifndef NO_SYSTEM_INCLUDESn") >> TFILE
- printf("#include <sys/types.h>nn") >> TFILE
- printf("#include <string.h>n") >> TFILE
- printf("#endifnn") >> TFILE
- printf("#include "db_int.h"n") >> TFILE
- printf("#include "db_page.h"n") >> TFILE
- printf("#include "%s.h"n", prefix) >> TFILE
- printf("#include "log.h"nn") >> TFILE
- }
- /^[ ]*INCLUDE/ {
- if ($3 == "")
- printf("%sn", $2) >> CFILE
- else
- printf("%s %sn", $2, $3) >> CFILE
- }
- /^[ ]*(BEGIN|DEPRECATED)/ {
- if (in_begin) {
- print "Invalid format: missing END statement"
- exit
- }
- in_begin = 1;
- is_dbt = 0;
- is_deprecated = ($1 == "DEPRECATED");
- nvars = 0;
- thisfunc = $2;
- funcname = sprintf("%s_%s", prefix, $2);
- rectype = $3;
- funcs[num_funcs] = funcname;
- funcs_dep[num_funcs] = is_deprecated;
- ++num_funcs;
- }
- /^[ ]*(ARG|DBT|POINTER)/ {
- vars[nvars] = $2;
- types[nvars] = $3;
- atypes[nvars] = $1;
- modes[nvars] = $1;
- formats[nvars] = $NF;
- for (i = 4; i < NF; i++)
- types[nvars] = sprintf("%s %s", types[nvars], $i);
- if ($1 == "ARG")
- sizes[nvars] = sprintf("sizeof(%s)", $2);
- else if ($1 == "POINTER")
- sizes[nvars] = sprintf("sizeof(*%s)", $2);
- else { # DBT
- sizes[nvars] =
- sprintf("sizeof(u_int32_t) + (%s == NULL ? 0 : %s->size)",
- $2, $2);
- is_dbt = 1;
- }
- nvars++;
- }
- /^[ ]*END/ {
- if (!in_begin) {
- print "Invalid format: missing BEGIN statement"
- exit;
- }
- # Declare the record type.
- printf("n#definetDB_%st%dn", funcname, rectype) >> HFILE
- # Structure declaration.
- printf("typedef struct _%s_args {n", funcname) >> HFILE
- # Here are the required fields for every structure
- printf("tu_int32_t type;ntDB_TXN *txnid;n") >> HFILE
- printf("tDB_LSN prev_lsn;n") >>HFILE
- # Here are the specified fields.
- for (i = 0; i < nvars; i++) {
- t = types[i];
- if (modes[i] == "POINTER") {
- ndx = index(t, "*");
- t = substr(types[i], 0, ndx - 2);
- }
- printf("t%st%s;n", t, vars[i]) >> HFILE
- }
- printf("} __%s_args;nn", funcname) >> HFILE
- # Output the log, print and read functions.
- if (!is_deprecated)
- log_function();
- print_function();
- read_function();
- # Recovery template
- cmd = sprintf("sed -e s/PREF/%s/ -e s/FUNC/%s/ < %s/rec_ctemp >> %s",
- prefix, thisfunc, TDIR, TFILE)
- system(cmd);
- # Done writing stuff, reset and continue.
- in_begin = 0;
- }
- END {
- # Print initialization routine; function prototype
- printf("int __%s_init_print __P((DB_ENV *));n", prefix) >> HFILE;
- # Create the routine to call db_add_recovery(print_fn, id)
- printf("intn__%s_init_print(dbenv)n", prefix) >> CFILE;
- printf("tDB_ENV *dbenv;n{ntint ret;nn") >> CFILE;
- for (i = 0; i < num_funcs; i++) {
- printf("tif ((ret = __db_add_recovery(dbenv,n") >> CFILE;
- printf("t __%s_print, DB_%s)) != 0)n",
- funcs[i], funcs[i]) >> CFILE;
- printf("ttreturn (ret);n") >> CFILE;
- }
- printf("treturn (0);n}nn") >> CFILE;
- # Recover initialization routine
- printf("int __%s_init_recover __P((DB_ENV *));n", prefix) >> HFILE;
- # Create the routine to call db_add_recovery(func, id)
- printf("intn__%s_init_recover(dbenv)n", prefix) >> CFILE;
- printf("tDB_ENV *dbenv;n{ntint ret;nn") >> CFILE;
- for (i = 0; i < num_funcs; i++) {
- printf("tif ((ret = __db_add_recovery(dbenv,n") >> CFILE;
- if (funcs_dep[i] == 1)
- printf("t __deprecated_recover, DB_%s)) != 0)n",
- funcs[i]) >> CFILE;
- else
- printf("t __%s_recover, DB_%s)) != 0)n",
- funcs[i], funcs[i]) >> CFILE;
- printf("ttreturn (ret);n") >> CFILE;
- }
- printf("treturn (0);n}nn") >> CFILE;
- # End the conditional for the HFILE
- printf("#endifn") >> HFILE;
- }
- function log_function() {
- # Write the log function; function prototype
- printf("int __%s_log __P((", funcname) >> HFILE;
- printf("DB_ENV *, DB_TXN *, DB_LSN *, u_int32_t") >> HFILE;
- for (i = 0; i < nvars; i++) {
- printf(", ") >> HFILE;
- if (modes[i] == "DBT")
- printf("const ") >> HFILE;
- printf("%s", types[i]) >> HFILE;
- if (modes[i] == "DBT")
- printf(" *") >> HFILE;
- }
- printf("));n") >> HFILE;
- # Function declaration
- printf("intn__%s_log(dbenv, txnid, ret_lsnp, flags",
- funcname) >> CFILE;
- for (i = 0; i < nvars; i++) {
- printf(",") >> CFILE;
- if ((i % 6) == 0)
- printf("nt") >> CFILE;
- else
- printf(" ") >> CFILE;
- printf("%s", vars[i]) >> CFILE;
- }
- printf(")n") >> CFILE;
- # Now print the parameters
- printf("tDB_ENV *dbenv;n") >> CFILE;
- printf("tDB_TXN *txnid;ntDB_LSN *ret_lsnp;n") >> CFILE;
- printf("tu_int32_t flags;n") >> CFILE;
- for (i = 0; i < nvars; i++) {
- if (modes[i] == "DBT")
- printf("tconst %s *%s;n", types[i], vars[i]) >> CFILE;
- else
- printf("t%s %s;n", types[i], vars[i]) >> CFILE;
- }
- # Function body and local decls
- printf("{n") >> CFILE;
- printf("tDBT logrec;n") >> CFILE;
- printf("tDB_LSN *lsnp, null_lsn;n") >> CFILE;
- if (is_dbt == 1)
- printf("tu_int32_t zero;n") >> CFILE;
- printf("tu_int32_t rectype, txn_num;n") >> CFILE;
- printf("tint ret;n") >> CFILE;
- printf("tu_int8_t *bp;nn") >> CFILE;
- # Initialization
- printf("trectype = DB_%s;n", funcname) >> CFILE;
- printf("tif (txnid != NULL &&n") >> CFILE;
- printf("t TAILQ_FIRST(&txnid->kids) != NULL &&n") >> CFILE;
- printf("t (ret = __txn_activekids(dbenv, rectype, txnid)) != 0)n")
- >> CFILE;
- printf("ttreturn (ret);n") >> CFILE;
- printf("ttxn_num = txnid == NULL ? 0 : txnid->txnid;n") >> CFILE;
- printf("tif (txnid == NULL) {n") >> CFILE;
- printf("ttZERO_LSN(null_lsn);n") >> CFILE;
- printf("ttlsnp = &null_lsn;n") >> CFILE;
- printf("t} elsenttlsnp = &txnid->last_lsn;n") >> CFILE;
- # Malloc
- printf("tlogrec.size = sizeof(rectype) + ") >> CFILE;
- printf("sizeof(txn_num) + sizeof(DB_LSN)") >> CFILE;
- for (i = 0; i < nvars; i++)
- printf("nt + %s", sizes[i]) >> CFILE;
- printf(";ntif ((ret = ") >> CFILE;
- printf(
- "__os_malloc(dbenv, logrec.size, NULL, &logrec.data)) != 0)n")
- >> CFILE;
- printf("ttreturn (ret);nn") >> CFILE;
- # Copy args into buffer
- printf("tbp = logrec.data;n") >> CFILE;
- printf("tmemcpy(bp, &rectype, sizeof(rectype));n") >> CFILE;
- printf("tbp += sizeof(rectype);n") >> CFILE;
- printf("tmemcpy(bp, &txn_num, sizeof(txn_num));n") >> CFILE;
- printf("tbp += sizeof(txn_num);n") >> CFILE;
- printf("tmemcpy(bp, lsnp, sizeof(DB_LSN));n") >> CFILE;
- printf("tbp += sizeof(DB_LSN);n") >> CFILE;
- for (i = 0; i < nvars; i ++) {
- if (modes[i] == "ARG") {
- printf("tmemcpy(bp, &%s, %s);n",
- vars[i], sizes[i]) >> CFILE;
- printf("tbp += %s;n", sizes[i]) >> CFILE;
- } else if (modes[i] == "DBT") {
- printf("tif (%s == NULL) {n", vars[i]) >> CFILE;
- printf("ttzero = 0;n") >> CFILE;
- printf("ttmemcpy(bp, &zero, sizeof(u_int32_t));n")
- >> CFILE;
- printf("ttbp += sizeof(u_int32_t);n") >> CFILE;
- printf("t} else {n") >> CFILE;
- printf("ttmemcpy(bp, &%s->size, ", vars[i]) >> CFILE;
- printf("sizeof(%s->size));n", vars[i]) >> CFILE;
- printf("ttbp += sizeof(%s->size);n", vars[i])
- >> CFILE;
- printf("ttmemcpy(bp, %s->data, %s->size);n",
- vars[i], vars[i]) >> CFILE;
- printf("ttbp += %s->size;nt}n", vars[i]) >> CFILE;
- } else { # POINTER
- printf("tif (%s != NULL)n", vars[i]) >> CFILE;
- printf("ttmemcpy(bp, %s, %s);n", vars[i],
- sizes[i]) >> CFILE;
- printf("telsen") >> CFILE;
- printf("ttmemset(bp, 0, %s);n", sizes[i]) >> CFILE;
- printf("tbp += %s;n", sizes[i]) >> CFILE;
- }
- }
- # Error checking
- printf("tDB_ASSERT((u_int32_t)") >> CFILE;
- printf("(bp - (u_int8_t *)logrec.data) == logrec.size);n") >> CFILE;
- # Issue log call
- # The logging system cannot call the public log_put routine
- # due to mutual exclusion constraints. So, if we are
- # generating code for the log subsystem, use the internal
- # __log_put.
- if (prefix == "log")
- printf("tret = __log_put(dbenv, ret_lsnp, ") >> CFILE;
- else
- printf("tret = log_put(dbenv, ret_lsnp, ") >> CFILE;
- printf("(DBT *)&logrec, flags);n") >> CFILE;
- # Update the transactions last_lsn
- printf("tif (txnid != NULL)n") >> CFILE;
- printf("tttxnid->last_lsn = *ret_lsnp;n") >> CFILE;
- # Free and return
- printf("t__os_free(logrec.data, logrec.size);n") >> CFILE;
- printf("treturn (ret);n}nn") >> CFILE;
- }
- function print_function() {
- # Write the print function; function prototype
- printf("int __%s_print", funcname) >> HFILE;
- printf(" __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));n")
- >> HFILE;
- # Function declaration
- printf("intn__%s_print(dbenv, ", funcname) >> CFILE;
- printf("dbtp, lsnp, notused2, notused3)n") >> CFILE;
- printf("tDB_ENV *dbenv;n") >> CFILE;
- printf("tDBT *dbtp;n") >> CFILE;
- printf("tDB_LSN *lsnp;n") >> CFILE;
- printf("tdb_recops notused2;ntvoid *notused3;n{n") >> CFILE;
- # Locals
- printf("t__%s_args *argp;n", funcname) >> CFILE;
- printf("tu_int32_t i;ntu_int ch;ntint ret;nn") >> CFILE;
- # Get rid of complaints about unused parameters.
- printf("ti = 0;ntch = 0;n") >> CFILE;
- printf("tnotused2 = DB_TXN_ABORT;ntnotused3 = NULL;nn") >> CFILE;
- # Call read routine to initialize structure
- printf("tif ((ret = __%s_read(dbenv, dbtp->data, &argp)) != 0)n",
- funcname) >> CFILE;
- printf("ttreturn (ret);n") >> CFILE;
- # Print values in every record
- printf("tprintf("[%%lu][%%lu]%s: ", funcname) >> CFILE;
- printf("rec: %%lu txnid %%lx ") >> CFILE;
- printf("prevlsn [%%lu][%%lu]\n",n") >> CFILE;
- printf("t (u_long)lsnp->file,n") >> CFILE;
- printf("t (u_long)lsnp->offset,n") >> CFILE;
- printf("t (u_long)argp->type,n") >> CFILE;
- printf("t (u_long)argp->txnid->txnid,n") >> CFILE;
- printf("t (u_long)argp->prev_lsn.file,n") >> CFILE;
- printf("t (u_long)argp->prev_lsn.offset);n") >> CFILE;
- # Now print fields of argp
- for (i = 0; i < nvars; i ++) {
- printf("tprintf("\t%s: ", vars[i]) >> CFILE;
- if (modes[i] == "DBT") {
- printf("");n") >> CFILE;
- printf("tfor (i = 0; i < ") >> CFILE;
- printf("argp->%s.size; i++) {n", vars[i]) >> CFILE;
- printf("ttch = ((u_int8_t *)argp->%s.data)[i];n",
- vars[i]) >> CFILE;
- printf("ttif (isprint(ch) || ch == 0xa)n") >> CFILE;
- printf("tttputchar(ch);n") >> CFILE;
- printf("ttelsen") >> CFILE;
- printf("tttprintf("%%#x ", ch);n") >> CFILE;
- printf("t}ntprintf("\n");n") >> CFILE;
- } else if (types[i] == "DB_LSN *") {
- printf("[%%%s][%%%s]\n",n",
- formats[i], formats[i]) >> CFILE;
- printf("t (u_long)argp->%s.file,",
- vars[i]) >> CFILE;
- printf(" (u_long)argp->%s.offset);n",
- vars[i]) >> CFILE;
- } else {
- if (formats[i] == "lx")
- printf("0x") >> CFILE;
- printf("%%%s\n", ", formats[i]) >> CFILE;
- if (formats[i] == "lx" || formats[i] == "lu")
- printf("(u_long)") >> CFILE;
- if (formats[i] == "ld")
- printf("(long)") >> CFILE;
- printf("argp->%s);n", vars[i]) >> CFILE;
- }
- }
- printf("tprintf("\n");n") >> CFILE;
- printf("t__os_free(argp, 0);n") >> CFILE;
- printf("treturn (0);n") >> CFILE;
- printf("}nn") >> CFILE;
- }
- function read_function() {
- # Write the read function; function prototype
- printf("int __%s_read __P((DB_ENV *, void *, ", funcname) >> HFILE;
- printf("__%s_args **));n", funcname) >> HFILE;
- # Function declaration
- printf("intn__%s_read(dbenv, recbuf, argpp)n", funcname) >> CFILE;
- # Now print the parameters
- printf("tDB_ENV *dbenv;n") >> CFILE;
- printf("tvoid *recbuf;n") >> CFILE;
- printf("t__%s_args **argpp;n", funcname) >> CFILE;
- # Function body and local decls
- printf("{nt__%s_args *argp;n", funcname) >> CFILE;
- printf("tu_int8_t *bp;n") >> CFILE;
- printf("tint ret;n") >> CFILE;
- printf("ntret = __os_malloc(dbenv, sizeof(") >> CFILE;
- printf("__%s_args) +nt sizeof(DB_TXN), NULL, &argp);n",
- funcname) >> CFILE;
- printf("tif (ret != 0)nttreturn (ret);n") >> CFILE;
- # Set up the pointers to the txnid and the prev lsn
- printf("targp->txnid = (DB_TXN *)&argp[1];n") >> CFILE;
- # First get the record type, prev_lsn, and txnid fields.
- printf("tbp = recbuf;n") >> CFILE;
- printf("tmemcpy(&argp->type, bp, sizeof(argp->type));n") >> CFILE;
- printf("tbp += sizeof(argp->type);n") >> CFILE;
- printf("tmemcpy(&argp->txnid->txnid, bp, ") >> CFILE;
- printf("sizeof(argp->txnid->txnid));n") >> CFILE;
- printf("tbp += sizeof(argp->txnid->txnid);n") >> CFILE;
- printf("tmemcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));n") >> CFILE;
- printf("tbp += sizeof(DB_LSN);n") >> CFILE;
- # Now get rest of data.
- for (i = 0; i < nvars; i ++) {
- if (modes[i] == "DBT") {
- printf("tmemset(&argp->%s, 0, sizeof(argp->%s));n",
- vars[i], vars[i]) >> CFILE;
- printf("tmemcpy(&argp->%s.size, ", vars[i]) >> CFILE;
- printf("bp, sizeof(u_int32_t));n") >> CFILE;
- printf("tbp += sizeof(u_int32_t);n") >> CFILE;
- printf("targp->%s.data = bp;n", vars[i]) >> CFILE;
- printf("tbp += argp->%s.size;n", vars[i]) >> CFILE;
- } else if (modes[i] == "ARG") {
- printf("tmemcpy(&argp->%s, bp, %s%s));n",
- vars[i], "sizeof(argp->", vars[i]) >> CFILE;
- printf("tbp += sizeof(argp->%s);n", vars[i]) >> CFILE;
- } else { # POINTER
- printf("tmemcpy(&argp->%s, bp, ", vars[i]) >> CFILE;
- printf(" sizeof(argp->%s));n", vars[i]) >> CFILE;
- printf("tbp += sizeof(argp->%s);n", vars[i]) >> CFILE;
- }
- }
- # Free and return
- printf("t*argpp = argp;n") >> CFILE;
- printf("treturn (0);n}nn") >> CFILE;
- }