Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
ccan
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
mirror
ccan
Commits
dc0aafc9
Commit
dc0aafc9
authored
Jan 01, 2011
by
Rusty Russell
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
list: list_del_from()
Deletion from a specific list.
parent
a04a5f74
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
55 additions
and
14 deletions
+55
-14
ccan/list/list.h
ccan/list/list.h
+45
-8
ccan/list/test/run-with-debug.c
ccan/list/test/run-with-debug.c
+5
-3
ccan/list/test/run.c
ccan/list/test/run.c
+5
-3
No files found.
ccan/list/list.h
View file @
dc0aafc9
#ifndef CCAN_LIST_H
#define CCAN_LIST_H
#include <stdbool.h>
#include <assert.h>
#include <ccan/container_of/container_of.h>
/**
...
...
@@ -164,9 +165,30 @@ static inline void list_add_tail(struct list_head *h, struct list_node *n)
}
/**
* list_del - delete an entry from a linked list.
* list_empty - is a list empty?
* @h: the list_head
*
* If the list is empty, returns true.
*
* Example:
* assert(list_empty(&parent->children) == (parent->num_children == 0));
*/
static
inline
bool
list_empty
(
const
struct
list_head
*
h
)
{
(
void
)
list_debug
(
h
);
return
h
->
n
.
next
==
&
h
->
n
;
}
/**
* list_del - delete an entry from an (unknown) linked list.
* @n: the list_node to delete from the list.
*
* Note that this leaves @n in an undefined state; it can be added to
* another list, but not deleted again.
*
* See also:
* list_del_from()
*
* Example:
* list_del(&child->list);
* parent->num_children--;
...
...
@@ -183,18 +205,33 @@ static inline void list_del(struct list_node *n)
}
/**
* list_empty - is a list empty?
* @h: the list_head
* list_del_from - delete an entry from a known linked list.
* @h: the list_head the node is in.
* @n: the list_node to delete from the list.
*
* If the list is empty, returns true.
* This explicitly indicates which list a node is expected to be in,
* which is better documentation and can catch more bugs.
*
* See also: list_del()
*
* Example:
* assert(list_empty(&parent->children) == (parent->num_children == 0));
* list_del_from(&parent->children, &child->list);
* parent->num_children--;
*/
static
inline
bool
list_empty
(
const
struct
list_head
*
h
)
static
inline
void
list_del_from
(
struct
list_head
*
h
,
struct
list_node
*
n
)
{
(
void
)
list_debug
(
h
);
return
h
->
n
.
next
==
&
h
->
n
;
#ifdef CCAN_LIST_DEBUG
{
/* Thorough check: make sure it was in list! */
struct
list_node
*
i
;
for
(
i
=
h
->
n
.
next
;
i
!=
n
;
i
=
i
->
next
)
assert
(
i
!=
&
h
->
n
);
}
#endif
/* CCAN_LIST_DEBUG */
/* Quick test that catches a surprising number of bugs. */
assert
(
!
list_empty
(
h
));
list_del
(
n
);
}
/**
...
...
ccan/list/test/run-with-debug.c
View file @
dc0aafc9
...
...
@@ -102,21 +102,23 @@ int main(int argc, char *argv[])
}
ok1
(
i
==
3
);
/* Test list_for_each_safe
and list_del
. */
/* Test list_for_each_safe
, list_del and list_del_from
. */
i
=
0
;
list_for_each_safe
(
&
parent
.
children
,
c
,
n
,
list
)
{
switch
(
i
++
)
{
case
0
:
ok1
(
c
==
&
c1
);
ok1
(
c
==
&
c1
);
list_del
(
&
c
->
list
);
break
;
case
1
:
ok1
(
c
==
&
c2
);
list_del_from
(
&
parent
.
children
,
&
c
->
list
);
break
;
case
2
:
ok1
(
c
==
&
c3
);
list_del_from
(
&
parent
.
children
,
&
c
->
list
);
break
;
}
list_del
(
&
c
->
list
);
ok1
(
list_check
(
&
parent
.
children
,
NULL
));
if
(
i
>
2
)
break
;
...
...
ccan/list/test/run.c
View file @
dc0aafc9
...
...
@@ -101,21 +101,23 @@ int main(int argc, char *argv[])
}
ok1
(
i
==
3
);
/* Test list_for_each_safe
and list_del
. */
/* Test list_for_each_safe
, list_del and list_del_from
. */
i
=
0
;
list_for_each_safe
(
&
parent
.
children
,
c
,
n
,
list
)
{
switch
(
i
++
)
{
case
0
:
ok1
(
c
==
&
c1
);
ok1
(
c
==
&
c1
);
list_del
(
&
c
->
list
);
break
;
case
1
:
ok1
(
c
==
&
c2
);
list_del_from
(
&
parent
.
children
,
&
c
->
list
);
break
;
case
2
:
ok1
(
c
==
&
c3
);
list_del_from
(
&
parent
.
children
,
&
c
->
list
);
break
;
}
list_del
(
&
c
->
list
);
ok1
(
list_check
(
&
parent
.
children
,
NULL
));
if
(
i
>
2
)
break
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment