+ return c1 - c2;
+}
+#endif
+
+#if 1
+static int cmpstring_PP(const void *p1, const void *p2)
+{
+ char s1[21] = {'\0'};
+ char s2[21] = {'\0'};
+ cmd_tbl_t *cp1 = *(cmd_tbl_t **) p1;
+ cmd_tbl_t *cp2 = *(cmd_tbl_t **) p2;
+ cmd_tbl_t *top1 = get_cmd_tbl_parent(*(cmd_tbl_t **) p1);
+ cmd_tbl_t *top2 = get_cmd_tbl_parent(*(cmd_tbl_t **) p2);
+
+ if (top1)
+ strlcpy_P(s1, top1->name, 21);
+ if (top2)
+ strlcpy_P(s2, top2->name, 21);
+
+ strlcat_P(s1, cp1->name, 21);
+ strlcat_P(s2, cp2->name, 21);
+
+ return strcmp(s1, s2);
+}
+#else
+static int cmpstring_PP(const void *p1, const void *p2)
+{
+ cmd_tbl_t *cp1 = *(cmd_tbl_t **) p1;
+ cmd_tbl_t *cp2 = *(cmd_tbl_t **) p2;
+ cmd_tbl_t *top1 = get_cmd_tbl_parent(*(cmd_tbl_t **) p1);
+ cmd_tbl_t *top2 = get_cmd_tbl_parent(*(cmd_tbl_t **) p2);
+ int res;
+
+ if (top1 && top2) {
+ res = strcmp_PP(top1->name, top2->name);
+ if (res == 0)
+ res = strcmp_PP(cp1->name, cp2->name);
+ return res;
+ }
+ if (top1) {
+ res = strcmp_PP(top1->name, cp2->name);
+ if (res == 0)
+ res = strcmp_PP(cp1->name, cp2->name);
+ return res;
+ }
+ if (top2) {
+ res = strcmp_PP(cp1->name, top2->name);
+ if (res == 0)
+ res = strcmp_PP(cp1->name, cp2->name);
+ return res;
+ }
+ return strcmp_PP(cp1->name, cp2->name);
+}
+#endif
+
+/****************************************************************************/
+
+/*
+ * find command table entry for a command
+ */
+
+static cmd_tbl_t *find_cmd (const char *cmd, cmd_tbl_t *table)
+{