00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "config.h"
00021
00022 #include <stdlib.h>
00023 #include <string.h>
00024 #include <stdio.h>
00025
00026
00027 #include "alpm_list.h"
00028 #include "util.h"
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 alpm_list_t SYMEXPORT *alpm_list_new()
00048 {
00049 alpm_list_t *list = NULL;
00050
00051 list = malloc(sizeof(alpm_list_t));
00052 if(list) {
00053 list->data = NULL;
00054 list->prev = list;
00055 list->next = NULL;
00056 }
00057
00058 return(list);
00059 }
00060
00061
00062
00063
00064
00065
00066 void SYMEXPORT alpm_list_free(alpm_list_t *list)
00067 {
00068 alpm_list_t *it = list;
00069
00070 while(it) {
00071 alpm_list_t *tmp = it->next;
00072 free(it);
00073 it = tmp;
00074 }
00075 }
00076
00077
00078
00079
00080
00081
00082
00083 void SYMEXPORT alpm_list_free_inner(alpm_list_t *list, alpm_list_fn_free fn)
00084 {
00085 alpm_list_t *it = list;
00086
00087 while(it) {
00088 if(fn && it->data) {
00089 fn(it->data);
00090 }
00091 it = it->next;
00092 }
00093 }
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106 alpm_list_t SYMEXPORT *alpm_list_add(alpm_list_t *list, void *data)
00107 {
00108 alpm_list_t *ptr, *lp;
00109
00110 ptr = list;
00111 if(ptr == NULL) {
00112 ptr = alpm_list_new();
00113 if(ptr == NULL) {
00114 return(NULL);
00115 }
00116 }
00117
00118 lp = alpm_list_last(ptr);
00119 if(lp == ptr && lp->data == NULL) {
00120
00121 } else {
00122 lp->next = alpm_list_new();
00123 if(lp->next == NULL) {
00124 return(NULL);
00125 }
00126 lp->next->prev = lp;
00127 lp = lp->next;
00128 list->prev = lp;
00129 }
00130
00131 lp->data = data;
00132
00133 return(ptr);
00134 }
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145 alpm_list_t SYMEXPORT *alpm_list_add_sorted(alpm_list_t *list, void *data, alpm_list_fn_cmp fn)
00146 {
00147 if(!fn) {
00148 return alpm_list_add(list, data);
00149 } else {
00150 alpm_list_t *add = NULL, *prev = NULL, *next = list;
00151
00152 add = alpm_list_new();
00153 add->data = data;
00154
00155
00156 while(next) {
00157 if(fn(add->data, next->data) <= 0) break;
00158 prev = next;
00159 next = next->next;
00160 }
00161
00162
00163 add->prev = prev;
00164 add->next = next;
00165
00166 if(next != NULL) {
00167 next->prev = add;
00168 }
00169
00170 if(prev != NULL) {
00171 prev->next = add;
00172 } else {
00173 list = add;
00174 }
00175
00176 if(next == NULL) {
00177
00178 list->prev = add;
00179 }
00180
00181 return(list);
00182 }
00183 }
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196 alpm_list_t SYMEXPORT *alpm_list_join(alpm_list_t *first, alpm_list_t *second)
00197 {
00198 alpm_list_t *tmp;
00199
00200 if (first == NULL) {
00201 return second;
00202 }
00203 if (second == NULL) {
00204 return first;
00205 }
00206
00207 tmp = first->prev;
00208
00209 tmp->next = second;
00210
00211 first->prev = second->prev;
00212
00213 second->prev = tmp;
00214
00215 return(first);
00216 }
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227 alpm_list_t SYMEXPORT *alpm_list_mmerge(alpm_list_t *left, alpm_list_t *right, alpm_list_fn_cmp fn)
00228 {
00229 alpm_list_t *newlist, *lp;
00230
00231 if (left == NULL)
00232 return right;
00233 if (right == NULL)
00234 return left;
00235
00236 if (fn(left->data, right->data) <= 0) {
00237 newlist = left;
00238 left = left->next;
00239 }
00240 else {
00241 newlist = right;
00242 right = right->next;
00243 }
00244 newlist->prev = NULL;
00245 newlist->next = NULL;
00246 lp = newlist;
00247
00248 while ((left != NULL) && (right != NULL)) {
00249 if (fn(left->data, right->data) <= 0) {
00250 lp->next = left;
00251 left->prev = lp;
00252 left = left->next;
00253 }
00254 else {
00255 lp->next = right;
00256 right->prev = lp;
00257 right = right->next;
00258 }
00259 lp = lp->next;
00260 lp->next = NULL;
00261 }
00262 if (left != NULL) {
00263 lp->next = left;
00264 left->prev = lp;
00265 }
00266 else if (right != NULL) {
00267 lp->next = right;
00268 right->prev = lp;
00269 }
00270
00271
00272
00273 lp = newlist;
00274 while(lp && lp->next) {
00275 lp = lp->next;
00276 }
00277 newlist->prev = lp;
00278
00279 return(newlist);
00280 }
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291 alpm_list_t SYMEXPORT *alpm_list_msort(alpm_list_t *list, int n, alpm_list_fn_cmp fn)
00292 {
00293 if (n > 1) {
00294 alpm_list_t *left = list;
00295 alpm_list_t *lastleft = alpm_list_nth(list, n/2 - 1);
00296 alpm_list_t *right = lastleft->next;
00297
00298 lastleft->next = NULL;
00299
00300 left = alpm_list_msort(left, n/2, fn);
00301 right = alpm_list_msort(right, n - (n/2), fn);
00302 list = alpm_list_mmerge(left, right, fn);
00303 }
00304 return(list);
00305 }
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317 alpm_list_t SYMEXPORT *alpm_list_remove(alpm_list_t *haystack, const void *needle, alpm_list_fn_cmp fn, void **data)
00318 {
00319 alpm_list_t *i = haystack, *tmp = NULL;
00320
00321 if(data) {
00322 *data = NULL;
00323 }
00324
00325 while(i) {
00326 if(i->data == NULL) {
00327 continue;
00328 }
00329 tmp = i->next;
00330 if(fn(needle, i->data) == 0) {
00331
00332 if(i == haystack) {
00333
00334
00335 haystack = i->next;
00336 if(haystack) {
00337 haystack->prev = i->prev;
00338 }
00339 i->prev = NULL;
00340 } else if(i == haystack->prev) {
00341
00342
00343 if(i->prev) {
00344
00345 i->prev->next = i->next;
00346 haystack->prev = i->prev;
00347 i->prev = NULL;
00348 }
00349 } else {
00350
00351 if(i->next) {
00352 i->next->prev = i->prev;
00353 }
00354 if(i->prev) {
00355 i->prev->next = i->next;
00356 }
00357 }
00358
00359 if(data) {
00360 *data = i->data;
00361 }
00362 i->data = NULL;
00363 free(i);
00364 i = NULL;
00365 } else {
00366 i = tmp;
00367 }
00368 }
00369
00370 return(haystack);
00371 }
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382 alpm_list_t SYMEXPORT *alpm_list_remove_dupes(const alpm_list_t *list)
00383 {
00384 const alpm_list_t *lp = list;
00385 alpm_list_t *newlist = NULL;
00386 while(lp) {
00387 if(!alpm_list_find_ptr(newlist, lp->data)) {
00388 newlist = alpm_list_add(newlist, lp->data);
00389 }
00390 lp = lp->next;
00391 }
00392 return(newlist);
00393 }
00394
00395
00396
00397
00398
00399
00400
00401
00402 alpm_list_t SYMEXPORT *alpm_list_strdup(const alpm_list_t *list)
00403 {
00404 const alpm_list_t *lp = list;
00405 alpm_list_t *newlist = NULL;
00406 while(lp) {
00407 newlist = alpm_list_add(newlist, strdup(lp->data));
00408 lp = lp->next;
00409 }
00410 return(newlist);
00411 }
00412
00413
00414
00415
00416
00417
00418
00419
00420 alpm_list_t SYMEXPORT *alpm_list_copy(const alpm_list_t *list)
00421 {
00422 const alpm_list_t *lp = list;
00423 alpm_list_t *newlist = NULL;
00424 while(lp) {
00425 newlist = alpm_list_add(newlist, lp->data);
00426 lp = lp->next;
00427 }
00428 return(newlist);
00429 }
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441 alpm_list_t SYMEXPORT *alpm_list_copy_data(const alpm_list_t *list,
00442 size_t size)
00443 {
00444 const alpm_list_t *lp = list;
00445 alpm_list_t *newlist = NULL;
00446 while(lp) {
00447 void *newdata = calloc(1, size);
00448 if(newdata) {
00449 memcpy(newdata, lp->data, size);
00450 newlist = alpm_list_add(newlist, newdata);
00451 lp = lp->next;
00452 }
00453 }
00454 return(newlist);
00455 }
00456
00457
00458
00459
00460
00461
00462
00463
00464 alpm_list_t SYMEXPORT *alpm_list_reverse(alpm_list_t *list)
00465 {
00466 const alpm_list_t *lp;
00467 alpm_list_t *newlist = NULL;
00468
00469 lp = alpm_list_last(list);
00470 if(list) {
00471
00472 list->prev = NULL;
00473 }
00474
00475 while(lp) {
00476 newlist = alpm_list_add(newlist, lp->data);
00477 lp = lp->prev;
00478 }
00479 return(newlist);
00480 }
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491 inline alpm_list_t SYMEXPORT *alpm_list_first(const alpm_list_t *list)
00492 {
00493 return((alpm_list_t*)list);
00494 }
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504 alpm_list_t SYMEXPORT *alpm_list_nth(const alpm_list_t *list, int n)
00505 {
00506 const alpm_list_t *i = list;
00507 while(n--) {
00508 i = i->next;
00509 }
00510 return((alpm_list_t*)i);
00511 }
00512
00513
00514
00515
00516
00517
00518
00519
00520 inline alpm_list_t SYMEXPORT *alpm_list_next(const alpm_list_t *node)
00521 {
00522 return(node->next);
00523 }
00524
00525
00526
00527
00528
00529
00530
00531
00532 alpm_list_t SYMEXPORT *alpm_list_last(const alpm_list_t *list)
00533 {
00534 if(list) {
00535 return(list->prev);
00536 } else {
00537 return(NULL);
00538 }
00539 }
00540
00541
00542
00543
00544
00545
00546
00547
00548 void SYMEXPORT *alpm_list_getdata(const alpm_list_t *node)
00549 {
00550 if(node == NULL) return(NULL);
00551 return(node->data);
00552 }
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563 int SYMEXPORT alpm_list_count(const alpm_list_t *list)
00564 {
00565 unsigned int i = 0;
00566 const alpm_list_t *lp = list;
00567 while(lp) {
00568 ++i;
00569 lp = lp->next;
00570 }
00571 return(i);
00572 }
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583 void SYMEXPORT *alpm_list_find(const alpm_list_t *haystack, const void *needle,
00584 alpm_list_fn_cmp fn)
00585 {
00586 const alpm_list_t *lp = haystack;
00587 while(lp) {
00588 if(lp->data && fn(lp->data, needle) == 0) {
00589 return(lp->data);
00590 }
00591 lp = lp->next;
00592 }
00593 return(NULL);
00594 }
00595
00596
00597 static int ptrcmp(const void *p, const void *q)
00598 {
00599 return(p != q);
00600 }
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612 void SYMEXPORT *alpm_list_find_ptr(const alpm_list_t *haystack, const void *needle)
00613 {
00614 return(alpm_list_find(haystack, needle, ptrcmp));
00615 }
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625 char SYMEXPORT *alpm_list_find_str(const alpm_list_t *haystack, const char *needle)
00626 {
00627 return((char *)alpm_list_find(haystack, (const void*)needle, (alpm_list_fn_cmp)strcmp));
00628 }
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643 alpm_list_t SYMEXPORT *alpm_list_diff(const alpm_list_t *lhs,
00644 const alpm_list_t *rhs, alpm_list_fn_cmp fn)
00645 {
00646 const alpm_list_t *i, *j;
00647 alpm_list_t *ret = NULL;
00648 for(i = lhs; i; i = i->next) {
00649 int found = 0;
00650 for(j = rhs; j; j = j->next) {
00651 if(fn(i->data, j->data) == 0) {
00652 found = 1;
00653 break;
00654 }
00655 }
00656 if(!found) {
00657 ret = alpm_list_add(ret, i->data);
00658 }
00659 }
00660
00661 return(ret);
00662 }
00663
00664
00665
00666