00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "postgres.h"
00017
00018
00019 #define PG_LIST_INCLUDE_DEFINITIONS
00020
00021 #include "nodes/pg_list.h"
00022
00023
00024
00025
00026
00027
00028 #define IsPointerList(l) ((l) == NIL || IsA((l), List))
00029 #define IsIntegerList(l) ((l) == NIL || IsA((l), IntList))
00030 #define IsOidList(l) ((l) == NIL || IsA((l), OidList))
00031
00032 #ifdef USE_ASSERT_CHECKING
00033
00034
00035
00036 static void
00037 check_list_invariants(const List *list)
00038 {
00039 if (list == NIL)
00040 return;
00041
00042 Assert(list->length > 0);
00043 Assert(list->head != NULL);
00044 Assert(list->tail != NULL);
00045
00046 Assert(list->type == T_List ||
00047 list->type == T_IntList ||
00048 list->type == T_OidList);
00049
00050 if (list->length == 1)
00051 Assert(list->head == list->tail);
00052 if (list->length == 2)
00053 Assert(list->head->next == list->tail);
00054 Assert(list->tail->next == NULL);
00055 }
00056 #else
00057 #define check_list_invariants(l)
00058 #endif
00059
00060
00061
00062
00063
00064
00065 static List *
00066 new_list(NodeTag type)
00067 {
00068 List *new_list;
00069 ListCell *new_head;
00070
00071 new_head = (ListCell *) palloc(sizeof(*new_head));
00072 new_head->next = NULL;
00073
00074
00075 new_list = (List *) palloc(sizeof(*new_list));
00076 new_list->type = type;
00077 new_list->length = 1;
00078 new_list->head = new_head;
00079 new_list->tail = new_head;
00080
00081 return new_list;
00082 }
00083
00084
00085
00086
00087
00088
00089
00090
00091 static void
00092 new_head_cell(List *list)
00093 {
00094 ListCell *new_head;
00095
00096 new_head = (ListCell *) palloc(sizeof(*new_head));
00097 new_head->next = list->head;
00098
00099 list->head = new_head;
00100 list->length++;
00101 }
00102
00103
00104
00105
00106
00107
00108
00109
00110 static void
00111 new_tail_cell(List *list)
00112 {
00113 ListCell *new_tail;
00114
00115 new_tail = (ListCell *) palloc(sizeof(*new_tail));
00116 new_tail->next = NULL;
00117
00118 list->tail->next = new_tail;
00119 list->tail = new_tail;
00120 list->length++;
00121 }
00122
00123
00124
00125
00126
00127
00128
00129
00130 List *
00131 lappend(List *list, void *datum)
00132 {
00133 Assert(IsPointerList(list));
00134
00135 if (list == NIL)
00136 list = new_list(T_List);
00137 else
00138 new_tail_cell(list);
00139
00140 lfirst(list->tail) = datum;
00141 check_list_invariants(list);
00142 return list;
00143 }
00144
00145
00146
00147
00148 List *
00149 lappend_int(List *list, int datum)
00150 {
00151 Assert(IsIntegerList(list));
00152
00153 if (list == NIL)
00154 list = new_list(T_IntList);
00155 else
00156 new_tail_cell(list);
00157
00158 lfirst_int(list->tail) = datum;
00159 check_list_invariants(list);
00160 return list;
00161 }
00162
00163
00164
00165
00166 List *
00167 lappend_oid(List *list, Oid datum)
00168 {
00169 Assert(IsOidList(list));
00170
00171 if (list == NIL)
00172 list = new_list(T_OidList);
00173 else
00174 new_tail_cell(list);
00175
00176 lfirst_oid(list->tail) = datum;
00177 check_list_invariants(list);
00178 return list;
00179 }
00180
00181
00182
00183
00184
00185
00186
00187 static ListCell *
00188 add_new_cell(List *list, ListCell *prev_cell)
00189 {
00190 ListCell *new_cell;
00191
00192 new_cell = (ListCell *) palloc(sizeof(*new_cell));
00193
00194 new_cell->next = prev_cell->next;
00195 prev_cell->next = new_cell;
00196
00197 if (list->tail == prev_cell)
00198 list->tail = new_cell;
00199
00200 list->length++;
00201
00202 return new_cell;
00203 }
00204
00205
00206
00207
00208
00209
00210
00211 ListCell *
00212 lappend_cell(List *list, ListCell *prev, void *datum)
00213 {
00214 ListCell *new_cell;
00215
00216 Assert(IsPointerList(list));
00217
00218 new_cell = add_new_cell(list, prev);
00219 lfirst(new_cell) = datum;
00220 check_list_invariants(list);
00221 return new_cell;
00222 }
00223
00224 ListCell *
00225 lappend_cell_int(List *list, ListCell *prev, int datum)
00226 {
00227 ListCell *new_cell;
00228
00229 Assert(IsIntegerList(list));
00230
00231 new_cell = add_new_cell(list, prev);
00232 lfirst_int(new_cell) = datum;
00233 check_list_invariants(list);
00234 return new_cell;
00235 }
00236
00237 ListCell *
00238 lappend_cell_oid(List *list, ListCell *prev, Oid datum)
00239 {
00240 ListCell *new_cell;
00241
00242 Assert(IsOidList(list));
00243
00244 new_cell = add_new_cell(list, prev);
00245 lfirst_oid(new_cell) = datum;
00246 check_list_invariants(list);
00247 return new_cell;
00248 }
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261 List *
00262 lcons(void *datum, List *list)
00263 {
00264 Assert(IsPointerList(list));
00265
00266 if (list == NIL)
00267 list = new_list(T_List);
00268 else
00269 new_head_cell(list);
00270
00271 lfirst(list->head) = datum;
00272 check_list_invariants(list);
00273 return list;
00274 }
00275
00276
00277
00278
00279 List *
00280 lcons_int(int datum, List *list)
00281 {
00282 Assert(IsIntegerList(list));
00283
00284 if (list == NIL)
00285 list = new_list(T_IntList);
00286 else
00287 new_head_cell(list);
00288
00289 lfirst_int(list->head) = datum;
00290 check_list_invariants(list);
00291 return list;
00292 }
00293
00294
00295
00296
00297 List *
00298 lcons_oid(Oid datum, List *list)
00299 {
00300 Assert(IsOidList(list));
00301
00302 if (list == NIL)
00303 list = new_list(T_OidList);
00304 else
00305 new_head_cell(list);
00306
00307 lfirst_oid(list->head) = datum;
00308 check_list_invariants(list);
00309 return list;
00310 }
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323 List *
00324 list_concat(List *list1, List *list2)
00325 {
00326 if (list1 == NIL)
00327 return list2;
00328 if (list2 == NIL)
00329 return list1;
00330 if (list1 == list2)
00331 elog(ERROR, "cannot list_concat() a list to itself");
00332
00333 Assert(list1->type == list2->type);
00334
00335 list1->length += list2->length;
00336 list1->tail->next = list2->head;
00337 list1->tail = list2->tail;
00338
00339 check_list_invariants(list1);
00340 return list1;
00341 }
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352 List *
00353 list_truncate(List *list, int new_size)
00354 {
00355 ListCell *cell;
00356 int n;
00357
00358 if (new_size <= 0)
00359 return NIL;
00360
00361
00362 if (new_size >= list_length(list))
00363 return list;
00364
00365 n = 1;
00366 foreach(cell, list)
00367 {
00368 if (n == new_size)
00369 {
00370 cell->next = NULL;
00371 list->tail = cell;
00372 list->length = new_size;
00373 check_list_invariants(list);
00374 return list;
00375 }
00376 n++;
00377 }
00378
00379
00380 Assert(false);
00381 return list;
00382 }
00383
00384
00385
00386
00387
00388 static ListCell *
00389 list_nth_cell(const List *list, int n)
00390 {
00391 ListCell *match;
00392
00393 Assert(list != NIL);
00394 Assert(n >= 0);
00395 Assert(n < list->length);
00396 check_list_invariants(list);
00397
00398
00399 if (n == list->length - 1)
00400 return list->tail;
00401
00402 for (match = list->head; n-- > 0; match = match->next)
00403 ;
00404
00405 return match;
00406 }
00407
00408
00409
00410
00411
00412 void *
00413 list_nth(const List *list, int n)
00414 {
00415 Assert(IsPointerList(list));
00416 return lfirst(list_nth_cell(list, n));
00417 }
00418
00419
00420
00421
00422
00423 int
00424 list_nth_int(const List *list, int n)
00425 {
00426 Assert(IsIntegerList(list));
00427 return lfirst_int(list_nth_cell(list, n));
00428 }
00429
00430
00431
00432
00433
00434 Oid
00435 list_nth_oid(const List *list, int n)
00436 {
00437 Assert(IsOidList(list));
00438 return lfirst_oid(list_nth_cell(list, n));
00439 }
00440
00441
00442
00443
00444
00445
00446 bool
00447 list_member(const List *list, const void *datum)
00448 {
00449 const ListCell *cell;
00450
00451 Assert(IsPointerList(list));
00452 check_list_invariants(list);
00453
00454 foreach(cell, list)
00455 {
00456 if (equal(lfirst(cell), datum))
00457 return true;
00458 }
00459
00460 return false;
00461 }
00462
00463
00464
00465
00466
00467 bool
00468 list_member_ptr(const List *list, const void *datum)
00469 {
00470 const ListCell *cell;
00471
00472 Assert(IsPointerList(list));
00473 check_list_invariants(list);
00474
00475 foreach(cell, list)
00476 {
00477 if (lfirst(cell) == datum)
00478 return true;
00479 }
00480
00481 return false;
00482 }
00483
00484
00485
00486
00487 bool
00488 list_member_int(const List *list, int datum)
00489 {
00490 const ListCell *cell;
00491
00492 Assert(IsIntegerList(list));
00493 check_list_invariants(list);
00494
00495 foreach(cell, list)
00496 {
00497 if (lfirst_int(cell) == datum)
00498 return true;
00499 }
00500
00501 return false;
00502 }
00503
00504
00505
00506
00507 bool
00508 list_member_oid(const List *list, Oid datum)
00509 {
00510 const ListCell *cell;
00511
00512 Assert(IsOidList(list));
00513 check_list_invariants(list);
00514
00515 foreach(cell, list)
00516 {
00517 if (lfirst_oid(cell) == datum)
00518 return true;
00519 }
00520
00521 return false;
00522 }
00523
00524
00525
00526
00527
00528
00529
00530 List *
00531 list_delete_cell(List *list, ListCell *cell, ListCell *prev)
00532 {
00533 check_list_invariants(list);
00534 Assert(prev != NULL ? lnext(prev) == cell : list_head(list) == cell);
00535
00536
00537
00538
00539
00540
00541 if (list->length == 1)
00542 {
00543 list_free(list);
00544 return NIL;
00545 }
00546
00547
00548
00549
00550
00551 list->length--;
00552
00553 if (prev)
00554 prev->next = cell->next;
00555 else
00556 list->head = cell->next;
00557
00558 if (list->tail == cell)
00559 list->tail = prev;
00560
00561 pfree(cell);
00562 return list;
00563 }
00564
00565
00566
00567
00568
00569 List *
00570 list_delete(List *list, void *datum)
00571 {
00572 ListCell *cell;
00573 ListCell *prev;
00574
00575 Assert(IsPointerList(list));
00576 check_list_invariants(list);
00577
00578 prev = NULL;
00579 foreach(cell, list)
00580 {
00581 if (equal(lfirst(cell), datum))
00582 return list_delete_cell(list, cell, prev);
00583
00584 prev = cell;
00585 }
00586
00587
00588 return list;
00589 }
00590
00591
00592 List *
00593 list_delete_ptr(List *list, void *datum)
00594 {
00595 ListCell *cell;
00596 ListCell *prev;
00597
00598 Assert(IsPointerList(list));
00599 check_list_invariants(list);
00600
00601 prev = NULL;
00602 foreach(cell, list)
00603 {
00604 if (lfirst(cell) == datum)
00605 return list_delete_cell(list, cell, prev);
00606
00607 prev = cell;
00608 }
00609
00610
00611 return list;
00612 }
00613
00614
00615 List *
00616 list_delete_int(List *list, int datum)
00617 {
00618 ListCell *cell;
00619 ListCell *prev;
00620
00621 Assert(IsIntegerList(list));
00622 check_list_invariants(list);
00623
00624 prev = NULL;
00625 foreach(cell, list)
00626 {
00627 if (lfirst_int(cell) == datum)
00628 return list_delete_cell(list, cell, prev);
00629
00630 prev = cell;
00631 }
00632
00633
00634 return list;
00635 }
00636
00637
00638 List *
00639 list_delete_oid(List *list, Oid datum)
00640 {
00641 ListCell *cell;
00642 ListCell *prev;
00643
00644 Assert(IsOidList(list));
00645 check_list_invariants(list);
00646
00647 prev = NULL;
00648 foreach(cell, list)
00649 {
00650 if (lfirst_oid(cell) == datum)
00651 return list_delete_cell(list, cell, prev);
00652
00653 prev = cell;
00654 }
00655
00656
00657 return list;
00658 }
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668 List *
00669 list_delete_first(List *list)
00670 {
00671 check_list_invariants(list);
00672
00673 if (list == NIL)
00674 return NIL;
00675
00676 return list_delete_cell(list, list_head(list), NULL);
00677 }
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699 List *
00700 list_union(const List *list1, const List *list2)
00701 {
00702 List *result;
00703 const ListCell *cell;
00704
00705 Assert(IsPointerList(list1));
00706 Assert(IsPointerList(list2));
00707
00708 result = list_copy(list1);
00709 foreach(cell, list2)
00710 {
00711 if (!list_member(result, lfirst(cell)))
00712 result = lappend(result, lfirst(cell));
00713 }
00714
00715 check_list_invariants(result);
00716 return result;
00717 }
00718
00719
00720
00721
00722
00723 List *
00724 list_union_ptr(const List *list1, const List *list2)
00725 {
00726 List *result;
00727 const ListCell *cell;
00728
00729 Assert(IsPointerList(list1));
00730 Assert(IsPointerList(list2));
00731
00732 result = list_copy(list1);
00733 foreach(cell, list2)
00734 {
00735 if (!list_member_ptr(result, lfirst(cell)))
00736 result = lappend(result, lfirst(cell));
00737 }
00738
00739 check_list_invariants(result);
00740 return result;
00741 }
00742
00743
00744
00745
00746 List *
00747 list_union_int(const List *list1, const List *list2)
00748 {
00749 List *result;
00750 const ListCell *cell;
00751
00752 Assert(IsIntegerList(list1));
00753 Assert(IsIntegerList(list2));
00754
00755 result = list_copy(list1);
00756 foreach(cell, list2)
00757 {
00758 if (!list_member_int(result, lfirst_int(cell)))
00759 result = lappend_int(result, lfirst_int(cell));
00760 }
00761
00762 check_list_invariants(result);
00763 return result;
00764 }
00765
00766
00767
00768
00769 List *
00770 list_union_oid(const List *list1, const List *list2)
00771 {
00772 List *result;
00773 const ListCell *cell;
00774
00775 Assert(IsOidList(list1));
00776 Assert(IsOidList(list2));
00777
00778 result = list_copy(list1);
00779 foreach(cell, list2)
00780 {
00781 if (!list_member_oid(result, lfirst_oid(cell)))
00782 result = lappend_oid(result, lfirst_oid(cell));
00783 }
00784
00785 check_list_invariants(result);
00786 return result;
00787 }
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802 List *
00803 list_intersection(const List *list1, const List *list2)
00804 {
00805 List *result;
00806 const ListCell *cell;
00807
00808 if (list1 == NIL || list2 == NIL)
00809 return NIL;
00810
00811 Assert(IsPointerList(list1));
00812 Assert(IsPointerList(list2));
00813
00814 result = NIL;
00815 foreach(cell, list1)
00816 {
00817 if (list_member(list2, lfirst(cell)))
00818 result = lappend(result, lfirst(cell));
00819 }
00820
00821 check_list_invariants(result);
00822 return result;
00823 }
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834 List *
00835 list_difference(const List *list1, const List *list2)
00836 {
00837 const ListCell *cell;
00838 List *result = NIL;
00839
00840 Assert(IsPointerList(list1));
00841 Assert(IsPointerList(list2));
00842
00843 if (list2 == NIL)
00844 return list_copy(list1);
00845
00846 foreach(cell, list1)
00847 {
00848 if (!list_member(list2, lfirst(cell)))
00849 result = lappend(result, lfirst(cell));
00850 }
00851
00852 check_list_invariants(result);
00853 return result;
00854 }
00855
00856
00857
00858
00859
00860 List *
00861 list_difference_ptr(const List *list1, const List *list2)
00862 {
00863 const ListCell *cell;
00864 List *result = NIL;
00865
00866 Assert(IsPointerList(list1));
00867 Assert(IsPointerList(list2));
00868
00869 if (list2 == NIL)
00870 return list_copy(list1);
00871
00872 foreach(cell, list1)
00873 {
00874 if (!list_member_ptr(list2, lfirst(cell)))
00875 result = lappend(result, lfirst(cell));
00876 }
00877
00878 check_list_invariants(result);
00879 return result;
00880 }
00881
00882
00883
00884
00885 List *
00886 list_difference_int(const List *list1, const List *list2)
00887 {
00888 const ListCell *cell;
00889 List *result = NIL;
00890
00891 Assert(IsIntegerList(list1));
00892 Assert(IsIntegerList(list2));
00893
00894 if (list2 == NIL)
00895 return list_copy(list1);
00896
00897 foreach(cell, list1)
00898 {
00899 if (!list_member_int(list2, lfirst_int(cell)))
00900 result = lappend_int(result, lfirst_int(cell));
00901 }
00902
00903 check_list_invariants(result);
00904 return result;
00905 }
00906
00907
00908
00909
00910 List *
00911 list_difference_oid(const List *list1, const List *list2)
00912 {
00913 const ListCell *cell;
00914 List *result = NIL;
00915
00916 Assert(IsOidList(list1));
00917 Assert(IsOidList(list2));
00918
00919 if (list2 == NIL)
00920 return list_copy(list1);
00921
00922 foreach(cell, list1)
00923 {
00924 if (!list_member_oid(list2, lfirst_oid(cell)))
00925 result = lappend_oid(result, lfirst_oid(cell));
00926 }
00927
00928 check_list_invariants(result);
00929 return result;
00930 }
00931
00932
00933
00934
00935
00936
00937
00938 List *
00939 list_append_unique(List *list, void *datum)
00940 {
00941 if (list_member(list, datum))
00942 return list;
00943 else
00944 return lappend(list, datum);
00945 }
00946
00947
00948
00949
00950
00951 List *
00952 list_append_unique_ptr(List *list, void *datum)
00953 {
00954 if (list_member_ptr(list, datum))
00955 return list;
00956 else
00957 return lappend(list, datum);
00958 }
00959
00960
00961
00962
00963 List *
00964 list_append_unique_int(List *list, int datum)
00965 {
00966 if (list_member_int(list, datum))
00967 return list;
00968 else
00969 return lappend_int(list, datum);
00970 }
00971
00972
00973
00974
00975 List *
00976 list_append_unique_oid(List *list, Oid datum)
00977 {
00978 if (list_member_oid(list, datum))
00979 return list;
00980 else
00981 return lappend_oid(list, datum);
00982 }
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994 List *
00995 list_concat_unique(List *list1, List *list2)
00996 {
00997 ListCell *cell;
00998
00999 Assert(IsPointerList(list1));
01000 Assert(IsPointerList(list2));
01001
01002 foreach(cell, list2)
01003 {
01004 if (!list_member(list1, lfirst(cell)))
01005 list1 = lappend(list1, lfirst(cell));
01006 }
01007
01008 check_list_invariants(list1);
01009 return list1;
01010 }
01011
01012
01013
01014
01015
01016 List *
01017 list_concat_unique_ptr(List *list1, List *list2)
01018 {
01019 ListCell *cell;
01020
01021 Assert(IsPointerList(list1));
01022 Assert(IsPointerList(list2));
01023
01024 foreach(cell, list2)
01025 {
01026 if (!list_member_ptr(list1, lfirst(cell)))
01027 list1 = lappend(list1, lfirst(cell));
01028 }
01029
01030 check_list_invariants(list1);
01031 return list1;
01032 }
01033
01034
01035
01036
01037 List *
01038 list_concat_unique_int(List *list1, List *list2)
01039 {
01040 ListCell *cell;
01041
01042 Assert(IsIntegerList(list1));
01043 Assert(IsIntegerList(list2));
01044
01045 foreach(cell, list2)
01046 {
01047 if (!list_member_int(list1, lfirst_int(cell)))
01048 list1 = lappend_int(list1, lfirst_int(cell));
01049 }
01050
01051 check_list_invariants(list1);
01052 return list1;
01053 }
01054
01055
01056
01057
01058 List *
01059 list_concat_unique_oid(List *list1, List *list2)
01060 {
01061 ListCell *cell;
01062
01063 Assert(IsOidList(list1));
01064 Assert(IsOidList(list2));
01065
01066 foreach(cell, list2)
01067 {
01068 if (!list_member_oid(list1, lfirst_oid(cell)))
01069 list1 = lappend_oid(list1, lfirst_oid(cell));
01070 }
01071
01072 check_list_invariants(list1);
01073 return list1;
01074 }
01075
01076
01077
01078
01079 static void
01080 list_free_private(List *list, bool deep)
01081 {
01082 ListCell *cell;
01083
01084 check_list_invariants(list);
01085
01086 cell = list_head(list);
01087 while (cell != NULL)
01088 {
01089 ListCell *tmp = cell;
01090
01091 cell = lnext(cell);
01092 if (deep)
01093 pfree(lfirst(tmp));
01094 pfree(tmp);
01095 }
01096
01097 if (list)
01098 pfree(list);
01099 }
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109 void
01110 list_free(List *list)
01111 {
01112 list_free_private(list, false);
01113 }
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123 void
01124 list_free_deep(List *list)
01125 {
01126
01127
01128
01129 Assert(IsPointerList(list));
01130 list_free_private(list, true);
01131 }
01132
01133
01134
01135
01136 List *
01137 list_copy(const List *oldlist)
01138 {
01139 List *newlist;
01140 ListCell *newlist_prev;
01141 ListCell *oldlist_cur;
01142
01143 if (oldlist == NIL)
01144 return NIL;
01145
01146 newlist = new_list(oldlist->type);
01147 newlist->length = oldlist->length;
01148
01149
01150
01151
01152
01153 newlist->head->data = oldlist->head->data;
01154
01155 newlist_prev = newlist->head;
01156 oldlist_cur = oldlist->head->next;
01157 while (oldlist_cur)
01158 {
01159 ListCell *newlist_cur;
01160
01161 newlist_cur = (ListCell *) palloc(sizeof(*newlist_cur));
01162 newlist_cur->data = oldlist_cur->data;
01163 newlist_prev->next = newlist_cur;
01164
01165 newlist_prev = newlist_cur;
01166 oldlist_cur = oldlist_cur->next;
01167 }
01168
01169 newlist_prev->next = NULL;
01170 newlist->tail = newlist_prev;
01171
01172 check_list_invariants(newlist);
01173 return newlist;
01174 }
01175
01176
01177
01178
01179 List *
01180 list_copy_tail(const List *oldlist, int nskip)
01181 {
01182 List *newlist;
01183 ListCell *newlist_prev;
01184 ListCell *oldlist_cur;
01185
01186 if (nskip < 0)
01187 nskip = 0;
01188
01189 if (oldlist == NIL || nskip >= oldlist->length)
01190 return NIL;
01191
01192 newlist = new_list(oldlist->type);
01193 newlist->length = oldlist->length - nskip;
01194
01195
01196
01197
01198 oldlist_cur = oldlist->head;
01199 while (nskip-- > 0)
01200 oldlist_cur = oldlist_cur->next;
01201
01202
01203
01204
01205
01206 newlist->head->data = oldlist_cur->data;
01207
01208 newlist_prev = newlist->head;
01209 oldlist_cur = oldlist_cur->next;
01210 while (oldlist_cur)
01211 {
01212 ListCell *newlist_cur;
01213
01214 newlist_cur = (ListCell *) palloc(sizeof(*newlist_cur));
01215 newlist_cur->data = oldlist_cur->data;
01216 newlist_prev->next = newlist_cur;
01217
01218 newlist_prev = newlist_cur;
01219 oldlist_cur = oldlist_cur->next;
01220 }
01221
01222 newlist_prev->next = NULL;
01223 newlist->tail = newlist_prev;
01224
01225 check_list_invariants(newlist);
01226 return newlist;
01227 }
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245 int length(const List *list);
01246
01247 int
01248 length(const List *list)
01249 {
01250 return list_length(list);
01251 }