From patchwork Sun Apr 6 22:12:08 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Grant Erickson X-Patchwork-Id: 14039546 Received: from mail5.g24.pair.com (mail5.g24.pair.com [66.39.139.36]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BBE65197A8A for ; Sun, 6 Apr 2025 22:12:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=66.39.139.36 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743977541; cv=none; b=SmX0fXxcsL8PnVIEFN/07ebdf9npRMZBRtWkCcr3OjvJ600W1rfe+b+rWzjQJYiFm/au+1fJTUdaoLlqrmZFT0Mc+cMJEL9ZdATRjvPm3AKjN3GXKRqAv7cUagSV8WCCMgeumcyGaMAaYyS8buwzFuV1Y7Nbgu7JbewE+RNgtEM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743977541; c=relaxed/simple; bh=1zK0SXp2bVKtbi46qB44vt8W/6UouDirQ7CTYIZPX/c=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=TdPhw4ghSQAY4L0vlXPIX5hZ6HWGWOSUl9TqMio4WKq4P0sPZ7XtwiE5SXnB+pZAf2UxCXl0GCI0WJ7CLzGsMwPdBf879S9fc517aVQGoS77Puq6sdCPJ09Jwyw+hF8wGVGiRCd2YEDWKWxrgoi8QXU3mgyZoeMCpusa+IOTymg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=nuovations.com; spf=pass smtp.mailfrom=nuovations.com; dkim=pass (2048-bit key) header.d=nuovations.com header.i=@nuovations.com header.b=V7VNbLQ4; arc=none smtp.client-ip=66.39.139.36 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=nuovations.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=nuovations.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=nuovations.com header.i=@nuovations.com header.b="V7VNbLQ4" Received: from mail5.g24.pair.com (localhost [127.0.0.1]) by mail5.g24.pair.com (Postfix) with ESMTP id 877C4164A15 for ; Sun, 6 Apr 2025 18:12:17 -0400 (EDT) Received: from localhost.localdomain (c-73-202-173-252.hsd1.ca.comcast.net [73.202.173.252]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mail5.g24.pair.com (Postfix) with ESMTPSA id 3D2541260D8 for ; Sun, 6 Apr 2025 18:12:17 -0400 (EDT) From: Grant Erickson To: ell@lists.linux.dev Subject: [PATCH v6 1/8] edit: Initial revision. Date: Sun, 6 Apr 2025 15:12:08 -0700 Message-ID: X-Mailer: git-send-email 2.45.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: ell@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nuovations.com; h=from:to:subject:date:message-id:in-reply-to:references:mime-version:content-transfer-encoding; s=pair-202401062137; bh=x+lW2GeFPlu8dIlQvrQOHf91e5oBDpFJr4s1H5V9S0E=; b=V7VNbLQ4IUVjU/Pw2U0+AgXtR6M1nA5+vSWmzXLhM4pN7eHhQ8XaKPmnUojwOpual/7eDgs0nwz6sBvgQxGb2XNhDYc2RlKqte9QcZzkNxzV3bIG9WbK8YaySWzgN/hQgAq9IOojKqhl948nnxU3brNoV1TLUqWsSUMiiq6HyTbMATybimQ1E7hc2kxRICop0Y9Jfaxwp9JBx4nPcyqdVtasc7jaKWlDWqsxl+4/gx/hAFx6wYmrNpvh1wHuOR0lrlPRcV1DpAzsKYj69qbg6YJooVU7QfptyBYwyLmLB3zyLHGR7l2GUL0iALkLjU9LnXSdF0a6qHikKgyyynbpFA== X-Scanned-By: mailmunge 3.10 on 66.39.139.36 Initial revision of 'edit.[hc]', a line editor. --- ell/edit.c | 785 +++++++++++++++++++++++++++++++++++++++++++++++++++++ ell/edit.h | 59 ++++ 2 files changed, 844 insertions(+) create mode 100644 ell/edit.c create mode 100644 ell/edit.h diff --git a/ell/edit.c b/ell/edit.c new file mode 100644 index 000000000000..899fea4da830 --- /dev/null +++ b/ell/edit.c @@ -0,0 +1,785 @@ +/* + * Embedded Linux library + * Copyright (C) 2023 Intel Corporation + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include + +#include "private.h" +#include "string.h" +#include "edit.h" + +#define DEFAULT_BUFFER_SIZE (15) + +struct input_buf { + wchar_t *buf; + size_t size; + size_t len; + size_t pos; + struct input_buf *next; +}; + +struct l_edit { + struct input_buf *head; + struct input_buf *main; + size_t list_count; + size_t max_list_size; + size_t max_input_len; + size_t max_display_len; + l_edit_display_func_t display_handler; + void *display_data; + l_edit_debug_func_t debug_handler; + void *debug_data; +}; + +static inline size_t next_power(size_t len) +{ + size_t n = 1; + + if (len > SIZE_MAX / 2) + return SIZE_MAX; + + while (n < len) + n = n << 1; + + return n; +} + +static void grow_input_buf(struct input_buf *buf, size_t extra) +{ + if (buf->len + extra < buf->size) + return; + + buf->size = next_power(buf->len + extra + 1); + buf->buf = l_realloc(buf->buf, sizeof(wchar_t) * buf->size); +} + +static struct input_buf *alloc_sized_input_buf(size_t initial_size) +{ + struct input_buf *buf; + + buf = l_new(struct input_buf, 1); + + /* Set up new input buffer with initial size */ + buf->size = initial_size + 1; + buf->buf = l_malloc(sizeof(wchar_t) * buf->size); + buf->buf[0] = L'\0'; + buf->pos = 0; + buf->len = 0; + buf->next = NULL; + + return buf; +} + +static struct input_buf *alloc_duplicate_input_buf(struct input_buf *ref) +{ + struct input_buf *buf; + + if (!ref) + return NULL; + + buf = l_new(struct input_buf, 1); + + /* Set up new input buffer and copy from the reference */ + buf->size = ref->len; + buf->buf = wcsdup(ref->buf); + buf->pos = ref->len; + buf->len = ref->len; + buf->next = NULL; + + return buf; +} + +static void reset_input_buf(struct input_buf *buf, const char *input) +{ + if (input) { + size_t len; + + /* Calculate the required size of the wide character string + * including its terminating null character. + */ + len = mbstowcs(NULL, input, 0) + 1; + + /* If the current buffer is to small, then allocate a new + * one and free the previous one. Since in most cases the + * data is different, there is no need for using re-alloc + * procedure here. + */ + if (len > buf->size) { + l_free(buf->buf); + + buf->size = len; + buf->buf = l_malloc(sizeof(wchar_t) * buf->size); + } + + /* Convert the multibyte input into a wide character string + * and then move the cursor to the end. + */ + buf->len = mbstowcs(buf->buf, input, buf->size); + buf->pos = buf->len; + } else { + /* Reset the main item to an empty string */ + buf->buf[0] = L'\0'; + buf->pos = 0; + buf->len = 0; + } +} + +static void enforce_max_input_len(struct input_buf *buf, size_t max_len) +{ + /* When no limit is set, then nothing to do here */ + if (max_len == 0) + return; + + /* If the current buffer is to large, then truncate it and move + * the cursor to the end if needed. + */ + if (buf->len > max_len) { + buf->len = max_len; + if (buf->pos > buf->len) + buf->pos = buf->len; + buf->buf[buf->len] = L'\0'; + } +} + +static void free_input_buf(struct input_buf *buf) +{ + l_free(buf->buf); + l_free(buf); +} + +LIB_EXPORT struct l_edit *l_edit_new(void) +{ + static size_t initial_size = 15; + struct l_edit *edit; + + edit = l_new(struct l_edit, 1); + + edit->head = alloc_sized_input_buf(initial_size); + edit->main = edit->head; + edit->list_count = 0; + edit->max_list_size = 0; + edit->max_input_len = 0; + edit->max_display_len = 0; + + return edit; +} + +LIB_EXPORT void l_edit_free(struct l_edit *edit) +{ + struct input_buf *buf; + + if (!edit) + return; + + buf = edit->head; + while (buf) { + struct input_buf *tmp = buf->next; + free_input_buf(buf); + buf = tmp; + } + + l_free(edit); +} + +static void update_debug(struct l_edit *edit) +{ + struct input_buf *buf; + struct l_string *str; + char *tmp; + size_t len; + unsigned int pos = 0; + + if (!edit->debug_handler) + return; + + str = l_string_new(edit->head->len + 32); + + l_string_append_printf(str, "Display : %zu\n", edit->max_display_len); + l_string_append_printf(str, "Buffer : %zu\n", edit->main->size); + if (edit->max_input_len) + l_string_append_printf(str, "Input : %zu/%zu\n", + edit->main->len, edit->max_input_len); + else + l_string_append_printf(str, "Input : %zu/unlimited\n", + edit->main->len); + l_string_append_printf(str, "Cursor : %zu\n", edit->main->pos); + l_string_append_printf(str, "History : %zu/%zu\n", + edit->list_count, edit->max_list_size); + + buf = edit->head; + while (buf) { + len = wcstombs(NULL, buf->buf, 0) + 1; + tmp = l_malloc(len); + wcstombs(tmp, buf->buf, len); + l_string_append_printf(str, "%3u %s\n", pos, tmp); + l_free(tmp); + pos++; + buf = buf->next; + } + + tmp = l_string_unwrap(str); + + edit->debug_handler(tmp, edit->debug_data); + + l_free(tmp); +} + +LIB_EXPORT bool l_edit_set_debug_handler(struct l_edit *edit, + l_edit_debug_func_t handler, void *user_data) +{ + if (!edit) + return false; + + edit->debug_handler = handler; + edit->debug_data = user_data; + + update_debug(edit); + + return true; +} + +static void update_display(struct l_edit *edit) +{ + const wchar_t *buf = edit->main->buf; + size_t len = edit->main->len; + size_t pos = edit->main->pos; + + if (!edit->display_handler) + return; + + if (edit->max_display_len > 0) { + /* Move buffer until current position is in display size */ + while (pos >= edit->max_display_len) { + buf++; + len--; + pos--; + } + + /* Reduce the length until it fits in display size */ + while (len > edit->max_display_len) + len--; + } + + edit->display_handler(buf, len, pos, edit->display_data); + + update_debug(edit); +} + +LIB_EXPORT bool l_edit_set_display_handler(struct l_edit *edit, + l_edit_display_func_t handler, void *user_data) +{ + if (!edit) + return false; + + edit->display_handler = handler; + edit->display_data = user_data; + + update_display(edit); + + return true; +} + +LIB_EXPORT bool l_edit_set_max_display_length(struct l_edit *edit, size_t len) +{ + if (!edit) + return false; + + edit->max_display_len= len; + + update_display(edit); + + return true; +} + +LIB_EXPORT bool l_edit_set_max_input_length(struct l_edit *edit, size_t len) +{ + if (!edit) + return false; + + /* When switching to unlimited input length, then nothing is there + * do to, except storing the value. Refreshing the display is not + * needed since everything is already present. + */ + if (len == 0) { + edit->max_input_len = 0; + update_debug(edit); + return true; + } + + edit->max_input_len = len; + + if (edit->main->len > edit->max_input_len) { + /* If the current length is longer, then it is required to + * truncate and if needed move the cursor to the end. + */ + edit->main->len = edit->max_input_len; + if (edit->main->pos > edit->main->len) + edit->main->pos = edit->main->len; + edit->main->buf[edit->main->len] = L'\0'; + update_display(edit); + } else { + /* Since nothing has to be updated for the display, make + * sure the debug output is updated manually. + */ + update_debug(edit); + } + + return true; +} + +LIB_EXPORT bool l_edit_set_history_size(struct l_edit *edit, unsigned int size) +{ + if (!edit) + return false; + + edit->max_list_size = size; + + if (edit->list_count > edit->max_list_size) { + struct input_buf *buf = edit->head; + struct input_buf *last; + size_t count = 0; + + /* Truncating the history means, thattthe last still valid + * entry needs to be found. + */ + while (count < edit->max_list_size) { + if (!buf->next) + break; + count++; + buf = buf->next; + } + + /* Terminate the list on the last item and store it for + * later use. + */ + last = buf; + buf = last->next; + last->next = NULL; + + /* Now free the tail of the list. In case the history index + * was present in the tail, move it to the last item. + */ + while (buf) { + struct input_buf *tmp = buf->next; + if (buf == edit->main) + edit->main = last; + free_input_buf(buf); + buf = tmp; + } + + edit->list_count = count; + } + + update_display(edit); + + return true; +} + +LIB_EXPORT bool l_edit_refresh(struct l_edit *edit) +{ + if (!edit) + return false; + + update_display(edit); + + return true; +} + +LIB_EXPORT bool l_edit_is_empty(struct l_edit *edit) +{ + if (!edit) + return true; + + return (edit->main->len == 0); +} + +LIB_EXPORT char *l_edit_enter(struct l_edit *edit) +{ + struct input_buf *buf; + char *str; + size_t len; + + if (!edit) + return NULL; + + /* Convert the wide character string into the multibyte string + * representation like UTF-8 for example. + */ + len = wcstombs(NULL, edit->main->buf, 0) + 1; + str = l_malloc(len); + wcstombs(str, edit->main->buf, len); + + if (edit->main->len > 0) { + /* If the current entered item is different from the first + * one in history (if history is present), then allocate + * a copy of that item and push it to the head of the + * history list. + */ + if (!edit->head->next || wcscmp(edit->main->buf, + edit->head->next->buf)) { + buf = alloc_duplicate_input_buf(edit->main); + buf->next = edit->head->next; + edit->head->next = buf; + edit->list_count++; + } + + /* Reset the head item, since that becomes the next + * main input item. + */ + edit->head->buf[0] = L'\0'; + edit->head->pos = 0; + edit->head->len = 0; + + /* If the history size has grown to large, remove the + * last item from the list. + */ + if (edit->list_count > edit->max_list_size) { + buf = edit->head; + while (buf->next) { + if (!buf->next->next) { + free_input_buf(buf->next); + buf->next = NULL; + edit->list_count--; + break; + } + buf = buf->next; + } + } + } + + edit->main = edit->head; + update_display(edit); + + return str; +} + +LIB_EXPORT bool l_edit_reset(struct l_edit *edit, const char *input) +{ + if (!edit) + return false; + + /* Reset the main item back to the head of the history before + * resetting it or overwriting it with the provided input. + */ + edit->main = edit->head; + + reset_input_buf(edit->main, input); + update_display(edit); + + return true; +} + +LIB_EXPORT bool l_edit_insert(struct l_edit *edit, wint_t ch) +{ + if (!edit) + return false; + + /* Check if the max input length has already been reached */ + if (edit->max_input_len && edit->main->len >= edit->max_input_len) + return false; + + /* This will magically grow the buffer to make room for at least + * one wide character. + */ + grow_input_buf(edit->main, 1); + + /* If length is already the same as the max size of a possible + * string, there is nothing more to add. + */ + if (edit->main->len == SIZE_MAX) + return false; + + /* If the cursor is not at the end, the new character has to be + * inserted and for thus the tail portion needs to move one + * character back. + */ + if (edit->main->len != edit->main->pos) + wmemmove(edit->main->buf + edit->main->pos + 1, + edit->main->buf + edit->main->pos, + edit->main->len - edit->main->pos); + edit->main->buf[edit->main->pos] = ch; + edit->main->pos++; + edit->main->len++; + edit->main->buf[edit->main->len] = L'\0'; + update_display(edit); + + return true; +} + +LIB_EXPORT bool l_edit_delete(struct l_edit *edit) +{ + if (!edit) + return false; + + /* If the cursor is not at the end, deletion of a character means + * that the tail moves one character forward. + */ + if (edit->main->len > 0 && edit->main->pos < edit->main->len) { + wmemmove(edit->main->buf + edit->main->pos, + edit->main->buf + edit->main->pos + 1, + edit->main->len - edit->main->pos - 1); + edit->main->len--; + edit->main->buf[edit->main->len] = L'\0'; + update_display(edit); + } + + return true; +} + +LIB_EXPORT bool l_edit_delete_all(struct l_edit *edit) +{ + if (!edit) + return false; + + /* Keep the buffer allocated, but reset it to an empty string */ + edit->main->buf[0] = L'\0'; + edit->main->pos = 0; + edit->main->len = 0; + update_display(edit); + + return true; +} + +LIB_EXPORT bool l_edit_truncate(struct l_edit *edit) +{ + if (!edit) + return false; + + /* Keep the buffer allocated, but truncate after the cursor */ + edit->main->buf[edit->main->pos] = L'\0'; + edit->main->len = edit->main->pos; + update_display(edit); + + return true; +} + +LIB_EXPORT bool l_edit_backspace(struct l_edit *edit) +{ + if (!edit) + return false; + + /* If the cursor is not at the beginning, the backspace operation + * means that tail has to move one character forward. + */ + if (edit->main->pos > 0 && edit->main->len > 0) { + wmemmove(edit->main->buf + edit->main->pos - 1, + edit->main->buf + edit->main->pos, + edit->main->len - edit->main->pos); + edit->main->pos--; + edit->main->len--; + edit->main->buf[edit->main->len] = L'\0'; + update_display(edit); + } + + return true; +} + +LIB_EXPORT bool l_edit_move_left(struct l_edit *edit) +{ + if (!edit) + return false; + + /* If the cursor is not at the beginning, then move it one back */ + if (edit->main->pos > 0) { + edit->main->pos--; + update_display(edit); + } + + return true; +} + +LIB_EXPORT bool l_edit_move_right(struct l_edit *edit) +{ + if (!edit) + return false; + + /* If the cursor is not at the end, then move it one forward */ + if (edit->main->pos != edit->main->len) { + edit->main->pos++; + update_display(edit); + } + + return true; +} + +LIB_EXPORT bool l_edit_move_home(struct l_edit *edit) +{ + if (!edit) + return false; + + /* If the cursor is not at the beginning, move it there */ + if (edit->main->pos != 0) { + edit->main->pos = 0; + update_display(edit); + } + + return true; +} + +LIB_EXPORT bool l_edit_move_end(struct l_edit *edit) +{ + if (!edit) + return false; + + /* If the cursor is not at the end, move it there */ + if (edit->main->pos != edit->main->len) { + edit->main->pos = edit->main->len; + update_display(edit); + } + + return true; +} + +LIB_EXPORT bool l_edit_history_backward(struct l_edit *edit) +{ + if (!edit) + return false; + + /* If there is another item in the history list, move the main + * item to that and enforce the max input length on the new item. + */ + if (edit->main->next) { + edit->main = edit->main->next; + enforce_max_input_len(edit->main, edit->max_input_len); + update_display(edit); + } + + return true; +} + +LIB_EXPORT bool l_edit_history_forward(struct l_edit *edit) +{ + struct input_buf *buf; + + if (!edit) + return false; + + /* Walk the list of history items until the current main item + * matches the next item, then move the main item to current + * item and ensure that the max input length requirement is met. + */ + for (buf = edit->head; buf; buf = buf->next) { + if (buf->next == edit->main) { + edit->main = buf; + enforce_max_input_len(edit->main, edit->max_input_len); + update_display(edit); + break; + } + } + + return true; +} + +LIB_EXPORT bool l_edit_history_load(struct l_edit *edit, const char *pathname) +{ + static size_t initial_line_size = 16; + struct input_buf *buf; + struct l_string *str; + size_t count; + int fd; + + if (!edit) + return false; + + if (!pathname) + return false; + + if (!edit->max_list_size) + return true; + + fd = open(pathname, O_RDONLY); + if (fd < 0) + return false; + + str = l_string_new(initial_line_size); + + buf = edit->head; + count = 0; + + while (count < edit->max_list_size) { + char *tmp; + char ch; + int res; + + res = read(fd, &ch, 1); + if (res != 1) + break; + + if (ch != '\n') { + l_string_append_c(str, ch); + continue; + } + + tmp = l_string_unwrap(str); + + /* If there is not next item, but max count has not yet + * reached a new items is created. Otherwise the existing + * item is overwritten. + */ + if (!buf->next) + buf->next = alloc_sized_input_buf(0); + + /* Fill the item with input from the history file */ + reset_input_buf(buf->next, tmp); + buf = buf->next; + count++; + + l_free(tmp); + + str = l_string_new(initial_line_size); + } + + l_string_free(str); + + close(fd); + + edit->list_count = count; + update_display(edit); + + return true; +} + +LIB_EXPORT bool l_edit_history_save(struct l_edit *edit, const char *pathname) +{ + struct input_buf *buf; + int fd; + + if (!edit) + return false; + + if (!pathname) + return false; + + fd = open(pathname, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR|S_IWUSR); + if (fd < 0) + return false; + + buf = edit->head->next; + + while (buf) { + char *tmp; + size_t len; + + len = wcstombs(NULL, buf->buf, 0) + 1; + tmp = l_malloc(len); + wcstombs(tmp, buf->buf, len); + dprintf(fd, "%s\n", tmp); + l_free(tmp); + + buf = buf->next; + } + + close(fd); + + return true; +} diff --git a/ell/edit.h b/ell/edit.h new file mode 100644 index 000000000000..45ad2e657156 --- /dev/null +++ b/ell/edit.h @@ -0,0 +1,59 @@ +/* + * Embedded Linux library + * Copyright (C) 2023 Intel Corporation + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#ifndef __ELL_EDIT_H +#define __ELL_EDIT_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct l_edit; + +struct l_edit *l_edit_new(void); +void l_edit_free(struct l_edit *edit); + +typedef void (*l_edit_debug_func_t) (const char *str, void *user_data); + +bool l_edit_set_debug_handler(struct l_edit *edit, + l_edit_debug_func_t handler, void *user_data); + +typedef void (*l_edit_display_func_t) (const wchar_t *wstr, size_t wlen, + size_t pos, void *user_data); + +bool l_edit_set_display_handler(struct l_edit *edit, + l_edit_display_func_t handler, void *user_data); + +bool l_edit_set_max_display_length(struct l_edit *edit, size_t len); +bool l_edit_set_max_input_length(struct l_edit *edit, size_t len); +bool l_edit_set_history_size(struct l_edit *edit, unsigned int size); +bool l_edit_refresh(struct l_edit *edit); +bool l_edit_is_empty(struct l_edit *edit); +char *l_edit_enter(struct l_edit *edit); +bool l_edit_reset(struct l_edit *edit, const char *input); +bool l_edit_insert(struct l_edit *edit, wint_t ch); +bool l_edit_delete(struct l_edit *edit); +bool l_edit_delete_all(struct l_edit *edit); +bool l_edit_truncate(struct l_edit *edit); +bool l_edit_backspace(struct l_edit *edit); +bool l_edit_move_left(struct l_edit *edit); +bool l_edit_move_right(struct l_edit *edit); +bool l_edit_move_home(struct l_edit *edit); +bool l_edit_move_end(struct l_edit *edit); +bool l_edit_history_backward(struct l_edit *edit); +bool l_edit_history_forward(struct l_edit *edit); +bool l_edit_history_load(struct l_edit *edit, const char *pathname); +bool l_edit_history_save(struct l_edit *edit, const char *pathname); + +#ifdef __cplusplus +} +#endif + +#endif /* __ELL_EDIT_H */ From patchwork Sun Apr 6 22:12:09 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Grant Erickson X-Patchwork-Id: 14039543 Received: from mail5.g24.pair.com (mail5.g24.pair.com [66.39.139.36]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BBEBF1A8F9E for ; Sun, 6 Apr 2025 22:12:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=66.39.139.36 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743977540; cv=none; b=HeSoNx0avulnIa/53zdL949/mPHYcVez+JALhu93bGEarQ6mM8l7tT0Shfm/lA0Ud45BTyc0PaJNjkyexYwQ+yi3wOPY+jXajiwQOpvTi/xH/iID+GUPgWe3rDYjQJHdyA2OkY2D83mMIG/bmOan4NpFWGBD+ZvSajejTz19xq0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743977540; c=relaxed/simple; bh=siltQyIgFGEDAaysDlLQo7hvtOvLIgvt2toL/b1I6kg=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=JDDMPGxVC+yS+5rbdQC9MZkP6yX9hT2JHG8JAjePWJwIKjTUCrpRUSjUYgg2Lxwil8zweVaLdC2F0eHDtHQGS2dJrCqB/gw9LNNKHTY/vSl2k6/3fTHQhYZNGIvIK+gKe3McJGP36ctQnjHo1gep99GzgjL3MbW4fD43zqAt+JM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=nuovations.com; spf=pass smtp.mailfrom=nuovations.com; dkim=pass (2048-bit key) header.d=nuovations.com header.i=@nuovations.com header.b=hOA5f9m9; arc=none smtp.client-ip=66.39.139.36 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=nuovations.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=nuovations.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=nuovations.com header.i=@nuovations.com header.b="hOA5f9m9" Received: from mail5.g24.pair.com (localhost [127.0.0.1]) by mail5.g24.pair.com (Postfix) with ESMTP id 012EE164A4D for ; Sun, 6 Apr 2025 18:12:18 -0400 (EDT) Received: from localhost.localdomain (c-73-202-173-252.hsd1.ca.comcast.net [73.202.173.252]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mail5.g24.pair.com (Postfix) with ESMTPSA id A68951260D8 for ; Sun, 6 Apr 2025 18:12:17 -0400 (EDT) From: Grant Erickson To: ell@lists.linux.dev Subject: [PATCH v6 2/8] ell: Add include directive for 'ell/edit.h'. Date: Sun, 6 Apr 2025 15:12:09 -0700 Message-ID: X-Mailer: git-send-email 2.45.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: ell@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nuovations.com; h=from:to:subject:date:message-id:in-reply-to:references:mime-version:content-transfer-encoding; s=pair-202401062137; bh=m6L3GTgxskf5oiAebVFLMKGZSXyGGVPx2cddEDTfkNA=; b=hOA5f9m9nZ0ECncMzRz/uio8uhavhKExKYOCxrDlHLZq49JOn5SSvfsS7KwBxU67YuR7WR9+dX9UAyC2vaeneZHmFQf240pgrnJG+95zPg8RoDwinvc/L+upzuTW3QrBpoRKcLYiDQNjmXVT07E2+JTkKtH35F8HnmRnP1OszDt38IJJXqJK3Jceq3UIniwNwGRnf4JsSr/VZuD3Dk5h0iwn2LkElJPBnzEosydTDM8zDRCU0XyqAHzWPM94SIjwFD2ttuIlKP0t/dZBzr0wizqEC7CSWzDXnGFCIcbMn4tL/lnVHrbcr6WgY8fYf5J4LN8bsAGZ+GHRSWMPOsEe1A== X-Scanned-By: mailmunge 3.10 on 66.39.139.36 --- ell/ell.h | 1 + 1 file changed, 1 insertion(+) diff --git a/ell/ell.h b/ell/ell.h index 7a263e9376de..6db35b9cfb6b 100644 --- a/ell/ell.h +++ b/ell/ell.h @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include From patchwork Sun Apr 6 22:12:10 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Grant Erickson X-Patchwork-Id: 14039544 Received: from mail5.g24.pair.com (mail5.g24.pair.com [66.39.139.36]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 096B41B414A for ; Sun, 6 Apr 2025 22:12:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=66.39.139.36 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743977540; cv=none; b=jBVNBDeimgoe1xz2TTnaoyRzjt2TwLFuNQtcWzoKvGR4A1BpfCp55ga2eZLfo9z2ECQ61FWKFGrLUTk4LGD9jf6c54A+kdllEziz8CfSDNP94T/4nqvyvSo8cnQMI/tKiNwKF+MdG7vkq6ZcZU/o0u0DM9skseRBEZlWZ5Nem3Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743977540; c=relaxed/simple; bh=ha2HAu8ieEfQe+bJLL8MEztxFP/Urer8UmEPLRVmKeU=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=qiwcUu+0tNoQnoVPxAHImoykMOgZZUsxSOfsnEpgnt3T103+GxRA4yHNUEiLrg+17eQy+s941BJhoyEUyjOGZzSuVvIR6Qz6LaR5K9L+cUh/3CLsV7SLTUELhXiGac0zV20/M7SswZu/08OH5EJ77FXycV2P6bH4hUXCc7Ny1BM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=nuovations.com; spf=pass smtp.mailfrom=nuovations.com; dkim=pass (2048-bit key) header.d=nuovations.com header.i=@nuovations.com header.b=hdEiQVzv; arc=none smtp.client-ip=66.39.139.36 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=nuovations.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=nuovations.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=nuovations.com header.i=@nuovations.com header.b="hdEiQVzv" Received: from mail5.g24.pair.com (localhost [127.0.0.1]) by mail5.g24.pair.com (Postfix) with ESMTP id 70FFC164A54 for ; Sun, 6 Apr 2025 18:12:18 -0400 (EDT) Received: from localhost.localdomain (c-73-202-173-252.hsd1.ca.comcast.net [73.202.173.252]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mail5.g24.pair.com (Postfix) with ESMTPSA id 208A21260D8 for ; Sun, 6 Apr 2025 18:12:18 -0400 (EDT) From: Grant Erickson To: ell@lists.linux.dev Subject: [PATCH v6 3/8] ell/Makefile: Added 'edit.[ch]' to HEADERS and SOURCES. Date: Sun, 6 Apr 2025 15:12:10 -0700 Message-ID: <14d3dbc69f3e2c1702b0d52dab64c3c02700c9c8.1743977403.git.gerickson@nuovations.com> X-Mailer: git-send-email 2.45.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: ell@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nuovations.com; h=from:to:subject:date:message-id:in-reply-to:references:mime-version:content-transfer-encoding; s=pair-202401062137; bh=iA+XzckOV341mbIzz/ofVbfUCkFRaJcpGbcZUr27j3s=; b=hdEiQVzvZXi4lG/IdzlQcc4d3bKoglSTbh5+DidhIzDuNQa1FCwlyKbpNntL4h97kFD/H6oc8TeuUBU851k/hlz0rlj/2Xuy+i2ZfjeBcBk9ziVbcr4EAwG2ymLw3iNFcN1k1Bh43DpZMrUrTwqGZBGnmOgQaClJLlpFASSb0HTqDP4SWT2BZlzF+LRVlUBBCVFm3u2W1b4+he+SEFCT+F3ipua82xzJ4GZwVMW9pcL727nOahFU/DirYqnnvtsQoxYHApkyqyqJmJ/bIVpN2+HhRrwVbJ1AyIpJDdVj6UEzYIMAi88t6FDP3XaqyMaRwf9i/mkAi3ATpQ4H+fYZ9g== X-Scanned-By: mailmunge 3.10 on 66.39.139.36 --- Makefile.am | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile.am b/Makefile.am index 84d008febe0c..ae2612f4b770 100644 --- a/Makefile.am +++ b/Makefile.am @@ -55,6 +55,7 @@ pkginclude_HEADERS = ell/ell.h \ ell/ecc.h \ ell/ecdh.h \ ell/time.h \ + ell/edit.h \ ell/gpio.h \ ell/path.h \ ell/icmp6.h \ @@ -148,6 +149,7 @@ ell_libell_la_SOURCES = $(linux_headers) \ ell/ecdh.c \ ell/time.c \ ell/time-private.h \ + ell/edit.c \ ell/gpio.c \ ell/path.c \ ell/icmp6.c \ From patchwork Sun Apr 6 22:12:11 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Grant Erickson X-Patchwork-Id: 14039545 Received: from mail5.g24.pair.com (mail5.g24.pair.com [66.39.139.36]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 67B2021883C for ; Sun, 6 Apr 2025 22:12:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=66.39.139.36 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743977540; cv=none; b=NYJTyBFRroVH8XjQ7eQUv3bmAL40XFGP2+aOrLV+quEqww01XqVd6uHcsBTTC3PUrtGpI1jyDF3PNdop1hr447BZSsMpFTOqKKBxinw3PgtM7KXAZkYBK1jHFcqb48GIcPPXN8xS1A96Wf27SsdARXJwR4pvGNhNtYu476VfGx4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743977540; c=relaxed/simple; bh=d63Tu+Q0NJvTkI1FUcfH9WAKZrfZWtXxnbMKbIN+iyk=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=aRd2/tjVreptx5rj/5nGRJIulCiQmXH/VvjTcCwgjAvrBnVgF2ACil0rYiC3lkfI8lI8qXBdWxqRz0XydsgItdjYN3ClLakb6QP7OpqnoWV1NQrGlwDrEzzGZbg9CAtGtF13oDqEiSbB6oXj9kQtPNZbzui68mUVqOWptQvY5VI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=nuovations.com; spf=pass smtp.mailfrom=nuovations.com; dkim=pass (2048-bit key) header.d=nuovations.com header.i=@nuovations.com header.b=NL2juyli; arc=none smtp.client-ip=66.39.139.36 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=nuovations.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=nuovations.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=nuovations.com header.i=@nuovations.com header.b="NL2juyli" Received: from mail5.g24.pair.com (localhost [127.0.0.1]) by mail5.g24.pair.com (Postfix) with ESMTP id D530A164A58 for ; Sun, 6 Apr 2025 18:12:18 -0400 (EDT) Received: from localhost.localdomain (c-73-202-173-252.hsd1.ca.comcast.net [73.202.173.252]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mail5.g24.pair.com (Postfix) with ESMTPSA id 902BE1260D8 for ; Sun, 6 Apr 2025 18:12:18 -0400 (EDT) From: Grant Erickson To: ell@lists.linux.dev Subject: [PATCH v6 4/8] edit: Added 'l_edit_*' symbols. Date: Sun, 6 Apr 2025 15:12:11 -0700 Message-ID: <00030ad625bcf5115c992323dd29c5f8f84770e3.1743977403.git.gerickson@nuovations.com> X-Mailer: git-send-email 2.45.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: ell@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nuovations.com; h=from:to:subject:date:message-id:in-reply-to:references:mime-version:content-transfer-encoding; s=pair-202401062137; bh=oEiBHzH3WJ9iqTEOX0ImJUkVeoHl74y7EdeCMGp9GD8=; b=NL2juyli45hS+A3XjNEDU4bdl7DItcI9oi3x90UnE3F3MDw9EUBcDpcfOreSrSt0T9baFtgTacaPCox+2nrSE9GYnFVXHNA6SPwXY8eWDcW+p0EqCQQr5BUaxr1HZ+Foi92x2hUUFvmMrub+NDcsVF/7bGsrosjw1AIJQq4y0lPkRcwayAOoBRH8cQXIVpkDQYluj72cCEVxvmanG9XBQDJTEpx2NBt5y617Y9plCapfwc0xvzzIjmXrupWNSabfYmjk42fBbHyZ+KqOK336lveY608wzU2oPP++EAQaeHjfcxlM0o2gPyKiEZ8cLO7++WSx1rCScU7V31O5QO8IzQ== X-Scanned-By: mailmunge 3.10 on 66.39.139.36 --- ell/ell.sym | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/ell/ell.sym b/ell/ell.sym index f192c471a40c..3c31fd608e3a 100644 --- a/ell/ell.sym +++ b/ell/ell.sym @@ -643,6 +643,31 @@ global: l_ecdh_generate_shared_secret; /* time */ l_time_now; + /* edit */ + l_edit_new; + l_edit_free; + l_edit_set_debug_handler; + l_edit_set_display_handler; + l_edit_set_max_display_length; + l_edit_set_max_input_length; + l_edit_set_history_size; + l_edit_refresh; + l_edit_is_empty; + l_edit_enter; + l_edit_reset; + l_edit_insert; + l_edit_delete; + l_edit_delete_all; + l_edit_truncate; + l_edit_backspace; + l_edit_move_left; + l_edit_move_right; + l_edit_move_home; + l_edit_move_end; + l_edit_history_backward; + l_edit_history_forward; + l_edit_history_load; + l_edit_history_save; /* gpio */ l_gpio_chips_with_line_label; l_gpio_chip_new; From patchwork Sun Apr 6 22:12:12 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Grant Erickson X-Patchwork-Id: 14039548 Received: from mail5.g24.pair.com (mail5.g24.pair.com [66.39.139.36]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EAD2021D3FE for ; Sun, 6 Apr 2025 22:12:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=66.39.139.36 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743977542; cv=none; b=NNN873guaur68EAAVmtqk1Uy4jtWwIG8ISM2Zc3tXcVj6WxRWPhnJRiI4/no5ag4Y8XhUffmnB0HL2+LfN0wYkjFdt+7p2/2p+0UXK4kd1rxPGhYQcRpZtNY6G2Q7Ehn4r5YNZxLDTrSc+gliPKkr1JzdQzP5YrcJr0KedJ5AFI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743977542; c=relaxed/simple; bh=I/bPiFutfBafZW7hYkYhxFjGtXQRUrHDSe9+ISn9/ug=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=WYy/tL/GIyfOgRfHgXqx8mhW7tmoPWyvyRqSiihNFzXensAnjkiKMm0HkXk7Klp8XI5uuTk7PcxZJ7iqNNSx6rcDkQ5qi/OAcICVvuMRLGAdtAgcrRTQ+3HSb/Ew9dsT7W2TgwIF6bb0ldyokiSzi1FUkChlGgopV6V5ZrI2ZoY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=nuovations.com; spf=pass smtp.mailfrom=nuovations.com; dkim=pass (2048-bit key) header.d=nuovations.com header.i=@nuovations.com header.b=Z3DDMWA2; arc=none smtp.client-ip=66.39.139.36 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=nuovations.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=nuovations.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=nuovations.com header.i=@nuovations.com header.b="Z3DDMWA2" Received: from mail5.g24.pair.com (localhost [127.0.0.1]) by mail5.g24.pair.com (Postfix) with ESMTP id 439CA164A6C for ; Sun, 6 Apr 2025 18:12:19 -0400 (EDT) Received: from localhost.localdomain (c-73-202-173-252.hsd1.ca.comcast.net [73.202.173.252]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mail5.g24.pair.com (Postfix) with ESMTPSA id F3C2E1260D8 for ; Sun, 6 Apr 2025 18:12:18 -0400 (EDT) From: Grant Erickson To: ell@lists.linux.dev Subject: [PATCH v6 5/8] edit: pass the l_edit instance to the display and debug handlers. Date: Sun, 6 Apr 2025 15:12:12 -0700 Message-ID: <53394b18e388c2a6048705a7fa7a0a25ec49c868.1743977403.git.gerickson@nuovations.com> X-Mailer: git-send-email 2.45.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: ell@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nuovations.com; h=from:to:subject:date:message-id:in-reply-to:references:mime-version:content-transfer-encoding; s=pair-202401062137; bh=G5nrjmn2W7uEE+5lIEZ7pnTFzdNsrOoPo52OqKWuTCM=; b=Z3DDMWA2vFTmm6Thyr9t4vQieUsGwde7T6NuaCaN6fqDYXWHgLb+H32csz6eWGcB98sx3tJX5Pi93BOI5hOW0AfCccdALK5XruzN+A8qg22aoeqK/lsOm3gzXsov9gC/dZsGGY6CwrM4MhO0lyKlOhCus71qkuKXfNQfb7W0+7XDFYArE+ZMCWHd1CEt1qUXh2EAvud7Qr3bK22WTR0hicjhU2fKceE4iWd+h3UEksFNHz0sZPRxHvBwpn2KOILOU7S1KhZCkUXResWYx42rvuRWpvJoqFgY8aWpCDuGQblcJwZi6WECtxHVv48fQcueIqQJRz6Gdjrzjncizabv/Q== X-Scanned-By: mailmunge 3.10 on 66.39.139.36 l_edit integrations are made easier when they have access to the instance pointer in their callbacks. --- ell/edit.c | 4 ++-- ell/edit.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ell/edit.c b/ell/edit.c index 899fea4da830..54cfc566c4ad 100644 --- a/ell/edit.c +++ b/ell/edit.c @@ -229,7 +229,7 @@ static void update_debug(struct l_edit *edit) tmp = l_string_unwrap(str); - edit->debug_handler(tmp, edit->debug_data); + edit->debug_handler(edit, tmp, edit->debug_data); l_free(tmp); } @@ -270,7 +270,7 @@ static void update_display(struct l_edit *edit) len--; } - edit->display_handler(buf, len, pos, edit->display_data); + edit->display_handler(edit, buf, len, pos, edit->display_data); update_debug(edit); } diff --git a/ell/edit.h b/ell/edit.h index 45ad2e657156..decf261c7b9e 100644 --- a/ell/edit.h +++ b/ell/edit.h @@ -20,12 +20,12 @@ struct l_edit; struct l_edit *l_edit_new(void); void l_edit_free(struct l_edit *edit); -typedef void (*l_edit_debug_func_t) (const char *str, void *user_data); +typedef void (*l_edit_debug_func_t) (struct l_edit *edit, const char *str, void *user_data); bool l_edit_set_debug_handler(struct l_edit *edit, l_edit_debug_func_t handler, void *user_data); -typedef void (*l_edit_display_func_t) (const wchar_t *wstr, size_t wlen, +typedef void (*l_edit_display_func_t) (struct l_edit *edit, const wchar_t *wstr, size_t wlen, size_t pos, void *user_data); bool l_edit_set_display_handler(struct l_edit *edit, From patchwork Sun Apr 6 22:12:13 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Grant Erickson X-Patchwork-Id: 14039550 Received: from mail5.g24.pair.com (mail5.g24.pair.com [66.39.139.36]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EACC11B414A for ; Sun, 6 Apr 2025 22:12:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=66.39.139.36 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743977543; cv=none; b=Ld/A+1KTP7XQwmVB1Pfxvd9dgzQxIZFqm88ePtB+Rs7wOsX9Srquqvl1vGiKJ6+xqVExc8uQ3mz4x//O7ueHoiEhg+L1xpjI/vgj7w6ztFO1MA1BQmraDtNBwAxFphCHqr1AQtiGFyASCtpTVql6Jc603bYpvDCG7uCpohSILlQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743977543; c=relaxed/simple; bh=KTl9gqW/cTtUtxFw6BmBqjWUjXsufOferXWpVXZz0zw=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=DKBr2XhgmrKzWQoQVquEZTuqq2BtDkvRVeAwj5LbimJfuNaBEWv98PBizWZGwRTvEF/YzJwqVkIOc0ry8CQLgSAhzg/8Nui2+alk0oxTs3WrE2d7giBcuHXhJZ1ilG9i/sJHJhW64LHqTdxiaj5/pHiL1M6xgtfaJ2ptdsEQJd4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=nuovations.com; spf=pass smtp.mailfrom=nuovations.com; dkim=pass (2048-bit key) header.d=nuovations.com header.i=@nuovations.com header.b=GBYH2CGm; arc=none smtp.client-ip=66.39.139.36 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=nuovations.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=nuovations.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=nuovations.com header.i=@nuovations.com header.b="GBYH2CGm" Received: from mail5.g24.pair.com (localhost [127.0.0.1]) by mail5.g24.pair.com (Postfix) with ESMTP id A822D164A6F for ; Sun, 6 Apr 2025 18:12:19 -0400 (EDT) Received: from localhost.localdomain (c-73-202-173-252.hsd1.ca.comcast.net [73.202.173.252]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mail5.g24.pair.com (Postfix) with ESMTPSA id 62EEB1260D8 for ; Sun, 6 Apr 2025 18:12:19 -0400 (EDT) From: Grant Erickson To: ell@lists.linux.dev Subject: [PATCH v6 6/8] edit: change return signatures from 'bool' to 'int' Date: Sun, 6 Apr 2025 15:12:13 -0700 Message-ID: X-Mailer: git-send-email 2.45.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: ell@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nuovations.com; h=from:to:subject:date:message-id:in-reply-to:references:mime-version:content-transfer-encoding; s=pair-202401062137; bh=R8OeFKCELEZS9QBHXn6XZlr943X5Ip4OSCVsTqKPXrQ=; b=GBYH2CGmal4mBQDofovJR5pZfZN/0T2Ln5QiYGChPDPeRB9rcXLgV9cqYnjcsLy2ZgwCDA9LZuzhQ0s7iU5BafVtvppO8kHU7ezfNea1LU+UY1cHVk+VfoppV8M2i0uSL4Sp1VDqRA7AAPT9nxCWV6gSL0j44mTl0TI01RnjQDah5hcEmFkqaeUOeOB2Uu6kKtsT6HcQxZ1PHDSU4n6gCacEBCv+jOjL7b+HqiNRYzcUGMGq7L9Cjvr54gMMRNQexqZnQQV/m2vojuWnOlxNbp/MuYhC7LJC3Ls1yfEuRIBtCunuXe9pjeL7l81yloR2Bo8GdIc9Vn4t4ipcCWsNzQ== X-Scanned-By: mailmunge 3.10 on 66.39.139.36 Using an 'int' signature with 0 for success and < 0 for failure with failure enumerations sources from the negated POSIX errors from errno.h eases system integration by precluding system integrators from having to synthesize their own errors on the prior 'false' returns. --- ell/edit.c | 136 ++++++++++++++++++++++++++--------------------------- ell/edit.h | 40 ++++++++-------- 2 files changed, 88 insertions(+), 88 deletions(-) diff --git a/ell/edit.c b/ell/edit.c index 54cfc566c4ad..d6329d063c78 100644 --- a/ell/edit.c +++ b/ell/edit.c @@ -234,18 +234,18 @@ static void update_debug(struct l_edit *edit) l_free(tmp); } -LIB_EXPORT bool l_edit_set_debug_handler(struct l_edit *edit, +LIB_EXPORT int l_edit_set_debug_handler(struct l_edit *edit, l_edit_debug_func_t handler, void *user_data) { if (!edit) - return false; + return -EINVAL; edit->debug_handler = handler; edit->debug_data = user_data; update_debug(edit); - return true; + return 0; } static void update_display(struct l_edit *edit) @@ -275,36 +275,36 @@ static void update_display(struct l_edit *edit) update_debug(edit); } -LIB_EXPORT bool l_edit_set_display_handler(struct l_edit *edit, +LIB_EXPORT int l_edit_set_display_handler(struct l_edit *edit, l_edit_display_func_t handler, void *user_data) { if (!edit) - return false; + return -EINVAL; edit->display_handler = handler; edit->display_data = user_data; update_display(edit); - return true; + return 0; } -LIB_EXPORT bool l_edit_set_max_display_length(struct l_edit *edit, size_t len) +LIB_EXPORT int l_edit_set_max_display_length(struct l_edit *edit, size_t len) { if (!edit) - return false; + return -EINVAL; edit->max_display_len= len; update_display(edit); - return true; + return 0; } -LIB_EXPORT bool l_edit_set_max_input_length(struct l_edit *edit, size_t len) +LIB_EXPORT int l_edit_set_max_input_length(struct l_edit *edit, size_t len) { if (!edit) - return false; + return -EINVAL; /* When switching to unlimited input length, then nothing is there * do to, except storing the value. Refreshing the display is not @@ -313,7 +313,7 @@ LIB_EXPORT bool l_edit_set_max_input_length(struct l_edit *edit, size_t len) if (len == 0) { edit->max_input_len = 0; update_debug(edit); - return true; + return 0; } edit->max_input_len = len; @@ -334,13 +334,13 @@ LIB_EXPORT bool l_edit_set_max_input_length(struct l_edit *edit, size_t len) update_debug(edit); } - return true; + return 0; } -LIB_EXPORT bool l_edit_set_history_size(struct l_edit *edit, unsigned int size) +LIB_EXPORT int l_edit_set_history_size(struct l_edit *edit, unsigned int size) { if (!edit) - return false; + return -EINVAL; edit->max_list_size = size; @@ -382,17 +382,17 @@ LIB_EXPORT bool l_edit_set_history_size(struct l_edit *edit, unsigned int size) update_display(edit); - return true; + return 0; } -LIB_EXPORT bool l_edit_refresh(struct l_edit *edit) +LIB_EXPORT int l_edit_refresh(struct l_edit *edit) { if (!edit) - return false; + return -EINVAL; update_display(edit); - return true; + return 0; } LIB_EXPORT bool l_edit_is_empty(struct l_edit *edit) @@ -463,10 +463,10 @@ LIB_EXPORT char *l_edit_enter(struct l_edit *edit) return str; } -LIB_EXPORT bool l_edit_reset(struct l_edit *edit, const char *input) +LIB_EXPORT int l_edit_reset(struct l_edit *edit, const char *input) { if (!edit) - return false; + return -EINVAL; /* Reset the main item back to the head of the history before * resetting it or overwriting it with the provided input. @@ -476,17 +476,17 @@ LIB_EXPORT bool l_edit_reset(struct l_edit *edit, const char *input) reset_input_buf(edit->main, input); update_display(edit); - return true; + return 0; } -LIB_EXPORT bool l_edit_insert(struct l_edit *edit, wint_t ch) +LIB_EXPORT int l_edit_insert(struct l_edit *edit, wint_t ch) { if (!edit) - return false; + return -EINVAL; /* Check if the max input length has already been reached */ if (edit->max_input_len && edit->main->len >= edit->max_input_len) - return false; + return -EALREADY; /* This will magically grow the buffer to make room for at least * one wide character. @@ -497,7 +497,7 @@ LIB_EXPORT bool l_edit_insert(struct l_edit *edit, wint_t ch) * string, there is nothing more to add. */ if (edit->main->len == SIZE_MAX) - return false; + return -ENOBUFS; /* If the cursor is not at the end, the new character has to be * inserted and for thus the tail portion needs to move one @@ -513,13 +513,13 @@ LIB_EXPORT bool l_edit_insert(struct l_edit *edit, wint_t ch) edit->main->buf[edit->main->len] = L'\0'; update_display(edit); - return true; + return 0; } -LIB_EXPORT bool l_edit_delete(struct l_edit *edit) +LIB_EXPORT int l_edit_delete(struct l_edit *edit) { if (!edit) - return false; + return -EINVAL; /* If the cursor is not at the end, deletion of a character means * that the tail moves one character forward. @@ -533,13 +533,13 @@ LIB_EXPORT bool l_edit_delete(struct l_edit *edit) update_display(edit); } - return true; + return 0; } -LIB_EXPORT bool l_edit_delete_all(struct l_edit *edit) +LIB_EXPORT int l_edit_delete_all(struct l_edit *edit) { if (!edit) - return false; + return -EINVAL; /* Keep the buffer allocated, but reset it to an empty string */ edit->main->buf[0] = L'\0'; @@ -547,26 +547,26 @@ LIB_EXPORT bool l_edit_delete_all(struct l_edit *edit) edit->main->len = 0; update_display(edit); - return true; + return 0; } -LIB_EXPORT bool l_edit_truncate(struct l_edit *edit) +LIB_EXPORT int l_edit_truncate(struct l_edit *edit) { if (!edit) - return false; + return -EINVAL; /* Keep the buffer allocated, but truncate after the cursor */ edit->main->buf[edit->main->pos] = L'\0'; edit->main->len = edit->main->pos; update_display(edit); - return true; + return 0; } -LIB_EXPORT bool l_edit_backspace(struct l_edit *edit) +LIB_EXPORT int l_edit_backspace(struct l_edit *edit) { if (!edit) - return false; + return -EINVAL; /* If the cursor is not at the beginning, the backspace operation * means that tail has to move one character forward. @@ -581,13 +581,13 @@ LIB_EXPORT bool l_edit_backspace(struct l_edit *edit) update_display(edit); } - return true; + return 0; } -LIB_EXPORT bool l_edit_move_left(struct l_edit *edit) +LIB_EXPORT int l_edit_move_left(struct l_edit *edit) { if (!edit) - return false; + return -EINVAL; /* If the cursor is not at the beginning, then move it one back */ if (edit->main->pos > 0) { @@ -595,13 +595,13 @@ LIB_EXPORT bool l_edit_move_left(struct l_edit *edit) update_display(edit); } - return true; + return 0; } -LIB_EXPORT bool l_edit_move_right(struct l_edit *edit) +LIB_EXPORT int l_edit_move_right(struct l_edit *edit) { if (!edit) - return false; + return -EINVAL; /* If the cursor is not at the end, then move it one forward */ if (edit->main->pos != edit->main->len) { @@ -609,13 +609,13 @@ LIB_EXPORT bool l_edit_move_right(struct l_edit *edit) update_display(edit); } - return true; + return 0; } -LIB_EXPORT bool l_edit_move_home(struct l_edit *edit) +LIB_EXPORT int l_edit_move_home(struct l_edit *edit) { if (!edit) - return false; + return -EINVAL; /* If the cursor is not at the beginning, move it there */ if (edit->main->pos != 0) { @@ -623,13 +623,13 @@ LIB_EXPORT bool l_edit_move_home(struct l_edit *edit) update_display(edit); } - return true; + return 0; } -LIB_EXPORT bool l_edit_move_end(struct l_edit *edit) +LIB_EXPORT int l_edit_move_end(struct l_edit *edit) { if (!edit) - return false; + return -EINVAL; /* If the cursor is not at the end, move it there */ if (edit->main->pos != edit->main->len) { @@ -637,13 +637,13 @@ LIB_EXPORT bool l_edit_move_end(struct l_edit *edit) update_display(edit); } - return true; + return 0; } -LIB_EXPORT bool l_edit_history_backward(struct l_edit *edit) +LIB_EXPORT int l_edit_history_backward(struct l_edit *edit) { if (!edit) - return false; + return -EINVAL; /* If there is another item in the history list, move the main * item to that and enforce the max input length on the new item. @@ -654,15 +654,15 @@ LIB_EXPORT bool l_edit_history_backward(struct l_edit *edit) update_display(edit); } - return true; + return 0; } -LIB_EXPORT bool l_edit_history_forward(struct l_edit *edit) +LIB_EXPORT int l_edit_history_forward(struct l_edit *edit) { struct input_buf *buf; if (!edit) - return false; + return -EINVAL; /* Walk the list of history items until the current main item * matches the next item, then move the main item to current @@ -677,10 +677,10 @@ LIB_EXPORT bool l_edit_history_forward(struct l_edit *edit) } } - return true; + return 0; } -LIB_EXPORT bool l_edit_history_load(struct l_edit *edit, const char *pathname) +LIB_EXPORT int l_edit_history_load(struct l_edit *edit, const char *pathname) { static size_t initial_line_size = 16; struct input_buf *buf; @@ -689,17 +689,17 @@ LIB_EXPORT bool l_edit_history_load(struct l_edit *edit, const char *pathname) int fd; if (!edit) - return false; + return -EINVAL; if (!pathname) - return false; + return -EINVAL; if (!edit->max_list_size) - return true; + return 0; fd = open(pathname, O_RDONLY); if (fd < 0) - return false; + return -errno; str = l_string_new(initial_line_size); @@ -746,23 +746,23 @@ LIB_EXPORT bool l_edit_history_load(struct l_edit *edit, const char *pathname) edit->list_count = count; update_display(edit); - return true; + return 0; } -LIB_EXPORT bool l_edit_history_save(struct l_edit *edit, const char *pathname) +LIB_EXPORT int l_edit_history_save(struct l_edit *edit, const char *pathname) { struct input_buf *buf; int fd; if (!edit) - return false; + return -EINVAL; if (!pathname) - return false; + return -EINVAL; fd = open(pathname, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR|S_IWUSR); if (fd < 0) - return false; + return -errno; buf = edit->head->next; @@ -781,5 +781,5 @@ LIB_EXPORT bool l_edit_history_save(struct l_edit *edit, const char *pathname) close(fd); - return true; + return 0; } diff --git a/ell/edit.h b/ell/edit.h index decf261c7b9e..811246578894 100644 --- a/ell/edit.h +++ b/ell/edit.h @@ -22,35 +22,35 @@ void l_edit_free(struct l_edit *edit); typedef void (*l_edit_debug_func_t) (struct l_edit *edit, const char *str, void *user_data); -bool l_edit_set_debug_handler(struct l_edit *edit, +int l_edit_set_debug_handler(struct l_edit *edit, l_edit_debug_func_t handler, void *user_data); typedef void (*l_edit_display_func_t) (struct l_edit *edit, const wchar_t *wstr, size_t wlen, size_t pos, void *user_data); -bool l_edit_set_display_handler(struct l_edit *edit, +int l_edit_set_display_handler(struct l_edit *edit, l_edit_display_func_t handler, void *user_data); -bool l_edit_set_max_display_length(struct l_edit *edit, size_t len); -bool l_edit_set_max_input_length(struct l_edit *edit, size_t len); -bool l_edit_set_history_size(struct l_edit *edit, unsigned int size); -bool l_edit_refresh(struct l_edit *edit); +int l_edit_set_max_display_length(struct l_edit *edit, size_t len); +int l_edit_set_max_input_length(struct l_edit *edit, size_t len); +int l_edit_set_history_size(struct l_edit *edit, unsigned int size); +int l_edit_refresh(struct l_edit *edit); bool l_edit_is_empty(struct l_edit *edit); char *l_edit_enter(struct l_edit *edit); -bool l_edit_reset(struct l_edit *edit, const char *input); -bool l_edit_insert(struct l_edit *edit, wint_t ch); -bool l_edit_delete(struct l_edit *edit); -bool l_edit_delete_all(struct l_edit *edit); -bool l_edit_truncate(struct l_edit *edit); -bool l_edit_backspace(struct l_edit *edit); -bool l_edit_move_left(struct l_edit *edit); -bool l_edit_move_right(struct l_edit *edit); -bool l_edit_move_home(struct l_edit *edit); -bool l_edit_move_end(struct l_edit *edit); -bool l_edit_history_backward(struct l_edit *edit); -bool l_edit_history_forward(struct l_edit *edit); -bool l_edit_history_load(struct l_edit *edit, const char *pathname); -bool l_edit_history_save(struct l_edit *edit, const char *pathname); +int l_edit_reset(struct l_edit *edit, const char *input); +int l_edit_insert(struct l_edit *edit, wint_t ch); +int l_edit_delete(struct l_edit *edit); +int l_edit_delete_all(struct l_edit *edit); +int l_edit_truncate(struct l_edit *edit); +int l_edit_backspace(struct l_edit *edit); +int l_edit_move_left(struct l_edit *edit); +int l_edit_move_right(struct l_edit *edit); +int l_edit_move_home(struct l_edit *edit); +int l_edit_move_end(struct l_edit *edit); +int l_edit_history_backward(struct l_edit *edit); +int l_edit_history_forward(struct l_edit *edit); +int l_edit_history_load(struct l_edit *edit, const char *pathname); +int l_edit_history_save(struct l_edit *edit, const char *pathname); #ifdef __cplusplus } From patchwork Sun Apr 6 22:12:14 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Grant Erickson X-Patchwork-Id: 14039547 Received: from mail5.g24.pair.com (mail5.g24.pair.com [66.39.139.36]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 02F5621D583 for ; Sun, 6 Apr 2025 22:12:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=66.39.139.36 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743977542; cv=none; b=SyBvUlgSPvY20DpNBRzwSfra7gVHIOtwdGFQuU2ecOZMwPT+iOxG5GoHmnDJrfEM6JPegnNsi323QiVT0hC3qA4WeXUA6vSTN6hwx9ynrbW3jCux02cc/rdxrt1NRau4e07itnNkEhoYCQNTSIx3JF3LhT3qFxc6enECWYnqwBg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743977542; c=relaxed/simple; bh=y3ySH4sLpHcgvxV7ZorFZR5eaZY2MQUfZeVT1TpSDrA=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=sNtvhebINLhAjrGFmN0HTz/7wxlEv7+lGmn2jvgfWOIHhNmpmp3TGXMdhE3fMAA+gCpLzBylIKZEoAw45f0OZtHeeBgZP+yo36wkaqGLDoqiQUNUONieDFKGvI/LAkTwKELyJ8T3PMNf37Ua8ou21ZSxneJuRBc/8V3qwER4kuw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=nuovations.com; spf=pass smtp.mailfrom=nuovations.com; dkim=pass (2048-bit key) header.d=nuovations.com header.i=@nuovations.com header.b=gPKC6utD; arc=none smtp.client-ip=66.39.139.36 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=nuovations.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=nuovations.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=nuovations.com header.i=@nuovations.com header.b="gPKC6utD" Received: from mail5.g24.pair.com (localhost [127.0.0.1]) by mail5.g24.pair.com (Postfix) with ESMTP id 17EB8164A70 for ; Sun, 6 Apr 2025 18:12:20 -0400 (EDT) Received: from localhost.localdomain (c-73-202-173-252.hsd1.ca.comcast.net [73.202.173.252]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mail5.g24.pair.com (Postfix) with ESMTPSA id C73091260D8 for ; Sun, 6 Apr 2025 18:12:19 -0400 (EDT) From: Grant Erickson To: ell@lists.linux.dev Subject: [PATCH v6 7/8] edit: change the 'l_edit_enter' return signature from 'char *' to 'int' Date: Sun, 6 Apr 2025 15:12:14 -0700 Message-ID: <9aadf6433c5166cfb4c2ab2c1fd010f9718edf3f.1743977403.git.gerickson@nuovations.com> X-Mailer: git-send-email 2.45.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: ell@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nuovations.com; h=from:to:subject:date:message-id:in-reply-to:references:mime-version:content-transfer-encoding; s=pair-202401062137; bh=71MtMAj0ksGynXQkmaroKM5+cISjgkLmCEIeWTfpGqU=; b=gPKC6utDHeC6LKDMau8jg1YrnW7HNqv0HB/YbFZbVYiol7jVaToLfNaZnCFXU6qBvHmWtQ+2acLZIjs9+PBfbQDHapEjtf3ItR0FZLQASsx8ByRxlpj0sOrKJByRQprartO4sJWVec05nMl7jyvZ2J3jM83YElCbN8n1AYIUdnSKjW3ZDLTu9V4odhNh3HGXqnjdD66ASotpa6HIyACNCpdlFJkEcKmbQqPsjf5PfmNxnj52og1Ac3Odbj/jN+vnIeBg7InURVlhGIK2MMLElT2nnoRL6x0H73EI0UYKVP9y2p7narT8tO67uAIGOQ0YdtBdck6skJ1kTKEQvSWaUQ== X-Scanned-By: mailmunge 3.10 on 66.39.139.36 Using an 'int' signature with 0 for success and < 0 for failure with failure enumerations sources from the negated POSIX errors from errno.h eases system integration by precluding system integrators from having to synthesize their own errors on the prior 'false' returns. In addition, this sets the stage for better error handling of the 'wcstombs' and 'mbstowcs' functions. The entered line is now returned via a return parameter. --- ell/edit.c | 12 +++++++++--- ell/edit.h | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/ell/edit.c b/ell/edit.c index d6329d063c78..6747f92e289e 100644 --- a/ell/edit.c +++ b/ell/edit.c @@ -403,14 +403,14 @@ LIB_EXPORT bool l_edit_is_empty(struct l_edit *edit) return (edit->main->len == 0); } -LIB_EXPORT char *l_edit_enter(struct l_edit *edit) +LIB_EXPORT int l_edit_enter(struct l_edit *edit, char **line) { struct input_buf *buf; char *str; size_t len; if (!edit) - return NULL; + return -EINVAL; /* Convert the wide character string into the multibyte string * representation like UTF-8 for example. @@ -458,9 +458,15 @@ LIB_EXPORT char *l_edit_enter(struct l_edit *edit) } edit->main = edit->head; + update_display(edit); - return str; + if (line) + *line = str; + else + l_free(str); + + return 0; } LIB_EXPORT int l_edit_reset(struct l_edit *edit, const char *input) diff --git a/ell/edit.h b/ell/edit.h index 811246578894..425039733ad0 100644 --- a/ell/edit.h +++ b/ell/edit.h @@ -36,7 +36,7 @@ int l_edit_set_max_input_length(struct l_edit *edit, size_t len); int l_edit_set_history_size(struct l_edit *edit, unsigned int size); int l_edit_refresh(struct l_edit *edit); bool l_edit_is_empty(struct l_edit *edit); -char *l_edit_enter(struct l_edit *edit); +int l_edit_enter(struct l_edit *edit, char **line); int l_edit_reset(struct l_edit *edit, const char *input); int l_edit_insert(struct l_edit *edit, wint_t ch); int l_edit_delete(struct l_edit *edit); From patchwork Sun Apr 6 22:12:15 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Grant Erickson X-Patchwork-Id: 14039549 Received: from mail5.g24.pair.com (mail5.g24.pair.com [66.39.139.36]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 31D1022068B for ; Sun, 6 Apr 2025 22:12:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=66.39.139.36 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743977542; cv=none; b=BO+3cBEK5Fk1pDMVPagjd0eNeNzVLE/tgL2gV/5KYbYgmh34vBnmIeejLfsnsgnRItnU6NCMQGvn178VtbTXKedwpB1wssQ9qwjvWJfK+/FTIUNNT5PNr2Xg9C2bfkn0URfJkGqJlvdrCvpJkPGU9CILirZUj5rNadio19vDJfM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743977542; c=relaxed/simple; bh=jptL6KRnIjB0TN0f2Vlsrs2HGMs6lPiN/f2QCMTuVJE=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=nJPCKnIc4XszWeMZ7whDVmqrKIDz1VUqdn75SEr+RhA1fafOfmPYHn1uJ0ZJtO4xpvMlUcKgFL67hqtt/T/Pv6K00s2nTkHD5r7mbllnDznh+SJIZvJJC/NWNe2MTKvMjhvJG8GZSrgEVzbEeiMsISMT4v0Z9Svj4nE+Uw1LLoE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=nuovations.com; spf=pass smtp.mailfrom=nuovations.com; dkim=pass (2048-bit key) header.d=nuovations.com header.i=@nuovations.com header.b=JL+EyXqU; arc=none smtp.client-ip=66.39.139.36 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=nuovations.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=nuovations.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=nuovations.com header.i=@nuovations.com header.b="JL+EyXqU" Received: from mail5.g24.pair.com (localhost [127.0.0.1]) by mail5.g24.pair.com (Postfix) with ESMTP id 7B5461649AF for ; Sun, 6 Apr 2025 18:12:20 -0400 (EDT) Received: from localhost.localdomain (c-73-202-173-252.hsd1.ca.comcast.net [73.202.173.252]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mail5.g24.pair.com (Postfix) with ESMTPSA id 36EF31260D8 for ; Sun, 6 Apr 2025 18:12:20 -0400 (EDT) From: Grant Erickson To: ell@lists.linux.dev Subject: [PATCH v6 8/8] edit: improve error handling of 'mbstowcs' and 'wcstombs' functions. Date: Sun, 6 Apr 2025 15:12:15 -0700 Message-ID: <645e2d6dbe40ce23ce256199a6941605c568224d.1743977403.git.gerickson@nuovations.com> X-Mailer: git-send-email 2.45.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: ell@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nuovations.com; h=from:to:subject:date:message-id:in-reply-to:references:mime-version:content-transfer-encoding; s=pair-202401062137; bh=XbMbbyqF5gXNXq8YdEUv5r8DO4HkwtVdVkj1Y7GyX78=; b=JL+EyXqUPSz2HkWVgFGI3wOlrbk8eseaLjDFMHs0D7srIoHpP3ZR7QVLZte3IHgPra/C3gdUdYHBLsIekSadRPLPrGCdMlZSpP38B/qlcv/MTnt7uadIxEwwyzHsQB9kwzLxeFs7sBFq+sR5RPQbEtlGBCSnyMVwLEnDlHlaJs9R+Hz+gGVTg/zdszcsnZrHqD+RJ75ymW1CQ+JCOB5xb3A3hh6bRZcuxyvNI64uOh7QL0N4T0UI1ufbVyZUW/TJ5LY/5dxpa5d7m2DJmJK3HFK3kUDdmPQCjiob6lsMXb+WjBWdYO4zTkOJl5tPEY2WalUWLXzBvC0eR38XOQkThw== X-Scanned-By: mailmunge 3.10 on 66.39.139.36 On error, the 'mbstowcs' and 'wcstombs' functions could return 'SIZE_MAX' when uncountering unconvertable character sequences. Ensure that such errors are not obscured and are passed along to the caller. --- ell/edit.c | 53 ++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 44 insertions(+), 9 deletions(-) diff --git a/ell/edit.c b/ell/edit.c index 6747f92e289e..5551ae52bfdb 100644 --- a/ell/edit.c +++ b/ell/edit.c @@ -104,10 +104,16 @@ static void reset_input_buf(struct input_buf *buf, const char *input) if (input) { size_t len; - /* Calculate the required size of the wide character string - * including its terminating null character. + /* Calculate the required size of the wide character string. */ - len = mbstowcs(NULL, input, 0) + 1; + len = mbstowcs(NULL, input, 0); + if (len == SIZE_MAX) + return; + + /* Increase the size of the wide character string by one to + * cover its terminating null character. + */ + len += 1; /* If the current buffer is to small, then allocate a new * one and free the previous one. Since in most cases the @@ -125,6 +131,9 @@ static void reset_input_buf(struct input_buf *buf, const char *input) * and then move the cursor to the end. */ buf->len = mbstowcs(buf->buf, input, buf->size); + if (buf->len == SIZE_MAX) + return; + buf->pos = buf->len; } else { /* Reset the main item to an empty string */ @@ -197,6 +206,7 @@ static void update_debug(struct l_edit *edit) struct l_string *str; char *tmp; size_t len; + size_t status; unsigned int pos = 0; if (!edit->debug_handler) @@ -218,9 +228,14 @@ static void update_debug(struct l_edit *edit) buf = edit->head; while (buf) { - len = wcstombs(NULL, buf->buf, 0) + 1; + len = wcstombs(NULL, buf->buf, 0); + if (len == SIZE_MAX) + return; + len += 1; tmp = l_malloc(len); - wcstombs(tmp, buf->buf, len); + status = wcstombs(tmp, buf->buf, len); + if (status == SIZE_MAX) + return; l_string_append_printf(str, "%3u %s\n", pos, tmp); l_free(tmp); pos++; @@ -415,9 +430,18 @@ LIB_EXPORT int l_edit_enter(struct l_edit *edit, char **line) /* Convert the wide character string into the multibyte string * representation like UTF-8 for example. */ - len = wcstombs(NULL, edit->main->buf, 0) + 1; + len = wcstombs(NULL, edit->main->buf, 0); + if (len == SIZE_MAX) + return -EILSEQ; + + len += 1; + str = l_malloc(len); - wcstombs(str, edit->main->buf, len); + if (!str) + return -ENOMEM; + + if (wcstombs(str, edit->main->buf, len) == SIZE_MAX) + return -EILSEQ; if (edit->main->len > 0) { /* If the current entered item is different from the first @@ -775,10 +799,21 @@ LIB_EXPORT int l_edit_history_save(struct l_edit *edit, const char *pathname) while (buf) { char *tmp; size_t len; + size_t status; - len = wcstombs(NULL, buf->buf, 0) + 1; + len = wcstombs(NULL, buf->buf, 0); + if (len == SIZE_MAX) { + close(fd); + return -EILSEQ; + } + len += 1; tmp = l_malloc(len); - wcstombs(tmp, buf->buf, len); + status = wcstombs(tmp, buf->buf, len); + if (status == SIZE_MAX) { + l_free(tmp); + close(fd); + return -EILSEQ; + } dprintf(fd, "%s\n", tmp); l_free(tmp);