aboutsummaryrefslogtreecommitdiff
path: root/contrib/bsddialog/utility/util_builders.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/bsddialog/utility/util_builders.c')
-rw-r--r--contrib/bsddialog/utility/util_builders.c72
1 files changed, 55 insertions, 17 deletions
diff --git a/contrib/bsddialog/utility/util_builders.c b/contrib/bsddialog/utility/util_builders.c
index 2dfa20cb0f86..8c846819f4ee 100644
--- a/contrib/bsddialog/utility/util_builders.c
+++ b/contrib/bsddialog/utility/util_builders.c
@@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (c) 2021-2023 Alfonso Sabato Siciliano
+ * Copyright (c) 2021-2024 Alfonso Sabato Siciliano
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -30,6 +30,7 @@
#include <string.h>
#include <time.h>
#include <unistd.h>
+#include <wchar.h>
#include <bsddialog.h>
#include <bsddialog_theme.h>
@@ -532,6 +533,29 @@ int treeview_builder(BUILDER_ARGS)
}
/* form */
+static unsigned int strcols(const char *string)
+{
+ int w;
+ unsigned int ncol;
+ size_t charlen, mb_cur_max;
+ wchar_t wch;
+ mbstate_t mbs;
+
+ mb_cur_max = MB_CUR_MAX;
+ ncol = 0;
+ memset(&mbs, 0, sizeof(mbs));
+ while ((charlen = mbrlen(string, mb_cur_max, &mbs)) != 0 &&
+ charlen != (size_t)-1 && charlen != (size_t)-2) {
+ if (mbtowc(&wch, string, mb_cur_max) < 0)
+ return (0);
+ if ((w = wcwidth(wch)) > 0)
+ ncol += w;
+ string += charlen;
+ }
+
+ return (ncol);
+}
+
static void
print_form_items(int output, int nitems, struct bsddialog_formitem *items,
int focusitem, struct options *opt)
@@ -551,7 +575,7 @@ print_form_items(int output, int nitems, struct bsddialog_formitem *items,
helpname = items[focusitem].bottomdesc;
dprintf(opt->output_fd, " %s", helpname);
}
- if(opt->help_print_items == false)
+ if (opt->help_print_items == false)
return;
dprintf(opt->output_fd, "\n");
}
@@ -564,7 +588,7 @@ print_form_items(int output, int nitems, struct bsddialog_formitem *items,
int form_builder(BUILDER_ARGS)
{
- int output, fieldlen, valuelen, focusitem;
+ int output, fieldlen, focusitem;
unsigned int i, j, flags, formheight, nitems, sizeitem;
struct bsddialog_formitem *items;
@@ -591,12 +615,16 @@ int form_builder(BUILDER_ARGS)
items[i].xfield = (u_int)strtoul(argv[j++], NULL, 10);
fieldlen = (int)strtol(argv[j++], NULL, 10);
- items[i].fieldlen = abs(fieldlen);
+ if (fieldlen == 0)
+ items[i].fieldlen = strcols(items[i].init);
+ else
+ items[i].fieldlen = abs(fieldlen);
- valuelen = (int)strtol(argv[j++], NULL, 10);
- items[i].maxvaluelen = valuelen == 0 ? abs(fieldlen) : valuelen;
+ items[i].maxvaluelen = (u_int)strtoul(argv[j++], NULL, 10);
+ if (items[i].maxvaluelen == 0)
+ items[i].maxvaluelen = items[i].fieldlen;
- flags = (fieldlen < 0 ? BSDDIALOG_FIELDREADONLY : 0);
+ flags = (fieldlen <= 0) ? BSDDIALOG_FIELDREADONLY : 0;
items[i].flags = flags;
items[i].bottomdesc = opt->item_bottomdesc ? argv[j++] : "";
@@ -643,7 +671,7 @@ int inputbox_builder(BUILDER_ARGS)
int mixedform_builder(BUILDER_ARGS)
{
- int output, focusitem;
+ int output, fieldlen, focusitem;
unsigned int i, j, formheight, nitems, sizeitem;
struct bsddialog_formitem *items;
@@ -662,16 +690,26 @@ int mixedform_builder(BUILDER_ARGS)
exit_error(false, "cannot allocate memory for form items");
j = 0;
for (i = 0; i < nitems; i++) {
- items[i].label = argv[j++];
- items[i].ylabel = (u_int)strtoul(argv[j++], NULL, 10);
- items[i].xlabel = (u_int)strtoul(argv[j++], NULL, 10);
- items[i].init = argv[j++];
- items[i].yfield = (u_int)strtoul(argv[j++], NULL, 10);
- items[i].xfield = (u_int)strtoul(argv[j++], NULL, 10);
- items[i].fieldlen = (u_int)strtoul(argv[j++], NULL, 10);
+ items[i].label = argv[j++];
+ items[i].ylabel = (u_int)strtoul(argv[j++], NULL, 10);
+ items[i].xlabel = (u_int)strtoul(argv[j++], NULL, 10);
+ items[i].init = argv[j++];
+ items[i].yfield = (u_int)strtoul(argv[j++], NULL, 10);
+ items[i].xfield = (u_int)strtoul(argv[j++], NULL, 10);
+ fieldlen = (int)strtol(argv[j++], NULL, 10);
+ if (fieldlen == 0)
+ items[i].fieldlen = strcols(items[i].init);
+ else
+ items[i].fieldlen = abs(fieldlen);
items[i].maxvaluelen = (u_int)strtoul(argv[j++], NULL, 10);
- items[i].flags = (u_int)strtoul(argv[j++], NULL, 10);
- items[i].bottomdesc = opt->item_bottomdesc ? argv[j++] : "";
+ if (items[i].maxvaluelen == 0)
+ items[i].maxvaluelen = items[i].fieldlen;
+
+ items[i].flags = (u_int)strtoul(argv[j++], NULL, 10);
+ if (fieldlen <= 0)
+ items[i].flags |= BSDDIALOG_FIELDREADONLY;
+
+ items[i].bottomdesc = opt->item_bottomdesc ? argv[j++] : "";
}
focusitem = -1;