+ return t->target ? t : 0;
+}
+
+static chr_t_entry *find_entry_x(chr_t_entry *t, const char **from, int *len)
+{
+ chr_t_entry *res;
+
+ while (*len <= 0)
+ { /* switch to next buffer */
+ if (*len < 0)
+ break;
+ from++;
+ len++;
+ }
+ if (*len > 0 && t->children && t->children[(unsigned char) **from])
+ {
+ const char *old_from = *from;
+ int old_len = *len;
+
+ (*len)--;
+ (*from)++;
+ if ((res = find_entry_x(t->children[(unsigned char) *old_from],
+ from, len)))
+ return res;
+ /* no match */
+ *len = old_len;
+ *from = old_from;
+ }
+ /* no children match. use ourselves, if we have a target */
+ return t->target ? t : 0;
+}
+
+const char **chr_map_input_x(chrmaptab maptab, const char **from, int *len)
+{
+ chr_t_entry *t = maptab->input;
+ chr_t_entry *res;
+
+ if (!(res = find_entry_x(t, from, len)))
+ abort();
+ return (const char **) (res->target);