/* $NetBSD: literal.c,v 1.6 2024/12/05 22:21:53 christos Exp $ */12/*-3* Copyright (c) 2017 The NetBSD Foundation, Inc.4* All rights reserved.5*6* This code is derived from software contributed to The NetBSD Foundation7* by Christos Zoulas.8*9* Redistribution and use in source and binary forms, with or without10* modification, are permitted provided that the following conditions11* are met:12* 1. Redistributions of source code must retain the above copyright13* notice, this list of conditions and the following disclaimer.14* 2. Redistributions in binary form must reproduce the above copyright15* notice, this list of conditions and the following disclaimer in the16* documentation and/or other materials provided with the distribution.17*18* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND19* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE20* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE21* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE22* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL23* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS24* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)25* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT26* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY27* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF28* SUCH DAMAGE.29*/3031#include "config.h"32#if !defined(lint) && !defined(SCCSID)33__RCSID("$NetBSD: literal.c,v 1.6 2024/12/05 22:21:53 christos Exp $");34#endif /* not lint && not SCCSID */3536/*37* literal.c: Literal sequences handling.38*/39#include <assert.h>40#include <stdio.h>41#include <stdlib.h>42#include <string.h>43#include "el.h"4445libedit_private void46literal_init(EditLine *el)47{48el_literal_t *l = &el->el_literal;4950memset(l, 0, sizeof(*l));51}5253libedit_private void54literal_end(EditLine *el)55{56literal_clear(el);57}5859libedit_private void60literal_clear(EditLine *el)61{62el_literal_t *l = &el->el_literal;63size_t i;6465if (l->l_len == 0)66return;6768for (i = 0; i < l->l_idx; i++)69el_free(l->l_buf[i]);70el_free(l->l_buf);71l->l_buf = NULL;72l->l_len = 0;73l->l_idx = 0;74}7576libedit_private wint_t77literal_add(EditLine *el, const wchar_t *buf, const wchar_t *end, int *wp)78{79el_literal_t *l = &el->el_literal;80size_t i, len;81ssize_t w, n;82char *b;8384w = wcwidth(end[1]); /* column width of the visible char */85*wp = (int)w;8687if (w < 0) /* non-printable characters are negative */88return 0;8990len = (size_t)(end - buf);91for (w = 0, i = 0; i < len; i++)92w += ct_enc_width(buf[i]);93w += ct_enc_width(end[1]);9495b = el_malloc((size_t)(w + 1));96if (b == NULL)97return 0;9899for (n = 0, i = 0; i < len; i++)100n += ct_encode_char(b + n, (size_t)(w - n), buf[i]);101n += ct_encode_char(b + n, (size_t)(w - n), end[1]);102b[n] = '\0';103104/*105* Then save this literal string in the list of such strings,106* and return a "magic character" to put into the terminal buffer.107* When that magic char is 'printed' the saved string (which includes108* the char that belongs in that position) gets sent instead.109*/110if (l->l_idx == l->l_len) {111char **bp;112113l->l_len += 4;114bp = el_realloc(l->l_buf, sizeof(*l->l_buf) * l->l_len);115if (bp == NULL) {116free(b);117l->l_len -= 4;118return 0;119}120l->l_buf = bp;121}122l->l_buf[l->l_idx++] = b;123return EL_LITERAL | (wint_t)(l->l_idx - 1);124}125126libedit_private const char *127literal_get(EditLine *el, wint_t idx)128{129el_literal_t *l = &el->el_literal;130131assert(idx & EL_LITERAL);132idx &= ~EL_LITERAL;133assert(l->l_idx > (size_t)idx);134return l->l_buf[idx];135}136137138