linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/15] improve function-level documentation
@ 2016-10-01 19:46 Julia Lawall
  2016-10-01 19:46 ` [PATCH 07/15] clk: sunxi: mod0: " Julia Lawall
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Julia Lawall @ 2016-10-01 19:46 UTC (permalink / raw)
  To: linux-arm-kernel

These patches fix cases where the documentation above a function definition
is not consistent with the function header.  Issues are detected using the
semantic patch below (http://coccinelle.lip6.fr/).  Basically, the semantic
patch parses a file to find comments, then matches each function header,
and checks that the name and parameter list in the function header are
compatible with the comment that preceeds it most closely.

// <smpl>
@initialize:ocaml@
@@

let tbl = ref []
let fnstart = ref []
let success = Hashtbl.create 101
let thefile = ref ""
let parsed = ref []
let nea = ref []

let parse file =
  thefile := List.nth (Str.split (Str.regexp "linux-next/") file) 1;
  let i = open_in file in
  let startline = ref 0 in
  let fn = ref "" in
  let ids = ref [] in
  let rec inside n =
    let l = input_line i in
    let n = n + 1 in
    match Str.split_delim (Str.regexp_string "*/") l with
      before::after::_ ->
	(if not (!fn = "")
	then tbl := (!startline,n,!fn,List.rev !ids)::!tbl);
	startline := 0;
	fn := "";
	ids := [];
	outside n
    | _ ->
	(match Str.split (Str.regexp "[ \t]+") l with
	  "*"::name::rest ->
	    let len = String.length name in
	    (if !fn = "" && len > 2 && String.sub name (len-2) 2 = "()"
	    then fn := String.sub name 0 (len-2)
	    else if !fn = "" && (not (rest = [])) && List.hd rest = "-"
	    then
	      if String.get name (len-1) = ':'
	      then fn := String.sub name 0 (len-1)
	      else fn := name
	    else if not(!fn = "") && len > 2 &&
	      String.get name 0 = '@' && String.get name (len-1) = ':'
	    then ids := (String.sub name 1 (len-2)) :: !ids);
	| _ -> ());
	inside n
  and outside n =
    let l = input_line i in
    let n = n + 1 in
    if String.length l > 2 && String.sub l 0 3 = "/**"
    then
      begin
	startline := n;
	inside n
      end
    else outside n in
  try outside 0 with End_of_file -> ()

let hashadd tbl k v =
  let cell =
    try Hashtbl.find tbl k
    with Not_found ->
      let cell = ref [] in
      Hashtbl.add tbl k cell;
      cell in
  cell := v :: !cell

@script:ocaml@
@@

tbl := [];
fnstart := [];
Hashtbl.clear success;
parsed := [];
nea := [];
parse (List.hd (Coccilib.files()))

@r@
identifier f;
position p;
@@

f at p(...) { ... }

@script:ocaml@
p << r.p;
f << r.f;
@@

parsed := f :: !parsed;
fnstart := (List.hd p).line :: !fnstart

@param@
identifier f;
type T;
identifier i;
parameter list[n] ps;
parameter list[n1] ps1;
position p;
@@

f@p(ps,T i,ps1) { ... }

@script:ocaml@
@@

tbl := List.rev (List.sort compare !tbl)

@script:ocaml@
p << param.p;
f << param.f;
@@

let myline = (List.hd p).line in
let prevline =
  List.fold_left
    (fun prev x ->
      if x < myline
      then max x prev
      else prev)
    0 !fnstart in
let _ =
  List.exists
    (function (st,fn,nm,ids) ->
      if prevline < st && myline > st && prevline < fn && myline > fn
      then
	begin
	  (if not (String.lowercase f = String.lowercase nm)
	  then
	    Printf.printf "%s:%d %s doesn't match preceding comment: %s\n"
	      !thefile myline f nm);
	  true
	end
      else false)
    !tbl in
()

@script:ocaml@
p << param.p;
n << param.n;
n1 << param.n1;
i << param.i;
f << param.f;
@@

let myline = (List.hd p).line in
let prevline =
  List.fold_left
    (fun prev x ->
      if x < myline
      then max x prev
      else prev)
    0 !fnstart in
let _ =
  List.exists
    (function (st,fn,nm,ids) ->
      if prevline < st && myline > st && prevline < fn && myline > fn
      then
	begin
	  (if List.mem i ids then hashadd success (st,fn,nm) i);
	  (if ids = [] (* arg list seems not obligatory *)
	  then ()
	  else if not (List.mem i ids)
	  then
	    Printf.printf "%s:%d %s doesn't appear in ids: %s\n"
	      !thefile myline i (String.concat " " ids)
	  else if List.length ids <= n || List.length ids <= n1
	  then
	    (if not (List.mem f !nea)
	    then
	      begin
		nea := f :: !nea;
		Printf.printf "%s:%d %s not enough args\n" !thefile myline f;
	      end)
	  else
	    let foundid = List.nth ids n in
	    let efoundid = List.nth (List.rev ids) n1 in
	    if not(foundid = i || efoundid = i)
	    then
	      Printf.printf "%s:%d %s wrong arg in position %d: %s\n"
		!thefile myline i n foundid);
	  true
	end
      else false)
    !tbl in
()

@script:ocaml@
@@
List.iter
  (function (st,fn,nm,ids) ->
    if List.mem nm !parsed
    then
      let entry =
	try !(Hashtbl.find success (st,fn,nm))
	with Not_found -> [] in
      List.iter
	(fun id ->
	  if not (List.mem id entry) && not (id = "...")
	  then Printf.printf "%s:%d %s not used\n" !thefile st id)
	ids)
  !tbl
// </smpl>


---

 drivers/clk/keystone/pll.c               |    4 ++--
 drivers/clk/sunxi/clk-mod0.c             |    2 +-
 drivers/clk/tegra/cvb.c                  |   10 +++++-----
 drivers/dma-buf/sw_sync.c                |    6 +++---
 drivers/gpu/drm/gma500/intel_i2c.c       |    3 +--
 drivers/gpu/drm/omapdrm/omap_drv.c       |    4 ++--
 drivers/irqchip/irq-metag-ext.c          |    1 -
 drivers/irqchip/irq-vic.c                |    1 -
 drivers/mfd/tc3589x.c                    |    4 ++--
 drivers/power/supply/ab8500_fg.c         |    8 ++++----
 drivers/power/supply/abx500_chargalg.c   |    1 +
 drivers/power/supply/intel_mid_battery.c |    2 +-
 drivers/power/supply/power_supply_core.c |    4 ++--
 fs/crypto/crypto.c                       |    4 ++--
 fs/crypto/fname.c                        |    4 ++--
 fs/ubifs/file.c                          |    2 +-
 fs/ubifs/gc.c                            |    2 +-
 fs/ubifs/lprops.c                        |    2 +-
 fs/ubifs/lpt_commit.c                    |    4 +---
 fs/ubifs/replay.c                        |    2 +-
 lib/kobject_uevent.c                     |    6 +++---
 lib/lru_cache.c                          |    4 ++--
 lib/nlattr.c                             |    2 +-
 23 files changed, 39 insertions(+), 43 deletions(-)

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 07/15] clk: sunxi: mod0: improve function-level documentation
  2016-10-01 19:46 [PATCH 00/15] improve function-level documentation Julia Lawall
@ 2016-10-01 19:46 ` Julia Lawall
  2016-10-04 21:05   ` Maxime Ripard
  2016-10-01 20:19 ` [PATCH 00/15] " Joe Perches
  2016-10-05 13:15 ` Daniel Vetter
  2 siblings, 1 reply; 10+ messages in thread
From: Julia Lawall @ 2016-10-01 19:46 UTC (permalink / raw)
  To: linux-arm-kernel

Use the actual function name in the function documentation.

Issue detected using Coccinelle (http://coccinelle.lip6.fr/)

Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>

---
 drivers/clk/sunxi/clk-mod0.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/sunxi/clk-mod0.c b/drivers/clk/sunxi/clk-mod0.c
index e54266c..4417ae1 100644
--- a/drivers/clk/sunxi/clk-mod0.c
+++ b/drivers/clk/sunxi/clk-mod0.c
@@ -24,7 +24,7 @@
 #include "clk-factors.h"
 
 /**
- * sun4i_get_mod0_factors() - calculates m, n factors for MOD0-style clocks
+ * sun4i_a10_get_mod0_factors() - calculates m, n factors for MOD0-style clocks
  * MOD0 rate is calculated as follows
  * rate = (parent_rate >> p) / (m + 1);
  */

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 00/15] improve function-level documentation
  2016-10-01 19:46 [PATCH 00/15] improve function-level documentation Julia Lawall
  2016-10-01 19:46 ` [PATCH 07/15] clk: sunxi: mod0: " Julia Lawall
@ 2016-10-01 20:19 ` Joe Perches
  2016-10-01 20:39   ` Julia Lawall
  2016-10-05 13:15 ` Daniel Vetter
  2 siblings, 1 reply; 10+ messages in thread
From: Joe Perches @ 2016-10-01 20:19 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, 2016-10-01 at 21:46 +0200, Julia Lawall wrote:
> These patches fix cases where the documentation above a function definition
> is not consistent with the function header.  Issues are detected using the
> semantic patch below (http://coccinelle.lip6.fr/).  Basically, the semantic
> patch parses a file to find comments, then matches each function header,
> and checks that the name and parameter list in the function header are
> compatible with the comment that preceeds it most closely.

Hi Julia.

Would it be possible for a semantic patch to scan for
function definitions where the types do not have
identifiers and update the definitions to match the
declarations?

For instance, given:

<some.h>
int foo(int);

<some.c>
int foo(int bar)
{
	return baz;
}

Could coccinelle output:

diff a/some.h b/some.h
[]
-int foo(int);
+int foo(int bar);

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 00/15] improve function-level documentation
  2016-10-01 20:19 ` [PATCH 00/15] " Joe Perches
@ 2016-10-01 20:39   ` Julia Lawall
  0 siblings, 0 replies; 10+ messages in thread
From: Julia Lawall @ 2016-10-01 20:39 UTC (permalink / raw)
  To: linux-arm-kernel



On Sat, 1 Oct 2016, Joe Perches wrote:

> On Sat, 2016-10-01 at 21:46 +0200, Julia Lawall wrote:
> > These patches fix cases where the documentation above a function definition
> > is not consistent with the function header.  Issues are detected using the
> > semantic patch below (http://coccinelle.lip6.fr/).  Basically, the semantic
> > patch parses a file to find comments, then matches each function header,
> > and checks that the name and parameter list in the function header are
> > compatible with the comment that preceeds it most closely.
>
> Hi Julia.
>
> Would it be possible for a semantic patch to scan for
> function definitions where the types do not have
> identifiers and update the definitions to match the
> declarations?
>
> For instance, given:
>
> <some.h>
> int foo(int);
>
> <some.c>
> int foo(int bar)
> {
> 	return baz;
> }
>
> Could coccinelle output:
>
> diff a/some.h b/some.h
> []
> -int foo(int);
> +int foo(int bar);

The following seems to work:

@r@
identifier f;
position p;
type T, t;
parameter list[n] ps;
@@

T f at p(ps,t,...);

@s@
identifier r.f,x;
type r.T, r.t;
parameter list[r.n] ps;
@@

T f(ps,t x,...) { ... }

@@
identifier r.f, s.x;
position r.p;
type r.T, r.t;
parameter list[r.n] ps;
@@

T f at p(ps,t
+ x
  ,...);

After letting it run for a few minutes without making any effort to
include .h files, I get over 2700 changed lines.

julia

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 07/15] clk: sunxi: mod0: improve function-level documentation
  2016-10-01 19:46 ` [PATCH 07/15] clk: sunxi: mod0: " Julia Lawall
@ 2016-10-04 21:05   ` Maxime Ripard
  0 siblings, 0 replies; 10+ messages in thread
From: Maxime Ripard @ 2016-10-04 21:05 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Oct 01, 2016 at 09:46:24PM +0200, Julia Lawall wrote:
> Use the actual function name in the function documentation.
> 
> Issue detected using Coccinelle (http://coccinelle.lip6.fr/)
> 
> Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>

Applied, thanks!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161004/6642e966/attachment.sig>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 00/15] improve function-level documentation
  2016-10-01 19:46 [PATCH 00/15] improve function-level documentation Julia Lawall
  2016-10-01 19:46 ` [PATCH 07/15] clk: sunxi: mod0: " Julia Lawall
  2016-10-01 20:19 ` [PATCH 00/15] " Joe Perches
@ 2016-10-05 13:15 ` Daniel Vetter
  2016-10-05 14:04   ` kernel-doc-rst-lint (was: Re: [PATCH 00/15] improve function-level documentation) Jani Nikula
  2016-10-05 14:47   ` [PATCH 00/15] improve function-level documentation Julia Lawall
  2 siblings, 2 replies; 10+ messages in thread
From: Daniel Vetter @ 2016-10-05 13:15 UTC (permalink / raw)
  To: linux-arm-kernel

Jani Nikula has a patch with a scrip to make the one kernel-doc parser
into a lint/checker pass over the entire kernel. I think that'd would
be more robust instead of trying to approximate the real kerneldoc
parser. Otoh that parser is a horror show of a perl/regex driven state
machine ;-)

Jani, can you pls digg out these patches? Can't find them right now ...
-Daniel


On Sat, Oct 1, 2016 at 9:46 PM, Julia Lawall <Julia.Lawall@lip6.fr> wrote:
> These patches fix cases where the documentation above a function definition
> is not consistent with the function header.  Issues are detected using the
> semantic patch below (http://coccinelle.lip6.fr/).  Basically, the semantic
> patch parses a file to find comments, then matches each function header,
> and checks that the name and parameter list in the function header are
> compatible with the comment that preceeds it most closely.
>
> // <smpl>
> @initialize:ocaml@
> @@
>
> let tbl = ref []
> let fnstart = ref []
> let success = Hashtbl.create 101
> let thefile = ref ""
> let parsed = ref []
> let nea = ref []
>
> let parse file =
>   thefile := List.nth (Str.split (Str.regexp "linux-next/") file) 1;
>   let i = open_in file in
>   let startline = ref 0 in
>   let fn = ref "" in
>   let ids = ref [] in
>   let rec inside n =
>     let l = input_line i in
>     let n = n + 1 in
>     match Str.split_delim (Str.regexp_string "*/") l with
>       before::after::_ ->
>         (if not (!fn = "")
>         then tbl := (!startline,n,!fn,List.rev !ids)::!tbl);
>         startline := 0;
>         fn := "";
>         ids := [];
>         outside n
>     | _ ->
>         (match Str.split (Str.regexp "[ \t]+") l with
>           "*"::name::rest ->
>             let len = String.length name in
>             (if !fn = "" && len > 2 && String.sub name (len-2) 2 = "()"
>             then fn := String.sub name 0 (len-2)
>             else if !fn = "" && (not (rest = [])) && List.hd rest = "-"
>             then
>               if String.get name (len-1) = ':'
>               then fn := String.sub name 0 (len-1)
>               else fn := name
>             else if not(!fn = "") && len > 2 &&
>               String.get name 0 = '@' && String.get name (len-1) = ':'
>             then ids := (String.sub name 1 (len-2)) :: !ids);
>         | _ -> ());
>         inside n
>   and outside n =
>     let l = input_line i in
>     let n = n + 1 in
>     if String.length l > 2 && String.sub l 0 3 = "/**"
>     then
>       begin
>         startline := n;
>         inside n
>       end
>     else outside n in
>   try outside 0 with End_of_file -> ()
>
> let hashadd tbl k v =
>   let cell =
>     try Hashtbl.find tbl k
>     with Not_found ->
>       let cell = ref [] in
>       Hashtbl.add tbl k cell;
>       cell in
>   cell := v :: !cell
>
> @script:ocaml@
> @@
>
> tbl := [];
> fnstart := [];
> Hashtbl.clear success;
> parsed := [];
> nea := [];
> parse (List.hd (Coccilib.files()))
>
> @r@
> identifier f;
> position p;
> @@
>
> f at p(...) { ... }
>
> @script:ocaml@
> p << r.p;
> f << r.f;
> @@
>
> parsed := f :: !parsed;
> fnstart := (List.hd p).line :: !fnstart
>
> @param@
> identifier f;
> type T;
> identifier i;
> parameter list[n] ps;
> parameter list[n1] ps1;
> position p;
> @@
>
> f at p(ps,T i,ps1) { ... }
>
> @script:ocaml@
> @@
>
> tbl := List.rev (List.sort compare !tbl)
>
> @script:ocaml@
> p << param.p;
> f << param.f;
> @@
>
> let myline = (List.hd p).line in
> let prevline =
>   List.fold_left
>     (fun prev x ->
>       if x < myline
>       then max x prev
>       else prev)
>     0 !fnstart in
> let _ =
>   List.exists
>     (function (st,fn,nm,ids) ->
>       if prevline < st && myline > st && prevline < fn && myline > fn
>       then
>         begin
>           (if not (String.lowercase f = String.lowercase nm)
>           then
>             Printf.printf "%s:%d %s doesn't match preceding comment: %s\n"
>               !thefile myline f nm);
>           true
>         end
>       else false)
>     !tbl in
> ()
>
> @script:ocaml@
> p << param.p;
> n << param.n;
> n1 << param.n1;
> i << param.i;
> f << param.f;
> @@
>
> let myline = (List.hd p).line in
> let prevline =
>   List.fold_left
>     (fun prev x ->
>       if x < myline
>       then max x prev
>       else prev)
>     0 !fnstart in
> let _ =
>   List.exists
>     (function (st,fn,nm,ids) ->
>       if prevline < st && myline > st && prevline < fn && myline > fn
>       then
>         begin
>           (if List.mem i ids then hashadd success (st,fn,nm) i);
>           (if ids = [] (* arg list seems not obligatory *)
>           then ()
>           else if not (List.mem i ids)
>           then
>             Printf.printf "%s:%d %s doesn't appear in ids: %s\n"
>               !thefile myline i (String.concat " " ids)
>           else if List.length ids <= n || List.length ids <= n1
>           then
>             (if not (List.mem f !nea)
>             then
>               begin
>                 nea := f :: !nea;
>                 Printf.printf "%s:%d %s not enough args\n" !thefile myline f;
>               end)
>           else
>             let foundid = List.nth ids n in
>             let efoundid = List.nth (List.rev ids) n1 in
>             if not(foundid = i || efoundid = i)
>             then
>               Printf.printf "%s:%d %s wrong arg in position %d: %s\n"
>                 !thefile myline i n foundid);
>           true
>         end
>       else false)
>     !tbl in
> ()
>
> @script:ocaml@
> @@
> List.iter
>   (function (st,fn,nm,ids) ->
>     if List.mem nm !parsed
>     then
>       let entry =
>         try !(Hashtbl.find success (st,fn,nm))
>         with Not_found -> [] in
>       List.iter
>         (fun id ->
>           if not (List.mem id entry) && not (id = "...")
>           then Printf.printf "%s:%d %s not used\n" !thefile st id)
>         ids)
>   !tbl
> // </smpl>
>
>
> ---
>
>  drivers/clk/keystone/pll.c               |    4 ++--
>  drivers/clk/sunxi/clk-mod0.c             |    2 +-
>  drivers/clk/tegra/cvb.c                  |   10 +++++-----
>  drivers/dma-buf/sw_sync.c                |    6 +++---
>  drivers/gpu/drm/gma500/intel_i2c.c       |    3 +--
>  drivers/gpu/drm/omapdrm/omap_drv.c       |    4 ++--
>  drivers/irqchip/irq-metag-ext.c          |    1 -
>  drivers/irqchip/irq-vic.c                |    1 -
>  drivers/mfd/tc3589x.c                    |    4 ++--
>  drivers/power/supply/ab8500_fg.c         |    8 ++++----
>  drivers/power/supply/abx500_chargalg.c   |    1 +
>  drivers/power/supply/intel_mid_battery.c |    2 +-
>  drivers/power/supply/power_supply_core.c |    4 ++--
>  fs/crypto/crypto.c                       |    4 ++--
>  fs/crypto/fname.c                        |    4 ++--
>  fs/ubifs/file.c                          |    2 +-
>  fs/ubifs/gc.c                            |    2 +-
>  fs/ubifs/lprops.c                        |    2 +-
>  fs/ubifs/lpt_commit.c                    |    4 +---
>  fs/ubifs/replay.c                        |    2 +-
>  lib/kobject_uevent.c                     |    6 +++---
>  lib/lru_cache.c                          |    4 ++--
>  lib/nlattr.c                             |    2 +-
>  23 files changed, 39 insertions(+), 43 deletions(-)
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel



-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 10+ messages in thread

* kernel-doc-rst-lint (was: Re: [PATCH 00/15] improve function-level documentation)
  2016-10-05 13:15 ` Daniel Vetter
@ 2016-10-05 14:04   ` Jani Nikula
  2016-10-05 17:27     ` Markus Heiser
  2016-10-05 20:25     ` Julia Lawall
  2016-10-05 14:47   ` [PATCH 00/15] improve function-level documentation Julia Lawall
  1 sibling, 2 replies; 10+ messages in thread
From: Jani Nikula @ 2016-10-05 14:04 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 05 Oct 2016, Daniel Vetter <daniel@ffwll.ch> wrote:
> Jani Nikula has a patch with a scrip to make the one kernel-doc parser
> into a lint/checker pass over the entire kernel. I think that'd would
> be more robust instead of trying to approximate the real kerneldoc
> parser. Otoh that parser is a horror show of a perl/regex driven state
> machine ;-)
>
> Jani, can you pls digg out these patches? Can't find them right now ...

Expanding the massive Cc: with linux-doc list...

Here goes. It's a quick hack from months ago, but still seems to
somewhat work. At least for the kernel-doc parts. The reStructuredText
lint part isn't all that great, and doesn't have mapping to line numbers
like the Sphinx kernel-doc extension does. Anyway I'm happy how this
integrates with kernel build CHECK and C=1/C=2.

I guess Julia's goal is to automate the *fixing* of some of the error
classes from kernel-doc. Not sure how well this could be made to
integrate with any of that.

BR,
Jani.


>From 1244efa0f63a7b13795e8c37f81733a3c8bfc56a Mon Sep 17 00:00:00 2001
From: Jani Nikula <jani.nikula@intel.com>
Date: Tue, 31 May 2016 18:11:33 +0300
Subject: [PATCH] kernel-doc-rst-lint: add tool to check kernel-doc and rst
 correctness
Organization: Intel Finland Oy - BIC 0357606-4 - Westendinkatu 7, 02160 Espoo
Cc: Jani Nikula <jani.nikula@intel.com>

Simple kernel-doc and reStructuredText lint tool that can be used
independently and as a kernel build CHECK tool to validate kernel-doc
comments.

Independent usage:
$ kernel-doc-rst-lint FILE

Kernel CHECK usage:
$ make CHECK=scripts/kernel-doc-rst-lint C=1		# (or C=2)

Depends on docutils and the rst-lint package
https://pypi.python.org/pypi/restructuredtext_lint

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 scripts/kernel-doc-rst-lint | 106 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 106 insertions(+)
 create mode 100755 scripts/kernel-doc-rst-lint

diff --git a/scripts/kernel-doc-rst-lint b/scripts/kernel-doc-rst-lint
new file mode 100755
index 000000000000..7e0157679f83
--- /dev/null
+++ b/scripts/kernel-doc-rst-lint
@@ -0,0 +1,106 @@
+#!/usr/bin/env python
+# coding=utf-8
+#
+# Copyright ? 2016 Intel Corporation
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice (including the next
+# paragraph) shall be included in all copies or substantial portions of the
+# Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+# IN THE SOFTWARE.
+#
+# Authors:
+#    Jani Nikula <jani.nikula@intel.com>
+#
+# Simple kernel-doc and reStructuredText lint tool that can be used
+# independently and as a kernel build CHECK tool to validate kernel-doc
+# comments.
+#
+# Independent usage:
+# $ kernel-doc-rst-lint FILE
+#
+# Kernel CHECK usage:
+# $ make CHECK=scripts/kernel-doc-rst-lint C=1		# (or C=2)
+#
+# Depends on docutils and the rst-lint package
+# https://pypi.python.org/pypi/restructuredtext_lint
+#
+
+import os
+import subprocess
+import sys
+
+from docutils.parsers.rst import directives
+from docutils.parsers.rst import Directive
+from docutils.parsers.rst import roles
+from docutils import nodes, statemachine
+import restructuredtext_lint
+
+class DummyDirective(Directive):
+    required_argument = 1
+    optional_arguments = 0
+    option_spec = { }
+    has_content = True
+
+    def run(self):
+        return []
+
+# Fake the Sphinx C Domain directives and roles
+directives.register_directive('c:function', DummyDirective)
+directives.register_directive('c:type', DummyDirective)
+roles.register_generic_role('c:func', nodes.emphasis)
+roles.register_generic_role('c:type', nodes.emphasis)
+
+# We accept but ignore parameters to be compatible with how the kernel build
+# invokes CHECK.
+if len(sys.argv) < 2:
+    sys.stderr.write('usage: kernel-doc-rst-lint [IGNORED OPTIONS] FILE\n');
+    sys.exit(1)
+
+infile = sys.argv[len(sys.argv) - 1]
+cmd = ['scripts/kernel-doc', '-rst', infile]
+
+try:
+    p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
+    out, err = p.communicate()
+
+    # python2 needs conversion to unicode.
+    # python3 with universal_newlines=True returns strings.
+    if sys.version_info.major < 3:
+        out, err = unicode(out, 'utf-8'), unicode(err, 'utf-8')
+
+    # kernel-doc errors
+    sys.stderr.write(err)
+    if p.returncode != 0:
+        sys.exit(p.returncode)
+
+    # restructured text errors
+    lines = statemachine.string2lines(out, 8, convert_whitespace=True)
+    lint_errors = restructuredtext_lint.lint(out, infile)
+    for error in lint_errors:
+        # Ignore INFO
+        if error.level <= 1:
+            continue
+
+        print(error.source + ': ' + error.type + ': ' + error.full_message)
+        if error.line is not None:
+            print('Context:')
+            print('\t' + lines[error.line - 1])
+            print('\t' + lines[error.line])
+
+except Exception as e:
+    sys.stderr.write(str(e) + '\n')
+    sys.exit(1)
-- 
2.1.4


-- 
Jani Nikula, Intel Open Source Technology Center

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 00/15] improve function-level documentation
  2016-10-05 13:15 ` Daniel Vetter
  2016-10-05 14:04   ` kernel-doc-rst-lint (was: Re: [PATCH 00/15] improve function-level documentation) Jani Nikula
@ 2016-10-05 14:47   ` Julia Lawall
  1 sibling, 0 replies; 10+ messages in thread
From: Julia Lawall @ 2016-10-05 14:47 UTC (permalink / raw)
  To: linux-arm-kernel



On Wed, 5 Oct 2016, Daniel Vetter wrote:

> Jani Nikula has a patch with a scrip to make the one kernel-doc parser
> into a lint/checker pass over the entire kernel. I think that'd would
> be more robust instead of trying to approximate the real kerneldoc
> parser. Otoh that parser is a horror show of a perl/regex driven state
> machine ;-)

Sure.  To my recollection, I found around 2000 issues.  Many I ignored, eg
functions that simply have no documentation abuot the parameters,
functions that document their local variables, when these were more
interesting than the parameters etc.  But the set of patches is not
exhaustive with respect to the remaining interesting ones either.

julia

>
> Jani, can you pls digg out these patches? Can't find them right now ...
> -Daniel
>
>
> On Sat, Oct 1, 2016 at 9:46 PM, Julia Lawall <Julia.Lawall@lip6.fr> wrote:
> > These patches fix cases where the documentation above a function definition
> > is not consistent with the function header.  Issues are detected using the
> > semantic patch below (http://coccinelle.lip6.fr/).  Basically, the semantic
> > patch parses a file to find comments, then matches each function header,
> > and checks that the name and parameter list in the function header are
> > compatible with the comment that preceeds it most closely.
> >
> > // <smpl>
> > @initialize:ocaml@
> > @@
> >
> > let tbl = ref []
> > let fnstart = ref []
> > let success = Hashtbl.create 101
> > let thefile = ref ""
> > let parsed = ref []
> > let nea = ref []
> >
> > let parse file =
> >   thefile := List.nth (Str.split (Str.regexp "linux-next/") file) 1;
> >   let i = open_in file in
> >   let startline = ref 0 in
> >   let fn = ref "" in
> >   let ids = ref [] in
> >   let rec inside n =
> >     let l = input_line i in
> >     let n = n + 1 in
> >     match Str.split_delim (Str.regexp_string "*/") l with
> >       before::after::_ ->
> >         (if not (!fn = "")
> >         then tbl := (!startline,n,!fn,List.rev !ids)::!tbl);
> >         startline := 0;
> >         fn := "";
> >         ids := [];
> >         outside n
> >     | _ ->
> >         (match Str.split (Str.regexp "[ \t]+") l with
> >           "*"::name::rest ->
> >             let len = String.length name in
> >             (if !fn = "" && len > 2 && String.sub name (len-2) 2 = "()"
> >             then fn := String.sub name 0 (len-2)
> >             else if !fn = "" && (not (rest = [])) && List.hd rest = "-"
> >             then
> >               if String.get name (len-1) = ':'
> >               then fn := String.sub name 0 (len-1)
> >               else fn := name
> >             else if not(!fn = "") && len > 2 &&
> >               String.get name 0 = '@' && String.get name (len-1) = ':'
> >             then ids := (String.sub name 1 (len-2)) :: !ids);
> >         | _ -> ());
> >         inside n
> >   and outside n =
> >     let l = input_line i in
> >     let n = n + 1 in
> >     if String.length l > 2 && String.sub l 0 3 = "/**"
> >     then
> >       begin
> >         startline := n;
> >         inside n
> >       end
> >     else outside n in
> >   try outside 0 with End_of_file -> ()
> >
> > let hashadd tbl k v =
> >   let cell =
> >     try Hashtbl.find tbl k
> >     with Not_found ->
> >       let cell = ref [] in
> >       Hashtbl.add tbl k cell;
> >       cell in
> >   cell := v :: !cell
> >
> > @script:ocaml@
> > @@
> >
> > tbl := [];
> > fnstart := [];
> > Hashtbl.clear success;
> > parsed := [];
> > nea := [];
> > parse (List.hd (Coccilib.files()))
> >
> > @r@
> > identifier f;
> > position p;
> > @@
> >
> > f at p(...) { ... }
> >
> > @script:ocaml@
> > p << r.p;
> > f << r.f;
> > @@
> >
> > parsed := f :: !parsed;
> > fnstart := (List.hd p).line :: !fnstart
> >
> > @param@
> > identifier f;
> > type T;
> > identifier i;
> > parameter list[n] ps;
> > parameter list[n1] ps1;
> > position p;
> > @@
> >
> > f at p(ps,T i,ps1) { ... }
> >
> > @script:ocaml@
> > @@
> >
> > tbl := List.rev (List.sort compare !tbl)
> >
> > @script:ocaml@
> > p << param.p;
> > f << param.f;
> > @@
> >
> > let myline = (List.hd p).line in
> > let prevline =
> >   List.fold_left
> >     (fun prev x ->
> >       if x < myline
> >       then max x prev
> >       else prev)
> >     0 !fnstart in
> > let _ =
> >   List.exists
> >     (function (st,fn,nm,ids) ->
> >       if prevline < st && myline > st && prevline < fn && myline > fn
> >       then
> >         begin
> >           (if not (String.lowercase f = String.lowercase nm)
> >           then
> >             Printf.printf "%s:%d %s doesn't match preceding comment: %s\n"
> >               !thefile myline f nm);
> >           true
> >         end
> >       else false)
> >     !tbl in
> > ()
> >
> > @script:ocaml@
> > p << param.p;
> > n << param.n;
> > n1 << param.n1;
> > i << param.i;
> > f << param.f;
> > @@
> >
> > let myline = (List.hd p).line in
> > let prevline =
> >   List.fold_left
> >     (fun prev x ->
> >       if x < myline
> >       then max x prev
> >       else prev)
> >     0 !fnstart in
> > let _ =
> >   List.exists
> >     (function (st,fn,nm,ids) ->
> >       if prevline < st && myline > st && prevline < fn && myline > fn
> >       then
> >         begin
> >           (if List.mem i ids then hashadd success (st,fn,nm) i);
> >           (if ids = [] (* arg list seems not obligatory *)
> >           then ()
> >           else if not (List.mem i ids)
> >           then
> >             Printf.printf "%s:%d %s doesn't appear in ids: %s\n"
> >               !thefile myline i (String.concat " " ids)
> >           else if List.length ids <= n || List.length ids <= n1
> >           then
> >             (if not (List.mem f !nea)
> >             then
> >               begin
> >                 nea := f :: !nea;
> >                 Printf.printf "%s:%d %s not enough args\n" !thefile myline f;
> >               end)
> >           else
> >             let foundid = List.nth ids n in
> >             let efoundid = List.nth (List.rev ids) n1 in
> >             if not(foundid = i || efoundid = i)
> >             then
> >               Printf.printf "%s:%d %s wrong arg in position %d: %s\n"
> >                 !thefile myline i n foundid);
> >           true
> >         end
> >       else false)
> >     !tbl in
> > ()
> >
> > @script:ocaml@
> > @@
> > List.iter
> >   (function (st,fn,nm,ids) ->
> >     if List.mem nm !parsed
> >     then
> >       let entry =
> >         try !(Hashtbl.find success (st,fn,nm))
> >         with Not_found -> [] in
> >       List.iter
> >         (fun id ->
> >           if not (List.mem id entry) && not (id = "...")
> >           then Printf.printf "%s:%d %s not used\n" !thefile st id)
> >         ids)
> >   !tbl
> > // </smpl>
> >
> >
> > ---
> >
> >  drivers/clk/keystone/pll.c               |    4 ++--
> >  drivers/clk/sunxi/clk-mod0.c             |    2 +-
> >  drivers/clk/tegra/cvb.c                  |   10 +++++-----
> >  drivers/dma-buf/sw_sync.c                |    6 +++---
> >  drivers/gpu/drm/gma500/intel_i2c.c       |    3 +--
> >  drivers/gpu/drm/omapdrm/omap_drv.c       |    4 ++--
> >  drivers/irqchip/irq-metag-ext.c          |    1 -
> >  drivers/irqchip/irq-vic.c                |    1 -
> >  drivers/mfd/tc3589x.c                    |    4 ++--
> >  drivers/power/supply/ab8500_fg.c         |    8 ++++----
> >  drivers/power/supply/abx500_chargalg.c   |    1 +
> >  drivers/power/supply/intel_mid_battery.c |    2 +-
> >  drivers/power/supply/power_supply_core.c |    4 ++--
> >  fs/crypto/crypto.c                       |    4 ++--
> >  fs/crypto/fname.c                        |    4 ++--
> >  fs/ubifs/file.c                          |    2 +-
> >  fs/ubifs/gc.c                            |    2 +-
> >  fs/ubifs/lprops.c                        |    2 +-
> >  fs/ubifs/lpt_commit.c                    |    4 +---
> >  fs/ubifs/replay.c                        |    2 +-
> >  lib/kobject_uevent.c                     |    6 +++---
> >  lib/lru_cache.c                          |    4 ++--
> >  lib/nlattr.c                             |    2 +-
> >  23 files changed, 39 insertions(+), 43 deletions(-)
> > _______________________________________________
> > dri-devel mailing list
> > dri-devel at lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/dri-devel
>
>
>
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> +41 (0) 79 365 57 48 - http://blog.ffwll.ch
> --
> To unsubscribe from this list: send the line "unsubscribe kernel-janitors" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* kernel-doc-rst-lint (was: Re: [PATCH 00/15] improve function-level documentation)
  2016-10-05 14:04   ` kernel-doc-rst-lint (was: Re: [PATCH 00/15] improve function-level documentation) Jani Nikula
@ 2016-10-05 17:27     ` Markus Heiser
  2016-10-05 20:25     ` Julia Lawall
  1 sibling, 0 replies; 10+ messages in thread
From: Markus Heiser @ 2016-10-05 17:27 UTC (permalink / raw)
  To: linux-arm-kernel


Am 05.10.2016 um 16:04 schrieb Jani Nikula <jani.nikula@linux.intel.com>:

> On Wed, 05 Oct 2016, Daniel Vetter <daniel@ffwll.ch> wrote:
>> Jani Nikula has a patch with a scrip to make the one kernel-doc parser
>> into a lint/checker pass over the entire kernel. I think that'd would
>> be more robust instead of trying to approximate the real kerneldoc
>> parser. Otoh that parser is a horror show of a perl/regex driven state
>> machine ;-)
>> 
>> Jani, can you pls digg out these patches? Can't find them right now ...
> 
> Expanding the massive Cc: with linux-doc list...
> 
> Here goes. It's a quick hack from months ago, but still seems to
> somewhat work. At least for the kernel-doc parts. The reStructuredText
> lint part isn't all that great, and doesn't have mapping to line numbers
> like the Sphinx kernel-doc extension does. Anyway I'm happy how this
> integrates with kernel build CHECK and C=1/C=2.
> 
> I guess Julia's goal is to automate the *fixing* of some of the error
> classes from kernel-doc. Not sure how well this could be made to
> integrate with any of that.
> 
> BR,
> Jani.

Another lint alternative: 

 use the lint from the linuxdoc project 

install the linuxdoc package:

*  https://return42.github.io/linuxdoc/install.html

e.g.::

 pip install --user git+http://github.com/return42/linuxdoc.git

and run kernel-lintdoc with the file/folder to lint as argument / e.g.::

 kernel-lintdoc include/media/

-- Markus --


> 
> 
> From 1244efa0f63a7b13795e8c37f81733a3c8bfc56a Mon Sep 17 00:00:00 2001
> From: Jani Nikula <jani.nikula@intel.com>
> Date: Tue, 31 May 2016 18:11:33 +0300
> Subject: [PATCH] kernel-doc-rst-lint: add tool to check kernel-doc and rst
> correctness
> Organization: Intel Finland Oy - BIC 0357606-4 - Westendinkatu 7, 02160 Espoo
> Cc: Jani Nikula <jani.nikula@intel.com>
> 
> Simple kernel-doc and reStructuredText lint tool that can be used
> independently and as a kernel build CHECK tool to validate kernel-doc
> comments.
> 
> Independent usage:
> $ kernel-doc-rst-lint FILE
> 
> Kernel CHECK usage:
> $ make CHECK=scripts/kernel-doc-rst-lint C=1		# (or C=2)
> 
> Depends on docutils and the rst-lint package
> https://pypi.python.org/pypi/restructuredtext_lint
> 
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> ---
> scripts/kernel-doc-rst-lint | 106 ++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 106 insertions(+)
> create mode 100755 scripts/kernel-doc-rst-lint
> 
> diff --git a/scripts/kernel-doc-rst-lint b/scripts/kernel-doc-rst-lint
> new file mode 100755
> index 000000000000..7e0157679f83
> --- /dev/null
> +++ b/scripts/kernel-doc-rst-lint
> @@ -0,0 +1,106 @@
> +#!/usr/bin/env python
> +# coding=utf-8
> +#
> +# Copyright ? 2016 Intel Corporation
> +#
> +# Permission is hereby granted, free of charge, to any person obtaining a
> +# copy of this software and associated documentation files (the "Software"),
> +# to deal in the Software without restriction, including without limitation
> +# the rights to use, copy, modify, merge, publish, distribute, sublicense,
> +# and/or sell copies of the Software, and to permit persons to whom the
> +# Software is furnished to do so, subject to the following conditions:
> +#
> +# The above copyright notice and this permission notice (including the next
> +# paragraph) shall be included in all copies or substantial portions of the
> +# Software.
> +#
> +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> +# IN THE SOFTWARE.
> +#
> +# Authors:
> +#    Jani Nikula <jani.nikula@intel.com>
> +#
> +# Simple kernel-doc and reStructuredText lint tool that can be used
> +# independently and as a kernel build CHECK tool to validate kernel-doc
> +# comments.
> +#
> +# Independent usage:
> +# $ kernel-doc-rst-lint FILE
> +#
> +# Kernel CHECK usage:
> +# $ make CHECK=scripts/kernel-doc-rst-lint C=1		# (or C=2)
> +#
> +# Depends on docutils and the rst-lint package
> +# https://pypi.python.org/pypi/restructuredtext_lint
> +#
> +
> +import os
> +import subprocess
> +import sys
> +
> +from docutils.parsers.rst import directives
> +from docutils.parsers.rst import Directive
> +from docutils.parsers.rst import roles
> +from docutils import nodes, statemachine
> +import restructuredtext_lint
> +
> +class DummyDirective(Directive):
> +    required_argument = 1
> +    optional_arguments = 0
> +    option_spec = { }
> +    has_content = True
> +
> +    def run(self):
> +        return []
> +
> +# Fake the Sphinx C Domain directives and roles
> +directives.register_directive('c:function', DummyDirective)
> +directives.register_directive('c:type', DummyDirective)
> +roles.register_generic_role('c:func', nodes.emphasis)
> +roles.register_generic_role('c:type', nodes.emphasis)
> +
> +# We accept but ignore parameters to be compatible with how the kernel build
> +# invokes CHECK.
> +if len(sys.argv) < 2:
> +    sys.stderr.write('usage: kernel-doc-rst-lint [IGNORED OPTIONS] FILE\n');
> +    sys.exit(1)
> +
> +infile = sys.argv[len(sys.argv) - 1]
> +cmd = ['scripts/kernel-doc', '-rst', infile]
> +
> +try:
> +    p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
> +    out, err = p.communicate()
> +
> +    # python2 needs conversion to unicode.
> +    # python3 with universal_newlines=True returns strings.
> +    if sys.version_info.major < 3:
> +        out, err = unicode(out, 'utf-8'), unicode(err, 'utf-8')
> +
> +    # kernel-doc errors
> +    sys.stderr.write(err)
> +    if p.returncode != 0:
> +        sys.exit(p.returncode)
> +
> +    # restructured text errors
> +    lines = statemachine.string2lines(out, 8, convert_whitespace=True)
> +    lint_errors = restructuredtext_lint.lint(out, infile)
> +    for error in lint_errors:
> +        # Ignore INFO
> +        if error.level <= 1:
> +            continue
> +
> +        print(error.source + ': ' + error.type + ': ' + error.full_message)
> +        if error.line is not None:
> +            print('Context:')
> +            print('\t' + lines[error.line - 1])
> +            print('\t' + lines[error.line])
> +
> +except Exception as e:
> +    sys.stderr.write(str(e) + '\n')
> +    sys.exit(1)
> -- 
> 2.1.4
> 
> 
> -- 
> Jani Nikula, Intel Open Source Technology Center
> --
> To unsubscribe from this list: send the line "unsubscribe linux-media" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 10+ messages in thread

* kernel-doc-rst-lint (was: Re: [PATCH 00/15] improve function-level documentation)
  2016-10-05 14:04   ` kernel-doc-rst-lint (was: Re: [PATCH 00/15] improve function-level documentation) Jani Nikula
  2016-10-05 17:27     ` Markus Heiser
@ 2016-10-05 20:25     ` Julia Lawall
  1 sibling, 0 replies; 10+ messages in thread
From: Julia Lawall @ 2016-10-05 20:25 UTC (permalink / raw)
  To: linux-arm-kernel



On Wed, 5 Oct 2016, Jani Nikula wrote:

> On Wed, 05 Oct 2016, Daniel Vetter <daniel@ffwll.ch> wrote:
> > Jani Nikula has a patch with a scrip to make the one kernel-doc parser
> > into a lint/checker pass over the entire kernel. I think that'd would
> > be more robust instead of trying to approximate the real kerneldoc
> > parser. Otoh that parser is a horror show of a perl/regex driven state
> > machine ;-)
> >
> > Jani, can you pls digg out these patches? Can't find them right now ...
>
> Expanding the massive Cc: with linux-doc list...
>
> Here goes. It's a quick hack from months ago, but still seems to
> somewhat work. At least for the kernel-doc parts. The reStructuredText
> lint part isn't all that great, and doesn't have mapping to line numbers
> like the Sphinx kernel-doc extension does. Anyway I'm happy how this
> integrates with kernel build CHECK and C=1/C=2.
>
> I guess Julia's goal is to automate the *fixing* of some of the error
> classes from kernel-doc. Not sure how well this could be made to
> integrate with any of that.

No, my work doesn't fix anything.  Coccinelle can't actually process
comments.  I just correlated the parsed comment with the function header.

julia

>
> BR,
> Jani.
>
>
> From 1244efa0f63a7b13795e8c37f81733a3c8bfc56a Mon Sep 17 00:00:00 2001
> From: Jani Nikula <jani.nikula@intel.com>
> Date: Tue, 31 May 2016 18:11:33 +0300
> Subject: [PATCH] kernel-doc-rst-lint: add tool to check kernel-doc and rst
>  correctness
> Organization: Intel Finland Oy - BIC 0357606-4 - Westendinkatu 7, 02160 Espoo
> Cc: Jani Nikula <jani.nikula@intel.com>
>
> Simple kernel-doc and reStructuredText lint tool that can be used
> independently and as a kernel build CHECK tool to validate kernel-doc
> comments.
>
> Independent usage:
> $ kernel-doc-rst-lint FILE
>
> Kernel CHECK usage:
> $ make CHECK=scripts/kernel-doc-rst-lint C=1		# (or C=2)
>
> Depends on docutils and the rst-lint package
> https://pypi.python.org/pypi/restructuredtext_lint
>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> ---
>  scripts/kernel-doc-rst-lint | 106 ++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 106 insertions(+)
>  create mode 100755 scripts/kernel-doc-rst-lint
>
> diff --git a/scripts/kernel-doc-rst-lint b/scripts/kernel-doc-rst-lint
> new file mode 100755
> index 000000000000..7e0157679f83
> --- /dev/null
> +++ b/scripts/kernel-doc-rst-lint
> @@ -0,0 +1,106 @@
> +#!/usr/bin/env python
> +# coding=utf-8
> +#
> +# Copyright ? 2016 Intel Corporation
> +#
> +# Permission is hereby granted, free of charge, to any person obtaining a
> +# copy of this software and associated documentation files (the "Software"),
> +# to deal in the Software without restriction, including without limitation
> +# the rights to use, copy, modify, merge, publish, distribute, sublicense,
> +# and/or sell copies of the Software, and to permit persons to whom the
> +# Software is furnished to do so, subject to the following conditions:
> +#
> +# The above copyright notice and this permission notice (including the next
> +# paragraph) shall be included in all copies or substantial portions of the
> +# Software.
> +#
> +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> +# IN THE SOFTWARE.
> +#
> +# Authors:
> +#    Jani Nikula <jani.nikula@intel.com>
> +#
> +# Simple kernel-doc and reStructuredText lint tool that can be used
> +# independently and as a kernel build CHECK tool to validate kernel-doc
> +# comments.
> +#
> +# Independent usage:
> +# $ kernel-doc-rst-lint FILE
> +#
> +# Kernel CHECK usage:
> +# $ make CHECK=scripts/kernel-doc-rst-lint C=1		# (or C=2)
> +#
> +# Depends on docutils and the rst-lint package
> +# https://pypi.python.org/pypi/restructuredtext_lint
> +#
> +
> +import os
> +import subprocess
> +import sys
> +
> +from docutils.parsers.rst import directives
> +from docutils.parsers.rst import Directive
> +from docutils.parsers.rst import roles
> +from docutils import nodes, statemachine
> +import restructuredtext_lint
> +
> +class DummyDirective(Directive):
> +    required_argument = 1
> +    optional_arguments = 0
> +    option_spec = { }
> +    has_content = True
> +
> +    def run(self):
> +        return []
> +
> +# Fake the Sphinx C Domain directives and roles
> +directives.register_directive('c:function', DummyDirective)
> +directives.register_directive('c:type', DummyDirective)
> +roles.register_generic_role('c:func', nodes.emphasis)
> +roles.register_generic_role('c:type', nodes.emphasis)
> +
> +# We accept but ignore parameters to be compatible with how the kernel build
> +# invokes CHECK.
> +if len(sys.argv) < 2:
> +    sys.stderr.write('usage: kernel-doc-rst-lint [IGNORED OPTIONS] FILE\n');
> +    sys.exit(1)
> +
> +infile = sys.argv[len(sys.argv) - 1]
> +cmd = ['scripts/kernel-doc', '-rst', infile]
> +
> +try:
> +    p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
> +    out, err = p.communicate()
> +
> +    # python2 needs conversion to unicode.
> +    # python3 with universal_newlines=True returns strings.
> +    if sys.version_info.major < 3:
> +        out, err = unicode(out, 'utf-8'), unicode(err, 'utf-8')
> +
> +    # kernel-doc errors
> +    sys.stderr.write(err)
> +    if p.returncode != 0:
> +        sys.exit(p.returncode)
> +
> +    # restructured text errors
> +    lines = statemachine.string2lines(out, 8, convert_whitespace=True)
> +    lint_errors = restructuredtext_lint.lint(out, infile)
> +    for error in lint_errors:
> +        # Ignore INFO
> +        if error.level <= 1:
> +            continue
> +
> +        print(error.source + ': ' + error.type + ': ' + error.full_message)
> +        if error.line is not None:
> +            print('Context:')
> +            print('\t' + lines[error.line - 1])
> +            print('\t' + lines[error.line])
> +
> +except Exception as e:
> +    sys.stderr.write(str(e) + '\n')
> +    sys.exit(1)
> --
> 2.1.4
>
>
> --
> Jani Nikula, Intel Open Source Technology Center
> --
> To unsubscribe from this list: send the line "unsubscribe kernel-janitors" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2016-10-05 20:25 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-10-01 19:46 [PATCH 00/15] improve function-level documentation Julia Lawall
2016-10-01 19:46 ` [PATCH 07/15] clk: sunxi: mod0: " Julia Lawall
2016-10-04 21:05   ` Maxime Ripard
2016-10-01 20:19 ` [PATCH 00/15] " Joe Perches
2016-10-01 20:39   ` Julia Lawall
2016-10-05 13:15 ` Daniel Vetter
2016-10-05 14:04   ` kernel-doc-rst-lint (was: Re: [PATCH 00/15] improve function-level documentation) Jani Nikula
2016-10-05 17:27     ` Markus Heiser
2016-10-05 20:25     ` Julia Lawall
2016-10-05 14:47   ` [PATCH 00/15] improve function-level documentation Julia Lawall

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).