mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-03-22 05:33:45 -04:00
extract: add extract_finish_wide(), and optionally skip stripping trailing empty cells
extract_finish() returns the extracted text in UTF-8, while
extract_finish_wide() returns the extracted text in Unicode.
This patch also adds a new argument to extract_finish{,_wide},
that when set to true, skips stripping trailing empty cells.
This commit is contained in:
parent
eab874eb06
commit
1bc9fd5fe1
4 changed files with 55 additions and 13 deletions
57
extract.c
57
extract.c
|
|
@ -51,10 +51,9 @@ ensure_size(struct extraction_context *ctx, size_t additional_chars)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
extract_finish(struct extraction_context *ctx, char **text, size_t *len)
|
extract_finish_wide(struct extraction_context *ctx, bool strip_trailing_empty,
|
||||||
|
wchar_t **text, size_t *len)
|
||||||
{
|
{
|
||||||
bool ret = false;
|
|
||||||
|
|
||||||
if (text == NULL)
|
if (text == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
@ -63,12 +62,24 @@ extract_finish(struct extraction_context *ctx, char **text, size_t *len)
|
||||||
*len = 0;
|
*len = 0;
|
||||||
|
|
||||||
if (ctx->failed)
|
if (ctx->failed)
|
||||||
goto out;
|
goto err;
|
||||||
|
|
||||||
|
if (!strip_trailing_empty) {
|
||||||
|
/* Insert pending newlines, and replace empty cells with spaces */
|
||||||
|
if (!ensure_size(ctx, ctx->newline_count + ctx->empty_count))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < ctx->newline_count; i++)
|
||||||
|
ctx->buf[ctx->idx++] = L'\n';
|
||||||
|
|
||||||
|
for (size_t i = 0; i < ctx->empty_count; i++)
|
||||||
|
ctx->buf[ctx->idx++] = L' ';
|
||||||
|
}
|
||||||
|
|
||||||
if (ctx->idx == 0) {
|
if (ctx->idx == 0) {
|
||||||
/* Selection of empty cells only */
|
/* Selection of empty cells only */
|
||||||
if (!ensure_size(ctx, 1))
|
if (!ensure_size(ctx, 1))
|
||||||
goto out;
|
goto err;
|
||||||
ctx->buf[ctx->idx++] = L'\0';
|
ctx->buf[ctx->idx++] = L'\0';
|
||||||
} else {
|
} else {
|
||||||
xassert(ctx->idx > 0);
|
xassert(ctx->idx > 0);
|
||||||
|
|
@ -77,12 +88,39 @@ extract_finish(struct extraction_context *ctx, char **text, size_t *len)
|
||||||
ctx->buf[ctx->idx - 1] = L'\0';
|
ctx->buf[ctx->idx - 1] = L'\0';
|
||||||
else {
|
else {
|
||||||
if (!ensure_size(ctx, 1))
|
if (!ensure_size(ctx, 1))
|
||||||
goto out;
|
goto err;
|
||||||
ctx->buf[ctx->idx++] = L'\0';
|
ctx->buf[ctx->idx++] = L'\0';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t _len = wcstombs(NULL, ctx->buf, 0);
|
*text = ctx->buf;
|
||||||
|
if (len != NULL)
|
||||||
|
*len = ctx->idx - 1;
|
||||||
|
free(ctx);
|
||||||
|
return true;
|
||||||
|
|
||||||
|
err:
|
||||||
|
free(ctx->buf);
|
||||||
|
free(ctx);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
extract_finish(struct extraction_context *ctx, bool strip_trailing_empty,
|
||||||
|
char **text, size_t *len)
|
||||||
|
{
|
||||||
|
if (text == NULL)
|
||||||
|
return false;
|
||||||
|
if (len != NULL)
|
||||||
|
*len = 0;
|
||||||
|
|
||||||
|
wchar_t *wtext;
|
||||||
|
if (!extract_finish_wide(ctx, strip_trailing_empty, &wtext, NULL))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bool ret = false;
|
||||||
|
|
||||||
|
size_t _len = wcstombs(NULL, wtext, 0);
|
||||||
if (_len == (size_t)-1) {
|
if (_len == (size_t)-1) {
|
||||||
LOG_ERRNO("failed to convert selection to UTF-8");
|
LOG_ERRNO("failed to convert selection to UTF-8");
|
||||||
goto out;
|
goto out;
|
||||||
|
|
@ -94,7 +132,7 @@ extract_finish(struct extraction_context *ctx, char **text, size_t *len)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
wcstombs(*text, ctx->buf, _len + 1);
|
wcstombs(*text, wtext, _len + 1);
|
||||||
|
|
||||||
if (len != NULL)
|
if (len != NULL)
|
||||||
*len = _len;
|
*len = _len;
|
||||||
|
|
@ -102,8 +140,7 @@ extract_finish(struct extraction_context *ctx, char **text, size_t *len)
|
||||||
ret = true;
|
ret = true;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
free(ctx->buf);
|
free(wtext);
|
||||||
free(ctx);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
|
||||||
#include "terminal.h"
|
#include "terminal.h"
|
||||||
|
|
||||||
|
|
@ -14,4 +15,8 @@ bool extract_one(
|
||||||
int col, void *context);
|
int col, void *context);
|
||||||
|
|
||||||
bool extract_finish(
|
bool extract_finish(
|
||||||
struct extraction_context *context, char **text, size_t *len);
|
struct extraction_context *context, bool strip_trailing_empty,
|
||||||
|
char **text, size_t *len);
|
||||||
|
bool extract_finish_wide(
|
||||||
|
struct extraction_context *context, bool strip_trailing_empty,
|
||||||
|
wchar_t **text, size_t *len);
|
||||||
|
|
|
||||||
|
|
@ -224,7 +224,7 @@ selection_to_text(const struct terminal *term)
|
||||||
&extract_one_const_wrapper, ctx);
|
&extract_one_const_wrapper, ctx);
|
||||||
|
|
||||||
char *text;
|
char *text;
|
||||||
return extract_finish(ctx, &text, NULL) ? text : NULL;
|
return extract_finish(ctx, true, &text, NULL) ? text : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -2917,7 +2917,7 @@ rows_to_text(const struct terminal *term, int start, int end,
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
return extract_finish(ctx, text, len);
|
return extract_finish(ctx, true, text, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue