Mercurial > illumos > git > illumos-gate
changeset 19376:50a678a2c678
12178 Allow bytes to be removed from a custr
Reviewed by: Toomas Soome <tsoome@me.com>
Reviewed by: Andy Fiddaman <andy@omniosce.org>
Approved by: Gordon Ross <gwr@nexenta.com>
author | Jason King <jason.king@joyent.com> |
---|---|
date | Thu, 09 Jan 2020 10:59:44 -0600 |
parents | 0ec870e4a0af |
children | ce42a2836d9d |
files | usr/src/lib/libcustr/common/custr.c usr/src/lib/libcustr/common/libcustr.h usr/src/lib/libcustr/common/mapfile-vers usr/src/pkg/manifests/system-test-utiltest.mf usr/src/test/util-tests/runfiles/default.run usr/src/test/util-tests/tests/Makefile usr/src/test/util-tests/tests/libcustr/Makefile usr/src/test/util-tests/tests/libcustr/custr_remove.c usr/src/test/util-tests/tests/libcustr/custr_trunc.c |
diffstat | 9 files changed, 324 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/lib/libcustr/common/custr.c Wed Dec 18 08:05:59 2019 -0800 +++ b/usr/src/lib/libcustr/common/custr.c Thu Jan 09 10:59:44 2020 -0600 @@ -14,7 +14,7 @@ */ /* - * Copyright 2019 Joyent, Inc. + * Copyright 2020 Joyent, Inc. */ #include <stdlib.h> @@ -85,6 +85,81 @@ cus->cus_data[0] = '\0'; } +int +custr_remove(custr_t *cus, size_t idx, size_t len) +{ + size_t endidx = idx + len; + + /* + * Once gcc4 is dropped as a shadow compiler, we can migrate to + * using builtins for the overflow check. + */ + if (endidx < idx || endidx < len) { + errno = EINVAL; + return (-1); + } + + if (idx >= cus->cus_strlen || endidx > cus->cus_strlen) { + errno = EINVAL; + return (-1); + } + + if (len == 0) + return (0); + + /* The +1 will include the terminating NUL in the move */ + (void) memmove(cus->cus_data + idx, cus->cus_data + endidx, + cus->cus_strlen - endidx + 1); + cus->cus_strlen -= len; + + /* The result should be NUL */ + VERIFY0(cus->cus_data[cus->cus_strlen]); + return (0); +} + +int +custr_rremove(custr_t *cus, size_t ridx, size_t len) +{ + size_t idx; + + if (ridx >= cus->cus_strlen) { + errno = EINVAL; + return (-1); + } + + idx = cus->cus_strlen - ridx - 1; + return (custr_remove(cus, idx, len)); +} + +int +custr_trunc(custr_t *cus, size_t idx) +{ + if (idx >= cus->cus_strlen) { + errno = EINVAL; + return (-1); + } + + cus->cus_data[idx] = '\0'; + cus->cus_strlen = idx; + return (0); +} + +int +custr_rtrunc(custr_t *cus, size_t ridx) +{ + size_t idx; + + if (ridx >= cus->cus_strlen) { + errno = EINVAL; + return (-1); + } + + idx = cus->cus_strlen - ridx - 1; + cus->cus_data[idx] = '\0'; + cus->cus_strlen = idx; + return (0); +} + size_t custr_len(custr_t *cus) {
--- a/usr/src/lib/libcustr/common/libcustr.h Wed Dec 18 08:05:59 2019 -0800 +++ b/usr/src/lib/libcustr/common/libcustr.h Thu Jan 09 10:59:44 2020 -0600 @@ -10,7 +10,7 @@ */ /* - * Copyright 2019, Joyent, Inc. + * Copyright 2019 Joyent, Inc. */ #ifndef _LIBCUSTR_H @@ -142,6 +142,52 @@ void custr_reset(custr_t *); /* + * custr_remove(cus, idx, len) + * + * Remove len bytes from cus, starting at idx. + * + * Returns 0 on success or -1 on failure. On failure, errno will be set to: + * EINVAL Either the idx or len parameter is invalid + * + */ +int custr_remove(custr_t *, size_t, size_t); + +/* + * custr_rremove(cus, idx, len) + * + * Remove len bytes from cus, starting at idx relative to the end of cus. + * That is, 0 = last byte of cus, 1 = second to last byte of cus, ...). + * The direction of removal is always towards the end of the string. I.e. + * 'custr_rremove(cus, 1, 2)' removes the last two bytes of cus. + * + * Returns 0 on success or -1 on failure. On failure, errno will be set to: + * EINVAL Either the idx or len parameter is invalid + * + */ +int custr_rremove(custr_t *, size_t, size_t); + +/* + * custr_trunc(cus, idx) + * + * Truncate cus starting at idx. + * + * Returns 0 on success or -1 on failure. On failure, errno is set to: + * EINVAL The idx value was invalid. + */ +int custr_trunc(custr_t *, size_t); + +/* + * custr_rtrunc(cus, idx) + * + * Truncate cus starting at idx relative to the end of cus (similar to how + * the idx paramter is treated with custr_rremove()). + * + * Returns 0 on success or -1 on failure. On failure, errno is set to: + * EINVAL The idx value was invalid. + */ +int custr_rtrunc(custr_t *, size_t); + +/* * Retrieve a const pointer to a NUL-terminated string version of the contents * of the dynamic string. Storage for this string should not be freed, and * the pointer will be invalidated by any mutations to the dynamic string.
--- a/usr/src/lib/libcustr/common/mapfile-vers Wed Dec 18 08:05:59 2019 -0800 +++ b/usr/src/lib/libcustr/common/mapfile-vers Thu Jan 09 10:59:44 2020 -0600 @@ -10,7 +10,7 @@ # # -# Copyright 2019, Joyent, Inc. +# Copyright 2019 Joyent, Inc. # # @@ -42,7 +42,11 @@ custr_cstr; custr_free; custr_len; + custr_remove; custr_reset; + custr_rremove; + custr_rtrunc; + custr_trunc; custr_xalloc; custr_xalloc_buf; local:
--- a/usr/src/pkg/manifests/system-test-utiltest.mf Wed Dec 18 08:05:59 2019 -0800 +++ b/usr/src/pkg/manifests/system-test-utiltest.mf Thu Jan 09 10:59:44 2020 -0600 @@ -13,9 +13,8 @@ # Copyright (c) 2012 by Delphix. All rights reserved. # Copyright 2014, OmniTI Computer Consulting, Inc. All rights reserved. # Copyright 2014 Nexenta Systems, Inc. All rights reserved. -# Copyright 2019, Joyent, Inc. +# Copyright 2020 Joyent, Inc. # Copyright 2017 Jason King. -# Copyright 2018, Joyent, Inc. # Copyright 2019 OmniOS Community Edition (OmniOSce) Association. # @@ -56,6 +55,7 @@ dir path=opt/util-tests/tests/files/make_a/b dir path=opt/util-tests/tests/files/make_a/c dir path=opt/util-tests/tests/files/make_l +dir path=opt/util-tests/tests/libcustr dir path=opt/util-tests/tests/libnvpair_json dir path=opt/util-tests/tests/libsff dir path=opt/util-tests/tests/mergeq @@ -1423,6 +1423,8 @@ file path=opt/util-tests/tests/files/testnl mode=0444 file path=opt/util-tests/tests/grep_test mode=0555 file path=opt/util-tests/tests/iconv_test mode=0555 +file path=opt/util-tests/tests/libcustr/custr_remove mode=0555 +file path=opt/util-tests/tests/libcustr/custr_trunc mode=0555 file path=opt/util-tests/tests/libjedec_test mode=0555 file path=opt/util-tests/tests/libnvpair_json/json_00_blank mode=0555 file path=opt/util-tests/tests/libnvpair_json/json_01_boolean mode=0555
--- a/usr/src/test/util-tests/runfiles/default.run Wed Dec 18 08:05:59 2019 -0800 +++ b/usr/src/test/util-tests/runfiles/default.run Thu Jan 09 10:59:44 2020 -0600 @@ -70,3 +70,6 @@ [/opt/util-tests/tests/ctf] pre = precheck tests = [ 'ctftest' ] + +[/opt/util-tests/tests/libcustr] +tests = ['custr_remove', 'custr_trunc']
--- a/usr/src/test/util-tests/tests/Makefile Wed Dec 18 08:05:59 2019 -0800 +++ b/usr/src/test/util-tests/tests/Makefile Thu Jan 09 10:59:44 2020 -0600 @@ -14,11 +14,12 @@ # Copyright 2014 Garrett D'Amore <garrett@damore.org> # Copyright 2014 Nexenta Systems, Inc. All rights reserved. # Copyright 2017 Jason King -# Copyright 2019 Joyent, Inc. +# Copyright 2020 Joyent, Inc. # Copyright 2019 OmniOS Community Edition (OmniOSce) Association. # SUBDIRS = date dis dladm iconv libnvpair_json libsff printf xargs grep_xpg4 SUBDIRS += demangle mergeq workq chown ctf smbios libjedec awk make sleep +SUBDIRS += libcustr include $(SRC)/test/Makefile.com
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/test/util-tests/tests/libcustr/Makefile Thu Jan 09 10:59:44 2020 -0600 @@ -0,0 +1,50 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2019 Joyent, Inc. +# + +include $(SRC)/Makefile.master + +ROOTOPTPKG = $(ROOT)/opt/util-tests +TESTDIR = $(ROOTOPTPKG)/tests/libcustr + +PROGS = custr_remove custr_trunc + +include $(SRC)/cmd/Makefile.cmd +include $(SRC)/test/Makefile.com + +CMDS = $(PROGS:%=$(TESTDIR)/%) +$(CMDS) := FILEMODE = 0555 + +LDLIBS += -lcustr + +all: $(PROGS) + +install: all $(CMDS) $(OUTFILES) + +clobber: clean + -$(RM) $(PROGS) + +clean: + +$(CMDS): $(TESTDIR) $(PROG) + +$(TESTDIR): + $(INS.dir) + +$(TESTDIR)/%: % + $(INS.file) + +%: %.c + $(LINK.c) -o $@ $< $(LDLIBS) + $(POST_PROCESS)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/test/util-tests/tests/libcustr/custr_remove.c Thu Jan 09 10:59:44 2020 -0600 @@ -0,0 +1,73 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2019 Joyent, Inc. + */ + +#include <errno.h> +#include <libcustr.h> +#include <limits.h> +#include <stdio.h> +#include <string.h> +#include <sys/debug.h> + +static void +expect(const char *var, custr_t *cu, const char *str, const char *file, + size_t line) +{ + if (strcmp(custr_cstr(cu), str) == 0) + return; + + char msgbuf[256]; + + (void) snprintf(msgbuf, sizeof (msgbuf), "%s == '%s' ('%s' == '%s')", + var, str, custr_cstr(cu), str); + + (void) assfail(msgbuf, file, line); +} + +#define EXPECT(_cu, _str) expect(#_cu, _cu, _str, __FILE__, __LINE__) +#define FAIL(_expr, _ev) \ + VERIFY3S(_expr, ==, -1); \ + VERIFY3S(errno, ==, (_ev)) + +int +main(void) +{ + custr_t *cu; + + VERIFY0(custr_alloc(&cu)); + + VERIFY0(custr_append(cu, "12345")); + EXPECT(cu, "12345"); + + FAIL(custr_remove(cu, 6, 2), EINVAL); + FAIL(custr_remove(cu, 2, 10), EINVAL); + FAIL(custr_rremove(cu, 6, 2), EINVAL); + FAIL(custr_rremove(cu, 2, 10), EINVAL); + + VERIFY0(custr_remove(cu, 0, 1)); + EXPECT(cu, "2345"); + VERIFY0(custr_rremove(cu, 1, 2)); + EXPECT(cu, "23"); + + VERIFY0(custr_append(cu, "456")); + EXPECT(cu, "23456"); + + VERIFY0(custr_remove(cu, 1, 2)); + EXPECT(cu, "256"); + + VERIFY0(custr_rremove(cu, 1, 2)); + EXPECT(cu, "2"); + + return (0); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/test/util-tests/tests/libcustr/custr_trunc.c Thu Jan 09 10:59:44 2020 -0600 @@ -0,0 +1,64 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2019 Joyent, Inc. + */ + +#include <errno.h> +#include <libcustr.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/debug.h> + +static void +expect(const char *var, custr_t *cu, const char *str, const char *file, + size_t line) +{ + if (strcmp(custr_cstr(cu), str) == 0) + return; + + char msgbuf[256]; + + (void) snprintf(msgbuf, sizeof (msgbuf), "%s == '%s' ('%s' == '%s')", + var, str, custr_cstr(cu), str); + + (void) assfail(msgbuf, file, line); +} + +#define EXPECT(_cu, _str) expect(#_cu, _cu, _str, __FILE__, __LINE__) +#define FAIL(_expr, _ev) \ + VERIFY3S(_expr, ==, -1); \ + VERIFY3S(errno, ==, (_ev)) + +int +main(void) +{ + custr_t *cu; + + VERIFY0(custr_alloc(&cu)); + + VERIFY0(custr_append(cu, "12345")); + EXPECT(cu, "12345"); + + FAIL(custr_trunc(cu, 6), EINVAL); + FAIL(custr_rtrunc(cu, 10), EINVAL); + + VERIFY0(custr_trunc(cu, 3)); + EXPECT(cu, "123"); + + VERIFY0(custr_rtrunc(cu, 1)); + EXPECT(cu, "1"); + + return (0); +}