2007-11-29 14:18:54 +00:00
/* -*- mode: C; c-basic-offset: 4 -*- */
2008-01-24 15:10:32 +00:00
# ident "Copyright (c) 2007, 2008 Tokutek Inc. All rights reserved."
2007-11-29 14:18:54 +00:00
2007-11-22 05:09:29 +00:00
/* This file defines the logformat in an executable fashion.
* This code is used to generate
* The code that writes into the log .
* The code that reads the log and prints it to stdout ( the log_print utility )
* The code that reads the log for recovery .
* The struct definitions .
* The Latex documentation .
*/
2008-02-08 03:17:38 +00:00
# include "toku_assert.h"
2007-11-27 10:48:31 +00:00
# include <ctype.h>
2007-11-22 06:13:26 +00:00
# include <stdarg.h>
2007-11-22 07:13:08 +00:00
# include <stdio.h>
2008-01-18 21:28:27 +00:00
# include <stdlib.h>
2007-11-27 10:48:31 +00:00
# include <string.h>
2007-11-22 07:13:08 +00:00
# include <sys/stat.h>
# include <sys/types.h>
# include <unistd.h>
2007-11-22 05:09:29 +00:00
typedef struct field {
char * type ;
char * name ;
2007-11-27 10:48:31 +00:00
char * format ; // optional format string
2007-11-22 05:09:29 +00:00
} F ;
2007-11-27 10:48:31 +00:00
# define NULLFIELD {0,0,0}
2007-11-22 05:09:29 +00:00
# define FA (F[])
struct logtype {
char * name ;
char command ;
struct field * fields ;
} ;
// In the fields, don't mention the command, the LSN, the CRC or the trailing LEN.
2007-11-23 02:51:45 +00:00
int logformat_version_number = 0 ;
2007-11-22 05:09:29 +00:00
const struct logtype logtypes [ ] = {
2007-11-27 10:48:31 +00:00
{ " commit " , ' C ' , FA { { " TXNID " , " txnid " , 0 } , NULLFIELD } } ,
{ " delete " , ' D ' , FA { { " FILENUM " , " filenum " , 0 } ,
{ " DISKOFF " , " diskoff " , 0 } ,
{ " BYTESTRING " , " key " , 0 } ,
{ " BYTESTRING " , " data " , 0 } ,
2007-11-22 05:09:29 +00:00
NULLFIELD } } ,
2007-11-27 10:48:31 +00:00
{ " fcreate " , ' F ' , FA { { " TXNID " , " txnid " , 0 } ,
{ " BYTESTRING " , " fname " , 0 } ,
{ " u_int32_t " , " mode " , " 0%o " } ,
2007-11-22 21:11:21 +00:00
NULLFIELD } } ,
2007-11-27 10:48:31 +00:00
{ " fheader " , ' H ' , FA { { " TXNID " , " txnid " , 0 } ,
{ " FILENUM " , " filenum " , 0 } ,
{ " LOGGEDBRTHEADER " , " header " , 0 } ,
2007-11-23 17:16:26 +00:00
NULLFIELD } } ,
2008-02-08 19:54:00 +00:00
{ " newbrtnode " , ' N ' , FA { { " FILENUM " , " filenum " , 0 } ,
2007-11-27 10:48:31 +00:00
{ " DISKOFF " , " diskoff " , 0 } ,
{ " u_int32_t " , " height " , 0 } ,
{ " u_int32_t " , " nodesize " , 0 } ,
{ " u_int8_t " , " is_dup_sort " , 0 } ,
2008-01-23 18:06:23 +00:00
{ " u_int32_t " , " rand4fingerprint " , " %08x " } ,
2007-11-23 17:16:26 +00:00
NULLFIELD } } ,
2008-02-08 19:54:00 +00:00
{ " changechildfingerprint " , ' f ' , FA { { " FILENUM " , " filenum " , 0 } ,
2008-01-23 18:06:23 +00:00
{ " DISKOFF " , " diskoff " , 0 } ,
{ " u_int32_t " , " childnum " , 0 } ,
{ " u_int32_t " , " oldfingerprint " , " %08x " } ,
{ " u_int32_t " , " newfingerprint " , " %08x " } ,
NULLFIELD } } ,
2008-02-08 19:54:00 +00:00
{ " changeunnamedroot " , ' u ' , FA { { " FILENUM " , " filenum " , 0 } ,
{ " DISKOFF " , " oldroot " , 0 } ,
{ " DISKOFF " , " newroot " , 0 } ,
NULLFIELD } } ,
{ " changenamedroot " , ' n ' , FA { { " FILENUM " , " filenum " , 0 } ,
2008-01-18 21:28:27 +00:00
{ " BYTESTRING " , " name " , 0 } ,
{ " DISKOFF " , " oldroot " , 0 } ,
{ " DISKOFF " , " newroot " , 0 } ,
NULLFIELD } } ,
2008-02-08 19:54:00 +00:00
{ " changeunusedmemory " , ' m ' , FA { { " FILENUM " , " filenum " , 0 } ,
2008-01-18 21:28:27 +00:00
{ " DISKOFF " , " oldunused " , 0 } ,
{ " DISKOFF " , " newunused " , 0 } ,
NULLFIELD } } ,
2008-02-08 19:54:00 +00:00
{ " addchild " , ' c ' , FA { { " FILENUM " , " filenum " , 0 } ,
2008-01-17 19:03:37 +00:00
{ " DISKOFF " , " diskoff " , 0 } ,
{ " u_int32_t " , " childnum " , 0 } , // children scoot over
2008-01-29 21:43:08 +00:00
{ " DISKOFF " , " child " , 0 } ,
{ " u_int32_t " , " childfingerprint " , " %08x " } ,
NULLFIELD } } ,
2008-02-08 19:54:00 +00:00
{ " delchild " , ' r ' , FA { { " FILENUM " , " filenum " , 0 } ,
2008-01-29 21:43:08 +00:00
{ " DISKOFF " , " diskoff " , 0 } ,
{ " u_int32_t " , " childnum " , 0 } , // children scoot over
{ " DISKOFF " , " child " , 0 } ,
{ " u_int32_t " , " childfingerprint " , " %08x " } ,
{ " BYTESTRING " , " pivotkey " , 0 } ,
2008-01-17 19:03:37 +00:00
NULLFIELD } } ,
2008-02-08 19:54:00 +00:00
{ " setchild " , ' i ' , FA { { " FILENUM " , " filenum " , 0 } ,
2008-01-17 19:03:37 +00:00
{ " DISKOFF " , " diskoff " , 0 } ,
{ " u_int32_t " , " childnum " , 0 } ,
2008-01-29 21:43:08 +00:00
{ " DISKOFF " , " oldchild " , 0 } ,
{ " DISKOFF " , " newchild " , 0 } ,
2008-01-17 19:03:37 +00:00
NULLFIELD } } ,
2008-02-08 19:54:00 +00:00
{ " setpivot " , ' k ' , FA { { " FILENUM " , " filenum " , 0 } ,
2008-01-17 19:03:37 +00:00
{ " DISKOFF " , " diskoff " , 0 } ,
{ " u_int32_t " , " childnum " , 0 } ,
{ " BYTESTRING " , " pivotkey " , 0 } ,
NULLFIELD } } ,
2007-11-27 10:48:31 +00:00
{ " fopen " , ' O ' , FA { { " TXNID " , " txnid " , 0 } ,
{ " BYTESTRING " , " fname " , 0 } ,
{ " FILENUM " , " filenum " , 0 } ,
2007-11-22 21:11:21 +00:00
NULLFIELD } } ,
2008-02-08 19:54:00 +00:00
{ " brtdeq " , ' U ' , FA { { " FILENUM " , " filenum " , 0 } ,
2008-01-29 21:43:08 +00:00
{ " DISKOFF " , " diskoff " , 0 } ,
{ " u_int32_t " , " childnum " , 0 } ,
2008-02-08 19:54:00 +00:00
{ " TXNID " , " xid " , 0 } ,
2008-01-29 21:43:08 +00:00
{ " u_int32_t " , " typ " , 0 } ,
{ " BYTESTRING " , " key " , 0 } ,
{ " BYTESTRING " , " data " , 0 } ,
{ " u_int32_t " , " oldfingerprint " , " %08x " } ,
{ " u_int32_t " , " newfingerprint " , " %08x " } ,
NULLFIELD } } ,
2008-02-08 19:54:00 +00:00
{ " brtenq " , ' Q ' , FA { { " FILENUM " , " filenum " , 0 } ,
2008-01-29 21:43:08 +00:00
{ " DISKOFF " , " diskoff " , 0 } ,
{ " u_int32_t " , " childnum " , 0 } ,
2008-02-08 19:54:00 +00:00
{ " TXNID " , " xid " , 0 } ,
2008-01-29 21:43:08 +00:00
{ " u_int32_t " , " typ " , 0 } ,
{ " BYTESTRING " , " key " , 0 } ,
{ " BYTESTRING " , " data " , 0 } ,
{ " u_int32_t " , " oldfingerprint " , " %08x " } ,
{ " u_int32_t " , " newfingerprint " , " %08x " } ,
NULLFIELD } } ,
2007-11-27 10:48:31 +00:00
{ " insertinleaf " , ' I ' , FA { { " TXNID " , " txnid " , 0 } ,
{ " FILENUM " , " filenum " , 0 } ,
{ " DISKOFF " , " diskoff " , 0 } ,
{ " u_int32_t " , " pmaidx " , 0 } ,
{ " BYTESTRING " , " key " , 0 } ,
{ " BYTESTRING " , " data " , 0 } ,
2007-11-25 16:39:38 +00:00
NULLFIELD } } ,
2008-01-25 21:50:07 +00:00
{ " deleteinleaf " , ' d ' , FA { { " TXNID " , " txnid " , 0 } ,
{ " FILENUM " , " filenum " , 0 } ,
{ " DISKOFF " , " diskoff " , 0 } ,
{ " u_int32_t " , " pmaidx " , 0 } ,
{ " BYTESTRING " , " key " , 0 } ,
{ " BYTESTRING " , " data " , 0 } ,
NULLFIELD } } ,
2008-02-08 19:54:00 +00:00
{ " resizepma " , ' R ' , FA { { " FILENUM " , " filenum " , 0 } ,
2007-12-04 10:02:59 +00:00
{ " DISKOFF " , " diskoff " , 0 } ,
{ " u_int32_t " , " oldsize " , 0 } ,
{ " u_int32_t " , " newsize " , 0 } ,
NULLFIELD } } ,
2008-02-08 19:54:00 +00:00
{ " pmadistribute " , ' M ' , FA { { " FILENUM " , " filenum " , 0 } ,
2008-01-16 13:50:23 +00:00
{ " DISKOFF " , " old_diskoff " , 0 } ,
{ " DISKOFF " , " new_diskoff " , 0 } ,
2007-12-04 10:02:59 +00:00
{ " INTPAIRARRAY " , " fromto " , 0 } ,
NULLFIELD } } ,
2007-11-22 05:09:29 +00:00
{ 0 , 0 , FA { NULLFIELD } }
} ;
# define DO_LOGTYPES(lt, body) ({ \
const struct logtype * lt ; \
for ( lt = & logtypes [ 0 ] ; lt - > name ; lt + + ) { \
body ; \
} } )
# define DO_FIELDS(fld, lt, body) ({ \
struct field * fld ; \
for ( fld = lt - > fields ; fld - > type ; fld + + ) { \
body ; \
} } )
2007-11-22 06:13:26 +00:00
void fprintf2 ( FILE * f1 , FILE * f2 , const char * format , . . . ) {
va_list ap ;
int r ;
va_start ( ap , format ) ;
r = vfprintf ( f1 , format , ap ) ; assert ( r > = 0 ) ;
2007-11-25 14:32:52 +00:00
va_end ( ap ) ;
va_start ( ap , format ) ;
2007-11-22 06:13:26 +00:00
r = vfprintf ( f2 , format , ap ) ; assert ( r > = 0 ) ;
va_end ( ap ) ;
}
FILE * hf = 0 , * cf = 0 ;
void generate_lt_enum ( void ) {
2008-01-18 21:28:27 +00:00
char used_cmds [ 256 ] ;
2007-11-22 06:13:26 +00:00
int count = 0 ;
2008-01-18 21:28:27 +00:00
memset ( used_cmds , 0 , 256 ) ;
2007-11-22 07:13:08 +00:00
fprintf ( hf , " enum lt_cmd { " ) ;
2007-11-22 06:13:26 +00:00
DO_LOGTYPES ( lt ,
( {
if ( count ! = 0 ) fprintf ( hf , " , " ) ;
count + + ;
fprintf ( hf , " \n " ) ;
fprintf ( hf , " LT_%-16s = '%c' " , lt - > name , lt - > command ) ;
2008-01-18 21:28:27 +00:00
if ( used_cmds [ ( unsigned char ) lt - > command ] ! = 0 ) { fprintf ( stderr , " %s:%d Command %d (%c) was used twice \n " , __FILE__ , __LINE__ , lt - > command , lt - > command ) ; abort ( ) ; }
used_cmds [ ( unsigned char ) lt - > command ] = 1 ;
2007-11-22 06:13:26 +00:00
} ) ) ;
fprintf ( hf , " \n }; \n \n " ) ;
}
void generate_log_struct ( void ) {
2007-11-22 05:09:29 +00:00
DO_LOGTYPES ( lt ,
2007-11-22 06:13:26 +00:00
( { fprintf ( hf , " struct logtype_%s { \n " , lt - > name ) ;
fprintf ( hf , " %-16s lsn; \n " , " LSN " ) ;
2007-11-22 05:09:29 +00:00
DO_FIELDS ( ft , lt ,
2007-11-22 06:13:26 +00:00
fprintf ( hf , " %-16s %s; \n " , ft - > type , ft - > name ) ) ;
2007-11-22 07:13:08 +00:00
fprintf ( hf , " %-16s crc; \n " , " u_int32_t " ) ;
fprintf ( hf , " %-16s len; \n " , " u_int32_t " ) ;
2007-11-22 06:13:26 +00:00
fprintf ( hf , " }; \n " ) ;
2008-01-11 03:09:14 +00:00
fprintf ( hf , " void toku_recover_%s (struct logtype_%s *); \n " , lt - > name , lt - > name ) ;
fprintf ( hf , " int toku_rollback_%s (struct logtype_%s *, TOKUTXN); \n " , lt - > name , lt - > name ) ;
2007-11-22 05:09:29 +00:00
} ) ) ;
2007-11-23 18:27:50 +00:00
fprintf ( hf , " struct log_entry { \n " ) ;
fprintf ( hf , " enum lt_cmd cmd; \n " ) ;
fprintf ( hf , " union { \n " ) ;
DO_LOGTYPES ( lt , fprintf ( hf , " struct logtype_%s %s; \n " , lt - > name , lt - > name ) ) ;
fprintf ( hf , " } u; \n " ) ;
2008-01-08 22:18:42 +00:00
fprintf ( hf , " struct log_entry *next; /* for in-memory list of log entries */ \n " ) ;
2008-01-10 13:41:58 +00:00
fprintf ( hf , " struct log_entry *tmp; /* This will be a back pointer, but it is only created if needed (e.g., when abort is called. */ \n " ) ;
2007-11-23 18:27:50 +00:00
fprintf ( hf , " }; \n " ) ;
2007-11-22 05:09:29 +00:00
}
2007-11-23 20:36:03 +00:00
void generate_dispatch ( void ) {
2008-01-10 13:41:58 +00:00
fprintf ( hf , " #define logtype_dispatch(s, funprefix) ({ switch((s)->cmd) { \\ \n " ) ;
DO_LOGTYPES ( lt , fprintf ( hf , " case LT_%s: funprefix ## %s (&(s)->u.%s); break; \\ \n " , lt - > name , lt - > name , lt - > name ) ) ;
2007-11-23 20:36:03 +00:00
fprintf ( hf , " }}) \n " ) ;
2008-01-10 13:41:58 +00:00
fprintf ( hf , " #define logtype_dispatch_assign(s, funprefix, var, args...) ({ switch((s)->cmd) { \\ \n " ) ;
DO_LOGTYPES ( lt , fprintf ( hf , " case LT_%s: var = funprefix ## %s (&(s)->u.%s, ## args); break; \\ \n " , lt - > name , lt - > name , lt - > name ) ) ;
fprintf ( hf , " }}) \n " ) ;
2007-11-23 20:36:03 +00:00
}
2008-01-12 13:25:36 +00:00
void generate_log_free ( void ) {
DO_LOGTYPES ( lt , ( {
fprintf2 ( cf , hf , " void toku_free_logtype_%s(struct logtype_%s *e) " , lt - > name , lt - > name ) ;
fprintf ( hf , " ; \n " ) ;
fprintf ( cf , " { \n " ) ;
DO_FIELDS ( ft , lt , fprintf ( cf , " toku_free_%s(e->%s); \n " , ft - > type , ft - > name ) ) ;
fprintf ( cf , " } \n " ) ;
} ) ) ;
}
2007-11-23 20:36:03 +00:00
2007-11-22 06:13:26 +00:00
void generate_log_writer ( void ) {
2007-11-22 05:09:29 +00:00
DO_LOGTYPES ( lt , ( {
2008-02-08 19:54:00 +00:00
fprintf2 ( cf , hf , " int toku_log_%s (TOKULOGGER logger " , lt - > name ) ;
2007-11-22 05:09:29 +00:00
DO_FIELDS ( ft , lt ,
2007-11-22 06:13:26 +00:00
fprintf2 ( cf , hf , " , %s %s " , ft - > type , ft - > name ) ) ;
fprintf ( hf , " ); \n " ) ;
fprintf ( cf , " ) { \n " ) ;
2008-02-08 19:54:00 +00:00
fprintf ( cf , " if (logger==0) return 0; \n " ) ;
2007-11-24 23:21:02 +00:00
fprintf ( cf , " const unsigned int buflen= (+4 // len at the beginning \n " ) ;
fprintf ( cf , " +1 // log command \n " ) ;
2007-11-22 18:45:22 +00:00
fprintf ( cf , " +8 // lsn \n " ) ;
2007-11-22 05:09:29 +00:00
DO_FIELDS ( ft , lt ,
2007-11-22 18:45:22 +00:00
fprintf ( cf , " +toku_logsizeof_%s(%s) \n " , ft - > type , ft - > name ) ) ;
fprintf ( cf , " +8 // crc + len \n " ) ;
2007-11-22 06:13:26 +00:00
fprintf ( cf , " ); \n " ) ;
fprintf ( cf , " struct wbuf wbuf; \n " ) ;
2007-11-22 07:13:08 +00:00
fprintf ( cf , " char *buf = toku_malloc(buflen); \n " ) ;
2007-11-22 06:13:26 +00:00
fprintf ( cf , " if (buf==0) return errno; \n " ) ;
2007-11-22 07:13:08 +00:00
fprintf ( cf , " wbuf_init(&wbuf, buf, buflen); \n " ) ;
2007-11-24 23:21:02 +00:00
fprintf ( cf , " wbuf_int(&wbuf, buflen); \n " ) ;
2007-11-22 06:13:26 +00:00
fprintf ( cf , " wbuf_char(&wbuf, '%c'); \n " , lt - > command ) ;
2008-02-08 19:54:00 +00:00
fprintf ( cf , " wbuf_LSN(&wbuf, logger->lsn); \n " ) ;
fprintf ( cf , " logger->lsn.lsn++; \n " ) ;
2007-11-22 05:09:29 +00:00
DO_FIELDS ( ft , lt ,
2007-11-22 06:13:26 +00:00
fprintf ( cf , " wbuf_%s(&wbuf, %s); \n " , ft - > type , ft - > name ) ) ;
2008-02-08 19:54:00 +00:00
fprintf ( cf , " int r= toku_logger_finish(logger, &wbuf); \n " ) ;
2007-11-22 07:13:08 +00:00
fprintf ( cf , " assert(wbuf.ndone==buflen); \n " ) ;
2007-11-22 06:13:26 +00:00
fprintf ( cf , " toku_free(buf); \n " ) ;
2008-02-08 19:54:00 +00:00
fprintf ( cf , " return r; \n " ) ;
2007-11-22 06:13:26 +00:00
fprintf ( cf , " } \n \n " ) ;
2007-11-22 05:09:29 +00:00
} ) ) ;
}
2007-11-22 06:13:26 +00:00
void generate_log_reader ( void ) {
DO_LOGTYPES ( lt , ( {
2007-11-29 18:14:40 +00:00
fprintf ( cf , " static int toku_log_fread_%s (FILE *infile, struct logtype_%s *data, u_int32_t crc) " , lt - > name , lt - > name ) ;
2007-11-22 06:13:26 +00:00
fprintf ( cf , " { \n " ) ;
2007-11-22 18:45:22 +00:00
fprintf ( cf , " int r=0; \n " ) ;
2007-11-24 23:21:02 +00:00
fprintf ( cf , " u_int32_t actual_len=5; // 1 for the command, 4 for the first len. \n " ) ;
2007-11-22 06:13:26 +00:00
fprintf ( cf , " r=toku_fread_%-16s(infile, &data->%-16s, &crc, &actual_len); if (r!=0) return r; \n " , " LSN " , " lsn " ) ;
DO_FIELDS ( ft , lt ,
fprintf ( cf , " r=toku_fread_%-16s(infile, &data->%-16s, &crc, &actual_len); if (r!=0) return r; \n " , ft - > type , ft - > name ) ) ;
fprintf ( cf , " u_int32_t crc_in_file, len_in_file; \n " ) ;
2007-11-22 18:45:22 +00:00
fprintf ( cf , " r=toku_fread_u_int32_t_nocrclen(infile, &crc_in_file); actual_len+=4; if (r!=0) return r; \n " ) ;
fprintf ( cf , " r=toku_fread_u_int32_t_nocrclen(infile, &len_in_file); actual_len+=4; if (r!=0) return r; \n " ) ;
2007-11-22 06:13:26 +00:00
fprintf ( cf , " if (crc_in_file!=crc || len_in_file!=actual_len) return DB_BADFORMAT; \n " ) ;
fprintf ( cf , " return 0; \n " ) ;
fprintf ( cf , " } \n \n " ) ;
} ) ) ;
2007-11-29 18:14:40 +00:00
fprintf2 ( cf , hf , " int toku_log_fread (FILE *infile, struct log_entry *le) " ) ;
2007-11-23 18:27:50 +00:00
fprintf ( hf , " ; \n " ) ;
fprintf ( cf , " { \n " ) ;
2007-11-24 23:21:02 +00:00
fprintf ( cf , " u_int32_t len1; int r; \n " ) ;
fprintf ( cf , " u_int32_t crc=0,ignorelen=0; \n " ) ;
fprintf ( cf , " r = toku_fread_u_int32_t(infile, &len1,&crc,&ignorelen); if (r!=0) return r; \n " ) ;
2007-11-23 18:27:50 +00:00
fprintf ( cf , " int cmd=fgetc(infile); \n " ) ;
fprintf ( cf , " if (cmd==EOF) return EOF; \n " ) ;
2007-11-24 23:21:02 +00:00
fprintf ( cf , " char cmdchar = cmd; \n " ) ;
fprintf ( cf , " crc = toku_crc32(crc, &cmdchar, 1); \n " ) ;
2007-11-23 18:27:50 +00:00
fprintf ( cf , " le->cmd=cmd; \n " ) ;
fprintf ( cf , " switch ((enum lt_cmd)cmd) { \n " ) ;
DO_LOGTYPES ( lt , ( {
fprintf ( cf , " case LT_%s: \n " , lt - > name ) ;
2007-11-29 18:14:40 +00:00
fprintf ( cf , " return toku_log_fread_%s (infile, &le->u.%s, crc); \n " , lt - > name , lt - > name ) ;
2007-11-23 18:27:50 +00:00
} ) ) ;
fprintf ( cf , " }; \n " ) ;
fprintf ( cf , " return DB_BADFORMAT; \n " ) ; // Should read past the record using the len field.
fprintf ( cf , " } \n \n " ) ;
2007-11-22 06:13:26 +00:00
}
void generate_logprint ( void ) {
2007-11-27 10:48:31 +00:00
unsigned maxnamelen = 0 ;
2007-11-22 20:35:21 +00:00
fprintf2 ( cf , hf , " int toku_logprint_one_record(FILE *outf, FILE *f) " ) ;
fprintf ( hf , " ; \n " ) ;
fprintf ( cf , " { \n " ) ;
2007-11-22 06:46:00 +00:00
fprintf ( cf , " int cmd, r; \n " ) ;
2007-11-24 23:21:02 +00:00
fprintf ( cf , " u_int32_t len1, crc_in_file; \n " ) ;
fprintf ( cf , " u_int32_t crc = 0, ignorelen=0; \n " ) ;
fprintf ( cf , " r=toku_fread_u_int32_t(f, &len1, &crc, &ignorelen); \n " ) ;
fprintf ( cf , " if (r==EOF) return EOF; \n " ) ;
2007-11-22 06:46:00 +00:00
fprintf ( cf , " cmd=fgetc(f); \n " ) ;
2007-11-24 23:21:02 +00:00
fprintf ( cf , " if (cmd==EOF) return DB_BADFORMAT; \n " ) ;
fprintf ( cf , " u_int32_t len_in_file, len=1+4; // cmd + len1 \n " ) ;
2007-11-22 06:46:00 +00:00
fprintf ( cf , " char charcmd = cmd; \n " ) ;
2007-11-24 23:21:02 +00:00
fprintf ( cf , " crc = toku_crc32(crc, &charcmd, 1); \n " ) ;
2007-11-22 07:13:08 +00:00
fprintf ( cf , " switch ((enum lt_cmd)cmd) { \n " ) ;
2007-11-27 10:48:31 +00:00
DO_LOGTYPES ( lt , ( { if ( strlen ( lt - > name ) > maxnamelen ) maxnamelen = strlen ( lt - > name ) ; } ) ) ;
2007-11-22 06:13:26 +00:00
DO_LOGTYPES ( lt , ( {
2007-11-22 06:46:00 +00:00
fprintf ( cf , " case LT_%s: \n " , lt - > name ) ;
2007-11-22 06:13:26 +00:00
// We aren't using the log reader here because we want better diagnostics as soon as things go wrong.
2007-11-27 10:48:31 +00:00
fprintf ( cf , " fprintf(outf, \" %%-%ds \" , \" %s \" ); \n " , maxnamelen , lt - > name ) ;
if ( isprint ( lt - > command ) ) fprintf ( cf , " fprintf(outf, \" '%c': \" ); \n " , lt - > command ) ;
else fprintf ( cf , " fprintf(outf, \" 0%03o: \" ) ; \ n " , lt->command);
fprintf ( cf , " r = toku_logprint_%-16s(outf, f, \" lsn \" , &crc, &len, 0); if (r!=0) return r; \n " , " LSN " ) ;
2007-11-22 06:13:26 +00:00
DO_FIELDS ( ft , lt ,
2007-11-27 10:48:31 +00:00
( {
fprintf ( cf , " r = toku_logprint_%-16s(outf, f, \" %s \" , &crc, &len, " , ft - > type , ft - > name ) ;
if ( ft - > format ) fprintf ( cf , " \" %s \" " , ft - > format ) ;
else fprintf ( cf , " 0 " ) ;
fprintf ( cf , " ); if (r!=0) return r; \n " ) ;
} ) ) ;
2007-11-22 18:45:22 +00:00
fprintf ( cf , " r = toku_fread_u_int32_t_nocrclen (f, &crc_in_file); len+=4; if (r!=0) return r; \n " ) ;
2007-11-24 23:21:02 +00:00
fprintf ( cf , " fprintf(outf, \" crc=%%08x \" , crc_in_file); \n " ) ;
fprintf ( cf , " if (crc_in_file!=crc) fprintf(outf, \" actual_crc=%%08x \" , crc); \n " ) ;
2007-11-22 18:45:22 +00:00
fprintf ( cf , " r = toku_fread_u_int32_t_nocrclen (f, &len_in_file); len+=4; if (r!=0) return r; \n " ) ;
2007-11-22 06:46:00 +00:00
fprintf ( cf , " fprintf(outf, \" len=%%d \" , len_in_file); \n " ) ;
2007-11-22 07:13:08 +00:00
fprintf ( cf , " if (len_in_file!=len) fprintf(outf, \" actual_len=%%d \" , len); \n " ) ;
2007-11-22 06:46:00 +00:00
fprintf ( cf , " if (len_in_file!=len || crc_in_file!=crc) return DB_BADFORMAT; \n " ) ;
2007-11-22 20:39:18 +00:00
fprintf ( cf , " fprintf(outf, \" \\ n \" ); \n " ) ;
2007-11-22 06:46:00 +00:00
fprintf ( cf , " return 0;; \n \n " ) ;
2007-11-22 06:13:26 +00:00
} ) ) ;
fprintf ( cf , " } \n " ) ;
fprintf ( cf , " fprintf(outf, \" Unknown command %%d ('%%c') \" , cmd, cmd); \n " ) ;
fprintf ( cf , " return DB_BADFORMAT; \n " ) ;
fprintf ( cf , " } \n \n " ) ;
}
2007-11-22 05:09:29 +00:00
2007-11-22 07:13:08 +00:00
const char * codepath = " log_code.c " ;
const char * headerpath = " log_header.h " ;
2007-11-22 05:09:29 +00:00
int main ( int argc __attribute__ ( ( __unused__ ) ) , char * argv [ ] __attribute__ ( ( __unused__ ) ) ) {
2007-11-22 07:13:08 +00:00
unlink ( codepath ) ;
unlink ( headerpath ) ;
cf = fopen ( codepath , " w " ) ; assert ( cf ! = 0 ) ;
hf = fopen ( headerpath , " w " ) ; assert ( hf ! = 0 ) ;
2008-01-24 15:10:32 +00:00
fprintf2 ( cf , hf , " /* Do not edit this file. This code generated by logformat.c. Copyright 2007, 2008 Tokutek. */ \n " ) ;
fprintf2 ( cf , hf , " #ident \" Copyright (c) 2007, 2008 Tokutek Inc. All rights reserved. \" \n " ) ;
2007-11-22 06:46:00 +00:00
fprintf ( cf , " #include <stdio.h> \n " ) ;
fprintf ( hf , " #include \" brt-internal.h \" \n " ) ;
fprintf ( cf , " #include \" log_header.h \" \n " ) ;
2007-11-22 07:13:08 +00:00
fprintf ( cf , " #include \" wbuf.h \" \n " ) ;
fprintf ( cf , " #include \" log-internal.h \" \n " ) ;
generate_lt_enum ( ) ;
2007-11-22 05:09:29 +00:00
generate_log_struct ( ) ;
2007-11-23 20:36:03 +00:00
generate_dispatch ( ) ;
2007-11-22 05:09:29 +00:00
generate_log_writer ( ) ;
2008-01-12 13:25:36 +00:00
generate_log_free ( ) ;
2007-11-22 06:13:26 +00:00
generate_log_reader ( ) ;
generate_logprint ( ) ;
{
int r = fclose ( hf ) ;
assert ( r = = 0 ) ;
r = fclose ( cf ) ;
assert ( r = = 0 ) ;
2007-11-22 07:13:08 +00:00
// Make it tougher to modify by mistake
chmod ( codepath , S_IRUSR | S_IRGRP | S_IROTH ) ;
chmod ( headerpath , S_IRUSR | S_IRGRP | S_IROTH ) ;
2007-11-22 06:13:26 +00:00
}
2007-11-22 05:09:29 +00:00
return 0 ;
}