Example #1
0
JRB lprev(JRB n)
{
  if (ishead(n)) return n;
  while (!isroot(n)) {
    if (isright(n)) return n->parent;
    n = n->parent;
  }
  return n->parent;
}
Example #2
0
Rb_node lprev(Rb_node n)
{
  if (ishead(n)) return n;
  while (!isroot(n)) {
    if (isright(n)) return n->p.parent;
    n = n->p.parent;
  }
  return n->p.parent;
}
Example #3
0
JRB rprev(JRB n)
{
  if (ishead(n)) return n;
  while (!isroot(n)) {
    if (isleft(n)) return n->parent;
    n = n->parent;
  }
  return n->parent;
}
Example #4
0
void jrb_free_tree(JRB n)
{
  if (!ishead(n)) {
    fprintf(stderr, "ERROR: Rb_free_tree called on a non-head node\n");
    exit(1);
  }

  while(jrb_first(n) != jrb_nil(n)) {
    jrb_delete_node(jrb_first(n));
  }
  free(n);
}
Example #5
0
void jrb_print_tree(JRB t, int level)
{
  int i;
  if (ishead(t) && t->parent == t) {
    printf("tree 0x%x is empty\n", t);
  } else if (ishead(t)) {
    printf("Head: 0x%x.  Root = 0x%x\n", t, t->parent);
    jrb_print_tree(t->parent, 0);
  } else {
    if (isext(t)) {
      for (i = 0; i < level; i++) putchar(' ');
      printf("Ext node 0x%x: %c,%c: p=0x%x, k=%s\n", 
              t, isred(t)?'R':'B', isleft(t)?'l':'r', t->parent, t->key.s);
    } else {
      jrb_print_tree(t->flink, level+2);
      jrb_print_tree(t->blink, level+2);
      for (i = 0; i < level; i++) putchar(' ');
      printf("Int node 0x%x: %c,%c: l=0x%x, r=0x%x, p=0x%x, lr=(%s,%s)\n", 
              t, isred(t)?'R':'B', isleft(t)?'l':'r', t->flink, 
              t->blink, 
              t->parent, getlext(t)->key.s, getrext(t)->key.s);
    }
  }
}
Example #6
0
static JRB jrb_insert_b(JRB n, Jval key, Jval val)
{
    JRB newleft, newright, newnode, list, p;

    if (ishead(n)) {
        if (n->parent == n) {   /* Tree is empty */
            mk_new_ext(newnode, key, val);
            insert(newnode, n);
            n->parent = newnode;
            newnode->parent = n;
            setroot(newnode);
            return newnode;
        }
        else {
            mk_new_ext(newright, key, val);
            insert(newright, n);
            newleft = newright->blink;
            setnormal(newleft);
            mk_new_int(newleft, newright, newleft->parent, isleft(newleft));
            p = rprev(newright);
            if (!ishead(p))
                setlext(p, newright);
            return newright;
        }
    }
    else {
        mk_new_ext(newleft, key, val);
        insert(newleft, n);
        setnormal(n);
        mk_new_int(newleft, n, n->parent, isleft(n));
        p = lprev(newleft);
        if (!ishead(p))
            setrext(p, newleft);
        return newleft;
    }
}
Example #7
0
JRB jrb_find_gte_vptr(JRB n, void *vkey, int *fnd)
{
  *fnd = 0;
  if (!ishead(n)) {
    fprintf(stderr, "jrb_find_gte_int called on non-head 0x%p\n", (void *)n);
    exit(1);
  }
  if (n->parent == n) return n;
  if ((char *)vkey == (char *)n->blink->key.v) {
    *fnd = 1;
    return n->blink;
  }
  if ((char *)vkey > (char *)n->blink->key.v) return n;
  else n = n->parent;
  while (1) {
    if (isext(n)) return n;
    if ((char *)vkey == (char *)getlext(n)->key.v) {
      *fnd = 1;
      return getlext(n);
    }
    n = ((char *)vkey < (char *)getlext(n)->key.v) ? n->flink : n->blink;
  }
}
Example #8
0
JRB jrb_find_gte_int(JRB n, int ikey, int *fnd)
{
  *fnd = 0;
  if (!ishead(n)) {
    fprintf(stderr, "jrb_find_gte_int called on non-head 0x%p\n", (void *)n);
    exit(1);
  }
  if (n->parent == n) return n;
  if (ikey == n->blink->key.i) {
    *fnd = 1;
    return n->blink;
  }
  if (ikey > n->blink->key.i) return n;
  else n = n->parent;
  while (1) {
    if (isext(n)) return n;
    if (ikey == getlext(n)->key.i) {
      *fnd = 1;
      return getlext(n);
    }
    n = (ikey < getlext(n)->key.i) ? n->flink : n->blink;
  }
}
Example #9
0
JRB jrb_find_gte_dbl(JRB n, double dkey, int *fnd)
{
  *fnd = 0;
  if (!ishead(n)) {
    fprintf(stderr, "jrb_find_gte_dbl called on non-head 0x%x\n", n);
    exit(1);
  }
  if (n->parent == n) return n;
  if (dkey == n->blink->key.d) {
    *fnd = 1;
    return n->blink; 
  }
  if (dkey > n->blink->key.d) return n; 
  else n = n->parent;
  while (1) {
    if (isext(n)) return n;
    if (dkey == getlext(n)->key.d) {
      *fnd = 1;
      return getlext(n);
    }
    n = (dkey < getlext(n)->key.d) ? n->flink : n->blink;
  }
}
Example #10
0
Rb_node rb_find_ikey_n(Rb_node n, unsigned int ikey, int *fnd)
{
  *fnd = 0;
  if (!ishead(n)) {
    fprintf(stderr, "rb_find_ikey_n called on non-head 0x%p	\n", 
	    (void *) n);
    exit(1);
  }
  if (n->p.root == n) return n;
  if (ikey == n->c.list.blink->k.ikey) {
    *fnd = 1;
    return n->c.list.blink; 
  }
  if (ikey > n->c.list.blink->k.ikey) return n; 
  else n = n->p.root;
  while (1) {
    if (isext(n)) return n;
    if (ikey == n->k.lext->k.ikey) {
      *fnd = 1;
      return n->k.lext;
    }
    n = (ikey < n->k.lext->k.ikey) ? n->c.child.left : n->c.child.right;
  }
}
Example #11
0
void jrb_delete_node(JRB n)
{
  JRB s, p, gp;
  char ir;

  if (isint(n)) {
    fprintf(stderr, "Cannot delete an internal node: 0x%p\n", (void *)n);
    exit(1);
  }
  if (ishead(n)) {
    fprintf(stderr, "Cannot delete the head of an jrb_tree: 0x%p\n", (void *)n);
    exit(1);
  }
  delete_item(n); /* Delete it from the list */
  p = n->parent;  /* The only node */
  if (isroot(n)) {
    p->parent = p;
    free(n);
    return;
  }
  s = sibling(n);    /* The only node after deletion */
  if (isroot(p)) {
    s->parent = p->parent;
    s->parent->parent = s;
    setroot(s);
    free(p);
    free(n);
    return;
  }
  gp = p->parent;  /* Set parent to sibling */
  s->parent = gp;
  if (isleft(p)) {
    gp->flink = s;
    setleft(s);
  } else {
    gp->blink = s;
    setright(s);
  }
  ir = isred(p);
  free(p);
  free(n);

  if (isext(s)) {      /* Update proper rext and lext values */
    p = lprev(s);
    if (!ishead(p)) setrext(p, s);
    p = rprev(s);
    if (!ishead(p)) setlext(p, s);
  } else if (isblack(s)) {
    fprintf(stderr, "DELETION PROB -- sib is black, internal\n");
    exit(1);
  } else {
    p = lprev(s);
    if (!ishead(p)) setrext(p, s->flink);
    p = rprev(s);
    if (!ishead(p)) setlext(p, s->blink);
    setblack(s);
    return;
  }

  if (ir) return;

  /* Recolor */

  n = s;
  p = n->parent;
  s = sibling(n);
  while(isblack(p) && isblack(s) && isint(s) &&
        isblack(s->flink) && isblack(s->blink)) {
    setred(s);
    n = p;
    if (isroot(n)) return;
    p = n->parent;
    s = sibling(n);
  }

  if (isblack(p) && isred(s)) {  /* Rotation 2.3b */
    single_rotate(p, isright(n));
    setred(p);
    setblack(s);
    s = sibling(n);
  }

  { JRB x, z; char il;

    if (isext(s)) {
      fprintf(stderr, "DELETION ERROR: sibling not internal\n");
      exit(1);
    }

    il = isleft(n);
    x = il ? s->flink : s->blink ;
    z = sibling(x);

    if (isred(z)) {  /* Rotation 2.3f */
      single_rotate(p, !il);
      setblack(z);
      if (isred(p)) setred(s); else setblack(s);
      setblack(p);
    } else if (isblack(x)) {   /* Recoloring only (2.3c) */
      if (isred(s) || isblack(p)) {
        fprintf(stderr, "DELETION ERROR: 2.3c not quite right\n");
        exit(1);
      }
      setblack(p);
      setred(s);
      return;
    } else if (isred(p)) { /* 2.3d */
      single_rotate(s, il);
      single_rotate(p, !il);
      setblack(x);
      setred(s);
      return;
    } else {  /* 2.3e */
      single_rotate(s, il);
      single_rotate(p, !il);
      setblack(x);
      return;
    }
  }
}
Example #12
0
File: fio.c Project: coyizumi/cs111
/*
 * Set up the input pointers while copying the mail file into /tmp.
 */
void
setptr(FILE *ibuf, off_t offset)
{
	int c, count;
	char *cp, *cp2;
	struct message this;
	FILE *mestmp;
	int maybe, inhead;
	char linebuf[LINESIZE], pathbuf[PATHSIZE];
	int omsgCount;

	/* Get temporary file. */
	(void)snprintf(pathbuf, sizeof(pathbuf), "%s/mail.XXXXXXXXXX", tmpdir);
	if ((c = mkstemp(pathbuf)) == -1 || (mestmp = Fdopen(c, "r+")) == NULL)
		err(1, "can't open %s", pathbuf);
	(void)rm(pathbuf);

	if (offset == 0) {
		 msgCount = 0;
	} else {
		/* Seek into the file to get to the new messages */
		(void)fseeko(ibuf, offset, SEEK_SET);
		/*
		 * We need to make "offset" a pointer to the end of
		 * the temp file that has the copy of the mail file.
		 * If any messages have been edited, this will be
		 * different from the offset into the mail file.
		 */
		(void)fseeko(otf, (off_t)0, SEEK_END);
		offset = ftello(otf);
	}
	omsgCount = msgCount;
	maybe = 1;
	inhead = 0;
	this.m_flag = MUSED|MNEW;
	this.m_size = 0;
	this.m_lines = 0;
	this.m_block = 0;
	this.m_offset = 0;
	for (;;) {
		if (fgets(linebuf, sizeof(linebuf), ibuf) == NULL) {
			if (append(&this, mestmp))
				errx(1, "temporary file");
			makemessage(mestmp, omsgCount);
			return;
		}
		count = strlen(linebuf);
		/*
		 * Transforms lines ending in <CR><LF> to just <LF>.
		 * This allows mail to be able to read Eudora mailboxes.
		 */
		if (count >= 2 && linebuf[count - 1] == '\n' &&
		    linebuf[count - 2] == '\r') {
			count--;
			linebuf[count - 1] = '\n';
		}

		(void)fwrite(linebuf, sizeof(*linebuf), count, otf);
		if (ferror(otf))
			errx(1, "/tmp");
		if (count)
			linebuf[count - 1] = '\0';
		if (maybe && linebuf[0] == 'F' && ishead(linebuf)) {
			msgCount++;
			if (append(&this, mestmp))
				errx(1, "temporary file");
			this.m_flag = MUSED|MNEW;
			this.m_size = 0;
			this.m_lines = 0;
			this.m_block = blockof(offset);
			this.m_offset = boffsetof(offset);
			inhead = 1;
		} else if (linebuf[0] == 0) {
			inhead = 0;
		} else if (inhead) {
			for (cp = linebuf, cp2 = "status";; cp++) {
				if ((c = *cp2++) == '\0') {
					while (isspace((unsigned char)*cp++))
						;
					if (cp[-1] != ':')
						break;
					while ((c = *cp++) != '\0')
						if (c == 'R')
							this.m_flag |= MREAD;
						else if (c == 'O')
							this.m_flag &= ~MNEW;
					inhead = 0;
					break;
				}
				if (*cp != c && *cp != toupper((unsigned char)c))
					break;
			}
		}
		offset += count;
		this.m_size += count;
		this.m_lines++;
		maybe = linebuf[0] == 0;
	}
}
Example #13
0
File: fio.c Project: ryo/netbsd-src
/*
 * Set up the input pointers while copying the mail file into /tmp.
 */
PUBLIC void
setptr(FILE *ibuf, off_t offset)
{
    int c;
    size_t len;
    char *cp;
    const char *cp2;
    struct message this;
    FILE *mestmp;
    int maybe, inhead;
    char linebuf[LINESIZE];
    int omsgCount;
#ifdef THREAD_SUPPORT
    int nmsgCount;
#else
# define nmsgCount	msgCount
#endif

    /* Get temporary file. */
    (void)snprintf(linebuf, LINESIZE, "%s/mail.XXXXXX", tmpdir);
    if ((c = mkstemp(linebuf)) == -1 ||
            (mestmp = Fdopen(c, "re+")) == NULL) {
        (void)fprintf(stderr, "mail: can't open %s\n", linebuf);
        exit(1);
    }
    (void)unlink(linebuf);

    nmsgCount = get_abs_msgCount();
    if (offset == 0) {
        nmsgCount = 0;
    } else {
        /* Seek into the file to get to the new messages */
        (void)fseeko(ibuf, offset, 0);
        /*
         * We need to make "offset" a pointer to the end of
         * the temp file that has the copy of the mail file.
         * If any messages have been edited, this will be
         * different from the offset into the mail file.
         */
        (void)fseek(otf, 0L, SEEK_END);
        offset = ftell(otf);
    }
    omsgCount = nmsgCount;
    maybe = 1;
    inhead = 0;
    message_init(&this, (off_t)0, MUSED|MNEW);

    for (;;) {
        if (fgets(linebuf, LINESIZE, ibuf) == NULL) {
            if (append(&this, mestmp))
                err(EXIT_FAILURE, "temporary file");
            makemessage(mestmp, omsgCount, nmsgCount);
            return;
        }
        len = strlen(linebuf);
        /*
         * Transforms lines ending in <CR><LF> to just <LF>.
         * This allows mail to be able to read Eudora mailboxes
         * that reside on a DOS partition.
         */
        if (len >= 2 && linebuf[len - 1] == '\n' &&
                linebuf[len - 2] == '\r') {
            linebuf[len - 2] = '\n';
            len--;
        }
        (void)fwrite(linebuf, sizeof(*linebuf), len, otf);
        if (ferror(otf))
            err(EXIT_FAILURE, "/tmp");
        if (len)
            linebuf[len - 1] = 0;
        if (maybe && linebuf[0] == 'F' && ishead(linebuf)) {
            nmsgCount++;
            if (append(&this, mestmp))
                err(EXIT_FAILURE, "temporary file");
            message_init(&this, offset, MUSED|MNEW);
            inhead = 1;
        } else if (linebuf[0] == 0) {
            inhead = 0;
        } else if (inhead) {
            for (cp = linebuf, cp2 = "status";; cp++) {
                if ((c = *cp2++) == 0) {
                    while (isspace((unsigned char)*cp++))
                        continue;
                    if (cp[-1] != ':')
                        break;
                    while ((c = *cp++) != '\0')
                        if (c == 'R')
                            this.m_flag |= MREAD;
                        else if (c == 'O')
                            this.m_flag &= ~MNEW;
                    inhead = 0;
                    break;
                }
                if (*cp != c && *cp != toupper(c))
                    break;
            }
        }
        offset += len;
        this.m_size += len;
        this.m_lines++;
        if (!inhead) {
            int lines_plus_wraps = 1;
            int linelen = (int)strlen(linebuf);

            if (screenwidth && (int)linelen > screenwidth) {
                lines_plus_wraps = linelen / screenwidth;
                if (linelen % screenwidth != 0)
                    ++lines_plus_wraps;
            }
            this.m_blines += lines_plus_wraps;
        }
        maybe = linebuf[0] == 0;
    }
}
Example #14
0
File: fmt.c Project: alhazred/onarm
static void
fmt(FILE *fi)
{
	wchar_t linebuf[BUFSIZ], canonb[BUFSIZ];
	wchar_t *cp, *cp2;
	int col;
	wchar_t	c;
	char	cbuf[BUFSIZ];	/* stores wchar_t string as char string */

	c = getwc(fi);
	while (c != EOF) {
		/*
		 * Collect a line, doing ^H processing.
		 * Leave tabs for now.
		 */

		cp = linebuf;
		while (c != L'\n' && c != EOF && cp-linebuf < BUFSIZ-1) {
			if (c == L'\b') {
				if (cp > linebuf)
					cp--;
				c = getwc(fi);
				continue;
			}
			if (!(iswprint(c)) && c != L'\t') {
				c = getwc(fi);
				continue;
			}
			*cp++ = c;
			c = getwc(fi);
		}
		*cp = L'\0';

		/*
		 * Toss anything remaining on the input line.
		 */

		while (c != L'\n' && c != EOF)
			c = getwc(fi);
		/*
		 * Expand tabs on the way to canonb.
		 */

		col = 0;
		cp = linebuf;
		cp2 = canonb;
		while (c = *cp++) {
			if (c != L'\t') {
				col += scrwidth(c);
				if (cp2-canonb < BUFSIZ-1)
					*cp2++ = c;
				continue;
			}
			do {
				if (cp2-canonb < BUFSIZ-1)
					*cp2++ = L' ';
				col++;
			} while ((col & 07) != 0);
		}

		/*
		 * Swipe trailing blanks from the line.
		 */

		for (cp2--; cp2 >= canonb && *cp2 == L' '; cp2--);
		*++cp2 = '\0';

			/* special processing to look for mail header lines */
		switch (hdr_state) {
		case off:
			prefix(canonb);
		case not_in_hdr:
			/* look for an initial mail header line */
			/* skip initial blanks */
			for (cp = canonb; *cp == L' '; cp++);
			/*
			 * Need to convert string from wchar_t to char,
			 * since this is what ishead() expects.  Since we
			 * only want to make sure cp points to a "From" line
			 * of the email, we don't have to alloc
			 * BUFSIZ * MB_LEN_MAX to cbuf.
			 */
			wcstombs(cbuf, cp, (BUFSIZ - 1));
			if (ishead(cbuf)) {
				hdr_state = in_hdr;
				fill_hdrbuf(canonb);
			} else {
				/* no mail header line; process normally */
				prefix(canonb);
			}
			break;
		case in_hdr:
			/* already saw 1st mail header line; look for more */
			if (canonb[0] == L'\0') {
				/*
				 * blank line means end of mail header;
				 * verify current mail header buffer
				 * then process it accordingly
				 */
				header_chk();
				process_hdrbuf();
				/* now process the current blank line */
				prefix(canonb);
			} else
				/*
				 * not a blank line--save this line as
				 * a potential mail header line
				 */
				fill_hdrbuf(canonb);
			break;
		}
		if (c != EOF)
			c = getwc(fi);
	}
	/*
	 * end of this file--make sure we process the stuff in
	 * hdrbuf before we're finished
	 */
	if (hdr_state == in_hdr) {
		header_chk();
		process_hdrbuf();
	}
}