From b0532dd7b17b97f68423db938bfa6db60365dcf7 Mon Sep 17 00:00:00 2001 From: Olaf Rempel Date: Wed, 2 May 2007 21:21:59 +0200 Subject: [PATCH] introduce linebuffer.[ch] --- Makefile | 2 +- context.c | 8 ++++++ context.h | 4 +-- linebuffer.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++ linebuffer.h | 18 +++++++++++++ serial.c | 3 --- statemachine.c | 70 ++++++-------------------------------------------- 7 files changed, 105 insertions(+), 68 deletions(-) create mode 100644 linebuffer.c create mode 100644 linebuffer.h diff --git a/Makefile b/Makefile index d32d4bf..740ce7f 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ CFLAGS := -O2 -pipe -Wall all: zyxel-revert compress decompress cfgpatch -zyxel-revert: event.o filedata.o logging.o context.o serial.o statemachine.o xmodem.o zyxel-revert.o +zyxel-revert: event.o filedata.o linebuffer.o logging.o context.o serial.o statemachine.o xmodem.o zyxel-revert.o $(CC) $(CFLAGS) $^ -o $@ compress: filedata.o lzsc.o romfile.o compress.o diff --git a/context.c b/context.c index 5776ed6..a33257f 100644 --- a/context.c +++ b/context.c @@ -18,8 +18,15 @@ struct context * create_context(const char *filename) memset(ctx, 0, sizeof(struct context)); + ctx->lbuf = create_linebuffer(256); + if (ctx->lbuf == NULL) { + free(ctx); + return NULL; + } + ctx->file = get_filedata(filename); if (ctx->file == NULL) { + free(ctx->lbuf); free(ctx); return NULL; } @@ -36,6 +43,7 @@ int destroy_context(struct context *ctx) ctx->dev_close(ctx); free(ctx->file); + free(ctx->lbuf); free(ctx); return 0; } diff --git a/context.h b/context.h index daaccbe..15619b3 100644 --- a/context.h +++ b/context.h @@ -2,6 +2,7 @@ #define _CONTEXT_H_ #include "filedata.h" +#include "linebuffer.h" #include "list.h" struct context { @@ -21,8 +22,7 @@ struct context { int state; /* line buffer */ - char linebuf[256]; - int linepos; + struct linebuffer *lbuf; /* xmodem */ int lastpkt; diff --git a/linebuffer.c b/linebuffer.c new file mode 100644 index 0000000..c1b21b5 --- /dev/null +++ b/linebuffer.c @@ -0,0 +1,68 @@ +#include +#include +#include +#include + +#include "linebuffer.h" + +struct linebuffer * create_linebuffer(int size) +{ + struct linebuffer *retval = malloc(sizeof(struct linebuffer) + size); + if (retval == NULL) + return NULL; + + retval->size = size; + retval->pos = 0; + return retval; +} + +int linebuffer_read(struct linebuffer *lbuf, int fd) +{ + char buf[32]; + int len = read(fd, buf, sizeof(buf)); + if (len <= 0) + return -1; + + int i; + for (i = 0; i < len; i++) { + /* "understand" backspace */ + if (buf[i] == 0x08 && lbuf->pos > 0) { + lbuf->pos--; + + /* copy */ + } else if (buf[i] >= ' ' || buf[i] == '\r') { + lbuf->data[lbuf->pos++] = buf[i]; + } + + if (lbuf->pos > lbuf->size) + return -1; + } + + return 0; +} + +char * linebuffer_get(struct linebuffer *lbuf) +{ + char *newline = memchr(lbuf->data, '\r', lbuf->pos); + if (newline == NULL) + return NULL; + + char *retval = NULL; + *newline = '\0'; + + int len = newline - lbuf->data; + if (len > 0) + retval = strdup(lbuf->data); + + lbuf->pos -= len +1; + memmove(lbuf->data, newline +1, lbuf->pos); + + return retval; +} + +int linebuffer_clear(struct linebuffer *lbuf) +{ + int oldpos = lbuf->pos; + lbuf->pos = 0; + return oldpos; +} diff --git a/linebuffer.h b/linebuffer.h new file mode 100644 index 0000000..e9d2a77 --- /dev/null +++ b/linebuffer.h @@ -0,0 +1,18 @@ +#ifndef _LINEBUFFER_H_ +#define _LINEBUFFER_H_ + +struct linebuffer { + int size; + int pos; + + char data[0]; +}; + +struct linebuffer * create_linebuffer(int size); + +int linebuffer_read(struct linebuffer *lbuf, int fd); +char * linebuffer_get(struct linebuffer *lbuf); + +int linebuffer_clear(struct linebuffer *lbuf); + +#endif /* _LINEBUFFER_H_ */ diff --git a/serial.c b/serial.c index 23aea78..19af6cd 100644 --- a/serial.c +++ b/serial.c @@ -55,9 +55,6 @@ static int setbaudrate(struct context *ctx, int baudrate) cfsetispeed(&sdev->newtio, baudrate); cfsetospeed(&sdev->newtio, baudrate); - /* flush linebuffer */ - ctx->linepos = 0; - if (tcsetattr(ctx->fd, TCSANOW, &sdev->newtio) != 0) { log_print(LOG_WARN, "open_serial(): tcsetattr()"); close(ctx->fd); diff --git a/statemachine.c b/statemachine.c index b1791bc..78d698b 100644 --- a/statemachine.c +++ b/statemachine.c @@ -6,6 +6,7 @@ #include #include "context.h" +#include "linebuffer.h" #include "logging.h" #include "xmodem.h" @@ -39,57 +40,6 @@ enum { MSG_BAUD_LOW, }; -static int my_readline(int fd, struct context *ctx, char **retval) -{ - char *newline = memchr(ctx->linebuf, '\r', ctx->linepos); - if (newline != NULL) { - int len = newline - ctx->linebuf; - *newline = '\0'; - if (len > 0) - *retval = strdup(ctx->linebuf); - - ctx->linepos -= len +1; - memmove(ctx->linebuf, newline +1, ctx->linepos); - - newline = memchr(ctx->linebuf, '\r', ctx->linepos); - return ((*retval != NULL) ? 1 : 0) + ((newline != NULL) ? 1 : 0); - } - - char buf[32]; - int len = read(fd, buf, sizeof(buf)); - if (len <= 0) - return -1; - - int i, numlines = 0; - for (i = 0; i < len; i++) { - /* "understand" backspace */ - if (buf[i] == 0x08 && ctx->linepos > 0) { - ctx->linepos--; - - /* export buffer */ - } else if (buf[i] == '\r') { - if (*retval == NULL) { - ctx->linebuf[ctx->linepos] = '\0'; - - if (ctx->linepos > 0) - *retval = strdup(ctx->linebuf); - - ctx->linepos = 0; - numlines = 1; - - } else { - ctx->linebuf[ctx->linepos++] = buf[i]; - numlines++; - } - - /* copy */ - } else if (buf[i] >= ' ') { - ctx->linebuf[ctx->linepos++] = buf[i]; - } - } - return numlines; -} - int statemachine_read(int fd, void *privdata) { struct context *ctx = (struct context *)privdata; @@ -101,15 +51,11 @@ int statemachine_read(int fd, void *privdata) return 0; } - int numlines; - do { - char *line = NULL; - numlines = my_readline(fd, ctx, &line); - if (numlines < 0) - return -1; + if (linebuffer_read(ctx->lbuf, fd) < 0) + return -1; - if (line == NULL) - return 0; + char *line; + while ((line = linebuffer_get(ctx->lbuf)) != NULL) { log_print(LOG_DEBUG, "%s: '%s'", ctx->devname, line); @@ -141,7 +87,7 @@ int statemachine_read(int fd, void *privdata) /* follow device to high baudrate */ } else if (msg == MSG_BAUD_HIGH) { ctx->dev_setbaudrate(ctx, B115200); - numlines = 0; + linebuffer_clear(ctx->lbuf); ctx->state = STATE_XMODEM; write(fd, "ATLC\r\n", 6); @@ -154,11 +100,11 @@ int statemachine_read(int fd, void *privdata) /* follow device to low baudrate */ } else if (msg == MSG_BAUD_LOW) { ctx->dev_setbaudrate(ctx, B9600); - numlines = 0; + linebuffer_clear(ctx->lbuf); } free(line); - } while (numlines > 1); + }; return 0; }