* [PATCH 0/2] kernel-doc: Handle function typedefs
@ 2020-10-30 14:47 Paolo Bonzini
2020-10-30 14:47 ` [PATCH 1/2] kernel-doc: Handle function typedefs that return pointers Paolo Bonzini
2020-10-30 14:47 ` [PATCH 2/2] kernel-doc: Handle function typedefs without asterisks Paolo Bonzini
0 siblings, 2 replies; 17+ messages in thread
From: Paolo Bonzini @ 2020-10-30 14:47 UTC (permalink / raw)
To: linux-kernel, linux-doc, corbet; +Cc: Eduardo Habkost
Hi all,
QEMU has been using kernel-doc for a while and we're very happy with it. :)
These two patches are relatively simple regex changes that were done to
support QEMU header files; they handle function typedefs (i.e. not
function _pointer_ typedefs).
These are basically the only difference between Linux and QEMU kernel-doc,
so I thought I'd just send them out and see what you people think.
Paolo
Eduardo Habkost (2):
kernel-doc: Handle function typedefs that return pointers
kernel-doc: Handle function typedefs without asterisks
scripts/kernel-doc | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--
2.28.0
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 1/2] kernel-doc: Handle function typedefs that return pointers
2020-10-30 14:47 [PATCH 0/2] kernel-doc: Handle function typedefs Paolo Bonzini
@ 2020-10-30 14:47 ` Paolo Bonzini
2020-10-30 14:47 ` [PATCH 2/2] kernel-doc: Handle function typedefs without asterisks Paolo Bonzini
1 sibling, 0 replies; 17+ messages in thread
From: Paolo Bonzini @ 2020-10-30 14:47 UTC (permalink / raw)
To: linux-kernel, linux-doc, corbet; +Cc: Eduardo Habkost
From: Eduardo Habkost <ehabkost@redhat.com>
One example that was not being parsed correctly by kernel-doc is:
typedef Object *(ObjectPropertyResolve)(Object *obj,
void *opaque,
const char *part);
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
scripts/kernel-doc | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index f68d76dd97ba..5b5caa7642f7 100755
--- a/scripts/kernel-doc
+++ b/scripts/kernel-doc
@@ -1302,8 +1302,8 @@ sub dump_typedef($$) {
$x =~ s@/\*.*?\*/@@gos; # strip comments.
# Parse function prototypes
- if ($x =~ /typedef\s+(\w+)\s*\(\*\s*(\w\S+)\s*\)\s*\((.*)\);/ ||
- $x =~ /typedef\s+(\w+)\s*(\w\S+)\s*\s*\((.*)\);/) {
+ if ($x =~ /typedef\s+(\w+\s*\**)\s*\(\*\s*(\w\S+)\s*\)\s*\((.*)\);/ ||
+ $x =~ /typedef\s+(\w+\s*\**)\s*(\w\S+)\s*\s*\((.*)\);/) {
# Function typedefs
$return_type = $1;
--
2.28.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 2/2] kernel-doc: Handle function typedefs without asterisks
2020-10-30 14:47 [PATCH 0/2] kernel-doc: Handle function typedefs Paolo Bonzini
2020-10-30 14:47 ` [PATCH 1/2] kernel-doc: Handle function typedefs that return pointers Paolo Bonzini
@ 2020-10-30 14:47 ` Paolo Bonzini
2020-11-13 22:21 ` Jonathan Corbet
1 sibling, 1 reply; 17+ messages in thread
From: Paolo Bonzini @ 2020-10-30 14:47 UTC (permalink / raw)
To: linux-kernel, linux-doc, corbet; +Cc: Eduardo Habkost
From: Eduardo Habkost <ehabkost@redhat.com>
Example of typedef that was not parsed by kernel-doc:
typedef void (ObjectUnparent)(Object *obj);
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
scripts/kernel-doc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index 5b5caa7642f7..1a9c918aa653 100755
--- a/scripts/kernel-doc
+++ b/scripts/kernel-doc
@@ -1302,7 +1302,7 @@ sub dump_typedef($$) {
$x =~ s@/\*.*?\*/@@gos; # strip comments.
# Parse function prototypes
- if ($x =~ /typedef\s+(\w+\s*\**)\s*\(\*\s*(\w\S+)\s*\)\s*\((.*)\);/ ||
+ if ($x =~ /typedef\s+(\w+\s*\**)\s*\(\*?\s*(\w\S+)\s*\)\s*\((.*)\);/ ||
$x =~ /typedef\s+(\w+\s*\**)\s*(\w\S+)\s*\s*\((.*)\);/) {
# Function typedefs
--
2.28.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH 2/2] kernel-doc: Handle function typedefs without asterisks
2020-10-30 14:47 ` [PATCH 2/2] kernel-doc: Handle function typedefs without asterisks Paolo Bonzini
@ 2020-11-13 22:21 ` Jonathan Corbet
2020-11-13 22:35 ` Paolo Bonzini
2020-11-13 22:39 ` Matthew Wilcox
0 siblings, 2 replies; 17+ messages in thread
From: Jonathan Corbet @ 2020-11-13 22:21 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: linux-kernel, linux-doc, Eduardo Habkost
On Fri, 30 Oct 2020 15:47:13 +0100
Paolo Bonzini <pbonzini@redhat.com> wrote:
> From: Eduardo Habkost <ehabkost@redhat.com>
>
> Example of typedef that was not parsed by kernel-doc:
>
> typedef void (ObjectUnparent)(Object *obj);
>
> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
So as you've undoubtedly noticed, reading those kernel-doc regexes is ... a
wee bit on the painful side. Trying to compare two of them in a patch to
figure out what you have done is even worse. I suspect we want these
patches, but can you please supply a changelog that describes the change?
> ---
> scripts/kernel-doc | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/scripts/kernel-doc b/scripts/kernel-doc
> index 5b5caa7642f7..1a9c918aa653 100755
> --- a/scripts/kernel-doc
> +++ b/scripts/kernel-doc
> @@ -1302,7 +1302,7 @@ sub dump_typedef($$) {
> $x =~ s@/\*.*?\*/@@gos; # strip comments.
>
> # Parse function prototypes
> - if ($x =~ /typedef\s+(\w+\s*\**)\s*\(\*\s*(\w\S+)\s*\)\s*\((.*)\);/ ||
> + if ($x =~ /typedef\s+(\w+\s*\**)\s*\(\*?\s*(\w\S+)\s*\)\s*\((.*)\);/ ||
Here it appears that you are making the "*" before the function-pointer
name optional, right? It really would help to say so in the changelog.
This is true for the other patch as well.
> $x =~ /typedef\s+(\w+\s*\**)\s*(\w\S+)\s*\s*\((.*)\);/) {
>
> # Function typedefs
Thanks,
jon
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 2/2] kernel-doc: Handle function typedefs without asterisks
2020-11-13 22:21 ` Jonathan Corbet
@ 2020-11-13 22:35 ` Paolo Bonzini
2020-11-13 22:39 ` Matthew Wilcox
1 sibling, 0 replies; 17+ messages in thread
From: Paolo Bonzini @ 2020-11-13 22:35 UTC (permalink / raw)
To: Jonathan Corbet; +Cc: linux-kernel, linux-doc, Eduardo Habkost
On 13/11/20 23:21, Jonathan Corbet wrote:
>>
>> Signed-off-by: Eduardo Habkost<ehabkost@redhat.com>
>> Signed-off-by: Paolo Bonzini<pbonzini@redhat.com>
> So as you've undoubtedly noticed, reading those kernel-doc regexes is ... a
> wee bit on the painful side. Trying to compare two of them in a patch to
> figure out what you have done is even worse. I suspect we want these
> patches, but can you please supply a changelog that describes the change?
>
Seems like some of Mauro's recent patches take care of the same thing.
I'm going to update QEMU's kernel-doc, and if there's anything left to
do I'll resend.
Thanks,
Paolo
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 2/2] kernel-doc: Handle function typedefs without asterisks
2020-11-13 22:21 ` Jonathan Corbet
2020-11-13 22:35 ` Paolo Bonzini
@ 2020-11-13 22:39 ` Matthew Wilcox
2020-11-17 21:24 ` Eduardo Habkost
1 sibling, 1 reply; 17+ messages in thread
From: Matthew Wilcox @ 2020-11-13 22:39 UTC (permalink / raw)
To: Jonathan Corbet; +Cc: Paolo Bonzini, linux-kernel, linux-doc, Eduardo Habkost
On Fri, Nov 13, 2020 at 03:21:06PM -0700, Jonathan Corbet wrote:
> On Fri, 30 Oct 2020 15:47:13 +0100
> Paolo Bonzini <pbonzini@redhat.com> wrote:
>
> > From: Eduardo Habkost <ehabkost@redhat.com>
> >
> > Example of typedef that was not parsed by kernel-doc:
> >
> > typedef void (ObjectUnparent)(Object *obj);
> >
> > Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
> > Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
>
> So as you've undoubtedly noticed, reading those kernel-doc regexes is ... a
> wee bit on the painful side. Trying to compare two of them in a patch to
> figure out what you have done is even worse. I suspect we want these
> patches, but can you please supply a changelog that describes the change?
Better ... can we have a test suite for the regexes and make patches to
them include updates to the test suite? They have clearly passed the
point of human understanding ;-)
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 2/2] kernel-doc: Handle function typedefs without asterisks
2020-11-13 22:39 ` Matthew Wilcox
@ 2020-11-17 21:24 ` Eduardo Habkost
2020-11-17 21:30 ` Matthew Wilcox
0 siblings, 1 reply; 17+ messages in thread
From: Eduardo Habkost @ 2020-11-17 21:24 UTC (permalink / raw)
To: Matthew Wilcox; +Cc: Jonathan Corbet, Paolo Bonzini, linux-kernel, linux-doc
On Fri, Nov 13, 2020 at 10:39:12PM +0000, Matthew Wilcox wrote:
> On Fri, Nov 13, 2020 at 03:21:06PM -0700, Jonathan Corbet wrote:
> > On Fri, 30 Oct 2020 15:47:13 +0100
> > Paolo Bonzini <pbonzini@redhat.com> wrote:
> >
> > > From: Eduardo Habkost <ehabkost@redhat.com>
> > >
> > > Example of typedef that was not parsed by kernel-doc:
> > >
> > > typedef void (ObjectUnparent)(Object *obj);
> > >
> > > Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
> > > Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> >
> > So as you've undoubtedly noticed, reading those kernel-doc regexes is ... a
> > wee bit on the painful side. Trying to compare two of them in a patch to
> > figure out what you have done is even worse. I suspect we want these
> > patches, but can you please supply a changelog that describes the change?
>
> Better ... can we have a test suite for the regexes and make patches to
> them include updates to the test suite? They have clearly passed the
> point of human understanding ;-)
Would a simple black box test script like this be desirable?
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
scripts/kernel-doc-test-case.h | 89 ++++++++++++
scripts/kernel-doc-test-case.rst.expected | 167 ++++++++++++++++++++++
scripts/kernel-doc-test.sh | 15 ++
3 files changed, 271 insertions(+)
create mode 100644 scripts/kernel-doc-test-case.h
create mode 100644 scripts/kernel-doc-test-case.rst.expected
create mode 100755 scripts/kernel-doc-test.sh
diff --git a/scripts/kernel-doc-test-case.h b/scripts/kernel-doc-test-case.h
new file mode 100644
index 0000000000000..5cea705d85392
--- /dev/null
+++ b/scripts/kernel-doc-test-case.h
@@ -0,0 +1,89 @@
+/**
+ * DOC: kernel-doc test case
+ *
+ * ``kernel-doc-test-case.h`` contains a series of declarations
+ * and kernel-doc comments. The expected kernel-doc output can be
+ * found at ``kernel-doc-test-case.rst.expected``.
+ */
+
+/**
+ * typedef void_func_ptr - pointer to a function
+ * @a: first argument
+ * @b: second argument
+ */
+typedef void (*void_func_ptr)(int a, struct struct_name1 *b);
+
+/**
+ * typedef int_ptr_func_ptr - a pointer to a function returning a pointer
+ * @a: argument
+ */
+typedef int *(*int_ptr_func_ptr)(int a);
+
+/**
+ * typedef func_par - a function, with parenthesis
+ * @a: argument
+ *
+ * A typedef for a function type (not a function pointer), with
+ * parenthesis around the function name.
+ */
+typedef void (func_par)(int a);
+
+/**
+ * struct struct_name1 - a struct
+ * @i: an int field
+ * @j: an int pointer
+ * @u: an union field
+ * @sptr: pointer to a `struct_name1`
+ *
+ * A simple struct with multiple fields.
+ *
+ * Here's a reference to another struct type: &struct struct_name2.
+ */
+struct struct_name1 {
+ int i, *j;
+ union {
+ int i;
+ const char *s;
+ } u;
+ struct struct_name1 *sptr;
+ /**
+ * @field_with_inline_doc: another way to document struct fields
+ *
+ * This field is documented inside the struct definition,
+ * closer to the field declaration instead the doc comment at
+ * the top.
+ */
+ int field_with_inline_doc;
+ /**
+ * @func: a function pointer
+ *
+ * Parsing a function pointer field involves some tricks to handle
+ * the commas properly.
+ */
+ int (*func)(int x, struct struct_name1 *p);
+ /** @bitmap: a bitmap */
+ DECLARE_BITMAP(bitmap, 128);
+};
+
+/**
+ * struct struct_name2 - another struct
+ * @x: first field
+ * @y: second field
+ * @another: another struct
+ *
+ * This struct is defined inside a typedef declaration.
+ */
+typedef struct struct_name2 {
+ int x, y;
+ struct struct_name1 another;
+} struct_name2;
+
+/**
+ * SOME_MACRO - a macro that takes a few arguments
+ * @a: first argument
+ * @b: second argument
+ */
+#define SOME_MACRO(a, b) \
+ { multi_line_macro_definition(a); \
+ second_line(b); \
+ }
diff --git a/scripts/kernel-doc-test-case.rst.expected b/scripts/kernel-doc-test-case.rst.expected
new file mode 100644
index 0000000000000..4f68931121bb7
--- /dev/null
+++ b/scripts/kernel-doc-test-case.rst.expected
@@ -0,0 +1,167 @@
+**kernel-doc test case**
+
+
+``kernel-doc-test-case.h`` contains a series of declarations
+and kernel-doc comments. The expected kernel-doc output can be
+found at ``kernel-doc-test-case.rst.expected``.
+
+.. c:macro:: void_func_ptr
+
+ **Typedef**: pointer to a function
+
+
+**Syntax**
+
+ ``void void_func_ptr (int a, struct struct_name1 *b)``
+
+**Parameters**
+
+``int a``
+ first argument
+
+``struct struct_name1 *b``
+ second argument
+
+
+.. c:macro:: int_ptr_func_ptr
+
+ **Typedef**: a pointer to a function returning a pointer
+
+
+**Syntax**
+
+ ``int * int_ptr_func_ptr (int a)``
+
+**Parameters**
+
+``int a``
+ argument
+
+
+.. c:macro:: func_par
+
+ **Typedef**: a function, with parenthesis
+
+
+**Syntax**
+
+ ``void func_par (int a)``
+
+**Parameters**
+
+``int a``
+ argument
+
+**Description**
+
+A typedef for a function type (not a function pointer), with
+parenthesis around the function name.
+
+
+
+
+.. c:struct:: struct_name1
+
+ a struct
+
+**Definition**
+
+::
+
+ struct struct_name1 {
+ int i, *j;
+ union {
+ int i;
+ const char *s;
+ } u;
+ struct struct_name1 *sptr;
+ int field_with_inline_doc;
+ int (*func)(int x, struct struct_name1 *p);
+ unsigned long bitmap[BITS_TO_LONGS(128)];
+ };
+
+**Members**
+
+``i``
+ an int field
+
+``j``
+ an int pointer
+
+``u``
+ an union field
+
+``sptr``
+ pointer to a `struct_name1`
+
+``field_with_inline_doc``
+ another way to document struct fields
+
+ This field is documented inside the struct definition,
+ closer to the field declaration instead the doc comment at
+ the top.
+
+``func``
+ a function pointer
+
+ Parsing a function pointer field involves some tricks to handle
+ the commas properly.
+
+``bitmap``
+ a bitmap
+
+
+**Description**
+
+A simple struct with multiple fields.
+
+Here's a reference to another struct type: :c:type:`struct struct_name2 <struct_name2>`.
+
+
+
+
+.. c:struct:: struct_name2
+
+ another struct
+
+**Definition**
+
+::
+
+ struct struct_name2 {
+ int x, y;
+ struct struct_name1 another;
+ };
+
+**Members**
+
+``x``
+ first field
+
+``y``
+ second field
+
+``another``
+ another struct
+
+
+**Description**
+
+This struct is defined inside a typedef declaration.
+
+
+.. c:macro:: SOME_MACRO
+
+``SOME_MACRO (a, b)``
+
+ a macro that takes a few arguments
+
+**Parameters**
+
+``a``
+ first argument
+
+``b``
+ second argument
+
+
diff --git a/scripts/kernel-doc-test.sh b/scripts/kernel-doc-test.sh
new file mode 100755
index 0000000000000..4c96592649451
--- /dev/null
+++ b/scripts/kernel-doc-test.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+set -e
+mydir="$(dirname "$0")"
+kerneldoc="$mydir/kernel-doc"
+
+tmp="$(mktemp -d)"
+trap 'rm -rf "$tmp"' EXIT
+
+"$kerneldoc" -sphinx-version 3.2.1 -rst "$mydir/kernel-doc-test-case.h" > "$tmp/kernel-doc-test-case.rst.actual" 2>&1
+if diff -u "$mydir/kernel-doc-test-case.rst.expected" "$tmp/kernel-doc-test-case.rst.actual";then
+ echo OK
+else
+ echo kernel-doc output mismatch
+ exit 1
+fi
--
2.28.0
--
Eduardo
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH 2/2] kernel-doc: Handle function typedefs without asterisks
2020-11-17 21:24 ` Eduardo Habkost
@ 2020-11-17 21:30 ` Matthew Wilcox
2020-11-17 22:36 ` [RFC] Add kernel-doc test script Eduardo Habkost
0 siblings, 1 reply; 17+ messages in thread
From: Matthew Wilcox @ 2020-11-17 21:30 UTC (permalink / raw)
To: Eduardo Habkost; +Cc: Jonathan Corbet, Paolo Bonzini, linux-kernel, linux-doc
On Tue, Nov 17, 2020 at 04:24:52PM -0500, Eduardo Habkost wrote:
> On Fri, Nov 13, 2020 at 10:39:12PM +0000, Matthew Wilcox wrote:
> > Better ... can we have a test suite for the regexes and make patches to
> > them include updates to the test suite? They have clearly passed the
> > point of human understanding ;-)
>
> Would a simple black box test script like this be desirable?
I think this is fantastic! Yes please!
Can I add one more test case?
/**
* radix_tree_lookup_slot - lookup a slot in a radix tree
* @root: radix tree root
* @index: index key
*
* Returns: the slot corresponding to the position @index in the
* radix tree @root. This is useful for update-if-exists operations.
*
* This function can be called under rcu_read_lock iff the slot is not
* modified by radix_tree_replace_slot(), otherwise it must be called
* exclusive from other writers. Any dereference of the slot must be done
* using radix_tree_deref_slot().
*/
void __rcu **radix_tree_lookup_slot(const struct radix_tree_root *root,
unsigned long index)
{ }
(we used to have a problem with multiple '*' in the return type, and
we've also had problems with adornments like __rcu)
^ permalink raw reply [flat|nested] 17+ messages in thread
* [RFC] Add kernel-doc test script
2020-11-17 21:30 ` Matthew Wilcox
@ 2020-11-17 22:36 ` Eduardo Habkost
2020-11-18 0:23 ` Randy Dunlap
` (2 more replies)
0 siblings, 3 replies; 17+ messages in thread
From: Eduardo Habkost @ 2020-11-17 22:36 UTC (permalink / raw)
To: Matthew Wilcox; +Cc: Jonathan Corbet, Paolo Bonzini, linux-kernel, linux-doc
Add a kernel-doc test script to tools/testing/kernel-doc.
radix_tree_lookup_slot test case provided by Matthew Wilcox.
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
tools/testing/kernel-doc/test-case.h | 111 ++++++++++
.../testing/kernel-doc/test-case.man.expected | 150 ++++++++++++++
.../kernel-doc/test-case.none.expected | 0
.../kernel-doc/test-case.rst2.expected | 195 ++++++++++++++++++
.../kernel-doc/test-case.rst3.expected | 195 ++++++++++++++++++
tools/testing/kernel-doc/test.sh | 90 ++++++++
6 files changed, 741 insertions(+)
create mode 100644 tools/testing/kernel-doc/test-case.h
create mode 100644 tools/testing/kernel-doc/test-case.man.expected
create mode 100644 tools/testing/kernel-doc/test-case.none.expected
create mode 100644 tools/testing/kernel-doc/test-case.rst2.expected
create mode 100644 tools/testing/kernel-doc/test-case.rst3.expected
create mode 100755 tools/testing/kernel-doc/test.sh
diff --git a/tools/testing/kernel-doc/test-case.h b/tools/testing/kernel-doc/test-case.h
new file mode 100644
index 0000000000000..6d4e1f6b99631
--- /dev/null
+++ b/tools/testing/kernel-doc/test-case.h
@@ -0,0 +1,111 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/**
+ * DOC: kernel-doc test case
+ *
+ * ``test-case.h`` contains a series of declarations and
+ * kernel-doc comments. The expected kernel-doc output can be
+ * found at ``test-case.rst.expected``.
+ */
+
+/**
+ * typedef void_func_ptr - pointer to a function
+ * @a: first argument
+ * @b: second argument
+ */
+typedef void (*void_func_ptr)(int a, struct struct_name1 *b);
+
+/**
+ * typedef int_ptr_func_ptr - a pointer to a function returning a pointer
+ * @a: argument
+ */
+typedef int *(*int_ptr_func_ptr)(int a);
+
+/**
+ * typedef func_par - a function, with parenthesis
+ * @a: argument
+ *
+ * A typedef for a function type (not a function pointer), wit
+ * parenthesis around the function name.
+ */
+typedef void (func_par)(int a);
+
+/**
+ * struct struct_name1 - a struct
+ * @i: an int field
+ * @j: an int pointer
+ * @u: a union field
+ * @sptr: pointer to a `struct_name1`
+ *
+ * A simple struct with multiple fields.
+ *
+ * Here's a reference to another struct type: &struct struct_name2.
+ */
+struct struct_name1 {
+ int i, *j;
+ union {
+ int i;
+ const char *s;
+ } u;
+ struct struct_name1 *sptr;
+ /**
+ * @field_with_inline_doc: another way to document struct fields
+ *
+ * This field is documented inside the struct definition,
+ * closer to the field declaration instead the doc comment at
+ * the top.
+ */
+ int field_with_inline_doc;
+ /**
+ * @func: a function pointer
+ *
+ * Parsing a function pointer field involves some tricks to handle
+ * the commas properly.
+ */
+ int (*func)(int x, struct struct_name1 *p);
+ /** @bitmap: a bitmap */
+ DECLARE_BITMAP(bitmap, 128);
+};
+
+/**
+ * struct struct_name2 - another struct
+ * @x: first field
+ * @y: second field
+ * @another: another struct
+ *
+ * This struct is defined inside a typedef declaration.
+ */
+typedef struct struct_name2 {
+ int x, y;
+ struct struct_name1 another;
+} struct_name2;
+
+/**
+ * radix_tree_lookup_slot - lookup a slot in a radix tree
+ * @root: radix tree root
+ * @index: index key
+ *
+ * Returns: the slot corresponding to the position @index in the
+ * radix tree @root. This is useful for update-if-exists operations.
+ *
+ * This function can be called under rcu_read_lock iff the slot is not
+ * modified by radix_tree_replace_slot(), otherwise it must be called
+ * exclusive from other writers. Any dereference of the slot must be done
+ * using radix_tree_deref_slot().
+ *
+ * We used to have a problem with multiple ``*`` in the return type, and
+ * we've also had problems with adornments like __rcu).
+ */
+void __rcu **radix_tree_lookup_slot(const struct radix_tree_root *root,
+ unsigned long index)
+{ }
+
+/**
+ * SOME_MACRO - a macro that takes a few arguments
+ * @a: first argument
+ * @b: second argument
+ */
+#define SOME_MACRO(a, b) \
+ { multi_line_macro_definition(a); \
+ second_line(b); \
+ }
diff --git a/tools/testing/kernel-doc/test-case.man.expected b/tools/testing/kernel-doc/test-case.man.expected
new file mode 100644
index 0000000000000..6be2583469f04
--- /dev/null
+++ b/tools/testing/kernel-doc/test-case.man.expected
@@ -0,0 +1,150 @@
+.TH "Kernel API" 9 "Kernel API" "August 1991" "API Manual" LINUX
+.SH "kernel-doc test case"
+``test-case.h contains a series of declarations and
+kernel-doc comments. The expected kernel-doc output can be
+found at test-case.rst.expected``.
+.TH "void_func_ptr" 9 "void_func_ptr" "August 1991" "Kernel Hacker's Manual" LINUX
+.SH NAME
+void_func_ptr \- pointer to a function
+.SH SYNOPSIS
+.B "void" void_func_ptr
+.BI "(int a " ","
+.BI "struct struct_name1 *b " ");"
+.SH ARGUMENTS
+.IP "a" 12
+first argument
+.IP "b" 12
+second argument
+.TH "int_ptr_func_ptr" 9 "int_ptr_func_ptr" "August 1991" "Kernel Hacker's Manual" LINUX
+.SH NAME
+int_ptr_func_ptr \- a pointer to a function returning a pointer
+.SH SYNOPSIS
+.B "int *" int_ptr_func_ptr
+.BI "(int a " ");"
+.SH ARGUMENTS
+.IP "a" 12
+argument
+.TH "func_par" 9 "func_par" "August 1991" "Kernel Hacker's Manual" LINUX
+.SH NAME
+func_par \- a function, with parenthesis
+.SH SYNOPSIS
+.B "void" func_par
+.BI "(int a " ");"
+.SH ARGUMENTS
+.IP "a" 12
+argument
+.SH "DESCRIPTION"
+A typedef for a function type (not a function pointer), wit
+parenthesis around the function name.
+.TH "Kernel API" 9 "struct struct_name1" "August 1991" "API Manual" LINUX
+.SH NAME
+struct struct_name1 \- a struct
+.SH SYNOPSIS
+struct struct_name1 {
+.br
+.BI " int i, *j;"
+.br
+.BI " union {"
+.br
+.BI " int i;"
+.br
+.BI " const char *s;"
+.br
+.BI " } u;"
+.br
+.BI " struct struct_name1 *sptr;"
+.br
+.BI " int field_with_inline_doc;"
+.br
+.BI " int (*func)(int x, struct struct_name1 *p);"
+.br
+.BI " unsigned long bitmap[BITS_TO_LONGS(128)];"
+.br
+.BI "
+};
+.br
+
+.SH Members
+.IP "i" 12
+an int field
+.IP "j" 12
+an int pointer
+.IP "u" 12
+a union field
+.IP "sptr" 12
+pointer to a `struct_name1`
+.IP "field_with_inline_doc" 12
+another way to document struct fields
+
+This field is documented inside the struct definition,
+closer to the field declaration instead the doc comment at
+the top.
+.IP "func" 12
+a function pointer
+
+Parsing a function pointer field involves some tricks to handle
+the commas properly.
+.IP "bitmap" 12
+a bitmap
+.SH "Description"
+A simple struct with multiple fields.
+
+Here's a reference to another struct type: \fIstruct struct_name2\fP.
+.TH "Kernel API" 9 "struct struct_name2" "August 1991" "API Manual" LINUX
+.SH NAME
+struct struct_name2 \- another struct
+.SH SYNOPSIS
+struct struct_name2 {
+.br
+.BI " int x, y;"
+.br
+.BI " struct struct_name1 another;"
+.br
+.BI "
+};
+.br
+
+.SH Members
+.IP "x" 12
+first field
+.IP "y" 12
+second field
+.IP "another" 12
+another struct
+.SH "Description"
+This struct is defined inside a typedef declaration.
+.TH "radix_tree_lookup_slot" 9 "radix_tree_lookup_slot" "August 1991" "Kernel Hacker's Manual" LINUX
+.SH NAME
+radix_tree_lookup_slot \- lookup a slot in a radix tree
+.SH SYNOPSIS
+.B "void __rcu **" radix_tree_lookup_slot
+.BI "(const struct radix_tree_root *root " ","
+.BI "unsigned long index " ");"
+.SH ARGUMENTS
+.IP "root" 12
+radix tree root
+.IP "index" 12
+index key
+.SH "RETURN"
+the slot corresponding to the position \fIindex\fP in the
+radix tree \fIroot\fP. This is useful for update-if-exists operations.
+.SH "DESCRIPTION"
+This function can be called under rcu_read_lock iff the slot is not
+modified by \fBradix_tree_replace_slot\fP, otherwise it must be called
+exclusive from other writers. Any dereference of the slot must be done
+using \fBradix_tree_deref_slot\fP.
+
+We used to have a problem with multiple ``*`` in the return type, and
+we've also had problems with adornments like __rcu).
+.TH "SOME_MACRO" 9 "SOME_MACRO" "August 1991" "Kernel Hacker's Manual" LINUX
+.SH NAME
+SOME_MACRO \- a macro that takes a few arguments
+.SH SYNOPSIS
+.B "SOME_MACRO
+.BI "(a " ","
+.BI "b " ");"
+.SH ARGUMENTS
+.IP "a" 12
+first argument
+.IP "b" 12
+second argument
diff --git a/tools/testing/kernel-doc/test-case.none.expected b/tools/testing/kernel-doc/test-case.none.expected
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/tools/testing/kernel-doc/test-case.rst2.expected b/tools/testing/kernel-doc/test-case.rst2.expected
new file mode 100644
index 0000000000000..66ae737a808f2
--- /dev/null
+++ b/tools/testing/kernel-doc/test-case.rst2.expected
@@ -0,0 +1,195 @@
+**kernel-doc test case**
+
+
+``test-case.h`` contains a series of declarations and
+kernel-doc comments. The expected kernel-doc output can be
+found at ``test-case.rst.expected``.
+
+.. c:macro:: void_func_ptr
+
+ **Typedef**: pointer to a function
+
+
+**Syntax**
+
+ ``void void_func_ptr (int a, struct struct_name1 *b)``
+
+**Parameters**
+
+``int a``
+ first argument
+
+``struct struct_name1 *b``
+ second argument
+
+
+.. c:macro:: int_ptr_func_ptr
+
+ **Typedef**: a pointer to a function returning a pointer
+
+
+**Syntax**
+
+ ``int * int_ptr_func_ptr (int a)``
+
+**Parameters**
+
+``int a``
+ argument
+
+
+.. c:macro:: func_par
+
+ **Typedef**: a function, with parenthesis
+
+
+**Syntax**
+
+ ``void func_par (int a)``
+
+**Parameters**
+
+``int a``
+ argument
+
+**Description**
+
+A typedef for a function type (not a function pointer), wit
+parenthesis around the function name.
+
+
+
+
+.. c:struct:: struct_name1
+
+ a struct
+
+**Definition**
+
+::
+
+ struct struct_name1 {
+ int i, *j;
+ union {
+ int i;
+ const char *s;
+ } u;
+ struct struct_name1 *sptr;
+ int field_with_inline_doc;
+ int (*func)(int x, struct struct_name1 *p);
+ unsigned long bitmap[BITS_TO_LONGS(128)];
+ };
+
+**Members**
+
+``i``
+ an int field
+
+``j``
+ an int pointer
+
+``u``
+ a union field
+
+``sptr``
+ pointer to a `struct_name1`
+
+``field_with_inline_doc``
+ another way to document struct fields
+
+ This field is documented inside the struct definition,
+ closer to the field declaration instead the doc comment at
+ the top.
+
+``func``
+ a function pointer
+
+ Parsing a function pointer field involves some tricks to handle
+ the commas properly.
+
+``bitmap``
+ a bitmap
+
+
+**Description**
+
+A simple struct with multiple fields.
+
+Here's a reference to another struct type: :c:type:`struct struct_name2 <struct_name2>`.
+
+
+
+
+.. c:struct:: struct_name2
+
+ another struct
+
+**Definition**
+
+::
+
+ struct struct_name2 {
+ int x, y;
+ struct struct_name1 another;
+ };
+
+**Members**
+
+``x``
+ first field
+
+``y``
+ second field
+
+``another``
+ another struct
+
+
+**Description**
+
+This struct is defined inside a typedef declaration.
+
+
+.. c:function:: void __rcu ** radix_tree_lookup_slot (const struct radix_tree_root *root, unsigned long index)
+
+ lookup a slot in a radix tree
+
+**Parameters**
+
+``const struct radix_tree_root *root``
+ radix tree root
+
+``unsigned long index``
+ index key
+
+**Return**
+
+the slot corresponding to the position **index** in the
+radix tree **root**. This is useful for update-if-exists operations.
+
+**Description**
+
+This function can be called under rcu_read_lock iff the slot is not
+modified by radix_tree_replace_slot(), otherwise it must be called
+exclusive from other writers. Any dereference of the slot must be done
+using radix_tree_deref_slot().
+
+We used to have a problem with multiple ``*`` in the return type, and
+we've also had problems with adornments like __rcu).
+
+
+.. c:macro:: SOME_MACRO
+
+``SOME_MACRO (a, b)``
+
+ a macro that takes a few arguments
+
+**Parameters**
+
+``a``
+ first argument
+
+``b``
+ second argument
+
+
diff --git a/tools/testing/kernel-doc/test-case.rst3.expected b/tools/testing/kernel-doc/test-case.rst3.expected
new file mode 100644
index 0000000000000..66ae737a808f2
--- /dev/null
+++ b/tools/testing/kernel-doc/test-case.rst3.expected
@@ -0,0 +1,195 @@
+**kernel-doc test case**
+
+
+``test-case.h`` contains a series of declarations and
+kernel-doc comments. The expected kernel-doc output can be
+found at ``test-case.rst.expected``.
+
+.. c:macro:: void_func_ptr
+
+ **Typedef**: pointer to a function
+
+
+**Syntax**
+
+ ``void void_func_ptr (int a, struct struct_name1 *b)``
+
+**Parameters**
+
+``int a``
+ first argument
+
+``struct struct_name1 *b``
+ second argument
+
+
+.. c:macro:: int_ptr_func_ptr
+
+ **Typedef**: a pointer to a function returning a pointer
+
+
+**Syntax**
+
+ ``int * int_ptr_func_ptr (int a)``
+
+**Parameters**
+
+``int a``
+ argument
+
+
+.. c:macro:: func_par
+
+ **Typedef**: a function, with parenthesis
+
+
+**Syntax**
+
+ ``void func_par (int a)``
+
+**Parameters**
+
+``int a``
+ argument
+
+**Description**
+
+A typedef for a function type (not a function pointer), wit
+parenthesis around the function name.
+
+
+
+
+.. c:struct:: struct_name1
+
+ a struct
+
+**Definition**
+
+::
+
+ struct struct_name1 {
+ int i, *j;
+ union {
+ int i;
+ const char *s;
+ } u;
+ struct struct_name1 *sptr;
+ int field_with_inline_doc;
+ int (*func)(int x, struct struct_name1 *p);
+ unsigned long bitmap[BITS_TO_LONGS(128)];
+ };
+
+**Members**
+
+``i``
+ an int field
+
+``j``
+ an int pointer
+
+``u``
+ a union field
+
+``sptr``
+ pointer to a `struct_name1`
+
+``field_with_inline_doc``
+ another way to document struct fields
+
+ This field is documented inside the struct definition,
+ closer to the field declaration instead the doc comment at
+ the top.
+
+``func``
+ a function pointer
+
+ Parsing a function pointer field involves some tricks to handle
+ the commas properly.
+
+``bitmap``
+ a bitmap
+
+
+**Description**
+
+A simple struct with multiple fields.
+
+Here's a reference to another struct type: :c:type:`struct struct_name2 <struct_name2>`.
+
+
+
+
+.. c:struct:: struct_name2
+
+ another struct
+
+**Definition**
+
+::
+
+ struct struct_name2 {
+ int x, y;
+ struct struct_name1 another;
+ };
+
+**Members**
+
+``x``
+ first field
+
+``y``
+ second field
+
+``another``
+ another struct
+
+
+**Description**
+
+This struct is defined inside a typedef declaration.
+
+
+.. c:function:: void __rcu ** radix_tree_lookup_slot (const struct radix_tree_root *root, unsigned long index)
+
+ lookup a slot in a radix tree
+
+**Parameters**
+
+``const struct radix_tree_root *root``
+ radix tree root
+
+``unsigned long index``
+ index key
+
+**Return**
+
+the slot corresponding to the position **index** in the
+radix tree **root**. This is useful for update-if-exists operations.
+
+**Description**
+
+This function can be called under rcu_read_lock iff the slot is not
+modified by radix_tree_replace_slot(), otherwise it must be called
+exclusive from other writers. Any dereference of the slot must be done
+using radix_tree_deref_slot().
+
+We used to have a problem with multiple ``*`` in the return type, and
+we've also had problems with adornments like __rcu).
+
+
+.. c:macro:: SOME_MACRO
+
+``SOME_MACRO (a, b)``
+
+ a macro that takes a few arguments
+
+**Parameters**
+
+``a``
+ first argument
+
+``b``
+ second argument
+
+
diff --git a/tools/testing/kernel-doc/test.sh b/tools/testing/kernel-doc/test.sh
new file mode 100755
index 0000000000000..37042c5453823
--- /dev/null
+++ b/tools/testing/kernel-doc/test.sh
@@ -0,0 +1,90 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2020, Red Hat Inc.
+# Author: Eduardo Habkost <ehabkost@redhat.com>
+#
+# Black box test script for kernel-doc
+
+set -e
+mydir="$(dirname "$0")"
+
+usage()
+{
+ echo "Usage: $0 [--refresh] [--kernel-doc KERNELDOC_BINARY]"
+}
+
+refresh=no
+kerneldoc="$mydir/../../../scripts/kernel-doc"
+while [ "$#" -gt 0 ];do
+ case "$1" in
+ -h|--help)
+ usage
+ exit 0
+ ;;
+ --refresh)
+ refresh=yes
+ shift
+ ;;
+ --kernel-doc)
+ shift
+ kerneldoc="$1"
+ shift
+ ;;
+ *)
+ echo "Invalid argument: $1" >&2
+ usage >&2
+ exit 1
+ ;;
+ esac
+done
+
+tmp="$(mktemp -d)"
+trap 'rm -rf "$tmp"' EXIT
+
+test()
+{
+ local suffix="$1"
+ shift
+
+ if ! "$kerneldoc" "$@" "$mydir/test-case.h" \
+ > "$tmp/test-case.$suffix.actual" \
+ 2> "$tmp/test-case.$suffix.stderr" || \
+ [ -s "$tmp/test-case.$suffix.stderr" ];then
+ cat "$tmp/test-case.$suffix.stderr" >&2
+ echo "$suffix: kernel-doc $* failed" >&2
+ return 1
+ fi
+
+ if diff -u "$mydir/test-case.$suffix.expected" \
+ "$tmp/test-case.$suffix.actual";then
+ echo "$suffix: OK" >&2
+ else
+ echo "kernel-doc output mismatch for: $*" >&2
+ if [ "$refresh" = yes ];then
+ cp "$tmp/test-case.$suffix.actual" \
+ "$mydir/test-case.$suffix.expected"
+ fi
+ return 1
+ fi
+}
+
+if [ ! -x "$kerneldoc" ];then
+ echo "kernel-doc is not executable: $kerneldoc" >&2
+ exit 1
+fi
+
+# the -man output includes the build date
+export KBUILD_BUILD_TIMESTAMP=1991-08-25
+
+ok=yes
+
+# don't even try to test other formats if -none fails:
+test none -none || exit 1
+
+test rst2 -rst -sphinx-version 3.0.0 || ok=no
+test rst3 -rst -sphinx-version 3.0.0 || ok=no
+test man -man || ok=no
+
+if [ "$ok" != "yes" ];then
+ exit 1
+fi
--
2.28.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [RFC] Add kernel-doc test script
2020-11-17 22:36 ` [RFC] Add kernel-doc test script Eduardo Habkost
@ 2020-11-18 0:23 ` Randy Dunlap
2020-11-18 13:03 ` Eduardo Habkost
2020-11-18 8:21 ` Paolo Bonzini
2020-11-18 16:27 ` Jonathan Corbet
2 siblings, 1 reply; 17+ messages in thread
From: Randy Dunlap @ 2020-11-18 0:23 UTC (permalink / raw)
To: Eduardo Habkost, Matthew Wilcox
Cc: Jonathan Corbet, Paolo Bonzini, linux-kernel, linux-doc
On 11/17/20 2:36 PM, Eduardo Habkost wrote:
> Add a kernel-doc test script to tools/testing/kernel-doc.
>
> radix_tree_lookup_slot test case provided by Matthew Wilcox.
>
> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Very good idea.
I have had a kernel-doc test source file for (?) 10-12 years,
while I was the docs maintainer.
I didn't have the "expected" files for comparison.
I just used $web_browser.
> ---
> tools/testing/kernel-doc/test-case.h | 111 ++++++++++
> .../testing/kernel-doc/test-case.man.expected | 150 ++++++++++++++
> .../kernel-doc/test-case.none.expected | 0
> .../kernel-doc/test-case.rst2.expected | 195 ++++++++++++++++++
> .../kernel-doc/test-case.rst3.expected | 195 ++++++++++++++++++
> tools/testing/kernel-doc/test.sh | 90 ++++++++
> 6 files changed, 741 insertions(+)
> create mode 100644 tools/testing/kernel-doc/test-case.h
> create mode 100644 tools/testing/kernel-doc/test-case.man.expected
> create mode 100644 tools/testing/kernel-doc/test-case.none.expected
> create mode 100644 tools/testing/kernel-doc/test-case.rst2.expected
> create mode 100644 tools/testing/kernel-doc/test-case.rst3.expected
> create mode 100755 tools/testing/kernel-doc/test.sh
thanks.
--
~Randy
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [RFC] Add kernel-doc test script
2020-11-17 22:36 ` [RFC] Add kernel-doc test script Eduardo Habkost
2020-11-18 0:23 ` Randy Dunlap
@ 2020-11-18 8:21 ` Paolo Bonzini
2020-11-18 12:05 ` Eduardo Habkost
2020-11-18 16:27 ` Jonathan Corbet
2 siblings, 1 reply; 17+ messages in thread
From: Paolo Bonzini @ 2020-11-18 8:21 UTC (permalink / raw)
To: Eduardo Habkost, Matthew Wilcox; +Cc: Jonathan Corbet, linux-kernel, linux-doc
On 17/11/20 23:36, Eduardo Habkost wrote:
> +# the -man output includes the build date
> +export KBUILD_BUILD_TIMESTAMP=1991-08-25
Nice :)
> +ok=yes
> +
> +# don't even try to test other formats if -none fails:
> +test none -none || exit 1
> +
> +test rst2 -rst -sphinx-version 3.0.0 || ok=no
Do you want 3.0.0 here too?
> +test rst3 -rst -sphinx-version 3.0.0 || ok=no
> +test man -man || ok=no
Also since you are at it you might as well rename the function to
something other than "test", it's a bit confusing due to the "test"
shell builtin.
Paolo
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [RFC] Add kernel-doc test script
2020-11-18 8:21 ` Paolo Bonzini
@ 2020-11-18 12:05 ` Eduardo Habkost
0 siblings, 0 replies; 17+ messages in thread
From: Eduardo Habkost @ 2020-11-18 12:05 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: Matthew Wilcox, Jonathan Corbet, linux-kernel, linux-doc
On Wed, Nov 18, 2020 at 09:21:11AM +0100, Paolo Bonzini wrote:
> On 17/11/20 23:36, Eduardo Habkost wrote:
> > +# the -man output includes the build date
> > +export KBUILD_BUILD_TIMESTAMP=1991-08-25
>
> Nice :)
>
> > +ok=yes
> > +
> > +# don't even try to test other formats if -none fails:
> > +test none -none || exit 1
> > +
> > +test rst2 -rst -sphinx-version 3.0.0 || ok=no
>
> Do you want 3.0.0 here too?
Oops! No! I'll fix it.
>
> > +test rst3 -rst -sphinx-version 3.0.0 || ok=no
> > +test man -man || ok=no
>
> Also since you are at it you might as well rename the function to something
> other than "test", it's a bit confusing due to the "test" shell builtin.
Good point. I'll do.
--
Eduardo
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [RFC] Add kernel-doc test script
2020-11-18 0:23 ` Randy Dunlap
@ 2020-11-18 13:03 ` Eduardo Habkost
2020-11-18 16:32 ` Randy Dunlap
0 siblings, 1 reply; 17+ messages in thread
From: Eduardo Habkost @ 2020-11-18 13:03 UTC (permalink / raw)
To: Randy Dunlap
Cc: Matthew Wilcox, Jonathan Corbet, Paolo Bonzini, linux-kernel, linux-doc
On Tue, Nov 17, 2020 at 04:23:49PM -0800, Randy Dunlap wrote:
> On 11/17/20 2:36 PM, Eduardo Habkost wrote:
> > Add a kernel-doc test script to tools/testing/kernel-doc.
> >
> > radix_tree_lookup_slot test case provided by Matthew Wilcox.
> >
> > Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
>
> Very good idea.
>
> I have had a kernel-doc test source file for (?) 10-12 years,
> while I was the docs maintainer.
Is that test source file recoverable somewhere? It probably has
useful test cases not included here.
--
Eduardo
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [RFC] Add kernel-doc test script
2020-11-17 22:36 ` [RFC] Add kernel-doc test script Eduardo Habkost
2020-11-18 0:23 ` Randy Dunlap
2020-11-18 8:21 ` Paolo Bonzini
@ 2020-11-18 16:27 ` Jonathan Corbet
2 siblings, 0 replies; 17+ messages in thread
From: Jonathan Corbet @ 2020-11-18 16:27 UTC (permalink / raw)
To: Eduardo Habkost; +Cc: Matthew Wilcox, Paolo Bonzini, linux-kernel, linux-doc
On Tue, 17 Nov 2020 17:36:12 -0500
Eduardo Habkost <ehabkost@redhat.com> wrote:
> Add a kernel-doc test script to tools/testing/kernel-doc.
>
> radix_tree_lookup_slot test case provided by Matthew Wilcox.
>
> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
> ---
> tools/testing/kernel-doc/test-case.h | 111 ++++++++++
> .../testing/kernel-doc/test-case.man.expected | 150 ++++++++++++++
> .../kernel-doc/test-case.none.expected | 0
> .../kernel-doc/test-case.rst2.expected | 195 ++++++++++++++++++
> .../kernel-doc/test-case.rst3.expected | 195 ++++++++++++++++++
> tools/testing/kernel-doc/test.sh | 90 ++++++++
> 6 files changed, 741 insertions(+)
> create mode 100644 tools/testing/kernel-doc/test-case.h
> create mode 100644 tools/testing/kernel-doc/test-case.man.expected
> create mode 100644 tools/testing/kernel-doc/test-case.none.expected
> create mode 100644 tools/testing/kernel-doc/test-case.rst2.expected
> create mode 100644 tools/testing/kernel-doc/test-case.rst3.expected
> create mode 100755 tools/testing/kernel-doc/test.sh
Seems like a good thing to have overall.
I do worry a bit that the test will be sensitive to *any* change to
kernel-doc output, including formatting changes that might be deliberate.
But if that turns out to be a problem in the real world, we can deal with
it then.
Thanks,
jon
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [RFC] Add kernel-doc test script
2020-11-18 13:03 ` Eduardo Habkost
@ 2020-11-18 16:32 ` Randy Dunlap
2020-11-18 16:57 ` Eduardo Habkost
0 siblings, 1 reply; 17+ messages in thread
From: Randy Dunlap @ 2020-11-18 16:32 UTC (permalink / raw)
To: Eduardo Habkost
Cc: Matthew Wilcox, Jonathan Corbet, Paolo Bonzini, linux-kernel, linux-doc
[-- Attachment #1: Type: text/plain, Size: 749 bytes --]
On 11/18/20 5:03 AM, Eduardo Habkost wrote:
> On Tue, Nov 17, 2020 at 04:23:49PM -0800, Randy Dunlap wrote:
>> On 11/17/20 2:36 PM, Eduardo Habkost wrote:
>>> Add a kernel-doc test script to tools/testing/kernel-doc.
>>>
>>> radix_tree_lookup_slot test case provided by Matthew Wilcox.
>>>
>>> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
>>
>> Very good idea.
>>
>> I have had a kernel-doc test source file for (?) 10-12 years,
>> while I was the docs maintainer.
>
> Is that test source file recoverable somewhere? It probably has
> useful test cases not included here.
Sure. Of course, it may be out of date by quite a bit.
I last updated it in 2016:
-rw-r--r-- 1 rdunlap users 41737 Jun 17 2016 megatest.c
(attached)
--
~Randy
[-- Attachment #2: megatest.c --]
[-- Type: text/x-csrc, Size: 41737 bytes --]
/**
* struct my_struct - short description
* @a: first member
* @b: second member
*
* Longer description
*/
struct my_struct {
int a;
int b;
/* private: */
int c;
};
struct scan_channel;
/**
* struct scan_params - describes scan parameters
* @n_channels: number of items in @channels array or -1 to indicate all
* channels should be scanned (in that case @channels will be %NULL)
* @active: when n_channels is -1 this determines active/passive scanning.
* @phymode: when n_channels is -1 this determines PHY mode to scan. It is
* not possible to scan different PHY modes in one request w/o giving
* a channel list.
* @channels: array containing @n_channels &scan_channel items
*/
struct scan_params {
int n_channels;
int active;
int phymode;
struct scan_channel *channels;
};
/**
* typedef __kernel_fd_set - set of file descriptor bits
* @fds_bits: bitmask for all file descriptors, used in poll/select
*/
typedef struct {
unsigned long fds_bits [__FDSET_LONGS]; // what prints this out?
} __kernel_fd_set;
/**
* typedef __kernel_sighandler_t - Type of a signal handler.
*/
typedef void (*__kernel_sighandler_t)(int);
/**
* typedef __kernel_key_t - Type of a SYSV IPC key.
*/
typedef int __kernel_key_t;
/**
* typedef cpumask_var_t - type of a struct cpumask on-stack array
*/
typedef struct cpumask cpumask_var_t[1];
/**
* typedef note_buf_t - type for kexec kernel crash note buffer
*/
typedef u32 note_buf_t[KEXEC_NOTE_BYTES/4];
/**
* typedef nfs4_verifier - struct for NFS4 verifier data
*/
typedef struct { char data[NFS4_VERIFIER_SIZE]; } nfs4_verifier;
/**
* typedef match_table_t - type for file options parser match_token table
*/
typedef struct match_token match_table_t[];
/**
* struct acpi_interrupt_flags - with bitfields
* @polarity: active high or active low
* @trigger: edge or level triggered
* @reserved: not used
*/
struct acpi_interrupt_flags {
u16 polarity:2;
u16 trigger:2;
u16 reserved:12;
} __attribute__ ((packed));
/**
* typedef phys_drive_t - physical device information
* @type : Type of the device
* @cur_status : current status of the device
* @tag_depth : Level of tagging
* @sync_neg : sync negotiation - ENABLE or DISBALE
* @size : configurable size in terms of 512 byte
*/
typedef struct {
uint8_t type;
uint8_t cur_status;
uint8_t tag_depth;
uint8_t sync_neg;
uint32_t size;
}__attribute__ ((packed)) phys_drive_t;
/**
* mraid_mm_open - open routine for char node interface
* @inode : unused, but never the same as &filep
* @filep : unused, but never the same as &inodep
*
* Allow ioctl operations by apps only if they have superuser privilege.
* Returns %0 on success, -%EACCES on error.
* Never uses $ENV variables.
*/
static int // strip C99-comment
mraid_mm_open(struct inode *inode, struct file *filep)
// drop entire line
{
}
/**
* megaraid_queue_command - generic queue entry point for all LLDs
* @scp : pointer to the scsi command to be executed
* @done : callback routine to be called after the cmd has be completed
*
* Queue entry point for mailbox based controllers.
*/
static int
megaraid_queue_command(struct scsi_cmnd *scp, void (* done)(struct scsi_cmnd *))
{
}
struct sub_channels {
unsigned int flags;
int max_size;
int cur_size;
};
/**
* struct channels - struct for testing kernel-doc
* @n_sub_channels: number of &struct sub_channels pointers included
* @flags: flags for all channels
* @reserved: not yet used
* @sub_channels: the sub-channels
*/
struct channels {
int n_sub_channels;
unsigned int flags;
int reserved;
struct sub_channels *sub_channels;
};
/**
* clk_get - lookup and obtain a reference to a clock producer.
* @dev: device for clock "consumer"
* @id: clock consumer ID
*
* Returns a &struct clk corresponding to the clock producer, or
* valid IS_ERR() condition containing errno. The implementation
* uses @dev and @id to determine the clock consumer, and thereby
* the clock producer. (IOW, @id may be identical strings, but
* clk_get may return different clock producers depending on @dev.)
*
* Drivers must assume that the clock source is not enabled.
*
* Returns %NULL if a reference is not obtained. (for kernel-doc testing only.)
* However, if $CLKTEST is non-%NULL, some random value is returned.
*/
struct clk *clk_get(struct device *dev, const char *id);
/**
* struct sk_buff - socket buffer
* @next: Next buffer in list
* @prev: Previous buffer in list
* @sk: Socket we are owned by
* @tstamp: Time we arrived
* @dev: Device we arrived on/are leaving by
* @iif: ifindex of device we arrived on
* @transport_header: Transport layer header
* @network_header: Network layer header
* @mac_header: Link layer header
* @dst: destination entry
* @sp: the security path, used for xfrm
* @cb: Control buffer. Free for use by every layer. Put private vars here
* @len: Length of actual data
* @data_len: Data length
* @mac_len: Length of link layer header
* @csum: Checksum (must include start/offset pair)
* @csum_start: Offset from skb->head where checksumming should start
* @csum_offset: Offset from csum_start where checksum should be stored
* @local_df: allow local fragmentation
* @cloned: Head may be cloned (check refcnt to be sure)
* @nohdr: Payload reference only, must not modify header
* @pkt_type: Packet class
* @fclone: skbuff clone status
* @ip_summed: Driver fed us an IP checksum
* @priority: Packet queueing priority
* @users: User count - see {datagram,tcp}.c
* @protocol: Packet protocol from driver
* @truesize: Buffer size
* @head: Head of buffer
* @data: Data head pointer
* @tail: Tail pointer
* @end: End pointer
* @destructor: Destruct function
* @mark: Generic packet mark
* @nfct: Associated connection, if any
* @ipvs_property: skbuff is owned by ipvs
* @nfctinfo: Relationship of this skb to the connection
* @nfct_reasm: netfilter conntrack re-assembly pointer
* @nf_bridge: Saved data about a bridged frame - see br_netfilter.c
* @tc_index: Traffic control index
* @tc_verd: traffic control verdict
* @dma_cookie: a cookie to one of several possible DMA operations
* done by skb DMA functions
* @secmark: security marking
*/
struct sk_buff {
/* These two members must be first. */
struct sk_buff *next;
struct sk_buff *prev;
struct sock *sk;
ktime_t tstamp;
struct net_device *dev;
int iif;
/* 4 byte hole on 64 bit*/
struct dst_entry *dst;
struct sec_path *sp;
/*
* This is the control buffer. It is free to use for every
* layer. Please put your private variables there. If you
* want to keep them across layers you have to do a skb_clone()
* first. This is owned by whoever has the skb queued ATM.
*/
char cb[48];
unsigned int len,
data_len,
mac_len;
union { // fields inside structs/unions are not listed
__wsum csum;
struct {
__u16 csum_start;
__u16 csum_offset;
};
};
__u32 priority;
__u8 local_df:1,
cloned:1,
ip_summed:2,
nohdr:1,
nfctinfo:3;
__u8 pkt_type:3,
fclone:2,
ipvs_property:1;
__be16 protocol;
void (*destructor)(struct sk_buff *skb);
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
struct nf_conntrack *nfct;
struct sk_buff *nfct_reasm;
#endif
#ifdef CONFIG_BRIDGE_NETFILTER
struct nf_bridge_info *nf_bridge;
#endif
#ifdef CONFIG_NET_SCHED
__u16 tc_index; /* traffic control index */
#ifdef CONFIG_NET_CLS_ACT
__u16 tc_verd; /* traffic control verdict */
#endif
#endif
#ifdef CONFIG_NET_DMA
dma_cookie_t dma_cookie;
#endif
#ifdef CONFIG_NETWORK_SECMARK
__u32 secmark;
#endif
__u32 mark;
// layers headers:
sk_buff_data_t transport_header;
sk_buff_data_t network_header;
sk_buff_data_t mac_header;
/* These elements must be at the end, see alloc_skb() for details. */
sk_buff_data_t tail;
sk_buff_data_t end;
unsigned char *head,
*data;
unsigned int truesize;
atomic_t users;
};
/**
* struct anon_test - test anon struct/union ending lines
* @last_field: last field in the struct
*/
struct anon_test {
union { // fields inside structs/unions are not listed
__wsum csum;
__wsum zeta;
__u32 beta;
};
int last_field;
};
/**
* struct anon_test2 - test anon struct/union ending lines
* @some_field: some field in the struct
*/
struct anon_test2 {
int some_field;
union { // fields inside structs/unions are not listed
__wsum csum;
__wsum zeta;
__u32 beta;
};
};
/**
* el1_probe - probe for a 3c501
* @unit: device number
*
* This can be called from two places. The network layer will probe using
* a device structure passed in with the probe information completed. For a
* modular driver we use #init_module to fill in our own structure and probe
* for it.
*
* Returns 0 on success. ENXIO if asked not to probe and ENODEV if asked to
* probe and failing to find anything.
*/
struct net_device * __init el1_probe(int unit)
{
}
/**
* parport_register_device - register a device on a parallel port
* @port: port to which the device is attached
* @name: a name to refer to the device
* @pf: preemption callback
* @kf: kick callback (wake-up)
* @irq_func: interrupt handler
* @flags: registration flags
* @handle: data for callback functions
*
* This function, called by parallel port device drivers,
* declares that a device is connected to a port, and tells the
* system all it needs to know.
*
* The @name is allocated by the caller and must not be
* deallocated until the caller calls @parport_unregister_device
* for that device.
*
* The preemption callback function, @pf, is called when this
* device driver has claimed access to the port but another
* device driver wants to use it. It is given @handle as its
* parameter, and should return zero if it is willing for the
* system to release the port to another driver on its behalf.
* If it wants to keep control of the port it should return
* non-zero, and no action will be taken. It is good manners for
* the driver to try to release the port at the earliest
* opportunity after its preemption callback rejects a preemption
* attempt. Note that if a preemption callback is happy for
* preemption to go ahead, there is no need to release the port;
* it is done automatically. This function may not block, as it
* may be called from interrupt context. If the device driver
* does not support preemption, @pf can be %NULL.
*
* The wake-up ("kick") callback function, @kf, is called when
* the port is available to be claimed for exclusive access; that
* is, parport_claim() is guaranteed to succeed when called from
* inside the wake-up callback function. If the driver wants to
* claim the port it should do so; otherwise, it need not take
* any action. This function may not block, as it may be called
* from interrupt context. If the device driver does not want to
* be explicitly invited to claim the port in this way, @kf can
* be %NULL.
*
* The interrupt handler, @irq_func, is called when an interrupt
* arrives from the parallel port. Note that if a device driver
* wants to use interrupts it should use parport_enable_irq(),
* and can also check the irq member of the parport structure
* representing the port.
*
* The parallel port (lowlevel) driver is the one that has called
* request_irq() and whose interrupt handler is called first.
* This handler does whatever needs to be done to the hardware to
* acknowledge the interrupt (for PC-style ports there is nothing
* special to be done). It then tells the IEEE 1284 code about
* the interrupt, which may involve reacting to an IEEE 1284
* event depending on the current IEEE 1284 phase. After this,
* it calls @irq_func. Needless to say, @irq_func will be called
* from interrupt context, and may not block.
*
* The %PARPORT_DEV_EXCL flag is for preventing port sharing, and
* so should only be used when sharing the port with other device
* drivers is impossible and would lead to incorrect behaviour.
* Use it sparingly! Normally, @flags will be zero.
*
* This function returns a pointer to a structure that represents
* the device on the port, or %NULL if there is not enough memory
* to allocate space for that structure.
**/
struct pardevice *
parport_register_device(struct parport *port, const char *name,
int (*pf)(void *), void (*kf)(void *),
void (*irq_func)(int, void *),
int flags, void *handle)
{
}
/**
* atomic_set - set atomic variable
* @v: pointer of type atomic_t
* @i: required value
*
* Atomically sets the value of @v to @i.
*/
#define atomic_set(v,i) (((v)->counter) = (i))
/**
* atomic_set_varargs - set atomic variable
* @v: pointer of type atomic_t
* @i: required value
* @...: more varargs
*
* Atomically sets the value of @v to @i.
*/
#define atomic_set_varargs(v,i, ...) (((v)->counter) = (i))
/**
* ntfs_debug - write a debug level message to syslog
* @f: a printf format string containing the message
* @...: the variables to substitute into @f
*
* ntfs_debug() writes a DEBUG level message to the syslog but only if the
* driver was compiled with -DDEBUG. Otherwise, the call turns into a NOP.
*/
static void ntfs_debug(const char *f, ...);
/**
* __copy_to_user: - Copy a block of data into user space, with less checking.
* @to: Destination address, in user space.
* @from: Source address, in kernel space.
* @n: Number of bytes to copy.
*
* Context: User context only. This function may sleep.
*
* Copy data from kernel space to user space. Caller must check
* the specified block with access_ok() before calling this function.
*
* Returns number of bytes that could not be copied.
* On success, this will be zero.
*/
static __always_inline unsigned long __must_check
__copy_to_user(void __user *to, const void *from, unsigned long n)
{
}
/**
* pci_match_device - Tell if a PCI device structure has a matching PCI device id structure
* @drv: the PCI driver to match against
* @dev: the PCI device structure to match against
*
* Used by a driver to check whether a PCI device present in the
* system is in its list of supported devices. Returns the matching
* pci_device_id structure or %NULL if there is no match.
*/
const struct pci_device_id *pci_match_device(struct pci_driver *drv,
struct pci_dev *dev)
{
}
/**
* shost_for_each_device - iterate over all devices of a host
* @sdev: the &struct scsi_device to use as a cursor
* @shost: the &struct scsi_host to iterate over
*
* Iterator that returns each device attached to @shost. This loop
* takes a reference on each device and releases it at the end. If
* you break out of the loop, you must call scsi_device_put(sdev).
*/
#define shost_for_each_device(sdev, shost) \
for ((sdev) = __scsi_iterate_devices((shost), NULL); \
(sdev); \
(sdev) = __scsi_iterate_devices((shost), (sdev)))
/**
* __shost_for_each_device - iterate over all devices of a host (UNLOCKED)
* @sdev: the &struct scsi_device to use as a cursor
* @shost: the &struct scsi_host to iterate over
*
* Iterator that returns each device attached to @shost. It does _not_
* take a reference on the scsi_device, so the whole loop must be
* protected by shost->host_lock.
*
* Note: The only reason to use this is because you need to access the
* device list in interrupt context. Otherwise you really want to use
* shost_for_each_device instead.
*/
#define __shost_for_each_device(sdev, shost) \
list_for_each_entry((sdev), &((shost)->__devices), siblings)
//BAD: TBD: try to detect this:
/**
* scsi_devinfo: set up the dynamic device list.
*
* The short function description above is in invalid format and
* is probably missing in the generated output.
*/
int scsi_devinfo(void)
{
}
/**
* scsi_init_devinfo - set up the dynamic device list.
*
* Description:
*
* blank line1 above & below here should be kept as is, not deleted.
*
* Init all devinfo list entries and then add
* scsi_static_device_list entries to the scsi device info list.
*
* blank line2 above & below here should be kept as is, not deleted.
*
**/
int __init scsi_init_devinfo(void)
{
}
/**
* vunmap - release virtual mapping obtained by vmap()
* @addr: memory base address
*
* Free the virtually contiguous memory area starting at @addr,
* which was created from the page array passed to vmap().
*
* Must not be called in interrupt context.
*
* Returns a pointer to the array of pointers to page structs
*/
struct page **vunmap(const void *addr)
{
BUG_ON(in_interrupt());
return __vunmap(addr, 0);
}
/**
* blk_end_io - Generic end_io function to complete a request.
* @rq: the request being processed
* @error: 0 for success, < 0 for error
* @nr_bytes: number of bytes to complete @rq
* @bidi_bytes: number of bytes to complete @rq->next_rq
* @drv_callback: function called between completion of bios in the request
* and completion of the request.
* If the callback returns non 0, this helper returns without
* completion of the request.
*
* Description:
* Ends I/O on a number of bytes attached to @rq and @rq->next_rq.
* If @rq has leftover, sets it up for the next range of segments.
*
* Return:
* 0 - we are done with this request
* 1 - this request is not freed yet, it still has pending buffers.
**/
static int blk_end_io(struct request *rq, int error, unsigned int nr_bytes,
unsigned int bidi_bytes,
int (drv_callback)(struct request *))
{
}
/**
* func_with_dup_note_sections - any old function
*
* Note: each "section" (as indicated by "word:") should have a unique section-word
* identifier.
*
* Note1: teach kernel-doc to notice when it clobbers a previous section contents.
*/
static void func_with_dup_note_sections(void)
{
}
/**
* func_name_short_desc_test() -- any old function
*
* Note2: Just see how the output looks when () and -- are used.
*/
static void func_name_short_desc_test(void)
{
}
/**
* notify_cpu_starting(cpu) - call the CPU_STARTING notifiers
* @cpu: cpu that just started
*
* Note3: test for func prm name included.
*/
static void notify_cpu_starting(unsigned int cpu)
{
}
/**
* struct foobar - documented
*
* This is a struct whose members are all private.
*/
struct foobar {
/* private: */
int foo;
int bar;
/* public: */
};
/**
* struct skb_shared_hwtstamps - hardware time stamps
* @hwtstamp: hardware time stamp transformed into duration
* since arbitrary point in time
* @syststamp: hwtstamp transformed to system time base
*
* Software time stamps generated by ktime_get_real() are stored in
* skb->tstamp. The relation between the different kinds of time
* stamps is as follows:
*
* syststamp and tstamp can be compared against each other in
* arbitrary combinations. The accuracy of a
* syststamp/tstamp/"syststamp from other device" comparison is
* limited by the accuracy of the transformation into system time
* base. This depends on the device driver and its underlying
* hardware.
*
* hwtstamps can only be compared against other hwtstamps from
* the same device.
*
* This structure is attached to packets as part of the
* &skb_shared_info. Use skb_hwtstamps() to get a pointer.
*/
struct skb_shared_hwtstamps {
ktime_t hwtstamp;
ktime_t syststamp;
};
/**
* struct usb_function - describes one function of a configuration
* @name: For diagnostics, identifies the function.
* @strings: tables of strings, keyed by identifiers assigned during bind()
* and by language IDs provided in control requests
* @descriptors: Table of full (or low) speed descriptors, using interface and
* string identifiers assigned during @bind(). If this pointer is null,
* the function will not be available at full speed (or at low speed).
* @hs_descriptors: Table of high speed descriptors, using interface and
* string identifiers assigned during @bind(). If this pointer is null,
* the function will not be available at high speed.
* @config: assigned when @usb_add_function() is called; this is the
* configuration with which this function is associated.
* @bind: Before the gadget can register, all of its functions bind() to the
* available resources including string and interface identifiers used
* in interface or class descriptors; endpoints; I/O buffers; and so on.
* @unbind: Reverses @bind; called as a side effect of unregistering the
* driver which added this function.
* @set_alt: (REQUIRED) Reconfigures altsettings; function drivers may
* initialize usb_ep.driver data at this time (when it is used).
* Note that setting an interface to its current altsetting resets
* interface state, and that all interfaces have a disabled state.
* @get_alt: Returns the active altsetting. If this is not provided,
* then only altsetting zero is supported.
* @disable: (REQUIRED) Indicates the function should be disabled. Reasons
* include host resetting or reconfiguring the gadget, and disconnection.
* @setup: Used for interface-specific control requests.
* @suspend: Notifies functions when the host stops sending USB traffic.
* @resume: Notifies functions when the host restarts USB traffic.
*
* A single USB function uses one or more interfaces, and should in most
* cases support operation at both full and high speeds. Each function is
* associated by @usb_add_function() with a one configuration; that function
* causes @bind() to be called so resources can be allocated as part of
* setting up a gadget driver. Those resources include endpoints, which
* should be allocated using @usb_ep_autoconfig().
*
* To support dual speed operation, a function driver provides descriptors
* for both high and full speed operation. Except in rare cases that don't
* involve bulk endpoints, each speed needs different endpoint descriptors.
*
* Function drivers choose their own strategies for managing instance data.
* The simplest strategy just declares it "static', which means the function
* can only be activated once. If the function needs to be exposed in more
* than one configuration at a given speed, it needs to support multiple
* usb_function structures (one for each configuration).
*
* A more complex strategy might encapsulate a @usb_function structure inside
* a driver-specific instance structure to allows multiple activations. An
* example of multiple activations might be a CDC ACM function that supports
* two or more distinct instances within the same configuration, providing
* several independent logical data links to a USB host.
*/
struct usb_function {
const char *name;
struct usb_gadget_strings **strings;
struct usb_descriptor_header **descriptors;
struct usb_descriptor_header **hs_descriptors;
struct usb_configuration *config;
/* REVISIT: bind() functions can be marked __init, which
* makes trouble for section mismatch analysis. See if
* we can't restructure things to avoid mismatching.
* Related: unbind() may kfree() but bind() won't...
*/
/* configuration management: bind/unbind */
int (*bind)(struct usb_configuration *,
struct usb_function *);
void (*unbind)(struct usb_configuration *,
struct usb_function *);
/* runtime state management */
int (*set_alt)(struct usb_function *,
unsigned interface, unsigned alt);
int (*get_alt)(struct usb_function *,
unsigned interface);
void (*disable)(struct usb_function *);
int (*setup)(struct usb_function *,
const struct usb_ctrlrequest *);
void (*suspend)(struct usb_function *);
void (*resume)(struct usb_function *);
/* private: allow trailing text here, but not leading text before "private:" */
/* internals */
struct list_head list;
};
/**
* struct urb - USB Request Block
* @urb_list: For use by current owner of the URB.
* @anchor_list: membership in the list of an anchor
* @anchor: to anchor URBs to a common mooring
* @ep: Points to the endpoint's data structure. Will eventually
* replace @pipe.
* @pipe: Holds endpoint number, direction, type, and more.
* Create these values with the eight macros available;
* usb_{snd,rcv}TYPEpipe(dev,endpoint), where the TYPE is "ctrl"
* (control), "bulk", "int" (interrupt), or "iso" (isochronous).
* For example usb_sndbulkpipe() or usb_rcvintpipe(). Endpoint
* numbers range from zero to fifteen. Note that "in" endpoint two
* is a different endpoint (and pipe) from "out" endpoint two.
* The current configuration controls the existence, type, and
* maximum packet size of any given endpoint.
* @dev: Identifies the USB device to perform the request.
* @status: This is read in non-iso completion functions to get the
* status of the particular request. ISO requests only use it
* to tell whether the URB was unlinked; detailed status for
* each frame is in the fields of the iso_frame-desc.
* @transfer_flags: A variety of flags may be used to affect how URB
* submission, unlinking, or operation are handled. Different
* kinds of URB can use different flags.
* @transfer_buffer: This identifies the buffer to (or from) which
* the I/O request will be performed (unless URB_NO_TRANSFER_DMA_MAP
* is set). This buffer must be suitable for DMA; allocate it with
* kmalloc() or equivalent. For transfers to "in" endpoints, contents
* of this buffer will be modified. This buffer is used for the data
* stage of control transfers.
* @transfer_dma: When transfer_flags includes URB_NO_TRANSFER_DMA_MAP,
* the device driver is saying that it provided this DMA address,
* which the host controller driver should use in preference to the
* transfer_buffer.
* @transfer_buffer_length: How big is transfer_buffer. The transfer may
* be broken up into chunks according to the current maximum packet
* size for the endpoint, which is a function of the configuration
* and is encoded in the pipe. When the length is zero, neither
* transfer_buffer nor transfer_dma is used.
* @actual_length: This is read in non-iso completion functions, and
* it tells how many bytes (out of transfer_buffer_length) were
* transferred. It will normally be the same as requested, unless
* either an error was reported or a short read was performed.
* The URB_SHORT_NOT_OK transfer flag may be used to make such
* short reads be reported as errors.
* @setup_packet: Only used for control transfers, this points to eight bytes
* of setup data. Control transfers always start by sending this data
* to the device. Then transfer_buffer is read or written, if needed.
* @setup_dma: For control transfers with URB_NO_SETUP_DMA_MAP set, the
* device driver has provided this DMA address for the setup packet.
* The host controller driver should use this in preference to
* setup_packet.
* @start_frame: Returns the initial frame for isochronous transfers.
* @number_of_packets: Lists the number of ISO transfer buffers.
* @interval: Specifies the polling interval for interrupt or isochronous
* transfers. The units are frames (milliseconds) for for full and low
* speed devices, and microframes (1/8 millisecond) for highspeed ones.
* @error_count: Returns the number of ISO transfers that reported errors.
* @context: For use in completion functions. This normally points to
* request-specific driver context.
* @complete: Completion handler. This URB is passed as the parameter to the
* completion function. The completion function may then do what
* it likes with the URB, including resubmitting or freeing it.
* @iso_frame_desc: Used to provide arrays of ISO transfer buffers and to
* collect the transfer status for each buffer.
*/
struct urb {
/* private: usb core and host controller only fields in the urb */
struct kref kref; /* reference count of the URB */
void *hcpriv; /* private data for host controller */
atomic_t use_count; /* concurrent submissions counter */
atomic_t reject; /* submissions will fail */
int unlinked; /* unlink error code */
/* public: documented fields in the urb that can be used by drivers */
struct list_head urb_list; /* list head for use by the urb's
* current owner */
struct list_head anchor_list; /* the URB may be anchored */
struct usb_anchor *anchor;
struct usb_device *dev; /* (in) pointer to associated device */
struct usb_host_endpoint *ep; /* (internal) pointer to endpoint */
unsigned int pipe; /* (in) pipe information */
int status; /* (return) non-ISO status */
unsigned int transfer_flags; /* (in) URB_SHORT_NOT_OK | ...*/
void *transfer_buffer; /* (in) associated data buffer */
dma_addr_t transfer_dma; /* (in) dma addr for transfer_buffer */
u32 transfer_buffer_length; /* (in) data buffer length */
u32 actual_length; /* (return) actual transfer length */
unsigned char *setup_packet; /* (in) setup packet (control only) */
dma_addr_t setup_dma; /* (in) dma addr for setup_packet */
int start_frame; /* (modify) start frame (ISO) */
int number_of_packets; /* (in) number of ISO packets */
int interval; /* (modify) transfer interval
* (INT/ISO) */
int error_count; /* (return) number of ISO errors */
void *context; /* (in) context for completion */
usb_complete_t complete; /* (in) completion routine */
struct usb_iso_packet_descriptor iso_frame_desc[0];
/* (in) ISO ONLY */
};
/**
* struct sock - network layer representation of sockets
* @__sk_common: shared layout with inet_timewait_sock
* @sk_shutdown: mask of %SEND_SHUTDOWN and/or %RCV_SHUTDOWN
* @sk_userlocks: %SO_SNDBUF and %SO_RCVBUF settings
* @sk_lock: synchronizer
* @sk_rcvbuf: size of receive buffer in bytes
* @sk_sleep: sock wait queue
* @sk_dst_cache: destination cache
* @sk_dst_lock: destination cache lock
* @sk_policy: flow policy
* @sk_rmem_alloc: receive queue bytes committed
* @sk_receive_queue: incoming packets
* @sk_wmem_alloc: transmit queue bytes committed
* @sk_write_queue: Packet sending queue
* @sk_async_wait_queue: DMA copied packets
* @sk_omem_alloc: "o" is "option" or "other"
* @sk_wmem_queued: persistent queue size
* @sk_forward_alloc: space allocated forward
* @sk_allocation: allocation mode
* @sk_sndbuf: size of send buffer in bytes
* @sk_flags: %SO_LINGER (l_onoff), %SO_BROADCAST, %SO_KEEPALIVE,
* %SO_OOBINLINE settings, %SO_TIMESTAMPING settings
* @sk_no_check: %SO_NO_CHECK setting, wether or not checkup packets
* @sk_route_caps: route capabilities (e.g. %NETIF_F_TSO)
* @sk_gso_type: GSO type (e.g. %SKB_GSO_TCPV4)
* @sk_gso_max_size: Maximum GSO segment size to build
* @sk_lingertime: %SO_LINGER l_linger setting
* @sk_backlog: always used with the per-socket spinlock held
* @sk_callback_lock: used with the callbacks in the end of this struct
* @sk_error_queue: rarely used
* @sk_prot_creator: sk_prot of original sock creator (see ipv6_setsockopt,
* IPV6_ADDRFORM for instance)
* @sk_err: last error
* @sk_err_soft: errors that don't cause failure but are the cause of a
* persistent failure not just 'timed out'
* @sk_drops: raw/udp drops counter
* @sk_ack_backlog: current listen backlog
* @sk_max_ack_backlog: listen backlog set in listen()
* @sk_priority: %SO_PRIORITY setting
* @sk_type: socket type (%SOCK_STREAM, etc)
* @sk_protocol: which protocol this socket belongs in this network family
* @sk_peercred: %SO_PEERCRED setting
* @sk_rcvlowat: %SO_RCVLOWAT setting
* @sk_rcvtimeo: %SO_RCVTIMEO setting
* @sk_sndtimeo: %SO_SNDTIMEO setting
* @sk_filter: socket filtering instructions
* @sk_protinfo: private area, net family specific, when not using slab
* @sk_timer: sock cleanup timer
* @sk_stamp: time stamp of last packet received
* @sk_socket: Identd and reporting IO signals
* @sk_user_data: RPC layer private data
* @sk_sndmsg_page: cached page for sendmsg
* @sk_sndmsg_off: cached offset for sendmsg
* @sk_send_head: front of stuff to transmit
* @sk_security: used by security modules
* @sk_mark: generic packet mark
* @sk_write_pending: a write to stream socket waits to start
* @sk_state_change: callback to indicate change in the state of the sock
* @sk_data_ready: callback to indicate there is data to be processed
* @sk_write_space: callback to indicate there is bf sending space available
* @sk_error_report: callback to indicate errors (e.g. %MSG_ERRQUEUE)
* @sk_backlog_rcv: callback to process the backlog
* @sk_destruct: called at sock freeing time, i.e. when all refcnt == 0
*/
struct sock {
/*
* Now struct inet_timewait_sock also uses sock_common, so please just
* don't add nothing before this first member (__sk_common) --acme
*/
struct sock_common __sk_common;
#define sk_family __sk_common.skc_family
#define sk_state __sk_common.skc_state
#define sk_reuse __sk_common.skc_reuse
#define sk_bound_dev_if __sk_common.skc_bound_dev_if
#define sk_node __sk_common.skc_node
#define sk_nulls_node __sk_common.skc_nulls_node
#define sk_bind_node __sk_common.skc_bind_node
#define sk_refcnt __sk_common.skc_refcnt
#define sk_hash __sk_common.skc_hash
#define sk_prot __sk_common.skc_prot
#define sk_net __sk_common.skc_net
kmemcheck_bitfield_begin(flags);
unsigned char sk_shutdown : 2,
sk_no_check : 2,
sk_userlocks : 4;
kmemcheck_bitfield_end(flags);
unsigned char sk_protocol;
unsigned short sk_type;
int sk_rcvbuf;
socket_lock_t sk_lock;
/*
* The backlog queue is special, it is always used with
* the per-socket spinlock held and requires low latency
* access. Therefore we special case it's implementation.
*/
struct {
struct sk_buff *head;
struct sk_buff *tail;
} sk_backlog;
wait_queue_head_t *sk_sleep;
struct dst_entry *sk_dst_cache;
#ifdef CONFIG_XFRM
struct xfrm_policy *sk_policy[2];
#endif
rwlock_t sk_dst_lock;
atomic_t sk_rmem_alloc;
atomic_t sk_wmem_alloc;
atomic_t sk_omem_alloc;
int sk_sndbuf;
struct sk_buff_head sk_receive_queue;
struct sk_buff_head sk_write_queue;
#ifdef CONFIG_NET_DMA
struct sk_buff_head sk_async_wait_queue;
#endif
int sk_wmem_queued;
int sk_forward_alloc;
gfp_t sk_allocation;
int sk_route_caps;
int sk_gso_type;
unsigned int sk_gso_max_size;
int sk_rcvlowat;
unsigned long sk_flags;
unsigned long sk_lingertime;
struct sk_buff_head sk_error_queue;
struct proto *sk_prot_creator;
rwlock_t sk_callback_lock;
int sk_err,
sk_err_soft;
atomic_t sk_drops;
unsigned short sk_ack_backlog;
unsigned short sk_max_ack_backlog;
__u32 sk_priority;
struct ucred sk_peercred;
long sk_rcvtimeo;
long sk_sndtimeo;
struct sk_filter *sk_filter;
void *sk_protinfo;
struct timer_list sk_timer;
ktime_t sk_stamp;
struct socket *sk_socket;
void *sk_user_data;
struct page *sk_sndmsg_page;
struct sk_buff *sk_send_head;
__u32 sk_sndmsg_off;
int sk_write_pending;
#ifdef CONFIG_SECURITY
void *sk_security;
#endif
__u32 sk_mark;
/* XXX 4 bytes hole on 64 bit */
void (*sk_state_change)(struct sock *sk);
void (*sk_data_ready)(struct sock *sk, int bytes);
void (*sk_write_space)(struct sock *sk);
void (*sk_error_report)(struct sock *sk);
int (*sk_backlog_rcv)(struct sock *sk,
struct sk_buff *skb);
void (*sk_destruct)(struct sock *sk);
};
/**
* is_etherdev_addr - Tell if given Ethernet address belongs to the device.
* @dev: Pointer to a device structure
* @addr: Pointer to a six-byte array containing the Ethernet address
*
* Compare passed address with all addresses of the device. Return true if the
* address if one of the device addresses.
*
* Note that this function calls compare_ether_addr_64bits() so take care of
* the right padding.
*/
static inline bool is_etherdev_addr(const struct net_device *dev,
const u8 addr[6 + 2])
{
struct netdev_hw_addr *ha;
int res = 1;
rcu_read_lock();
for_each_dev_addr(dev, ha) {
res = compare_ether_addr_64bits(addr, ha->addr);
if (!res)
break;
}
rcu_read_unlock();
return !res;
}
/**
* flex_array_shrink - free unused second-level pages
*
* Frees all second-level pages that consist solely of unused
* elements. Returns the number of pages freed.
*
* Locking must be provided by the caller.
*/
int flex_array_shrink(struct flex_array *fa)
{
}
/* weird kernel-doc error from Johannes Berg on: */
#define FOO 10
/**
* struct foo - test kernel-doc struct errors
* @a: some field with attributes
* @b: some field with other attributes
*/
struct foo {
u8 a[0]
__attribute__((__aligned(sizeof(void *))));
u8 b[0]
__attribute__((__aligned__(FOO)));
};
/**
* dev_alloc_name - allocate a name for a device
* @dev: device
* @name: name format string
*
* Passed a format string - eg "lt%d" it will try and find a suitable
* id. It scans list of devices to build up a free map, then chooses
* the first empty slot. The caller must hold the dev_base or rtnl lock
* while allocating the name and adding the device in order to avoid
* duplicates.
* Limited to bits_per_byte * page size devices (ie 32K on most platforms).
* Returns the number of the unit assigned or a negative errno code.
*/
int dev_alloc_name(struct net_device *dev, const char *name)
{
}
/**
* struct - i/q coordinate.
*
* @i: real part of coordinate (in phase).
* @q: imaginary part of coordinate (quadrature).
*/
struct cordic_iq {
s32 i;
s32 q;
};
/**
* struct nand_flash_dev - NAND Flash Device ID Structure
* @name: a human-readable name of the NAND chip
* @dev_id: the device ID (the second byte of the full chip ID array)
* @mfr_id: manufecturer ID part of the full chip ID array (refers the same
* memory address as @id[0])
* @dev_id: device ID part of the full chip ID array (refers the same memory
* address as @id[1])
* @id: full device ID array
* @pagesize: size of the NAND page in bytes; if 0, then the real page size (as
* well as the eraseblock size) is determined from the extended NAND
* chip ID array)
* @chipsize: total chip size in MiB
* @erasesize: eraseblock size in bytes (determined from the extended ID if 0)
* @options: stores various chip bit options
* @id_len: The valid length of the @id.
* @oobsize: OOB size
* @ecc: ecc parameters from datasheet
* @ecc.strength_ds: The ECC correctability from the datasheet, same as the
* @ecc_strength_ds in nand_chip{}.
* @ecc.step_ds: The ECC step required by the @ecc.strength_ds, same as the
* @ecc_step_ds in nand_chip{}, also from the datasheet.
* For example, the "4bit ECC for each 512Byte" can be set with
* NAND_ECC_INFO(4, 512).
* WITHOUT named nested unions/structs;
*/
struct nand_flash_dev {
char *name;
union {
struct {
uint8_t mfr_id;
uint8_t dev_id;
};
uint8_t id[NAND_MAX_ID_LEN];
};
unsigned int pagesize;
unsigned int chipsize;
unsigned int erasesize;
unsigned int options;
uint16_t id_len;
uint16_t oobsize;
struct {
uint16_t strength_ds;
uint16_t step_ds;
} ecc;
};
/**
* struct nand_flash_device - NAND Flash Device ID Structure
* @name: a human-readable name of the NAND chip
* @dev_id: the device ID (the second byte of the full chip ID array)
* @mfr_id: manufecturer ID part of the full chip ID array (refers the same
* memory address as @id[0])
* @dev_id: device ID part of the full chip ID array (refers the same memory
* address as @id[1])
* @id: full device ID array
* @pagesize: size of the NAND page in bytes; if 0, then the real page size (as
* well as the eraseblock size) is determined from the extended NAND
* chip ID array)
* @chipsize: total chip size in MiB
* @erasesize: eraseblock size in bytes (determined from the extended ID if 0)
* @options: stores various chip bit options
* @id_len: The valid length of the @id.
* @oobsize: OOB size
* @ecc: ecc parameters from datasheet
* @ecc.strength_ds: The ECC correctability from the datasheet, same as the
* @ecc_strength_ds in nand_chip{}.
* @ecc.step_ds: The ECC step required by the @ecc.strength_ds, same as the
* @ecc_step_ds in nand_chip{}, also from the datasheet.
* For example, the "4bit ECC for each 512Byte" can be set with
* NAND_ECC_INFO(4, 512).
* WITH named nested unions/structs;
*/
struct nand_flash_device {
char *name;
union u_ids_ary {
struct nand_ids {
uint8_t mfr_id;
uint8_t dev_id;
} ids;
uint8_t id[NAND_MAX_ID_LEN];
} ids_ary;
unsigned int pagesize;
unsigned int chipsize;
unsigned int erasesize;
unsigned int options;
uint16_t id_len;
uint16_t oobsize;
struct ecc_ds {
uint16_t strength_ds;
uint16_t step_ds;
} ecc;
};
/**
* crc32_le_generic() - Calculate bitwise little-endian Ethernet AUTODIN II
* CRC32/CRC32C
* @crc: seed value for computation. ~0 for Ethernet, sometimes 0 for other
* uses, or the previous crc32/crc32c value if computing incrementally.
* @p: pointer to buffer over which CRC32/CRC32C is run
* @len: length of buffer @p
* @tab: little-endian Ethernet table
* @polynomial: CRC32/CRC32c LE polynomial
*/
static inline u32 __pure crc32_le_generic(u32 crc, unsigned char const *p,
size_t len, const u32 (*tab)[256],
u32 polynomial)
{
return crc;
}
/**
* strreplace - Replace all occurrences of character in string.
* @s: The string to operate on.
* @old: The character being replaced.
* @new: The character @old is replaced with.
*
* Returns pointer to the nul byte at the end of @s.
*/
char *strreplace(char *s, char old, char new)
{
for (; *s; ++s)
if (*s == old)
*s = new;
return s;
}
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [RFC] Add kernel-doc test script
2020-11-18 16:32 ` Randy Dunlap
@ 2020-11-18 16:57 ` Eduardo Habkost
2020-11-18 16:58 ` Randy Dunlap
0 siblings, 1 reply; 17+ messages in thread
From: Eduardo Habkost @ 2020-11-18 16:57 UTC (permalink / raw)
To: Randy Dunlap
Cc: Matthew Wilcox, Jonathan Corbet, Paolo Bonzini, linux-kernel, linux-doc
On Wed, Nov 18, 2020 at 08:32:35AM -0800, Randy Dunlap wrote:
> On 11/18/20 5:03 AM, Eduardo Habkost wrote:
> > On Tue, Nov 17, 2020 at 04:23:49PM -0800, Randy Dunlap wrote:
> >> On 11/17/20 2:36 PM, Eduardo Habkost wrote:
> >>> Add a kernel-doc test script to tools/testing/kernel-doc.
> >>>
> >>> radix_tree_lookup_slot test case provided by Matthew Wilcox.
> >>>
> >>> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
> >>
> >> Very good idea.
> >>
> >> I have had a kernel-doc test source file for (?) 10-12 years,
> >> while I was the docs maintainer.
> >
> > Is that test source file recoverable somewhere? It probably has
> > useful test cases not included here.
>
> Sure. Of course, it may be out of date by quite a bit.
> I last updated it in 2016:
> -rw-r--r-- 1 rdunlap users 41737 Jun 17 2016 megatest.c
>
> (attached)
>
Thanks! Are the contents licensed under GPL 2.0?
--
Eduardo
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [RFC] Add kernel-doc test script
2020-11-18 16:57 ` Eduardo Habkost
@ 2020-11-18 16:58 ` Randy Dunlap
0 siblings, 0 replies; 17+ messages in thread
From: Randy Dunlap @ 2020-11-18 16:58 UTC (permalink / raw)
To: Eduardo Habkost
Cc: Matthew Wilcox, Jonathan Corbet, Paolo Bonzini, linux-kernel, linux-doc
On 11/18/20 8:57 AM, Eduardo Habkost wrote:
> On Wed, Nov 18, 2020 at 08:32:35AM -0800, Randy Dunlap wrote:
>> On 11/18/20 5:03 AM, Eduardo Habkost wrote:
>>> On Tue, Nov 17, 2020 at 04:23:49PM -0800, Randy Dunlap wrote:
>>>> On 11/17/20 2:36 PM, Eduardo Habkost wrote:
>>>>> Add a kernel-doc test script to tools/testing/kernel-doc.
>>>>>
>>>>> radix_tree_lookup_slot test case provided by Matthew Wilcox.
>>>>>
>>>>> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
>>>>
>>>> Very good idea.
>>>>
>>>> I have had a kernel-doc test source file for (?) 10-12 years,
>>>> while I was the docs maintainer.
>>>
>>> Is that test source file recoverable somewhere? It probably has
>>> useful test cases not included here.
>>
>> Sure. Of course, it may be out of date by quite a bit.
>> I last updated it in 2016:
>> -rw-r--r-- 1 rdunlap users 41737 Jun 17 2016 megatest.c
>>
>> (attached)
>>
>
> Thanks! Are the contents licensed under GPL 2.0?
Sure!
--
~Randy
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2020-11-18 16:59 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-30 14:47 [PATCH 0/2] kernel-doc: Handle function typedefs Paolo Bonzini
2020-10-30 14:47 ` [PATCH 1/2] kernel-doc: Handle function typedefs that return pointers Paolo Bonzini
2020-10-30 14:47 ` [PATCH 2/2] kernel-doc: Handle function typedefs without asterisks Paolo Bonzini
2020-11-13 22:21 ` Jonathan Corbet
2020-11-13 22:35 ` Paolo Bonzini
2020-11-13 22:39 ` Matthew Wilcox
2020-11-17 21:24 ` Eduardo Habkost
2020-11-17 21:30 ` Matthew Wilcox
2020-11-17 22:36 ` [RFC] Add kernel-doc test script Eduardo Habkost
2020-11-18 0:23 ` Randy Dunlap
2020-11-18 13:03 ` Eduardo Habkost
2020-11-18 16:32 ` Randy Dunlap
2020-11-18 16:57 ` Eduardo Habkost
2020-11-18 16:58 ` Randy Dunlap
2020-11-18 8:21 ` Paolo Bonzini
2020-11-18 12:05 ` Eduardo Habkost
2020-11-18 16:27 ` Jonathan Corbet
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).