+ /* tmp != NULL means we already found a shorter prefix at case 1 */
+ if (tmp == NULL
+ && m_strncmp(qptr, q_list->prefix, q_list->length) == 0) {
+ /* ok, it's a subclass somewhere on this branch */
+
+ ptr = q_list;
+ offset = q_list->length;
+
+ q_list = q_list->down;
+ tail_lng = length - offset;
+ tail_qptr = (char *) qptr + offset;
+
+ while (q_list) {
+ if (length <= q_list->length) {
+ if (m_strncmp(tail_qptr, (q_list->prefix) + offset, tail_lng)
+ == 0) {
+ /* same prefix: return the current class */
+ if (length == q_list->length)
+ return q_list;
+
+ /* found shorter common prefix */
+ if (tmp == NULL) {
+ /* add a node above q_list */
+ tmp = p_new(struct q_class_t, 1);
+ tmp->prefix = p_dupstr(qptr, length);
+ tmp->length = length;
+
+ /* replace q_list by tmp */
+ if (q_list->next) {
+ tmp->next = q_list->next;
+ q_list->next->prev = tmp;
+ }
+ if (q_list->prev) {
+ tmp->prev = q_list->prev;
+ q_list->prev->next = tmp;
+ }
+
+ /* make q_list a child of tmp */
+ tmp->down = q_list;
+ tmp->up = q_list->up;
+ q_list->up = tmp;
+ if (tmp->up->down == q_list)
+ tmp->up->down = tmp;
+
+ /* q_list has no siblings */
+ q_list->next = NULL;
+ q_list->prev = NULL;
+
+ lindex = q_list->index;
+
+ /* tmp should be the return class too */
+ class = tmp;
+
+ /* next class to test */
+ q_list = tmp->next;
+ } else {
+ /* found another branch for which tmp is a shorter prefix */
+
+ /* save the next sibling for later */
+ save = q_list->next;
+
+ /* unlink q_list from the top level list */
+ if (q_list->next)
+ q_list->next->prev = q_list->prev;
+ if (q_list->prev)
+ q_list->prev->next = q_list->next;
+
+ /* at this point, we have a tmp->down; link q_list to it */
+ ptr = tmp->down;
+ while (ptr->next)
+ ptr = ptr->next;
+ ptr->next = q_list;
+ q_list->next = NULL;
+ q_list->prev = ptr;
+ q_list->up = tmp;
+
+ lindex = q_list->index;
+
+ /* next class to test */
+ q_list = save;
+ }
+
+ /* we found a shorter prefix, so we need a redraw */
+ *force_redraw = 1;
+ continue;
+ } else {
+ q_list = q_list->next;
+ continue;
+ }
+ } else {
+ /* longer than the current prefix: try subclassing it */
+ if (tmp == NULL
+ && m_strncmp(tail_qptr, (q_list->prefix) + offset,
+ q_list->length - offset) == 0) {
+ /* still a subclass: go down one level */
+ ptr = q_list;
+ offset = q_list->length;
+
+ q_list = q_list->down;
+ tail_lng = length - offset;
+ tail_qptr = (char *) qptr + offset;
+
+ continue;
+ } else {
+ /* nope, try the next prefix */
+ q_list = q_list->next;
+ continue;
+ }
+ }
+ }