diff options
Diffstat (limited to 'contrib/bsddialog/utility/util_builders.c')
-rw-r--r-- | contrib/bsddialog/utility/util_builders.c | 72 |
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; |