+#include "getopt-min.h"
+#include "strerror.h"
+
+#define DEBUG_CMD 0 /* set to 1 to debug */
+
+#define debug_cmd(fmt, args...) \
+ debug_cond(DEBUG_CMD, fmt, ##args)
+
+
+jmp_buf cmd_jbuf;
+
+char *strcasestr_P2(const FLASH char *haystack, const char *needle)
+{
+ int nlen = strlen(needle);
+ int hlen = strlen_P(haystack) - nlen + 1;
+ int i;
+
+ for (i = 0; i < hlen; i++) {
+ int j;
+ for (j = 0; j < nlen; j++) {
+ unsigned char c1 = haystack[i+j];
+ unsigned char c2 = needle[j];
+ if (toupper(c1) != toupper(c2))
+ goto next;
+ }
+ return (char *) haystack + i;
+ next:
+ ;
+ }
+ return NULL;
+}
+
+
+#if 0
+static int cmd_tbl_item_count(cmd_tbl_t *p)
+{
+ int count = 0;
+
+ while (p->name != NULL) {
+ if (p->subcmd) {
+ cmd_tbl_t *sub = p->subcmd;
+ while (sub->name != NULL) {
+ if (sub->flags & CTBL_SUBCMDAUTO)
+ count++;
+ sub++;
+ }
+ }
+ if ((p->flags & CTBL_SUBCMDAUTO) == 0)
+ count++;
+ p++;
+ }
+ return count;
+}
+#endif
+
+static cmd_tbl_t *get_cmd_tbl_base(cmd_tbl_t *cmdtp)
+{
+ cmd_tbl_t *p = cmdtp;
+
+ while (p->name != NULL)
+ ++p;
+
+ return p->subcmd;
+}
+
+static cmd_tbl_t *get_cmd_tbl_parent(cmd_tbl_t *child)
+{
+ if ((child->flags & CTBL_SUBCMDAUTO) == 0) {
+
+ cmd_tbl_t *tbl_start = get_cmd_tbl_base(child);
+ if (tbl_start != cmd_tbl) {
+ cmd_tbl_t *top = cmd_tbl;
+ while (top->subcmd != tbl_start)
+ ++top;
+ return top;
+ }
+ }
+ return NULL;
+}
+
+static int print_nameprefix(cmd_tbl_t *p)
+{
+ cmd_tbl_t *top = get_cmd_tbl_parent(p);
+
+ int width = 0;
+ if (top) {
+ width = printf_P(PSTR("%S "), top->name);
+ }
+
+ return width;
+}