* Returns a list organized in an intermediate format suited * to chaining of merge() calls: null-terminated, no reserved or * sentinel head node, "prev" links not maintained. */ @ @ decreases 0; @*/
| 40 | @ decreases 0; |
| 41 | @*/ |
| 42 | static struct td_list_head *merge( |
| 43 | int (*cmp)(const struct td_list_head *a, const struct td_list_head *b), |
| 44 | struct td_list_head *a, struct td_list_head *b) |
| 45 | { |
| 46 | struct td_list_head head, *tail = &head; |
| 47 | |
| 48 | /*@ |
| 49 | @ loop invariant \valid_function(cmp); |
| 50 | @ loop invariant \valid(tail); |
| 51 | @ loop invariant \valid(a); |
| 52 | @ loop invariant \valid(b); |
| 53 | @*/ |
| 54 | while (a && b) { |
| 55 | /* if equal, take 'a' -- important for sort stability */ |
| 56 | if ((*cmp)(a, b) <= 0) { |
| 57 | tail->next = a; |
| 58 | a = a->next; |
| 59 | } else { |
| 60 | tail->next = b; |
| 61 | b = b->next; |
| 62 | } |
| 63 | tail = tail->next; |
| 64 | } |
| 65 | tail->next = a?a:b; |
| 66 | return head.next; |
| 67 | } |
| 68 | |
| 69 | /* |
| 70 | * Combine final list merge with restoration of standard doubly-linked |