diff options
-rw-r--r-- | MAINTAINERS | 7 | ||||
-rw-r--r-- | arch/sandbox/include/asm/serial.h | 2 | ||||
-rw-r--r-- | boot/bootmeth_extlinux.c | 8 | ||||
-rw-r--r-- | common/console.c | 32 | ||||
-rw-r--r-- | drivers/serial/sandbox.c | 10 | ||||
-rw-r--r-- | drivers/usb/emul/sandbox_keyb.c | 8 | ||||
-rw-r--r-- | include/asm-generic/global_data.h | 6 | ||||
-rw-r--r-- | include/membuf.h (renamed from include/membuff.h) | 92 | ||||
-rw-r--r-- | lib/Makefile | 2 | ||||
-rw-r--r-- | lib/membuf.c (renamed from lib/membuff.c) | 73 | ||||
-rw-r--r-- | test/lib/Makefile | 1 | ||||
-rw-r--r-- | test/lib/membuf.c | 239 |
12 files changed, 366 insertions, 114 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 92d4a158fd0..fac9ce81d70 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1281,6 +1281,13 @@ T: git git://github.com/ARM-software/u-boot.git F: drivers/video/mali_dp.c F: drivers/i2c/i2c-versatile.c +MEMBUF +M: Simon Glass <sjg@chromium.org> +S: Maintained +T: git https://source.denx.de/u-boot/u-boot.git +F: include/membuf.h +F: lib/membuf.c + MICROBLAZE M: Michal Simek <monstr@monstr.eu> S: Maintained diff --git a/arch/sandbox/include/asm/serial.h b/arch/sandbox/include/asm/serial.h index 16589a1b219..41506341816 100644 --- a/arch/sandbox/include/asm/serial.h +++ b/arch/sandbox/include/asm/serial.h @@ -44,7 +44,7 @@ void sandbox_serial_endisable(bool enabled); * @buf: holds input characters available to be read by this driver */ struct sandbox_serial_priv { - struct membuff buf; + struct membuf buf; char serial_buf[16]; bool start_of_line; }; diff --git a/boot/bootmeth_extlinux.c b/boot/bootmeth_extlinux.c index 17c6cebd2f4..921d721a27b 100644 --- a/boot/bootmeth_extlinux.c +++ b/boot/bootmeth_extlinux.c @@ -108,15 +108,15 @@ static int extlinux_check(struct udevice *dev, struct bootflow_iter *iter) */ static int extlinux_fill_info(struct bootflow *bflow) { - struct membuff mb; + struct membuf mb; char line[200]; char *data; int len; log_debug("parsing bflow file size %x\n", bflow->size); - membuff_init(&mb, bflow->buf, bflow->size); - membuff_putraw(&mb, bflow->size, true, &data); - while (len = membuff_readline(&mb, line, sizeof(line) - 1, ' ', true), len) { + membuf_init(&mb, bflow->buf, bflow->size); + membuf_putraw(&mb, bflow->size, true, &data); + while (len = membuf_readline(&mb, line, sizeof(line) - 1, ' ', true), len) { char *tok, *p = line; tok = strsep(&p, " "); diff --git a/common/console.c b/common/console.c index 26812b2ccbe..b69bb189639 100644 --- a/common/console.c +++ b/common/console.c @@ -101,7 +101,7 @@ static void console_record_putc(const char c) if (!(gd->flags & GD_FLG_RECORD)) return; if (gd->console_out.start && - !membuff_putbyte((struct membuff *)&gd->console_out, c)) + !membuf_putbyte((struct membuf *)&gd->console_out, c)) gd->flags |= GD_FLG_RECORD_OVF; } @@ -112,7 +112,7 @@ static void console_record_puts(const char *s) if (gd->console_out.start) { int len = strlen(s); - if (membuff_put((struct membuff *)&gd->console_out, s, len) != + if (membuf_put((struct membuf *)&gd->console_out, s, len) != len) gd->flags |= GD_FLG_RECORD_OVF; } @@ -125,7 +125,7 @@ static int console_record_getc(void) if (!gd->console_in.start) return -1; - return membuff_getbyte((struct membuff *)&gd->console_in); + return membuf_getbyte((struct membuf *)&gd->console_in); } static int console_record_tstc(void) @@ -133,7 +133,7 @@ static int console_record_tstc(void) if (!(gd->flags & GD_FLG_RECORD)) return 0; if (gd->console_in.start) { - if (membuff_peekbyte((struct membuff *)&gd->console_in) != -1) + if (membuf_peekbyte((struct membuf *)&gd->console_in) != -1) return 1; } return 0; @@ -810,14 +810,14 @@ int console_record_init(void) { int ret; - ret = membuff_new((struct membuff *)&gd->console_out, - gd->flags & GD_FLG_RELOC ? - CONFIG_CONSOLE_RECORD_OUT_SIZE : - CONFIG_CONSOLE_RECORD_OUT_SIZE_F); + ret = membuf_new((struct membuf *)&gd->console_out, + gd->flags & GD_FLG_RELOC ? + CONFIG_CONSOLE_RECORD_OUT_SIZE : + CONFIG_CONSOLE_RECORD_OUT_SIZE_F); if (ret) return ret; - ret = membuff_new((struct membuff *)&gd->console_in, - CONFIG_CONSOLE_RECORD_IN_SIZE); + ret = membuf_new((struct membuf *)&gd->console_in, + CONFIG_CONSOLE_RECORD_IN_SIZE); /* Start recording from the beginning */ gd->flags |= GD_FLG_RECORD; @@ -827,8 +827,8 @@ int console_record_init(void) void console_record_reset(void) { - membuff_purge((struct membuff *)&gd->console_out); - membuff_purge((struct membuff *)&gd->console_in); + membuf_purge((struct membuf *)&gd->console_out); + membuf_purge((struct membuf *)&gd->console_in); gd->flags &= ~GD_FLG_RECORD_OVF; } @@ -847,23 +847,23 @@ int console_record_readline(char *str, int maxlen) if (console_record_isempty()) return -ENOENT; - return membuff_readline((struct membuff *)&gd->console_out, str, + return membuf_readline((struct membuf *)&gd->console_out, str, maxlen, '\0', false); } int console_record_avail(void) { - return membuff_avail((struct membuff *)&gd->console_out); + return membuf_avail((struct membuf *)&gd->console_out); } bool console_record_isempty(void) { - return membuff_isempty((struct membuff *)&gd->console_out); + return membuf_isempty((struct membuf *)&gd->console_out); } int console_in_puts(const char *str) { - return membuff_put((struct membuff *)&gd->console_in, str, strlen(str)); + return membuf_put((struct membuf *)&gd->console_in, str, strlen(str)); } #endif diff --git a/drivers/serial/sandbox.c b/drivers/serial/sandbox.c index 77a1558db68..cc0491bc3c8 100644 --- a/drivers/serial/sandbox.c +++ b/drivers/serial/sandbox.c @@ -63,7 +63,7 @@ static int sandbox_serial_probe(struct udevice *dev) if (state->term_raw != STATE_TERM_RAW) disable_ctrlc(1); - membuff_init(&priv->buf, priv->serial_buf, sizeof(priv->serial_buf)); + membuf_init(&priv->buf, priv->serial_buf, sizeof(priv->serial_buf)); return 0; } @@ -138,15 +138,15 @@ static int sandbox_serial_pending(struct udevice *dev, bool input) return 0; os_usleep(100); - avail = membuff_putraw(&priv->buf, 100, false, &data); + avail = membuf_putraw(&priv->buf, 100, false, &data); if (!avail) return 1; /* buffer full */ count = os_read(0, data, avail); if (count > 0) - membuff_putraw(&priv->buf, count, true, &data); + membuf_putraw(&priv->buf, count, true, &data); - return membuff_avail(&priv->buf); + return membuf_avail(&priv->buf); } static int sandbox_serial_getc(struct udevice *dev) @@ -156,7 +156,7 @@ static int sandbox_serial_getc(struct udevice *dev) if (!sandbox_serial_pending(dev, true)) return -EAGAIN; /* buffer empty */ - return membuff_getbyte(&priv->buf); + return membuf_getbyte(&priv->buf); } #ifdef CONFIG_DEBUG_UART_SANDBOX diff --git a/drivers/usb/emul/sandbox_keyb.c b/drivers/usb/emul/sandbox_keyb.c index db769883ba3..5ed8c2c799a 100644 --- a/drivers/usb/emul/sandbox_keyb.c +++ b/drivers/usb/emul/sandbox_keyb.c @@ -38,7 +38,7 @@ enum { * */ struct sandbox_keyb_priv { - struct membuff in; + struct membuf in; }; struct sandbox_keyb_plat { @@ -167,7 +167,7 @@ int sandbox_usb_keyb_add_string(struct udevice *dev, struct sandbox_keyb_priv *priv = dev_get_priv(dev); int ret; - ret = membuff_put(&priv->in, scancode, USB_KBD_BOOT_REPORT_SIZE); + ret = membuf_put(&priv->in, scancode, USB_KBD_BOOT_REPORT_SIZE); if (ret != USB_KBD_BOOT_REPORT_SIZE) return -ENOSPC; @@ -194,7 +194,7 @@ static int sandbox_keyb_interrupt(struct udevice *dev, struct usb_device *udev, if (length < USB_KBD_BOOT_REPORT_SIZE) return 0; - membuff_get(&priv->in, buffer, USB_KBD_BOOT_REPORT_SIZE); + membuf_get(&priv->in, buffer, USB_KBD_BOOT_REPORT_SIZE); return 0; } @@ -220,7 +220,7 @@ static int sandbox_keyb_probe(struct udevice *dev) struct sandbox_keyb_priv *priv = dev_get_priv(dev); /* Provide an 80 character keyboard buffer */ - return membuff_new(&priv->in, 80 * USB_KBD_BOOT_REPORT_SIZE); + return membuf_new(&priv->in, 80 * USB_KBD_BOOT_REPORT_SIZE); } static const struct dm_usb_ops sandbox_usb_keyb_ops = { diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h index 789adf2c3f9..506ee51cdb0 100644 --- a/include/asm-generic/global_data.h +++ b/include/asm-generic/global_data.h @@ -23,7 +23,7 @@ #include <board_f.h> #include <event_internal.h> #include <fdtdec.h> -#include <membuff.h> +#include <membuf.h> #include <linux/list.h> #include <linux/build_bug.h> #include <asm-offsets.h> @@ -316,14 +316,14 @@ struct global_data { * * This buffer is used to collect output during console recording. */ - struct membuff console_out; + struct membuf console_out; /** * @console_in: input buffer for console recording * * If console recording is activated, this buffer can be used to * emulate input. */ - struct membuff console_in; + struct membuf console_in; #endif #if CONFIG_IS_ENABLED(VIDEO) /** diff --git a/include/membuff.h b/include/membuf.h index 4eba626ce1c..46764690f53 100644 --- a/include/membuff.h +++ b/include/membuf.h @@ -6,11 +6,13 @@ * Copyright (c) 1992 Simon Glass */ -#ifndef _MEMBUFF_H -#define _MEMBUFF_H +#ifndef _membuf_H +#define _membuf_H + +#include <stdbool.h> /** - * @struct membuff: holds the state of a membuff - it is used for input and + * @struct membuf: holds the state of a membuff - it is used for input and * output buffers. The buffer extends from @start to (@start + @size - 1). * Data in the buffer extends from @tail to @head: it is written in at * @head and read out from @tail. The membuff is empty when @head == @tail @@ -23,13 +25,13 @@ * * .............xxxxxxxxxxxxxxxx......................... * ^ ^ - * tail head + * ^start tail head ^end * * xxxxxxxxxxxxx................xxxxxxxxxxxxxxxxxxxxxxxxx * ^ ^ * head tail */ -struct membuff { +struct membuf { char *start; /** the start of the buffer */ char *end; /** the end of the buffer (start + length) */ char *head; /** current buffer head */ @@ -37,16 +39,16 @@ struct membuff { }; /** - * membuff_purge() - reset a membuff to the empty state + * membuf_purge() - reset a membuff to the empty state * * Initialise head and tail pointers so that the membuff becomes empty. * * @mb: membuff to purge */ -void membuff_purge(struct membuff *mb); +void membuf_purge(struct membuf *mb); /** - * membuff_putraw() - find out where bytes can be written + * membuf_putraw() - find out where bytes can be written * * Work out where in the membuff some data could be written. Return a pointer * to the address and the number of bytes which can be written there. If @@ -64,10 +66,10 @@ void membuff_purge(struct membuff *mb); * @data: the address data can be written to * Return: number of bytes which can be written */ -int membuff_putraw(struct membuff *mb, int maxlen, bool update, char **data); +int membuf_putraw(struct membuf *mb, int maxlen, bool update, char **data); /** - * membuff_getraw() - find and return a pointer to available bytes + * membuf_getraw() - find and return a pointer to available bytes * * Returns a pointer to any valid input data in the given membuff and * optionally marks it as read. Note that not all input data may not be @@ -82,37 +84,37 @@ int membuff_putraw(struct membuff *mb, int maxlen, bool update, char **data); * @data: returns address of data in input membuff * Return: the number of bytes available at *@data */ -int membuff_getraw(struct membuff *mb, int maxlen, bool update, char **data); +int membuf_getraw(struct membuf *mb, int maxlen, bool update, char **data); /** - * membuff_putbyte() - Writes a byte to a membuff + * membuf_putbyte() - Writes a byte to a membuff * * @mb: membuff to adjust * @ch: byte to write * Return: true on success, false if membuff is full */ -bool membuff_putbyte(struct membuff *mb, int ch); +bool membuf_putbyte(struct membuf *mb, int ch); /** * @mb: membuff to adjust - * membuff_getbyte() - Read a byte from the membuff + * membuf_getbyte() - Read a byte from the membuff * Return: the byte read, or -1 if the membuff is empty */ -int membuff_getbyte(struct membuff *mb); +int membuf_getbyte(struct membuf *mb); /** - * membuff_peekbyte() - check the next available byte + * membuf_peekbyte() - check the next available byte * - * Return the next byte which membuff_getbyte() would return, without + * Return the next byte which membuf_getbyte() would return, without * removing it from the membuff. * * @mb: membuff to adjust * Return: the byte peeked, or -1 if the membuff is empty */ -int membuff_peekbyte(struct membuff *mb); +int membuf_peekbyte(struct membuf *mb); /** - * membuff_get() - get data from a membuff + * membuf_get() - get data from a membuff * * Copies any available data (up to @maxlen bytes) to @buff and removes it * from the membuff. @@ -122,10 +124,10 @@ int membuff_peekbyte(struct membuff *mb); * @maxlen: maximum number of bytes to read * Return: the number of bytes read */ -int membuff_get(struct membuff *mb, char *buff, int maxlen); +int membuf_get(struct membuf *mb, char *buff, int maxlen); /** - * membuff_put() - write data to a membuff + * membuf_put() - write data to a membuff * * Writes some data to a membuff. Returns the number of bytes added. If this * is less than @lnehgt, then the membuff got full @@ -135,36 +137,36 @@ int membuff_get(struct membuff *mb, char *buff, int maxlen); * @length: number of bytes to write from 'data' * Return: the number of bytes added */ -int membuff_put(struct membuff *mb, const char *buff, int length); +int membuf_put(struct membuf *mb, const char *buff, int length); /** - * membuff_isempty() - check if a membuff is empty + * membuf_isempty() - check if a membuff is empty * * @mb: membuff to check * Return: true if empty, else false */ -bool membuff_isempty(struct membuff *mb); +bool membuf_isempty(struct membuf *mb); /** - * membuff_avail() - check available data in a membuff + * membuf_avail() - check available data in a membuff * * @mb: membuff to check * Return: number of bytes of data available */ -int membuff_avail(struct membuff *mb); +int membuf_avail(struct membuf *mb); /** - * membuff_size() - get the size of a membuff + * membuf_size() - get the size of a membuff * * Note that a membuff can only old data up to one byte less than its size. * * @mb: membuff to check * Return: total size */ -int membuff_size(struct membuff *mb); +int membuf_size(struct membuf *mb); /** - * membuff_makecontig() - adjust all membuff data to be contiguous + * membuf_makecontig() - adjust all membuff data to be contiguous * * This places all data in a membuff into a single contiguous lump, if * possible @@ -172,18 +174,18 @@ int membuff_size(struct membuff *mb); * @mb: membuff to adjust * Return: true on success */ -bool membuff_makecontig(struct membuff *mb); +bool membuf_makecontig(struct membuf *mb); /** - * membuff_free() - find the number of bytes that can be written to a membuff + * membuf_free() - find the number of bytes that can be written to a membuff * * @mb: membuff to check * Return: returns the number of bytes free in a membuff */ -int membuff_free(struct membuff *mb); +int membuf_free(struct membuf *mb); /** - * membuff_readline() - read a line of text from a membuff + * membuf_readline() - read a line of text from a membuff * * Reads a line of text of up to 'maxlen' characters from a membuff and puts * it in @str. Any character less than @minch is assumed to be the end of @@ -192,14 +194,16 @@ int membuff_free(struct membuff *mb); * @mb: membuff to adjust * @str: Place to put the line * @maxlen: Maximum line length (excluding terminator) + * @minch: Minimum ASCII character to permit as part of the line (e.g. ' ') * @must_fit: If true then str is empty if line doesn't fit * Return: number of bytes read (including terminator) if a line has been * read, 0 if nothing was there or line didn't fit when must_fit is set */ -int membuff_readline(struct membuff *mb, char *str, int maxlen, int minch, bool must_fit); +int membuf_readline(struct membuf *mb, char *str, int maxlen, int minch, + bool must_fit); /** - * membuff_extend_by() - expand a membuff + * membuf_extend_by() - expand a membuff * * Extends a membuff by the given number of bytes * @@ -209,38 +213,38 @@ int membuff_readline(struct membuff *mb, char *str, int maxlen, int minch, bool * Return: 0 if the expand succeeded, -ENOMEM if not enough memory, -E2BIG * if the the size would exceed @max */ -int membuff_extend_by(struct membuff *mb, int by, int max); +int membuf_extend_by(struct membuf *mb, int by, int max); /** - * membuff_init() - set up a new membuff using an existing membuff + * membuf_init() - set up a new membuff using an existing membuff * * @mb: membuff to set up * @buff: Address of buffer * @size: Size of buffer */ -void membuff_init(struct membuff *mb, char *buff, int size); +void membuf_init(struct membuf *mb, char *buff, int size); /** - * membuff_uninit() - clear a membuff so it can no longer be used + * membuf_uninit() - clear a membuff so it can no longer be used * * @mb: membuff to uninit */ -void membuff_uninit(struct membuff *mb); +void membuf_uninit(struct membuf *mb); /** - * membuff_new() - create a new membuff + * membuf_new() - create a new membuff * * @mb: membuff to init * @size: size of membuff to create * Return: 0 if OK, -ENOMEM if out of memory */ -int membuff_new(struct membuff *mb, int size); +int membuf_new(struct membuf *mb, int size); /** - * membuff_dispose() - free memory allocated to a membuff and uninit it + * membuf_dispose() - free memory allocated to a membuff and uninit it * * @mb: membuff to dispose */ -void membuff_dispose(struct membuff *mb); +void membuf_dispose(struct membuf *mb); #endif diff --git a/lib/Makefile b/lib/Makefile index a30ce1595d5..41de2671cc6 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -125,7 +125,7 @@ obj-y += hang.o obj-y += linux_compat.o obj-y += linux_string.o obj-$(CONFIG_$(PHASE_)LMB) += lmb.o -obj-y += membuff.o +obj-y += membuf.o obj-$(CONFIG_REGEX) += slre.o obj-y += string.o obj-y += tables_csum.o diff --git a/lib/membuff.c b/lib/membuf.c index b242a38ff1c..f38ff36cb0b 100644 --- a/lib/membuff.c +++ b/lib/membuf.c @@ -9,17 +9,17 @@ #include <errno.h> #include <log.h> #include <malloc.h> -#include "membuff.h" +#include "membuf.h" -void membuff_purge(struct membuff *mb) +void membuf_purge(struct membuf *mb) { /* set mb->head and mb->tail so the buffers look empty */ mb->head = mb->start; mb->tail = mb->start; } -static int membuff_putrawflex(struct membuff *mb, int maxlen, bool update, - char ***data, int *offsetp) +static int membuf_putrawflex(struct membuf *mb, int maxlen, bool update, + char ***data, int *offsetp) { int len; @@ -72,30 +72,30 @@ static int membuff_putrawflex(struct membuff *mb, int maxlen, bool update, return len; } -int membuff_putraw(struct membuff *mb, int maxlen, bool update, char **data) +int membuf_putraw(struct membuf *mb, int maxlen, bool update, char **data) { char **datap; int offset; int size; - size = membuff_putrawflex(mb, maxlen, update, &datap, &offset); + size = membuf_putrawflex(mb, maxlen, update, &datap, &offset); *data = *datap + offset; return size; } -bool membuff_putbyte(struct membuff *mb, int ch) +bool membuf_putbyte(struct membuf *mb, int ch) { char *data; - if (membuff_putraw(mb, 1, true, &data) != 1) + if (membuf_putraw(mb, 1, true, &data) != 1) return false; *data = ch; return true; } -int membuff_getraw(struct membuff *mb, int maxlen, bool update, char **data) +int membuf_getraw(struct membuf *mb, int maxlen, bool update, char **data) { int len; @@ -146,21 +146,21 @@ int membuff_getraw(struct membuff *mb, int maxlen, bool update, char **data) return len; } -int membuff_getbyte(struct membuff *mb) +int membuf_getbyte(struct membuf *mb) { char *data = 0; - return membuff_getraw(mb, 1, true, &data) != 1 ? -1 : *(uint8_t *)data; + return membuf_getraw(mb, 1, true, &data) != 1 ? -1 : *(uint8_t *)data; } -int membuff_peekbyte(struct membuff *mb) +int membuf_peekbyte(struct membuf *mb) { char *data = 0; - return membuff_getraw(mb, 1, false, &data) != 1 ? -1 : *(uint8_t *)data; + return membuf_getraw(mb, 1, false, &data) != 1 ? -1 : *(uint8_t *)data; } -int membuff_get(struct membuff *mb, char *buff, int maxlen) +int membuf_get(struct membuf *mb, char *buff, int maxlen) { char *data = 0, *buffptr = buff; int len = 1, i; @@ -171,7 +171,7 @@ int membuff_get(struct membuff *mb, char *buff, int maxlen) */ for (i = 0; len && i < 2; i++) { /* get a pointer to the data available */ - len = membuff_getraw(mb, maxlen, true, &data); + len = membuf_getraw(mb, maxlen, true, &data); /* copy it into the buffer */ memcpy(buffptr, data, len); @@ -183,14 +183,14 @@ int membuff_get(struct membuff *mb, char *buff, int maxlen) return buffptr - buff; } -int membuff_put(struct membuff *mb, const char *buff, int length) +int membuf_put(struct membuf *mb, const char *buff, int length) { char *data; int towrite, i, written; for (i = written = 0; i < 2; i++) { /* ask where some data can be written */ - towrite = membuff_putraw(mb, length, true, &data); + towrite = membuf_putraw(mb, length, true, &data); /* and write it, updating the bytes length */ memcpy(data, buff, towrite); @@ -203,14 +203,14 @@ int membuff_put(struct membuff *mb, const char *buff, int length) return written; } -bool membuff_isempty(struct membuff *mb) +bool membuf_isempty(struct membuf *mb) { return mb->head == mb->tail; } -int membuff_avail(struct membuff *mb) +int membuf_avail(struct membuf *mb) { - struct membuff copy; + struct membuf copy; int i, avail; char *data = 0; @@ -219,18 +219,18 @@ int membuff_avail(struct membuff *mb) /* now read everything out of the copied buffer */ for (i = avail = 0; i < 2; i++) - avail += membuff_getraw(©, -1, true, &data); + avail += membuf_getraw(©, -1, true, &data); /* and return how much we read */ return avail; } -int membuff_size(struct membuff *mb) +int membuf_size(struct membuf *mb) { return mb->end - mb->start; } -bool membuff_makecontig(struct membuff *mb) +bool membuf_makecontig(struct membuf *mb) { int topsize, botsize; @@ -281,13 +281,14 @@ bool membuff_makecontig(struct membuff *mb) return true; } -int membuff_free(struct membuff *mb) +int membuf_free(struct membuf *mb) { return mb->end == mb->start ? 0 : - (mb->end - mb->start) - 1 - membuff_avail(mb); + (mb->end - mb->start) - 1 - membuf_avail(mb); } -int membuff_readline(struct membuff *mb, char *str, int maxlen, int minch, bool must_fit) +int membuf_readline(struct membuf *mb, char *str, int maxlen, int minch, + bool must_fit) { int len; /* number of bytes read (!= string length) */ char *s, *end; @@ -322,7 +323,7 @@ int membuff_readline(struct membuff *mb, char *str, int maxlen, int minch, bool return len; } -int membuff_extend_by(struct membuff *mb, int by, int max) +int membuf_extend_by(struct membuf *mb, int by, int max) { int oldhead, oldtail; int size, orig; @@ -358,32 +359,32 @@ int membuff_extend_by(struct membuff *mb, int by, int max) return 0; } -void membuff_init(struct membuff *mb, char *buff, int size) +void membuf_init(struct membuf *mb, char *buff, int size) { mb->start = buff; mb->end = mb->start + size; - membuff_purge(mb); + membuf_purge(mb); } -int membuff_new(struct membuff *mb, int size) +int membuf_new(struct membuf *mb, int size) { mb->start = malloc(size); if (!mb->start) return -ENOMEM; - membuff_init(mb, mb->start, size); + membuf_init(mb, mb->start, size); return 0; } -void membuff_uninit(struct membuff *mb) +void membuf_uninit(struct membuf *mb) { mb->end = NULL; mb->start = NULL; - membuff_purge(mb); + membuf_purge(mb); } -void membuff_dispose(struct membuff *mb) +void membuf_dispose(struct membuf *mb) { - free(&mb->start); - membuff_uninit(mb); + free(mb->start); + membuf_uninit(mb); } diff --git a/test/lib/Makefile b/test/lib/Makefile index 0e4cb8e3dfd..aa89923f786 100644 --- a/test/lib/Makefile +++ b/test/lib/Makefile @@ -14,6 +14,7 @@ obj-y += hexdump.o obj-$(CONFIG_SANDBOX) += kconfig.o obj-y += lmb.o obj-$(CONFIG_HAVE_SETJMP) += longjmp.o +obj-$(CONFIG_SANDBOX) += membuf.o obj-$(CONFIG_CONSOLE_RECORD) += test_print.o obj-$(CONFIG_SSCANF) += sscanf.o obj-$(CONFIG_$(PHASE_)STRTO) += str.o diff --git a/test/lib/membuf.c b/test/lib/membuf.c new file mode 100644 index 00000000000..3f268a422d5 --- /dev/null +++ b/test/lib/membuf.c @@ -0,0 +1,239 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2024 Google LLC + * Written by Simon Glass <sjg@chromium.org> + */ + +#include <membuf.h> +#include <os.h> +#include <rand.h> +#include <string.h> +#include <test/lib.h> +#include <test/test.h> +#include <test/ut.h> + +#define TEST_SIZE 16 +#define TEST_COUNT 10000 + +static void membuf_zero(struct membuf *mb) +{ + memset(mb->start, '\0', mb->end - mb->start); +} + +static int membuf_check(struct unit_test_state *uts, struct membuf *mb, + int value) +{ + /* head is out of range */ + ut_assert(!(mb->head < mb->start || mb->head >= mb->end)); + + /* tail is out of range */ + ut_assert(!(mb->tail < mb->start || mb->tail >= mb->end)); + + return 0; +} + +/* write from 1 to test_size bytes, and check they come back OK */ +static int lib_test_membuf_one(struct unit_test_state *uts) +{ + char in[TEST_SIZE * 2], out[TEST_SIZE * 2]; + struct membuf mb; + int size, ret, test_size, i; + + ut_assertok(membuf_new(&mb, TEST_SIZE)); + + /* setup in test */ + for (i = 0; i < TEST_SIZE; i++) { + in[i] = (i & 63) + '0'; + in[i + TEST_SIZE] = in[i]; + } + + test_size = TEST_SIZE; + + for (i = 1; i < TEST_COUNT; i++) { + membuf_zero(&mb); + size = rand() % test_size; + + // now write patterns and check they come back OK + ret = membuf_put(&mb, in, 0); + ret = membuf_put(&mb, in, size); + ut_asserteq(size, ret); + + ret = membuf_put(&mb, in, 0); + ut_assertok(membuf_check(uts, &mb, i)); + + ret = membuf_get(&mb, out, 0); + ret = membuf_get(&mb, out, size); + ut_asserteq(size, ret); + + ret = membuf_get(&mb, out, 0); + ut_assertok(membuf_check(uts, &mb, i)); + + ut_asserteq_mem(in, out, size); + } + + return 0; +} +LIB_TEST(lib_test_membuf_one, 0); + +/* write random number of bytes, and check they come back OK */ +static int lib_test_membuf_random(struct unit_test_state *uts) +{ + char in[TEST_SIZE * 2]; + char buf[TEST_SIZE * 2]; + struct membuf mb; + int size, ret, test_size, i; + char *inptr, *outptr; + int max_avail, min_free; + + ut_assertok(membuf_new(&mb, TEST_SIZE)); + + for (i = 0; i < TEST_SIZE; i++) { + in[i] = (i & 63) + '0'; + in[i + TEST_SIZE] = in[i]; + } + + test_size = TEST_SIZE; + + inptr = in; + outptr = in; + min_free = TEST_COUNT; + max_avail = 0; + membuf_zero(&mb); + for (i = 0; i < TEST_COUNT; i++) { + size = rand() % test_size; + + if (membuf_free(&mb) < min_free) + min_free = membuf_free(&mb); + + ret = membuf_put(&mb, inptr, size); + ut_assertok(membuf_check(uts, &mb, i)); + inptr += ret; + if (inptr >= in + TEST_SIZE) + inptr -= TEST_SIZE; + + size = rand() % (test_size - 1); + + if (membuf_avail(&mb) > max_avail) + max_avail = membuf_avail(&mb); + + ret = membuf_get(&mb, buf, size); + ut_assertok(membuf_check(uts, &mb, i)); + ut_asserteq_mem(buf, outptr, ret); + + outptr += ret; + if (outptr >= in + TEST_SIZE) + outptr -= TEST_SIZE; + } + + return 0; +} +LIB_TEST(lib_test_membuf_random, 0); + +/* test membuf_extend() with split segments */ +static int lib_test_membuf_extend(struct unit_test_state *uts) +{ + char in[TEST_SIZE * 2]; + char buf[TEST_SIZE * 2]; + struct membuf mb; + int ret, test_size, i, cur; + char *data; + + ut_assertok(membuf_new(&mb, TEST_SIZE)); + + for (i = 0; i < TEST_SIZE; i++) { + in[i] = (i & 63) + '0'; + in[i + TEST_SIZE] = in[i]; + } + + test_size = TEST_SIZE - 1; + + for (cur = 0; cur <= test_size; cur++) { + ut_assertok(membuf_new(&mb, TEST_SIZE)); + + membuf_zero(&mb); + + /* + * add some bytes, then remove them - this will force the membuf + * to have data split into two segments when we fill it + */ + ret = membuf_putraw(&mb, TEST_SIZE / 2, true, &data); + membuf_getraw(&mb, ret, true, &data); + ut_asserteq(TEST_SIZE / 2, ret); + + /* fill it */ + ret = membuf_put(&mb, in, cur); + ut_assertok(membuf_check(uts, &mb, cur)); + ut_asserteq(cur, ret); + + /* extend the buffer */ + ut_assertok(membuf_extend_by(&mb, TEST_SIZE, -1)); + ut_assertok(membuf_check(uts, &mb, cur)); + + /* check our data is still there */ + ret = membuf_get(&mb, buf, TEST_SIZE * 2); + ut_assertok(membuf_check(uts, &mb, cur)); + ut_asserteq(cur, ret); + ut_asserteq_mem(in, buf, cur); + membuf_uninit(&mb); + } + + return 0; +} +LIB_TEST(lib_test_membuf_extend, 0); + +/* test membuf_readline() with generated data */ +static int lib_test_membuf_readline(struct unit_test_state *uts) +{ + char *buf; + int size, cur, i, ret, readptr, cmpptr; + struct membuf mb; + char *data; + char str[256]; + char *s; + + ut_assertok(membuf_new(&mb, 1024)); + membuf_zero(&mb); + + /* Use the README as test data */ + ut_assertok(os_read_file("README", (void **)&buf, &size)); + + cur = 0; + readptr = 0; + cmpptr = 0; + for (i = 0; i < 100000; i++, cur += 1) { + /* fill the buffer with up to 'cur' bytes */ + ret = membuf_putraw(&mb, cur, false, &data); + + if (ret > 0) { + int can_read = min(ret, size - readptr); + + memcpy(data, &buf[readptr], can_read); + readptr += can_read; + + membuf_putraw(&mb, can_read, true, &data); + ut_assertok(membuf_check(uts, &mb, i)); + } + + /* read a line and compare */ + ret = membuf_readline(&mb, str, 256, 0, true); + ut_assertok(membuf_check(uts, &mb, i)); + if (ret) { + char *ptr; + + s = &buf[cmpptr]; + ptr = strchr(s, '\n'); + *ptr = '\0'; + + ut_asserteq_str(s, str); + cmpptr += strlen(s) + 1; + *ptr = '\n'; + } else { + ut_assert(membuf_free(&mb)); + } + } + membuf_dispose(&mb); + os_free(buf); + + return 0; +} +LIB_TEST(lib_test_membuf_readline, 0); |