# HG changeset patch # User John Tsiombikas # Date 1318386334 -10800 # Node ID 56a08d00bb4187812e27b4a817a2a825638d347b # Parent c4f36d709ee957a7f7528ce7c6a2196ac3e9b4d8 added rb_copy and rb_clear moved the visualization test to test/vis/ diff -r c4f36d709ee9 -r 56a08d00bb41 Makefile.in --- a/Makefile.in Wed Oct 12 05:01:11 2011 +0300 +++ b/Makefile.in Wed Oct 12 05:25:34 2011 +0300 @@ -11,7 +11,7 @@ ifeq ($(shell uname -s), Darwin) lib_a = $(name).a lib_so = $(name).dylib - shared = -dynamiclib $(lib_so) + shared = -dynamiclib else lib_a = lib$(name).a devlink = lib$(name).so diff -r c4f36d709ee9 -r 56a08d00bb41 src/rbtree.c --- a/src/rbtree.c Wed Oct 12 05:01:11 2011 +0300 +++ b/src/rbtree.c Wed Oct 12 05:25:34 2011 +0300 @@ -90,6 +90,27 @@ rb->del_cls = cls; } + +void rb_clear(struct rbtree *rb) +{ + del_tree(rb->root, rb->del, rb->del_cls); + rb->root = 0; +} + +int rb_copy(struct rbtree *dest, struct rbtree *src) +{ + struct rbnode *node; + + rb_clear(dest); + rb_begin(src); + while((node = rb_next(src))) { + if(rb_insert(dest, node->key, node->data) == -1) { + return -1; + } + } + return 0; +} + int rb_size(struct rbtree *rb) { return count_nodes(rb->root); diff -r c4f36d709ee9 -r 56a08d00bb41 src/rbtree.h --- a/src/rbtree.h Wed Oct 12 05:01:11 2011 +0300 +++ b/src/rbtree.h Wed Oct 12 05:25:34 2011 +0300 @@ -37,6 +37,9 @@ void rb_set_compare_func(struct rbtree *rb, rb_cmp_func_t func); void rb_set_delete_func(struct rbtree *rb, rb_del_func_t func, void *cls); +void rb_clear(struct rbtree *rb); +int rb_copy(struct rbtree *dest, struct rbtree *src); + int rb_size(struct rbtree *rb); int rb_insert(struct rbtree *rb, void *key, void *data); diff -r c4f36d709ee9 -r 56a08d00bb41 test/Makefile --- a/test/Makefile Wed Oct 12 05:01:11 2011 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +0,0 @@ -obj = test.o -bin = test - -font = linux-libertine.ttf - -CC = gcc -CFLAGS = -pedantic -Wall -g -I../src -I/usr/local/include -LDFLAGS = -L.. -L/usr/local/lib $(libgl) -lrbtree -ldrawtext - -ifeq ($(shell uname -s), Darwin) - libgl = -framework OpenGL -framework GLUT -else - libgl = -lGL -lglut -endif - -.PHONY: all -all: $(bin) $(font) - -$(bin): $(obj) - $(CC) -o $@ $(obj) $(LDFLAGS) - -$(font): - wget http://downloads.sourceforge.net/project/linuxlibertine/linuxlibertine/5.1.3-2/LinLibertineTTF_5.1.3_2011_06_21.tgz - mkdir -p linlibertine - cd linlibertine; tar xzvf ../LinLibertineTTF_5.1.3_2011_06_21.tgz - rm -f LinLibertineTTF_5.1.3_2011_06_21.tgz - cp linlibertine/LinLibertine_R.ttf $@ - - -.PHONY: clean -clean: - rm -f $(obj) $(bin) diff -r c4f36d709ee9 -r 56a08d00bb41 test/test.c --- a/test/test.c Wed Oct 12 05:01:11 2011 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,403 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#ifndef __APPLE__ -#include -#else -#include -#endif -#include -#include - -#define FONTSZ 18 - -void init_gl(int argc, char **argv); -float rbvis_width(struct rbnode *tree); -void rbvis_draw(struct rbnode *tree, float x, float y); - -void draw_roundbox(float xsz, float ysz, float rad, int segm, const float *col, float border, const float *bcol); -void draw_fillet(float rad, int segm); - -struct rbtree *tree; -int num_nodes; -struct dtx_font *font; -char input_buffer[64]; -int win_xsz, win_ysz; - -int main(int argc, char **argv) -{ - int i; - - if(argv[1]) { - if(!isdigit(argv[1][0])) { - fprintf(stderr, "pass a fucking number, not: %s\n", argv[1]); - return 1; - } - num_nodes = atoi(argv[1]); - } - - if(!(font = dtx_open_font("linux-libertine.ttf", FONTSZ))) { - fprintf(stderr, "failed to open font\n"); - return 1; - } - - if(!(tree = rb_create(RB_KEY_INT))) { - return 1; - } - - for(i=0; idata) - -void disp(void); -void reshape(int x, int y); -void keyb(unsigned char key, int x, int y); -void draw_rect(float x, float y, float width, float height, const char *text, int red); -void draw_link(float x0, float y0, float x1, float y1, int red); - -void init_gl(int argc, char **argv) -{ - glutInitWindowSize(1280, 720); - glutInit(&argc, argv); - glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_MULTISAMPLE); - - glutCreateWindow("foo"); - - dtx_use_font(font, FONTSZ); - - glutDisplayFunc(disp); - glutReshapeFunc(reshape); - glutKeyboardFunc(keyb); - - glEnable(GL_DEPTH_TEST); - glEnable(GL_MULTISAMPLE); - - glutMainLoop(); -} - -void disp(void) -{ - struct rbnode *root = rb_root(tree); - - glClearColor(0.57, 0.64, 0.59, 1.0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - if(input_buffer[0]) { - char *prompt = "select node: "; - char *buf = alloca(strlen(prompt) + strlen(input_buffer)); - - glPushMatrix(); - glTranslatef(10, 10, -0.9); - glColor3f(0, 0, 0); - sprintf(buf, "%s%s", prompt, input_buffer); - dtx_string(buf); - glPopMatrix(); - } - - if(root) { - rbvis_draw(root, rbvis_width(root->left) + NWIDTH, 550); - } - - glutSwapBuffers(); - assert(glGetError() == GL_NO_ERROR); -} - - -float rbvis_width(struct rbnode *tree) -{ - if(!tree) - return NWIDTH; - - return NWIDTH + rbvis_width(tree->left) + rbvis_width(tree->right) + PADDING * 3.0; -} - -void rbvis_draw(struct rbnode *tree, float x, float y) -{ - float leftx, rightx, nexty; - static const float hxsz = NWIDTH / 2.0; - static const float hysz = NHEIGHT / 2.0; - char text[16]; - - if(!tree) - return; - - leftx = x - (tree->left ? rbvis_width(tree->left->right) + NWIDTH : rbvis_width(tree->left) / 2.0); - rightx = x + (tree->right ? rbvis_width(tree->right->left) + NWIDTH : rbvis_width(tree->right) / 2.0); - - nexty = y - DY; - - sprintf(text, "%d", rb_node_keyi(tree)); - draw_rect(x - hxsz, y - hysz, NWIDTH, NHEIGHT, text, tree->red); - - rbvis_draw(tree->left, leftx, nexty); - rbvis_draw(tree->right, rightx, nexty); - - if(tree->left) - draw_link(x, y, leftx, nexty, tree->left->red); - if(tree->right) - draw_link(x, y, rightx, nexty, tree->right->red); -} - -void draw_rect(float x, float y, float width, float height, const char *text, int red) -{ - float node_col[] = {0.63, 0.71, 0.82, 1.0}; - float bord_col[] = {0, 0, 0, 1}; - - if(red) { - bord_col[0] = 1.0; - } - - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glTranslatef(x + width / 2.0, y + height / 2.0, 0.0); - - draw_roundbox(width, height, 8, 6, node_col, 1.2, bord_col); - - glColor3f(0.15, 0.15, 0.15); - glTranslatef(-dtx_string_width(text) / 2.0, -dtx_string_height(text) / 2.0, 0.1); - dtx_string(text); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); -} - -void draw_link(float x0, float y0, float x1, float y1, int red) -{ - glPushAttrib(GL_LINE_BIT); - if(red) { - glLineWidth(3); - } else { - glLineWidth(2); - } - - glBegin(GL_LINES); - if(red) { - glColor3f(0.8, 0.36, 0.3); - } else { - glColor3f(0, 0, 0); - } - glVertex3f(x0, y0, -0.8); - glVertex3f(x1, y1, -0.8); - glEnd(); - - glPopAttrib(); -} - -void draw_roundbox(float xsz, float ysz, float rad, int segm, const float *col, float border, const float *bcol) -{ - float hin_xsz, hin_ysz; - - if(border > 0.0f) { - glPushMatrix(); - glTranslatef(0, 0, -0.001); - draw_roundbox(xsz + 2 * border, ysz + 2 * border, rad + border, segm, bcol, 0.0, bcol); - glPopMatrix(); - } - - /* half inner size */ - hin_xsz = (xsz - 2.0 * rad) / 2.0; - hin_ysz = (ysz - 2.0 * rad) / 2.0; - - glColor4fv(col); - - glBegin(GL_QUADS); - /* center */ - glVertex2f(-hin_xsz, -hin_ysz); - glVertex2f(hin_xsz, -hin_ysz); - glVertex2f(hin_xsz, hin_ysz); - glVertex2f(-hin_xsz, hin_ysz); - /* right */ - glVertex2f(hin_xsz, -hin_ysz); - glVertex2f(hin_xsz + rad, -hin_ysz); - glVertex2f(hin_xsz + rad, hin_ysz); - glVertex2f(hin_xsz, hin_ysz); - /* top */ - glVertex2f(-hin_xsz, hin_ysz); - glVertex2f(hin_xsz, hin_ysz); - glVertex2f(hin_xsz, hin_ysz + rad); - glVertex2f(-hin_xsz, hin_ysz + rad); - /* left */ - glVertex2f(-hin_xsz - rad, -hin_ysz); - glVertex2f(-hin_xsz, -hin_ysz); - glVertex2f(-hin_xsz, hin_ysz); - glVertex2f(-hin_xsz - rad, hin_ysz); - /* bottom */ - glVertex2f(-hin_xsz, -hin_ysz - rad); - glVertex2f(hin_xsz, -hin_ysz - rad); - glVertex2f(hin_xsz, -hin_ysz); - glVertex2f(-hin_xsz, -hin_ysz); - glEnd(); - - glMatrixMode(GL_MODELVIEW); - - glPushMatrix(); - glTranslatef(hin_xsz, hin_ysz, 0); - draw_fillet(rad, segm); - glPopMatrix(); - - glPushMatrix(); - glTranslatef(-hin_xsz, hin_ysz, 0); - glRotatef(90, 0, 0, 1); - draw_fillet(rad, segm); - glPopMatrix(); - - glPushMatrix(); - glTranslatef(-hin_xsz, -hin_ysz, 0); - glRotatef(180, 0, 0, 1); - draw_fillet(rad, segm); - glPopMatrix(); - - glPushMatrix(); - glTranslatef(hin_xsz, -hin_ysz, 0); - glRotatef(270, 0, 0, 1); - draw_fillet(rad, segm); - glPopMatrix(); -} - -void draw_fillet(float rad, int segm) -{ - int i; - - glBegin(GL_TRIANGLE_FAN); - glVertex2f(0, 0); - for(i=0; i input_buffer) { - *--inp_next = 0; - glutPostRedisplay(); - } - break; - - case '\n': - case '\r': - if(inp_next) { - int x; - char *endp; - - *inp_next = 0; - inp_next = 0; - - if((x = strtol(input_buffer, &endp, 10)), endp == input_buffer) { - fprintf(stderr, "invalid input: %s\n", input_buffer); - } else if(!rb_findi(tree, x)) { - fprintf(stderr, "%d not found in the tree\n", x); - } else { - if(op == 'd') { - printf("deleting: %d\n", x); - rb_deletei(tree, x); - } else { - printf("%d found!\n", x); - } - } - input_buffer[0] = 0; - glutPostRedisplay(); - } - break; - - case 'p': - { - struct rbnode *node; - - rb_begin(tree); - while((node = rb_next(tree))) { - int key = rb_node_keyi(node); - printf("%d ", key); - } - putchar('\n'); - } - break; - } -} - diff -r c4f36d709ee9 -r 56a08d00bb41 test/vis/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/vis/Makefile Wed Oct 12 05:25:34 2011 +0300 @@ -0,0 +1,32 @@ +obj = test.o +bin = test + +font = linux-libertine.ttf + +CC = gcc +CFLAGS = -pedantic -Wall -g -I../src -I/usr/local/include +LDFLAGS = -L.. -L/usr/local/lib $(libgl) -lrbtree -ldrawtext + +ifeq ($(shell uname -s), Darwin) + libgl = -framework OpenGL -framework GLUT +else + libgl = -lGL -lglut +endif + +.PHONY: all +all: $(bin) $(font) + +$(bin): $(obj) + $(CC) -o $@ $(obj) $(LDFLAGS) + +$(font): + wget http://downloads.sourceforge.net/project/linuxlibertine/linuxlibertine/5.1.3-2/LinLibertineTTF_5.1.3_2011_06_21.tgz + mkdir -p linlibertine + cd linlibertine; tar xzvf ../LinLibertineTTF_5.1.3_2011_06_21.tgz + rm -f LinLibertineTTF_5.1.3_2011_06_21.tgz + cp linlibertine/LinLibertine_R.ttf $@ + + +.PHONY: clean +clean: + rm -f $(obj) $(bin) diff -r c4f36d709ee9 -r 56a08d00bb41 test/vis/test.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/vis/test.c Wed Oct 12 05:25:34 2011 +0300 @@ -0,0 +1,403 @@ +#include +#include +#include +#include +#include +#include +#include + +#ifndef __APPLE__ +#include +#else +#include +#endif +#include +#include + +#define FONTSZ 18 + +void init_gl(int argc, char **argv); +float rbvis_width(struct rbnode *tree); +void rbvis_draw(struct rbnode *tree, float x, float y); + +void draw_roundbox(float xsz, float ysz, float rad, int segm, const float *col, float border, const float *bcol); +void draw_fillet(float rad, int segm); + +struct rbtree *tree; +int num_nodes; +struct dtx_font *font; +char input_buffer[64]; +int win_xsz, win_ysz; + +int main(int argc, char **argv) +{ + int i; + + if(argv[1]) { + if(!isdigit(argv[1][0])) { + fprintf(stderr, "pass a fucking number, not: %s\n", argv[1]); + return 1; + } + num_nodes = atoi(argv[1]); + } + + if(!(font = dtx_open_font("linux-libertine.ttf", FONTSZ))) { + fprintf(stderr, "failed to open font\n"); + return 1; + } + + if(!(tree = rb_create(RB_KEY_INT))) { + return 1; + } + + for(i=0; idata) + +void disp(void); +void reshape(int x, int y); +void keyb(unsigned char key, int x, int y); +void draw_rect(float x, float y, float width, float height, const char *text, int red); +void draw_link(float x0, float y0, float x1, float y1, int red); + +void init_gl(int argc, char **argv) +{ + glutInitWindowSize(1280, 720); + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_MULTISAMPLE); + + glutCreateWindow("foo"); + + dtx_use_font(font, FONTSZ); + + glutDisplayFunc(disp); + glutReshapeFunc(reshape); + glutKeyboardFunc(keyb); + + glEnable(GL_DEPTH_TEST); + glEnable(GL_MULTISAMPLE); + + glutMainLoop(); +} + +void disp(void) +{ + struct rbnode *root = rb_root(tree); + + glClearColor(0.57, 0.64, 0.59, 1.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + if(input_buffer[0]) { + char *prompt = "select node: "; + char *buf = alloca(strlen(prompt) + strlen(input_buffer)); + + glPushMatrix(); + glTranslatef(10, 10, -0.9); + glColor3f(0, 0, 0); + sprintf(buf, "%s%s", prompt, input_buffer); + dtx_string(buf); + glPopMatrix(); + } + + if(root) { + rbvis_draw(root, rbvis_width(root->left) + NWIDTH, 550); + } + + glutSwapBuffers(); + assert(glGetError() == GL_NO_ERROR); +} + + +float rbvis_width(struct rbnode *tree) +{ + if(!tree) + return NWIDTH; + + return NWIDTH + rbvis_width(tree->left) + rbvis_width(tree->right) + PADDING * 3.0; +} + +void rbvis_draw(struct rbnode *tree, float x, float y) +{ + float leftx, rightx, nexty; + static const float hxsz = NWIDTH / 2.0; + static const float hysz = NHEIGHT / 2.0; + char text[16]; + + if(!tree) + return; + + leftx = x - (tree->left ? rbvis_width(tree->left->right) + NWIDTH : rbvis_width(tree->left) / 2.0); + rightx = x + (tree->right ? rbvis_width(tree->right->left) + NWIDTH : rbvis_width(tree->right) / 2.0); + + nexty = y - DY; + + sprintf(text, "%d", rb_node_keyi(tree)); + draw_rect(x - hxsz, y - hysz, NWIDTH, NHEIGHT, text, tree->red); + + rbvis_draw(tree->left, leftx, nexty); + rbvis_draw(tree->right, rightx, nexty); + + if(tree->left) + draw_link(x, y, leftx, nexty, tree->left->red); + if(tree->right) + draw_link(x, y, rightx, nexty, tree->right->red); +} + +void draw_rect(float x, float y, float width, float height, const char *text, int red) +{ + float node_col[] = {0.63, 0.71, 0.82, 1.0}; + float bord_col[] = {0, 0, 0, 1}; + + if(red) { + bord_col[0] = 1.0; + } + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glTranslatef(x + width / 2.0, y + height / 2.0, 0.0); + + draw_roundbox(width, height, 8, 6, node_col, 1.2, bord_col); + + glColor3f(0.15, 0.15, 0.15); + glTranslatef(-dtx_string_width(text) / 2.0, -dtx_string_height(text) / 2.0, 0.1); + dtx_string(text); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); +} + +void draw_link(float x0, float y0, float x1, float y1, int red) +{ + glPushAttrib(GL_LINE_BIT); + if(red) { + glLineWidth(3); + } else { + glLineWidth(2); + } + + glBegin(GL_LINES); + if(red) { + glColor3f(0.8, 0.36, 0.3); + } else { + glColor3f(0, 0, 0); + } + glVertex3f(x0, y0, -0.8); + glVertex3f(x1, y1, -0.8); + glEnd(); + + glPopAttrib(); +} + +void draw_roundbox(float xsz, float ysz, float rad, int segm, const float *col, float border, const float *bcol) +{ + float hin_xsz, hin_ysz; + + if(border > 0.0f) { + glPushMatrix(); + glTranslatef(0, 0, -0.001); + draw_roundbox(xsz + 2 * border, ysz + 2 * border, rad + border, segm, bcol, 0.0, bcol); + glPopMatrix(); + } + + /* half inner size */ + hin_xsz = (xsz - 2.0 * rad) / 2.0; + hin_ysz = (ysz - 2.0 * rad) / 2.0; + + glColor4fv(col); + + glBegin(GL_QUADS); + /* center */ + glVertex2f(-hin_xsz, -hin_ysz); + glVertex2f(hin_xsz, -hin_ysz); + glVertex2f(hin_xsz, hin_ysz); + glVertex2f(-hin_xsz, hin_ysz); + /* right */ + glVertex2f(hin_xsz, -hin_ysz); + glVertex2f(hin_xsz + rad, -hin_ysz); + glVertex2f(hin_xsz + rad, hin_ysz); + glVertex2f(hin_xsz, hin_ysz); + /* top */ + glVertex2f(-hin_xsz, hin_ysz); + glVertex2f(hin_xsz, hin_ysz); + glVertex2f(hin_xsz, hin_ysz + rad); + glVertex2f(-hin_xsz, hin_ysz + rad); + /* left */ + glVertex2f(-hin_xsz - rad, -hin_ysz); + glVertex2f(-hin_xsz, -hin_ysz); + glVertex2f(-hin_xsz, hin_ysz); + glVertex2f(-hin_xsz - rad, hin_ysz); + /* bottom */ + glVertex2f(-hin_xsz, -hin_ysz - rad); + glVertex2f(hin_xsz, -hin_ysz - rad); + glVertex2f(hin_xsz, -hin_ysz); + glVertex2f(-hin_xsz, -hin_ysz); + glEnd(); + + glMatrixMode(GL_MODELVIEW); + + glPushMatrix(); + glTranslatef(hin_xsz, hin_ysz, 0); + draw_fillet(rad, segm); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(-hin_xsz, hin_ysz, 0); + glRotatef(90, 0, 0, 1); + draw_fillet(rad, segm); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(-hin_xsz, -hin_ysz, 0); + glRotatef(180, 0, 0, 1); + draw_fillet(rad, segm); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(hin_xsz, -hin_ysz, 0); + glRotatef(270, 0, 0, 1); + draw_fillet(rad, segm); + glPopMatrix(); +} + +void draw_fillet(float rad, int segm) +{ + int i; + + glBegin(GL_TRIANGLE_FAN); + glVertex2f(0, 0); + for(i=0; i input_buffer) { + *--inp_next = 0; + glutPostRedisplay(); + } + break; + + case '\n': + case '\r': + if(inp_next) { + int x; + char *endp; + + *inp_next = 0; + inp_next = 0; + + if((x = strtol(input_buffer, &endp, 10)), endp == input_buffer) { + fprintf(stderr, "invalid input: %s\n", input_buffer); + } else if(!rb_findi(tree, x)) { + fprintf(stderr, "%d not found in the tree\n", x); + } else { + if(op == 'd') { + printf("deleting: %d\n", x); + rb_deletei(tree, x); + } else { + printf("%d found!\n", x); + } + } + input_buffer[0] = 0; + glutPostRedisplay(); + } + break; + + case 'p': + { + struct rbnode *node; + + rb_begin(tree); + while((node = rb_next(tree))) { + int key = rb_node_keyi(node); + printf("%d ", key); + } + putchar('\n'); + } + break; + } +} +