コード例 #1
0
ファイル: btree.cpp プロジェクト: dolaneast/AlgorithmPractice
tree234 *newtree234(cmpfn234 cmp) {
    tree234 *ret = mknew(tree234);
    LOG(("created tree %p\n", ret));
    ret->root = NULL;
    ret->cmp = cmp;
    return ret;
}
コード例 #2
0
ファイル: memory.c プロジェクト: rdebath/sgt
level *level_new(void) {
    level *p;

    p = mknew(level);
    p->leveldata = NULL;

    return p;
}
コード例 #3
0
ファイル: memory.c プロジェクト: rdebath/sgt
levelset *levelset_new(void) {
    levelset *p;

    p = mknew(levelset);
    p->levels = NULL;
    p->nlevels = 0;

    return p;
}
コード例 #4
0
ファイル: input.c プロジェクト: 151706061/nsis-chinese
/*
 * Adds a new paragraph to a linked list
 */
static paragraph *addpara(paragraph newpara, paragraph *** hptrptr)
{
  paragraph *mnewpara = mknew(paragraph);
  *mnewpara = newpara;          /* structure copy */
  mnewpara->next = NULL;
  **hptrptr = mnewpara;
  *hptrptr = &mnewpara->next;
  return mnewpara;
}
コード例 #5
0
ファイル: input.c プロジェクト: 151706061/nsis-chinese
/*
 * Adds a new word to a linked list
 */
static word *addword(word newword, word *** hptrptr)
{
  word *mnewword;
  if (!hptrptr)
    return NULL;
  mnewword = mknew(word);
  *mnewword = newword;          /* structure copy */
  mnewword->next = NULL;
  **hptrptr = mnewword;
  *hptrptr = &mnewword->next;
  return mnewword;
}
コード例 #6
0
ファイル: memory.c プロジェクト: rdebath/sgt
gamestate *gamestate_new(int width, int height, int flags) {
    gamestate *p;

    p = mknew(gamestate);
    p->leveldata = mknewn(char, width * height);
    p->width = width;
    p->height = height;
    p->flags = flags;
    p->sequence = NULL;
    p->sequence_size = 0;

    return p;
}
コード例 #7
0
ファイル: input.c プロジェクト: 151706061/nsis-chinese
static void
macrodef(tree234 * macros, wchar_t * name, wchar_t * text, filepos fpos)
{
  macro *m = mknew(macro);
  m->name = name;
  m->text = text;
  if (add234(macros, m) != m)
  {
    error(err_macroexists, &fpos, name);
    sfree(name);
    sfree(text);
  }
}
コード例 #8
0
ファイル: input.c プロジェクト: 151706061/nsis-chinese
static int
macrolookup(tree234 * macros, input * in, wchar_t * name, filepos * pos)
{
  macro m, *gotit;
  m.name = name;
  gotit = find234(macros, &m, NULL);
  if (gotit)
  {
    macrostack *expansion = mknew(macrostack);
    expansion->next = in->stack;
    expansion->text = gotit->text;
    expansion->pos = *pos;      /* structure copy */
    expansion->ptr = 0;
    expansion->npushback = in->npushback;
    in->stack = expansion;
    return TRUE;
  } else
    return FALSE;
}
コード例 #9
0
ファイル: malloc.c プロジェクト: HrantOhanyan/unsis
/*
 * Duplicate a linked list of words
 */
word *dup_word_list(word * w)
{
  word *head, **eptr = &head;

  while (w)
  {
    word *newwd = mknew(word);
    *newwd = *w;                /* structure copy */
    newwd->text = ustrdup(w->text);
    if (w->alt)
      newwd->alt = dup_word_list(w->alt);
    *eptr = newwd;
    newwd->next = NULL;
    eptr = &newwd->next;

    w = w->next;
  }

  return head;
}
コード例 #10
0
ファイル: btree.cpp プロジェクト: dolaneast/AlgorithmPractice
static void *add234_internal(tree234 *t, void *e, int index) {
    node234 *n, **np, *left, *right;
    void *orig_e = e;
    int c, lcount, rcount;

    LOG(("adding node %p to tree %p\n", e, t));
    if (t->root == NULL) {
	t->root = mknew(node234);
	t->root->elems[1] = t->root->elems[2] = NULL;
	t->root->kids[0] = t->root->kids[1] = NULL;
	t->root->kids[2] = t->root->kids[3] = NULL;
	t->root->counts[0] = t->root->counts[1] = 0;
	t->root->counts[2] = t->root->counts[3] = 0;
	t->root->parent = NULL;
	t->root->elems[0] = e;
	LOG(("  created root %p\n", t->root));
	return orig_e;
    }

    np = &t->root;
    while (*np) {
	int childnum;
	n = *np;
	LOG(("  node %p: %p/%d [%p] %p/%d [%p] %p/%d [%p] %p/%d\n",
	     n,
	     n->kids[0], n->counts[0], n->elems[0],
	     n->kids[1], n->counts[1], n->elems[1],
	     n->kids[2], n->counts[2], n->elems[2],
	     n->kids[3], n->counts[3]));
	if (index >= 0) {
	    if (!n->kids[0]) {
	
		childnum = index;
	    } else {

		do { 
		    if (index <= n->counts[0]) {
			childnum = 0;
			break;
		    }
		    index -= n->counts[0] + 1;
		    if (index <= n->counts[1]) {
			childnum = 1;
			break;
		    }
		    index -= n->counts[1] + 1;
		    if (index <= n->counts[2]) {
			childnum = 2;
			break;
		    }
		    index -= n->counts[2] + 1;
		    if (index <= n->counts[3]) {
			childnum = 3;
			break;
		    }
		    return NULL;      
		} while (0);
	    }
	} else {
	    if ((c = t->cmp(e, n->elems[0])) < 0)
		childnum = 0;
	    else if (c == 0)
		return n->elems[0];	       
	    else if (n->elems[1] == NULL || (c = t->cmp(e, n->elems[1])) < 0)
		childnum = 1;
	    else if (c == 0)
		return n->elems[1];	       
	    else if (n->elems[2] == NULL || (c = t->cmp(e, n->elems[2])) < 0)
		childnum = 2;
	    else if (c == 0)
		return n->elems[2];	      
	    else
		childnum = 3;
	}
	np = &n->kids[childnum];
	LOG(("  moving to child %d (%p)\n", childnum, *np));
    }


    left = NULL;  lcount = 0;
    right = NULL; rcount = 0;
    while (n) {
	LOG(("  at %p: %p/%d [%p] %p/%d [%p] %p/%d [%p] %p/%d\n",
	     n,
	     n->kids[0], n->counts[0], n->elems[0],
	     n->kids[1], n->counts[1], n->elems[1],
	     n->kids[2], n->counts[2], n->elems[2],
	     n->kids[3], n->counts[3]));
	LOG(("  need to insert %p/%d [%p] %p/%d at position %d\n",
	     left, lcount, e, right, rcount, np - n->kids));
	if (n->elems[1] == NULL) {

	    if (np == &n->kids[0]) {
		LOG(("  inserting on left of 2-node\n"));
		n->kids[2] = n->kids[1];     n->counts[2] = n->counts[1];
		n->elems[1] = n->elems[0];
		n->kids[1] = right;          n->counts[1] = rcount;
		n->elems[0] = e;
		n->kids[0] = left;           n->counts[0] = lcount;
	    } else { 
		LOG(("  inserting on right of 2-node\n"));
		n->kids[2] = right;          n->counts[2] = rcount;
		n->elems[1] = e;
		n->kids[1] = left;           n->counts[1] = lcount;
	    }
	    if (n->kids[0]) n->kids[0]->parent = n;
	    if (n->kids[1]) n->kids[1]->parent = n;
	    if (n->kids[2]) n->kids[2]->parent = n;
	    LOG(("  done\n"));
	    break;
	} else if (n->elems[2] == NULL) {

	    if (np == &n->kids[0]) {
		LOG(("  inserting on left of 3-node\n"));
		n->kids[3] = n->kids[2];    n->counts[3] = n->counts[2];
		n->elems[2] = n->elems[1];
		n->kids[2] = n->kids[1];    n->counts[2] = n->counts[1];
		n->elems[1] = n->elems[0];
		n->kids[1] = right;         n->counts[1] = rcount;
		n->elems[0] = e;
		n->kids[0] = left;          n->counts[0] = lcount;
	    } else if (np == &n->kids[1]) {
		LOG(("  inserting in middle of 3-node\n"));
		n->kids[3] = n->kids[2];    n->counts[3] = n->counts[2];
		n->elems[2] = n->elems[1];
		n->kids[2] = right;         n->counts[2] = rcount;
		n->elems[1] = e;
		n->kids[1] = left;          n->counts[1] = lcount;
	    } else { /* np == &n->kids[2] */
		LOG(("  inserting on right of 3-node\n"));
		n->kids[3] = right;         n->counts[3] = rcount;
		n->elems[2] = e;
		n->kids[2] = left;          n->counts[2] = lcount;
	    }
	    if (n->kids[0]) n->kids[0]->parent = n;
	    if (n->kids[1]) n->kids[1]->parent = n;
	    if (n->kids[2]) n->kids[2]->parent = n;
	    if (n->kids[3]) n->kids[3]->parent = n;
	    LOG(("  done\n"));
	    break;
	} else {
	    node234 *m = mknew(node234);
	    m->parent = n->parent;
	    LOG(("  splitting a 4-node; created new node %p\n", m));

	    if (np == &n->kids[0]) {
		m->kids[0] = left;          m->counts[0] = lcount;
		m->elems[0] = e;
		m->kids[1] = right;         m->counts[1] = rcount;
		m->elems[1] = n->elems[0];
		m->kids[2] = n->kids[1];    m->counts[2] = n->counts[1];
		e = n->elems[1];
		n->kids[0] = n->kids[2];    n->counts[0] = n->counts[2];
		n->elems[0] = n->elems[2];
		n->kids[1] = n->kids[3];    n->counts[1] = n->counts[3];
	    } else if (np == &n->kids[1]) {
		m->kids[0] = n->kids[0];    m->counts[0] = n->counts[0];
		m->elems[0] = n->elems[0];
		m->kids[1] = left;          m->counts[1] = lcount;
		m->elems[1] = e;
		m->kids[2] = right;         m->counts[2] = rcount;
		e = n->elems[1];
		n->kids[0] = n->kids[2];    n->counts[0] = n->counts[2];
		n->elems[0] = n->elems[2];
		n->kids[1] = n->kids[3];    n->counts[1] = n->counts[3];
	    } else if (np == &n->kids[2]) {
		m->kids[0] = n->kids[0];    m->counts[0] = n->counts[0];
		m->elems[0] = n->elems[0];
		m->kids[1] = n->kids[1];    m->counts[1] = n->counts[1];
		m->elems[1] = n->elems[1];
		m->kids[2] = left;          m->counts[2] = lcount;
		/* e = e; */
		n->kids[0] = right;         n->counts[0] = rcount;
		n->elems[0] = n->elems[2];
		n->kids[1] = n->kids[3];    n->counts[1] = n->counts[3];
	    } else { /* np == &n->kids[3] */
		m->kids[0] = n->kids[0];    m->counts[0] = n->counts[0];
		m->elems[0] = n->elems[0];
		m->kids[1] = n->kids[1];    m->counts[1] = n->counts[1];
		m->elems[1] = n->elems[1];
		m->kids[2] = n->kids[2];    m->counts[2] = n->counts[2];
		n->kids[0] = left;          n->counts[0] = lcount;
		n->elems[0] = e;
		n->kids[1] = right;         n->counts[1] = rcount;
		e = n->elems[2];
	    }
	    m->kids[3] = n->kids[3] = n->kids[2] = NULL;
	    m->counts[3] = n->counts[3] = n->counts[2] = 0;
	    m->elems[2] = n->elems[2] = n->elems[1] = NULL;
	    if (m->kids[0]) m->kids[0]->parent = m;
	    if (m->kids[1]) m->kids[1]->parent = m;
	    if (m->kids[2]) m->kids[2]->parent = m;
	    if (n->kids[0]) n->kids[0]->parent = n;
	    if (n->kids[1]) n->kids[1]->parent = n;
	    LOG(("  left (%p): %p/%d [%p] %p/%d [%p] %p/%d\n", m,
		 m->kids[0], m->counts[0], m->elems[0],
		 m->kids[1], m->counts[1], m->elems[1],
		 m->kids[2], m->counts[2]));
	    LOG(("  right (%p): %p/%d [%p] %p/%d\n", n,
		 n->kids[0], n->counts[0], n->elems[0],
		 n->kids[1], n->counts[1]));
	    left = m;  lcount = countnode234(left);
	    right = n; rcount = countnode234(right);
	}
	if (n->parent)
	    np = (n->parent->kids[0] == n ? &n->parent->kids[0] :
		  n->parent->kids[1] == n ? &n->parent->kids[1] :
		  n->parent->kids[2] == n ? &n->parent->kids[2] :
		  &n->parent->kids[3]);
	n = n->parent;
    }


    if (n) {
	while (n->parent) {
	    int count = countnode234(n);
	    int childnum;
	    childnum = (n->parent->kids[0] == n ? 0 :
			n->parent->kids[1] == n ? 1 :
			n->parent->kids[2] == n ? 2 : 3);
	    n->parent->counts[childnum] = count;
	    n = n->parent;
	}
    } else {
	LOG(("  root is overloaded, split into two\n"));
	t->root = mknew(node234);
	t->root->kids[0] = left;     t->root->counts[0] = lcount;
	t->root->elems[0] = e;
	t->root->kids[1] = right;    t->root->counts[1] = rcount;
	t->root->elems[1] = NULL;
	t->root->kids[2] = NULL;     t->root->counts[2] = 0;
	t->root->elems[2] = NULL;
	t->root->kids[3] = NULL;     t->root->counts[3] = 0;
	t->root->parent = NULL;
	if (t->root->kids[0]) t->root->kids[0]->parent = t->root;
	if (t->root->kids[1]) t->root->kids[1]->parent = t->root;
	LOG(("  new root is %p/%d [%p] %p/%d\n",
	     t->root->kids[0], t->root->counts[0],
	     t->root->elems[0],
	     t->root->kids[1], t->root->counts[1]));
    }

    return orig_e;
}
コード例 #11
0
ファイル: tree234.c プロジェクト: rdebath/sgt
/*
 * Add an element e to a 2-3-4 tree t. Returns e on success, or if
 * an existing element compares equal, returns that.
 */
void *add234(tree234 *t, void *e) {
    node234 *n, **np, *left, *right;
    void *orig_e = e;
    int c;

    LOG(("adding node %p to tree %p\n", e, t));
    if (t->root == NULL) {
	t->root = mknew(node234);
	t->root->elems[1] = t->root->elems[2] = NULL;
	t->root->kids[0] = t->root->kids[1] = NULL;
	t->root->kids[2] = t->root->kids[3] = NULL;
	t->root->parent = NULL;
	t->root->elems[0] = e;
	LOG(("  created root %p\n", t->root));
	return orig_e;
    }

    np = &t->root;
    while (*np) {
	n = *np;
	LOG(("  node %p: %p [%p] %p [%p] %p [%p] %p\n",
	     n, n->kids[0], n->elems[0], n->kids[1], n->elems[1],
	     n->kids[2], n->elems[2], n->kids[3]));
	if ((c = t->cmp(e, n->elems[0])) < 0)
	    np = &n->kids[0];
	else if (c == 0)
	    return n->elems[0];	       /* already exists */
	else if (n->elems[1] == NULL || (c = t->cmp(e, n->elems[1])) < 0)
	    np = &n->kids[1];
	else if (c == 0)
	    return n->elems[1];	       /* already exists */
	else if (n->elems[2] == NULL || (c = t->cmp(e, n->elems[2])) < 0)
	    np = &n->kids[2];
	else if (c == 0)
	    return n->elems[2];	       /* already exists */
	else
	    np = &n->kids[3];
	LOG(("  moving to child %d (%p)\n", np - n->kids, *np));
    }

    /*
     * We need to insert the new element in n at position np.
     */
    left = NULL;
    right = NULL;
    while (n) {
	LOG(("  at %p: %p [%p] %p [%p] %p [%p] %p\n",
	     n, n->kids[0], n->elems[0], n->kids[1], n->elems[1],
	     n->kids[2], n->elems[2], n->kids[3]));
	LOG(("  need to insert %p [%p] %p at position %d\n",
	     left, e, right, np - n->kids));
	if (n->elems[1] == NULL) {
	    /*
	     * Insert in a 2-node; simple.
	     */
	    if (np == &n->kids[0]) {
		LOG(("  inserting on left of 2-node\n"));
		n->kids[2] = n->kids[1];
		n->elems[1] = n->elems[0];
		n->kids[1] = right;
		n->elems[0] = e;
		n->kids[0] = left;
	    } else { /* np == &n->kids[1] */
		LOG(("  inserting on right of 2-node\n"));
		n->kids[2] = right;
		n->elems[1] = e;
		n->kids[1] = left;
	    }
	    if (n->kids[0]) n->kids[0]->parent = n;
	    if (n->kids[1]) n->kids[1]->parent = n;
	    if (n->kids[2]) n->kids[2]->parent = n;
	    LOG(("  done\n"));
	    break;
	} else if (n->elems[2] == NULL) {
	    /*
	     * Insert in a 3-node; simple.
	     */
	    if (np == &n->kids[0]) {
		LOG(("  inserting on left of 3-node\n"));
		n->kids[3] = n->kids[2];
		n->elems[2] = n->elems[1];
		n->kids[2] = n->kids[1];
		n->elems[1] = n->elems[0];
		n->kids[1] = right;
		n->elems[0] = e;
		n->kids[0] = left;
	    } else if (np == &n->kids[1]) {
		LOG(("  inserting in middle of 3-node\n"));
		n->kids[3] = n->kids[2];
		n->elems[2] = n->elems[1];
		n->kids[2] = right;
		n->elems[1] = e;
		n->kids[1] = left;
	    } else { /* np == &n->kids[2] */
		LOG(("  inserting on right of 3-node\n"));
		n->kids[3] = right;
		n->elems[2] = e;
		n->kids[2] = left;
	    }
	    if (n->kids[0]) n->kids[0]->parent = n;
	    if (n->kids[1]) n->kids[1]->parent = n;
	    if (n->kids[2]) n->kids[2]->parent = n;
	    if (n->kids[3]) n->kids[3]->parent = n;
	    LOG(("  done\n"));
	    break;
	} else {
	    node234 *m = mknew(node234);
	    m->parent = n->parent;
	    LOG(("  splitting a 4-node; created new node %p\n", m));
	    /*
	     * Insert in a 4-node; split into a 2-node and a
	     * 3-node, and move focus up a level.
	     * 
	     * I don't think it matters which way round we put the
	     * 2 and the 3. For simplicity, we'll put the 3 first
	     * always.
	     */
	    if (np == &n->kids[0]) {
		m->kids[0] = left;
		m->elems[0] = e;
		m->kids[1] = right;
		m->elems[1] = n->elems[0];
		m->kids[2] = n->kids[1];
		e = n->elems[1];
		n->kids[0] = n->kids[2];
		n->elems[0] = n->elems[2];
		n->kids[1] = n->kids[3];
	    } else if (np == &n->kids[1]) {
		m->kids[0] = n->kids[0];
		m->elems[0] = n->elems[0];
		m->kids[1] = left;
		m->elems[1] = e;
		m->kids[2] = right;
		e = n->elems[1];
		n->kids[0] = n->kids[2];
		n->elems[0] = n->elems[2];
		n->kids[1] = n->kids[3];
	    } else if (np == &n->kids[2]) {
		m->kids[0] = n->kids[0];
		m->elems[0] = n->elems[0];
		m->kids[1] = n->kids[1];
		m->elems[1] = n->elems[1];
		m->kids[2] = left;
		/* e = e; */
		n->kids[0] = right;
		n->elems[0] = n->elems[2];
		n->kids[1] = n->kids[3];
	    } else { /* np == &n->kids[3] */
		m->kids[0] = n->kids[0];
		m->elems[0] = n->elems[0];
		m->kids[1] = n->kids[1];
		m->elems[1] = n->elems[1];
		m->kids[2] = n->kids[2];
		n->kids[0] = left;
		n->elems[0] = e;
		n->kids[1] = right;
		e = n->elems[2];
	    }
	    m->kids[3] = n->kids[3] = n->kids[2] = NULL;
	    m->elems[2] = n->elems[2] = n->elems[1] = NULL;
	    if (m->kids[0]) m->kids[0]->parent = m;
	    if (m->kids[1]) m->kids[1]->parent = m;
	    if (m->kids[2]) m->kids[2]->parent = m;
	    if (n->kids[0]) n->kids[0]->parent = n;
	    if (n->kids[1]) n->kids[1]->parent = n;
	    LOG(("  left (%p): %p [%p] %p [%p] %p\n", m,
		 m->kids[0], m->elems[0],
		 m->kids[1], m->elems[1],
		 m->kids[2]));
	    LOG(("  right (%p): %p [%p] %p\n", n,
		 n->kids[0], n->elems[0],
		 n->kids[1]));
	    left = m;
	    right = n;
	}
	if (n->parent)
	    np = (n->parent->kids[0] == n ? &n->parent->kids[0] :
		  n->parent->kids[1] == n ? &n->parent->kids[1] :
		  n->parent->kids[2] == n ? &n->parent->kids[2] :
		  &n->parent->kids[3]);
	n = n->parent;
    }

    /*
     * If we've come out of here by `break', n will still be
     * non-NULL and we've finished. If we've come here because n is
     * NULL, we need to create a new root for the tree because the
     * old one has just split into two.
     */
    if (!n) {
	LOG(("  root is overloaded, split into two\n"));
	t->root = mknew(node234);
	t->root->kids[0] = left;
	t->root->elems[0] = e;
	t->root->kids[1] = right;
	t->root->elems[1] = NULL;
	t->root->kids[2] = NULL;
	t->root->elems[2] = NULL;
	t->root->kids[3] = NULL;
	t->root->parent = NULL;
	if (t->root->kids[0]) t->root->kids[0]->parent = t->root;
	if (t->root->kids[1]) t->root->kids[1]->parent = t->root;
	LOG(("  new root is %p [%p] %p\n",
	     t->root->kids[0], t->root->elems[0], t->root->kids[1]));
    }

    return orig_e;
}
コード例 #12
0
ファイル: tree234.c プロジェクト: Distrotech/opensips
/*
 * Add an element e to a 2-3-4 tree t. Returns e on success, or if
 * an existing element compares equal, returns that.
 */
static void *add234_internal(tree234 *t, void *e, int index) {
    node234 *n, **np, *left, *right;
    void *orig_e = e;
    int c, lcount, rcount;

    LOG123(("adding node %p to tree %p\n", e, t));
    if (t->root == NULL) {
	t->root = mknew(node234);
	t->root->elems[1] = t->root->elems[2] = NULL;
	t->root->kids[0] = t->root->kids[1] = NULL;
	t->root->kids[2] = t->root->kids[3] = NULL;
	t->root->counts[0] = t->root->counts[1] = 0;
	t->root->counts[2] = t->root->counts[3] = 0;
	t->root->parent = NULL;
	t->root->elems[0] = e;
	LOG123(("  created root %p\n", t->root));
	return orig_e;
	}

	np = &t->root;
	n = *np;

	while (*np) {
	int childnum;
	n = *np;
	LOG123(("  node %p: %p/%d [%p] %p/%d [%p] %p/%d [%p] %p/%d\n",
	     n,
	     n->kids[0], n->counts[0], n->elems[0],
	     n->kids[1], n->counts[1], n->elems[1],
	     n->kids[2], n->counts[2], n->elems[2],
	     n->kids[3], n->counts[3]));
	if (index >= 0) {
	    if (!n->kids[0]) {
		/*
		 * Leaf node. We want to insert at kid position
		 * equal to the index:
		 *
		 *   0 A 1 B 2 C 3
		 */
		childnum = index;
	    } else {
		/*
		 * Internal node. We always descend through it (add
		 * always starts at the bottom, never in the
		 * middle).
		 */
		do { /* this is a do ... while (0) to allow `break' */
		    if (index <= n->counts[0]) {
			childnum = 0;
			break;
		    }
		    index -= n->counts[0] + 1;
		    if (index <= n->counts[1]) {
			childnum = 1;
			break;
		    }
		    index -= n->counts[1] + 1;
		    if (index <= n->counts[2]) {
			childnum = 2;
			break;
		    }
		    index -= n->counts[2] + 1;
		    if (index <= n->counts[3]) {
			childnum = 3;
			break;
		    }
		    return NULL;       /* error: index out of range */
		} while (0);
	    }
	} else {
	    if ((c = t->cmp(e, n->elems[0])) < 0)
		childnum = 0;
	    else if (c == 0)
		return n->elems[0];	       /* already exists */
	    else if (n->elems[1] == NULL || (c = t->cmp(e, n->elems[1])) < 0)
		childnum = 1;
	    else if (c == 0)
		return n->elems[1];	       /* already exists */
	    else if (n->elems[2] == NULL || (c = t->cmp(e, n->elems[2])) < 0)
		childnum = 2;
	    else if (c == 0)
		return n->elems[2];	       /* already exists */
	    else
		childnum = 3;
	}
	np = &n->kids[childnum];
	LOG123(("  moving to child %d (%p)\n", childnum, *np));
    }

    /*
     * We need to insert the new element in n at position np.
     */
    left = NULL;  lcount = 0;
    right = NULL; rcount = 0;
    while (n) {
	LOG123(("  at %p: %p/%d [%p] %p/%d [%p] %p/%d [%p] %p/%d\n",
	     n,
	     n->kids[0], n->counts[0], n->elems[0],
	     n->kids[1], n->counts[1], n->elems[1],
	     n->kids[2], n->counts[2], n->elems[2],
	     n->kids[3], n->counts[3]));
	LOG123(("  need to insert %p/%d [%p] %p/%d at position %d\n",
	     left, lcount, e, right, rcount, np - n->kids));
	if (n->elems[1] == NULL) {
	    /*
	     * Insert in a 2-node; simple.
	     */
	    if (np == &n->kids[0]) {
		LOG123(("  inserting on left of 2-node\n"));
		n->kids[2] = n->kids[1];     n->counts[2] = n->counts[1];
		n->elems[1] = n->elems[0];
		n->kids[1] = right;          n->counts[1] = rcount;
		n->elems[0] = e;
		n->kids[0] = left;           n->counts[0] = lcount;
	    } else { /* np == &n->kids[1] */
		LOG123(("  inserting on right of 2-node\n"));
		n->kids[2] = right;          n->counts[2] = rcount;
		n->elems[1] = e;
		n->kids[1] = left;           n->counts[1] = lcount;
	    }
	    if (n->kids[0]) n->kids[0]->parent = n;
	    if (n->kids[1]) n->kids[1]->parent = n;
	    if (n->kids[2]) n->kids[2]->parent = n;
	    LOG123(("  done\n"));
	    break;
	} else if (n->elems[2] == NULL) {
	    /*
	     * Insert in a 3-node; simple.
	     */
	    if (np == &n->kids[0]) {
		LOG123(("  inserting on left of 3-node\n"));
		n->kids[3] = n->kids[2];    n->counts[3] = n->counts[2];
		n->elems[2] = n->elems[1];
		n->kids[2] = n->kids[1];    n->counts[2] = n->counts[1];
		n->elems[1] = n->elems[0];
		n->kids[1] = right;         n->counts[1] = rcount;
		n->elems[0] = e;
		n->kids[0] = left;          n->counts[0] = lcount;
	    } else if (np == &n->kids[1]) {
		LOG123(("  inserting in middle of 3-node\n"));
		n->kids[3] = n->kids[2];    n->counts[3] = n->counts[2];
		n->elems[2] = n->elems[1];
		n->kids[2] = right;         n->counts[2] = rcount;
		n->elems[1] = e;
		n->kids[1] = left;          n->counts[1] = lcount;
	    } else { /* np == &n->kids[2] */
		LOG123(("  inserting on right of 3-node\n"));
		n->kids[3] = right;         n->counts[3] = rcount;
		n->elems[2] = e;
		n->kids[2] = left;          n->counts[2] = lcount;
	    }
	    if (n->kids[0]) n->kids[0]->parent = n;
	    if (n->kids[1]) n->kids[1]->parent = n;
	    if (n->kids[2]) n->kids[2]->parent = n;
	    if (n->kids[3]) n->kids[3]->parent = n;
	    LOG123(("  done\n"));
	    break;
	} else {
	    node234 *m = mknew(node234);
	    m->parent = n->parent;
	    LOG123(("  splitting a 4-node; created new node %p\n", m));
	    /*
	     * Insert in a 4-node; split into a 2-node and a
	     * 3-node, and move focus up a level.
	     *
	     * I don't think it matters which way round we put the
	     * 2 and the 3. For simplicity, we'll put the 3 first
	     * always.
	     */
	    if (np == &n->kids[0]) {
		m->kids[0] = left;          m->counts[0] = lcount;
		m->elems[0] = e;
		m->kids[1] = right;         m->counts[1] = rcount;
		m->elems[1] = n->elems[0];
		m->kids[2] = n->kids[1];    m->counts[2] = n->counts[1];
		e = n->elems[1];
		n->kids[0] = n->kids[2];    n->counts[0] = n->counts[2];
		n->elems[0] = n->elems[2];
		n->kids[1] = n->kids[3];    n->counts[1] = n->counts[3];
	    } else if (np == &n->kids[1]) {
		m->kids[0] = n->kids[0];    m->counts[0] = n->counts[0];
		m->elems[0] = n->elems[0];
		m->kids[1] = left;          m->counts[1] = lcount;
		m->elems[1] = e;
		m->kids[2] = right;         m->counts[2] = rcount;
		e = n->elems[1];
		n->kids[0] = n->kids[2];    n->counts[0] = n->counts[2];
		n->elems[0] = n->elems[2];
		n->kids[1] = n->kids[3];    n->counts[1] = n->counts[3];
	    } else if (np == &n->kids[2]) {
		m->kids[0] = n->kids[0];    m->counts[0] = n->counts[0];
		m->elems[0] = n->elems[0];
		m->kids[1] = n->kids[1];    m->counts[1] = n->counts[1];
		m->elems[1] = n->elems[1];
		m->kids[2] = left;          m->counts[2] = lcount;
		/* e = e; */
		n->kids[0] = right;         n->counts[0] = rcount;
		n->elems[0] = n->elems[2];
		n->kids[1] = n->kids[3];    n->counts[1] = n->counts[3];
	    } else { /* np == &n->kids[3] */
		m->kids[0] = n->kids[0];    m->counts[0] = n->counts[0];
		m->elems[0] = n->elems[0];
		m->kids[1] = n->kids[1];    m->counts[1] = n->counts[1];
		m->elems[1] = n->elems[1];
		m->kids[2] = n->kids[2];    m->counts[2] = n->counts[2];
		n->kids[0] = left;          n->counts[0] = lcount;
		n->elems[0] = e;
		n->kids[1] = right;         n->counts[1] = rcount;
		e = n->elems[2];
	    }
	    m->kids[3] = n->kids[3] = n->kids[2] = NULL;
	    m->counts[3] = n->counts[3] = n->counts[2] = 0;
	    m->elems[2] = n->elems[2] = n->elems[1] = NULL;
	    if (m->kids[0]) m->kids[0]->parent = m;
	    if (m->kids[1]) m->kids[1]->parent = m;
	    if (m->kids[2]) m->kids[2]->parent = m;
	    if (n->kids[0]) n->kids[0]->parent = n;
	    if (n->kids[1]) n->kids[1]->parent = n;
	    LOG123(("  left (%p): %p/%d [%p] %p/%d [%p] %p/%d\n", m,
		 m->kids[0], m->counts[0], m->elems[0],
		 m->kids[1], m->counts[1], m->elems[1],
		 m->kids[2], m->counts[2]));
	    LOG123(("  right (%p): %p/%d [%p] %p/%d\n", n,
		 n->kids[0], n->counts[0], n->elems[0],
		 n->kids[1], n->counts[1]));
	    left = m;  lcount = countnode234(left);
	    right = n; rcount = countnode234(right);
	}
	if (n->parent)
	    np = (n->parent->kids[0] == n ? &n->parent->kids[0] :
		  n->parent->kids[1] == n ? &n->parent->kids[1] :
		  n->parent->kids[2] == n ? &n->parent->kids[2] :
		  &n->parent->kids[3]);
	n = n->parent;
    }

    /*
     * If we've come out of here by `break', n will still be
     * non-NULL and all we need to do is go back up the tree
     * updating counts. If we've come here because n is NULL, we
     * need to create a new root for the tree because the old one
     * has just split into two. */
    if (n) {
	while (n->parent) {
	    int count = countnode234(n);
	    int childnum;
	    childnum = (n->parent->kids[0] == n ? 0 :
			n->parent->kids[1] == n ? 1 :
			n->parent->kids[2] == n ? 2 : 3);
	    n->parent->counts[childnum] = count;
	    n = n->parent;
	}
    } else {
	LOG123(("  root is overloaded, split into two\n"));
	t->root = mknew(node234);
	t->root->kids[0] = left;     t->root->counts[0] = lcount;
	t->root->elems[0] = e;
	t->root->kids[1] = right;    t->root->counts[1] = rcount;
	t->root->elems[1] = NULL;
	t->root->kids[2] = NULL;     t->root->counts[2] = 0;
	t->root->elems[2] = NULL;
	t->root->kids[3] = NULL;     t->root->counts[3] = 0;
	t->root->parent = NULL;
	if (t->root->kids[0]) t->root->kids[0]->parent = t->root;
	if (t->root->kids[1]) t->root->kids[1]->parent = t->root;
	LOG123(("  new root is %p/%d [%p] %p/%d\n",
	     t->root->kids[0], t->root->counts[0],
	     t->root->elems[0],
	     t->root->kids[1], t->root->counts[1]));
    }

    return orig_e;
}