gen_rec.awk
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:15k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. #!/bin/sh -
  2. #
  3. # See the file LICENSE for redistribution information.
  4. #
  5. # Copyright (c) 1996, 1997, 1998, 1999, 2000
  6. # Sleepycat Software.  All rights reserved.
  7. #
  8. # $Id: gen_rec.awk,v 11.26 2001/01/08 21:06:46 bostic Exp $
  9. #
  10. # This awk script generates all the log, print, and read routines for the DB
  11. # logging. It also generates a template for the recovery functions (these
  12. # functions must still be edited, but are highly stylized and the initial
  13. # template gets you a fair way along the path).
  14. #
  15. # For a given file prefix.src, we generate a file prefix_auto.c, and a file
  16. # prefix_auto.h that contains:
  17. #
  18. # external declarations for the file's functions
  19. #  defines for the physical record types
  20. #     (logical types are defined in each subsystem manually)
  21. # structures to contain the data unmarshalled from the log.
  22. #
  23. # This awk script requires that five variables be set when it is called:
  24. #
  25. # source_file -- the C source file being created
  26. # subsystem -- the subsystem prefix, e.g., "db"
  27. # header_file -- the C #include file being created
  28. # template_file -- the template file being created
  29. # template_dir -- the directory to find the source template
  30. #
  31. # And stdin must be the input file that defines the recovery setup.
  32. BEGIN {
  33. if (source_file == "" || subsystem == "" ||
  34.     header_file == "" || template_file == "" || template_dir == "") {
  35.     print "Usage: gen_rec.awk requires five variables to be set:"
  36.     print "tsource_filet-- the C source file being created"
  37.     print "tsubsystemt-- the subsystem prefix, e.g., "db""
  38.     print "theader_filet-- the C #include file being created"
  39.     print "ttemplate_filet-- the template file being created"
  40.     print "ttemplate_dirt-- the directory to find the source template"
  41.     exit
  42. }
  43. FS="[t ][t ]*"
  44. CFILE=source_file
  45. NAME=subsystem
  46. HFILE=header_file
  47. TFILE=template_file
  48. TDIR=template_dir
  49. }
  50. /^[  ]*PREFIX/ {
  51. prefix = $2
  52. num_funcs = 0;
  53. # Start .c file.
  54. printf("/* Do not edit: automatically built by gen_rec.awk. */n") 
  55.     > CFILE
  56. # Start .h file, make the entire file conditional.
  57. printf("/* Do not edit: automatically built by gen_rec.awk. */nn") 
  58.     > HFILE
  59. printf("#ifndeft%s_AUTO_Hn#definet%s_AUTO_Hn", prefix, prefix) 
  60.     >> HFILE;
  61. # Write recovery template file headers
  62. # This assumes we're doing DB recovery.
  63. printf("#include "db_config.h"nn") > TFILE
  64. printf("#ifndef NO_SYSTEM_INCLUDESn") >> TFILE
  65. printf("#include <sys/types.h>nn") >> TFILE
  66. printf("#include <string.h>n") >> TFILE
  67. printf("#endifnn") >> TFILE
  68. printf("#include "db_int.h"n") >> TFILE
  69. printf("#include "db_page.h"n") >> TFILE
  70. printf("#include "%s.h"n", prefix) >> TFILE
  71. printf("#include "log.h"nn") >> TFILE
  72. }
  73. /^[  ]*INCLUDE/ {
  74. if ($3 == "")
  75. printf("%sn", $2) >> CFILE
  76. else
  77. printf("%s %sn", $2, $3) >> CFILE
  78. }
  79. /^[  ]*(BEGIN|DEPRECATED)/ {
  80. if (in_begin) {
  81. print "Invalid format: missing END statement"
  82. exit
  83. }
  84. in_begin = 1;
  85. is_dbt = 0;
  86. is_deprecated = ($1 == "DEPRECATED");
  87. nvars = 0;
  88. thisfunc = $2;
  89. funcname = sprintf("%s_%s", prefix, $2);
  90. rectype = $3;
  91. funcs[num_funcs] = funcname;
  92. funcs_dep[num_funcs] = is_deprecated;
  93. ++num_funcs;
  94. }
  95. /^[  ]*(ARG|DBT|POINTER)/ {
  96. vars[nvars] = $2;
  97. types[nvars] = $3;
  98. atypes[nvars] = $1;
  99. modes[nvars] = $1;
  100. formats[nvars] = $NF;
  101. for (i = 4; i < NF; i++)
  102. types[nvars] = sprintf("%s %s", types[nvars], $i);
  103. if ($1 == "ARG")
  104. sizes[nvars] = sprintf("sizeof(%s)", $2);
  105. else if ($1 == "POINTER")
  106. sizes[nvars] = sprintf("sizeof(*%s)", $2);
  107. else { # DBT
  108. sizes[nvars] = 
  109.     sprintf("sizeof(u_int32_t) + (%s == NULL ? 0 : %s->size)", 
  110.     $2, $2);
  111. is_dbt = 1;
  112. }
  113. nvars++;
  114. }
  115. /^[  ]*END/ {
  116. if (!in_begin) {
  117. print "Invalid format: missing BEGIN statement"
  118. exit;
  119. }
  120. # Declare the record type.
  121. printf("n#definetDB_%st%dn", funcname, rectype) >> HFILE
  122. # Structure declaration.
  123. printf("typedef struct _%s_args {n", funcname) >> HFILE
  124. # Here are the required fields for every structure
  125. printf("tu_int32_t type;ntDB_TXN *txnid;n") >> HFILE
  126. printf("tDB_LSN prev_lsn;n") >>HFILE
  127. # Here are the specified fields.
  128. for (i = 0; i < nvars; i++) {
  129. t = types[i];
  130. if (modes[i] == "POINTER") {
  131. ndx = index(t, "*");
  132. t = substr(types[i], 0, ndx - 2);
  133. }
  134. printf("t%st%s;n", t, vars[i]) >> HFILE
  135. }
  136. printf("} __%s_args;nn", funcname) >> HFILE
  137. # Output the log, print and read functions.
  138. if (!is_deprecated)
  139. log_function();
  140. print_function();
  141. read_function();
  142. # Recovery template
  143. cmd = sprintf("sed -e s/PREF/%s/ -e s/FUNC/%s/ < %s/rec_ctemp >> %s",
  144.     prefix, thisfunc, TDIR, TFILE)
  145. system(cmd);
  146. # Done writing stuff, reset and continue.
  147. in_begin = 0;
  148. }
  149. END {
  150. # Print initialization routine; function prototype
  151. printf("int __%s_init_print __P((DB_ENV *));n", prefix) >> HFILE;
  152. # Create the routine to call db_add_recovery(print_fn, id)
  153. printf("intn__%s_init_print(dbenv)n", prefix) >> CFILE;
  154. printf("tDB_ENV *dbenv;n{ntint ret;nn") >> CFILE;
  155. for (i = 0; i < num_funcs; i++) {
  156. printf("tif ((ret = __db_add_recovery(dbenv,n") >> CFILE;
  157. printf("t    __%s_print, DB_%s)) != 0)n", 
  158.     funcs[i], funcs[i]) >> CFILE;
  159. printf("ttreturn (ret);n") >> CFILE;
  160. }
  161. printf("treturn (0);n}nn") >> CFILE;
  162. # Recover initialization routine
  163. printf("int __%s_init_recover __P((DB_ENV *));n", prefix) >> HFILE;
  164. # Create the routine to call db_add_recovery(func, id)
  165. printf("intn__%s_init_recover(dbenv)n", prefix) >> CFILE;
  166. printf("tDB_ENV *dbenv;n{ntint ret;nn") >> CFILE;
  167. for (i = 0; i < num_funcs; i++) {
  168. printf("tif ((ret = __db_add_recovery(dbenv,n") >> CFILE;
  169. if (funcs_dep[i] == 1)
  170. printf("t    __deprecated_recover, DB_%s)) != 0)n", 
  171.     funcs[i]) >> CFILE;
  172. else
  173. printf("t    __%s_recover, DB_%s)) != 0)n", 
  174.     funcs[i], funcs[i]) >> CFILE;
  175. printf("ttreturn (ret);n") >> CFILE;
  176. }
  177. printf("treturn (0);n}nn") >> CFILE;
  178. # End the conditional for the HFILE
  179. printf("#endifn") >> HFILE;
  180. }
  181. function log_function() {
  182. # Write the log function; function prototype
  183. printf("int __%s_log __P((", funcname) >> HFILE;
  184. printf("DB_ENV *, DB_TXN *, DB_LSN *, u_int32_t") >> HFILE;
  185. for (i = 0; i < nvars; i++) {
  186. printf(", ") >> HFILE;
  187. if (modes[i] == "DBT")
  188. printf("const ") >> HFILE;
  189. printf("%s", types[i]) >> HFILE;
  190. if (modes[i] == "DBT")
  191. printf(" *") >> HFILE;
  192. }
  193. printf("));n") >> HFILE;
  194. # Function declaration
  195. printf("intn__%s_log(dbenv, txnid, ret_lsnp, flags", 
  196.     funcname) >> CFILE;
  197. for (i = 0; i < nvars; i++) {
  198. printf(",") >> CFILE;
  199. if ((i % 6) == 0)
  200. printf("nt") >> CFILE;
  201. else
  202. printf(" ") >> CFILE;
  203. printf("%s", vars[i]) >> CFILE;
  204. }
  205. printf(")n") >> CFILE;
  206. # Now print the parameters
  207. printf("tDB_ENV *dbenv;n") >> CFILE;
  208. printf("tDB_TXN *txnid;ntDB_LSN *ret_lsnp;n") >> CFILE;
  209. printf("tu_int32_t flags;n") >> CFILE;
  210. for (i = 0; i < nvars; i++) {
  211. if (modes[i] == "DBT")
  212. printf("tconst %s *%s;n", types[i], vars[i]) >> CFILE;
  213. else
  214. printf("t%s %s;n", types[i], vars[i]) >> CFILE;
  215. }
  216. # Function body and local decls
  217. printf("{n") >> CFILE;
  218. printf("tDBT logrec;n") >> CFILE;
  219. printf("tDB_LSN *lsnp, null_lsn;n") >> CFILE;
  220. if (is_dbt == 1)
  221. printf("tu_int32_t zero;n") >> CFILE;
  222. printf("tu_int32_t rectype, txn_num;n") >> CFILE;
  223. printf("tint ret;n") >> CFILE;
  224. printf("tu_int8_t *bp;nn") >> CFILE;
  225. # Initialization
  226. printf("trectype = DB_%s;n", funcname) >> CFILE;
  227. printf("tif (txnid != NULL &&n") >> CFILE;
  228. printf("t    TAILQ_FIRST(&txnid->kids) != NULL &&n") >> CFILE;
  229. printf("t    (ret = __txn_activekids(dbenv, rectype, txnid)) != 0)n")
  230.     >> CFILE;
  231. printf("ttreturn (ret);n") >> CFILE;
  232. printf("ttxn_num = txnid == NULL ? 0 : txnid->txnid;n") >> CFILE;
  233. printf("tif (txnid == NULL) {n") >> CFILE;
  234. printf("ttZERO_LSN(null_lsn);n") >> CFILE;
  235. printf("ttlsnp = &null_lsn;n") >> CFILE;
  236. printf("t} elsenttlsnp = &txnid->last_lsn;n") >> CFILE;
  237. # Malloc
  238. printf("tlogrec.size = sizeof(rectype) + ") >> CFILE;
  239. printf("sizeof(txn_num) + sizeof(DB_LSN)") >> CFILE;
  240. for (i = 0; i < nvars; i++)
  241. printf("nt    + %s", sizes[i]) >> CFILE;
  242. printf(";ntif ((ret = ") >> CFILE;
  243. printf(
  244.     "__os_malloc(dbenv, logrec.size, NULL, &logrec.data)) != 0)n")
  245.     >> CFILE;
  246. printf("ttreturn (ret);nn") >> CFILE;
  247. # Copy args into buffer
  248. printf("tbp = logrec.data;n") >> CFILE;
  249. printf("tmemcpy(bp, &rectype, sizeof(rectype));n") >> CFILE;
  250. printf("tbp += sizeof(rectype);n") >> CFILE;
  251. printf("tmemcpy(bp, &txn_num, sizeof(txn_num));n") >> CFILE;
  252. printf("tbp += sizeof(txn_num);n") >> CFILE;
  253. printf("tmemcpy(bp, lsnp, sizeof(DB_LSN));n") >> CFILE;
  254. printf("tbp += sizeof(DB_LSN);n") >> CFILE;
  255. for (i = 0; i < nvars; i ++) {
  256. if (modes[i] == "ARG") {
  257. printf("tmemcpy(bp, &%s, %s);n", 
  258.     vars[i], sizes[i]) >> CFILE;
  259. printf("tbp += %s;n", sizes[i]) >> CFILE;
  260. } else if (modes[i] == "DBT") {
  261. printf("tif (%s == NULL) {n", vars[i]) >> CFILE;
  262. printf("ttzero = 0;n") >> CFILE;
  263. printf("ttmemcpy(bp, &zero, sizeof(u_int32_t));n") 
  264. >> CFILE;
  265. printf("ttbp += sizeof(u_int32_t);n") >> CFILE;
  266. printf("t} else {n") >> CFILE;
  267. printf("ttmemcpy(bp, &%s->size, ", vars[i]) >> CFILE;
  268. printf("sizeof(%s->size));n", vars[i]) >> CFILE;
  269. printf("ttbp += sizeof(%s->size);n", vars[i]) 
  270.     >> CFILE;
  271. printf("ttmemcpy(bp, %s->data, %s->size);n", 
  272.     vars[i], vars[i]) >> CFILE;
  273. printf("ttbp += %s->size;nt}n", vars[i]) >> CFILE;
  274. } else { # POINTER
  275. printf("tif (%s != NULL)n", vars[i]) >> CFILE;
  276. printf("ttmemcpy(bp, %s, %s);n", vars[i], 
  277.     sizes[i]) >> CFILE;
  278. printf("telsen") >> CFILE;
  279. printf("ttmemset(bp, 0, %s);n", sizes[i]) >> CFILE;
  280. printf("tbp += %s;n", sizes[i]) >> CFILE;
  281. }
  282. }
  283. # Error checking
  284. printf("tDB_ASSERT((u_int32_t)") >> CFILE;
  285. printf("(bp - (u_int8_t *)logrec.data) == logrec.size);n") >> CFILE;
  286. # Issue log call
  287. # The logging system cannot call the public log_put routine
  288. # due to mutual exclusion constraints.  So, if we are
  289. # generating code for the log subsystem, use the internal
  290. # __log_put.
  291. if (prefix == "log")
  292. printf("tret = __log_put(dbenv, ret_lsnp, ") >> CFILE;
  293. else
  294. printf("tret = log_put(dbenv, ret_lsnp, ") >> CFILE;
  295. printf("(DBT *)&logrec, flags);n") >> CFILE;
  296. # Update the transactions last_lsn
  297. printf("tif (txnid != NULL)n") >> CFILE;
  298. printf("tttxnid->last_lsn = *ret_lsnp;n") >> CFILE;
  299. # Free and return
  300. printf("t__os_free(logrec.data, logrec.size);n") >> CFILE;
  301. printf("treturn (ret);n}nn") >> CFILE;
  302. }
  303. function print_function() {
  304. # Write the print function; function prototype
  305. printf("int __%s_print", funcname) >> HFILE;
  306. printf(" __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));n") 
  307.     >> HFILE;
  308. # Function declaration
  309. printf("intn__%s_print(dbenv, ", funcname) >> CFILE;
  310. printf("dbtp, lsnp, notused2, notused3)n") >> CFILE;
  311. printf("tDB_ENV *dbenv;n") >> CFILE;
  312. printf("tDBT *dbtp;n") >> CFILE;
  313. printf("tDB_LSN *lsnp;n") >> CFILE;
  314. printf("tdb_recops notused2;ntvoid *notused3;n{n") >> CFILE;
  315. # Locals
  316. printf("t__%s_args *argp;n", funcname) >> CFILE;
  317. printf("tu_int32_t i;ntu_int ch;ntint ret;nn") >> CFILE;
  318. # Get rid of complaints about unused parameters.
  319. printf("ti = 0;ntch = 0;n") >> CFILE;
  320. printf("tnotused2 = DB_TXN_ABORT;ntnotused3 = NULL;nn") >> CFILE;
  321. # Call read routine to initialize structure
  322. printf("tif ((ret = __%s_read(dbenv, dbtp->data, &argp)) != 0)n", 
  323.     funcname) >> CFILE;
  324. printf("ttreturn (ret);n") >> CFILE;
  325. # Print values in every record
  326. printf("tprintf("[%%lu][%%lu]%s: ", funcname) >> CFILE;
  327. printf("rec: %%lu txnid %%lx ") >> CFILE;
  328. printf("prevlsn [%%lu][%%lu]\n",n") >> CFILE;
  329. printf("t    (u_long)lsnp->file,n") >> CFILE;
  330. printf("t    (u_long)lsnp->offset,n") >> CFILE;
  331. printf("t    (u_long)argp->type,n") >> CFILE;
  332. printf("t    (u_long)argp->txnid->txnid,n") >> CFILE;
  333. printf("t    (u_long)argp->prev_lsn.file,n") >> CFILE;
  334. printf("t    (u_long)argp->prev_lsn.offset);n") >> CFILE;
  335. # Now print fields of argp
  336. for (i = 0; i < nvars; i ++) {
  337. printf("tprintf("\t%s: ", vars[i]) >> CFILE;
  338. if (modes[i] == "DBT") {
  339. printf("");n") >> CFILE;
  340. printf("tfor (i = 0; i < ") >> CFILE;
  341. printf("argp->%s.size; i++) {n", vars[i]) >> CFILE;
  342. printf("ttch = ((u_int8_t *)argp->%s.data)[i];n", 
  343.     vars[i]) >> CFILE;
  344. printf("ttif (isprint(ch) || ch == 0xa)n") >> CFILE;
  345. printf("tttputchar(ch);n") >> CFILE;
  346. printf("ttelsen") >> CFILE;
  347. printf("tttprintf("%%#x ", ch);n") >> CFILE;
  348. printf("t}ntprintf("\n");n") >> CFILE;
  349. } else if (types[i] == "DB_LSN *") {
  350. printf("[%%%s][%%%s]\n",n", 
  351.     formats[i], formats[i]) >> CFILE;
  352. printf("t    (u_long)argp->%s.file,", 
  353.     vars[i]) >> CFILE;
  354. printf(" (u_long)argp->%s.offset);n", 
  355.     vars[i]) >> CFILE;
  356. } else {
  357. if (formats[i] == "lx")
  358. printf("0x") >> CFILE;
  359. printf("%%%s\n", ", formats[i]) >> CFILE;
  360. if (formats[i] == "lx" || formats[i] == "lu")
  361. printf("(u_long)") >> CFILE;
  362. if (formats[i] == "ld")
  363. printf("(long)") >> CFILE;
  364. printf("argp->%s);n", vars[i]) >> CFILE;
  365. }
  366. }
  367. printf("tprintf("\n");n") >> CFILE;
  368. printf("t__os_free(argp, 0);n") >> CFILE;
  369. printf("treturn (0);n") >> CFILE;
  370. printf("}nn") >> CFILE;
  371. }
  372. function read_function() {
  373. # Write the read function; function prototype
  374. printf("int __%s_read __P((DB_ENV *, void *, ", funcname) >> HFILE;
  375. printf("__%s_args **));n", funcname) >> HFILE;
  376. # Function declaration
  377. printf("intn__%s_read(dbenv, recbuf, argpp)n", funcname) >> CFILE;
  378. # Now print the parameters
  379. printf("tDB_ENV *dbenv;n") >> CFILE;
  380. printf("tvoid *recbuf;n") >> CFILE;
  381. printf("t__%s_args **argpp;n", funcname) >> CFILE;
  382. # Function body and local decls
  383. printf("{nt__%s_args *argp;n", funcname) >> CFILE;
  384. printf("tu_int8_t *bp;n") >> CFILE;
  385. printf("tint ret;n") >> CFILE;
  386. printf("ntret = __os_malloc(dbenv, sizeof(") >> CFILE;
  387. printf("__%s_args) +nt    sizeof(DB_TXN), NULL, &argp);n", 
  388.     funcname) >> CFILE;
  389. printf("tif (ret != 0)nttreturn (ret);n") >> CFILE;
  390. # Set up the pointers to the txnid and the prev lsn
  391. printf("targp->txnid = (DB_TXN *)&argp[1];n") >> CFILE;
  392. # First get the record type, prev_lsn, and txnid fields.
  393. printf("tbp = recbuf;n") >> CFILE;
  394. printf("tmemcpy(&argp->type, bp, sizeof(argp->type));n") >> CFILE;
  395. printf("tbp += sizeof(argp->type);n") >> CFILE;
  396. printf("tmemcpy(&argp->txnid->txnid,  bp, ") >> CFILE;
  397. printf("sizeof(argp->txnid->txnid));n") >> CFILE;
  398. printf("tbp += sizeof(argp->txnid->txnid);n") >> CFILE;
  399. printf("tmemcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));n") >> CFILE;
  400. printf("tbp += sizeof(DB_LSN);n") >> CFILE;
  401. # Now get rest of data.
  402. for (i = 0; i < nvars; i ++) {
  403. if (modes[i] == "DBT") {
  404. printf("tmemset(&argp->%s, 0, sizeof(argp->%s));n", 
  405.     vars[i], vars[i]) >> CFILE;
  406. printf("tmemcpy(&argp->%s.size, ", vars[i]) >> CFILE;
  407. printf("bp, sizeof(u_int32_t));n") >> CFILE;
  408. printf("tbp += sizeof(u_int32_t);n") >> CFILE;
  409. printf("targp->%s.data = bp;n", vars[i]) >> CFILE;
  410. printf("tbp += argp->%s.size;n", vars[i]) >> CFILE;
  411. } else if (modes[i] == "ARG") {
  412. printf("tmemcpy(&argp->%s, bp, %s%s));n", 
  413.     vars[i], "sizeof(argp->", vars[i]) >> CFILE;
  414. printf("tbp += sizeof(argp->%s);n", vars[i]) >> CFILE;
  415. } else { # POINTER
  416. printf("tmemcpy(&argp->%s, bp, ", vars[i]) >> CFILE;
  417. printf(" sizeof(argp->%s));n", vars[i]) >> CFILE;
  418. printf("tbp += sizeof(argp->%s);n", vars[i]) >> CFILE;
  419. }
  420. }
  421. # Free and return
  422. printf("t*argpp = argp;n") >> CFILE;
  423. printf("treturn (0);n}nn") >> CFILE;
  424. }