JunkBox_Lib  1.10.2
ttree.c
Go to the documentation of this file.
1 
9 #include "ttree.h"
10 #include "jbxl_state.h"
11 
12 
14 // ノード操作
15 //
16 
24 {
25  tTree* pp;
26 
27  pp = (tList*)malloc(sizeof(tTree));
28  if (pp==NULL) return NULL;
29  memset(pp, 0, sizeof(tTree));
30  pp->ldat = init_tList_data();
31  pp->state = JBXL_NORMAL;
32 
33  return pp;
34 }
35 
36 
38 {
39  tTree* pp;
40 
41  pp = (tList*)malloc(sizeof(tTree));
42  if (pp==NULL) return NULL;
43  memset(pp, 0, sizeof(tTree));
44  pp->ldat = init_tList_data();
45  pp->ldat.id = TREE_ANCHOR_NODE;
46  pp->depth = -1;
47  pp->state = JBXL_STATE_ANCHOR; // TREE_ANCHOR_NODE と同じ
48 
49  return pp;
50 }
51 
52 
54 {
55  tTree* pp = node;
56 
57  if (node!=NULL && node->ldat.id==TREE_ANCHOR_NODE) {
58  pp = node->next;
59  free_tTree_node(node);
60  free(node);
61  }
62 
63  return pp;
64 }
65 
66 
75 {
76  tTree pp;
77 
78  memset(&pp, 0, sizeof(tTree));
79  pp.ldat = data;
80  pp.state = JBXL_NORMAL;
81 
82  return pp;
83 }
84 
85 
98 {
99  if (node==NULL) return NULL;
100  if (pp==NULL) return node;
101 
102  if (node->ldat.id==TREE_ANCHOR_NODE) node = node->next;
103  if (node==NULL) return NULL;
104 
105  node->prev = pp;
106  node->ysis = NULL;
107  node->esis = pp->yngr;
108 
109  if (pp->yngr!=NULL) pp->yngr->ysis = node;
110  if (pp->next==NULL) pp->next = node;
111  pp->yngr = node;
112 
113  node->depth = pp->depth + 1;
114  pp->num++;
115 
116  if (node->next!=NULL) {
117  node->next->depth = node->depth + 1;
118  adjust_tTree_depth(node->next);
119  }
120 
121  return node;
122 }
123 
124 
136 {
137  tTree* pt;
138 
139  pt = new_tTree_node();
140  pt->ldat = ldat;
141  pt->depth = 0;
142 
143  if (pp==NULL) return pt;
144 
145  pt->prev = pp;
146  pt->ysis = NULL;
147  pt->esis = pp->yngr;
148 
149  if (pp->yngr!=NULL) pp->yngr->ysis = pt;
150  if (pp->next==NULL) pp->next = pt;
151  pp->yngr = pt;
152 
153  pt->depth = pp->depth + 1;
154  pp->num++;
155 
156  return pt;
157 }
158 
159 
175 tTree* add_tTree_node_byBuffer(tTree* pp, int id, int lv, Buffer key, Buffer val, void* ptr, int sz)
176 {
177  tTree* pt;
178  tList_data ldat;
179 
180  ldat = make_tList_data(id, lv, key, val, ptr, sz);
181  pt = add_tTree_node_bydata(pp, ldat);
182 
183  return pt;
184 }
185 
186 
202 tTree* add_tTree_node_bystr(tTree* pp, int id, int lv, const char* key, const char* val, void* ptr, int sz)
203 {
204  tTree* pt;
205  tList_data ldat;
206 
207  ldat = make_tList_data_bystr(id, lv, key, val, ptr, sz);
208  pt = add_tTree_node_bydata(pp, ldat);
209 
210  return pt;
211 }
212 
213 
226 {
227  if (node==NULL) return NULL;
228  if (pp==NULL) return node;
229 
230  if (pp->next!=NULL) pp->next->esis = node;
231  node->ysis = pp->next;
232  node->esis = NULL;
233 
234  pp->next = node;
235  node->prev = pp;
236 
237  node->depth = pp->depth + 1;
238  pp->num++;
239 
240  if (node->next!=NULL) {
241  node->next->depth = node->depth + 1;
242  adjust_tTree_depth(node->next);
243  }
244 
245  return node;
246 }
247 
248 
260 {
261  tTree* pt;
262 
263  pt = new_tTree_node();
264  pt->ldat = ldat;
265  pt->depth = 0;
266 
267  if (pp==NULL) return pt;
268  //
269  if (pp->next!=NULL) pp->next->esis = pt;
270  pt->ysis = pp->next;
271  pt->esis = NULL;
272 
273  pp->next = pt;
274  pt->prev = pp;
275 
276  pt->depth = pp->depth + 1;
277  pp->num++;
278 
279  return pt;
280 }
281 
282 
298 tTree* insert_tTree_node_byBuffer(tTree* pp, int id, int lv, Buffer key, Buffer val, void* ptr, int sz)
299 {
300  tTree* pt;
301  tList_data ldat;
302 
303  ldat = make_tList_data(id, lv, key, val, ptr, sz);
304  pt = insert_tTree_node_bydata(pp, ldat);
305 
306  return pt;
307 }
308 
309 
325 tTree* insert_tTree_node_bystr(tTree* pp, int id, int lv, const char* key, const char* val, void* ptr, int sz)
326 {
327  tTree* pt;
328  tList_data ldat;
329 
330  ldat = make_tList_data_bystr(id, lv, key, val, ptr, sz);
331  pt = insert_tTree_node_bydata(pp, ldat);
332 
333  return pt;
334 }
335 
336 
345 {
346  if (node==NULL) return NULL;
347 
348  if (node->next!=NULL) { // 子ノードを持つ場合
349  tTree* ss;
350 
351  if (node->ldat.id!=TREE_ANCHOR_NODE) {
352  node->next->depth--;
353  adjust_tTree_depth(node->next);
354  }
355 
356  ss = node->next;
357  ss->prev = node->prev;
358  while (ss->ysis!=NULL) {
359  ss = ss->ysis;
360  ss->prev = node->prev;
361  }
362 
363  ss->ysis = node->ysis;
364  node->next->esis = node->esis;
365  if (node->ysis!=NULL) node->ysis->esis = ss;
366  if (node->esis!=NULL) node->esis->ysis = node->next;
367 
368  if (node->prev!=NULL) {
369  if (node->prev->next==node) node->prev->next = node->next;
370  if (node->prev->yngr==node) node->prev->yngr = ss;
371  }
372  }
373 
374  else { // 子ノードを持たない場合
375  if (node->prev!=NULL) {
376  if (node->prev->next==node) node->prev->next = node->ysis;
377  if (node->prev->yngr==node) node->prev->yngr = node->esis;
378  }
379  if (node->ysis!=NULL) node->ysis->esis = node->esis;
380  if (node->esis!=NULL) node->esis->ysis = node->ysis;
381  }
382 
383  tTree* pp = node->prev;
384  clear_tList_data(&(node->ldat));
385  if (node->prev!=NULL) node->prev->num += node->num - 1;
386 
387  return pp;
388 }
389 
390 
401 {
402  if (node==NULL || *node==NULL) return NULL;
403 
404  tTree* pp = free_tTree_node(*node);
405  free(*node);
406  *node = NULL;
407 
408  return pp;
409 }
410 
411 
426 {
427  if (node==NULL || pp==NULL) return NULL;
428 
429  // ノードの切り離し
430  if (node->next!=NULL) { // 子ノードを持つ場合
431  tTree* ss;
432  node->next->depth--;
433  adjust_tTree_depth(node->next);
434 
435  ss = node->next;
436  ss->prev = node->prev;
437  while (ss->ysis!=NULL) {
438  ss = ss->ysis;
439  ss->prev = node->prev;
440  }
441 
442  ss->ysis = node->ysis;
443  node->next->esis = node->esis;
444  if (node->ysis!=NULL) node->ysis->esis = ss;
445  if (node->esis!=NULL) node->esis->ysis = node->next;
446 
447  if (node->prev!=NULL) {
448  if (node->prev->next==node) node->prev->next = node->next;
449  if (node->prev->yngr==node) node->prev->yngr = ss;
450  }
451  }
452  else { // 子ノードを持たない場合
453  if (node->prev!=NULL) {
454  if (node->prev->next==node) node->prev->next = node->ysis;
455  if (node->prev->yngr==node) node->prev->yngr = node->esis;
456  }
457  if (node->ysis!=NULL) node->ysis->esis = node->esis;
458  if (node->esis!=NULL) node->esis->ysis = node->ysis;
459  }
460  if (node->prev!=NULL) node->prev->num += node->num - 1;
461 
462  // ノードの再結合(移動)
463  node->prev = pp;
464  node->ysis = NULL;
465  node->esis = pp->yngr;
466 
467  if (pp->yngr!=NULL) pp->yngr->ysis = node;
468  if (pp->next==NULL) pp->next = node;
469  pp->yngr = node;
470 
471  node->depth = pp->depth + 1;
472  pp->num++;
473 
474  if (node->next!=NULL) {
475  node->next->depth = node->depth + 1;
476  adjust_tTree_depth(node->next);
477  }
478 
479  return node;
480 }
481 
482 
499 int replace_all_tTree_node(tTree* tp, char* key, char* src, char* dst, int len)
500 {
501  int nn = 0;
502 
503  do {
504  if (ex_strncmp((char*)(tp->ldat).key.buf, (char*)key, len)) {
505  if (ex_strncmp((char*)(tp->ldat.val.buf), (char*)src, len)) {
506  free_Buffer(&(tp->ldat.val));
507  tp->ldat.val = make_Buffer_bystr(dst);
508  nn++;
509  }
510  }
511 
512  if (tp->next!=NULL) nn += replace_all_tTree_node(tp->next, key, src, dst, len);
513 
514  tp = tp->ysis;
515  } while(tp!=NULL);
516 
517  return nn;
518 }
519 
520 
521 
523 // ツリー操作
524 //
525 
535 {
536  if (pp==NULL || *pp==NULL) return;
537 
538  tTree* tp = *pp;
539  if (tp->ldat.id==TREE_ANCHOR_NODE) {
540  tp = tp->next;
541  }
542  else {
543  PRINT_MESG("JBXL::del_delete_node_tTree: WARNING: top node is not ANCHOR node. top addresses are not guaranteed.\n");
544  }
545 
547  return;
548 }
549 
550 
552 {
553  if (pp==NULL || *pp==NULL) return;
554 
555  tTree* tp = *pp;
556  while(tp->esis!=NULL) tp = tp->esis;
557 
558  while(tp!=NULL) {
559  if (tp->next) _del_delete_node_tTree(&(tp->next));
560  // delete own
561  if (tp->ctrl==TREE_DELETE_NODE || tp->ctrl_alt==TREE_DELETE_NODE) {
562  tTree* tt = tp;
563  del_tTree_node(&tp);
564  tp = tt;
565  }
566  tp = tp->ysis;
567  }
568  return;
569 }
570 
571 
581 {
582  if (pp==NULL || *pp==NULL) return;
583 
584  tTree* tp = *pp;
585  if (tp->ldat.id==TREE_ANCHOR_NODE) {
586  tp = tp->next;
587  }
588  else {
589  PRINT_MESG("JBXL::del_non_keep_node_tTree: WARNING: top node is not ANCHOR node. top addresses are not guaranteed.\n");
590  }
591 
593  return;
594 }
595 
596 
598 {
599  if (pp==NULL || *pp==NULL) return;
600 
601  tTree* tp = *pp;
602  while(tp->esis!=NULL) tp = tp->esis;
603 
604  while(tp!=NULL) {
605  if (tp->next) _del_non_keep_node_tTree(&(tp->next));
606  // delete own
607  if (tp->ctrl!=TREE_KEEP_NODE && tp->ctrl_alt!=TREE_KEEP_NODE) {
608  tTree* tt = tp;
609  del_tTree_node(&tp);
610  tp = tt;
611  }
612  tp = tp->ysis;
613  }
614  return;
615 }
616 
617 
629 {
630  tTree* pt;
631 
632  if (pp==NULL || *pp==NULL) return NULL;
633 
634  // 子ノードの削除
635  if ((*pp)->next!=NULL) del_sisters_children_tTree(&((*pp)->next));
636 
637  // 自分自身の削除
638  pt = (*pp)->prev;
639  if (pt!=NULL) {
640  if (pt->next==*pp) {
641  if ((*pp)->ysis!=NULL) pt->next = (*pp)->ysis;
642  else pt->next = (*pp)->esis;
643  }
644  if (pt->yngr==*pp) pt->yngr = (*pp)->esis;
645  pt->num--;
646  }
647  if ((*pp)->ysis!=NULL) (*pp)->ysis->esis = (*pp)->esis;
648  if ((*pp)->esis!=NULL) (*pp)->esis->ysis = (*pp)->ysis;
649 
650  clear_tList_data(&((*pp)->ldat));
651  free(*pp);
652  *pp = NULL;
653 
654  return pt;
655 }
656 
657 
667 {
668  if (pp==NULL || *pp==NULL) return NULL;
669 
670  if ((*pp)->next!=NULL) del_sisters_children_tTree(&((*pp)->next));
671 
672  (*pp)->num = 0;
673  (*pp)->next = NULL;
674  (*pp)->yngr = NULL;
675 
676  return *pp;
677 }
678 
679 
689 {
690  tTree* pt;
691 
692  if (pp==NULL || *pp==NULL) return NULL;
693 
694  pt = (*pp)->prev;
695  if (pt!=NULL) {
696  pt->next = NULL;
697  pt->yngr = NULL;
698  pt->num = 0;
699  }
700 
702 
703  return pt;
704 }
705 
706 
719 {
720  tTree* pm;
721  tTree* pt;
722 
723  if (pp==NULL || *pp==NULL) return NULL;
724  pt = (*pp)->prev;
725 
726  pm = *pp;
727  while (pm->esis!=NULL) pm = pm->esis;
728  while (pm!=NULL) {
729  tTree* pw = pm;
730  if (pm->next!=NULL) del_sisters_children_tTree(&(pm->next));
731  pm = pm->ysis;
732  clear_tList_data(&(pw->ldat));
733  free(pw);
734  }
735  *pp = NULL;
736 
737  pt->next = NULL;
738  pt->yngr = NULL;
739 
740  return pt;
741 }
742 
743 
753 {
754  tTree* pm;
755 
756  if (pp==NULL || *pp==NULL) return;
757 
758  pm = *pp;
759  while (pm->prev!=NULL) pm = pm->prev;
760  del_tTree(&pm);
761 
762  *pp = NULL;
763  return;
764 }
765 
766 
779 {
780  int nn;
781  tTree* tm;
782  tTree* tw;
783 
784  if (tt==NULL) return NULL;
785  if (tp==NULL) return tt;
786 
787  while(tt->esis!=NULL) tt = tt->esis;
788  tt->esis = tp->yngr;
789  if (tp->yngr!=NULL) tp->yngr->ysis = tt;
790  if (tp->next==NULL) tp->next = tt;
791 
792  nn = 0;
793  tm = tw = tt;
794  while (tm!=NULL) {
795  nn++;
796  tm->prev = tp;
797  tm->depth = tp->depth + 1;
798 
799  if (tm->next!=NULL) {
800  tm->next->depth = tm->depth + 1;
801  adjust_tTree_depth(tm->next);
802  }
803  tw = tm;
804  tm = tm->ysis;
805  }
806 
807  tp->yngr = tw;
808  tp->num += nn;
809 
810  return tt;
811 }
812 
813 
823 {
824  if (tt==NULL) return NULL;
825  if (tt->prev==NULL) return tt;
826 
827  if (tt->prev->next==tt) tt->prev->next = tt->ysis;
828  if (tt->prev->yngr==tt) tt->prev->yngr = tt->esis;
829 
830  if (tt->ysis!=NULL) tt->ysis->esis = tt->esis;
831  if (tt->esis!=NULL) tt->esis->ysis = tt->ysis;
832 
833  tt->depth = 0;
834  if (tt->next!=NULL) {
835  tt->next->depth = 1;
836  adjust_tTree_depth(tt->next);
837  }
838 
839  tt->prev->num--;
840  tt->prev = NULL;
841 
842  return tt;
843 }
844 
845 
859 {
860  if (tp==NULL) return pp;
861 
862  if (pp!=NULL) {
863  if (tp->ctrl!=TREE_NOSIS_NODE) while(tp->esis!=NULL) tp = tp->esis;
864  while(tp!=NULL) {
865  tTree* pt = dup_tList_node(tp);
866  pt->next = pt->prev = pt->yngr = pt->ysis = pt->esis = NULL;
867  add_tTree(pp, pt);
868  if (tp->next!=NULL) dup_merge_tTree(pt, tp->next);
869  if (tp->ctrl!=TREE_NOSIS_NODE) tp = tp->ysis;
870  else tp = NULL;
871  }
872  }
873  else {
874  pp = new_tTree_anchor_node();
875  dup_merge_tTree(pp, tp);
876  pp = del_tTree_anchor_node(pp);
877  }
878 
879  return pp;
880 }
881 
882 
917 void merge_tTree(tTree* tp, tTree* tt)
918 {
919  tTree* tl;
920  tTree* nt;
921  tTree* nl;
922  int depth;
923 
924  if (tp==NULL || tt==NULL) return;
925 
926  depth = tp->depth;
927  tl = tp;
928  while (tt!=NULL) {
929  if ((tt->ldat).key.buf==NULL) return;
930  if (tl!=NULL && (tl->ldat).key.buf==NULL) return;
931  while (tl!=NULL && strcmp((char*)((tl->ldat).key.buf), (char*)((tt->ldat).key.buf))) tl = tl->ysis;
932 
933  nt = tt;
934  nl = tl;
935  tt = tt->ysis;
936 
937  if (tl==NULL) {
938  div_tTree(nt);
939  add_tTree(tp->prev, nt);
940  tl = nt;
941  return;
942  }
943  else if (nl->next!=NULL && nt->next!=NULL) {
944  merge_tTree(nl->next, nt->next);
945  tl = tl->ysis;
946  }
947  else {
948  tl = tl->ysis;
949  exchange_tTree(nl, nt);
950  }
951  }
952 
953  tp->depth = depth;
954  adjust_tTree_depth(tp);
955 
956  return;
957 }
958 
959 
968 void exchange_tTree(tTree* tl, tTree* tt)
969 {
970  int dt = tt->depth;
971  tTree* pt = tt->prev;
972  tTree* yt = tt->ysis;
973  tTree* et = tt->esis;
974 
975  if (tl->esis!=NULL) tl->esis->ysis = tt;
976  if (tl->ysis!=NULL) tl->ysis->esis = tt;
977  if (tl->prev!=NULL) {
978  if (tl->prev->next==tl) tl->prev->next = tt;
979  if (tl->prev->yngr==tl) tl->prev->yngr = tt;
980  }
981 
982  tt->ysis = tl->ysis;
983  tt->esis = tl->esis;
984  tt->prev = tl->prev;
985  tt->depth = tl->depth;
986  if (tt->next!=NULL) {
987  tt->next->depth = tt->depth + 1;
988  adjust_tTree_depth(tt->next);
989  }
990 
991  if (et!=NULL) et->ysis = tl;
992  if (yt!=NULL) yt->esis = tl;
993  if (pt!=NULL) {
994  if (pt->next==tt) pt->next = tl;
995  if (pt->yngr==tt) pt->yngr = tl;
996  }
997 
998  tl->ysis = yt;
999  tl->esis = et;
1000  tl->prev = pt;
1001  tl->depth = dt;
1002  if (tl->next!=NULL) {
1003  tl->next->depth = dt + 1;
1004  adjust_tTree_depth(tl->next);
1005  }
1006 }
1007 
1008 
1017 {
1018  int depth;
1019  tTree* pt;
1020 
1021  if (pp==NULL) return;
1022 
1023  depth = pp->depth;
1024  pt = pp;
1025  while (pt->ysis!=NULL) {
1026  pt = pt->ysis;
1027  pt->depth = depth;
1028  if (pt->next!=NULL) {
1029  pt->next->depth = depth + 1;
1030  adjust_tTree_depth(pt->next);
1031  }
1032  }
1033 
1034  pt = pp;
1035  while (pt->esis!=NULL) {
1036  pt = pt->esis;
1037  pt->depth = depth;
1038  if (pt->next!=NULL) {
1039  pt->next->depth = depth + 1;
1040  adjust_tTree_depth(pt->next);
1041  }
1042  }
1043 
1044  if (pp->next!=NULL) {
1045  pp->next->depth = depth + 1;
1046  adjust_tTree_depth(pp->next);
1047  }
1048 
1049  return;
1050 }
1051 
1052 
1063 void print_tTree_tree(FILE* fp, tTree* pp, const char* space)
1064 {
1065  if (fp==NULL) fp = stderr;
1066 
1067  if (pp!=NULL) {
1068  if (pp->ctrl!=TREE_NOSIS_NODE) while(pp->esis!=NULL) pp = pp->esis;
1069  do {
1070  int i;
1071  tList_data ld = pp->ldat;
1072 
1073  if (pp->depth>=1) {
1074  for(i=1; i<pp->depth; i++) fprintf(fp, "%s", space);
1075  fprintf(fp, " -> ");
1076  }
1077  fprintf(fp, "%d: %d %d %s %s\n", pp->depth, ld.id, ld.lv, ld.key.buf, ld.val.buf);
1078  if (pp->next!=NULL) print_tTree_tree(fp, pp->next, space);
1079 
1080  if (pp->ctrl!=TREE_NOSIS_NODE) pp = pp->ysis;
1081  else pp = NULL;
1082  } while(pp!=NULL);
1083  }
1084  else {
1085  fprintf(fp, "(Tree is NULL)\n");
1086  }
1087  fflush(fp);
1088 
1089  return;
1090 }
1091 
1092 
1102 void print_tTree(FILE* fp, tTree* pp)
1103 {
1104  if (fp==NULL) fp = stderr;
1105 
1106  if (pp!=NULL) {
1107  if (pp->ctrl!=TREE_NOSIS_NODE) while(pp->esis!=NULL) pp = pp->esis;
1108  do {
1109  tList_data ld = pp->ldat;
1110  //
1111  fprintf(fp, "[%d]: [%d] [%d] [%s] [%s]\n", pp->depth, ld.id, ld.lv, ld.key.buf, ld.val.buf);
1112  if (pp->next!=NULL) print_tTree(fp, pp->next);
1113 
1114  if (pp->ctrl!=TREE_NOSIS_NODE) pp = pp->ysis;
1115  else pp = NULL;
1116  } while(pp!=NULL);
1117  }
1118  else {
1119  fprintf(fp, "(Tree is NULL)\n");
1120  }
1121  fflush(fp);
1122 
1123  return;
1124 }
1125 
1126 
1133 {
1134  if (pp==NULL) return NULL;
1135 
1136  while(pp->prev!=NULL) pp = pp->prev; // Top を探す
1137  while(pp->yngr!=NULL) pp = pp->yngr;
1138 
1139  return pp;
1140 }
1141 
1142 
1152 {
1153  int cnt = 0;
1154 
1155  if (pp==NULL) return 0;
1156  while(pp->esis!=NULL) pp = pp->esis;
1157 
1158  do {
1159  cnt++;
1160  if (pp->next!=NULL) cnt += count_tTree(pp->next);
1161  pp = pp->ysis;
1162  } while(pp!=NULL);
1163 
1164  return cnt;
1165 }
1166 
1167 
1168 
1170 // Pattern Matching
1171 //
1172 
1190 tTree* strncmp_tTree(tTree* pp, const char* key, int len, int no)
1191 {
1192  tTree* pt = NULL;
1193  int nn = 0;
1194 
1195  if (pp==NULL) return NULL;
1196  if (len<=-3) return NULL;
1197  if (no<=0) no = 1;
1198 
1199  if (ex_strncmp((char*)(pp->ldat).key.buf, key, len)) {
1200  nn++;
1201  if (no==nn) return pp;
1202  }
1203  if (pp->next!=NULL) pt = _next_strncmp_vertical_tTree(pp->next, key, len, no, &nn);
1204 
1205  return pt;
1206 }
1207 
1208 
1226 tTree* strncasecmp_tTree(tTree* pp, const char* key, int len, int no)
1227 {
1228  tTree* pt = NULL;
1229  int nn = 0;
1230 
1231  if (pp==NULL) return NULL;
1232  if (len<=-3) return NULL;
1233  if (no<=0) no = 1;
1234 
1235  if (ex_strncasecmp((char*)(pp->ldat).key.buf, key, len)) {
1236  nn++;
1237  if (no==nn) return pp;
1238  }
1239  if (pp->next!=NULL) pt = _next_strncasecmp_vertical_tTree(pp->next, key, len, no, &nn);
1240 
1241  return pt;
1242 }
1243 
1244 
1275 {
1276  tTree* ta;
1277  tTree* tb = NULL;
1278  tTree* ts;
1279 
1280  ts = tp;
1281  while (ts!=NULL){
1282  ta = ts;
1283  tb = tr;
1284  while (ta!=NULL && tb!=NULL) {
1285  if (ta->ctrl==TREE_ALREADY_FOUND_NODE) break;
1286  if (tb->ctrl!=TREE_NOCMP_NODE && tb->ctrl!=TREE_NOCMP_COPY_NODE) {
1287  if ((ta->ldat).key.buf!=NULL && (tb->ldat).key.buf!=NULL) {
1288  if (strcmp((char*)((ta->ldat).key.buf), (char*)((tb->ldat).key.buf))) break;
1289  }
1290  else break;
1291  }
1292  tb->altp = ta;
1293  ta = ta->ysis;
1294  tb = tb->ysis;
1295  }
1296 
1297  if (tb==NULL) return ts;
1298 
1299  ts = ts->ysis;
1300  }
1301  if (tb!=NULL) return NULL;
1302 
1303  return ts;
1304 }
1305 
1306 
1326 {
1327  int ret;
1328  tTree* te;
1329  tTree* ts;
1330 
1331  tTree* tt;
1332  tTree* ta;
1333  tTree* tb;
1334 
1335  if (tp==NULL || tr==NULL) return FALSE;
1336 
1337  te = find_tList_end(tr);
1338 
1339  ts = tp;
1340  while (ts!=NULL) {
1341  tt = cmp_sisters_tTree(ts, tr); // その階層でキー値が全て一致しているか確認
1342  if (tt==NULL) return FALSE; // 一致していなければ,FALSE
1343 
1344  ta = tt; // 比べられるツリー
1345  tb = tr; // 比べるパターン
1346  ret = TRUE;
1347  while (tb!=NULL && ret) {
1348  if (tb->next==NULL) ret = TRUE;
1349  // ->ta, ->tb->tx: FALSE
1350  else if (tb->next!=NULL && ta->next==NULL) ret = FALSE;
1351  // ->ta->xa, ->tb->xb: xaとxbをチェック
1352  else ret = check_match_tTree(ta->next, tb->next);
1353 
1354  ta = ta->ysis;
1355  tb = tb->ysis;
1356  }
1357 
1358  if (ret) {
1359  if (tr==te) tt->ctrl = TREE_ALREADY_FOUND_NODE;
1360  return TRUE;
1361  }
1362 
1363  ts = tt->ysis;
1364  }
1365 
1366  return FALSE;
1367 }
1368 
1369 
1391 {
1392  int ret;
1393  tTree* pm;
1394 
1395  pm = pp;
1396  while(pp!=NULL) {
1397  ret = check_match_tTree(pp, pt);
1398  if (ret) return TRUE;
1399 
1400  if (pp->next!=NULL) {
1401  ret = find_match_tTree(pp->next, pt);
1402  if (ret) {
1403  _clear_tTree_ctrl(pm);
1404  return TRUE;
1405  }
1406  }
1407  pp = pp->ysis;
1408  }
1409 
1410  return FALSE;
1411 }
1412 
1413 
1421 {
1422  while (pp->esis!=NULL) pp = pp->esis;
1423 
1424  while (pp!=NULL) {
1425  pp->ctrl = TREE_NOCTRL_NODE;
1426  if (pp->next!=NULL) _clear_tTree_ctrl(pp->next);
1427  pp = pp->ysis;
1428  }
1429 }
1430 
1431 
1447 {
1448  tTree* te;
1449  tList* lp;
1450 
1451  te = find_tTree_end(pt);
1452  while(pp->esis!=NULL) pp = pp->esis;
1453 
1454  lp = _find_match_tTree_endlist_rcsv(pp, pt, te);
1455  if (lp!=NULL) _clear_tTree_ctrl(pp);
1456 
1457  return lp;
1458 }
1459 
1460 
1467 {
1468  tList* lt = NULL;
1469  tList* lp = NULL;
1470 
1471  while(pp!=NULL) {
1472  int ret = check_match_tTree(pp, pt);
1473  if (ret && te->altp!=NULL) {
1474  tList* lm = new_tList_node();
1475  lm->altp = te->altp;
1476  lt = insert_tList(lt, lm);
1477  if (lp==NULL) lp = lt;
1478  te->altp = NULL;
1479  }
1480 
1481  if (pp->next!=NULL) {
1482  tList* lm = _find_match_tTree_endlist_rcsv(pp->next, pt, te);
1483  if (lm!=NULL) {
1484  lt = insert_tList(lt, lm);
1485  if (lp==NULL) lp = lt;
1486  _clear_tTree_ctrl(pp->next);
1487  }
1488  }
1489 
1490  if (!ret) pp = pp->ysis; // 見つかった場合はもう一度.見つからなかった場合へ次へ.
1491  }
1492 
1493  return lp;
1494 }
1495 
1496 
1516 {
1517  int ret;
1518 
1519  if (pp==NULL || pt==NULL) return FALSE;
1520  while(pp->esis!=NULL) pp = pp->esis;
1521 
1522  ret = find_match_tTree(pp, pt);
1523  if (ret) {
1524  _copy_tTree_byctrl(pt);
1525  adjust_tTree_depth(pp);
1526  }
1527 
1528  return ret;
1529 }
1530 
1531 
1542 {
1543  while(pt!=NULL) {
1544  if (pt->altp!=NULL) {
1545  if (pt->ctrl==TREE_COPY_NODE || pt->ctrl==TREE_NOCMP_COPY_NODE) {
1546  pt->altp->ldat.id = pt->ldat.id;
1547  pt->altp->ldat.lv = pt->ldat.lv;
1548  pt->altp->ldat.sz = pt->ldat.sz;
1549 
1550  if (pt->ldat.key.buf!=NULL) {
1551  free_Buffer(&(pt->altp->ldat.key));
1552  pt->altp->ldat.key = dup_Buffer(pt->ldat.key);
1553  }
1554  if (pt->ldat.val.buf!=NULL) {
1555  free_Buffer(&(pt->altp->ldat.val));
1556  pt->altp->ldat.val = dup_Buffer(pt->ldat.val);
1557  }
1558 
1559  if (pt->ldat.ptr!=NULL && pt->ldat.sz>0) {
1560  if (pt->altp->ldat.ptr!=NULL) free(pt->altp->ldat.ptr);
1561  pt->altp->ldat.ptr = (void*)malloc(pt->ldat.sz);
1562  if (pt->altp->ldat.ptr!=NULL) memcpy(pt->altp->ldat.ptr, pt->ldat.ptr, pt->ldat.sz);
1563  }
1564 
1565  if (pt->ldat.lst!=NULL) {
1566  del_all_tList(&(pt->altp->ldat.lst));
1567  pt->altp->ldat.lst = dup_tList(pt->ldat.lst);
1568  }
1569  }
1570  }
1571 
1572  if (pt->next!=NULL) _copy_tTree_byctrl(pt->next);
1573  pt = pt->ysis;
1574  }
1575 
1576  return;
1577 }
1578 
1579 
1601 {
1602  int fnd;
1603  Buffer val;
1604 
1605  val = init_Buffer();
1606  if (pp==NULL || pt==NULL) return val;
1607 
1608  while(pp->esis!=NULL) pp = pp->esis;
1609 
1610  fnd = find_match_tTree(pp, pt);
1611  if (fnd) {
1612  tTree* tt = find_tTree_end(pt);
1613  if (tt->altp!=NULL) {
1614  val = dup_Buffer(tt->altp->ldat.val);
1615  }
1616  }
1617 
1618  return val;
1619 }
1620 
1621 
1622 
1624 //
1625 
1631 tTree* _next_strncmp_vertical_tTree(tTree* pp, const char* key, int len, int no, int* nn)
1632 {
1633  do {
1634  if (ex_strncmp((char*)(pp->ldat).key.buf, key, len)) {
1635  (*nn)++;
1636  if (no==*nn) return pp;
1637  }
1638  if (pp->next!=NULL) {
1639  tTree* tt = _next_strncmp_vertical_tTree(pp->next, key, len, no, nn);
1640  if (tt!=NULL) return tt;
1641  }
1642  pp = pp->ysis;
1643  } while(pp!=NULL);
1644 
1645  return NULL;
1646 }
1647 
1648 
1654 tTree* _next_strncmp_horizon_tTree(tTree* pp, const char* key, int len, int no, int* nn)
1655 {
1656  do {
1657  if (ex_strncmp((char*)(pp->ldat).key.buf, key, len)) {
1658  (*nn)++;
1659  if (no==*nn) return pp;
1660  }
1661  if (pp->ysis!=NULL) {
1662  tTree* tt = _next_strncmp_horizon_tTree(pp->ysis, key, len, no, nn);
1663  if (tt!=NULL) return tt;
1664  }
1665  pp = pp->next;
1666  } while(pp!=NULL);
1667 
1668  return NULL;
1669 }
1670 
1671 
1677 tTree* _next_strncasecmp_vertical_tTree(tTree* pp, const char* key, int len, int no, int* nn)
1678 {
1679  do {
1680  if (ex_strncasecmp((char*)(pp->ldat).key.buf, key, len)) {
1681  (*nn)++;
1682  if (no==*nn) return pp;
1683  }
1684  if (pp->next!=NULL) {
1685  tTree* tt = _next_strncasecmp_vertical_tTree(pp->next, key, len, no, nn);
1686  if (tt!=NULL) return tt;
1687  }
1688  pp = pp->ysis;
1689  } while(pp!=NULL);
1690 
1691  return NULL;
1692 }
1693 
1694 
1700 tTree* _next_strncasecmp_horizon_tTree(tTree* pp, const char* key, int len, int no, int* nn)
1701 {
1702  do {
1703  if (ex_strncasecmp((char*)(pp->ldat).key.buf, key, len)) {
1704  (*nn)++;
1705  if (no==*nn) return pp;
1706  }
1707  if (pp->ysis!=NULL) {
1708  tTree* tt = _next_strncasecmp_horizon_tTree(pp->ysis, key, len, no, nn);
1709  if (tt!=NULL) return tt;
1710  }
1711  pp = pp->next;
1712  } while(pp!=NULL);
1713 
1714  return NULL;
1715 }
1716 
void free_Buffer(Buffer *buf)
Buffer型変数のバッファ部を解放する
Definition: buffer.c:128
Buffer init_Buffer()
初期化したBuffer型変数を返す.
Definition: buffer.c:47
Buffer dup_Buffer(Buffer buf)
Buffer型変数のコピーをつくる.
Definition: buffer.c:211
#define make_Buffer_bystr(str)
set_Buffer()
Definition: buffer.h:57
#define TRUE
Definition: common.h:226
#define FALSE
Definition: common.h:223
JunkBox_Lib 状態ヘッダ
#define JBXL_STATE_ANCHOR
アンカーノード
Definition: jbxl_state.h:30
#define JBXL_NORMAL
正常
Definition: jbxl_state.h:32
unsigned char unsigned long * len
Definition: jpeg_tool.h:96
Definition: buffer.h:35
tList * find_tList_end(tList *pl)
リストの最後のノードを探す.
Definition: tlist.c:1023
tList_data make_tList_data_bystr(int id, int lv, const char *key, const char *val, void *ptr, int sz)
文字列データを指定してノードデータを作成
Definition: tlist.c:89
tList * dup_tList(tList *pp)
リストを複製する.
Definition: tlist.c:843
tList_data make_tList_data(int id, int lv, Buffer key, Buffer val, void *ptr, int sz)
データを指定してノードデータを作成
Definition: tlist.c:50
tList * new_tList_node(void)
リスト用の空ノードを動的に生成する.
Definition: tlist.c:198
void del_all_tList(tList **pp)
リストの全ノードの削除.ポインタ ppのノードを含むリスト全体を削除する.
Definition: tlist.c:769
tList * dup_tList_node(tList *node)
ノードデータを複製する (new).ノードのポインタは複製しない.
Definition: tlist.c:287
void clear_tList_data(tList_data *ldat)
ノードデータのバッファ部をクリアする.データ自身は削除しない.
Definition: tlist.c:120
tList * insert_tList(tList *pp, tList *pt)
ノードppの直ぐ後ろに ptを挿入する.
Definition: tlist.c:903
tList_data init_tList_data(void)
空のノードデータを静的に作成.データを初期化するのに使用する.
Definition: tlist.c:26
int ex_strncmp(const char *dat, const char *key, int len)
文字列 s1とs2を拡張比較する.一致するなら TRUE
Definition: tools.c:784
int ex_strncasecmp(const char *dat, const char *key, int len)
文字列 s1とs2を拡張比較する.大文字小文字を区別しない.一致するなら TRUE
Definition: tools.c:820
#define PRINT_MESG
環境依存用の出力関数.print_message()
Definition: tools.h:475
tTree * insert_tTree_node_byBuffer(tTree *pp, int id, int lv, Buffer key, Buffer val, void *ptr, int sz)
ノードを長子としてリストに追加.
Definition: ttree.c:298
tTree * strncmp_tTree(tTree *pp, const char *key, int len, int no)
ツリーノードのキー値のサーチ
Definition: ttree.c:1190
tList * _find_match_tTree_endlist_rcsv(tTree *pp, tTree *pt, tTree *te)
find_match_tTree_endlist() の補助関数
Definition: ttree.c:1466
void del_delete_node_tTree(tTree **pp)
ctrl==TREE_DELETE_NODE を削除する.
Definition: ttree.c:534
tTree * new_tTree_node(void)
ツリー用の空ノードを動的に生成.
Definition: ttree.c:23
tTree * find_tTree_end(tTree *pp)
ツリーの最終ノードを見つける.
Definition: ttree.c:1132
tTree * del_sisters_tTree(tTree **pp)
指定したノード以下のXMLツリー(ppの姉妹を含む)を削除する.
Definition: ttree.c:688
tTree * strncasecmp_tTree(tTree *pp, const char *key, int len, int no)
ツリーノードのキー値のサーチ.大文字小文字を無視する.
Definition: ttree.c:1226
Buffer get_value_tTree(tTree *pp, tTree *pt)
同じパターンの枝を検索し,一致した枝があれば,その枝の最後のノードの値を返す.
Definition: ttree.c:1600
void exchange_tTree(tTree *tl, tTree *tt)
ツリー tlと ツリー ttを交換する.
Definition: ttree.c:968
tTree * add_tTree_node_bydata(tTree *pp, tList_data ldat)
データから Treeノードをつくり出し,それを ppの子ノード(末っ子)として追加.
Definition: ttree.c:135
tTree * _next_strncasecmp_vertical_tTree(tTree *pp, const char *key, int len, int no, int *nn)
tTree 検索用補助関数.vertical は縦方向探索
Definition: ttree.c:1677
void adjust_tTree_depth(tTree *pp)
指定したノード ppを基準にして,木の深さを測り直す
Definition: ttree.c:1016
tTree * _next_strncmp_vertical_tTree(tTree *pp, const char *key, int len, int no, int *nn)
tTree 検索用補助関数.vertical は縦方向探索
Definition: ttree.c:1631
tTree * add_tTree_node(tTree *pp, tTree *node)
ツリー ppへノード nodeを末っ子として追加.
Definition: ttree.c:97
void print_tTree(FILE *fp, tTree *pp)
ツリーの表示.ポインタ ノードのキー部のバッファをfpに表示する.
Definition: ttree.c:1102
tTree * del_sisters_children_tTree(tTree **pp)
指定したノードの姉妹ツリー,子ツリーを削除する.
Definition: ttree.c:718
tTree * del_tTree_anchor_node(tTree *node)
ANCHORノードを削除して,TOP(長女)へのポインターを返す.
Definition: ttree.c:53
tList * find_match_tTree_endlist(tTree *pp, tTree *pt)
pp内で ptと同じパターンの枝を全て探して,その枝の最後のノードへの情報を返す.
Definition: ttree.c:1446
tTree * del_tTree(tTree **pp)
指定したノード以下のツリーを削除する.
Definition: ttree.c:628
void del_all_tTree(tTree **pp)
ツリーの全ノードの削除.ポインタ ppのノードを含むツリー全体を削除する.
Definition: ttree.c:752
void del_non_keep_node_tTree(tTree **pp)
ctrl==TREE_KEEP_NODE 以外を削除する.
Definition: ttree.c:580
tTree * div_tTree(tTree *tt)
ツリー tp から ツリー ttを分離する.
Definition: ttree.c:822
int replace_tTree_node(tTree *pp, tTree *pt)
同じパターンの枝を検索し,ptのノードの属性で置き換える.
Definition: ttree.c:1515
int count_tTree(tTree *pp)
ツリーの ppノード以降のノードの数を数える.
Definition: ttree.c:1151
tTree * _next_strncmp_horizon_tTree(tTree *pp, const char *key, int len, int no, int *nn)
tTree 検索用補助関数.horizon は擬似的な横方向探索
Definition: ttree.c:1654
tTree * _next_strncasecmp_horizon_tTree(tTree *pp, const char *key, int len, int no, int *nn)
tTree 検索用補助関数.horizon は擬似的な横方向探索
Definition: ttree.c:1700
int replace_all_tTree_node(tTree *tp, char *key, char *src, char *dst, int len)
対象の全てのノードのノード値を dst に書き換える.
Definition: ttree.c:499
int check_match_tTree(tTree *tp, tTree *tr)
tpが trと同じパターン(キー値)を持っているかどうかを検査する.
Definition: ttree.c:1325
void _del_delete_node_tTree(tTree **pp)
Definition: ttree.c:551
tTree * move_tTree_node(tTree *pp, tTree *node)
nodeを現在のツリーから切り離し,ppへ移動する.
Definition: ttree.c:425
tTree * insert_tTree_node_bydata(tTree *pp, tList_data ldat)
ノードをつくり出し,それを ppの子ノード(長子)として追加.
Definition: ttree.c:259
tTree * new_tTree_anchor_node(void)
ツリー用の ANCHORノードを動的に生成.
Definition: ttree.c:37
void _clear_tTree_ctrl(tTree *pp)
ppツリーの ctrlをクリアする.
Definition: ttree.c:1420
tTree * free_tTree_node(tTree *node)
ツリーノードの解放.解放されたノードが子ノードを持つ場合は,その子ノードを格上げする(木構造を詰める)
Definition: ttree.c:344
void merge_tTree(tTree *tp, tTree *tt)
ツリー tp にツリー tt を結合する.結合後,tt の内容は壊れる(tpとノードを交換した形になる).
Definition: ttree.c:917
tTree * insert_tTree_node_bystr(tTree *pp, int id, int lv, const char *key, const char *val, void *ptr, int sz)
ノードを長子としてリストに追加.
Definition: ttree.c:325
void _del_non_keep_node_tTree(tTree **pp)
Definition: ttree.c:597
tTree * del_tTree_node(tTree **node)
ツリーノードの削除.削除されたノードが子ノードを持つ場合は,その子ノードを格上げする(木構造を詰める)
Definition: ttree.c:400
void print_tTree_tree(FILE *fp, tTree *pp, const char *space)
ツリーの表示.ポインタ ノードのキー部のバッファをfpに表示する.
Definition: ttree.c:1063
tTree * add_tTree(tTree *tp, tTree *tt)
ツリー tpへ ツリー ttを追加.
Definition: ttree.c:778
tTree make_tTree_node(tList_data data)
ツリー用ノードを静的に作成.
Definition: ttree.c:74
tTree * add_tTree_node_byBuffer(tTree *pp, int id, int lv, Buffer key, Buffer val, void *ptr, int sz)
ノードを末っ子としてリストに追加.
Definition: ttree.c:175
tTree * insert_tTree_node(tTree *pp, tTree *node)
ツリー ppへノード nodeを長子として追加.
Definition: ttree.c:225
tTree * cmp_sisters_tTree(tTree *tp, tTree *tr)
tpの姉妹ノードが trの姉妹ノードと同じキー値を持っているかどうかを検査する.
Definition: ttree.c:1274
tTree * dup_merge_tTree(tTree *pp, tTree *tp)
ツリー ppの直下にツリー tpを複製する.
Definition: ttree.c:858
void _copy_tTree_byctrl(tTree *pt)
同じパターンの枝を検索し,ptのノードの属性をコピーする.
Definition: ttree.c:1541
tTree * del_children_tTree(tTree **pp)
指定したノードの子ツリーを削除する.指定したノードは削除しない.
Definition: ttree.c:666
int find_match_tTree(tTree *pp, tTree *pt)
ツリー pp内で ツリー ptと同じパターンの枝を探す.
Definition: ttree.c:1390
tTree * add_tTree_node_bystr(tTree *pp, int id, int lv, const char *key, const char *val, void *ptr, int sz)
ノードを末っ子としてリストに追加.
Definition: ttree.c:202
Tiny Tree Graph 構造ライブラリヘッダ
#define TREE_ANCHOR_NODE
ldat.ctrl リスト制御用
Definition: ttree.h:51
#define TREE_NOSIS_NODE
このノードの姉妹ノードは処理しない.一部の関数のみ有効.
Definition: ttree.h:56
#define TREE_NOCMP_NODE
比較対照から外すノード.通常は無条件で一致させる.
Definition: ttree.h:53
#define TREE_NOCMP_COPY_NODE
比較対照から外し,最後にコピー処理を行うノード.通常は無条件で一致させる.
Definition: ttree.h:54
#define TREE_ALREADY_FOUND_NODE
検索などにおいて既に見つけたノード.見つけたことを確定したノード.
Definition: ttree.h:59
#define TREE_COPY_NODE
後でコピー処理を行うノード.copy_tTree_byctrl()など.
Definition: ttree.h:55
#define TREE_DELETE_NODE
後で削除処理を行うノード.
Definition: ttree.h:57
#define TREE_KEEP_NODE
削除などの処理対象から外すノードに設定.
Definition: ttree.h:58
#define TREE_NOCTRL_NODE
何の制御(制限)も受けていないノード.デフォルト.
Definition: ttree.h:52