#include <assert.h>
#include <errno.h>
#include <string.h>
+#include <stdlib.h>
+#include <wctype.h>
#include "log/log.h"
#include "talloc/talloc.h"
pmenu_post(scr);
}
+static int pmenu_item_destructor(void *arg)
+{
+ struct pmenu_item *item = arg;
+ free_item(item->nci);
+ return 0;
+}
+
+static const char *pmenu_item_label(struct pmenu_item *item, const char *name)
+{
+ static int invalid_idx;
+ unsigned int i;
+ wchar_t *tmp;
+ char *label;
+ size_t len;
+
+ len = mbstowcs(NULL, name, 0);
+
+ /* if we have an invalid multibyte sequence, create an entirely
+ * new name, indicating that we had invalid input */
+ if (len == SIZE_MAX) {
+ name = talloc_asprintf(item, "!Invalid option %d\n",
+ ++invalid_idx);
+ return name;
+ }
+
+ tmp = talloc_array(item, wchar_t, len + 1);
+ mbstowcs(tmp, name, len + 1);
+
+ /* replace anything unprintable with U+FFFD REPLACEMENT CHARACTER */
+ for (i = 0; i < len; i++) {
+ if (!iswprint(tmp[i]))
+ tmp[i] = 0xfffd;
+ }
+
+ len = wcstombs(NULL, tmp, 0);
+ label = talloc_array(item, char, len + 1);
+ wcstombs(label, tmp, len + 1);
+
+ pb_log("%s: %s\n", __func__, label);
+
+ talloc_free(tmp);
+ return label;
+}
+
/**
* pmenu_item_create - Allocate and initialize a new pmenu_item instance.
*
struct pmenu_item *pmenu_item_create(struct pmenu *menu, const char *name)
{
struct pmenu_item *item = talloc_zero(menu, struct pmenu_item);
+ const char *label;
+
+ label = pmenu_item_label(item, name);
item->i_sig = pb_item_sig;
item->pmenu = menu;
- item->nci = new_item(name, NULL);
+ item->nci = new_item(label, NULL);
if (!item->nci) {
talloc_free(item);
return NULL;
}
+ talloc_set_destructor(item, pmenu_item_destructor);
+
set_item_userptr(item->nci, item);
return item;
if (index < 0)
return -1;
- free_item(item->nci);
talloc_free(item);
/* Note that items array has a null terminator. */
void pmenu_delete(struct pmenu *menu)
{
- unsigned int i;
-
assert(menu->scr.sig == pb_pmenu_sig);
menu->scr.sig = pb_removed_sig;
- for (i = item_count(menu->ncm); i; i--)
- free_item(menu->items[i - 1]);
-
+ unpost_menu(menu->ncm);
free_menu(menu->ncm);
delwin(menu->scr.sub_ncw);
delwin(menu->scr.main_ncw);