source: mainline/uspace/lib/pcut/src/list.c@ 9b20126

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 9b20126 was 9b20126, checked in by Vojtech Horky <vojtechhorky@…>, 11 years ago

Update PCUT to newest version

  • Property mode set to 100644
File size: 4.8 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
34#include <assert.h>
35#include <stdlib.h>
36#include "internal.h"
[134ac5d]37#include <pcut/pcut.h>
[01579ad]38
39
40/** Find next item with actual content.
41 *
42 * @param item Head of the list.
43 * @return First item with actual content or NULL on end of list.
44 */
45pcut_item_t *pcut_get_real_next(pcut_item_t *item) {
46 if (item == NULL) {
47 return NULL;
48 }
49
50 do {
51 item = item->next;
52 } while ((item != NULL) && (item->kind == PCUT_KIND_SKIP));
53
54
55 return item;
56}
57
58/** Retrieve the first item with actual content.
59 *
60 * Unlike pcut_get_real_next(), where we always advance after the
61 * first item, here the @p item itself could be returned.
62 *
63 * @param item Head of the list.
64 * @return First item with actual content or NULL on end of list.
65 */
66pcut_item_t *pcut_get_real(pcut_item_t *item) {
67 if (item == NULL) {
68 return NULL;
69 }
70
71 if (item->kind == PCUT_KIND_SKIP) {
72 return pcut_get_real_next(item);
73 } else {
74 return item;
75 }
76}
77
78
79/** In-line nested lists into the parent.
80 *
81 * @param nested Head of the nested list.
82 */
83static void inline_nested_lists(pcut_item_t *nested) {
[9b20126]84 pcut_item_t *first;
85
[01579ad]86 if (nested->kind != PCUT_KIND_NESTED) {
87 return;
88 }
89
[9b20126]90 if (nested->nested == NULL) {
[01579ad]91 nested->kind = PCUT_KIND_SKIP;
92 return;
93 }
94
[9b20126]95 first = pcut_fix_list_get_real_head(nested->nested);
96 nested->nested->next = nested->next;
[01579ad]97 if (nested->next != NULL) {
[9b20126]98 nested->next->previous = nested->nested;
[01579ad]99 }
100 nested->next = first;
101 first->previous = nested;
102
103 nested->kind = PCUT_KIND_SKIP;
104}
105
106/** Assing unique ids to each item in the list.
107 *
108 * @param first List head.
109 */
110static void set_ids(pcut_item_t *first) {
111 int id = 1;
[9b20126]112 pcut_item_t *it;
113
114 assert(first != NULL);
115
[01579ad]116 if (first->kind == PCUT_KIND_SKIP) {
117 first = pcut_get_real_next(first);
118 }
[9b20126]119
120 for (it = first; it != NULL; it = pcut_get_real_next(it)) {
[01579ad]121 it->id = id;
122 id++;
123 }
124}
125
[134ac5d]126/** Hide tests that are marked to be skipped.
127 *
128 * Go through all tests and those that have PCUT_EXTRA_SKIP mark
129 * as skipped with PCUT_KIND_SKIP.
130 *
131 * @param first Head of the list.
132 */
133static void detect_skipped_tests(pcut_item_t *first) {
[9b20126]134 pcut_item_t *it;
135
[134ac5d]136 assert(first != NULL);
137 if (first->kind == PCUT_KIND_SKIP) {
138 first = pcut_get_real_next(first);
139 }
[9b20126]140
141 for (it = first; it != NULL; it = pcut_get_real_next(it)) {
142 pcut_extra_t *extras;
143
[134ac5d]144 if (it->kind != PCUT_KIND_TEST) {
145 continue;
146 }
[9b20126]147
148 extras = it->extras;
[134ac5d]149 while (extras->type != PCUT_EXTRA_LAST) {
150 if (extras->type == PCUT_EXTRA_SKIP) {
151 it->kind = PCUT_KIND_SKIP;
152 break;
153 }
154 extras++;
155 }
156 }
157}
158
[01579ad]159/** Convert the static single-linked list into a flat double-linked list.
160 *
161 * The conversion includes
162 * * adding forward links
163 * * flattening of any nested lists
164 * * assigning of unique ids
165 *
166 * @param last Tail of the list.
167 * @return Head of the fixed list.
168 */
169pcut_item_t *pcut_fix_list_get_real_head(pcut_item_t *last) {
[9b20126]170 pcut_item_t *next, *it;
171
[01579ad]172 last->next = NULL;
173
174 inline_nested_lists(last);
175
[9b20126]176 next = last;
177 it = last->previous;
[01579ad]178 while (it != NULL) {
179 it->next = next;
180 inline_nested_lists(it);
181 next = it;
182 it = it->previous;
183 }
184
[134ac5d]185 detect_skipped_tests(next);
186
[01579ad]187 set_ids(next);
188
189 return next;
190}
191
192/** Compute the number of all tests in a list.
193 *
194 * @param it Head of the list.
195 * @return Number of tests.
196 */
197int pcut_count_tests(pcut_item_t *it) {
198 int count = 0;
199 while (it != NULL) {
200 if (it->kind == PCUT_KIND_TEST) {
201 count++;
202 }
203 it = pcut_get_real_next(it);
204 }
205 return count;
206}
Note: See TracBrowser for help on using the repository browser.