source: mainline/uspace/lib/pcut/src/list.c@ 0b63dc2

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 0b63dc2 was 4b54bd9, checked in by Vojtech Horky <vojtech.horky@…>, 7 years ago

Update PCUT to latest revision

  • Property mode set to 100644
File size: 4.9 KB
RevLine 
[01579ad]1/*
2 * Copyright (c) 2012-2013 Vojtech Horky
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @file
30 *
31 * Helper functions for working with list of items.
32 */
33
[4b54bd9]34#pragma warning(push, 0)
[01579ad]35#include <assert.h>
36#include <stdlib.h>
[4b54bd9]37#pragma warning(pop)
38
[01579ad]39#include "internal.h"
[134ac5d]40#include <pcut/pcut.h>
[01579ad]41
42
43/** Find next item with actual content.
44 *
45 * @param item Head of the list.
46 * @return First item with actual content or NULL on end of list.
47 */
[4b54bd9]48pcut_item_t *pcut_get_real_next(pcut_item_t *item) {
[01579ad]49 if (item == NULL) {
50 return NULL;
51 }
52
53 do {
54 item = item->next;
55 } while ((item != NULL) && (item->kind == PCUT_KIND_SKIP));
56
57
58 return item;
59}
60
61/** Retrieve the first item with actual content.
62 *
63 * Unlike pcut_get_real_next(), where we always advance after the
64 * first item, here the @p item itself could be returned.
65 *
66 * @param item Head of the list.
67 * @return First item with actual content or NULL on end of list.
68 */
[4b54bd9]69pcut_item_t *pcut_get_real(pcut_item_t *item) {
[01579ad]70 if (item == NULL) {
71 return NULL;
72 }
73
74 if (item->kind == PCUT_KIND_SKIP) {
75 return pcut_get_real_next(item);
76 } else {
77 return item;
78 }
79}
80
81
82/** In-line nested lists into the parent.
83 *
84 * @param nested Head of the nested list.
85 */
[4b54bd9]86static void inline_nested_lists(pcut_item_t *nested) {
[9b20126]87 pcut_item_t *first;
88
[01579ad]89 if (nested->kind != PCUT_KIND_NESTED) {
90 return;
91 }
92
[9b20126]93 if (nested->nested == NULL) {
[01579ad]94 nested->kind = PCUT_KIND_SKIP;
95 return;
96 }
97
[9b20126]98 first = pcut_fix_list_get_real_head(nested->nested);
99 nested->nested->next = nested->next;
[01579ad]100 if (nested->next != NULL) {
[9b20126]101 nested->next->previous = nested->nested;
[01579ad]102 }
103 nested->next = first;
104 first->previous = nested;
105
106 nested->kind = PCUT_KIND_SKIP;
107}
108
109/** Assing unique ids to each item in the list.
110 *
111 * @param first List head.
112 */
[4b54bd9]113static void set_ids(pcut_item_t *first) {
[01579ad]114 int id = 1;
[9b20126]115 pcut_item_t *it;
116
117 assert(first != NULL);
118
[01579ad]119 if (first->kind == PCUT_KIND_SKIP) {
120 first = pcut_get_real_next(first);
121 }
[9b20126]122
123 for (it = first; it != NULL; it = pcut_get_real_next(it)) {
[01579ad]124 it->id = id;
125 id++;
126 }
127}
128
[134ac5d]129/** Hide tests that are marked to be skipped.
130 *
131 * Go through all tests and those that have PCUT_EXTRA_SKIP mark
132 * as skipped with PCUT_KIND_SKIP.
133 *
134 * @param first Head of the list.
135 */
[4b54bd9]136static void detect_skipped_tests(pcut_item_t *first) {
[9b20126]137 pcut_item_t *it;
138
[134ac5d]139 assert(first != NULL);
140 if (first->kind == PCUT_KIND_SKIP) {
141 first = pcut_get_real_next(first);
142 }
[9b20126]143
144 for (it = first; it != NULL; it = pcut_get_real_next(it)) {
145 pcut_extra_t *extras;
146
[134ac5d]147 if (it->kind != PCUT_KIND_TEST) {
148 continue;
149 }
[9b20126]150
151 extras = it->extras;
[134ac5d]152 while (extras->type != PCUT_EXTRA_LAST) {
153 if (extras->type == PCUT_EXTRA_SKIP) {
154 it->kind = PCUT_KIND_SKIP;
155 break;
156 }
157 extras++;
158 }
159 }
160}
161
[01579ad]162/** Convert the static single-linked list into a flat double-linked list.
163 *
164 * The conversion includes
165 * * adding forward links
166 * * flattening of any nested lists
167 * * assigning of unique ids
168 *
169 * @param last Tail of the list.
170 * @return Head of the fixed list.
171 */
[4b54bd9]172pcut_item_t *pcut_fix_list_get_real_head(pcut_item_t *last) {
[9b20126]173 pcut_item_t *next, *it;
174
[01579ad]175 last->next = NULL;
176
177 inline_nested_lists(last);
178
[9b20126]179 next = last;
180 it = last->previous;
[01579ad]181 while (it != NULL) {
182 it->next = next;
183 inline_nested_lists(it);
184 next = it;
185 it = it->previous;
186 }
187
[134ac5d]188 detect_skipped_tests(next);
189
[01579ad]190 set_ids(next);
191
192 return next;
193}
194
195/** Compute the number of all tests in a list.
196 *
197 * @param it Head of the list.
198 * @return Number of tests.
199 */
[4b54bd9]200int pcut_count_tests(pcut_item_t *it) {
[01579ad]201 int count = 0;
202 while (it != NULL) {
203 if (it->kind == PCUT_KIND_TEST) {
204 count++;
205 }
206 it = pcut_get_real_next(it);
207 }
208 return count;
209}
Note: See TracBrowser for help on using the repository browser.