public inbox for linux-man@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v1] CONTRIBUTING.d/style/c: Add coding style for the example programs
@ 2025-02-08 22:44 Alejandro Colomar
  2025-02-08 22:57 ` Alejandro Colomar
  2025-02-17 20:24 ` Günther Noack
  0 siblings, 2 replies; 11+ messages in thread
From: Alejandro Colomar @ 2025-02-08 22:44 UTC (permalink / raw)
  To: linux-man, branden; +Cc: Alejandro Colomar, Jason Yundt

[-- Attachment #1: Type: text/plain, Size: 5049 bytes --]

Personally, I prefer tabs for actual programming.  But for manual pages,
we can live with 4 spaces for $reasons.

Reported-by: "G. Branden Robinson" <branden@debian.org>
Reported-by: Jason Yundt <jason@jasonyundt.email>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
---

Hi Branden, Jason,

Here's a first iteration of a C coding style.  Please let me know if you
think something isn't clear enough, or if something would need more
rationale.


Have a lovely night!
Alex

 CONTRIBUTING.d/style/c | 128 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 128 insertions(+)
 create mode 100644 CONTRIBUTING.d/style/c

diff --git a/CONTRIBUTING.d/style/c b/CONTRIBUTING.d/style/c
new file mode 100644
index 000000000..2ac09d043
--- /dev/null
+++ b/CONTRIBUTING.d/style/c
@@ -0,0 +1,128 @@
+Name
+       style/c - C coding style
+
+Description
+    Indentation
+	Use 4 spaces.  Ideally, tabs would be preferred; however, they
+	cause 5 spaces in manual pages, which is weird, so we use 4
+	spaces.
+
+		if (foo)
+		    bar();
+
+	Indent preprocessor directives after the hash by 1 space.
+
+		#ifndef  FOO
+		# define FOO
+		#endif
+
+	'case' is not indented within a 'switch'.
+
+		switch (x) {
+		case 1:
+		    foo();
+		    break;
+		default:
+		    break;
+		}
+
+    Line length
+	Lines should not be longer than 80 columns.  Except that if they
+	contain string literals, they can be longer; don't break
+	user-visible string literals.
+
+	When breaking a function prototype, start the continuation line
+	with 4 spaces.
+
+	When breaking a function call, align at the opening parenthesis.
+
+    Braces and spaces
+	Use K&R style for braces.  But if the controlling expression of
+	an if/for/while is broken, the opening brace goes on a line of
+	its own.
+
+		if (foo)
+		    bar();
+
+		if (foooooooooooooooooooooooooo
+		 || baaaaaaaaaaaaaaaaaaaaaaaaaar)
+		{
+		    baz();
+		}
+
+	Treat sizeof() and similar operators as functions, not keywords.
+	Use a space after keywords, but not after functions.
+
+	Use a space to separate binary and ternary operators (except
+	`.` and `->`), but not to separate unary operators.
+
+	Use a space between a cast and the expression it converts.
+
+    Naming
+	Use short names.  Long names should be an exception, and
+	indicate that something probably isn't well designed.
+
+    Functions
+	Functions should be short and sweet.
+
+	All functions should have prototypes.
+
+    Macros
+	Don't be worried about using macros.  They can and do improve
+	safety, if used judiciously.
+
+    Error handling
+	goto is good for error handling.  It's certainly better than the
+	alternatives most of the time.
+
+	Check for explicit error codes (connect(sfd, &sa, len) == -1)
+	instead of vague comparisons (connect(sfd, &sa, len) < 0).
+
+    Includes
+	Follow include-what-you-use guidelines.
+
+    Comments
+	Comments lie; don't write comments.  If you need to comment
+	code, do it in the commit message.  If that's not enough, maybe
+	the code isn't good.
+
+	In most cases, a function with an appropriate name is better
+	than a comment.  A function is also better than a named loop.
+
+    Variables
+	Variable should be declared at the top of the block in which
+	they are used.  That is, use C89 declarations.  The exception is
+	loop variables; we use C99 for-loop variable declarations.
+
+	The '*' goes with the variable name, not with the type name.
+	Except if the pointer is qualified, in which case the '*' goes
+	with the type name.
+
+	Variable declarations should be sorted by type-name length, and
+	then by type-name alphabetic order.  The variable names should
+	all be aligned.  There should be at least two spaces between a
+	type name and the variable name.  Declarations should be
+	separate from statements by a blank line.
+
+		int     i;
+		char    c;
+		char    *p;
+		size_t  size;
+
+    Dialect
+	We use the latest GNU C dialect.  Feel free to use new language
+	features, unless they are evil.
+
+See also
+	For anything not explicitly covered above, you can check the
+	following coding styles, roughly in order of appearance:
+
+	<https://include-what-you-use.org/>
+	<https://doc.cat-v.org/bell_labs/pikestyle>
+	<https://www.kernel.org/doc/html/latest/process/coding-style.html>
+	<https://git.kernel.org/pub/scm/git/git.git/tree/Documentation/CodingGuidelines>
+	<https://mbsd.evolvis.org/htman/i386/man9/style.htm>
+	<https://nginx.org/en/docs/dev/development_guide.html#code_style>
+	<https://google.github.io/styleguide/>
+	<https://www.gnu.org/prep/standards/standards.html>
+	<https://www.cis.upenn.edu/~lee/06cse480/data/cstyle.ms.pdf>

Range-diff against v0:
-:  --------- > 1:  63bd99658 CONTRIBUTING.d/style/c: Add coding style for the example programs

base-commit: 6f71d1e4958bd327b4cea006d27a854e66b85380
prerequisite-patch-id: 1567497bcbaa900493128c86ca25a75f15ecd394
-- 
2.47.2


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v1] CONTRIBUTING.d/style/c: Add coding style for the example programs
  2025-02-08 22:44 [PATCH v1] CONTRIBUTING.d/style/c: Add coding style for the example programs Alejandro Colomar
@ 2025-02-08 22:57 ` Alejandro Colomar
  2025-02-08 23:46   ` G. Branden Robinson
  2025-02-17 20:24 ` Günther Noack
  1 sibling, 1 reply; 11+ messages in thread
From: Alejandro Colomar @ 2025-02-08 22:57 UTC (permalink / raw)
  To: linux-man, branden; +Cc: Jason Yundt

[-- Attachment #1: Type: text/plain, Size: 687 bytes --]

Hi Branden,

On Sat, Feb 08, 2025 at 11:44:43PM +0100, Alejandro Colomar wrote:
> Personally, I prefer tabs for actual programming.  But for manual pages,
> we can live with 4 spaces for $reasons.
> 

[...]

> +Description
> +    Indentation
> +	Use 4 spaces.  Ideally, tabs would be preferred; however, they
> +	cause 5 spaces in manual pages, which is weird, so we use 4
> +	spaces.

On a side note, Branden, I've considered changing the manual pages'
EXAMPLES' source code to use tabs, and let the formatter do whatever it
wants.  Do you have any opinion on that?


Cheers,
Alex

> +
> +		if (foo)
> +		    bar();

-- 
<https://www.alejandro-colomar.es/>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v1] CONTRIBUTING.d/style/c: Add coding style for the example programs
  2025-02-08 22:57 ` Alejandro Colomar
@ 2025-02-08 23:46   ` G. Branden Robinson
  2025-02-08 23:59     ` Alejandro Colomar
  2025-02-09  2:20     ` onf
  0 siblings, 2 replies; 11+ messages in thread
From: G. Branden Robinson @ 2025-02-08 23:46 UTC (permalink / raw)
  To: Alejandro Colomar; +Cc: linux-man, Jason Yundt, groff

[-- Attachment #1: Type: text/plain, Size: 3085 bytes --]

[looping in groff list because I bring up grotty *roff details]

(in both senses of "grotty"!)

Hi Alex,

At 2025-02-08T23:57:07+0100, Alejandro Colomar wrote:
> On Sat, Feb 08, 2025 at 11:44:43PM +0100, Alejandro Colomar wrote:
> > Personally, I prefer tabs for actual programming.  But for manual
> > pages, we can live with 4 spaces for $reasons.
> > 
> 
> [...]
> 
> > +Description
> > +    Indentation
> > +	Use 4 spaces.  Ideally, tabs would be preferred; however, they
> > +	cause 5 spaces in manual pages, which is weird, so we use 4
> > +	spaces.
> 
> On a side note, Branden, I've considered changing the manual pages'
> EXAMPLES' source code to use tabs, and let the formatter do whatever
> it wants.  Do you have any opinion on that?

The behavior of input tab characters is well-defined in *roff, but
defined _weirdly_ to most people's sensibilities when filling is
enabled.  I won't quote the documentation here, merely point to it.

https://www.gnu.org/software/groff/manual/groff.html.node/Tabs-and-Leaders.html

(This discussion is somewhat elaborated for clarity in the forthcoming
groff 1.24.)

_If_ you advise the use of tab characters _only_ when filling is
disabled, as, apropos of the Subject line, is the case in (displayed)
code examples, you should be fine.

However, you will get 8 character cells per tab stop and I am _not_ sure
it's portable to expect, or to try to configure, anything else.

For example, grotty(1) has the `-h` option, which is accessible via the
MANROFFOPT environment variable supported by man-db man(1).

     -h      Use literal horizontal tab characters in the output.  Tabs
             are assumed to be set every 8 columns.

Hmm, I should edit this to add "to optimize movement to the next tab
stop" or similar language.  In other words, when given this option,
grotty(1) performs a crude curses-style optimization, replacing long
sequences of spaces with tabs even where tabs do not appear in the
input.  For example:

$ printf 'foo\tbar          baz' | nroff | od -c
0000000   f   o   o                       b   a   r
0000020                       b   a   z  \n  \n  \n  \n  \n  \n  \n  \n
0000040  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n
*
0000120  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n
0000132
$ printf 'foo\tbar          baz' | nroff -P-h | od -c
0000000   f   o   o  \t   b   a   r  \t                       b   a   z
0000020  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n
*
0000120  \n  \n
0000122

Finally, I have a vague memory--perhaps not a correct one--that Michael
Kerrisk preferred 4-cell tab stops over 8-cell ones (however obtained)
because he found that the latter caused lines to overrun too frequently.
Keep in mind that displayed code examples in man pages will always be
significantly indented, unlike in real C source where we start
everything at column 0.  Things to consider.

I would proceed with caution, and test with multiple formatters.  (Maybe
you already do.)

Regards,
Branden

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v1] CONTRIBUTING.d/style/c: Add coding style for the example programs
  2025-02-08 23:46   ` G. Branden Robinson
@ 2025-02-08 23:59     ` Alejandro Colomar
  2025-02-09  0:45       ` G. Branden Robinson
  2025-02-09  2:20     ` onf
  1 sibling, 1 reply; 11+ messages in thread
From: Alejandro Colomar @ 2025-02-08 23:59 UTC (permalink / raw)
  To: G. Branden Robinson; +Cc: linux-man, Jason Yundt, groff

[-- Attachment #1: Type: text/plain, Size: 3086 bytes --]

Hi Branden,

On Sat, Feb 08, 2025 at 05:46:19PM -0600, G. Branden Robinson wrote:
> _If_ you advise the use of tab characters _only_ when filling is
> disabled, as, apropos of the Subject line, is the case in (displayed)
> code examples, you should be fine.

Yes, I'm proposing using tabs exclusively within EX/EE.

> However, you will get 8 character cells per tab stop and I am _not_ sure
> it's portable to expect, or to try to configure, anything else.

Are you sure?  I'm getting 5 characters per cell, which is what has
prevented me from doing it more happily.  I would have done it already
if I had seen 8 chars-per-tab.

	alx@devuan:~/tmp$ cat c.man 
	.TH a s d f
	.SH g
	.EX
	if (foo)
		bar();
	.EE
	alx@devuan:~/tmp$ hd c.man 
	00000000  2e 54 48 20 61 20 73 20  64 20 66 0a 2e 53 48 20  |.TH a s d f..SH |
	00000010  67 0a 2e 45 58 0a 69 66  20 28 66 6f 6f 29 0a 09  |g..EX.if (foo)..|
	00000020  62 61 72 28 29 3b 0a 2e  45 45 0a                 |bar();..EE.|
	0000002b
	alx@devuan:~/tmp$ groff -man -Tutf8 c.man 
	a(s)                                                                        a(s)

	g
	     if (foo)
		  bar();

	f                                       d                                   a(s)
	alx@devuan:~/tmp$ groff -man -Tutf8 c.man | hd
	00000000  1b 5b 34 6d 61 1b 5b 32  34 6d 28 73 29 20 20 20  |.[4ma.[24m(s)   |
	00000010  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20  |                |
	*
	00000050  20 20 20 20 20 1b 5b 34  6d 61 1b 5b 32 34 6d 28  |     .[4ma.[24m(|
	00000060  73 29 0a 0a 1b 5b 31 6d  67 1b 5b 30 6d 0a 20 20  |s)...[1mg.[0m.  |
	00000070  20 20 20 69 66 20 28 66  6f 6f 29 0a 20 20 20 20  |   if (foo).    |
	00000080  20 20 20 20 20 20 62 61  72 28 29 3b 0a 0a 66 20  |      bar();..f |
	00000090  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20  |                |
	*
	000000b0  20 20 20 20 20 20 64 20  20 20 20 20 20 20 20 20  |      d         |
	000000c0  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20  |                |
	000000d0  20 20 20 20 20 20 20 20  20 20 1b 5b 34 6d 61 1b  |          .[4ma.|
	000000e0  5b 32 34 6d 28 73 29 0a                           |[24m(s).|
	000000e8

Why am I not seeing 8-char indents?

> Finally, I have a vague memory--perhaps not a correct one--that Michael
> Kerrisk preferred 4-cell tab stops over 8-cell ones (however obtained)
> because he found that the latter caused lines to overrun too frequently.
> Keep in mind that displayed code examples in man pages will always be
> significantly indented, unlike in real C source where we start
> everything at column 0.  Things to consider.

Yeah, that's one consideration.  I'd try to make sure that examples fit
in 80 columns before switching to tabs.  On the other hand, once I have
all the examples fit in there with tabs, the code will be more readable
(less nesting).

> I would proceed with caution, and test with multiple formatters.  (Maybe
> you already do.)

Yup.  :-)


Have a lovely night!
Alex

-- 
<https://www.alejandro-colomar.es/>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v1] CONTRIBUTING.d/style/c: Add coding style for the example programs
  2025-02-08 23:59     ` Alejandro Colomar
@ 2025-02-09  0:45       ` G. Branden Robinson
  2025-02-09  9:45         ` Alejandro Colomar
  0 siblings, 1 reply; 11+ messages in thread
From: G. Branden Robinson @ 2025-02-09  0:45 UTC (permalink / raw)
  To: Alejandro Colomar; +Cc: linux-man, Jason Yundt, groff

[-- Attachment #1: Type: text/plain, Size: 3415 bytes --]

Hi Alex,

At 2025-02-09T00:59:50+0100, Alejandro Colomar wrote:
> On Sat, Feb 08, 2025 at 05:46:19PM -0600, G. Branden Robinson wrote:
> > _If_ you advise the use of tab characters _only_ when filling is
> > disabled, as, apropos of the Subject line, is the case in
> > (displayed) code examples, you should be fine.
> 
> Yes, I'm proposing using tabs exclusively within EX/EE.
> 
> > However, you will get 8 character cells per tab stop and I am _not_
> > sure it's portable to expect, or to try to configure, anything else.
> 
> Are you sure?  I'm getting 5 characters per cell, which is what has
> prevented me from doing it more happily.  I would have done it already
> if I had seen 8 chars-per-tab.

Good thing I looped in the groff list; this way more people got to see
me make a fool of myself.

You're right.  Here's why.

https://git.savannah.gnu.org/cgit/groff.git/tree/tmac/an.tmac?h=1.23.0#n162

My days of furious hacking on the man(7) macro package seem mostly to be
in the past, and I'm spending much more time on GNU troff itself of
late.  So I insensibly crafted a demonstrator for the formatter's own
behavior, not incorporating that of the macro package.

> Why am I not seeing 8-char indents?

Because the package redefines the tab stops.

This rears the head of the portability beast a bit higher.

Famous Original Doug's man(7) in Seventh Edition Unix also set the tab
stops at every half-inch.

https://minnie.tuhs.org/cgi-bin/utree.pl?file=V7/usr/lib/tmac/tmac.an

So does Heirloom Doctools.  So does mandoc(1).

Neatroff doesn't ship its own man(7) implementation, and Plan 9 and
Solaris 10 troffs, and whatever other System V troffs still exist,
I'll wager have no relevance to the Linux man-pages project.

Fortunately grotty(1)'s different idea of how wide a tab stop is doesn't
pose a problem.  It renders a page as a rectangular grid of character
cells, populates those cells where the formatter (which knows the
document's tab stops) tells it to, then, if it's been given the `-h`
option, it uses 8-column tab stops to optimize output.  But, provided
the Unix terminal driver's tab stops are also configured to every 8
columns,[1] this causes no alteration of the output.

This works out okay because there's no such thing as a "tab stop" in the
formatter's page description language.

This half-inch tab stop default would seem to foreclose the possibility
of using hard tabs for code examples in your man page sources, unless
you want to depart from Ingo's and my man(7) portability advice
regarding the use of formatter requests.

Regards,
Branden

[1] ...which is almost always true, and while traditionally this was
    configurable on Unix systems,[2] it's possible that userland and/or
    terminal driver support has bitrotted to nonfunctionality on
    Linux-based systems, or was never implemented in the first place.

    See subsection "Tabs and Initialization" of terminfo(5).

[2] ...because of the long shadow cast by typewriters (the original Unix
    terminal devices) and the corresponding more "manual" and
    labor-intensive table composition procedures they required.
    Similarly, newspaper-style page composition with "cut" and "paste"
    operations involving scissors and adhesive are fading from memory--
    as is the Aldus PageMaker product that largely killed the practice.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v1] CONTRIBUTING.d/style/c: Add coding style for the example programs
  2025-02-08 23:46   ` G. Branden Robinson
  2025-02-08 23:59     ` Alejandro Colomar
@ 2025-02-09  2:20     ` onf
  1 sibling, 0 replies; 11+ messages in thread
From: onf @ 2025-02-09  2:20 UTC (permalink / raw)
  To: G. Branden Robinson, Alejandro Colomar; +Cc: linux-man, Jason Yundt, groff

Hi Branden & Alex,

On Sun Feb 9, 2025 at 12:46 AM CET, G. Branden Robinson wrote:
> [...]
> At 2025-02-08T23:57:07+0100, Alejandro Colomar wrote:
> > On Sat, Feb 08, 2025 at 11:44:43PM +0100, Alejandro Colomar wrote:
> > > Personally, I prefer tabs for actual programming.  But for manual
> > > pages, we can live with 4 spaces for $reasons.
> > > 
> > 
> > [...]
> > 
> > > +Description
> > > +    Indentation
> > > +	Use 4 spaces.  Ideally, tabs would be preferred; however, they
> > > +	cause 5 spaces in manual pages, which is weird, so we use 4
> > > +	spaces.
> > 
> > On a side note, Branden, I've considered changing the manual pages'
> > EXAMPLES' source code to use tabs, and let the formatter do whatever
> > it wants.  Do you have any opinion on that?
>
> The behavior of input tab characters is well-defined in *roff, but
> defined _weirdly_ to most people's sensibilities when filling is
> enabled.  I won't quote the documentation here, merely point to it.
>
> https://www.gnu.org/software/groff/manual/groff.html.node/Tabs-and-Leaders.html
> [...]

TL;DR:
With the default settings, a tab essentially translates into a
horizontal motion. What this means is that when filling is on
and you have text like this:
  int main(int argc, char **argv) {
  \tif (argc != 2 || strcmp(argv[1], "-h") == 0) {
  \t\tfprintf(stderr, usage, argv[0]);
  \t\treturn argc != 2;
  \t}
  \treturn 0;
  }

it ends up like this:
  int  main(int  argc, char **argv) {         if (argc != 2 || str‐
  cmp(argv[1], "‐h") == 0) {                 fprintf(stderr, usage,
  argv[0]);                 return argc != 2;         }         re‐
  turn 0; }

This is because tab stops are related to the beginning of a paragraph
rather than the beginning of an output line as one would expect.

The desired behavior can be enabled with the request .linetabs,
but this is groff-specific and not supported by other troffs.

~ onf

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

* Re: [PATCH v1] CONTRIBUTING.d/style/c: Add coding style for the example programs
  2025-02-09  0:45       ` G. Branden Robinson
@ 2025-02-09  9:45         ` Alejandro Colomar
  0 siblings, 0 replies; 11+ messages in thread
From: Alejandro Colomar @ 2025-02-09  9:45 UTC (permalink / raw)
  To: G. Branden Robinson; +Cc: linux-man, Jason Yundt, groff, Ingo Schwarze

[-- Attachment #1: Type: text/plain, Size: 1999 bytes --]

[CC += Ingo]

Hi Branden,

On Sat, Feb 08, 2025 at 06:45:31PM -0600, G. Branden Robinson wrote:
> https://git.savannah.gnu.org/cgit/groff.git/tree/tmac/an.tmac?h=1.23.0#n162

Hmmm.  What would be affected by changing that default?  Does it affect
anything other than a literal tab in source code?  I presume it doesn't
affect .IP or .RS, and it shouldn't affect tbl(7), so it would be
quite harmless to define that to a different value.

Considering that the BSDs are 8-col tabs people too, I suspect Ingo
won't be too much attached to that default.  Especially, since few
people already use tabs in their manual pages.

And even if the default doesn't change, I can just point to people to
the reason why they see 5-col indents in their manuals, so they can
tweak it if they are too irritated by it (most likely to poke their
packager to tweak it for them).

> > Why am I not seeing 8-char indents?
> 
> Because the package redefines the tab stops.
> 
> This rears the head of the portability beast a bit higher.
> 
> Famous Original Doug's man(7) in Seventh Edition Unix also set the tab
> stops at every half-inch.
> 
> https://minnie.tuhs.org/cgi-bin/utree.pl?file=V7/usr/lib/tmac/tmac.an
> 
> So does Heirloom Doctools.  So does mandoc(1).

Hmmm.

> Neatroff doesn't ship its own man(7) implementation, and Plan 9 and
> Solaris 10 troffs, and whatever other System V troffs still exist,
> I'll wager have no relevance to the Linux man-pages project.

No, they don't have much.

> This half-inch tab stop default would seem to foreclose the possibility
> of using hard tabs for code examples in your man page sources, unless
> you want to depart from Ingo's and my man(7) portability advice
> regarding the use of formatter requests.

Well, I'm not too uncomfortable indenting by 5 spaces, if that's the
default.  Then it's up to each one to reconsider the defaults.  :-)


Have a lovely day!
Alex

-- 
<https://www.alejandro-colomar.es/>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v1] CONTRIBUTING.d/style/c: Add coding style for the example programs
  2025-02-08 22:44 [PATCH v1] CONTRIBUTING.d/style/c: Add coding style for the example programs Alejandro Colomar
  2025-02-08 22:57 ` Alejandro Colomar
@ 2025-02-17 20:24 ` Günther Noack
  2025-02-17 22:16   ` Alejandro Colomar
  1 sibling, 1 reply; 11+ messages in thread
From: Günther Noack @ 2025-02-17 20:24 UTC (permalink / raw)
  To: Alejandro Colomar; +Cc: linux-man, branden, Jason Yundt

Hi!

On Sat, Feb 08, 2025 at 11:44:40PM +0100, Alejandro Colomar wrote:
> Personally, I prefer tabs for actual programming.  But for manual pages,
> we can live with 4 spaces for $reasons.
> 
> Reported-by: "G. Branden Robinson" <branden@debian.org>
> Reported-by: Jason Yundt <jason@jasonyundt.email>
> Signed-off-by: Alejandro Colomar <alx@kernel.org>
> ---
> 
> Hi Branden, Jason,
> 
> Here's a first iteration of a C coding style.  Please let me know if you
> think something isn't clear enough, or if something would need more
> rationale.
> 
> 
> Have a lovely night!
> Alex
> 
>  CONTRIBUTING.d/style/c | 128 +++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 128 insertions(+)
>  create mode 100644 CONTRIBUTING.d/style/c
> 
> diff --git a/CONTRIBUTING.d/style/c b/CONTRIBUTING.d/style/c
> new file mode 100644
> index 000000000..2ac09d043
> --- /dev/null
> +++ b/CONTRIBUTING.d/style/c
> @@ -0,0 +1,128 @@
> +Name
> +       style/c - C coding style

"...for code examples in man pages"?

> +
> +Description
> +    Indentation
> +	Use 4 spaces.  Ideally, tabs would be preferred; however, they
> +	cause 5 spaces in manual pages, which is weird, so we use 4
> +	spaces.
> +
> +		if (foo)
> +		    bar();
> +
> +	Indent preprocessor directives after the hash by 1 space.
> +
> +		#ifndef  FOO
> +		# define FOO
> +		#endif
> +
> +	'case' is not indented within a 'switch'.
> +
> +		switch (x) {
> +		case 1:
> +		    foo();
> +		    break;
> +		default:
> +		    break;
> +		}
> +
> +    Line length
> +	Lines should not be longer than 80 columns.

I assume that this is referring to a column limit on the fully
rendered man page, including surrounding indentation?

> +     Except that if they
> +	contain string literals, they can be longer; don't break
> +	user-visible string literals.
> +
> +	When breaking a function prototype, start the continuation line
> +	with 4 spaces.

When we break parameter lists in function prototypes, do we need to
break them in function definitions the same?  I'm asking because it
might make the indentation confusing when it's next to a function body
with the same indentation.  For instance:

void foobar(char *bananas, int oranges, float pineapples,
    int cucumbers) {
    int gherkins;
    int potatoes;

    /* actual code starts here */
}

Now the last parameter and the local variables have the same
indentation and can get confused more easily.


> +
> +	When breaking a function call, align at the opening parenthesis.
> +
> +    Braces and spaces
> +	Use K&R style for braces.  But if the controlling expression of
> +	an if/for/while is broken, the opening brace goes on a line of
> +	its own.
> +
> +		if (foo)
> +		    bar();
> +
> +		if (foooooooooooooooooooooooooo
> +		 || baaaaaaaaaaaaaaaaaaaaaaaaaar)
> +		{
> +		    baz();
> +		}
> +
> +	Treat sizeof() and similar operators as functions, not keywords.
> +	Use a space after keywords, but not after functions.
> +
> +	Use a space to separate binary and ternary operators (except
> +	`.` and `->`), but not to separate unary operators.
> +
> +	Use a space between a cast and the expression it converts.
> +
> +    Naming
> +	Use short names.  Long names should be an exception, and
> +	indicate that something probably isn't well designed.
> +
> +    Functions
> +	Functions should be short and sweet.
> +
> +	All functions should have prototypes.

Like this?

int foobar(int a, int b);

int foobar(int a, int b) {
    return a + b;
}

I don't understand what this duplication would be good for.
Or I am misunderstanding what you meant here. :)

> +
> +    Macros
> +	Don't be worried about using macros.  They can and do improve
> +	safety, if used judiciously.
> +
> +    Error handling
> +	goto is good for error handling.  It's certainly better than the
> +	alternatives most of the time.
> +
> +	Check for explicit error codes (connect(sfd, &sa, len) == -1)
> +	instead of vague comparisons (connect(sfd, &sa, len) < 0).
> +
> +    Includes
> +	Follow include-what-you-use guidelines.
> +
> +    Comments
> +	Comments lie; don't write comments.  If you need to comment
> +	code, do it in the commit message.  If that's not enough, maybe
> +	the code isn't good.
> +
> +	In most cases, a function with an appropriate name is better
> +	than a comment.  A function is also better than a named loop.
> +
> +    Variables
> +	Variable should be declared at the top of the block in which
> +	they are used.  That is, use C89 declarations.  The exception is
> +	loop variables; we use C99 for-loop variable declarations.
> +
> +	The '*' goes with the variable name, not with the type name.
> +	Except if the pointer is qualified, in which case the '*' goes
> +	with the type name.
> +
> +	Variable declarations should be sorted by type-name length, and
> +	then by type-name alphabetic order.  The variable names should
> +	all be aligned.  There should be at least two spaces between a
> +	type name and the variable name.  Declarations should be
> +	separate from statements by a blank line.
> +
> +		int     i;
> +		char    c;
> +		char    *p;
> +		size_t  size;
> +
> +    Dialect
> +	We use the latest GNU C dialect.  Feel free to use new language
> +	features, unless they are evil.
> +
> +See also
> +	For anything not explicitly covered above, you can check the
> +	following coding styles, roughly in order of appearance:
> +
> +	<https://include-what-you-use.org/>
> +	<https://doc.cat-v.org/bell_labs/pikestyle>
> +	<https://www.kernel.org/doc/html/latest/process/coding-style.html>
> +	<https://git.kernel.org/pub/scm/git/git.git/tree/Documentation/CodingGuidelines>
> +	<https://mbsd.evolvis.org/htman/i386/man9/style.htm>
> +	<https://nginx.org/en/docs/dev/development_guide.html#code_style>
> +	<https://google.github.io/styleguide/>
> +	<https://www.gnu.org/prep/standards/standards.html>
> +	<https://www.cis.upenn.edu/~lee/06cse480/data/cstyle.ms.pdf>
> 
> Range-diff against v0:
> -:  --------- > 1:  63bd99658 CONTRIBUTING.d/style/c: Add coding style for the example programs
> 
> base-commit: 6f71d1e4958bd327b4cea006d27a854e66b85380
> prerequisite-patch-id: 1567497bcbaa900493128c86ca25a75f15ecd394
> -- 
> 2.47.2

–-Günther

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

* Re: [PATCH v1] CONTRIBUTING.d/style/c: Add coding style for the example programs
  2025-02-17 20:24 ` Günther Noack
@ 2025-02-17 22:16   ` Alejandro Colomar
  2025-02-17 22:35     ` G. Branden Robinson
  0 siblings, 1 reply; 11+ messages in thread
From: Alejandro Colomar @ 2025-02-17 22:16 UTC (permalink / raw)
  To: Günther Noack; +Cc: linux-man, branden, Jason Yundt

[-- Attachment #1: Type: text/plain, Size: 4573 bytes --]

On Mon, Feb 17, 2025 at 09:24:11PM +0100, Günther Noack wrote:
> Hi!

Hi!

> > +Name
> > +       style/c - C coding style
> 
> "...for code examples in man pages"?

I didn't specify, because it also applies to programs written in commit
messages (for example to prove that a patch is correct).  It applies to
every C program that I have to look at as maintainer of this project
(and actually, of any project that I comaintain too).

> > +
> > +Description
> > +    Indentation
> > +	Use 4 spaces.  Ideally, tabs would be preferred; however, they
> > +	cause 5 spaces in manual pages, which is weird, so we use 4
> > +	spaces.
> > +
> > +		if (foo)
> > +		    bar();
> > +
> > +	Indent preprocessor directives after the hash by 1 space.
> > +
> > +		#ifndef  FOO
> > +		# define FOO
> > +		#endif
> > +
> > +	'case' is not indented within a 'switch'.
> > +
> > +		switch (x) {
> > +		case 1:
> > +		    foo();
> > +		    break;
> > +		default:
> > +		    break;
> > +		}
> > +
> > +    Line length
> > +	Lines should not be longer than 80 columns.
> 
> I assume that this is referring to a column limit on the fully
> rendered man page, including surrounding indentation?

It applies at several levels:

-  The source code cannot go past column 80.
-  The rendered page cannot go past column 80.

80 is a hard limit in every way possible.

> > +     Except that if they
> > +	contain string literals, they can be longer; don't break
> > +	user-visible string literals.
> > +
> > +	When breaking a function prototype, start the continuation line
> > +	with 4 spaces.
> 
> When we break parameter lists in function prototypes, do we need to
> break them in function definitions the same?

Yes.  With the only difference that the return type goes in a line of
its own in the definition, but goes in the same line in the declaration.

>  I'm asking because it
> might make the indentation confusing when it's next to a function body
> with the same indentation.  For instance:
> 
> void foobar(char *bananas, int oranges, float pineapples,
>     int cucumbers) {

The opening brace goes in a line of its own.  It should be:



	void foobar(char *bananas, int oranges, float pineapples,
	    int cucumbers);

	void
	foobar(char *bananas, int oranges, float pineapples,
	    int cucumbers)
	{
	}


>     int gherkins;
>     int potatoes;
> 
>     /* actual code starts here */
> }
> 
> Now the last parameter and the local variables have the same
> indentation and can get confused more easily.

The rule for braces is K&R, which places the opening brace of a function
in a line of its own (unlike most other braces).

When a conditional is split across several lines, I also override K&R by
moving the brace to an empty line to avoid precisely that:

                if (foooooooooooooooooooooooooo
                 || baaaaaaaaaaaaaaaaaaaaaaaaaar)
                {
                    baz();
                }

> > +
> > +	When breaking a function call, align at the opening parenthesis.
> > +
> > +    Braces and spaces
> > +	Use K&R style for braces.  But if the controlling expression of
> > +	an if/for/while is broken, the opening brace goes on a line of
> > +	its own.
> > +
> > +		if (foo)
> > +		    bar();
> > +
> > +		if (foooooooooooooooooooooooooo
> > +		 || baaaaaaaaaaaaaaaaaaaaaaaaaar)
> > +		{
> > +		    baz();
> > +		}
> > +
> > +	Treat sizeof() and similar operators as functions, not keywords.
> > +	Use a space after keywords, but not after functions.
> > +
> > +	Use a space to separate binary and ternary operators (except
> > +	`.` and `->`), but not to separate unary operators.
> > +
> > +	Use a space between a cast and the expression it converts.
> > +
> > +    Naming
> > +	Use short names.  Long names should be an exception, and
> > +	indicate that something probably isn't well designed.
> > +
> > +    Functions
> > +	Functions should be short and sweet.
> > +
> > +	All functions should have prototypes.
> 
> Like this?
> 
> int foobar(int a, int b);
> 
> int foobar(int a, int b) {
>     return a + b;
> }
> 
> I don't understand what this duplication would be good for.
> Or I am misunderstanding what you meant here. :)

The definitions go all after main().  The prototypes go all before
main().  The benefit is that you can get an overview of what is defined
without having to look at the implementation.


Have a lovely night!
Alex

-- 
<https://www.alejandro-colomar.es/>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v1] CONTRIBUTING.d/style/c: Add coding style for the example programs
  2025-02-17 22:16   ` Alejandro Colomar
@ 2025-02-17 22:35     ` G. Branden Robinson
  2025-02-17 23:03       ` Alejandro Colomar
  0 siblings, 1 reply; 11+ messages in thread
From: G. Branden Robinson @ 2025-02-17 22:35 UTC (permalink / raw)
  To: Alejandro Colomar; +Cc: Günther Noack, linux-man, branden, Jason Yundt

[-- Attachment #1: Type: text/plain, Size: 1647 bytes --]

At 2025-02-17T23:16:59+0100, Alejandro Colomar wrote:
> On Mon, Feb 17, 2025 at 09:24:11PM +0100, Günther Noack wrote:
> > > +Name
> > > +       style/c - C coding style
> > 
> > "...for code examples in man pages"?
> 
> I didn't specify, because it also applies to programs written in commit
> messages (for example to prove that a patch is correct).  It applies to
> every C program that I have to look at as maintainer of this project
> (and actually, of any project that I comaintain too).

Maybe you need a name for this class/category.

"Colomar C coding style guide"?

> The definitions go all after main().  The prototypes go all before
> main().  The benefit is that you can get an overview of what is
> defined without having to look at the implementation.

My understanding is that function prototypes were added to the C
language to permit type-checking of function call arguments (and return
values) _across_ translation units--specifically.  So if a function is
static, or has no callers outside of its translation unit,[1] the
compiler can be expected to exercise whatever type-checking facilities
it has within that translation unit.  (I admit not knowing whether the
pre-ANSI Ritchie compiler or pcc were this careful.  I'll brace myself.)

Regards,
Branden

[1] ...in which case the correct thing to do is _declare it static_, but
    hey, this is C, man, we're "terse".  More modern languages like Go
    and Rust have started to recognize that having symbols be public
    and/or mutable by default are worse choices for modularity and
    concurrency.  Even Ada was not quite this careful.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v1] CONTRIBUTING.d/style/c: Add coding style for the example programs
  2025-02-17 22:35     ` G. Branden Robinson
@ 2025-02-17 23:03       ` Alejandro Colomar
  0 siblings, 0 replies; 11+ messages in thread
From: Alejandro Colomar @ 2025-02-17 23:03 UTC (permalink / raw)
  To: G. Branden Robinson; +Cc: Günther Noack, linux-man, branden, Jason Yundt

[-- Attachment #1: Type: text/plain, Size: 2634 bytes --]

Hi Branden,

On Mon, Feb 17, 2025 at 04:35:37PM -0600, G. Branden Robinson wrote:
> At 2025-02-17T23:16:59+0100, Alejandro Colomar wrote:
> > On Mon, Feb 17, 2025 at 09:24:11PM +0100, Günther Noack wrote:
> > > > +Name
> > > > +       style/c - C coding style
> > > 
> > > "...for code examples in man pages"?
> > 
> > I didn't specify, because it also applies to programs written in commit
> > messages (for example to prove that a patch is correct).  It applies to
> > every C program that I have to look at as maintainer of this project
> > (and actually, of any project that I comaintain too).
> 
> Maybe you need a name for this class/category.
> 
> "Colomar C coding style guide"?

Well, I guess being a file within our repository makes it explicit
enough that it applies at least to this project in its entirety.  That
is also applies to my other things, is coincidence.  :)

I'll avoid giving it a name, for now.

> > The definitions go all after main().  The prototypes go all before
> > main().  The benefit is that you can get an overview of what is
> > defined without having to look at the implementation.
> 
> My understanding is that function prototypes were added to the C
> language to permit type-checking of function call arguments (and return
> values) _across_ translation units--specifically.  So if a function is
> static, or has no callers outside of its translation unit,[1] the
> compiler can be expected to exercise whatever type-checking facilities
> it has within that translation unit.  (I admit not knowing whether the
> pre-ANSI Ritchie compiler or pcc were this careful.  I'll brace myself.)

Yep, their main reason to exist is type safety across TUs.  However,
that is useless in this project, because example programs are a single
TU most of the time.

However, they're still useful as an "index" of the program source code.
You can have a look at the list of prototypes, and that gives you an
idea of what is implemented below.

> 
> Regards,
> Branden
> 
> [1] ...in which case the correct thing to do is _declare it static_, but
>     hey, this is C, man, we're "terse".  More modern languages like Go
>     and Rust have started to recognize that having symbols be public
>     and/or mutable by default are worse choices for modularity and
>     concurrency.  Even Ada was not quite this careful.

Even for functions internal to a TU, I do always provide prototypes for
them in my code.  It helps see what's in a .c file by looking at the
"index" at the top.


Have a lovely night!
Alex

-- 
<https://www.alejandro-colomar.es/>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

end of thread, other threads:[~2025-02-17 23:02 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-02-08 22:44 [PATCH v1] CONTRIBUTING.d/style/c: Add coding style for the example programs Alejandro Colomar
2025-02-08 22:57 ` Alejandro Colomar
2025-02-08 23:46   ` G. Branden Robinson
2025-02-08 23:59     ` Alejandro Colomar
2025-02-09  0:45       ` G. Branden Robinson
2025-02-09  9:45         ` Alejandro Colomar
2025-02-09  2:20     ` onf
2025-02-17 20:24 ` Günther Noack
2025-02-17 22:16   ` Alejandro Colomar
2025-02-17 22:35     ` G. Branden Robinson
2025-02-17 23:03       ` Alejandro Colomar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox