diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2013-10-12 17:29:05 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2013-10-12 17:29:05 +0300 |
commit | 66f3521c257d2777cbf9697716a9f2288254376c (patch) | |
tree | be3b4993d1b4bb515f67227bd0647dac4dbc08ff | |
parent | 60a356d55ed0aca4283ddc3134298936e45ad18b (diff) | |
download | vmod-binlog-66f3521c257d2777cbf9697716a9f2288254376c.tar.gz vmod-binlog-66f3521c257d2777cbf9697716a9f2288254376c.tar.bz2 |
Fix processing repeat counts in packinnext.
* src/binlog.c (vmod_start): call packinit.
* src/pack.c (packinst) <cur>: New member.
(packinnext): Correctly process repeat counts.
(packout): Likewise.
(packinit): New function.
* src/pack.h (packinit): New proto.
-rw-r--r-- | src/binlog.c | 44 | ||||
-rw-r--r-- | src/pack.c | 24 | ||||
-rw-r--r-- | src/pack.h | 1 |
3 files changed, 42 insertions, 27 deletions
diff --git a/src/binlog.c b/src/binlog.c index b2d9f87..325f337 100644 --- a/src/binlog.c +++ b/src/binlog.c @@ -42,35 +42,35 @@ enum binlog_state { state_init, state_start, state_pack }; struct binlog_config { - size_t size; /* maximum file size */ - unsigned interval; /* file rotation interval */ - char *pattern; /* file name pattern */ - int umask; /* umask for new files and directories */ - char *dir; /* root storage directory */ - int dd; /* directory descriptor */ - char *fname; /* current file name */ - int fd; /* current file descriptor */ + size_t size; /* maximum file size */ + unsigned interval; /* file rotation interval */ + char *pattern; /* file name pattern */ + int umask; /* umask for new files and directories */ + char *dir; /* root storage directory */ + int dd; /* directory descriptor */ + char *fname; /* current file name */ + int fd; /* current file descriptor */ struct binlog_file_header *base; /* mmap base */ - char *recbase; /* record base */ - size_t recnum; /* number of records in recbase */ - size_t recsize; /* record size */ - time_t stoptime; /* when to rotate the current file */ + char *recbase; /* record base */ + size_t recnum; /* number of records in recbase */ + size_t recsize; /* record size */ + time_t stoptime; /* when to rotate the current file */ pthread_mutex_t mutex; - int debug; - int flags; - - char *dataspec; - struct packinst *inst_head; - struct packinst *inst_cur; - struct packenv *env; - enum binlog_state state; - time_t timestamp; + int debug; /* debug level */ + int flags; /* flags (see BLF_* defines above) */ + + char *dataspec; /* data format specification */ + struct packinst *inst_head; /* compiled dataspec */ + struct packinst *inst_cur; /* current instruction */ + struct packenv *env; /* pack environment */ + enum binlog_state state; /* binlog machine state */ + time_t timestamp; /* timestamp for the entry being built */ }; static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; void binlog_error(const char *fmt, ...) @@ -493,13 +493,13 @@ vmod_start(struct sess *sp, struct vmod_priv *priv) newfile(sp, conf); AZ(pthread_mutex_unlock(&conf->mutex)); } packenv_init(conf->env); conf->state = state_start; - conf->inst_cur = conf->inst_head; + conf->inst_cur = packinit(conf->inst_head); conf->timestamp = ts; } void vmod_pack(struct sess *sp, struct vmod_priv *priv, const char *str) { @@ -66,12 +66,13 @@ struct packspec { }; struct packinst { struct packinst *next; struct packspec *spec; int rep; + int cur; }; static char * packenv_get(struct packenv *env) { if (env->argi == env->argc) @@ -506,29 +507,34 @@ packinnext(struct packinst *pi, struct packenv *env) int i; if (!pi) return NULL; if (pi->spec->flags & F_REP) pi->spec->packer(env, pi->spec, pi->rep); - else - for (i = 0; i < pi->rep; i++) - pi->spec->packer(env, pi->spec, 1); - return pi->next; + else { + pi->spec->packer(env, pi->spec, 1); + if (++pi->cur < pi->rep) + return pi; + } + return packinit(pi->next); } void packout(struct packinst *pi, struct packenv *env) { int i; for (; pi; pi = pi->next) { if (pi->spec->flags & F_REP) pi->spec->unpacker(env, pi->spec, pi->rep); else - for (i = 0; i < pi->rep; i++) + for (i = 0; i < pi->rep; i++) { + if (i > 0) + fputc(' ', env->fp); pi->spec->unpacker(env, pi->spec, 1); + } if (pi->next) fputc(' ', env->fp); } } size_t @@ -538,12 +544,20 @@ packsize(struct packinst *pi) memset(&env, 0, sizeof env); packin(pi, &env); return env.buf_pos; } +struct packinst * +packinit(struct packinst *inst) +{ + if (inst) + inst->cur = 0; + return inst; +} + struct packenv * packenv_create(size_t size) { struct packenv *env = calloc(1, sizeof(*env)); if (env) { env->buf_base = calloc(1, size); @@ -27,12 +27,13 @@ struct packenv { }; struct packinst; struct packinst *packcomp(const char *s, char **endp); void packfree(struct packinst *pi); +struct packinst *packinit(struct packinst *pi); void packin(struct packinst *pi, struct packenv *env); void packout(struct packinst *pi, struct packenv *env); struct packinst *packinnext(struct packinst *pi, struct packenv *env); size_t packsize(struct packinst *pi); struct packenv *packenv_create(size_t size); |