00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include <stdio.h>
00040 #include <stdlib.h>
00041 #include <ctype.h>
00042 #include <string.h>
00043 #include <sys/time.h>
00044 #include <sys/types.h>
00045 #include <sys/socket.h>
00046 #include <netinet/in.h>
00047 #include <arpa/inet.h>
00048 #include <fcntl.h>
00049 #include <sys/ioctl.h>
00050 #include <errno.h>
00051 #include <netdb.h>
00052 #ifdef _AIX
00053 #include <sys/select.h>
00054 #endif
00055
00056 #include "utils.h"
00057
00058
00059
00060
00061
00062
00063 const char *
00064 dumb_strcasestr(const char *string, const char *substr)
00065 {
00066 int str_len, substr_len, cmplen, i;
00067 const char *ptr;
00068
00069 str_len = strlen(string);
00070 substr_len = strlen(substr);
00071 cmplen = str_len - substr_len + 1;
00072
00073 for (ptr = string, i=0; i<cmplen; i++, ptr++) {
00074 if (strncasecmp(ptr, substr, substr_len) == 0)
00075 return ptr;
00076 }
00077 return NULL;
00078 }
00079
00080
00081
00082
00083
00084 void dump_buf(FILE *std, char *buf, int retlen)
00085 {
00086 int i, j;
00087
00088 for (i=0; i<retlen/5; i++) {
00089 for (j=0; j<5; j++) {
00090 fprintf(std, "%.02x ", *(buf + (unsigned) 5*i + j));
00091 }
00092 fprintf(std, " ");
00093 for (j=0; j<5; j++) {
00094 fprintf(std, "%c ", *(buf + (unsigned) 5*i + j));
00095 }
00096 fprintf(std, "\n");
00097 }
00098 if (retlen % 5 != 0) {
00099 for (j=0; j < retlen % 5; j++) {
00100 fprintf(std, "%.02x ", *(buf + (unsigned) 5*(retlen/5) + j));
00101 }
00102 fprintf(std, " ");
00103 for (j=0; j<5; j++) {
00104 fprintf(std, "%c ", *(buf + (unsigned) 5*i + j));
00105 }
00106 fprintf(std, "\n");
00107 }
00108 }
00109
00110
00111
00112
00113
00114 tv_time tv_timeadd(tv_time t1, tv_time t2)
00115 {
00116 tv_time ret;
00117
00118 ret.tv_sec = t1.tv_sec + t2.tv_sec;
00119 ret.tv_usec = t1.tv_usec + t2.tv_usec;
00120 if (ret.tv_usec > 1000000L) {
00121 ret.tv_sec += 1;
00122 ret.tv_usec -= 1000000L;
00123 }
00124 return ret;
00125 }
00126
00127 tv_time tv_timesub(tv_time t1, tv_time t2)
00128 {
00129 tv_time ret;
00130
00131 if (t2.tv_usec > t1.tv_usec) {
00132 t1.tv_usec += 1000000;
00133 t2.tv_sec += 1;
00134 }
00135 ret.tv_sec = t1.tv_sec - t2.tv_sec;
00136 ret.tv_usec = t1.tv_usec - t2.tv_usec;
00137 return ret;
00138 }
00139
00140 tv_time tv_timemul(tv_time t1, double mult)
00141 {
00142 tv_time ret;
00143 double rsec;
00144 double rusec;
00145
00146 rsec = mult * ((double) t1.tv_sec);
00147 rusec = mult * ((double) t1.tv_usec);
00148
00149 ret.tv_sec = (long)rsec;
00150 ret.tv_usec = (long)rusec;
00151
00152 ret.tv_usec += (long)((double) 1000000.0 * (rsec - (double) ret.tv_sec));
00153 while (ret.tv_usec > 1000000) {
00154 ret.tv_usec -= 1000000;
00155 ret.tv_sec += 1;
00156 }
00157 return ret;
00158 }
00159
00160 int tv_timecmp(tv_time t1, tv_time t2)
00161 {
00162 if (t1.tv_sec > t2.tv_sec)
00163 return 1;
00164 if (t1.tv_sec < t2.tv_sec)
00165 return -1;
00166 if (t1.tv_usec > t2.tv_usec)
00167 return 1;
00168 if (t1.tv_usec < t2.tv_usec)
00169 return -1;
00170 return 0;
00171 }
00172
00173 ts_time ts_timeadd(ts_time t1, ts_time t2)
00174 {
00175 ts_time ret;
00176
00177 ret.tv_sec = t1.tv_sec + t2.tv_sec;
00178 ret.tv_nsec = t1.tv_nsec + t2.tv_nsec;
00179 if (ret.tv_nsec > 1000000000L) {
00180 ret.tv_sec += 1;
00181 ret.tv_nsec -= 1000000000L;
00182 }
00183 return ret;
00184 }
00185 ts_time ts_timesub(ts_time t1, ts_time t2)
00186 {
00187 ts_time ret;
00188
00189 if (t2.tv_nsec > t1.tv_nsec) {
00190 t1.tv_nsec += 1000000000;
00191 t2.tv_sec += 1;
00192 }
00193 ret.tv_sec = t1.tv_sec - t2.tv_sec;
00194 ret.tv_nsec = t1.tv_nsec - t2.tv_nsec;
00195 return ret;
00196 }
00197
00198 ts_time ts_timemul(ts_time t1, double mult)
00199 {
00200 ts_time ret;
00201 double rsec;
00202 double rnsec;
00203
00204 rsec = mult * ((double) t1.tv_sec);
00205 rnsec = mult * ((double) t1.tv_nsec);
00206
00207 ret.tv_sec = (long)rsec;
00208 ret.tv_nsec = (long)rnsec;
00209
00210 ret.tv_nsec += (long)((double) 1000000000.0 * (rsec - (double) ret.tv_sec));
00211 while (ret.tv_nsec > 1000000000) {
00212 ret.tv_nsec -= 1000000000;
00213 ret.tv_sec += 1;
00214 }
00215 return ret;
00216 }
00217
00218 int ts_timecmp(ts_time t1, ts_time t2)
00219 {
00220 if (t1.tv_sec > t2.tv_sec)
00221 return 1;
00222 if (t1.tv_sec < t2.tv_sec)
00223 return -1;
00224 if (t1.tv_nsec > t2.tv_nsec)
00225 return 1;
00226 if (t1.tv_nsec < t2.tv_nsec)
00227 return -1;
00228 return 0;
00229 }
00230
00231
00232
00233
00234
00235 ts_strtok_state *ts_strtok_init(char *string)
00236 {
00237 ts_strtok_state *retval;
00238
00239 if (string == NULL)
00240 return NULL;
00241
00242 retval = (ts_strtok_state *) malloc(sizeof(ts_strtok_state));
00243 if (retval == NULL)
00244 return NULL;
00245
00246 retval->string_dupe = strdup(string);
00247 if (retval->string_dupe == NULL) {
00248 free(retval);
00249 return NULL;
00250 }
00251 retval->nxt_ptr = retval->string_dupe;
00252 retval->chars_remaining = strlen(retval->string_dupe);
00253
00254 return retval;
00255 }
00256
00257 char *ts_strtok(char *matching, ts_strtok_state *state)
00258 {
00259 int len1, len2;
00260 char *tmpo;
00261
00262 if ((matching == NULL) || (state == NULL) || (state->chars_remaining <= 0))
00263 return NULL;
00264
00265 len1 = strspn(state->nxt_ptr, matching);
00266 if (len1 > state->chars_remaining) {
00267 return NULL;
00268 }
00269
00270 tmpo = state->nxt_ptr + (unsigned) len1;
00271 len2 = strcspn(tmpo, matching);
00272 if (len2+len1 > state->chars_remaining) {
00273 return NULL;
00274 }
00275 *(tmpo+len2) = '\0';
00276 state->nxt_ptr = tmpo + len2 + 1;
00277 state->chars_remaining -= len1+len2+1;
00278 return tmpo;
00279 }
00280
00281 int ts_strtok_finish(ts_strtok_state *state)
00282 {
00283 if (state) {
00284 if (state->string_dupe)
00285 free(state->string_dupe);
00286 free(state);
00287 }
00288 return 1;
00289 }
00290
00291
00292 char *dumb_strnstr(char *str, char *substr, int n)
00293 {
00294 int i, substrlen, ml;
00295 char *tmp;
00296
00297 substrlen = strlen(substr);
00298
00299 for (i=0,tmp=str; i<=n-substrlen; i++, tmp++) {
00300 if (*tmp == '\0')
00301 return NULL;
00302 if ( (ml = memcmp(tmp, substr, substrlen)) == 0)
00303 return tmp;
00304 }
00305 return NULL;
00306 }
00307
00308
00309
00310 int correct_write(int s, char *data, int len)
00311 {
00312 int sofar, ret;
00313 char *tmp;
00314
00315 if (len == -1)
00316 len = strlen(data);
00317
00318 sofar = 0;
00319 while (sofar != len) {
00320 tmp = data + (unsigned long) sofar;
00321 ret = write(s, tmp, len-sofar);
00322 if (ret <= 0) {
00323 if (! ((ret == -1) && ((errno == EAGAIN) || (errno == EINTR))) )
00324
00325 return ret;
00326 } else
00327 sofar += ret;
00328 }
00329 return len;
00330 }
00331
00332 int correct_read(int s, char *data, int len)
00333 {
00334 int sofar, ret;
00335 char *tmp;
00336
00337 sofar = 0;
00338 while(sofar != len) {
00339 tmp = data + (unsigned long) sofar;
00340 ret = read(s, tmp, len-sofar);
00341 if (ret <= 0) {
00342 if (! ((ret == -1) && ((errno == EAGAIN) || (errno == EINTR))) )
00343
00344 return ret;
00345 } else
00346 sofar += ret;
00347 }
00348 return len;
00349 }
00350
00351
00352
00353 #define LL_HEAPSIZE 50
00354 static ll heap_o_ll = NULL;
00355
00356
00357 ll Allocate_ll(void);
00358 void Free_ll(ll freeMe);
00359
00360 int ll_add_to_end(ll *addToMe, void *data)
00361 {
00362 ll temp;
00363
00364 temp = *addToMe;
00365 if (temp == NULL)
00366 {
00367 *addToMe = temp = Allocate_ll();
00368 temp->data = data;
00369 temp->prev = temp->next = NULL;
00370 return 1;
00371 }
00372
00373 while (temp->next != NULL)
00374 temp = temp->next;
00375
00376 temp->next = Allocate_ll();
00377 (temp->next)->prev = temp;
00378 (temp->next)->next = NULL;
00379 (temp->next)->data = data;
00380 return 1;
00381 }
00382
00383 int ll_add_to_start(ll *addToMe, void *data)
00384 {
00385 ll temp;
00386
00387 temp = *addToMe;
00388 if (temp == NULL)
00389 {
00390 *addToMe = temp = Allocate_ll();
00391 temp->data = data;
00392 temp->prev = temp->next = NULL;
00393 return 1;
00394 }
00395
00396 temp->prev = Allocate_ll();
00397 (temp->prev)->next = temp;
00398 (temp->prev)->prev = NULL;
00399 (temp->prev)->data = data;
00400 *addToMe = temp->prev;
00401
00402 return 1;
00403
00404 }
00405
00406 ll ll_find(ll *findInMe, void *data, int (*compare)(void *d1, void *d2))
00407 {
00408 ll temp = *findInMe;
00409
00410 while (temp != NULL)
00411 {
00412 if (compare(data, temp->data) == 0)
00413 return temp;
00414
00415 temp = temp->next;
00416 }
00417 return temp;
00418 }
00419
00420 int ll_sorted_insert(ll *insertme, void *data,
00421 int (*compare)(void *d1, void *d2))
00422 {
00423 ll temp = *insertme, addEl;
00424
00425 while (temp != NULL) {
00426 if (compare(data, temp->data) <= 0) {
00427
00428 addEl = Allocate_ll();
00429 addEl->data = data;
00430 addEl->prev = temp->prev;
00431 addEl->next = temp;
00432 temp->prev = addEl;
00433 if (addEl->prev == NULL)
00434 *insertme = addEl;
00435 else
00436 (addEl->prev)->next = addEl;
00437 return 1;
00438 }
00439 temp = temp->next;
00440 }
00441
00442
00443 return ll_add_to_end(insertme, data);
00444 }
00445
00446 int ll_del(ll *delFromMe, void *data, int (*compare)(void *d1, void *d2),
00447 void (*nukeElement)(void *nukeMe))
00448 {
00449 ll temp = *delFromMe;
00450
00451 while (temp != NULL)
00452 {
00453 if (compare(data, temp->data) == 0)
00454 {
00455 if (temp->prev != NULL)
00456 (temp->prev)->next = temp->next;
00457
00458 if (temp->next != NULL)
00459 (temp->next)->prev = temp->prev;
00460
00461 if (temp == *delFromMe)
00462 *delFromMe = temp->next;
00463
00464 if (nukeElement != NULL)
00465 nukeElement(temp->data);
00466 Free_ll(temp);
00467 return 1;
00468 }
00469 temp = temp->next;
00470 }
00471 return 0;
00472 }
00473
00474 int ll_delfirst(ll *delFromMe, void (*nukeElement)(void *nukeMe))
00475 {
00476 ll temp = *delFromMe;
00477
00478 if (temp == NULL)
00479 return 0;
00480
00481 if (temp->prev != NULL)
00482 (temp->prev)->next = temp->next;
00483
00484 if (temp->next != NULL)
00485 (temp->next)->prev = temp->prev;
00486
00487 if (temp == *delFromMe)
00488 *delFromMe = temp->next;
00489
00490 if (nukeElement != NULL)
00491 nukeElement(temp->data);
00492 Free_ll(temp);
00493 return 1;
00494 }
00495
00496 int ll_destroy(ll *destroyMe, void (*nukeElement)(void *nukeMe))
00497 {
00498 ll temp = *destroyMe, next;
00499
00500 while (temp != NULL)
00501 {
00502 next = temp->next;
00503 if (nukeElement != NULL)
00504 nukeElement(temp->data);
00505 Free_ll(temp);
00506 temp = next;
00507 }
00508 *destroyMe = NULL;
00509 return 1;
00510 }
00511
00512 ll Allocate_ll(void)
00513 {
00514 int counter;
00515 ll temp_pointer;
00516
00517
00518 if (heap_o_ll == NULL)
00519 {
00520 heap_o_ll = (ll_node *) malloc(LL_HEAPSIZE * sizeof(ll_node));
00521 if (heap_o_ll == NULL)
00522 {
00523 fprintf(stderr, "Out of memory in Allocate_ll!\n");
00524 exit(1);
00525 }
00526 for (counter=0; counter < LL_HEAPSIZE - 1; counter++)
00527 {
00528 (heap_o_ll + counter)->data = NULL;
00529 (heap_o_ll + counter)->prev = NULL;
00530 (heap_o_ll + counter)->next = (heap_o_ll + counter + 1);
00531 }
00532 (heap_o_ll + LL_HEAPSIZE - 1)->next = NULL;
00533 }
00534
00535
00536 temp_pointer = heap_o_ll;
00537 heap_o_ll = heap_o_ll->next;
00538 temp_pointer->next = NULL;
00539 return temp_pointer;
00540 }
00541
00542 void Free_ll(ll freeMe)
00543 {
00544 freeMe->next = heap_o_ll;
00545 heap_o_ll = freeMe;
00546 }
00547
00548
00549 int ll_build(ll *buildMe, char *buildFromMe)
00550 {
00551
00552
00553
00554
00555 char *end, *start, *data, *temp;
00556
00557 data = (char *) malloc(sizeof(char) * (strlen(buildFromMe)+1));
00558 if (data == NULL)
00559 {
00560 fprintf(stderr, "Out of memory in ll_build!\n");
00561 return 0;
00562 }
00563 strcpy(data, buildFromMe);
00564 start = end = data + 1;
00565
00566 while ((*end != ']') && (*end != '\0'))
00567 {
00568 while (*start == ' ')
00569 {
00570 start++; end++;
00571 }
00572
00573 if (*end == ',')
00574 {
00575 *end = '\0';
00576 temp = (char *) (malloc(sizeof(char) * (strlen(start)+1)));
00577 if (temp == NULL)
00578 {
00579 fprintf(stderr, "Out of memory in ll_build!\n");
00580 return 0;
00581 }
00582 strcpy(temp, start);
00583 ll_add_to_end(buildMe, (void *) temp);
00584 start = end + 1;
00585 }
00586 end++;
00587 }
00588 *end = '\0';
00589 temp = (char *) (malloc(sizeof(char) * (strlen(start)+1)));
00590 if (temp == NULL)
00591 {
00592 fprintf(stderr, "Out of memory in ll_build!\n");
00593 return 0;
00594 }
00595 strcpy(temp, start);
00596 ll_add_to_end(buildMe, (void *) temp);
00597 free(data);
00598 return 1;
00599 }
00600
00601
00602
00603 int chained_hash_create(int num_slots, hash_table *rt)
00604 {
00605 hash_table retval;
00606 hash_el *sArray;
00607 int i;
00608
00609
00610
00611
00612 sArray = retval.slot_array = (hash_el *) malloc(num_slots*sizeof(hash_el));
00613 if (retval.slot_array == NULL)
00614 return -1;
00615
00616 retval.num_elements = num_slots;
00617 *rt = retval;
00618
00619
00620 for (i=0; i<num_slots; i++)
00621 sArray[i] = NULL;
00622
00623 return 0;
00624 }
00625
00626 int chained_hash_destroy(hash_table ht, deletor d)
00627 {
00628 int i, numEl;
00629 hash_el *sArray;
00630
00631
00632
00633
00634 for (i=0, numEl=ht.num_elements, sArray=ht.slot_array; i<numEl; i++)
00635 {
00636 if (sArray[i] != NULL)
00637 {
00638
00639 ll_destroy(&(sArray[i]), d);
00640 sArray[i] = NULL;
00641 }
00642 }
00643 free(sArray);
00644 return 0;
00645 }
00646
00647 int chained_hash_insert(hash_table ht, void *element, hash_function f)
00648 {
00649 int slotnum;
00650 ll *slotList;
00651
00652 slotnum = f(element, ht.num_elements);
00653 if (! ((slotnum >= 0) && (slotnum < ht.num_elements)) )
00654 return -1;
00655
00656 slotList = &(ht.slot_array[slotnum]);
00657 if (ll_add_to_start(slotList, element) != 1)
00658 return -1;
00659
00660 return 0;
00661 }
00662
00663 void *chained_hash_search(hash_table ht, void *element, hash_function f,
00664 sc_comparator c)
00665 {
00666 ll *slotList, foundEl;
00667 int slotnum;
00668
00669 #ifdef DEBUG
00670 printf("chained_hash_search: about to f element, numelements %d\n", ht.num_elements);
00671 #endif
00672
00673 slotnum = f(element, ht.num_elements);
00674
00675 #ifdef DEBUG
00676 printf("f() returned slotnum %d\n", slotnum);
00677 #endif
00678
00679 if (! ((slotnum >= 0) && (slotnum < ht.num_elements)) )
00680 return NULL;
00681
00682 #ifdef DEBUG
00683 printf("in chs: slotnum %d\n", slotnum);
00684 #endif
00685 slotList = &(ht.slot_array[slotnum]);
00686 if (slotList == NULL)
00687 return NULL;
00688
00689 #ifdef DEBUG
00690 printf("about to ll_find on slotList.\n");
00691 #endif
00692 foundEl = ll_find(slotList, element, c);
00693 if (foundEl == NULL)
00694 return NULL;
00695 return foundEl->data;
00696 }
00697
00698 int chained_hash_delete(hash_table ht, void *element, hash_function f,
00699 deletor d, sc_comparator c)
00700 {
00701 ll *slotList;
00702 int slotnum;
00703
00704 slotnum = f(element, ht.num_elements);
00705 if (! ((slotnum >= 0) && (slotnum < ht.num_elements)) )
00706 return 0;
00707
00708 slotList = &(ht.slot_array[slotnum]);
00709 if (slotList == NULL)
00710 return 0;
00711
00712 return ll_del(slotList, element, c, d);
00713 }
00714
00715
00716
00717
00718
00719
00720 #define AVL_ALLOC_NUM 200
00721
00722
00723
00724
00725 AVL_tree Allocate_AVL_tree(void);
00726 void Free_AVL_tree(AVL_tree freeMe);
00727
00728
00729
00730 int Tree_Add(AVL_tree *addToMe, void *addMe, AVL_comparator theComp)
00731 {
00732 static int checkBalance = FALSE;
00733 static AVL_tree parent = NULL;
00734 AVL_tree *addTree = addToMe;
00735
00736 if (*addTree == NULL)
00737 {
00738 *addTree = Allocate_AVL_tree();
00739 (*addTree)->data = addMe;
00740 (*addTree)->bal = 0;
00741 (*addTree)->left = (*addTree)->right = NULL;
00742 (*addTree)->parent = parent;
00743 checkBalance = TRUE;
00744 parent = NULL;
00745 return 0;
00746 }
00747 else
00748 if ( theComp( (*addTree)->data, addMe) > 0 )
00749 {
00750 parent = *addTree;
00751 if ( Tree_Add(&((*addTree)->left), addMe, theComp) != 0 )
00752 { checkBalance = FALSE; return -1; }
00753 if (checkBalance == TRUE)
00754
00755 {
00756 switch( (*addTree)->bal) {
00757 case 1 : (*addTree)->bal = 0;
00758 checkBalance = FALSE; return 0;
00759 case 0 : (*addTree)->bal = -1;
00760 checkBalance = TRUE; return 0;
00761 case -1:
00762 { AVL_tree p = (*addTree)->left;
00763 switch (p->bal) {
00764 case -1: {
00765 AVL_tree q = *addTree;
00766 AVL_tree r = p->right;
00767 p->parent = q->parent;
00768 p->right = q;
00769 q->parent = p; q->left = r;
00770 if (r != NULL)
00771 r->parent = q;
00772 *addTree = p; (*addTree)->bal = 0;
00773 q->bal = 0; checkBalance = FALSE;
00774 return 0; }
00775 case 1: {
00776 AVL_tree m = *addTree;
00777 AVL_tree q = p->right;
00778 AVL_tree s = q->left;
00779 AVL_tree u = q->right;
00780 q->parent = m->parent;
00781 m->parent = q;
00782 p->parent = q;
00783 if (s != NULL)
00784 s->parent = p;
00785 if (u != NULL)
00786 u->parent = m;
00787 p->right = s; q->left = p;
00788 q->right = m; m->left = u;
00789 *addTree = q;
00790 if (q->bal == 0)
00791 {
00792 q->bal = 0;
00793 p->bal = 0;
00794 m->bal = 0;
00795 }
00796 else if (q->bal == -1)
00797 {
00798 q->bal = 0;
00799 p->bal = 0;
00800 m->bal = 1;
00801
00802 }
00803 else if (q->bal == 1)
00804 {
00805 q->bal = 0;
00806 p->bal = -1;
00807 m->bal = 0;
00808 }
00809 checkBalance = FALSE; return 0; }
00810 default: exit(1);
00811 } } }
00812 }
00813 else
00814 { checkBalance = FALSE; return 0; }
00815 }
00816 else
00817 if ( theComp( (*addTree)->data, addMe) < 0 )
00818 {
00819 parent = *addTree;
00820 if ( Tree_Add(&((*addTree)->right), addMe, theComp) != 0 )
00821 { checkBalance = FALSE; return -1; }
00822 if (checkBalance == TRUE)
00823 {
00824 switch ( (*addTree)->bal) {
00825 case -1: (*addTree)->bal = 0;
00826 checkBalance = FALSE; return 0;
00827 case 0 : (*addTree)->bal = 1;
00828 checkBalance = TRUE; return 0;
00829 case 1 :
00830 { AVL_tree p = (*addTree)->right;
00831 switch (p->bal) {
00832 case -1: {
00833 AVL_tree m = *addTree;
00834 AVL_tree q = p->left;
00835 AVL_tree r = q->right;
00836 AVL_tree s = q->left;
00837 q->parent = m->parent;
00838 m->parent = q;
00839 p->parent = q;
00840 if (s != NULL)
00841 s->parent = m;
00842 if (r != NULL)
00843 r->parent = p;
00844 m->right = s; q->left = m;
00845 q->right = p; p->left = r;
00846 (*addTree) = q;
00847 if (q->bal == 0)
00848 {
00849 q->bal = 0;
00850 p->bal = 0;
00851 m->bal = 0;
00852 }
00853 else if (q->bal == -1)
00854 {
00855 q->bal = 0;
00856 p->bal = 1;
00857 m->bal = 0;
00858
00859 }
00860 else if (q->bal == 1)
00861 {
00862 q->bal = 0;
00863 p->bal = 0;
00864 m->bal = -1;
00865 }
00866 checkBalance = FALSE;
00867 return 0; }
00868 case 1: {
00869 AVL_tree q = (*addTree);
00870 AVL_tree r = p->left;
00871 p->parent = q->parent;
00872 q->parent = p;
00873 if (r != NULL)
00874 r->parent = q;
00875 p->left = q; q->right = r;
00876 (*addTree) = p; (*addTree)->bal = 0;
00877 q->bal = 0; checkBalance = FALSE;
00878 return 0; }
00879 }
00880 }
00881 }
00882 }
00883 else
00884 { checkBalance = FALSE; return 0; }
00885 }
00886 else
00887 { checkBalance = FALSE; return -1; }
00888
00889 return 0;
00890 }
00891
00892 int Tree_Delete(AVL_tree *deleteFromMe, void *deleteMe,
00893 AVL_comparator theComp, AVL_deletor theDel)
00894 {
00895
00896
00897
00898 AVL_tree tempTree, tempTreeX, Z;
00899 static AVL_tree *root = NULL;
00900
00901 Z = *deleteFromMe;
00902
00903 if (*deleteFromMe == NULL)
00904 { root = NULL;
00905 return -1;
00906 }
00907
00908 if (root == NULL)
00909 root = deleteFromMe;
00910
00911 if ( theComp((*deleteFromMe)->data, deleteMe) > 0 )
00912 return Tree_Delete(&((*deleteFromMe)->left), deleteMe, theComp, theDel);
00913 else
00914 {
00915 if ( theComp((*deleteFromMe)->data, deleteMe) < 0)
00916 return Tree_Delete(&((*deleteFromMe)->right), deleteMe, theComp, theDel);
00917 else
00918 {
00919 theDel((*deleteFromMe)->data);
00920
00921
00922 if ( (((*deleteFromMe)->left) == NULL) ||
00923 (((*deleteFromMe)->right) == NULL) )
00924 tempTree = *deleteFromMe;
00925 else
00926 tempTree = Tree_Next(*deleteFromMe);
00927
00928 if ( tempTree->left != NULL)
00929 tempTreeX = tempTree->left;
00930 else
00931 tempTreeX = tempTree->right;
00932
00933 if (tempTreeX != NULL)
00934 tempTreeX->parent = tempTree->parent;
00935
00936 if (tempTree->parent == NULL)
00937 *root = tempTreeX;
00938 else
00939 {
00940 if ( tempTree == ((tempTree->parent)->left) )
00941 ((tempTree->parent)->left) = tempTreeX;
00942 else
00943 ((tempTree->parent)->right) = tempTreeX;
00944 }
00945
00946 if (tempTree != Z)
00947 {
00948
00949 (*deleteFromMe)->data = tempTree->data;
00950 }
00951
00952 Free_AVL_tree(tempTree);
00953 root = NULL;
00954 return 0;
00955
00956 }
00957 }
00958 }
00959
00960 int Tree_Destroy(AVL_tree *destroyMe, AVL_deletor theDel)
00961 {
00962 if (*destroyMe == NULL)
00963 return 0;
00964
00965 Tree_Destroy( &((*destroyMe)->left), theDel);
00966 Tree_Destroy( &((*destroyMe)->right), theDel);
00967
00968 theDel( (*destroyMe)->data );
00969 Free_AVL_tree(*destroyMe);
00970 *destroyMe = NULL;
00971 return 0;
00972 }
00973
00974 AVL_tree Tree_Search(AVL_tree searchMe, void *searchForMe, AVL_comparator theComp)
00975 {
00976 if (searchMe == NULL)
00977 return NULL;
00978
00979 if (theComp(searchMe->data, searchForMe) > 0 )
00980 return Tree_Search(searchMe->left, searchForMe, theComp);
00981
00982 if (theComp(searchMe->data, searchForMe) < 0 )
00983 return Tree_Search(searchMe->right, searchForMe, theComp);
00984
00985
00986 return searchMe;
00987 }
00988
00989 AVL_tree Tree_First(AVL_tree searchMe)
00990 {
00991 AVL_tree retTree = searchMe;
00992
00993 if (retTree == NULL)
00994 return NULL;
00995
00996 while (retTree->left != NULL)
00997 retTree = retTree->left;
00998
00999 return retTree;
01000 }
01001
01002 AVL_tree Tree_Last(AVL_tree searchMe)
01003 {
01004 AVL_tree retTree = searchMe;
01005
01006 if (retTree == NULL)
01007 return NULL;
01008
01009 while (retTree->right != NULL)
01010 retTree = retTree->right;
01011
01012 return retTree;
01013 }
01014
01015 AVL_tree Tree_Next(AVL_tree searchMe)
01016 {
01017 AVL_tree tempTree;
01018
01019 if ((searchMe->right) != NULL)
01020 {
01021 tempTree = searchMe->right;
01022 while ((tempTree->left) != NULL)
01023 tempTree = tempTree->left;
01024 return tempTree;
01025 }
01026
01027
01028 tempTree = searchMe->parent;
01029 while ( (tempTree != NULL) && (searchMe == tempTree->right) )
01030 {
01031 searchMe = tempTree;
01032 tempTree = tempTree->parent;
01033 }
01034 return tempTree;
01035 }
01036
01037
01038
01039
01040
01041
01042 AVL_tree Allocate_AVL_tree(void)
01043 {
01044 AVL_tree temp_pointer;
01045
01046 temp_pointer = (AVL_tree) malloc(sizeof(AVL_tree_element));
01047 if (temp_pointer == NULL) {
01048 fprintf(stderr, "Out of memory in Allocate_AVL_tree!\n");
01049 exit(-1);
01050 }
01051 return temp_pointer;
01052 }
01053
01054 void Free_AVL_tree(AVL_tree freeMe)
01055 {
01056
01057 if (freeMe == NULL)
01058 return;
01059
01060 free(freeMe);
01061 }